diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..a6d73960 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,7 @@ +.git +.next +node_modules +npm-debug.log* +.env*.local +/tmp +*.db diff --git a/Dockerfile b/Dockerfile index 9e0457c2..bb461823 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,16 +1,18 @@ -FROM oven/bun:1 AS deps +FROM node:20-alpine AS deps WORKDIR /app -COPY ui/package.json ui/bun.lock ./ -RUN bun install --frozen-lockfile +# better-sqlite3 requires native compilation +RUN apk add --no-cache python3 make g++ +COPY package.json package-lock.json ./ +RUN npm ci -FROM oven/bun:1 AS builder +FROM node:20-alpine AS builder WORKDIR /app COPY --from=deps /app/node_modules ./node_modules -COPY ./ui . +COPY . . ENV NEXT_TELEMETRY_DISABLED=1 -RUN bun run build +RUN npm run build FROM node:20-alpine AS runner WORKDIR /app @@ -21,12 +23,18 @@ ENV NEXT_TELEMETRY_DISABLED=1 RUN addgroup --system --gid 1001 nodejs RUN adduser --system --uid 1001 nextjs -RUN mkdir .next -RUN chown nextjs:nodejs .next +RUN mkdir -p .next /data +RUN chown nextjs:nodejs .next /data +# Full node_modules (not standalone) so indexer.mjs can resolve viem + better-sqlite3 +COPY --from=deps /app/node_modules ./node_modules +COPY --from=builder --chown=nextjs:nodejs /app/.next ./.next COPY --from=builder /app/public ./public -COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./ -COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static +COPY --from=builder /app/package.json ./package.json +COPY --from=builder /app/scripts ./scripts +COPY --from=builder /app/docker/migrations ./docker/migrations + +RUN chown -R nextjs:nodejs node_modules && chmod +x scripts/start.sh USER nextjs @@ -35,4 +43,4 @@ EXPOSE 3000 ENV PORT=3000 ENV HOSTNAME="0.0.0.0" -CMD ["node", "server.js"] +CMD ["sh", "scripts/start.sh"] diff --git a/bun.lock b/bun.lock deleted file mode 100644 index 929dbf55..00000000 --- a/bun.lock +++ /dev/null @@ -1,482 +0,0 @@ -{ - "lockfileVersion": 1, - "configVersion": 1, - "workspaces": { - "": { - "name": "ui", - "dependencies": { - "@aws-sdk/client-s3": "3.940.0", - "next": "16.0.7", - "react": "19.2.1", - "react-dom": "19.2.1", - "viem": "2.40.3", - }, - "devDependencies": { - "@biomejs/biome": "2.3.8", - "@tailwindcss/postcss": "4.1.17", - "@types/node": "20.19.25", - "@types/react": "19.2.7", - "@types/react-dom": "19.2.3", - "tailwindcss": "4.1.17", - "typescript": "5.9.3", - }, - }, - }, - "packages": { - "@adraffy/ens-normalize": ["@adraffy/ens-normalize@1.11.1", "", {}, "sha512-nhCBV3quEgesuf7c7KYfperqSS14T8bYuvJ8PcLJp6znkZpFc0AuW4qBtr8eKVyPPe/8RSr7sglCWPU5eaxwKQ=="], - - "@alloc/quick-lru": ["@alloc/quick-lru@5.2.0", "", {}, "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw=="], - - "@aws-crypto/crc32": ["@aws-crypto/crc32@5.2.0", "", { "dependencies": { "@aws-crypto/util": "^5.2.0", "@aws-sdk/types": "^3.222.0", "tslib": "^2.6.2" } }, "sha512-nLbCWqQNgUiwwtFsen1AdzAtvuLRsQS8rYgMuxCrdKf9kOssamGLuPwyTY9wyYblNr9+1XM8v6zoDTPPSIeANg=="], - - "@aws-crypto/crc32c": ["@aws-crypto/crc32c@5.2.0", "", { "dependencies": { "@aws-crypto/util": "^5.2.0", "@aws-sdk/types": "^3.222.0", "tslib": "^2.6.2" } }, "sha512-+iWb8qaHLYKrNvGRbiYRHSdKRWhto5XlZUEBwDjYNf+ly5SVYG6zEoYIdxvf5R3zyeP16w4PLBn3rH1xc74Rag=="], - - "@aws-crypto/sha1-browser": ["@aws-crypto/sha1-browser@5.2.0", "", { "dependencies": { "@aws-crypto/supports-web-crypto": "^5.2.0", "@aws-crypto/util": "^5.2.0", "@aws-sdk/types": "^3.222.0", "@aws-sdk/util-locate-window": "^3.0.0", "@smithy/util-utf8": "^2.0.0", "tslib": "^2.6.2" } }, "sha512-OH6lveCFfcDjX4dbAvCFSYUjJZjDr/3XJ3xHtjn3Oj5b9RjojQo8npoLeA/bNwkOkrSQ0wgrHzXk4tDRxGKJeg=="], - - "@aws-crypto/sha256-browser": ["@aws-crypto/sha256-browser@5.2.0", "", { "dependencies": { "@aws-crypto/sha256-js": "^5.2.0", "@aws-crypto/supports-web-crypto": "^5.2.0", "@aws-crypto/util": "^5.2.0", "@aws-sdk/types": "^3.222.0", "@aws-sdk/util-locate-window": "^3.0.0", "@smithy/util-utf8": "^2.0.0", "tslib": "^2.6.2" } }, "sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw=="], - - "@aws-crypto/sha256-js": ["@aws-crypto/sha256-js@5.2.0", "", { "dependencies": { "@aws-crypto/util": "^5.2.0", "@aws-sdk/types": "^3.222.0", "tslib": "^2.6.2" } }, "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA=="], - - "@aws-crypto/supports-web-crypto": ["@aws-crypto/supports-web-crypto@5.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-iAvUotm021kM33eCdNfwIN//F77/IADDSs58i+MDaOqFrVjZo9bAal0NK7HurRuWLLpF1iLX7gbWrjHjeo+YFg=="], - - "@aws-crypto/util": ["@aws-crypto/util@5.2.0", "", { "dependencies": { "@aws-sdk/types": "^3.222.0", "@smithy/util-utf8": "^2.0.0", "tslib": "^2.6.2" } }, "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ=="], - - "@aws-sdk/client-s3": ["@aws-sdk/client-s3@3.940.0", "", { "dependencies": { "@aws-crypto/sha1-browser": "5.2.0", "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.940.0", "@aws-sdk/credential-provider-node": "3.940.0", "@aws-sdk/middleware-bucket-endpoint": "3.936.0", "@aws-sdk/middleware-expect-continue": "3.936.0", "@aws-sdk/middleware-flexible-checksums": "3.940.0", "@aws-sdk/middleware-host-header": "3.936.0", "@aws-sdk/middleware-location-constraint": "3.936.0", "@aws-sdk/middleware-logger": "3.936.0", "@aws-sdk/middleware-recursion-detection": "3.936.0", "@aws-sdk/middleware-sdk-s3": "3.940.0", "@aws-sdk/middleware-ssec": "3.936.0", "@aws-sdk/middleware-user-agent": "3.940.0", "@aws-sdk/region-config-resolver": "3.936.0", "@aws-sdk/signature-v4-multi-region": "3.940.0", "@aws-sdk/types": "3.936.0", "@aws-sdk/util-endpoints": "3.936.0", "@aws-sdk/util-user-agent-browser": "3.936.0", "@aws-sdk/util-user-agent-node": "3.940.0", "@smithy/config-resolver": "^4.4.3", "@smithy/core": "^3.18.5", "@smithy/eventstream-serde-browser": "^4.2.5", "@smithy/eventstream-serde-config-resolver": "^4.3.5", "@smithy/eventstream-serde-node": "^4.2.5", "@smithy/fetch-http-handler": "^5.3.6", "@smithy/hash-blob-browser": "^4.2.6", "@smithy/hash-node": "^4.2.5", "@smithy/hash-stream-node": "^4.2.5", "@smithy/invalid-dependency": "^4.2.5", "@smithy/md5-js": "^4.2.5", "@smithy/middleware-content-length": "^4.2.5", "@smithy/middleware-endpoint": "^4.3.12", "@smithy/middleware-retry": "^4.4.12", "@smithy/middleware-serde": "^4.2.6", "@smithy/middleware-stack": "^4.2.5", "@smithy/node-config-provider": "^4.3.5", "@smithy/node-http-handler": "^4.4.5", "@smithy/protocol-http": "^5.3.5", "@smithy/smithy-client": "^4.9.8", "@smithy/types": "^4.9.0", "@smithy/url-parser": "^4.2.5", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-body-length-node": "^4.2.1", "@smithy/util-defaults-mode-browser": "^4.3.11", "@smithy/util-defaults-mode-node": "^4.2.14", "@smithy/util-endpoints": "^3.2.5", "@smithy/util-middleware": "^4.2.5", "@smithy/util-retry": "^4.2.5", "@smithy/util-stream": "^4.5.6", "@smithy/util-utf8": "^4.2.0", "@smithy/util-waiter": "^4.2.5", "tslib": "^2.6.2" } }, "sha512-Wi4qnBT6shRRMXuuTgjMFTU5mu2KFWisgcigEMPptjPGUtJvBVi4PTGgS64qsLoUk/obqDAyOBOfEtRZ2ddC2w=="], - - "@aws-sdk/client-sso": ["@aws-sdk/client-sso@3.940.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.940.0", "@aws-sdk/middleware-host-header": "3.936.0", "@aws-sdk/middleware-logger": "3.936.0", "@aws-sdk/middleware-recursion-detection": "3.936.0", "@aws-sdk/middleware-user-agent": "3.940.0", "@aws-sdk/region-config-resolver": "3.936.0", "@aws-sdk/types": "3.936.0", "@aws-sdk/util-endpoints": "3.936.0", "@aws-sdk/util-user-agent-browser": "3.936.0", "@aws-sdk/util-user-agent-node": "3.940.0", "@smithy/config-resolver": "^4.4.3", "@smithy/core": "^3.18.5", "@smithy/fetch-http-handler": "^5.3.6", "@smithy/hash-node": "^4.2.5", "@smithy/invalid-dependency": "^4.2.5", "@smithy/middleware-content-length": "^4.2.5", "@smithy/middleware-endpoint": "^4.3.12", "@smithy/middleware-retry": "^4.4.12", "@smithy/middleware-serde": "^4.2.6", "@smithy/middleware-stack": "^4.2.5", "@smithy/node-config-provider": "^4.3.5", "@smithy/node-http-handler": "^4.4.5", "@smithy/protocol-http": "^5.3.5", "@smithy/smithy-client": "^4.9.8", "@smithy/types": "^4.9.0", "@smithy/url-parser": "^4.2.5", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-body-length-node": "^4.2.1", "@smithy/util-defaults-mode-browser": "^4.3.11", "@smithy/util-defaults-mode-node": "^4.2.14", "@smithy/util-endpoints": "^3.2.5", "@smithy/util-middleware": "^4.2.5", "@smithy/util-retry": "^4.2.5", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-SdqJGWVhmIURvCSgkDditHRO+ozubwZk9aCX9MK8qxyOndhobCndW1ozl3hX9psvMAo9Q4bppjuqy/GHWpjB+A=="], - - "@aws-sdk/core": ["@aws-sdk/core@3.940.0", "", { "dependencies": { "@aws-sdk/types": "3.936.0", "@aws-sdk/xml-builder": "3.930.0", "@smithy/core": "^3.18.5", "@smithy/node-config-provider": "^4.3.5", "@smithy/property-provider": "^4.2.5", "@smithy/protocol-http": "^5.3.5", "@smithy/signature-v4": "^5.3.5", "@smithy/smithy-client": "^4.9.8", "@smithy/types": "^4.9.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-middleware": "^4.2.5", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-KsGD2FLaX5ngJao1mHxodIVU9VYd1E8810fcYiGwO1PFHDzf5BEkp6D9IdMeQwT8Q6JLYtiiT1Y/o3UCScnGoA=="], - - "@aws-sdk/credential-provider-env": ["@aws-sdk/credential-provider-env@3.940.0", "", { "dependencies": { "@aws-sdk/core": "3.940.0", "@aws-sdk/types": "3.936.0", "@smithy/property-provider": "^4.2.5", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-/G3l5/wbZYP2XEQiOoIkRJmlv15f1P3MSd1a0gz27lHEMrOJOGq66rF1Ca4OJLzapWt3Fy9BPrZAepoAX11kMw=="], - - "@aws-sdk/credential-provider-http": ["@aws-sdk/credential-provider-http@3.940.0", "", { "dependencies": { "@aws-sdk/core": "3.940.0", "@aws-sdk/types": "3.936.0", "@smithy/fetch-http-handler": "^5.3.6", "@smithy/node-http-handler": "^4.4.5", "@smithy/property-provider": "^4.2.5", "@smithy/protocol-http": "^5.3.5", "@smithy/smithy-client": "^4.9.8", "@smithy/types": "^4.9.0", "@smithy/util-stream": "^4.5.6", "tslib": "^2.6.2" } }, "sha512-dOrc03DHElNBD6N9Okt4U0zhrG4Wix5QUBSZPr5VN8SvmjD9dkrrxOkkJaMCl/bzrW7kbQEp7LuBdbxArMmOZQ=="], - - "@aws-sdk/credential-provider-ini": ["@aws-sdk/credential-provider-ini@3.940.0", "", { "dependencies": { "@aws-sdk/core": "3.940.0", "@aws-sdk/credential-provider-env": "3.940.0", "@aws-sdk/credential-provider-http": "3.940.0", "@aws-sdk/credential-provider-login": "3.940.0", "@aws-sdk/credential-provider-process": "3.940.0", "@aws-sdk/credential-provider-sso": "3.940.0", "@aws-sdk/credential-provider-web-identity": "3.940.0", "@aws-sdk/nested-clients": "3.940.0", "@aws-sdk/types": "3.936.0", "@smithy/credential-provider-imds": "^4.2.5", "@smithy/property-provider": "^4.2.5", "@smithy/shared-ini-file-loader": "^4.4.0", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-gn7PJQEzb/cnInNFTOaDoCN/hOKqMejNmLof1W5VW95Qk0TPO52lH8R4RmJPnRrwFMswOWswTOpR1roKNLIrcw=="], - - "@aws-sdk/credential-provider-login": ["@aws-sdk/credential-provider-login@3.940.0", "", { "dependencies": { "@aws-sdk/core": "3.940.0", "@aws-sdk/nested-clients": "3.940.0", "@aws-sdk/types": "3.936.0", "@smithy/property-provider": "^4.2.5", "@smithy/protocol-http": "^5.3.5", "@smithy/shared-ini-file-loader": "^4.4.0", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-fOKC3VZkwa9T2l2VFKWRtfHQPQuISqqNl35ZhcXjWKVwRwl/o7THPMkqI4XwgT2noGa7LLYVbWMwnsgSsBqglg=="], - - "@aws-sdk/credential-provider-node": ["@aws-sdk/credential-provider-node@3.940.0", "", { "dependencies": { "@aws-sdk/credential-provider-env": "3.940.0", "@aws-sdk/credential-provider-http": "3.940.0", "@aws-sdk/credential-provider-ini": "3.940.0", "@aws-sdk/credential-provider-process": "3.940.0", "@aws-sdk/credential-provider-sso": "3.940.0", "@aws-sdk/credential-provider-web-identity": "3.940.0", "@aws-sdk/types": "3.936.0", "@smithy/credential-provider-imds": "^4.2.5", "@smithy/property-provider": "^4.2.5", "@smithy/shared-ini-file-loader": "^4.4.0", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-M8NFAvgvO6xZjiti5kztFiAYmSmSlG3eUfr4ZHSfXYZUA/KUdZU/D6xJyaLnU8cYRWBludb6K9XPKKVwKfqm4g=="], - - "@aws-sdk/credential-provider-process": ["@aws-sdk/credential-provider-process@3.940.0", "", { "dependencies": { "@aws-sdk/core": "3.940.0", "@aws-sdk/types": "3.936.0", "@smithy/property-provider": "^4.2.5", "@smithy/shared-ini-file-loader": "^4.4.0", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-pILBzt5/TYCqRsJb7vZlxmRIe0/T+FZPeml417EK75060ajDGnVJjHcuVdLVIeKoTKm9gmJc9l45gon6PbHyUQ=="], - - "@aws-sdk/credential-provider-sso": ["@aws-sdk/credential-provider-sso@3.940.0", "", { "dependencies": { "@aws-sdk/client-sso": "3.940.0", "@aws-sdk/core": "3.940.0", "@aws-sdk/token-providers": "3.940.0", "@aws-sdk/types": "3.936.0", "@smithy/property-provider": "^4.2.5", "@smithy/shared-ini-file-loader": "^4.4.0", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-q6JMHIkBlDCOMnA3RAzf8cGfup+8ukhhb50fNpghMs1SNBGhanmaMbZSgLigBRsPQW7fOk2l8jnzdVLS+BB9Uw=="], - - "@aws-sdk/credential-provider-web-identity": ["@aws-sdk/credential-provider-web-identity@3.940.0", "", { "dependencies": { "@aws-sdk/core": "3.940.0", "@aws-sdk/nested-clients": "3.940.0", "@aws-sdk/types": "3.936.0", "@smithy/property-provider": "^4.2.5", "@smithy/shared-ini-file-loader": "^4.4.0", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-9QLTIkDJHHaYL0nyymO41H8g3ui1yz6Y3GmAN1gYQa6plXisuFBnGAbmKVj7zNvjWaOKdF0dV3dd3AFKEDoJ/w=="], - - "@aws-sdk/middleware-bucket-endpoint": ["@aws-sdk/middleware-bucket-endpoint@3.936.0", "", { "dependencies": { "@aws-sdk/types": "3.936.0", "@aws-sdk/util-arn-parser": "3.893.0", "@smithy/node-config-provider": "^4.3.5", "@smithy/protocol-http": "^5.3.5", "@smithy/types": "^4.9.0", "@smithy/util-config-provider": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-XLSVVfAorUxZh6dzF+HTOp4R1B5EQcdpGcPliWr0KUj2jukgjZEcqbBmjyMF/p9bmyQsONX80iURF1HLAlW0qg=="], - - "@aws-sdk/middleware-expect-continue": ["@aws-sdk/middleware-expect-continue@3.936.0", "", { "dependencies": { "@aws-sdk/types": "3.936.0", "@smithy/protocol-http": "^5.3.5", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-Eb4ELAC23bEQLJmUMYnPWcjD3FZIsmz2svDiXEcxRkQU9r7NRID7pM7C5NPH94wOfiCk0b2Y8rVyFXW0lGQwbA=="], - - "@aws-sdk/middleware-flexible-checksums": ["@aws-sdk/middleware-flexible-checksums@3.940.0", "", { "dependencies": { "@aws-crypto/crc32": "5.2.0", "@aws-crypto/crc32c": "5.2.0", "@aws-crypto/util": "5.2.0", "@aws-sdk/core": "3.940.0", "@aws-sdk/types": "3.936.0", "@smithy/is-array-buffer": "^4.2.0", "@smithy/node-config-provider": "^4.3.5", "@smithy/protocol-http": "^5.3.5", "@smithy/types": "^4.9.0", "@smithy/util-middleware": "^4.2.5", "@smithy/util-stream": "^4.5.6", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-WdsxDAVj5qaa5ApAP+JbpCOMHFGSmzjs2Y2OBSbWPeR9Ew7t/Okj+kUub94QJPsgzhvU1/cqNejhsw5VxeFKSQ=="], - - "@aws-sdk/middleware-host-header": ["@aws-sdk/middleware-host-header@3.936.0", "", { "dependencies": { "@aws-sdk/types": "3.936.0", "@smithy/protocol-http": "^5.3.5", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-tAaObaAnsP1XnLGndfkGWFuzrJYuk9W0b/nLvol66t8FZExIAf/WdkT2NNAWOYxljVs++oHnyHBCxIlaHrzSiw=="], - - "@aws-sdk/middleware-location-constraint": ["@aws-sdk/middleware-location-constraint@3.936.0", "", { "dependencies": { "@aws-sdk/types": "3.936.0", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-SCMPenDtQMd9o5da9JzkHz838w3327iqXk3cbNnXWqnNRx6unyW8FL0DZ84gIY12kAyVHz5WEqlWuekc15ehfw=="], - - "@aws-sdk/middleware-logger": ["@aws-sdk/middleware-logger@3.936.0", "", { "dependencies": { "@aws-sdk/types": "3.936.0", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-aPSJ12d3a3Ea5nyEnLbijCaaYJT2QjQ9iW+zGh5QcZYXmOGWbKVyPSxmVOboZQG+c1M8t6d2O7tqrwzIq8L8qw=="], - - "@aws-sdk/middleware-recursion-detection": ["@aws-sdk/middleware-recursion-detection@3.936.0", "", { "dependencies": { "@aws-sdk/types": "3.936.0", "@aws/lambda-invoke-store": "^0.2.0", "@smithy/protocol-http": "^5.3.5", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-l4aGbHpXM45YNgXggIux1HgsCVAvvBoqHPkqLnqMl9QVapfuSTjJHfDYDsx1Xxct6/m7qSMUzanBALhiaGO2fA=="], - - "@aws-sdk/middleware-sdk-s3": ["@aws-sdk/middleware-sdk-s3@3.940.0", "", { "dependencies": { "@aws-sdk/core": "3.940.0", "@aws-sdk/types": "3.936.0", "@aws-sdk/util-arn-parser": "3.893.0", "@smithy/core": "^3.18.5", "@smithy/node-config-provider": "^4.3.5", "@smithy/protocol-http": "^5.3.5", "@smithy/signature-v4": "^5.3.5", "@smithy/smithy-client": "^4.9.8", "@smithy/types": "^4.9.0", "@smithy/util-config-provider": "^4.2.0", "@smithy/util-middleware": "^4.2.5", "@smithy/util-stream": "^4.5.6", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-JYkLjgS1wLoKHJ40G63+afM1ehmsPsjcmrHirKh8+kSCx4ip7+nL1e/twV4Zicxr8RJi9Y0Ahq5mDvneilDDKQ=="], - - "@aws-sdk/middleware-ssec": ["@aws-sdk/middleware-ssec@3.936.0", "", { "dependencies": { "@aws-sdk/types": "3.936.0", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-/GLC9lZdVp05ozRik5KsuODR/N7j+W+2TbfdFL3iS+7un+gnP6hC8RDOZd6WhpZp7drXQ9guKiTAxkZQwzS8DA=="], - - "@aws-sdk/middleware-user-agent": ["@aws-sdk/middleware-user-agent@3.940.0", "", { "dependencies": { "@aws-sdk/core": "3.940.0", "@aws-sdk/types": "3.936.0", "@aws-sdk/util-endpoints": "3.936.0", "@smithy/core": "^3.18.5", "@smithy/protocol-http": "^5.3.5", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-nJbLrUj6fY+l2W2rIB9P4Qvpiy0tnTdg/dmixRxrU1z3e8wBdspJlyE+AZN4fuVbeL6rrRrO/zxQC1bB3cw5IA=="], - - "@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.940.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.940.0", "@aws-sdk/middleware-host-header": "3.936.0", "@aws-sdk/middleware-logger": "3.936.0", "@aws-sdk/middleware-recursion-detection": "3.936.0", "@aws-sdk/middleware-user-agent": "3.940.0", "@aws-sdk/region-config-resolver": "3.936.0", "@aws-sdk/types": "3.936.0", "@aws-sdk/util-endpoints": "3.936.0", "@aws-sdk/util-user-agent-browser": "3.936.0", "@aws-sdk/util-user-agent-node": "3.940.0", "@smithy/config-resolver": "^4.4.3", "@smithy/core": "^3.18.5", "@smithy/fetch-http-handler": "^5.3.6", "@smithy/hash-node": "^4.2.5", "@smithy/invalid-dependency": "^4.2.5", "@smithy/middleware-content-length": "^4.2.5", "@smithy/middleware-endpoint": "^4.3.12", "@smithy/middleware-retry": "^4.4.12", "@smithy/middleware-serde": "^4.2.6", "@smithy/middleware-stack": "^4.2.5", "@smithy/node-config-provider": "^4.3.5", "@smithy/node-http-handler": "^4.4.5", "@smithy/protocol-http": "^5.3.5", "@smithy/smithy-client": "^4.9.8", "@smithy/types": "^4.9.0", "@smithy/url-parser": "^4.2.5", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-body-length-node": "^4.2.1", "@smithy/util-defaults-mode-browser": "^4.3.11", "@smithy/util-defaults-mode-node": "^4.2.14", "@smithy/util-endpoints": "^3.2.5", "@smithy/util-middleware": "^4.2.5", "@smithy/util-retry": "^4.2.5", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-x0mdv6DkjXqXEcQj3URbCltEzW6hoy/1uIL+i8gExP6YKrnhiZ7SzuB4gPls2UOpK5UqLiqXjhRLfBb1C9i4Dw=="], - - "@aws-sdk/region-config-resolver": ["@aws-sdk/region-config-resolver@3.936.0", "", { "dependencies": { "@aws-sdk/types": "3.936.0", "@smithy/config-resolver": "^4.4.3", "@smithy/node-config-provider": "^4.3.5", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-wOKhzzWsshXGduxO4pqSiNyL9oUtk4BEvjWm9aaq6Hmfdoydq6v6t0rAGHWPjFwy9z2haovGRi3C8IxdMB4muw=="], - - "@aws-sdk/signature-v4-multi-region": ["@aws-sdk/signature-v4-multi-region@3.940.0", "", { "dependencies": { "@aws-sdk/middleware-sdk-s3": "3.940.0", "@aws-sdk/types": "3.936.0", "@smithy/protocol-http": "^5.3.5", "@smithy/signature-v4": "^5.3.5", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-ugHZEoktD/bG6mdgmhzLDjMP2VrYRAUPRPF1DpCyiZexkH7DCU7XrSJyXMvkcf0DHV+URk0q2sLf/oqn1D2uYw=="], - - "@aws-sdk/token-providers": ["@aws-sdk/token-providers@3.940.0", "", { "dependencies": { "@aws-sdk/core": "3.940.0", "@aws-sdk/nested-clients": "3.940.0", "@aws-sdk/types": "3.936.0", "@smithy/property-provider": "^4.2.5", "@smithy/shared-ini-file-loader": "^4.4.0", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-k5qbRe/ZFjW9oWEdzLIa2twRVIEx7p/9rutofyrRysrtEnYh3HAWCngAnwbgKMoiwa806UzcTRx0TjyEpnKcCg=="], - - "@aws-sdk/types": ["@aws-sdk/types@3.936.0", "", { "dependencies": { "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-uz0/VlMd2pP5MepdrHizd+T+OKfyK4r3OA9JI+L/lPKg0YFQosdJNCKisr6o70E3dh8iMpFYxF1UN/4uZsyARg=="], - - "@aws-sdk/util-arn-parser": ["@aws-sdk/util-arn-parser@3.893.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-u8H4f2Zsi19DGnwj5FSZzDMhytYF/bCh37vAtBsn3cNDL3YG578X5oc+wSX54pM3tOxS+NY7tvOAo52SW7koUA=="], - - "@aws-sdk/util-endpoints": ["@aws-sdk/util-endpoints@3.936.0", "", { "dependencies": { "@aws-sdk/types": "3.936.0", "@smithy/types": "^4.9.0", "@smithy/url-parser": "^4.2.5", "@smithy/util-endpoints": "^3.2.5", "tslib": "^2.6.2" } }, "sha512-0Zx3Ntdpu+z9Wlm7JKUBOzS9EunwKAb4KdGUQQxDqh5Lc3ta5uBoub+FgmVuzwnmBu9U1Os8UuwVTH0Lgu+P5w=="], - - "@aws-sdk/util-locate-window": ["@aws-sdk/util-locate-window@3.965.5", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-WhlJNNINQB+9qtLtZJcpQdgZw3SCDCpXdUJP7cToGwHbCWCnRckGlc6Bx/OhWwIYFNAn+FIydY8SZ0QmVu3xTQ=="], - - "@aws-sdk/util-user-agent-browser": ["@aws-sdk/util-user-agent-browser@3.936.0", "", { "dependencies": { "@aws-sdk/types": "3.936.0", "@smithy/types": "^4.9.0", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "sha512-eZ/XF6NxMtu+iCma58GRNRxSq4lHo6zHQLOZRIeL/ghqYJirqHdenMOwrzPettj60KWlv827RVebP9oNVrwZbw=="], - - "@aws-sdk/util-user-agent-node": ["@aws-sdk/util-user-agent-node@3.940.0", "", { "dependencies": { "@aws-sdk/middleware-user-agent": "3.940.0", "@aws-sdk/types": "3.936.0", "@smithy/node-config-provider": "^4.3.5", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" }, "peerDependencies": { "aws-crt": ">=1.0.0" }, "optionalPeers": ["aws-crt"] }, "sha512-dlD/F+L/jN26I8Zg5x0oDGJiA+/WEQmnSE27fi5ydvYnpfQLwThtQo9SsNS47XSR/SOULaaoC9qx929rZuo74A=="], - - "@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.930.0", "", { "dependencies": { "@smithy/types": "^4.9.0", "fast-xml-parser": "5.2.5", "tslib": "^2.6.2" } }, "sha512-YIfkD17GocxdmlUVc3ia52QhcWuRIUJonbF8A2CYfcWNV3HzvAqpcPeC0bYUhkK+8e8YO1ARnLKZQE0TlwzorA=="], - - "@aws/lambda-invoke-store": ["@aws/lambda-invoke-store@0.2.4", "", {}, "sha512-iY8yvjE0y651BixKNPgmv1WrQc+GZ142sb0z4gYnChDDY2YqI4P/jsSopBWrKfAt7LOJAkOXt7rC/hms+WclQQ=="], - - "@biomejs/biome": ["@biomejs/biome@2.3.8", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "2.3.8", "@biomejs/cli-darwin-x64": "2.3.8", "@biomejs/cli-linux-arm64": "2.3.8", "@biomejs/cli-linux-arm64-musl": "2.3.8", "@biomejs/cli-linux-x64": "2.3.8", "@biomejs/cli-linux-x64-musl": "2.3.8", "@biomejs/cli-win32-arm64": "2.3.8", "@biomejs/cli-win32-x64": "2.3.8" }, "bin": { "biome": "bin/biome" } }, "sha512-Qjsgoe6FEBxWAUzwFGFrB+1+M8y/y5kwmg5CHac+GSVOdmOIqsAiXM5QMVGZJ1eCUCLlPZtq4aFAQ0eawEUuUA=="], - - "@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@2.3.8", "", { "os": "darwin", "cpu": "arm64" }, "sha512-HM4Zg9CGQ3txTPflxD19n8MFPrmUAjaC7PQdLkugeeC0cQ+PiVrd7i09gaBS/11QKsTDBJhVg85CEIK9f50Qww=="], - - "@biomejs/cli-darwin-x64": ["@biomejs/cli-darwin-x64@2.3.8", "", { "os": "darwin", "cpu": "x64" }, "sha512-lUDQ03D7y/qEao7RgdjWVGCu+BLYadhKTm40HkpJIi6kn8LSv5PAwRlew/DmwP4YZ9ke9XXoTIQDO1vAnbRZlA=="], - - "@biomejs/cli-linux-arm64": ["@biomejs/cli-linux-arm64@2.3.8", "", { "os": "linux", "cpu": "arm64" }, "sha512-Uo1OJnIkJgSgF+USx970fsM/drtPcQ39I+JO+Fjsaa9ZdCN1oysQmy6oAGbyESlouz+rzEckLTF6DS7cWse95g=="], - - "@biomejs/cli-linux-arm64-musl": ["@biomejs/cli-linux-arm64-musl@2.3.8", "", { "os": "linux", "cpu": "arm64" }, "sha512-PShR4mM0sjksUMyxbyPNMxoKFPVF48fU8Qe8Sfx6w6F42verbwRLbz+QiKNiDPRJwUoMG1nPM50OBL3aOnTevA=="], - - "@biomejs/cli-linux-x64": ["@biomejs/cli-linux-x64@2.3.8", "", { "os": "linux", "cpu": "x64" }, "sha512-QDPMD5bQz6qOVb3kiBui0zKZXASLo0NIQ9JVJio5RveBEFgDgsvJFUvZIbMbUZT3T00M/1wdzwWXk4GIh0KaAw=="], - - "@biomejs/cli-linux-x64-musl": ["@biomejs/cli-linux-x64-musl@2.3.8", "", { "os": "linux", "cpu": "x64" }, "sha512-YGLkqU91r1276uwSjiUD/xaVikdxgV1QpsicT0bIA1TaieM6E5ibMZeSyjQ/izBn4tKQthUSsVZacmoJfa3pDA=="], - - "@biomejs/cli-win32-arm64": ["@biomejs/cli-win32-arm64@2.3.8", "", { "os": "win32", "cpu": "arm64" }, "sha512-H4IoCHvL1fXKDrTALeTKMiE7GGWFAraDwBYFquE/L/5r1927Te0mYIGseXi4F+lrrwhSWbSGt5qPFswNoBaCxg=="], - - "@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@2.3.8", "", { "os": "win32", "cpu": "x64" }, "sha512-RguzimPoZWtBapfKhKjcWXBVI91tiSprqdBYu7tWhgN8pKRZhw24rFeNZTNf6UiBfjCYCi9eFQs/JzJZIhuK4w=="], - - "@emnapi/runtime": ["@emnapi/runtime@1.9.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-VYi5+ZVLhpgK4hQ0TAjiQiZ6ol0oe4mBx7mVv7IflsiEp0OWoVsp/+f9Vc1hOhE0TtkORVrI1GvzyreqpgWtkA=="], - - "@img/colour": ["@img/colour@1.1.0", "", {}, "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ=="], - - "@img/sharp-darwin-arm64": ["@img/sharp-darwin-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-arm64": "1.2.4" }, "os": "darwin", "cpu": "arm64" }, "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w=="], - - "@img/sharp-darwin-x64": ["@img/sharp-darwin-x64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-x64": "1.2.4" }, "os": "darwin", "cpu": "x64" }, "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw=="], - - "@img/sharp-libvips-darwin-arm64": ["@img/sharp-libvips-darwin-arm64@1.2.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g=="], - - "@img/sharp-libvips-darwin-x64": ["@img/sharp-libvips-darwin-x64@1.2.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg=="], - - "@img/sharp-libvips-linux-arm": ["@img/sharp-libvips-linux-arm@1.2.4", "", { "os": "linux", "cpu": "arm" }, "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A=="], - - "@img/sharp-libvips-linux-arm64": ["@img/sharp-libvips-linux-arm64@1.2.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw=="], - - "@img/sharp-libvips-linux-ppc64": ["@img/sharp-libvips-linux-ppc64@1.2.4", "", { "os": "linux", "cpu": "ppc64" }, "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA=="], - - "@img/sharp-libvips-linux-riscv64": ["@img/sharp-libvips-linux-riscv64@1.2.4", "", { "os": "linux", "cpu": "none" }, "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA=="], - - "@img/sharp-libvips-linux-s390x": ["@img/sharp-libvips-linux-s390x@1.2.4", "", { "os": "linux", "cpu": "s390x" }, "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ=="], - - "@img/sharp-libvips-linux-x64": ["@img/sharp-libvips-linux-x64@1.2.4", "", { "os": "linux", "cpu": "x64" }, "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw=="], - - "@img/sharp-libvips-linuxmusl-arm64": ["@img/sharp-libvips-linuxmusl-arm64@1.2.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw=="], - - "@img/sharp-libvips-linuxmusl-x64": ["@img/sharp-libvips-linuxmusl-x64@1.2.4", "", { "os": "linux", "cpu": "x64" }, "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg=="], - - "@img/sharp-linux-arm": ["@img/sharp-linux-arm@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm": "1.2.4" }, "os": "linux", "cpu": "arm" }, "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw=="], - - "@img/sharp-linux-arm64": ["@img/sharp-linux-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm64": "1.2.4" }, "os": "linux", "cpu": "arm64" }, "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg=="], - - "@img/sharp-linux-ppc64": ["@img/sharp-linux-ppc64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-ppc64": "1.2.4" }, "os": "linux", "cpu": "ppc64" }, "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA=="], - - "@img/sharp-linux-riscv64": ["@img/sharp-linux-riscv64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-riscv64": "1.2.4" }, "os": "linux", "cpu": "none" }, "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw=="], - - "@img/sharp-linux-s390x": ["@img/sharp-linux-s390x@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-s390x": "1.2.4" }, "os": "linux", "cpu": "s390x" }, "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg=="], - - "@img/sharp-linux-x64": ["@img/sharp-linux-x64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-x64": "1.2.4" }, "os": "linux", "cpu": "x64" }, "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ=="], - - "@img/sharp-linuxmusl-arm64": ["@img/sharp-linuxmusl-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-arm64": "1.2.4" }, "os": "linux", "cpu": "arm64" }, "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg=="], - - "@img/sharp-linuxmusl-x64": ["@img/sharp-linuxmusl-x64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-x64": "1.2.4" }, "os": "linux", "cpu": "x64" }, "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q=="], - - "@img/sharp-wasm32": ["@img/sharp-wasm32@0.34.5", "", { "dependencies": { "@emnapi/runtime": "^1.7.0" }, "cpu": "none" }, "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw=="], - - "@img/sharp-win32-arm64": ["@img/sharp-win32-arm64@0.34.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g=="], - - "@img/sharp-win32-ia32": ["@img/sharp-win32-ia32@0.34.5", "", { "os": "win32", "cpu": "ia32" }, "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg=="], - - "@img/sharp-win32-x64": ["@img/sharp-win32-x64@0.34.5", "", { "os": "win32", "cpu": "x64" }, "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw=="], - - "@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.13", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA=="], - - "@jridgewell/remapping": ["@jridgewell/remapping@2.3.5", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ=="], - - "@jridgewell/resolve-uri": ["@jridgewell/resolve-uri@3.1.2", "", {}, "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="], - - "@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="], - - "@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="], - - "@next/env": ["@next/env@16.0.7", "", {}, "sha512-gpaNgUh5nftFKRkRQGnVi5dpcYSKGcZZkQffZ172OrG/XkrnS7UBTQ648YY+8ME92cC4IojpI2LqTC8sTDhAaw=="], - - "@next/swc-darwin-arm64": ["@next/swc-darwin-arm64@16.0.7", "", { "os": "darwin", "cpu": "arm64" }, "sha512-LlDtCYOEj/rfSnEn/Idi+j1QKHxY9BJFmxx7108A6D8K0SB+bNgfYQATPk/4LqOl4C0Wo3LACg2ie6s7xqMpJg=="], - - "@next/swc-darwin-x64": ["@next/swc-darwin-x64@16.0.7", "", { "os": "darwin", "cpu": "x64" }, "sha512-rtZ7BhnVvO1ICf3QzfW9H3aPz7GhBrnSIMZyr4Qy6boXF0b5E3QLs+cvJmg3PsTCG2M1PBoC+DANUi4wCOKXpA=="], - - "@next/swc-linux-arm64-gnu": ["@next/swc-linux-arm64-gnu@16.0.7", "", { "os": "linux", "cpu": "arm64" }, "sha512-mloD5WcPIeIeeZqAIP5c2kdaTa6StwP4/2EGy1mUw8HiexSHGK/jcM7lFuS3u3i2zn+xH9+wXJs6njO7VrAqww=="], - - "@next/swc-linux-arm64-musl": ["@next/swc-linux-arm64-musl@16.0.7", "", { "os": "linux", "cpu": "arm64" }, "sha512-+ksWNrZrthisXuo9gd1XnjHRowCbMtl/YgMpbRvFeDEqEBd523YHPWpBuDjomod88U8Xliw5DHhekBC3EOOd9g=="], - - "@next/swc-linux-x64-gnu": ["@next/swc-linux-x64-gnu@16.0.7", "", { "os": "linux", "cpu": "x64" }, "sha512-4WtJU5cRDxpEE44Ana2Xro1284hnyVpBb62lIpU5k85D8xXxatT+rXxBgPkc7C1XwkZMWpK5rXLXTh9PFipWsA=="], - - "@next/swc-linux-x64-musl": ["@next/swc-linux-x64-musl@16.0.7", "", { "os": "linux", "cpu": "x64" }, "sha512-HYlhqIP6kBPXalW2dbMTSuB4+8fe+j9juyxwfMwCe9kQPPeiyFn7NMjNfoFOfJ2eXkeQsoUGXg+O2SE3m4Qg2w=="], - - "@next/swc-win32-arm64-msvc": ["@next/swc-win32-arm64-msvc@16.0.7", "", { "os": "win32", "cpu": "arm64" }, "sha512-EviG+43iOoBRZg9deGauXExjRphhuYmIOJ12b9sAPy0eQ6iwcPxfED2asb/s2/yiLYOdm37kPaiZu8uXSYPs0Q=="], - - "@next/swc-win32-x64-msvc": ["@next/swc-win32-x64-msvc@16.0.7", "", { "os": "win32", "cpu": "x64" }, "sha512-gniPjy55zp5Eg0896qSrf3yB1dw4F/3s8VK1ephdsZZ129j2n6e1WqCbE2YgcKhW9hPB9TVZENugquWJD5x0ug=="], - - "@noble/ciphers": ["@noble/ciphers@1.3.0", "", {}, "sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw=="], - - "@noble/curves": ["@noble/curves@1.9.1", "", { "dependencies": { "@noble/hashes": "1.8.0" } }, "sha512-k11yZxZg+t+gWvBbIswW0yoJlu8cHOC7dhunwOzoWH/mXGBiYyR4YY6hAEK/3EUs4UpB8la1RfdRpeGsFHkWsA=="], - - "@noble/hashes": ["@noble/hashes@1.8.0", "", {}, "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A=="], - - "@scure/base": ["@scure/base@1.2.6", "", {}, "sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg=="], - - "@scure/bip32": ["@scure/bip32@1.7.0", "", { "dependencies": { "@noble/curves": "~1.9.0", "@noble/hashes": "~1.8.0", "@scure/base": "~1.2.5" } }, "sha512-E4FFX/N3f4B80AKWp5dP6ow+flD1LQZo/w8UnLGYZO674jS6YnYeepycOOksv+vLPSpgN35wgKgy+ybfTb2SMw=="], - - "@scure/bip39": ["@scure/bip39@1.6.0", "", { "dependencies": { "@noble/hashes": "~1.8.0", "@scure/base": "~1.2.5" } }, "sha512-+lF0BbLiJNwVlev4eKelw1WWLaiKXw7sSl8T6FvBlWkdX+94aGJ4o8XjUdlyhTCjd8c+B3KT3JfS8P0bLRNU6A=="], - - "@smithy/abort-controller": ["@smithy/abort-controller@4.2.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-xolrFw6b+2iYGl6EcOL7IJY71vvyZ0DJ3mcKtpykqPe2uscwtzDZJa1uVQXyP7w9Dd+kGwYnPbMsJrGISKiY/Q=="], - - "@smithy/chunked-blob-reader": ["@smithy/chunked-blob-reader@5.2.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-St+kVicSyayWQca+I1rGitaOEH6uKgE8IUWoYnnEX26SWdWQcL6LvMSD19Lg+vYHKdT9B2Zuu7rd3i6Wnyb/iw=="], - - "@smithy/chunked-blob-reader-native": ["@smithy/chunked-blob-reader-native@4.2.3", "", { "dependencies": { "@smithy/util-base64": "^4.3.2", "tslib": "^2.6.2" } }, "sha512-jA5k5Udn7Y5717L86h4EIv06wIr3xn8GM1qHRi/Nf31annXcXHJjBKvgztnbn2TxH3xWrPBfgwHsOwZf0UmQWw=="], - - "@smithy/config-resolver": ["@smithy/config-resolver@4.4.13", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.12", "@smithy/types": "^4.13.1", "@smithy/util-config-provider": "^4.2.2", "@smithy/util-endpoints": "^3.3.3", "@smithy/util-middleware": "^4.2.12", "tslib": "^2.6.2" } }, "sha512-iIzMC5NmOUP6WL6o8iPBjFhUhBZ9pPjpUpQYWMUFQqKyXXzOftbfK8zcQCz/jFV1Psmf05BK5ypx4K2r4Tnwdg=="], - - "@smithy/core": ["@smithy/core@3.23.12", "", { "dependencies": { "@smithy/protocol-http": "^5.3.12", "@smithy/types": "^4.13.1", "@smithy/url-parser": "^4.2.12", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-middleware": "^4.2.12", "@smithy/util-stream": "^4.5.20", "@smithy/util-utf8": "^4.2.2", "@smithy/uuid": "^1.1.2", "tslib": "^2.6.2" } }, "sha512-o9VycsYNtgC+Dy3I0yrwCqv9CWicDnke0L7EVOrZtJpjb2t0EjaEofmMrYc0T1Kn3yk32zm6cspxF9u9Bj7e5w=="], - - "@smithy/credential-provider-imds": ["@smithy/credential-provider-imds@4.2.12", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.12", "@smithy/property-provider": "^4.2.12", "@smithy/types": "^4.13.1", "@smithy/url-parser": "^4.2.12", "tslib": "^2.6.2" } }, "sha512-cr2lR792vNZcYMriSIj+Um3x9KWrjcu98kn234xA6reOAFMmbRpQMOv8KPgEmLLtx3eldU6c5wALKFqNOhugmg=="], - - "@smithy/eventstream-codec": ["@smithy/eventstream-codec@4.2.12", "", { "dependencies": { "@aws-crypto/crc32": "5.2.0", "@smithy/types": "^4.13.1", "@smithy/util-hex-encoding": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-FE3bZdEl62ojmy8x4FHqxq2+BuOHlcxiH5vaZ6aqHJr3AIZzwF5jfx8dEiU/X0a8RboyNDjmXjlbr8AdEyLgiA=="], - - "@smithy/eventstream-serde-browser": ["@smithy/eventstream-serde-browser@4.2.12", "", { "dependencies": { "@smithy/eventstream-serde-universal": "^4.2.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-XUSuMxlTxV5pp4VpqZf6Sa3vT/Q75FVkLSpSSE3KkWBvAQWeuWt1msTv8fJfgA4/jcJhrbrbMzN1AC/hvPmm5A=="], - - "@smithy/eventstream-serde-config-resolver": ["@smithy/eventstream-serde-config-resolver@4.3.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-7epsAZ3QvfHkngz6RXQYseyZYHlmWXSTPOfPmXkiS+zA6TBNo1awUaMFL9vxyXlGdoELmCZyZe1nQE+imbmV+Q=="], - - "@smithy/eventstream-serde-node": ["@smithy/eventstream-serde-node@4.2.12", "", { "dependencies": { "@smithy/eventstream-serde-universal": "^4.2.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-D1pFuExo31854eAvg89KMn9Oab/wEeJR6Buy32B49A9Ogdtx5fwZPqBHUlDzaCDpycTFk2+fSQgX689Qsk7UGA=="], - - "@smithy/eventstream-serde-universal": ["@smithy/eventstream-serde-universal@4.2.12", "", { "dependencies": { "@smithy/eventstream-codec": "^4.2.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-+yNuTiyBACxOJUTvbsNsSOfH9G9oKbaJE1lNL3YHpGcuucl6rPZMi3nrpehpVOVR2E07YqFFmtwpImtpzlouHQ=="], - - "@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.3.15", "", { "dependencies": { "@smithy/protocol-http": "^5.3.12", "@smithy/querystring-builder": "^4.2.12", "@smithy/types": "^4.13.1", "@smithy/util-base64": "^4.3.2", "tslib": "^2.6.2" } }, "sha512-T4jFU5N/yiIfrtrsb9uOQn7RdELdM/7HbyLNr6uO/mpkj1ctiVs7CihVr51w4LyQlXWDpXFn4BElf1WmQvZu/A=="], - - "@smithy/hash-blob-browser": ["@smithy/hash-blob-browser@4.2.13", "", { "dependencies": { "@smithy/chunked-blob-reader": "^5.2.2", "@smithy/chunked-blob-reader-native": "^4.2.3", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-YrF4zWKh+ghLuquldj6e/RzE3xZYL8wIPfkt0MqCRphVICjyyjH8OwKD7LLlKpVEbk4FLizFfC1+gwK6XQdR3g=="], - - "@smithy/hash-node": ["@smithy/hash-node@4.2.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "@smithy/util-buffer-from": "^4.2.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-QhBYbGrbxTkZ43QoTPrK72DoYviDeg6YKDrHTMJbbC+A0sml3kSjzFtXP7BtbyJnXojLfTQldGdUR0RGD8dA3w=="], - - "@smithy/hash-stream-node": ["@smithy/hash-stream-node@4.2.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-O3YbmGExeafuM/kP7Y8r6+1y0hIh3/zn6GROx0uNlB54K9oihAL75Qtc+jFfLNliTi6pxOAYZrRKD9A7iA6UFw=="], - - "@smithy/invalid-dependency": ["@smithy/invalid-dependency@4.2.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-/4F1zb7Z8LOu1PalTdESFHR0RbPwHd3FcaG1sI3UEIriQTWakysgJr65lc1jj6QY5ye7aFsisajotH6UhWfm/g=="], - - "@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-n6rQ4N8Jj4YTQO3YFrlgZuwKodf4zUFs7EJIWH86pSCWBaAtAGBFfCM7Wx6D2bBJ2xqFNxGBSrUWswT3M0VJow=="], - - "@smithy/md5-js": ["@smithy/md5-js@4.2.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-W/oIpHCpWU2+iAkfZYyGWE+qkpuf3vEXHLxQQDx9FPNZTTdnul0dZ2d/gUFrtQ5je1G2kp4cjG0/24YueG2LbQ=="], - - "@smithy/middleware-content-length": ["@smithy/middleware-content-length@4.2.12", "", { "dependencies": { "@smithy/protocol-http": "^5.3.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-YE58Yz+cvFInWI/wOTrB+DbvUVz/pLn5mC5MvOV4fdRUc6qGwygyngcucRQjAhiCEbmfLOXX0gntSIcgMvAjmA=="], - - "@smithy/middleware-endpoint": ["@smithy/middleware-endpoint@4.4.27", "", { "dependencies": { "@smithy/core": "^3.23.12", "@smithy/middleware-serde": "^4.2.15", "@smithy/node-config-provider": "^4.3.12", "@smithy/shared-ini-file-loader": "^4.4.7", "@smithy/types": "^4.13.1", "@smithy/url-parser": "^4.2.12", "@smithy/util-middleware": "^4.2.12", "tslib": "^2.6.2" } }, "sha512-T3TFfUgXQlpcg+UdzcAISdZpj4Z+XECZ/cefgA6wLBd6V4lRi0svN2hBouN/be9dXQ31X4sLWz3fAQDf+nt6BA=="], - - "@smithy/middleware-retry": ["@smithy/middleware-retry@4.4.44", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.12", "@smithy/protocol-http": "^5.3.12", "@smithy/service-error-classification": "^4.2.12", "@smithy/smithy-client": "^4.12.7", "@smithy/types": "^4.13.1", "@smithy/util-middleware": "^4.2.12", "@smithy/util-retry": "^4.2.12", "@smithy/uuid": "^1.1.2", "tslib": "^2.6.2" } }, "sha512-Y1Rav7m5CFRPQyM4CI0koD/bXjyjJu3EQxZZhtLGD88WIrBrQ7kqXM96ncd6rYnojwOo/u9MXu57JrEvu/nLrA=="], - - "@smithy/middleware-serde": ["@smithy/middleware-serde@4.2.15", "", { "dependencies": { "@smithy/core": "^3.23.12", "@smithy/protocol-http": "^5.3.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-ExYhcltZSli0pgAKOpQQe1DLFBLryeZ22605y/YS+mQpdNWekum9Ujb/jMKfJKgjtz1AZldtwA/wCYuKJgjjlg=="], - - "@smithy/middleware-stack": ["@smithy/middleware-stack@4.2.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-kruC5gRHwsCOuyCd4ouQxYjgRAym2uDlCvQ5acuMtRrcdfg7mFBg6blaxcJ09STpt3ziEkis6bhg1uwrWU7txw=="], - - "@smithy/node-config-provider": ["@smithy/node-config-provider@4.3.12", "", { "dependencies": { "@smithy/property-provider": "^4.2.12", "@smithy/shared-ini-file-loader": "^4.4.7", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-tr2oKX2xMcO+rBOjobSwVAkV05SIfUKz8iI53rzxEmgW3GOOPOv0UioSDk+J8OpRQnpnhsO3Af6IEBabQBVmiw=="], - - "@smithy/node-http-handler": ["@smithy/node-http-handler@4.5.0", "", { "dependencies": { "@smithy/abort-controller": "^4.2.12", "@smithy/protocol-http": "^5.3.12", "@smithy/querystring-builder": "^4.2.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-Rnq9vQWiR1+/I6NZZMNzJHV6pZYyEHt2ZnuV3MG8z2NNenC4i/8Kzttz7CjZiHSmsN5frhXhg17z3Zqjjhmz1A=="], - - "@smithy/property-provider": ["@smithy/property-provider@4.2.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-jqve46eYU1v7pZ5BM+fmkbq3DerkSluPr5EhvOcHxygxzD05ByDRppRwRPPpFrsFo5yDtCYLKu+kreHKVrvc7A=="], - - "@smithy/protocol-http": ["@smithy/protocol-http@5.3.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-fit0GZK9I1xoRlR4jXmbLhoN0OdEpa96ul8M65XdmXnxXkuMxM0Y8HDT0Fh0Xb4I85MBvBClOzgSrV1X2s1Hxw=="], - - "@smithy/querystring-builder": ["@smithy/querystring-builder@4.2.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "@smithy/util-uri-escape": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-6wTZjGABQufekycfDGMEB84BgtdOE/rCVTov+EDXQ8NHKTUNIp/j27IliwP7tjIU9LR+sSzyGBOXjeEtVgzCHg=="], - - "@smithy/querystring-parser": ["@smithy/querystring-parser@4.2.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-P2OdvrgiAKpkPNKlKUtWbNZKB1XjPxM086NeVhK+W+wI46pIKdWBe5QyXvhUm3MEcyS/rkLvY8rZzyUdmyDZBw=="], - - "@smithy/service-error-classification": ["@smithy/service-error-classification@4.2.12", "", { "dependencies": { "@smithy/types": "^4.13.1" } }, "sha512-LlP29oSQN0Tw0b6D0Xo6BIikBswuIiGYbRACy5ujw/JgWSzTdYj46U83ssf6Ux0GyNJVivs2uReU8pt7Eu9okQ=="], - - "@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.4.7", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-HrOKWsUb+otTeo1HxVWeEb99t5ER1XrBi/xka2Wv6NVmTbuCUC1dvlrksdvxFtODLBjsC+PHK+fuy2x/7Ynyiw=="], - - "@smithy/signature-v4": ["@smithy/signature-v4@5.3.12", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.2", "@smithy/protocol-http": "^5.3.12", "@smithy/types": "^4.13.1", "@smithy/util-hex-encoding": "^4.2.2", "@smithy/util-middleware": "^4.2.12", "@smithy/util-uri-escape": "^4.2.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-B/FBwO3MVOL00DaRSXfXfa/TRXRheagt/q5A2NM13u7q+sHS59EOVGQNfG7DkmVtdQm5m3vOosoKAXSqn/OEgw=="], - - "@smithy/smithy-client": ["@smithy/smithy-client@4.12.7", "", { "dependencies": { "@smithy/core": "^3.23.12", "@smithy/middleware-endpoint": "^4.4.27", "@smithy/middleware-stack": "^4.2.12", "@smithy/protocol-http": "^5.3.12", "@smithy/types": "^4.13.1", "@smithy/util-stream": "^4.5.20", "tslib": "^2.6.2" } }, "sha512-q3gqnwml60G44FECaEEsdQMplYhDMZYCtYhMCzadCnRnnHIobZJjegmdoUo6ieLQlPUzvrMdIJUpx6DoPmzANQ=="], - - "@smithy/types": ["@smithy/types@4.13.1", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-787F3yzE2UiJIQ+wYW1CVg2odHjmaWLGksnKQHUrK/lYZSEcy1msuLVvxaR/sI2/aDe9U+TBuLsXnr3vod1g0g=="], - - "@smithy/url-parser": ["@smithy/url-parser@4.2.12", "", { "dependencies": { "@smithy/querystring-parser": "^4.2.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-wOPKPEpso+doCZGIlr+e1lVI6+9VAKfL4kZWFgzVgGWY2hZxshNKod4l2LXS3PRC9otH/JRSjtEHqQ/7eLciRA=="], - - "@smithy/util-base64": ["@smithy/util-base64@4.3.2", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-XRH6b0H/5A3SgblmMa5ErXQ2XKhfbQB+Fm/oyLZ2O2kCUrwgg55bU0RekmzAhuwOjA9qdN5VU2BprOvGGUkOOQ=="], - - "@smithy/util-body-length-browser": ["@smithy/util-body-length-browser@4.2.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-JKCrLNOup3OOgmzeaKQwi4ZCTWlYR5H4Gm1r2uTMVBXoemo1UEghk5vtMi1xSu2ymgKVGW631e2fp9/R610ZjQ=="], - - "@smithy/util-body-length-node": ["@smithy/util-body-length-node@4.2.3", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-ZkJGvqBzMHVHE7r/hcuCxlTY8pQr1kMtdsVPs7ex4mMU+EAbcXppfo5NmyxMYi2XU49eqaz56j2gsk4dHHPG/g=="], - - "@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.2", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-FDXD7cvUoFWwN6vtQfEta540Y/YBe5JneK3SoZg9bThSoOAC/eGeYEua6RkBgKjGa/sz6Y+DuBZj3+YEY21y4Q=="], - - "@smithy/util-config-provider": ["@smithy/util-config-provider@4.2.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-dWU03V3XUprJwaUIFVv4iOnS1FC9HnMHDfUrlNDSh4315v0cWyaIErP8KiqGVbf5z+JupoVpNM7ZB3jFiTejvQ=="], - - "@smithy/util-defaults-mode-browser": ["@smithy/util-defaults-mode-browser@4.3.43", "", { "dependencies": { "@smithy/property-provider": "^4.2.12", "@smithy/smithy-client": "^4.12.7", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-Qd/0wCKMaXxev/z00TvNzGCH2jlKKKxXP1aDxB6oKwSQthe3Og2dMhSayGCnsma1bK/kQX1+X7SMP99t6FgiiQ=="], - - "@smithy/util-defaults-mode-node": ["@smithy/util-defaults-mode-node@4.2.47", "", { "dependencies": { "@smithy/config-resolver": "^4.4.13", "@smithy/credential-provider-imds": "^4.2.12", "@smithy/node-config-provider": "^4.3.12", "@smithy/property-provider": "^4.2.12", "@smithy/smithy-client": "^4.12.7", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-qSRbYp1EQ7th+sPFuVcVO05AE0QH635hycdEXlpzIahqHHf2Fyd/Zl+8v0XYMJ3cgDVPa0lkMefU7oNUjAP+DQ=="], - - "@smithy/util-endpoints": ["@smithy/util-endpoints@3.3.3", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-VACQVe50j0HZPjpwWcjyT51KUQ4AnsvEaQ2lKHOSL4mNLD0G9BjEniQ+yCt1qqfKfiAHRAts26ud7hBjamrwig=="], - - "@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-Qcz3W5vuHK4sLQdyT93k/rfrUwdJ8/HZ+nMUOyGdpeGA1Wxt65zYwi3oEl9kOM+RswvYq90fzkNDahPS8K0OIg=="], - - "@smithy/util-middleware": ["@smithy/util-middleware@4.2.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-Er805uFUOvgc0l8nv0e0su0VFISoxhJ/AwOn3gL2NWNY2LUEldP5WtVcRYSQBcjg0y9NfG8JYrCJaYDpupBHJQ=="], - - "@smithy/util-retry": ["@smithy/util-retry@4.2.12", "", { "dependencies": { "@smithy/service-error-classification": "^4.2.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-1zopLDUEOwumjcHdJ1mwBHddubYF8GMQvstVCLC54Y46rqoHwlIU+8ZzUeaBcD+WCJHyDGSeZ2ml9YSe9aqcoQ=="], - - "@smithy/util-stream": ["@smithy/util-stream@4.5.20", "", { "dependencies": { "@smithy/fetch-http-handler": "^5.3.15", "@smithy/node-http-handler": "^4.5.0", "@smithy/types": "^4.13.1", "@smithy/util-base64": "^4.3.2", "@smithy/util-buffer-from": "^4.2.2", "@smithy/util-hex-encoding": "^4.2.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-4yXLm5n/B5SRBR2p8cZ90Sbv4zL4NKsgxdzCzp/83cXw2KxLEumt5p+GAVyRNZgQOSrzXn9ARpO0lUe8XSlSDw=="], - - "@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-2kAStBlvq+lTXHyAZYfJRb/DfS3rsinLiwb+69SstC9Vb0s9vNWkRwpnj918Pfi85mzi42sOqdV72OLxWAISnw=="], - - "@smithy/util-utf8": ["@smithy/util-utf8@4.2.2", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw=="], - - "@smithy/util-waiter": ["@smithy/util-waiter@4.2.13", "", { "dependencies": { "@smithy/abort-controller": "^4.2.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-2zdZ9DTHngRtcYxJK1GUDxruNr53kv5W2Lupe0LMU+Imr6ohQg8M2T14MNkj1Y0wS3FFwpgpGQyvuaMF7CiTmQ=="], - - "@smithy/uuid": ["@smithy/uuid@1.1.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-O/IEdcCUKkubz60tFbGA7ceITTAJsty+lBjNoorP4Z6XRqaFb/OjQjZODophEcuq68nKm6/0r+6/lLQ+XVpk8g=="], - - "@swc/helpers": ["@swc/helpers@0.5.15", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g=="], - - "@tailwindcss/node": ["@tailwindcss/node@4.1.17", "", { "dependencies": { "@jridgewell/remapping": "^2.3.4", "enhanced-resolve": "^5.18.3", "jiti": "^2.6.1", "lightningcss": "1.30.2", "magic-string": "^0.30.21", "source-map-js": "^1.2.1", "tailwindcss": "4.1.17" } }, "sha512-csIkHIgLb3JisEFQ0vxr2Y57GUNYh447C8xzwj89U/8fdW8LhProdxvnVH6U8M2Y73QKiTIH+LWbK3V2BBZsAg=="], - - "@tailwindcss/oxide": ["@tailwindcss/oxide@4.1.17", "", { "optionalDependencies": { "@tailwindcss/oxide-android-arm64": "4.1.17", "@tailwindcss/oxide-darwin-arm64": "4.1.17", "@tailwindcss/oxide-darwin-x64": "4.1.17", "@tailwindcss/oxide-freebsd-x64": "4.1.17", "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.17", "@tailwindcss/oxide-linux-arm64-gnu": "4.1.17", "@tailwindcss/oxide-linux-arm64-musl": "4.1.17", "@tailwindcss/oxide-linux-x64-gnu": "4.1.17", "@tailwindcss/oxide-linux-x64-musl": "4.1.17", "@tailwindcss/oxide-wasm32-wasi": "4.1.17", "@tailwindcss/oxide-win32-arm64-msvc": "4.1.17", "@tailwindcss/oxide-win32-x64-msvc": "4.1.17" } }, "sha512-F0F7d01fmkQhsTjXezGBLdrl1KresJTcI3DB8EkScCldyKp3Msz4hub4uyYaVnk88BAS1g5DQjjF6F5qczheLA=="], - - "@tailwindcss/oxide-android-arm64": ["@tailwindcss/oxide-android-arm64@4.1.17", "", { "os": "android", "cpu": "arm64" }, "sha512-BMqpkJHgOZ5z78qqiGE6ZIRExyaHyuxjgrJ6eBO5+hfrfGkuya0lYfw8fRHG77gdTjWkNWEEm+qeG2cDMxArLQ=="], - - "@tailwindcss/oxide-darwin-arm64": ["@tailwindcss/oxide-darwin-arm64@4.1.17", "", { "os": "darwin", "cpu": "arm64" }, "sha512-EquyumkQweUBNk1zGEU/wfZo2qkp/nQKRZM8bUYO0J+Lums5+wl2CcG1f9BgAjn/u9pJzdYddHWBiFXJTcxmOg=="], - - "@tailwindcss/oxide-darwin-x64": ["@tailwindcss/oxide-darwin-x64@4.1.17", "", { "os": "darwin", "cpu": "x64" }, "sha512-gdhEPLzke2Pog8s12oADwYu0IAw04Y2tlmgVzIN0+046ytcgx8uZmCzEg4VcQh+AHKiS7xaL8kGo/QTiNEGRog=="], - - "@tailwindcss/oxide-freebsd-x64": ["@tailwindcss/oxide-freebsd-x64@4.1.17", "", { "os": "freebsd", "cpu": "x64" }, "sha512-hxGS81KskMxML9DXsaXT1H0DyA+ZBIbyG/sSAjWNe2EDl7TkPOBI42GBV3u38itzGUOmFfCzk1iAjDXds8Oh0g=="], - - "@tailwindcss/oxide-linux-arm-gnueabihf": ["@tailwindcss/oxide-linux-arm-gnueabihf@4.1.17", "", { "os": "linux", "cpu": "arm" }, "sha512-k7jWk5E3ldAdw0cNglhjSgv501u7yrMf8oeZ0cElhxU6Y2o7f8yqelOp3fhf7evjIS6ujTI3U8pKUXV2I4iXHQ=="], - - "@tailwindcss/oxide-linux-arm64-gnu": ["@tailwindcss/oxide-linux-arm64-gnu@4.1.17", "", { "os": "linux", "cpu": "arm64" }, "sha512-HVDOm/mxK6+TbARwdW17WrgDYEGzmoYayrCgmLEw7FxTPLcp/glBisuyWkFz/jb7ZfiAXAXUACfyItn+nTgsdQ=="], - - "@tailwindcss/oxide-linux-arm64-musl": ["@tailwindcss/oxide-linux-arm64-musl@4.1.17", "", { "os": "linux", "cpu": "arm64" }, "sha512-HvZLfGr42i5anKtIeQzxdkw/wPqIbpeZqe7vd3V9vI3RQxe3xU1fLjss0TjyhxWcBaipk7NYwSrwTwK1hJARMg=="], - - "@tailwindcss/oxide-linux-x64-gnu": ["@tailwindcss/oxide-linux-x64-gnu@4.1.17", "", { "os": "linux", "cpu": "x64" }, "sha512-M3XZuORCGB7VPOEDH+nzpJ21XPvK5PyjlkSFkFziNHGLc5d6g3di2McAAblmaSUNl8IOmzYwLx9NsE7bplNkwQ=="], - - "@tailwindcss/oxide-linux-x64-musl": ["@tailwindcss/oxide-linux-x64-musl@4.1.17", "", { "os": "linux", "cpu": "x64" }, "sha512-k7f+pf9eXLEey4pBlw+8dgfJHY4PZ5qOUFDyNf7SI6lHjQ9Zt7+NcscjpwdCEbYi6FI5c2KDTDWyf2iHcCSyyQ=="], - - "@tailwindcss/oxide-wasm32-wasi": ["@tailwindcss/oxide-wasm32-wasi@4.1.17", "", { "dependencies": { "@emnapi/core": "^1.6.0", "@emnapi/runtime": "^1.6.0", "@emnapi/wasi-threads": "^1.1.0", "@napi-rs/wasm-runtime": "^1.0.7", "@tybys/wasm-util": "^0.10.1", "tslib": "^2.4.0" }, "cpu": "none" }, "sha512-cEytGqSSoy7zK4JRWiTCx43FsKP/zGr0CsuMawhH67ONlH+T79VteQeJQRO/X7L0juEUA8ZyuYikcRBf0vsxhg=="], - - "@tailwindcss/oxide-win32-arm64-msvc": ["@tailwindcss/oxide-win32-arm64-msvc@4.1.17", "", { "os": "win32", "cpu": "arm64" }, "sha512-JU5AHr7gKbZlOGvMdb4722/0aYbU+tN6lv1kONx0JK2cGsh7g148zVWLM0IKR3NeKLv+L90chBVYcJ8uJWbC9A=="], - - "@tailwindcss/oxide-win32-x64-msvc": ["@tailwindcss/oxide-win32-x64-msvc@4.1.17", "", { "os": "win32", "cpu": "x64" }, "sha512-SKWM4waLuqx0IH+FMDUw6R66Hu4OuTALFgnleKbqhgGU30DY20NORZMZUKgLRjQXNN2TLzKvh48QXTig4h4bGw=="], - - "@tailwindcss/postcss": ["@tailwindcss/postcss@4.1.17", "", { "dependencies": { "@alloc/quick-lru": "^5.2.0", "@tailwindcss/node": "4.1.17", "@tailwindcss/oxide": "4.1.17", "postcss": "^8.4.41", "tailwindcss": "4.1.17" } }, "sha512-+nKl9N9mN5uJ+M7dBOOCzINw94MPstNR/GtIhz1fpZysxL/4a+No64jCBD6CPN+bIHWFx3KWuu8XJRrj/572Dw=="], - - "@types/node": ["@types/node@20.19.25", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-ZsJzA5thDQMSQO788d7IocwwQbI8B5OPzmqNvpf3NY/+MHDAS759Wo0gd2WQeXYt5AAAQjzcrTVC6SKCuYgoCQ=="], - - "@types/react": ["@types/react@19.2.7", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-MWtvHrGZLFttgeEj28VXHxpmwYbor/ATPYbBfSFZEIRK0ecCFLl2Qo55z52Hss+UV9CRN7trSeq1zbgx7YDWWg=="], - - "@types/react-dom": ["@types/react-dom@19.2.3", "", { "peerDependencies": { "@types/react": "^19.2.0" } }, "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ=="], - - "abitype": ["abitype@1.1.0", "", { "peerDependencies": { "typescript": ">=5.0.4", "zod": "^3.22.0 || ^4.0.0" }, "optionalPeers": ["typescript", "zod"] }, "sha512-6Vh4HcRxNMLA0puzPjM5GBgT4aAcFGKZzSgAXvuZ27shJP6NEpielTuqbBmZILR5/xd0PizkBGy5hReKz9jl5A=="], - - "bowser": ["bowser@2.14.1", "", {}, "sha512-tzPjzCxygAKWFOJP011oxFHs57HzIhOEracIgAePE4pqB3LikALKnSzUyU4MGs9/iCEUuHlAJTjTc5M+u7YEGg=="], - - "caniuse-lite": ["caniuse-lite@1.0.30001781", "", {}, "sha512-RdwNCyMsNBftLjW6w01z8bKEvT6e/5tpPVEgtn22TiLGlstHOVecsX2KHFkD5e/vRnIE4EGzpuIODb3mtswtkw=="], - - "client-only": ["client-only@0.0.1", "", {}, "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA=="], - - "csstype": ["csstype@3.2.3", "", {}, "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="], - - "detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="], - - "enhanced-resolve": ["enhanced-resolve@5.20.1", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.3.0" } }, "sha512-Qohcme7V1inbAfvjItgw0EaxVX5q2rdVEZHRBrEQdRZTssLDGsL8Lwrznl8oQ/6kuTJONLaDcGjkNP247XEhcA=="], - - "eventemitter3": ["eventemitter3@5.0.1", "", {}, "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA=="], - - "fast-xml-parser": ["fast-xml-parser@5.2.5", "", { "dependencies": { "strnum": "^2.1.0" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-pfX9uG9Ki0yekDHx2SiuRIyFdyAr1kMIMitPvb0YBo8SUfKvia7w7FIyd/l6av85pFYRhZscS75MwMnbvY+hcQ=="], - - "graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="], - - "isows": ["isows@1.0.7", "", { "peerDependencies": { "ws": "*" } }, "sha512-I1fSfDCZL5P0v33sVqeTDSpcstAg/N+wF5HS033mogOVIp4B+oHC7oOCsA3axAbBSGTJ8QubbNmnIRN/h8U7hg=="], - - "jiti": ["jiti@2.6.1", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ=="], - - "lightningcss": ["lightningcss@1.30.2", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.30.2", "lightningcss-darwin-arm64": "1.30.2", "lightningcss-darwin-x64": "1.30.2", "lightningcss-freebsd-x64": "1.30.2", "lightningcss-linux-arm-gnueabihf": "1.30.2", "lightningcss-linux-arm64-gnu": "1.30.2", "lightningcss-linux-arm64-musl": "1.30.2", "lightningcss-linux-x64-gnu": "1.30.2", "lightningcss-linux-x64-musl": "1.30.2", "lightningcss-win32-arm64-msvc": "1.30.2", "lightningcss-win32-x64-msvc": "1.30.2" } }, "sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ=="], - - "lightningcss-android-arm64": ["lightningcss-android-arm64@1.30.2", "", { "os": "android", "cpu": "arm64" }, "sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A=="], - - "lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.30.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA=="], - - "lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.30.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-oBZgKchomuDYxr7ilwLcyms6BCyLn0z8J0+ZZmfpjwg9fRVZIR5/GMXd7r9RH94iDhld3UmSjBM6nXWM2TfZTQ=="], - - "lightningcss-freebsd-x64": ["lightningcss-freebsd-x64@1.30.2", "", { "os": "freebsd", "cpu": "x64" }, "sha512-c2bH6xTrf4BDpK8MoGG4Bd6zAMZDAXS569UxCAGcA7IKbHNMlhGQ89eRmvpIUGfKWNVdbhSbkQaWhEoMGmGslA=="], - - "lightningcss-linux-arm-gnueabihf": ["lightningcss-linux-arm-gnueabihf@1.30.2", "", { "os": "linux", "cpu": "arm" }, "sha512-eVdpxh4wYcm0PofJIZVuYuLiqBIakQ9uFZmipf6LF/HRj5Bgm0eb3qL/mr1smyXIS1twwOxNWndd8z0E374hiA=="], - - "lightningcss-linux-arm64-gnu": ["lightningcss-linux-arm64-gnu@1.30.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A=="], - - "lightningcss-linux-arm64-musl": ["lightningcss-linux-arm64-musl@1.30.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA=="], - - "lightningcss-linux-x64-gnu": ["lightningcss-linux-x64-gnu@1.30.2", "", { "os": "linux", "cpu": "x64" }, "sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w=="], - - "lightningcss-linux-x64-musl": ["lightningcss-linux-x64-musl@1.30.2", "", { "os": "linux", "cpu": "x64" }, "sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA=="], - - "lightningcss-win32-arm64-msvc": ["lightningcss-win32-arm64-msvc@1.30.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ=="], - - "lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.30.2", "", { "os": "win32", "cpu": "x64" }, "sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw=="], - - "magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="], - - "nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="], - - "next": ["next@16.0.7", "", { "dependencies": { "@next/env": "16.0.7", "@swc/helpers": "0.5.15", "caniuse-lite": "^1.0.30001579", "postcss": "8.4.31", "styled-jsx": "5.1.6" }, "optionalDependencies": { "@next/swc-darwin-arm64": "16.0.7", "@next/swc-darwin-x64": "16.0.7", "@next/swc-linux-arm64-gnu": "16.0.7", "@next/swc-linux-arm64-musl": "16.0.7", "@next/swc-linux-x64-gnu": "16.0.7", "@next/swc-linux-x64-musl": "16.0.7", "@next/swc-win32-arm64-msvc": "16.0.7", "@next/swc-win32-x64-msvc": "16.0.7", "sharp": "^0.34.4" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", "@playwright/test": "^1.51.1", "babel-plugin-react-compiler": "*", "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "sass": "^1.3.0" }, "optionalPeers": ["@opentelemetry/api", "@playwright/test", "babel-plugin-react-compiler", "sass"], "bin": { "next": "dist/bin/next" } }, "sha512-3mBRJyPxT4LOxAJI6IsXeFtKfiJUbjCLgvXO02fV8Wy/lIhPvP94Fe7dGhUgHXcQy4sSuYwQNcOLhIfOm0rL0A=="], - - "ox": ["ox@0.9.6", "", { "dependencies": { "@adraffy/ens-normalize": "^1.11.0", "@noble/ciphers": "^1.3.0", "@noble/curves": "1.9.1", "@noble/hashes": "^1.8.0", "@scure/bip32": "^1.7.0", "@scure/bip39": "^1.6.0", "abitype": "^1.0.9", "eventemitter3": "5.0.1" }, "peerDependencies": { "typescript": ">=5.4.0" }, "optionalPeers": ["typescript"] }, "sha512-8SuCbHPvv2eZLYXrNmC0EC12rdzXQLdhnOMlHDW2wiCPLxBrOOJwX5L5E61by+UjTPOryqQiRSnjIKCI+GykKg=="], - - "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="], - - "postcss": ["postcss@8.5.8", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg=="], - - "react": ["react@19.2.1", "", {}, "sha512-DGrYcCWK7tvYMnWh79yrPHt+vdx9tY+1gPZa7nJQtO/p8bLTDaHp4dzwEhQB7pZ4Xe3ok4XKuEPrVuc+wlpkmw=="], - - "react-dom": ["react-dom@19.2.1", "", { "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { "react": "^19.2.1" } }, "sha512-ibrK8llX2a4eOskq1mXKu/TGZj9qzomO+sNfO98M6d9zIPOEhlBkMkBUBLd1vgS0gQsLDBzA+8jJBVXDnfHmJg=="], - - "scheduler": ["scheduler@0.27.0", "", {}, "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q=="], - - "semver": ["semver@7.7.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="], - - "sharp": ["sharp@0.34.5", "", { "dependencies": { "@img/colour": "^1.0.0", "detect-libc": "^2.1.2", "semver": "^7.7.3" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.34.5", "@img/sharp-darwin-x64": "0.34.5", "@img/sharp-libvips-darwin-arm64": "1.2.4", "@img/sharp-libvips-darwin-x64": "1.2.4", "@img/sharp-libvips-linux-arm": "1.2.4", "@img/sharp-libvips-linux-arm64": "1.2.4", "@img/sharp-libvips-linux-ppc64": "1.2.4", "@img/sharp-libvips-linux-riscv64": "1.2.4", "@img/sharp-libvips-linux-s390x": "1.2.4", "@img/sharp-libvips-linux-x64": "1.2.4", "@img/sharp-libvips-linuxmusl-arm64": "1.2.4", "@img/sharp-libvips-linuxmusl-x64": "1.2.4", "@img/sharp-linux-arm": "0.34.5", "@img/sharp-linux-arm64": "0.34.5", "@img/sharp-linux-ppc64": "0.34.5", "@img/sharp-linux-riscv64": "0.34.5", "@img/sharp-linux-s390x": "0.34.5", "@img/sharp-linux-x64": "0.34.5", "@img/sharp-linuxmusl-arm64": "0.34.5", "@img/sharp-linuxmusl-x64": "0.34.5", "@img/sharp-wasm32": "0.34.5", "@img/sharp-win32-arm64": "0.34.5", "@img/sharp-win32-ia32": "0.34.5", "@img/sharp-win32-x64": "0.34.5" } }, "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg=="], - - "source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="], - - "strnum": ["strnum@2.2.2", "", {}, "sha512-DnR90I+jtXNSTXWdwrEy9FakW7UX+qUZg28gj5fk2vxxl7uS/3bpI4fjFYVmdK9etptYBPNkpahuQnEwhwECqA=="], - - "styled-jsx": ["styled-jsx@5.1.6", "", { "dependencies": { "client-only": "0.0.1" }, "peerDependencies": { "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0" } }, "sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA=="], - - "tailwindcss": ["tailwindcss@4.1.17", "", {}, "sha512-j9Ee2YjuQqYT9bbRTfTZht9W/ytp5H+jJpZKiYdP/bpnXARAuELt9ofP0lPnmHjbga7SNQIxdTAXCmtKVYjN+Q=="], - - "tapable": ["tapable@2.3.2", "", {}, "sha512-1MOpMXuhGzGL5TTCZFItxCc0AARf1EZFQkGqMm7ERKj8+Hgr5oLvJOVFcC+lRmR8hCe2S3jC4T5D7Vg/d7/fhA=="], - - "tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - - "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="], - - "undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="], - - "viem": ["viem@2.40.3", "", { "dependencies": { "@noble/curves": "1.9.1", "@noble/hashes": "1.8.0", "@scure/bip32": "1.7.0", "@scure/bip39": "1.6.0", "abitype": "1.1.0", "isows": "1.0.7", "ox": "0.9.6", "ws": "8.18.3" }, "peerDependencies": { "typescript": ">=5.0.4" }, "optionalPeers": ["typescript"] }, "sha512-feYfEpbgjRkZYQpwcgxqkWzjxHI5LSDAjcGetHHwDRuX9BRQHUdV8ohrCosCYpdEhus/RknD3/bOd4qLYVPPuA=="], - - "ws": ["ws@8.18.3", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg=="], - - "@aws-crypto/sha1-browser/@smithy/util-utf8": ["@smithy/util-utf8@2.3.0", "", { "dependencies": { "@smithy/util-buffer-from": "^2.2.0", "tslib": "^2.6.2" } }, "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A=="], - - "@aws-crypto/sha256-browser/@smithy/util-utf8": ["@smithy/util-utf8@2.3.0", "", { "dependencies": { "@smithy/util-buffer-from": "^2.2.0", "tslib": "^2.6.2" } }, "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A=="], - - "@aws-crypto/util/@smithy/util-utf8": ["@smithy/util-utf8@2.3.0", "", { "dependencies": { "@smithy/util-buffer-from": "^2.2.0", "tslib": "^2.6.2" } }, "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A=="], - - "@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.9.1", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.0", "tslib": "^2.4.0" }, "bundled": true }, "sha512-mukuNALVsoix/w1BJwFzwXBN/dHeejQtuVzcDsfOEsdpCumXb/E9j8w11h5S54tT1xhifGfbbSm/ICrObRb3KA=="], - - "@tailwindcss/oxide-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.9.1", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-VYi5+ZVLhpgK4hQ0TAjiQiZ6ol0oe4mBx7mVv7IflsiEp0OWoVsp/+f9Vc1hOhE0TtkORVrI1GvzyreqpgWtkA=="], - - "@tailwindcss/oxide-wasm32-wasi/@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.0", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-N10dEJNSsUx41Z6pZsXU8FjPjpBEplgH24sfkmITrBED1/U2Esum9F3lfLrMjKHHjmi557zQn7kR9R+XWXu5Rg=="], - - "@tailwindcss/oxide-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.1", "", { "dependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1", "@tybys/wasm-util": "^0.10.1" }, "bundled": true }, "sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A=="], - - "@tailwindcss/oxide-wasm32-wasi/@tybys/wasm-util": ["@tybys/wasm-util@0.10.1", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg=="], - - "@tailwindcss/oxide-wasm32-wasi/tslib": ["tslib@2.8.1", "", { "bundled": true }, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - - "next/postcss": ["postcss@8.4.31", "", { "dependencies": { "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" } }, "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ=="], - - "@aws-crypto/sha1-browser/@smithy/util-utf8/@smithy/util-buffer-from": ["@smithy/util-buffer-from@2.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^2.2.0", "tslib": "^2.6.2" } }, "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA=="], - - "@aws-crypto/sha256-browser/@smithy/util-utf8/@smithy/util-buffer-from": ["@smithy/util-buffer-from@2.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^2.2.0", "tslib": "^2.6.2" } }, "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA=="], - - "@aws-crypto/util/@smithy/util-utf8/@smithy/util-buffer-from": ["@smithy/util-buffer-from@2.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^2.2.0", "tslib": "^2.6.2" } }, "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA=="], - - "@aws-crypto/sha1-browser/@smithy/util-utf8/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@2.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA=="], - - "@aws-crypto/sha256-browser/@smithy/util-utf8/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@2.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA=="], - - "@aws-crypto/util/@smithy/util-utf8/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@2.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA=="], - } -} diff --git a/docker/migrations/0001_init.sql b/docker/migrations/0001_init.sql new file mode 100644 index 00000000..9d1a5a56 --- /dev/null +++ b/docker/migrations/0001_init.sql @@ -0,0 +1,65 @@ +-- vibescan indexer schema (ported from crates/vibenet/explorer). +-- Everything derivable from RPC stays in the node; the only persisted state +-- is the cursor + the address-activity join index that plain JSON-RPC cannot +-- serve efficiently. + +CREATE TABLE IF NOT EXISTS cursor ( + id INTEGER PRIMARY KEY CHECK (id = 0), + last_indexed_block INTEGER NOT NULL, + last_indexed_hash TEXT NOT NULL, + updated_at INTEGER NOT NULL +); + +CREATE TABLE IF NOT EXISTS blocks ( + number INTEGER PRIMARY KEY, + hash TEXT NOT NULL UNIQUE, + timestamp INTEGER NOT NULL, + miner TEXT NOT NULL, + tx_count INTEGER NOT NULL, + gas_used INTEGER NOT NULL, + gas_limit INTEGER NOT NULL, + base_fee TEXT +); + +CREATE TABLE IF NOT EXISTS txs ( + hash TEXT PRIMARY KEY, + block_num INTEGER NOT NULL, + tx_index INTEGER NOT NULL, + from_addr TEXT NOT NULL, + to_addr TEXT, + value TEXT NOT NULL, + status INTEGER NOT NULL, + created TEXT +); +CREATE INDEX IF NOT EXISTS idx_txs_block_num ON txs (block_num DESC, tx_index DESC); + +-- address -> activity feed. role values: +-- 0 = sender, 1 = recipient, 2 = creator +-- 3 = erc20/721 log from, 4 = erc20/721 log to +CREATE TABLE IF NOT EXISTS address_activity ( + address TEXT NOT NULL, + block_num INTEGER NOT NULL, + tx_index INTEGER NOT NULL, + log_index INTEGER NOT NULL DEFAULT -1, + tx_hash TEXT NOT NULL, + role INTEGER NOT NULL, + token TEXT, + PRIMARY KEY (address, block_num, tx_index, log_index, role) +); +CREATE INDEX IF NOT EXISTS idx_activity_addr_block + ON address_activity (address, block_num DESC, tx_index DESC, log_index DESC); + +CREATE TABLE IF NOT EXISTS addresses ( + address TEXT PRIMARY KEY +); + +CREATE TABLE IF NOT EXISTS explorer_stats ( + id INTEGER PRIMARY KEY CHECK (id = 0), + blocks INTEGER NOT NULL, + txs INTEGER NOT NULL, + addresses INTEGER NOT NULL +); + +INSERT INTO explorer_stats (id, blocks, txs, addresses) +VALUES (0, 0, 0, 0) +ON CONFLICT(id) DO NOTHING; diff --git a/docker/vibenet-env.example b/docker/vibenet-env.example new file mode 100644 index 00000000..e5ca3149 --- /dev/null +++ b/docker/vibenet-env.example @@ -0,0 +1,12 @@ +# base/ui vibenet env — UI-specific config only. +# Infra secrets (chain IDs, faucet key, etc.) live in base/base etc/vibenet/vibenet-env. +# This file is passed as a second --env-file to docker compose and merges with it. + +# === Explorer === +VIBESCAN_DB_PATH=/data/vibescan.db +VIBESCAN_START_BLOCK=0 +VIBESCAN_BACKFILL_CONCURRENCY=16 + +# === Optional: surfaced in explorer footer === +# VIBESCAN_PUBLIC_RPC_URL=https://rpc.vibes.base.org +# VIBESCAN_PUBLIC_FAUCET_URL=https://faucet.vibes.base.org diff --git a/next.config.ts b/next.config.ts index 68a6c64d..89cdbd2a 100644 --- a/next.config.ts +++ b/next.config.ts @@ -1,7 +1,8 @@ import type { NextConfig } from "next"; const nextConfig: NextConfig = { - output: "standalone", + // better-sqlite3 is a native module; exclude it from webpack bundling + serverExternalPackages: ["better-sqlite3"], }; export default nextConfig; diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 00000000..4a3c1fe5 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,3888 @@ +{ + "name": "ui", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "ui", + "version": "0.1.0", + "dependencies": { + "@aws-sdk/client-s3": "3.940.0", + "next": "16.0.7", + "react": "19.2.1", + "react-dom": "19.2.1", + "viem": "2.40.3" + }, + "devDependencies": { + "@biomejs/biome": "2.3.8", + "@tailwindcss/postcss": "4.1.17", + "@types/better-sqlite3": "^7.6.13", + "@types/node": "20.19.25", + "@types/react": "19.2.7", + "@types/react-dom": "19.2.3", + "better-sqlite3": "^12.10.0", + "tailwindcss": "4.1.17", + "typescript": "5.9.3" + } + }, + "node_modules/@adraffy/ens-normalize": { + "version": "1.11.1", + "resolved": "https://registry-npm.cbhq.net/@adraffy/ens-normalize/-/ens-normalize-1.11.1.tgz", + "integrity": "sha512-nhCBV3quEgesuf7c7KYfperqSS14T8bYuvJ8PcLJp6znkZpFc0AuW4qBtr8eKVyPPe/8RSr7sglCWPU5eaxwKQ==", + "license": "MIT" + }, + "node_modules/@alloc/quick-lru": { + "version": "5.2.0", + "resolved": "https://registry-npm.cbhq.net/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", + "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@aws-crypto/crc32": { + "version": "5.2.0", + "resolved": "https://registry-npm.cbhq.net/@aws-crypto/crc32/-/crc32-5.2.0.tgz", + "integrity": "sha512-nLbCWqQNgUiwwtFsen1AdzAtvuLRsQS8rYgMuxCrdKf9kOssamGLuPwyTY9wyYblNr9+1XM8v6zoDTPPSIeANg==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-crypto/crc32c": { + "version": "5.2.0", + "resolved": "https://registry-npm.cbhq.net/@aws-crypto/crc32c/-/crc32c-5.2.0.tgz", + "integrity": "sha512-+iWb8qaHLYKrNvGRbiYRHSdKRWhto5XlZUEBwDjYNf+ly5SVYG6zEoYIdxvf5R3zyeP16w4PLBn3rH1xc74Rag==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-crypto/sha1-browser": { + "version": "5.2.0", + "resolved": "https://registry-npm.cbhq.net/@aws-crypto/sha1-browser/-/sha1-browser-5.2.0.tgz", + "integrity": "sha512-OH6lveCFfcDjX4dbAvCFSYUjJZjDr/3XJ3xHtjn3Oj5b9RjojQo8npoLeA/bNwkOkrSQ0wgrHzXk4tDRxGKJeg==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/supports-web-crypto": "^5.2.0", + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "@aws-sdk/util-locate-window": "^3.0.0", + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-crypto/sha1-browser/node_modules/@smithy/util-utf8": { + "version": "2.3.0", + "resolved": "https://registry-npm.cbhq.net/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", + "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/sha256-browser": { + "version": "5.2.0", + "resolved": "https://registry-npm.cbhq.net/@aws-crypto/sha256-browser/-/sha256-browser-5.2.0.tgz", + "integrity": "sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-js": "^5.2.0", + "@aws-crypto/supports-web-crypto": "^5.2.0", + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "@aws-sdk/util-locate-window": "^3.0.0", + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-utf8": { + "version": "2.3.0", + "resolved": "https://registry-npm.cbhq.net/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", + "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/sha256-js": { + "version": "5.2.0", + "resolved": "https://registry-npm.cbhq.net/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz", + "integrity": "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-crypto/supports-web-crypto": { + "version": "5.2.0", + "resolved": "https://registry-npm.cbhq.net/@aws-crypto/supports-web-crypto/-/supports-web-crypto-5.2.0.tgz", + "integrity": "sha512-iAvUotm021kM33eCdNfwIN//F77/IADDSs58i+MDaOqFrVjZo9bAal0NK7HurRuWLLpF1iLX7gbWrjHjeo+YFg==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-crypto/util": { + "version": "5.2.0", + "resolved": "https://registry-npm.cbhq.net/@aws-crypto/util/-/util-5.2.0.tgz", + "integrity": "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.222.0", + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-crypto/util/node_modules/@smithy/util-utf8": { + "version": "2.3.0", + "resolved": "https://registry-npm.cbhq.net/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", + "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-s3": { + "version": "3.940.0", + "resolved": "https://registry-npm.cbhq.net/@aws-sdk/client-s3/-/client-s3-3.940.0.tgz", + "integrity": "sha512-Wi4qnBT6shRRMXuuTgjMFTU5mu2KFWisgcigEMPptjPGUtJvBVi4PTGgS64qsLoUk/obqDAyOBOfEtRZ2ddC2w==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha1-browser": "5.2.0", + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "3.940.0", + "@aws-sdk/credential-provider-node": "3.940.0", + "@aws-sdk/middleware-bucket-endpoint": "3.936.0", + "@aws-sdk/middleware-expect-continue": "3.936.0", + "@aws-sdk/middleware-flexible-checksums": "3.940.0", + "@aws-sdk/middleware-host-header": "3.936.0", + "@aws-sdk/middleware-location-constraint": "3.936.0", + "@aws-sdk/middleware-logger": "3.936.0", + "@aws-sdk/middleware-recursion-detection": "3.936.0", + "@aws-sdk/middleware-sdk-s3": "3.940.0", + "@aws-sdk/middleware-ssec": "3.936.0", + "@aws-sdk/middleware-user-agent": "3.940.0", + "@aws-sdk/region-config-resolver": "3.936.0", + "@aws-sdk/signature-v4-multi-region": "3.940.0", + "@aws-sdk/types": "3.936.0", + "@aws-sdk/util-endpoints": "3.936.0", + "@aws-sdk/util-user-agent-browser": "3.936.0", + "@aws-sdk/util-user-agent-node": "3.940.0", + "@smithy/config-resolver": "^4.4.3", + "@smithy/core": "^3.18.5", + "@smithy/eventstream-serde-browser": "^4.2.5", + "@smithy/eventstream-serde-config-resolver": "^4.3.5", + "@smithy/eventstream-serde-node": "^4.2.5", + "@smithy/fetch-http-handler": "^5.3.6", + "@smithy/hash-blob-browser": "^4.2.6", + "@smithy/hash-node": "^4.2.5", + "@smithy/hash-stream-node": "^4.2.5", + "@smithy/invalid-dependency": "^4.2.5", + "@smithy/md5-js": "^4.2.5", + "@smithy/middleware-content-length": "^4.2.5", + "@smithy/middleware-endpoint": "^4.3.12", + "@smithy/middleware-retry": "^4.4.12", + "@smithy/middleware-serde": "^4.2.6", + "@smithy/middleware-stack": "^4.2.5", + "@smithy/node-config-provider": "^4.3.5", + "@smithy/node-http-handler": "^4.4.5", + "@smithy/protocol-http": "^5.3.5", + "@smithy/smithy-client": "^4.9.8", + "@smithy/types": "^4.9.0", + "@smithy/url-parser": "^4.2.5", + "@smithy/util-base64": "^4.3.0", + "@smithy/util-body-length-browser": "^4.2.0", + "@smithy/util-body-length-node": "^4.2.1", + "@smithy/util-defaults-mode-browser": "^4.3.11", + "@smithy/util-defaults-mode-node": "^4.2.14", + "@smithy/util-endpoints": "^3.2.5", + "@smithy/util-middleware": "^4.2.5", + "@smithy/util-retry": "^4.2.5", + "@smithy/util-stream": "^4.5.6", + "@smithy/util-utf8": "^4.2.0", + "@smithy/util-waiter": "^4.2.5", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/client-sso": { + "version": "3.940.0", + "resolved": "https://registry-npm.cbhq.net/@aws-sdk/client-sso/-/client-sso-3.940.0.tgz", + "integrity": "sha512-SdqJGWVhmIURvCSgkDditHRO+ozubwZk9aCX9MK8qxyOndhobCndW1ozl3hX9psvMAo9Q4bppjuqy/GHWpjB+A==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "3.940.0", + "@aws-sdk/middleware-host-header": "3.936.0", + "@aws-sdk/middleware-logger": "3.936.0", + "@aws-sdk/middleware-recursion-detection": "3.936.0", + "@aws-sdk/middleware-user-agent": "3.940.0", + "@aws-sdk/region-config-resolver": "3.936.0", + "@aws-sdk/types": "3.936.0", + "@aws-sdk/util-endpoints": "3.936.0", + "@aws-sdk/util-user-agent-browser": "3.936.0", + "@aws-sdk/util-user-agent-node": "3.940.0", + "@smithy/config-resolver": "^4.4.3", + "@smithy/core": "^3.18.5", + "@smithy/fetch-http-handler": "^5.3.6", + "@smithy/hash-node": "^4.2.5", + "@smithy/invalid-dependency": "^4.2.5", + "@smithy/middleware-content-length": "^4.2.5", + "@smithy/middleware-endpoint": "^4.3.12", + "@smithy/middleware-retry": "^4.4.12", + "@smithy/middleware-serde": "^4.2.6", + "@smithy/middleware-stack": "^4.2.5", + "@smithy/node-config-provider": "^4.3.5", + "@smithy/node-http-handler": "^4.4.5", + "@smithy/protocol-http": "^5.3.5", + "@smithy/smithy-client": "^4.9.8", + "@smithy/types": "^4.9.0", + "@smithy/url-parser": "^4.2.5", + "@smithy/util-base64": "^4.3.0", + "@smithy/util-body-length-browser": "^4.2.0", + "@smithy/util-body-length-node": "^4.2.1", + "@smithy/util-defaults-mode-browser": "^4.3.11", + "@smithy/util-defaults-mode-node": "^4.2.14", + "@smithy/util-endpoints": "^3.2.5", + "@smithy/util-middleware": "^4.2.5", + "@smithy/util-retry": "^4.2.5", + "@smithy/util-utf8": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/core": { + "version": "3.940.0", + "resolved": "https://registry-npm.cbhq.net/@aws-sdk/core/-/core-3.940.0.tgz", + "integrity": "sha512-KsGD2FLaX5ngJao1mHxodIVU9VYd1E8810fcYiGwO1PFHDzf5BEkp6D9IdMeQwT8Q6JLYtiiT1Y/o3UCScnGoA==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.936.0", + "@aws-sdk/xml-builder": "3.930.0", + "@smithy/core": "^3.18.5", + "@smithy/node-config-provider": "^4.3.5", + "@smithy/property-provider": "^4.2.5", + "@smithy/protocol-http": "^5.3.5", + "@smithy/signature-v4": "^5.3.5", + "@smithy/smithy-client": "^4.9.8", + "@smithy/types": "^4.9.0", + "@smithy/util-base64": "^4.3.0", + "@smithy/util-middleware": "^4.2.5", + "@smithy/util-utf8": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-env": { + "version": "3.940.0", + "resolved": "https://registry-npm.cbhq.net/@aws-sdk/credential-provider-env/-/credential-provider-env-3.940.0.tgz", + "integrity": "sha512-/G3l5/wbZYP2XEQiOoIkRJmlv15f1P3MSd1a0gz27lHEMrOJOGq66rF1Ca4OJLzapWt3Fy9BPrZAepoAX11kMw==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.940.0", + "@aws-sdk/types": "3.936.0", + "@smithy/property-provider": "^4.2.5", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-http": { + "version": "3.940.0", + "resolved": "https://registry-npm.cbhq.net/@aws-sdk/credential-provider-http/-/credential-provider-http-3.940.0.tgz", + "integrity": "sha512-dOrc03DHElNBD6N9Okt4U0zhrG4Wix5QUBSZPr5VN8SvmjD9dkrrxOkkJaMCl/bzrW7kbQEp7LuBdbxArMmOZQ==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.940.0", + "@aws-sdk/types": "3.936.0", + "@smithy/fetch-http-handler": "^5.3.6", + "@smithy/node-http-handler": "^4.4.5", + "@smithy/property-provider": "^4.2.5", + "@smithy/protocol-http": "^5.3.5", + "@smithy/smithy-client": "^4.9.8", + "@smithy/types": "^4.9.0", + "@smithy/util-stream": "^4.5.6", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-ini": { + "version": "3.940.0", + "resolved": "https://registry-npm.cbhq.net/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.940.0.tgz", + "integrity": "sha512-gn7PJQEzb/cnInNFTOaDoCN/hOKqMejNmLof1W5VW95Qk0TPO52lH8R4RmJPnRrwFMswOWswTOpR1roKNLIrcw==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.940.0", + "@aws-sdk/credential-provider-env": "3.940.0", + "@aws-sdk/credential-provider-http": "3.940.0", + "@aws-sdk/credential-provider-login": "3.940.0", + "@aws-sdk/credential-provider-process": "3.940.0", + "@aws-sdk/credential-provider-sso": "3.940.0", + "@aws-sdk/credential-provider-web-identity": "3.940.0", + "@aws-sdk/nested-clients": "3.940.0", + "@aws-sdk/types": "3.936.0", + "@smithy/credential-provider-imds": "^4.2.5", + "@smithy/property-provider": "^4.2.5", + "@smithy/shared-ini-file-loader": "^4.4.0", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-login": { + "version": "3.940.0", + "resolved": "https://registry-npm.cbhq.net/@aws-sdk/credential-provider-login/-/credential-provider-login-3.940.0.tgz", + "integrity": "sha512-fOKC3VZkwa9T2l2VFKWRtfHQPQuISqqNl35ZhcXjWKVwRwl/o7THPMkqI4XwgT2noGa7LLYVbWMwnsgSsBqglg==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.940.0", + "@aws-sdk/nested-clients": "3.940.0", + "@aws-sdk/types": "3.936.0", + "@smithy/property-provider": "^4.2.5", + "@smithy/protocol-http": "^5.3.5", + "@smithy/shared-ini-file-loader": "^4.4.0", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-node": { + "version": "3.940.0", + "resolved": "https://registry-npm.cbhq.net/@aws-sdk/credential-provider-node/-/credential-provider-node-3.940.0.tgz", + "integrity": "sha512-M8NFAvgvO6xZjiti5kztFiAYmSmSlG3eUfr4ZHSfXYZUA/KUdZU/D6xJyaLnU8cYRWBludb6K9XPKKVwKfqm4g==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/credential-provider-env": "3.940.0", + "@aws-sdk/credential-provider-http": "3.940.0", + "@aws-sdk/credential-provider-ini": "3.940.0", + "@aws-sdk/credential-provider-process": "3.940.0", + "@aws-sdk/credential-provider-sso": "3.940.0", + "@aws-sdk/credential-provider-web-identity": "3.940.0", + "@aws-sdk/types": "3.936.0", + "@smithy/credential-provider-imds": "^4.2.5", + "@smithy/property-provider": "^4.2.5", + "@smithy/shared-ini-file-loader": "^4.4.0", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-process": { + "version": "3.940.0", + "resolved": "https://registry-npm.cbhq.net/@aws-sdk/credential-provider-process/-/credential-provider-process-3.940.0.tgz", + "integrity": "sha512-pILBzt5/TYCqRsJb7vZlxmRIe0/T+FZPeml417EK75060ajDGnVJjHcuVdLVIeKoTKm9gmJc9l45gon6PbHyUQ==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.940.0", + "@aws-sdk/types": "3.936.0", + "@smithy/property-provider": "^4.2.5", + "@smithy/shared-ini-file-loader": "^4.4.0", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-sso": { + "version": "3.940.0", + "resolved": "https://registry-npm.cbhq.net/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.940.0.tgz", + "integrity": "sha512-q6JMHIkBlDCOMnA3RAzf8cGfup+8ukhhb50fNpghMs1SNBGhanmaMbZSgLigBRsPQW7fOk2l8jnzdVLS+BB9Uw==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/client-sso": "3.940.0", + "@aws-sdk/core": "3.940.0", + "@aws-sdk/token-providers": "3.940.0", + "@aws-sdk/types": "3.936.0", + "@smithy/property-provider": "^4.2.5", + "@smithy/shared-ini-file-loader": "^4.4.0", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-web-identity": { + "version": "3.940.0", + "resolved": "https://registry-npm.cbhq.net/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.940.0.tgz", + "integrity": "sha512-9QLTIkDJHHaYL0nyymO41H8g3ui1yz6Y3GmAN1gYQa6plXisuFBnGAbmKVj7zNvjWaOKdF0dV3dd3AFKEDoJ/w==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.940.0", + "@aws-sdk/nested-clients": "3.940.0", + "@aws-sdk/types": "3.936.0", + "@smithy/property-provider": "^4.2.5", + "@smithy/shared-ini-file-loader": "^4.4.0", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/middleware-bucket-endpoint": { + "version": "3.936.0", + "resolved": "https://registry-npm.cbhq.net/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.936.0.tgz", + "integrity": "sha512-XLSVVfAorUxZh6dzF+HTOp4R1B5EQcdpGcPliWr0KUj2jukgjZEcqbBmjyMF/p9bmyQsONX80iURF1HLAlW0qg==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.936.0", + "@aws-sdk/util-arn-parser": "3.893.0", + "@smithy/node-config-provider": "^4.3.5", + "@smithy/protocol-http": "^5.3.5", + "@smithy/types": "^4.9.0", + "@smithy/util-config-provider": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/middleware-expect-continue": { + "version": "3.936.0", + "resolved": "https://registry-npm.cbhq.net/@aws-sdk/middleware-expect-continue/-/middleware-expect-continue-3.936.0.tgz", + "integrity": "sha512-Eb4ELAC23bEQLJmUMYnPWcjD3FZIsmz2svDiXEcxRkQU9r7NRID7pM7C5NPH94wOfiCk0b2Y8rVyFXW0lGQwbA==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.936.0", + "@smithy/protocol-http": "^5.3.5", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/middleware-flexible-checksums": { + "version": "3.940.0", + "resolved": "https://registry-npm.cbhq.net/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.940.0.tgz", + "integrity": "sha512-WdsxDAVj5qaa5ApAP+JbpCOMHFGSmzjs2Y2OBSbWPeR9Ew7t/Okj+kUub94QJPsgzhvU1/cqNejhsw5VxeFKSQ==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/crc32": "5.2.0", + "@aws-crypto/crc32c": "5.2.0", + "@aws-crypto/util": "5.2.0", + "@aws-sdk/core": "3.940.0", + "@aws-sdk/types": "3.936.0", + "@smithy/is-array-buffer": "^4.2.0", + "@smithy/node-config-provider": "^4.3.5", + "@smithy/protocol-http": "^5.3.5", + "@smithy/types": "^4.9.0", + "@smithy/util-middleware": "^4.2.5", + "@smithy/util-stream": "^4.5.6", + "@smithy/util-utf8": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/middleware-host-header": { + "version": "3.936.0", + "resolved": "https://registry-npm.cbhq.net/@aws-sdk/middleware-host-header/-/middleware-host-header-3.936.0.tgz", + "integrity": "sha512-tAaObaAnsP1XnLGndfkGWFuzrJYuk9W0b/nLvol66t8FZExIAf/WdkT2NNAWOYxljVs++oHnyHBCxIlaHrzSiw==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.936.0", + "@smithy/protocol-http": "^5.3.5", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/middleware-location-constraint": { + "version": "3.936.0", + "resolved": "https://registry-npm.cbhq.net/@aws-sdk/middleware-location-constraint/-/middleware-location-constraint-3.936.0.tgz", + "integrity": "sha512-SCMPenDtQMd9o5da9JzkHz838w3327iqXk3cbNnXWqnNRx6unyW8FL0DZ84gIY12kAyVHz5WEqlWuekc15ehfw==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.936.0", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/middleware-logger": { + "version": "3.936.0", + "resolved": "https://registry-npm.cbhq.net/@aws-sdk/middleware-logger/-/middleware-logger-3.936.0.tgz", + "integrity": "sha512-aPSJ12d3a3Ea5nyEnLbijCaaYJT2QjQ9iW+zGh5QcZYXmOGWbKVyPSxmVOboZQG+c1M8t6d2O7tqrwzIq8L8qw==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.936.0", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/middleware-recursion-detection": { + "version": "3.936.0", + "resolved": "https://registry-npm.cbhq.net/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.936.0.tgz", + "integrity": "sha512-l4aGbHpXM45YNgXggIux1HgsCVAvvBoqHPkqLnqMl9QVapfuSTjJHfDYDsx1Xxct6/m7qSMUzanBALhiaGO2fA==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.936.0", + "@aws/lambda-invoke-store": "^0.2.0", + "@smithy/protocol-http": "^5.3.5", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/middleware-sdk-s3": { + "version": "3.940.0", + "resolved": "https://registry-npm.cbhq.net/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.940.0.tgz", + "integrity": "sha512-JYkLjgS1wLoKHJ40G63+afM1ehmsPsjcmrHirKh8+kSCx4ip7+nL1e/twV4Zicxr8RJi9Y0Ahq5mDvneilDDKQ==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.940.0", + "@aws-sdk/types": "3.936.0", + "@aws-sdk/util-arn-parser": "3.893.0", + "@smithy/core": "^3.18.5", + "@smithy/node-config-provider": "^4.3.5", + "@smithy/protocol-http": "^5.3.5", + "@smithy/signature-v4": "^5.3.5", + "@smithy/smithy-client": "^4.9.8", + "@smithy/types": "^4.9.0", + "@smithy/util-config-provider": "^4.2.0", + "@smithy/util-middleware": "^4.2.5", + "@smithy/util-stream": "^4.5.6", + "@smithy/util-utf8": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/middleware-ssec": { + "version": "3.936.0", + "resolved": "https://registry-npm.cbhq.net/@aws-sdk/middleware-ssec/-/middleware-ssec-3.936.0.tgz", + "integrity": "sha512-/GLC9lZdVp05ozRik5KsuODR/N7j+W+2TbfdFL3iS+7un+gnP6hC8RDOZd6WhpZp7drXQ9guKiTAxkZQwzS8DA==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.936.0", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/middleware-user-agent": { + "version": "3.940.0", + "resolved": "https://registry-npm.cbhq.net/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.940.0.tgz", + "integrity": "sha512-nJbLrUj6fY+l2W2rIB9P4Qvpiy0tnTdg/dmixRxrU1z3e8wBdspJlyE+AZN4fuVbeL6rrRrO/zxQC1bB3cw5IA==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.940.0", + "@aws-sdk/types": "3.936.0", + "@aws-sdk/util-endpoints": "3.936.0", + "@smithy/core": "^3.18.5", + "@smithy/protocol-http": "^5.3.5", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/nested-clients": { + "version": "3.940.0", + "resolved": "https://registry-npm.cbhq.net/@aws-sdk/nested-clients/-/nested-clients-3.940.0.tgz", + "integrity": "sha512-x0mdv6DkjXqXEcQj3URbCltEzW6hoy/1uIL+i8gExP6YKrnhiZ7SzuB4gPls2UOpK5UqLiqXjhRLfBb1C9i4Dw==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "3.940.0", + "@aws-sdk/middleware-host-header": "3.936.0", + "@aws-sdk/middleware-logger": "3.936.0", + "@aws-sdk/middleware-recursion-detection": "3.936.0", + "@aws-sdk/middleware-user-agent": "3.940.0", + "@aws-sdk/region-config-resolver": "3.936.0", + "@aws-sdk/types": "3.936.0", + "@aws-sdk/util-endpoints": "3.936.0", + "@aws-sdk/util-user-agent-browser": "3.936.0", + "@aws-sdk/util-user-agent-node": "3.940.0", + "@smithy/config-resolver": "^4.4.3", + "@smithy/core": "^3.18.5", + "@smithy/fetch-http-handler": "^5.3.6", + "@smithy/hash-node": "^4.2.5", + "@smithy/invalid-dependency": "^4.2.5", + "@smithy/middleware-content-length": "^4.2.5", + "@smithy/middleware-endpoint": "^4.3.12", + "@smithy/middleware-retry": "^4.4.12", + "@smithy/middleware-serde": "^4.2.6", + "@smithy/middleware-stack": "^4.2.5", + "@smithy/node-config-provider": "^4.3.5", + "@smithy/node-http-handler": "^4.4.5", + "@smithy/protocol-http": "^5.3.5", + "@smithy/smithy-client": "^4.9.8", + "@smithy/types": "^4.9.0", + "@smithy/url-parser": "^4.2.5", + "@smithy/util-base64": "^4.3.0", + "@smithy/util-body-length-browser": "^4.2.0", + "@smithy/util-body-length-node": "^4.2.1", + "@smithy/util-defaults-mode-browser": "^4.3.11", + "@smithy/util-defaults-mode-node": "^4.2.14", + "@smithy/util-endpoints": "^3.2.5", + "@smithy/util-middleware": "^4.2.5", + "@smithy/util-retry": "^4.2.5", + "@smithy/util-utf8": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/region-config-resolver": { + "version": "3.936.0", + "resolved": "https://registry-npm.cbhq.net/@aws-sdk/region-config-resolver/-/region-config-resolver-3.936.0.tgz", + "integrity": "sha512-wOKhzzWsshXGduxO4pqSiNyL9oUtk4BEvjWm9aaq6Hmfdoydq6v6t0rAGHWPjFwy9z2haovGRi3C8IxdMB4muw==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.936.0", + "@smithy/config-resolver": "^4.4.3", + "@smithy/node-config-provider": "^4.3.5", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/signature-v4-multi-region": { + "version": "3.940.0", + "resolved": "https://registry-npm.cbhq.net/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.940.0.tgz", + "integrity": "sha512-ugHZEoktD/bG6mdgmhzLDjMP2VrYRAUPRPF1DpCyiZexkH7DCU7XrSJyXMvkcf0DHV+URk0q2sLf/oqn1D2uYw==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/middleware-sdk-s3": "3.940.0", + "@aws-sdk/types": "3.936.0", + "@smithy/protocol-http": "^5.3.5", + "@smithy/signature-v4": "^5.3.5", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/token-providers": { + "version": "3.940.0", + "resolved": "https://registry-npm.cbhq.net/@aws-sdk/token-providers/-/token-providers-3.940.0.tgz", + "integrity": "sha512-k5qbRe/ZFjW9oWEdzLIa2twRVIEx7p/9rutofyrRysrtEnYh3HAWCngAnwbgKMoiwa806UzcTRx0TjyEpnKcCg==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.940.0", + "@aws-sdk/nested-clients": "3.940.0", + "@aws-sdk/types": "3.936.0", + "@smithy/property-provider": "^4.2.5", + "@smithy/shared-ini-file-loader": "^4.4.0", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/types": { + "version": "3.936.0", + "resolved": "https://registry-npm.cbhq.net/@aws-sdk/types/-/types-3.936.0.tgz", + "integrity": "sha512-uz0/VlMd2pP5MepdrHizd+T+OKfyK4r3OA9JI+L/lPKg0YFQosdJNCKisr6o70E3dh8iMpFYxF1UN/4uZsyARg==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/util-arn-parser": { + "version": "3.893.0", + "resolved": "https://registry-npm.cbhq.net/@aws-sdk/util-arn-parser/-/util-arn-parser-3.893.0.tgz", + "integrity": "sha512-u8H4f2Zsi19DGnwj5FSZzDMhytYF/bCh37vAtBsn3cNDL3YG578X5oc+wSX54pM3tOxS+NY7tvOAo52SW7koUA==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/util-endpoints": { + "version": "3.936.0", + "resolved": "https://registry-npm.cbhq.net/@aws-sdk/util-endpoints/-/util-endpoints-3.936.0.tgz", + "integrity": "sha512-0Zx3Ntdpu+z9Wlm7JKUBOzS9EunwKAb4KdGUQQxDqh5Lc3ta5uBoub+FgmVuzwnmBu9U1Os8UuwVTH0Lgu+P5w==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.936.0", + "@smithy/types": "^4.9.0", + "@smithy/url-parser": "^4.2.5", + "@smithy/util-endpoints": "^3.2.5", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/util-locate-window": { + "version": "3.965.5", + "resolved": "https://registry-npm.cbhq.net/@aws-sdk/util-locate-window/-/util-locate-window-3.965.5.tgz", + "integrity": "sha512-WhlJNNINQB+9qtLtZJcpQdgZw3SCDCpXdUJP7cToGwHbCWCnRckGlc6Bx/OhWwIYFNAn+FIydY8SZ0QmVu3xTQ==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/util-user-agent-browser": { + "version": "3.936.0", + "resolved": "https://registry-npm.cbhq.net/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.936.0.tgz", + "integrity": "sha512-eZ/XF6NxMtu+iCma58GRNRxSq4lHo6zHQLOZRIeL/ghqYJirqHdenMOwrzPettj60KWlv827RVebP9oNVrwZbw==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.936.0", + "@smithy/types": "^4.9.0", + "bowser": "^2.11.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-sdk/util-user-agent-node": { + "version": "3.940.0", + "resolved": "https://registry-npm.cbhq.net/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.940.0.tgz", + "integrity": "sha512-dlD/F+L/jN26I8Zg5x0oDGJiA+/WEQmnSE27fi5ydvYnpfQLwThtQo9SsNS47XSR/SOULaaoC9qx929rZuo74A==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/middleware-user-agent": "3.940.0", + "@aws-sdk/types": "3.936.0", + "@smithy/node-config-provider": "^4.3.5", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "aws-crt": ">=1.0.0" + }, + "peerDependenciesMeta": { + "aws-crt": { + "optional": true + } + } + }, + "node_modules/@aws-sdk/xml-builder": { + "version": "3.930.0", + "resolved": "https://registry-npm.cbhq.net/@aws-sdk/xml-builder/-/xml-builder-3.930.0.tgz", + "integrity": "sha512-YIfkD17GocxdmlUVc3ia52QhcWuRIUJonbF8A2CYfcWNV3HzvAqpcPeC0bYUhkK+8e8YO1ARnLKZQE0TlwzorA==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.9.0", + "fast-xml-parser": "5.2.5", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws/lambda-invoke-store": { + "version": "0.2.4", + "resolved": "https://registry-npm.cbhq.net/@aws/lambda-invoke-store/-/lambda-invoke-store-0.2.4.tgz", + "integrity": "sha512-iY8yvjE0y651BixKNPgmv1WrQc+GZ142sb0z4gYnChDDY2YqI4P/jsSopBWrKfAt7LOJAkOXt7rC/hms+WclQQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@biomejs/biome": { + "version": "2.3.8", + "resolved": "https://registry-npm.cbhq.net/@biomejs/biome/-/biome-2.3.8.tgz", + "integrity": "sha512-Qjsgoe6FEBxWAUzwFGFrB+1+M8y/y5kwmg5CHac+GSVOdmOIqsAiXM5QMVGZJ1eCUCLlPZtq4aFAQ0eawEUuUA==", + "dev": true, + "license": "MIT OR Apache-2.0", + "bin": { + "biome": "bin/biome" + }, + "engines": { + "node": ">=14.21.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/biome" + }, + "optionalDependencies": { + "@biomejs/cli-darwin-arm64": "2.3.8", + "@biomejs/cli-darwin-x64": "2.3.8", + "@biomejs/cli-linux-arm64": "2.3.8", + "@biomejs/cli-linux-arm64-musl": "2.3.8", + "@biomejs/cli-linux-x64": "2.3.8", + "@biomejs/cli-linux-x64-musl": "2.3.8", + "@biomejs/cli-win32-arm64": "2.3.8", + "@biomejs/cli-win32-x64": "2.3.8" + } + }, + "node_modules/@biomejs/cli-darwin-arm64": { + "version": "2.3.8", + "resolved": "https://registry-npm.cbhq.net/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.3.8.tgz", + "integrity": "sha512-HM4Zg9CGQ3txTPflxD19n8MFPrmUAjaC7PQdLkugeeC0cQ+PiVrd7i09gaBS/11QKsTDBJhVg85CEIK9f50Qww==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-darwin-x64": { + "version": "2.3.8", + "resolved": "https://registry-npm.cbhq.net/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.3.8.tgz", + "integrity": "sha512-lUDQ03D7y/qEao7RgdjWVGCu+BLYadhKTm40HkpJIi6kn8LSv5PAwRlew/DmwP4YZ9ke9XXoTIQDO1vAnbRZlA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-arm64": { + "version": "2.3.8", + "resolved": "https://registry-npm.cbhq.net/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.3.8.tgz", + "integrity": "sha512-Uo1OJnIkJgSgF+USx970fsM/drtPcQ39I+JO+Fjsaa9ZdCN1oysQmy6oAGbyESlouz+rzEckLTF6DS7cWse95g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-arm64-musl": { + "version": "2.3.8", + "resolved": "https://registry-npm.cbhq.net/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.3.8.tgz", + "integrity": "sha512-PShR4mM0sjksUMyxbyPNMxoKFPVF48fU8Qe8Sfx6w6F42verbwRLbz+QiKNiDPRJwUoMG1nPM50OBL3aOnTevA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-x64": { + "version": "2.3.8", + "resolved": "https://registry-npm.cbhq.net/@biomejs/cli-linux-x64/-/cli-linux-x64-2.3.8.tgz", + "integrity": "sha512-QDPMD5bQz6qOVb3kiBui0zKZXASLo0NIQ9JVJio5RveBEFgDgsvJFUvZIbMbUZT3T00M/1wdzwWXk4GIh0KaAw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-x64-musl": { + "version": "2.3.8", + "resolved": "https://registry-npm.cbhq.net/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.3.8.tgz", + "integrity": "sha512-YGLkqU91r1276uwSjiUD/xaVikdxgV1QpsicT0bIA1TaieM6E5ibMZeSyjQ/izBn4tKQthUSsVZacmoJfa3pDA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-win32-arm64": { + "version": "2.3.8", + "resolved": "https://registry-npm.cbhq.net/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.3.8.tgz", + "integrity": "sha512-H4IoCHvL1fXKDrTALeTKMiE7GGWFAraDwBYFquE/L/5r1927Te0mYIGseXi4F+lrrwhSWbSGt5qPFswNoBaCxg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-win32-x64": { + "version": "2.3.8", + "resolved": "https://registry-npm.cbhq.net/@biomejs/cli-win32-x64/-/cli-win32-x64-2.3.8.tgz", + "integrity": "sha512-RguzimPoZWtBapfKhKjcWXBVI91tiSprqdBYu7tWhgN8pKRZhw24rFeNZTNf6UiBfjCYCi9eFQs/JzJZIhuK4w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.10.0", + "resolved": "https://registry-npm.cbhq.net/@emnapi/runtime/-/runtime-1.10.0.tgz", + "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@img/colour": { + "version": "1.1.0", + "resolved": "https://registry-npm.cbhq.net/@img/colour/-/colour-1.1.0.tgz", + "integrity": "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.34.5", + "resolved": "https://registry-npm.cbhq.net/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.5.tgz", + "integrity": "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-darwin-x64": { + "version": "0.34.5", + "resolved": "https://registry-npm.cbhq.net/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.5.tgz", + "integrity": "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.2.4", + "resolved": "https://registry-npm.cbhq.net/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.4.tgz", + "integrity": "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.2.4", + "resolved": "https://registry-npm.cbhq.net/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.4.tgz", + "integrity": "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.2.4", + "resolved": "https://registry-npm.cbhq.net/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.4.tgz", + "integrity": "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==", + "cpu": [ + "arm" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.2.4", + "resolved": "https://registry-npm.cbhq.net/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.4.tgz", + "integrity": "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-ppc64": { + "version": "1.2.4", + "resolved": "https://registry-npm.cbhq.net/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.4.tgz", + "integrity": "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==", + "cpu": [ + "ppc64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-riscv64": { + "version": "1.2.4", + "resolved": "https://registry-npm.cbhq.net/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.2.4.tgz", + "integrity": "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==", + "cpu": [ + "riscv64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.2.4", + "resolved": "https://registry-npm.cbhq.net/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.4.tgz", + "integrity": "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==", + "cpu": [ + "s390x" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.2.4", + "resolved": "https://registry-npm.cbhq.net/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.4.tgz", + "integrity": "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.2.4", + "resolved": "https://registry-npm.cbhq.net/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.4.tgz", + "integrity": "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.2.4", + "resolved": "https://registry-npm.cbhq.net/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.4.tgz", + "integrity": "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.34.5", + "resolved": "https://registry-npm.cbhq.net/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.5.tgz", + "integrity": "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==", + "cpu": [ + "arm" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.34.5", + "resolved": "https://registry-npm.cbhq.net/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.5.tgz", + "integrity": "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-ppc64": { + "version": "0.34.5", + "resolved": "https://registry-npm.cbhq.net/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.5.tgz", + "integrity": "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==", + "cpu": [ + "ppc64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-ppc64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-riscv64": { + "version": "0.34.5", + "resolved": "https://registry-npm.cbhq.net/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.34.5.tgz", + "integrity": "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==", + "cpu": [ + "riscv64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-riscv64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-s390x": { + "version": "0.34.5", + "resolved": "https://registry-npm.cbhq.net/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.5.tgz", + "integrity": "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==", + "cpu": [ + "s390x" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.34.5", + "resolved": "https://registry-npm.cbhq.net/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.5.tgz", + "integrity": "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.34.5", + "resolved": "https://registry-npm.cbhq.net/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.5.tgz", + "integrity": "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.34.5", + "resolved": "https://registry-npm.cbhq.net/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.5.tgz", + "integrity": "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-wasm32": { + "version": "0.34.5", + "resolved": "https://registry-npm.cbhq.net/@img/sharp-wasm32/-/sharp-wasm32-0.34.5.tgz", + "integrity": "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==", + "cpu": [ + "wasm32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.7.0" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-arm64": { + "version": "0.34.5", + "resolved": "https://registry-npm.cbhq.net/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.5.tgz", + "integrity": "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-ia32": { + "version": "0.34.5", + "resolved": "https://registry-npm.cbhq.net/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.5.tgz", + "integrity": "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==", + "cpu": [ + "ia32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.34.5", + "resolved": "https://registry-npm.cbhq.net/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.5.tgz", + "integrity": "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry-npm.cbhq.net/@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/remapping": { + "version": "2.3.5", + "resolved": "https://registry-npm.cbhq.net/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry-npm.cbhq.net/@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/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry-npm.cbhq.net/@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-npm.cbhq.net/@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/@next/env": { + "version": "16.0.7", + "resolved": "https://registry-npm.cbhq.net/@next/env/-/env-16.0.7.tgz", + "integrity": "sha512-gpaNgUh5nftFKRkRQGnVi5dpcYSKGcZZkQffZ172OrG/XkrnS7UBTQ648YY+8ME92cC4IojpI2LqTC8sTDhAaw==", + "license": "MIT" + }, + "node_modules/@next/swc-darwin-arm64": { + "version": "16.0.7", + "resolved": "https://registry-npm.cbhq.net/@next/swc-darwin-arm64/-/swc-darwin-arm64-16.0.7.tgz", + "integrity": "sha512-LlDtCYOEj/rfSnEn/Idi+j1QKHxY9BJFmxx7108A6D8K0SB+bNgfYQATPk/4LqOl4C0Wo3LACg2ie6s7xqMpJg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-darwin-x64": { + "version": "16.0.7", + "resolved": "https://registry-npm.cbhq.net/@next/swc-darwin-x64/-/swc-darwin-x64-16.0.7.tgz", + "integrity": "sha512-rtZ7BhnVvO1ICf3QzfW9H3aPz7GhBrnSIMZyr4Qy6boXF0b5E3QLs+cvJmg3PsTCG2M1PBoC+DANUi4wCOKXpA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-gnu": { + "version": "16.0.7", + "resolved": "https://registry-npm.cbhq.net/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-16.0.7.tgz", + "integrity": "sha512-mloD5WcPIeIeeZqAIP5c2kdaTa6StwP4/2EGy1mUw8HiexSHGK/jcM7lFuS3u3i2zn+xH9+wXJs6njO7VrAqww==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-musl": { + "version": "16.0.7", + "resolved": "https://registry-npm.cbhq.net/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-16.0.7.tgz", + "integrity": "sha512-+ksWNrZrthisXuo9gd1XnjHRowCbMtl/YgMpbRvFeDEqEBd523YHPWpBuDjomod88U8Xliw5DHhekBC3EOOd9g==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-gnu": { + "version": "16.0.7", + "resolved": "https://registry-npm.cbhq.net/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-16.0.7.tgz", + "integrity": "sha512-4WtJU5cRDxpEE44Ana2Xro1284hnyVpBb62lIpU5k85D8xXxatT+rXxBgPkc7C1XwkZMWpK5rXLXTh9PFipWsA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-musl": { + "version": "16.0.7", + "resolved": "https://registry-npm.cbhq.net/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-16.0.7.tgz", + "integrity": "sha512-HYlhqIP6kBPXalW2dbMTSuB4+8fe+j9juyxwfMwCe9kQPPeiyFn7NMjNfoFOfJ2eXkeQsoUGXg+O2SE3m4Qg2w==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-arm64-msvc": { + "version": "16.0.7", + "resolved": "https://registry-npm.cbhq.net/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-16.0.7.tgz", + "integrity": "sha512-EviG+43iOoBRZg9deGauXExjRphhuYmIOJ12b9sAPy0eQ6iwcPxfED2asb/s2/yiLYOdm37kPaiZu8uXSYPs0Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-x64-msvc": { + "version": "16.0.7", + "resolved": "https://registry-npm.cbhq.net/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-16.0.7.tgz", + "integrity": "sha512-gniPjy55zp5Eg0896qSrf3yB1dw4F/3s8VK1ephdsZZ129j2n6e1WqCbE2YgcKhW9hPB9TVZENugquWJD5x0ug==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@noble/ciphers": { + "version": "1.3.0", + "resolved": "https://registry-npm.cbhq.net/@noble/ciphers/-/ciphers-1.3.0.tgz", + "integrity": "sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw==", + "license": "MIT", + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/curves": { + "version": "1.9.1", + "resolved": "https://registry-npm.cbhq.net/@noble/curves/-/curves-1.9.1.tgz", + "integrity": "sha512-k11yZxZg+t+gWvBbIswW0yoJlu8cHOC7dhunwOzoWH/mXGBiYyR4YY6hAEK/3EUs4UpB8la1RfdRpeGsFHkWsA==", + "license": "MIT", + "dependencies": { + "@noble/hashes": "1.8.0" + }, + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/hashes": { + "version": "1.8.0", + "resolved": "https://registry-npm.cbhq.net/@noble/hashes/-/hashes-1.8.0.tgz", + "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", + "license": "MIT", + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/base": { + "version": "1.2.6", + "resolved": "https://registry-npm.cbhq.net/@scure/base/-/base-1.2.6.tgz", + "integrity": "sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg==", + "license": "MIT", + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip32": { + "version": "1.7.0", + "resolved": "https://registry-npm.cbhq.net/@scure/bip32/-/bip32-1.7.0.tgz", + "integrity": "sha512-E4FFX/N3f4B80AKWp5dP6ow+flD1LQZo/w8UnLGYZO674jS6YnYeepycOOksv+vLPSpgN35wgKgy+ybfTb2SMw==", + "license": "MIT", + "dependencies": { + "@noble/curves": "~1.9.0", + "@noble/hashes": "~1.8.0", + "@scure/base": "~1.2.5" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip39": { + "version": "1.6.0", + "resolved": "https://registry-npm.cbhq.net/@scure/bip39/-/bip39-1.6.0.tgz", + "integrity": "sha512-+lF0BbLiJNwVlev4eKelw1WWLaiKXw7sSl8T6FvBlWkdX+94aGJ4o8XjUdlyhTCjd8c+B3KT3JfS8P0bLRNU6A==", + "license": "MIT", + "dependencies": { + "@noble/hashes": "~1.8.0", + "@scure/base": "~1.2.5" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@smithy/config-resolver": { + "version": "4.5.2", + "resolved": "https://registry-npm.cbhq.net/@smithy/config-resolver/-/config-resolver-4.5.2.tgz", + "integrity": "sha512-Gxr1czgeGUKgUJBf3fUSvpb1d+EjEl17f5s8qAzn36QIWmVzNPZQb3C9Rdtfya1yu2qUSAhDGoHUvHI/GJjbBQ==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.24.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/core": { + "version": "3.24.2", + "resolved": "https://registry-npm.cbhq.net/@smithy/core/-/core-3.24.2.tgz", + "integrity": "sha512-IKS7qX59fAGCYBmt5JChcDswQDupZqT2Yn2ZBA3UgTlsjRNNkQzZobbn95xoAAdtTyJmBiJB3Y02qR3rgy3Zog==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/crc32": "5.2.0", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/credential-provider-imds": { + "version": "4.3.2", + "resolved": "https://registry-npm.cbhq.net/@smithy/credential-provider-imds/-/credential-provider-imds-4.3.2.tgz", + "integrity": "sha512-iYr9ekBjmZ+FwkiHEopqGscBbl78X62cq3p5Dd0eC+gNd7fybNZFQQdDuOQjTVmFymleuA8YRWZnuXWZ8B3kKA==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.24.2", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/eventstream-serde-browser": { + "version": "4.3.2", + "resolved": "https://registry-npm.cbhq.net/@smithy/eventstream-serde-browser/-/eventstream-serde-browser-4.3.2.tgz", + "integrity": "sha512-wq3p8g8pyciXSTmysvOvpGeMQaPssgJqyJdfKquwAgpgRW5cKcXb4c0V/K48Lsn24oYK/cox/vHtj/eaGm0PEg==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.24.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/eventstream-serde-config-resolver": { + "version": "4.4.2", + "resolved": "https://registry-npm.cbhq.net/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-4.4.2.tgz", + "integrity": "sha512-/Z4Rn+d/HzU96Ciy2bPDZq2KdlRM18ZhGSiy1lSUZPCpGQxXzGQCIItsk3vMcioBHn8E5t48LEXpTL0rOogrSA==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.24.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/eventstream-serde-node": { + "version": "4.3.2", + "resolved": "https://registry-npm.cbhq.net/@smithy/eventstream-serde-node/-/eventstream-serde-node-4.3.2.tgz", + "integrity": "sha512-D4b+U+tOm9DVB8sk0/iDTVYLtBbid9T4+kX25k3rLie1SNqsaKNPTkx6dTWuB4TGNczKixeTCB4RGiV7KGO4Jw==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.24.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/fetch-http-handler": { + "version": "5.4.2", + "resolved": "https://registry-npm.cbhq.net/@smithy/fetch-http-handler/-/fetch-http-handler-5.4.2.tgz", + "integrity": "sha512-3wF40g8OOCA5BnwQUvwtzZqYBbWWftDjpAlWIUo6Yld3ZzJaMAKqg7MWQBPjE8oLaqvZQUE7tVGlZPsae6A4bQ==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.24.2", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/hash-blob-browser": { + "version": "4.3.2", + "resolved": "https://registry-npm.cbhq.net/@smithy/hash-blob-browser/-/hash-blob-browser-4.3.2.tgz", + "integrity": "sha512-p/X2kAc11zKkSZYW4bQb2CuWB0rZyXz52UAOtDpMpj8gXlVE7K9NU3sqh3gpTsPFS/2qvMoDS/w1a839k+815w==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.24.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/hash-node": { + "version": "4.3.2", + "resolved": "https://registry-npm.cbhq.net/@smithy/hash-node/-/hash-node-4.3.2.tgz", + "integrity": "sha512-27ImyEVgDZ2ZQz1rnQMSlw9rm7x3244oZVIFI1WKi3vNtbxQ75XU2jA9BQuH8eb91zBLlyGjWQ/L/QGvmJfEHA==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.24.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/hash-stream-node": { + "version": "4.3.2", + "resolved": "https://registry-npm.cbhq.net/@smithy/hash-stream-node/-/hash-stream-node-4.3.2.tgz", + "integrity": "sha512-eUIHSr4RWqMQVtsnZ4p4tNDFuyCuOFCO3cfkvMHLbTRUIbCAq/7XEeGor7h0o0KYMGLeBztOKLQ0WQyc0j/8gA==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.24.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/invalid-dependency": { + "version": "4.3.2", + "resolved": "https://registry-npm.cbhq.net/@smithy/invalid-dependency/-/invalid-dependency-4.3.2.tgz", + "integrity": "sha512-bP0RYUtgINyMsUEzTnjnwJ/NX9Aa8y7bj0NbqwrMMqT6vjpp7H9SqGuKsn0+wD+Fu4GXcxUex1mH3k0t6WsatQ==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.24.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/is-array-buffer": { + "version": "4.3.2", + "resolved": "https://registry-npm.cbhq.net/@smithy/is-array-buffer/-/is-array-buffer-4.3.2.tgz", + "integrity": "sha512-JYNfdKj1kr3ke+Pip+qxiuXW/OuSe8KlCyJz93bU25uKVq6wQGdm6H0/1g2XoFjehJFUmNdS+2/nM6Oabe6/+A==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.24.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/md5-js": { + "version": "4.3.2", + "resolved": "https://registry-npm.cbhq.net/@smithy/md5-js/-/md5-js-4.3.2.tgz", + "integrity": "sha512-i7ES+52XcEuvIYaZrSePh8YHoLjI43hC3HO/KLO2osWEaUdX8kh4YpE6/iyfVud1M1vB3zEGHvwmsmqxDhw/Xw==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.24.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/middleware-content-length": { + "version": "4.3.2", + "resolved": "https://registry-npm.cbhq.net/@smithy/middleware-content-length/-/middleware-content-length-4.3.2.tgz", + "integrity": "sha512-Zq4MFXu6Cl/00FKXcc6mkio0xzd6D9Q8+AmtBOC6vHpN6Fz1MButZ0zfL46WxhJH/JgKjv5xl4Qo8HZsr6sDBg==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.24.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/middleware-endpoint": { + "version": "4.5.2", + "resolved": "https://registry-npm.cbhq.net/@smithy/middleware-endpoint/-/middleware-endpoint-4.5.2.tgz", + "integrity": "sha512-1aiE05F2Er+ZYvGfrfI0+JRNeFY4M+hSjUp0SIKyq98k9iC0Lo71XwLbKWcFgFBZuhg5n6i+MQzRVmeCDlWOjw==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.24.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/middleware-retry": { + "version": "4.6.2", + "resolved": "https://registry-npm.cbhq.net/@smithy/middleware-retry/-/middleware-retry-4.6.2.tgz", + "integrity": "sha512-ovt2p0LV3sSRpt8EBajI6imGMz/kq8F73P0eSOq6bhtvcOZM3xODFOjk6Lz2KvKfe7dVlxpNIiOYYyVe8ofv0A==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.24.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/middleware-serde": { + "version": "4.3.2", + "resolved": "https://registry-npm.cbhq.net/@smithy/middleware-serde/-/middleware-serde-4.3.2.tgz", + "integrity": "sha512-hM3b9/JgMjohYHcgh5780ymND7RWGvYuyjNDtQL6P/DawtdbUu5m4oon4FHas+rmjdQ2DHee3cmAetTgU6keJw==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.24.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/middleware-stack": { + "version": "4.3.2", + "resolved": "https://registry-npm.cbhq.net/@smithy/middleware-stack/-/middleware-stack-4.3.2.tgz", + "integrity": "sha512-WthvBnmmksOBbW2I8CRc35QUJn/whgXucpW/hNmE70znXG16/yuC7LGtbDYTr7ak+LNZKzBGmaQR1uDNpeBd1g==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.24.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/node-config-provider": { + "version": "4.4.2", + "resolved": "https://registry-npm.cbhq.net/@smithy/node-config-provider/-/node-config-provider-4.4.2.tgz", + "integrity": "sha512-LKup5BaU51fQM1YI/T64SJnn561tUPCfbpStnEygz5u1AqSAOALYY4e8imzz2EuMjcUtaYhOBtMazaN3TRXTgw==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.24.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/node-http-handler": { + "version": "4.7.2", + "resolved": "https://registry-npm.cbhq.net/@smithy/node-http-handler/-/node-http-handler-4.7.2.tgz", + "integrity": "sha512-EdksTZ8UXYxGUgQ4mpIKrHoaj9WVGsp66TpZuixLAz1Jex8YDLnS4RH9ktGED5aOpN0OJlEtrsC9IGt76go1eA==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.24.2", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/property-provider": { + "version": "4.3.2", + "resolved": "https://registry-npm.cbhq.net/@smithy/property-provider/-/property-provider-4.3.2.tgz", + "integrity": "sha512-utUCslUrmJxKqSEidPhE1yfBgox78yhZQcHfdU4qvh79Rhi0nNKq6xNG4J/IwPD+Pm9y7a5FdXOgJxmHU5CGoA==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.24.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/protocol-http": { + "version": "5.4.2", + "resolved": "https://registry-npm.cbhq.net/@smithy/protocol-http/-/protocol-http-5.4.2.tgz", + "integrity": "sha512-rUvFCkbaHglm1zgOJ3QKFcD8jx/e68OUme3n+kAEiefAcGHK46UtmIT0/cuVLuiuSZzTqo8ts0Ju5hy9wqMGZA==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.24.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/shared-ini-file-loader": { + "version": "4.5.2", + "resolved": "https://registry-npm.cbhq.net/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-4.5.2.tgz", + "integrity": "sha512-4Cyy2IrFCgZBdw8G5eqB0G5FQ3HwH9FRYMJXGAMdo7hVIguVwQtLvEMmveIBlHf6hKQBd116M9IQRCA/7sxrpg==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.24.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/signature-v4": { + "version": "5.4.2", + "resolved": "https://registry-npm.cbhq.net/@smithy/signature-v4/-/signature-v4-5.4.2.tgz", + "integrity": "sha512-1km1OjdLRFuITWpCPofjFqzZ+tbeWuB72ZhcYjbjkCxZ21tTPfIs4GUxRrelMyKMLxLghGD58RENnXorU/O8cw==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.24.2", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/smithy-client": { + "version": "4.13.2", + "resolved": "https://registry-npm.cbhq.net/@smithy/smithy-client/-/smithy-client-4.13.2.tgz", + "integrity": "sha512-lK+Ssl8FzZHvdiPwB6qWLlPV6ih8FCr2BbRV+6/7QWabtMoiTbMTiGrrKsfKu6fcYzt+5akGAY7Xqna+EySq5g==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.24.2", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/types": { + "version": "4.14.1", + "resolved": "https://registry-npm.cbhq.net/@smithy/types/-/types-4.14.1.tgz", + "integrity": "sha512-59b5HtSVrVR/eYNei3BUj3DCPKD/G7EtDDe7OEJE7i7FtQFugYo6MxbotS8mVJkLNVf8gYaAlEBwwtJ9HzhWSg==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/url-parser": { + "version": "4.3.2", + "resolved": "https://registry-npm.cbhq.net/@smithy/url-parser/-/url-parser-4.3.2.tgz", + "integrity": "sha512-ADEFjhX7Iv+cWrwkK+31tqoUzICzYAjB8GvpGDMoCQ71CA519Qd1ZRg1gDveYe20WQJxwW/ls4F0fSMZZTZnQQ==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.24.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-base64": { + "version": "4.4.2", + "resolved": "https://registry-npm.cbhq.net/@smithy/util-base64/-/util-base64-4.4.2.tgz", + "integrity": "sha512-+dxoGuQMmtP/m3ApPgliWQOTasVP9AHaKWCvczdiJlYk0SmTWrXMKq3lyiooeqMXWLuptcptQPiUYPitGzJjQQ==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.24.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-body-length-browser": { + "version": "4.3.2", + "resolved": "https://registry-npm.cbhq.net/@smithy/util-body-length-browser/-/util-body-length-browser-4.3.2.tgz", + "integrity": "sha512-69ETVcLni5dcIneXl7/Kc9Km/MqxOB4rGtr0zhuiVAz6mEr4QLo0P+c9bHZZzqrL5Tizd3fbPOVYpUOW1w4+MQ==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.24.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-body-length-node": { + "version": "4.3.2", + "resolved": "https://registry-npm.cbhq.net/@smithy/util-body-length-node/-/util-body-length-node-4.3.2.tgz", + "integrity": "sha512-P6E2/3h8FZgMadSoUx/xZALw8pwDBQux4W/AYu1TwM/icy/P2G0LXjhLkBclgaR6AJr6xXjaT5p+vivgIQ+wYQ==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.24.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-buffer-from": { + "version": "2.2.0", + "resolved": "https://registry-npm.cbhq.net/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", + "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/is-array-buffer": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/util-buffer-from/node_modules/@smithy/is-array-buffer": { + "version": "2.2.0", + "resolved": "https://registry-npm.cbhq.net/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", + "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/util-config-provider": { + "version": "4.3.2", + "resolved": "https://registry-npm.cbhq.net/@smithy/util-config-provider/-/util-config-provider-4.3.2.tgz", + "integrity": "sha512-gVuLsMyqePBzTD4BY+VeOxT/o09t+QEwGClHh7yNDL7Wl+XktX6qXmAkAAjAAzOPI8u+ZpoQFq9+ooH2ftKnFw==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.24.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-defaults-mode-browser": { + "version": "4.4.2", + "resolved": "https://registry-npm.cbhq.net/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.4.2.tgz", + "integrity": "sha512-e9TZwwffgUFLgafwzyx4wNnxtgbipHG515xHmurkmjtuyJyCRkAn+Tbd4+iF/fnoCyeJXsZAzPX/OSo2nW9XOQ==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.24.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-defaults-mode-node": { + "version": "4.3.2", + "resolved": "https://registry-npm.cbhq.net/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.3.2.tgz", + "integrity": "sha512-RsmNY73PM8iO8iRreeXxE3MwY/kRRvBlbJpfm3VKMJc6MQ7vN+LulWj+VrDh+Wf5jCLdQyP43OrTSEH8d/lpCA==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.24.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-endpoints": { + "version": "3.5.2", + "resolved": "https://registry-npm.cbhq.net/@smithy/util-endpoints/-/util-endpoints-3.5.2.tgz", + "integrity": "sha512-3qGB71aqXTJnNqNlOh3R9u+9nVbR3qgd7BhtBj1Na/fgD/KAJ/+nkUHt/CGmWyEa+P1Jl361hRO2zwlMvuKJGA==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.24.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-middleware": { + "version": "4.3.2", + "resolved": "https://registry-npm.cbhq.net/@smithy/util-middleware/-/util-middleware-4.3.2.tgz", + "integrity": "sha512-0GFlqDcWjnJT+TsAj91L4iTPvpR7VySjsALxtGROZaIfR03LLM69nmJDr3V/GjhZfyv/DWlFEnAWyaoKkmby1g==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.24.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-retry": { + "version": "4.4.2", + "resolved": "https://registry-npm.cbhq.net/@smithy/util-retry/-/util-retry-4.4.2.tgz", + "integrity": "sha512-CwOWVLoMWyeHxaFM9a6jpq47yFKx2awaa8oFzQ6e+c5qlIATVc8MX0aN2PGuTgCaTZw//BDgHSjdAFaSbdbJRg==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.24.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-stream": { + "version": "4.6.2", + "resolved": "https://registry-npm.cbhq.net/@smithy/util-stream/-/util-stream-4.6.2.tgz", + "integrity": "sha512-b5kyVsNM3pU36cJGyxwAQajGxs4JkNuaKKNufDu7oASWmzKG5gtXEdVK1rvz99O2JV1B85Pp9bAcN7fXWbN6Aw==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.24.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-utf8": { + "version": "4.3.2", + "resolved": "https://registry-npm.cbhq.net/@smithy/util-utf8/-/util-utf8-4.3.2.tgz", + "integrity": "sha512-Bswgu9zDwZRp5HBQKIaW6QrKrbwQ9RuOyAg2adsIjJTHA2SmE0XXBk+mYP82Ay6I3XzkY5lM7K9R0XZDFzJ3tw==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.24.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-waiter": { + "version": "4.4.2", + "resolved": "https://registry-npm.cbhq.net/@smithy/util-waiter/-/util-waiter-4.4.2.tgz", + "integrity": "sha512-2lAaVh9CAMVi0yI5nGX8nFeZed2v3CstXqX9sqYcIo2OjABSziqk/o/xekYsNHI4nwLzXeTazcm+eN7DpdSbLA==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.24.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@swc/helpers": { + "version": "0.5.15", + "resolved": "https://registry-npm.cbhq.net/@swc/helpers/-/helpers-0.5.15.tgz", + "integrity": "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.8.0" + } + }, + "node_modules/@tailwindcss/node": { + "version": "4.1.17", + "resolved": "https://registry-npm.cbhq.net/@tailwindcss/node/-/node-4.1.17.tgz", + "integrity": "sha512-csIkHIgLb3JisEFQ0vxr2Y57GUNYh447C8xzwj89U/8fdW8LhProdxvnVH6U8M2Y73QKiTIH+LWbK3V2BBZsAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/remapping": "^2.3.4", + "enhanced-resolve": "^5.18.3", + "jiti": "^2.6.1", + "lightningcss": "1.30.2", + "magic-string": "^0.30.21", + "source-map-js": "^1.2.1", + "tailwindcss": "4.1.17" + } + }, + "node_modules/@tailwindcss/oxide": { + "version": "4.1.17", + "resolved": "https://registry-npm.cbhq.net/@tailwindcss/oxide/-/oxide-4.1.17.tgz", + "integrity": "sha512-F0F7d01fmkQhsTjXezGBLdrl1KresJTcI3DB8EkScCldyKp3Msz4hub4uyYaVnk88BAS1g5DQjjF6F5qczheLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10" + }, + "optionalDependencies": { + "@tailwindcss/oxide-android-arm64": "4.1.17", + "@tailwindcss/oxide-darwin-arm64": "4.1.17", + "@tailwindcss/oxide-darwin-x64": "4.1.17", + "@tailwindcss/oxide-freebsd-x64": "4.1.17", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.17", + "@tailwindcss/oxide-linux-arm64-gnu": "4.1.17", + "@tailwindcss/oxide-linux-arm64-musl": "4.1.17", + "@tailwindcss/oxide-linux-x64-gnu": "4.1.17", + "@tailwindcss/oxide-linux-x64-musl": "4.1.17", + "@tailwindcss/oxide-wasm32-wasi": "4.1.17", + "@tailwindcss/oxide-win32-arm64-msvc": "4.1.17", + "@tailwindcss/oxide-win32-x64-msvc": "4.1.17" + } + }, + "node_modules/@tailwindcss/oxide-android-arm64": { + "version": "4.1.17", + "resolved": "https://registry-npm.cbhq.net/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.17.tgz", + "integrity": "sha512-BMqpkJHgOZ5z78qqiGE6ZIRExyaHyuxjgrJ6eBO5+hfrfGkuya0lYfw8fRHG77gdTjWkNWEEm+qeG2cDMxArLQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-darwin-arm64": { + "version": "4.1.17", + "resolved": "https://registry-npm.cbhq.net/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.17.tgz", + "integrity": "sha512-EquyumkQweUBNk1zGEU/wfZo2qkp/nQKRZM8bUYO0J+Lums5+wl2CcG1f9BgAjn/u9pJzdYddHWBiFXJTcxmOg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-darwin-x64": { + "version": "4.1.17", + "resolved": "https://registry-npm.cbhq.net/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.17.tgz", + "integrity": "sha512-gdhEPLzke2Pog8s12oADwYu0IAw04Y2tlmgVzIN0+046ytcgx8uZmCzEg4VcQh+AHKiS7xaL8kGo/QTiNEGRog==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-freebsd-x64": { + "version": "4.1.17", + "resolved": "https://registry-npm.cbhq.net/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.17.tgz", + "integrity": "sha512-hxGS81KskMxML9DXsaXT1H0DyA+ZBIbyG/sSAjWNe2EDl7TkPOBI42GBV3u38itzGUOmFfCzk1iAjDXds8Oh0g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { + "version": "4.1.17", + "resolved": "https://registry-npm.cbhq.net/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.17.tgz", + "integrity": "sha512-k7jWk5E3ldAdw0cNglhjSgv501u7yrMf8oeZ0cElhxU6Y2o7f8yqelOp3fhf7evjIS6ujTI3U8pKUXV2I4iXHQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { + "version": "4.1.17", + "resolved": "https://registry-npm.cbhq.net/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.17.tgz", + "integrity": "sha512-HVDOm/mxK6+TbARwdW17WrgDYEGzmoYayrCgmLEw7FxTPLcp/glBisuyWkFz/jb7ZfiAXAXUACfyItn+nTgsdQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-musl": { + "version": "4.1.17", + "resolved": "https://registry-npm.cbhq.net/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.17.tgz", + "integrity": "sha512-HvZLfGr42i5anKtIeQzxdkw/wPqIbpeZqe7vd3V9vI3RQxe3xU1fLjss0TjyhxWcBaipk7NYwSrwTwK1hJARMg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-gnu": { + "version": "4.1.17", + "resolved": "https://registry-npm.cbhq.net/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.17.tgz", + "integrity": "sha512-M3XZuORCGB7VPOEDH+nzpJ21XPvK5PyjlkSFkFziNHGLc5d6g3di2McAAblmaSUNl8IOmzYwLx9NsE7bplNkwQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-musl": { + "version": "4.1.17", + "resolved": "https://registry-npm.cbhq.net/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.17.tgz", + "integrity": "sha512-k7f+pf9eXLEey4pBlw+8dgfJHY4PZ5qOUFDyNf7SI6lHjQ9Zt7+NcscjpwdCEbYi6FI5c2KDTDWyf2iHcCSyyQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi": { + "version": "4.1.17", + "resolved": "https://registry-npm.cbhq.net/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.17.tgz", + "integrity": "sha512-cEytGqSSoy7zK4JRWiTCx43FsKP/zGr0CsuMawhH67ONlH+T79VteQeJQRO/X7L0juEUA8ZyuYikcRBf0vsxhg==", + "bundleDependencies": [ + "@napi-rs/wasm-runtime", + "@emnapi/core", + "@emnapi/runtime", + "@tybys/wasm-util", + "@emnapi/wasi-threads", + "tslib" + ], + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.6.0", + "@emnapi/runtime": "^1.6.0", + "@emnapi/wasi-threads": "^1.1.0", + "@napi-rs/wasm-runtime": "^1.0.7", + "@tybys/wasm-util": "^0.10.1", + "tslib": "^2.4.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { + "version": "4.1.17", + "resolved": "https://registry-npm.cbhq.net/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.17.tgz", + "integrity": "sha512-JU5AHr7gKbZlOGvMdb4722/0aYbU+tN6lv1kONx0JK2cGsh7g148zVWLM0IKR3NeKLv+L90chBVYcJ8uJWbC9A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-win32-x64-msvc": { + "version": "4.1.17", + "resolved": "https://registry-npm.cbhq.net/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.17.tgz", + "integrity": "sha512-SKWM4waLuqx0IH+FMDUw6R66Hu4OuTALFgnleKbqhgGU30DY20NORZMZUKgLRjQXNN2TLzKvh48QXTig4h4bGw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/postcss": { + "version": "4.1.17", + "resolved": "https://registry-npm.cbhq.net/@tailwindcss/postcss/-/postcss-4.1.17.tgz", + "integrity": "sha512-+nKl9N9mN5uJ+M7dBOOCzINw94MPstNR/GtIhz1fpZysxL/4a+No64jCBD6CPN+bIHWFx3KWuu8XJRrj/572Dw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@alloc/quick-lru": "^5.2.0", + "@tailwindcss/node": "4.1.17", + "@tailwindcss/oxide": "4.1.17", + "postcss": "^8.4.41", + "tailwindcss": "4.1.17" + } + }, + "node_modules/@types/better-sqlite3": { + "version": "7.6.13", + "resolved": "https://registry-npm.cbhq.net/@types/better-sqlite3/-/better-sqlite3-7.6.13.tgz", + "integrity": "sha512-NMv9ASNARoKksWtsq/SHakpYAYnhBrQgGD8zkLYk/jaK8jUGn08CfEdTRgYhMypUQAfzSP8W6gNLe0q19/t4VA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/node": { + "version": "20.19.25", + "resolved": "https://registry-npm.cbhq.net/@types/node/-/node-20.19.25.tgz", + "integrity": "sha512-ZsJzA5thDQMSQO788d7IocwwQbI8B5OPzmqNvpf3NY/+MHDAS759Wo0gd2WQeXYt5AAAQjzcrTVC6SKCuYgoCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@types/react": { + "version": "19.2.7", + "resolved": "https://registry-npm.cbhq.net/@types/react/-/react-19.2.7.tgz", + "integrity": "sha512-MWtvHrGZLFttgeEj28VXHxpmwYbor/ATPYbBfSFZEIRK0ecCFLl2Qo55z52Hss+UV9CRN7trSeq1zbgx7YDWWg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "csstype": "^3.2.2" + } + }, + "node_modules/@types/react-dom": { + "version": "19.2.3", + "resolved": "https://registry-npm.cbhq.net/@types/react-dom/-/react-dom-19.2.3.tgz", + "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^19.2.0" + } + }, + "node_modules/abitype": { + "version": "1.1.0", + "resolved": "https://registry-npm.cbhq.net/abitype/-/abitype-1.1.0.tgz", + "integrity": "sha512-6Vh4HcRxNMLA0puzPjM5GBgT4aAcFGKZzSgAXvuZ27shJP6NEpielTuqbBmZILR5/xd0PizkBGy5hReKz9jl5A==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/wevm" + }, + "peerDependencies": { + "typescript": ">=5.0.4", + "zod": "^3.22.0 || ^4.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + }, + "zod": { + "optional": true + } + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry-npm.cbhq.net/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/better-sqlite3": { + "version": "12.10.0", + "resolved": "https://registry-npm.cbhq.net/better-sqlite3/-/better-sqlite3-12.10.0.tgz", + "integrity": "sha512-CyzaZRQKyHkB2ZInfTTl2nvT33EbDpjkLEbE8/Zck3Ll6O0qqvuGdrJ45HgtH+HykRg88ITY3AdreBGN70aBSQ==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "bindings": "^1.5.0", + "prebuild-install": "^7.1.1" + }, + "engines": { + "node": "20.x || 22.x || 23.x || 24.x || 25.x || 26.x" + } + }, + "node_modules/bindings": { + "version": "1.5.0", + "resolved": "https://registry-npm.cbhq.net/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "file-uri-to-path": "1.0.0" + } + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry-npm.cbhq.net/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/bowser": { + "version": "2.14.1", + "resolved": "https://registry-npm.cbhq.net/bowser/-/bowser-2.14.1.tgz", + "integrity": "sha512-tzPjzCxygAKWFOJP011oxFHs57HzIhOEracIgAePE4pqB3LikALKnSzUyU4MGs9/iCEUuHlAJTjTc5M+u7YEGg==", + "license": "MIT" + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry-npm.cbhq.net/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001792", + "resolved": "https://registry-npm.cbhq.net/caniuse-lite/-/caniuse-lite-1.0.30001792.tgz", + "integrity": "sha512-hVLMUZFgR4JJ6ACt1uEESvQN1/dBVqPAKY0hgrV70eN3391K6juAfTjKZLKvOMsx8PxA7gsY1/tLMMTcfFLLpw==", + "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/chownr": { + "version": "1.1.4", + "resolved": "https://registry-npm.cbhq.net/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true, + "license": "ISC" + }, + "node_modules/client-only": { + "version": "0.0.1", + "resolved": "https://registry-npm.cbhq.net/client-only/-/client-only-0.0.1.tgz", + "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==", + "license": "MIT" + }, + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry-npm.cbhq.net/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry-npm.cbhq.net/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry-npm.cbhq.net/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/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry-npm.cbhq.net/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "devOptional": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.5", + "resolved": "https://registry-npm.cbhq.net/end-of-stream/-/end-of-stream-1.4.5.tgz", + "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/enhanced-resolve": { + "version": "5.21.3", + "resolved": "https://registry-npm.cbhq.net/enhanced-resolve/-/enhanced-resolve-5.21.3.tgz", + "integrity": "sha512-QyL119InA+XXEkNLNTPCXPugSvOfhwv0JOlGNzvxs0hZaiHLNvXSpudUWsOlsXGWJh8G6ckCScEkVHfX3kw/2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.3.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry-npm.cbhq.net/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "license": "MIT" + }, + "node_modules/expand-template": { + "version": "2.0.3", + "resolved": "https://registry-npm.cbhq.net/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", + "dev": true, + "license": "(MIT OR WTFPL)", + "engines": { + "node": ">=6" + } + }, + "node_modules/fast-xml-parser": { + "version": "5.2.5", + "resolved": "https://registry-npm.cbhq.net/fast-xml-parser/-/fast-xml-parser-5.2.5.tgz", + "integrity": "sha512-pfX9uG9Ki0yekDHx2SiuRIyFdyAr1kMIMitPvb0YBo8SUfKvia7w7FIyd/l6av85pFYRhZscS75MwMnbvY+hcQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT", + "dependencies": { + "strnum": "^2.1.0" + }, + "bin": { + "fxparser": "src/cli/cli.js" + } + }, + "node_modules/file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry-npm.cbhq.net/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry-npm.cbhq.net/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "dev": true, + "license": "MIT" + }, + "node_modules/github-from-package": { + "version": "0.0.0", + "resolved": "https://registry-npm.cbhq.net/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", + "dev": true, + "license": "MIT" + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry-npm.cbhq.net/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/ieee754": { + "version": "1.2.1", + "resolved": "https://registry-npm.cbhq.net/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry-npm.cbhq.net/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry-npm.cbhq.net/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true, + "license": "ISC" + }, + "node_modules/isows": { + "version": "1.0.7", + "resolved": "https://registry-npm.cbhq.net/isows/-/isows-1.0.7.tgz", + "integrity": "sha512-I1fSfDCZL5P0v33sVqeTDSpcstAg/N+wF5HS033mogOVIp4B+oHC7oOCsA3axAbBSGTJ8QubbNmnIRN/h8U7hg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/wevm" + } + ], + "license": "MIT", + "peerDependencies": { + "ws": "*" + } + }, + "node_modules/jiti": { + "version": "2.7.0", + "resolved": "https://registry-npm.cbhq.net/jiti/-/jiti-2.7.0.tgz", + "integrity": "sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/lightningcss": { + "version": "1.30.2", + "resolved": "https://registry-npm.cbhq.net/lightningcss/-/lightningcss-1.30.2.tgz", + "integrity": "sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.30.2", + "lightningcss-darwin-arm64": "1.30.2", + "lightningcss-darwin-x64": "1.30.2", + "lightningcss-freebsd-x64": "1.30.2", + "lightningcss-linux-arm-gnueabihf": "1.30.2", + "lightningcss-linux-arm64-gnu": "1.30.2", + "lightningcss-linux-arm64-musl": "1.30.2", + "lightningcss-linux-x64-gnu": "1.30.2", + "lightningcss-linux-x64-musl": "1.30.2", + "lightningcss-win32-arm64-msvc": "1.30.2", + "lightningcss-win32-x64-msvc": "1.30.2" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.30.2", + "resolved": "https://registry-npm.cbhq.net/lightningcss-android-arm64/-/lightningcss-android-arm64-1.30.2.tgz", + "integrity": "sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.30.2", + "resolved": "https://registry-npm.cbhq.net/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.2.tgz", + "integrity": "sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.30.2", + "resolved": "https://registry-npm.cbhq.net/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.2.tgz", + "integrity": "sha512-oBZgKchomuDYxr7ilwLcyms6BCyLn0z8J0+ZZmfpjwg9fRVZIR5/GMXd7r9RH94iDhld3UmSjBM6nXWM2TfZTQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.30.2", + "resolved": "https://registry-npm.cbhq.net/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.2.tgz", + "integrity": "sha512-c2bH6xTrf4BDpK8MoGG4Bd6zAMZDAXS569UxCAGcA7IKbHNMlhGQ89eRmvpIUGfKWNVdbhSbkQaWhEoMGmGslA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.30.2", + "resolved": "https://registry-npm.cbhq.net/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.2.tgz", + "integrity": "sha512-eVdpxh4wYcm0PofJIZVuYuLiqBIakQ9uFZmipf6LF/HRj5Bgm0eb3qL/mr1smyXIS1twwOxNWndd8z0E374hiA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.30.2", + "resolved": "https://registry-npm.cbhq.net/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.2.tgz", + "integrity": "sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.30.2", + "resolved": "https://registry-npm.cbhq.net/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.2.tgz", + "integrity": "sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.30.2", + "resolved": "https://registry-npm.cbhq.net/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.2.tgz", + "integrity": "sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.30.2", + "resolved": "https://registry-npm.cbhq.net/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.2.tgz", + "integrity": "sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.30.2", + "resolved": "https://registry-npm.cbhq.net/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.2.tgz", + "integrity": "sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.30.2", + "resolved": "https://registry-npm.cbhq.net/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.2.tgz", + "integrity": "sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry-npm.cbhq.net/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry-npm.cbhq.net/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry-npm.cbhq.net/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry-npm.cbhq.net/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", + "dev": true, + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.12", + "resolved": "https://registry-npm.cbhq.net/nanoid/-/nanoid-3.3.12.tgz", + "integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/napi-build-utils": { + "version": "2.0.0", + "resolved": "https://registry-npm.cbhq.net/napi-build-utils/-/napi-build-utils-2.0.0.tgz", + "integrity": "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==", + "dev": true, + "license": "MIT" + }, + "node_modules/next": { + "version": "16.0.7", + "resolved": "https://registry-npm.cbhq.net/next/-/next-16.0.7.tgz", + "integrity": "sha512-3mBRJyPxT4LOxAJI6IsXeFtKfiJUbjCLgvXO02fV8Wy/lIhPvP94Fe7dGhUgHXcQy4sSuYwQNcOLhIfOm0rL0A==", + "deprecated": "This version has a security vulnerability. Please upgrade to a patched version. See https://nextjs.org/blog/security-update-2025-12-11 for more details.", + "license": "MIT", + "dependencies": { + "@next/env": "16.0.7", + "@swc/helpers": "0.5.15", + "caniuse-lite": "^1.0.30001579", + "postcss": "8.4.31", + "styled-jsx": "5.1.6" + }, + "bin": { + "next": "dist/bin/next" + }, + "engines": { + "node": ">=20.9.0" + }, + "optionalDependencies": { + "@next/swc-darwin-arm64": "16.0.7", + "@next/swc-darwin-x64": "16.0.7", + "@next/swc-linux-arm64-gnu": "16.0.7", + "@next/swc-linux-arm64-musl": "16.0.7", + "@next/swc-linux-x64-gnu": "16.0.7", + "@next/swc-linux-x64-musl": "16.0.7", + "@next/swc-win32-arm64-msvc": "16.0.7", + "@next/swc-win32-x64-msvc": "16.0.7", + "sharp": "^0.34.4" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.1.0", + "@playwright/test": "^1.51.1", + "babel-plugin-react-compiler": "*", + "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", + "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", + "sass": "^1.3.0" + }, + "peerDependenciesMeta": { + "@opentelemetry/api": { + "optional": true + }, + "@playwright/test": { + "optional": true + }, + "babel-plugin-react-compiler": { + "optional": true + }, + "sass": { + "optional": true + } + } + }, + "node_modules/next/node_modules/postcss": { + "version": "8.4.31", + "resolved": "https://registry-npm.cbhq.net/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/node-abi": { + "version": "3.92.0", + "resolved": "https://registry-npm.cbhq.net/node-abi/-/node-abi-3.92.0.tgz", + "integrity": "sha512-KdHvFWZjEKDf0cakgFjebl371GPsISX2oZHcuyKqM7DtogIsHrqKeLTo8wBHxaXRAQlY2PsPlZmfo+9ZCxEREQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry-npm.cbhq.net/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/ox": { + "version": "0.9.6", + "resolved": "https://registry-npm.cbhq.net/ox/-/ox-0.9.6.tgz", + "integrity": "sha512-8SuCbHPvv2eZLYXrNmC0EC12rdzXQLdhnOMlHDW2wiCPLxBrOOJwX5L5E61by+UjTPOryqQiRSnjIKCI+GykKg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/wevm" + } + ], + "license": "MIT", + "dependencies": { + "@adraffy/ens-normalize": "^1.11.0", + "@noble/ciphers": "^1.3.0", + "@noble/curves": "1.9.1", + "@noble/hashes": "^1.8.0", + "@scure/bip32": "^1.7.0", + "@scure/bip39": "^1.6.0", + "abitype": "^1.0.9", + "eventemitter3": "5.0.1" + }, + "peerDependencies": { + "typescript": ">=5.4.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry-npm.cbhq.net/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/postcss": { + "version": "8.5.14", + "resolved": "https://registry-npm.cbhq.net/postcss/-/postcss-8.5.14.tgz", + "integrity": "sha512-SoSL4+OSEtR99LHFZQiJLkT59C5B1amGO1NzTwj7TT1qCUgUO6hxOvzkOYxD+vMrXBM3XJIKzokoERdqQq/Zmg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/prebuild-install": { + "version": "7.1.3", + "resolved": "https://registry-npm.cbhq.net/prebuild-install/-/prebuild-install-7.1.3.tgz", + "integrity": "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==", + "deprecated": "No longer maintained. Please contact the author of the relevant native addon; alternatives are available.", + "dev": true, + "license": "MIT", + "dependencies": { + "detect-libc": "^2.0.0", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^2.0.0", + "node-abi": "^3.3.0", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^4.0.0", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0" + }, + "bin": { + "prebuild-install": "bin.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/pump": { + "version": "3.0.4", + "resolved": "https://registry-npm.cbhq.net/pump/-/pump-3.0.4.tgz", + "integrity": "sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry-npm.cbhq.net/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/react": { + "version": "19.2.1", + "resolved": "https://registry-npm.cbhq.net/react/-/react-19.2.1.tgz", + "integrity": "sha512-DGrYcCWK7tvYMnWh79yrPHt+vdx9tY+1gPZa7nJQtO/p8bLTDaHp4dzwEhQB7pZ4Xe3ok4XKuEPrVuc+wlpkmw==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "19.2.1", + "resolved": "https://registry-npm.cbhq.net/react-dom/-/react-dom-19.2.1.tgz", + "integrity": "sha512-ibrK8llX2a4eOskq1mXKu/TGZj9qzomO+sNfO98M6d9zIPOEhlBkMkBUBLd1vgS0gQsLDBzA+8jJBVXDnfHmJg==", + "license": "MIT", + "peer": true, + "dependencies": { + "scheduler": "^0.27.0" + }, + "peerDependencies": { + "react": "^19.2.1" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry-npm.cbhq.net/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/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry-npm.cbhq.net/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/scheduler": { + "version": "0.27.0", + "resolved": "https://registry-npm.cbhq.net/scheduler/-/scheduler-0.27.0.tgz", + "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", + "license": "MIT" + }, + "node_modules/semver": { + "version": "7.8.0", + "resolved": "https://registry-npm.cbhq.net/semver/-/semver-7.8.0.tgz", + "integrity": "sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==", + "devOptional": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/sharp": { + "version": "0.34.5", + "resolved": "https://registry-npm.cbhq.net/sharp/-/sharp-0.34.5.tgz", + "integrity": "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==", + "hasInstallScript": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@img/colour": "^1.0.0", + "detect-libc": "^2.1.2", + "semver": "^7.7.3" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.34.5", + "@img/sharp-darwin-x64": "0.34.5", + "@img/sharp-libvips-darwin-arm64": "1.2.4", + "@img/sharp-libvips-darwin-x64": "1.2.4", + "@img/sharp-libvips-linux-arm": "1.2.4", + "@img/sharp-libvips-linux-arm64": "1.2.4", + "@img/sharp-libvips-linux-ppc64": "1.2.4", + "@img/sharp-libvips-linux-riscv64": "1.2.4", + "@img/sharp-libvips-linux-s390x": "1.2.4", + "@img/sharp-libvips-linux-x64": "1.2.4", + "@img/sharp-libvips-linuxmusl-arm64": "1.2.4", + "@img/sharp-libvips-linuxmusl-x64": "1.2.4", + "@img/sharp-linux-arm": "0.34.5", + "@img/sharp-linux-arm64": "0.34.5", + "@img/sharp-linux-ppc64": "0.34.5", + "@img/sharp-linux-riscv64": "0.34.5", + "@img/sharp-linux-s390x": "0.34.5", + "@img/sharp-linux-x64": "0.34.5", + "@img/sharp-linuxmusl-arm64": "0.34.5", + "@img/sharp-linuxmusl-x64": "0.34.5", + "@img/sharp-wasm32": "0.34.5", + "@img/sharp-win32-arm64": "0.34.5", + "@img/sharp-win32-ia32": "0.34.5", + "@img/sharp-win32-x64": "0.34.5" + } + }, + "node_modules/simple-concat": { + "version": "1.0.1", + "resolved": "https://registry-npm.cbhq.net/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "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/simple-get": { + "version": "4.0.1", + "resolved": "https://registry-npm.cbhq.net/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", + "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": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry-npm.cbhq.net/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry-npm.cbhq.net/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/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry-npm.cbhq.net/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/strnum": { + "version": "2.3.0", + "resolved": "https://registry-npm.cbhq.net/strnum/-/strnum-2.3.0.tgz", + "integrity": "sha512-ums3KNd42PGyx5xaoVTO1mjU1bH3NpY4vsrVlnv9PNGqQj8wd7rJ6nEypLrJ7z5vxK5RP0yMLo6J/Gsm62DI5Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT" + }, + "node_modules/styled-jsx": { + "version": "5.1.6", + "resolved": "https://registry-npm.cbhq.net/styled-jsx/-/styled-jsx-5.1.6.tgz", + "integrity": "sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==", + "license": "MIT", + "dependencies": { + "client-only": "0.0.1" + }, + "engines": { + "node": ">= 12.0.0" + }, + "peerDependencies": { + "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "babel-plugin-macros": { + "optional": true + } + } + }, + "node_modules/tailwindcss": { + "version": "4.1.17", + "resolved": "https://registry-npm.cbhq.net/tailwindcss/-/tailwindcss-4.1.17.tgz", + "integrity": "sha512-j9Ee2YjuQqYT9bbRTfTZht9W/ytp5H+jJpZKiYdP/bpnXARAuELt9ofP0lPnmHjbga7SNQIxdTAXCmtKVYjN+Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/tapable": { + "version": "2.3.3", + "resolved": "https://registry-npm.cbhq.net/tapable/-/tapable-2.3.3.tgz", + "integrity": "sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/tar-fs": { + "version": "2.1.4", + "resolved": "https://registry-npm.cbhq.net/tar-fs/-/tar-fs-2.1.4.tgz", + "integrity": "sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry-npm.cbhq.net/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dev": true, + "license": "MIT", + "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" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry-npm.cbhq.net/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry-npm.cbhq.net/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry-npm.cbhq.net/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "devOptional": true, + "license": "Apache-2.0", + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry-npm.cbhq.net/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry-npm.cbhq.net/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/viem": { + "version": "2.40.3", + "resolved": "https://registry-npm.cbhq.net/viem/-/viem-2.40.3.tgz", + "integrity": "sha512-feYfEpbgjRkZYQpwcgxqkWzjxHI5LSDAjcGetHHwDRuX9BRQHUdV8ohrCosCYpdEhus/RknD3/bOd4qLYVPPuA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/wevm" + } + ], + "license": "MIT", + "dependencies": { + "@noble/curves": "1.9.1", + "@noble/hashes": "1.8.0", + "@scure/bip32": "1.7.0", + "@scure/bip39": "1.6.0", + "abitype": "1.1.0", + "isows": "1.0.7", + "ox": "0.9.6", + "ws": "8.18.3" + }, + "peerDependencies": { + "typescript": ">=5.0.4" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry-npm.cbhq.net/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/ws": { + "version": "8.18.3", + "resolved": "https://registry-npm.cbhq.net/ws/-/ws-8.18.3.tgz", + "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + } + } +} diff --git a/package.json b/package.json index 54d105ce..e10cc4c0 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ }, "dependencies": { "@aws-sdk/client-s3": "3.940.0", + "better-sqlite3": "^12.10.0", "next": "16.0.7", "react": "19.2.1", "react-dom": "19.2.1", @@ -19,6 +20,7 @@ "devDependencies": { "@biomejs/biome": "2.3.8", "@tailwindcss/postcss": "4.1.17", + "@types/better-sqlite3": "^7.6.13", "@types/node": "20.19.25", "@types/react": "19.2.7", "@types/react-dom": "19.2.3", diff --git a/scripts/indexer.mjs b/scripts/indexer.mjs new file mode 100644 index 00000000..20a146ba --- /dev/null +++ b/scripts/indexer.mjs @@ -0,0 +1,247 @@ +#!/usr/bin/env node +// Background block indexer for vibescan. +// Reads env: VIBESCAN_RPC_HTTP_URL, VIBESCAN_RPC_WS_URL, VIBESCAN_CHAIN_ID, +// VIBESCAN_DB_PATH, VIBESCAN_START_BLOCK, VIBESCAN_BACKFILL_CONCURRENCY + +import Database from "better-sqlite3"; +import { readFileSync } from "node:fs"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; +import { createPublicClient, http, webSocket, defineChain, parseAbiItem } from "viem"; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); + +const DB_PATH = process.env.VIBESCAN_DB_PATH ?? "/data/vibescan.db"; +const RPC_HTTP = process.env.VIBESCAN_RPC_HTTP_URL ?? "http://localhost:8545"; +const RPC_WS = process.env.VIBESCAN_RPC_WS_URL ?? "ws://localhost:8546"; +const CHAIN_ID = Number(process.env.VIBESCAN_CHAIN_ID ?? "84538453"); +const START_BLOCK = BigInt(process.env.VIBESCAN_START_BLOCK ?? "0"); +const CONCURRENCY = Number(process.env.VIBESCAN_BACKFILL_CONCURRENCY ?? "16"); + +// keccak256("Transfer(address,address,uint256)") — same topic for ERC-20 and ERC-721 +const ERC20_TRANSFER = "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"; + +const chain = defineChain({ + id: CHAIN_ID, + name: "vibenet", + nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 }, + rpcUrls: { default: { http: [RPC_HTTP], webSocket: [RPC_WS] } }, +}); + +const httpClient = createPublicClient({ chain, transport: http(RPC_HTTP) }); + +// --- DB setup --- + +function openDb() { + const db = new Database(DB_PATH); + db.pragma("journal_mode = WAL"); + db.pragma("synchronous = NORMAL"); + const migrationPath = path.join(__dirname, "../docker/migrations/0001_init.sql"); + db.exec(readFileSync(migrationPath, "utf8")); + return db; +} + +const db = openDb(); + +const stmts = { + getCursor: db.prepare("SELECT last_indexed_block, last_indexed_hash FROM cursor WHERE id = 0"), + upsertCursor: db.prepare(` + INSERT INTO cursor (id, last_indexed_block, last_indexed_hash, updated_at) + VALUES (0, ?, ?, ?) + ON CONFLICT(id) DO UPDATE SET + last_indexed_block = excluded.last_indexed_block, + last_indexed_hash = excluded.last_indexed_hash, + updated_at = excluded.updated_at + `), + insertBlock: db.prepare(` + INSERT OR IGNORE INTO blocks (number, hash, timestamp, miner, tx_count, gas_used, gas_limit, base_fee) + VALUES (?, ?, ?, ?, ?, ?, ?, ?) + `), + insertTx: db.prepare(` + INSERT OR IGNORE INTO txs (hash, block_num, tx_index, from_addr, to_addr, value, status, created) + VALUES (?, ?, ?, ?, ?, ?, ?, ?) + `), + insertActivity: db.prepare(` + INSERT OR IGNORE INTO address_activity (address, block_num, tx_index, log_index, tx_hash, role, token) + VALUES (?, ?, ?, ?, ?, ?, ?) + `), + insertAddress: db.prepare("INSERT OR IGNORE INTO addresses (address) VALUES (?)"), + updateStats: db.prepare(` + UPDATE explorer_stats SET + blocks = (SELECT COUNT(*) FROM blocks), + txs = (SELECT COUNT(*) FROM txs), + addresses = (SELECT COUNT(*) FROM addresses) + WHERE id = 0 + `), + getBlockHash: db.prepare("SELECT hash FROM blocks WHERE number = ?"), +}; + +function wipeDb() { + db.exec(` + DELETE FROM blocks; + DELETE FROM txs; + DELETE FROM address_activity; + DELETE FROM addresses; + DELETE FROM cursor; + UPDATE explorer_stats SET blocks=0, txs=0, addresses=0 WHERE id=0; + `); +} + +// --- Indexing logic --- + +async function processBlock(blockNum) { + const [block, receipts] = await Promise.all([ + httpClient.getBlock({ blockNumber: blockNum, includeTransactions: true }), + httpClient.request({ + method: "eth_getBlockReceipts", + params: [`0x${blockNum.toString(16)}`], + }).catch(() => null), + ]); + + if (!block) return null; + + db.transaction(() => { + stmts.insertBlock.run( + Number(block.number), + block.hash, + Number(block.timestamp), + block.miner.toLowerCase(), + block.transactions.length, + Number(block.gasUsed), + Number(block.gasLimit), + block.baseFeePerGas != null ? `0x${block.baseFeePerGas.toString(16)}` : null, + ); + + for (let i = 0; i < block.transactions.length; i++) { + const tx = block.transactions[i]; + const receipt = receipts?.[i]; + const status = receipt ? (receipt.status === "0x1" ? 1 : 0) : 1; + const to = tx.to ? tx.to.toLowerCase() : null; + const from = tx.from.toLowerCase(); + + stmts.insertTx.run( + tx.hash, Number(block.number), i, from, to, + `0x${tx.value.toString(16)}`, status, + to === null ? (receipt?.contractAddress?.toLowerCase() ?? null) : null, + ); + + // sender + stmts.insertActivity.run(from, Number(block.number), i, -1, tx.hash, 0, null); + stmts.insertAddress.run(from); + + // recipient or creator + if (to) { + stmts.insertActivity.run(to, Number(block.number), i, -1, tx.hash, 1, null); + stmts.insertAddress.run(to); + } else if (receipt?.contractAddress) { + const created = receipt.contractAddress.toLowerCase(); + stmts.insertActivity.run(created, Number(block.number), i, -1, tx.hash, 2, null); + stmts.insertAddress.run(created); + } + + // ERC-20/721 Transfer logs + if (receipt?.logs) { + for (const log of receipt.logs) { + if (log.topics[0] === ERC20_TRANSFER && log.topics.length >= 3) { + const token = log.address.toLowerCase(); + const logIdx = Number(log.logIndex); + const fromLog = `0x${log.topics[1].slice(26)}`; + const toLog = `0x${log.topics[2].slice(26)}`; + stmts.insertActivity.run(fromLog, Number(block.number), i, logIdx, tx.hash, 3, token); + stmts.insertActivity.run(toLog, Number(block.number), i, logIdx, tx.hash, 4, token); + stmts.insertAddress.run(fromLog); + stmts.insertAddress.run(toLog); + } + } + } + } + + stmts.upsertCursor.run(Number(block.number), block.hash, Math.floor(Date.now() / 1000)); + stmts.updateStats.run(); + })(); + + return block; +} + +async function ensureGenesisConsistent() { + const stored = stmts.getBlockHash.get(0); + if (!stored) return; + const upstream = await httpClient.getBlock({ blockNumber: 0n }); + if (!upstream) return; + if (upstream.hash !== stored.hash) { + console.log(`[indexer] genesis hash mismatch — chain reset detected, wiping DB`); + db.exec("DELETE FROM blocks; DELETE FROM txs; DELETE FROM address_activity; DELETE FROM addresses; DELETE FROM cursor; UPDATE explorer_stats SET blocks=0, txs=0, addresses=0 WHERE id=0;"); + } +} + +async function backfill(fromBlock, toBlock) { + console.log(`[indexer] backfilling blocks ${fromBlock}–${toBlock}`); + let i = fromBlock; + while (i <= toBlock) { + const batch = []; + for (let j = 0; j < CONCURRENCY && i + BigInt(j) <= toBlock; j++) { + batch.push(processBlock(i + BigInt(j))); + } + await Promise.all(batch); + i += BigInt(CONCURRENCY); + process.stdout.write(`\r[indexer] backfilled up to ${i - 1n}`); + } + console.log(`\n[indexer] backfill complete`); +} + +async function streamLive() { + console.log(`[indexer] subscribing to newHeads via ${RPC_WS}`); + + const wsClient = createPublicClient({ chain, transport: webSocket(RPC_WS) }); + + const unwatch = wsClient.watchBlocks({ + onBlock: async (block) => { + try { + await processBlock(block.number); + console.log(`[indexer] indexed block #${block.number}`); + } catch (e) { + console.error(`[indexer] error processing block #${block.number}:`, e); + } + }, + onError: (err) => { + console.error(`[indexer] subscription error:`, err); + }, + }); + + // Keep running; signal handler below handles cleanup + process.on("SIGTERM", () => { unwatch(); process.exit(0); }); + process.on("SIGINT", () => { unwatch(); process.exit(0); }); + await new Promise(() => {}); // block forever +} + +async function main() { + console.log(`[indexer] starting (chain=${CHAIN_ID}, rpc=${RPC_HTTP})`); + + // Wait for node to be reachable + for (let attempt = 0; attempt < 30; attempt++) { + try { + await httpClient.getChainId(); + break; + } catch { + console.log(`[indexer] waiting for node… (attempt ${attempt + 1}/30)`); + await new Promise((r) => setTimeout(r, 2000)); + } + } + + await ensureGenesisConsistent(); + + const cursor = stmts.getCursor.get(); + const resumeFrom = cursor + ? BigInt(cursor.last_indexed_block) + 1n + : START_BLOCK; + + const latest = await httpClient.getBlockNumber(); + + if (resumeFrom <= latest) { + await backfill(resumeFrom, latest); + } + + await streamLive(); +} + +main().catch((e) => { console.error("[indexer] fatal:", e); process.exit(1); }); diff --git a/scripts/start.sh b/scripts/start.sh new file mode 100644 index 00000000..e47f1774 --- /dev/null +++ b/scripts/start.sh @@ -0,0 +1,8 @@ +#!/bin/sh +set -e + +# Start the background indexer (writes to SQLite, reads from node via RPC) +node scripts/indexer.mjs & + +# Start Next.js server in foreground so Docker tracks its exit code +exec npm start diff --git a/src/app/(vibenet)/explorer/address/[addr]/page.tsx b/src/app/(vibenet)/explorer/address/[addr]/page.tsx new file mode 100644 index 00000000..98d95114 --- /dev/null +++ b/src/app/(vibenet)/explorer/address/[addr]/page.tsx @@ -0,0 +1,154 @@ +"use client"; + +import Link from "next/link"; +import { useEffect, useState } from "react"; + +interface PageProps { + params: Promise<{ addr: string }>; +} + +interface ActivityRow { + tx_hash: string; + block_num: number; + log_index: number; + role: number; + token: string | null; +} + +interface AddressDetail { + address: string; + balance_wei: string; + nonce: number; + is_contract: boolean; + code_size: number; + activity: ActivityRow[]; +} + +const ROLE_LABELS: Record = { + 0: "sender", + 1: "recipient", + 2: "creator", + 3: "token-from", + 4: "token-to", +}; + +function shortHash(h: string, n = 12): string { + if (!h || h.length <= n + 4) return h; + return `${h.slice(0, n)}…${h.slice(-4)}`; +} + +function weiToEth(hex: string): string { + const n = BigInt(hex); + if (n === 0n) return "0 ETH"; + const eth = Number(n) / 1e18; + return `${eth.toFixed(6)} ETH`; +} + +export default function ExplorerAddressPage({ params }: PageProps) { + const [addr, setAddr] = useState(""); + const [data, setData] = useState(null); + const [loading, setLoading] = useState(true); + + useEffect(() => { + params.then((p) => setAddr(p.addr)); + }, [params]); + + useEffect(() => { + if (!addr) return; + setLoading(true); + fetch(`/api/vibenet/explorer/address/${addr}`) + .then((r) => r.json()) + .then(setData) + .catch(() => null) + .finally(() => setLoading(false)); + }, [addr]); + + return ( + <> +
+ + + +
+ +
+

Address

+

+ {addr} +

+ + {loading &&

Loading…

} + + {data && ( + <> +
+
Type
+
+ {data.is_contract + ? `Contract (${data.code_size.toLocaleString()} bytes)` + : "EOA"} +
+
Balance
+
{weiToEth(data.balance_wei)}
+
Nonce
+
{data.nonce.toString()}
+
+ +

Activity

+ {data.activity.length === 0 ? ( +

No activity indexed yet.

+ ) : ( + + + + + + + + + + + {data.activity.map((row) => ( + + + + + + + ))} + +
BlockTxRoleDetail
+ + {row.block_num.toLocaleString()} + + + + + {shortHash(row.tx_hash, 12)} + + + {ROLE_LABELS[row.role] ?? row.role} + {row.token ? ( + <> + via{" "} + + + {shortHash(row.token, 8)} + + + + ) : ( + + )} +
+ )} + + )} +
+ + ); +} diff --git a/src/app/(vibenet)/explorer/block/[hash]/page.tsx b/src/app/(vibenet)/explorer/block/[hash]/page.tsx new file mode 100644 index 00000000..c8e11b86 --- /dev/null +++ b/src/app/(vibenet)/explorer/block/[hash]/page.tsx @@ -0,0 +1,143 @@ +"use client"; + +import Link from "next/link"; +import { useEffect, useState } from "react"; + +interface PageProps { + params: Promise<{ hash: string }>; +} + +interface BlockDetail { + number: string; + hash: string; + parentHash: string; + timestamp: string; + miner: string; + gasUsed: string; + gasLimit: string; + baseFeePerGas: string | null; + transactions: string[]; +} + +export default function ExplorerBlockPage({ params }: PageProps) { + const [hash, setHash] = useState(""); + const [block, setBlock] = useState(null); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(null); + + useEffect(() => { + params.then((p) => setHash(p.hash)); + }, [params]); + + useEffect(() => { + if (!hash) return; + setLoading(true); + fetch(`/api/vibenet/explorer/block/${hash}`) + .then(async (r) => { + if (!r.ok) + throw new Error( + r.status === 404 ? "Block not found" : "Failed to fetch block", + ); + return r.json(); + }) + .then(setBlock) + .catch((e) => setError(e.message)) + .finally(() => setLoading(false)); + }, [hash]); + + const num = block ? Number.parseInt(block.number, 16) : null; + const ts = block + ? new Date(Number.parseInt(block.timestamp, 16) * 1000).toLocaleString() + : null; + + return ( + <> +
+ + + +
+ +
+

Block {num !== null ? num.toLocaleString() : ""}

+ {block && ( +

+ {block.hash} +

+ )} + {loading &&

Loading…

} + {error &&
{error}
} + {block && ( + <> +
+
Number
+
{num?.toLocaleString()}
+
Timestamp
+
{ts}
+
Miner
+
+ + + {block.miner} + + +
+
Parent
+
+ {num && num > 0 ? ( + + + {block.parentHash} + + + ) : ( + {block.parentHash} + )} +
+
Gas Used
+
{Number.parseInt(block.gasUsed, 16).toLocaleString()}
+
Gas Limit
+
{Number.parseInt(block.gasLimit, 16).toLocaleString()}
+
Base Fee
+
+ {block.baseFeePerGas + ? `${Number.parseInt(block.baseFeePerGas, 16).toLocaleString()} wei` + : "—"} +
+
+ +

Transactions ({block.transactions.length})

+ {block.transactions.length === 0 ? ( +

No transactions in this block.

+ ) : ( + + + + + + + + + {block.transactions.map((txHash, i) => ( + + + + + ))} + +
#Hash
{i} + + {txHash} + +
+ )} + + )} +
+ + ); +} diff --git a/src/app/(vibenet)/explorer/page.tsx b/src/app/(vibenet)/explorer/page.tsx new file mode 100644 index 00000000..2e33b824 --- /dev/null +++ b/src/app/(vibenet)/explorer/page.tsx @@ -0,0 +1,358 @@ +"use client"; + +import Link from "next/link"; +import { useRouter } from "next/navigation"; +import { useEffect, useRef, useState } from "react"; + +interface BlockRow { + number: number; + hash: string; + timestamp: number; + tx_count: number; + gas_used: number; +} + +interface TxRow { + hash: string; + block_num: number; + from_addr: string; + to_addr: string | null; + value: string; + status: number; +} + +interface Stats { + blocks: number; + txs: number; + addresses: number; +} + +const PROD_HOSTS = { + ui: "vibes.base.org", + faucet: "faucet.vibes.base.org", + explorer: "explorer.vibes.base.org", +}; + +function isProdHost(host: string) { + return host === PROD_HOSTS.ui || host.endsWith(".vibes.base.org"); +} + +function buildHomeUrl() { + if (typeof window === "undefined") return "/"; + return isProdHost(window.location.hostname) + ? `https://${PROD_HOSTS.ui}` + : "/"; +} + +function buildFaucetUrl() { + if (typeof window === "undefined") return "/faucet"; + return isProdHost(window.location.hostname) + ? `https://${PROD_HOSTS.faucet}` + : "/faucet"; +} + +function timeAgo(ts: number): string { + const s = Math.floor(Date.now() / 1000 - ts); + if (s < 60) return `${s}s ago`; + if (s < 3600) return `${Math.floor(s / 60)}m ago`; + return `${Math.floor(s / 3600)}h ago`; +} + +function shortHash(h: string, n = 18) { + return `${h.slice(0, n)}…`; +} + +function classifyQuery( + q: string, +): { kind: "block" | "tx" | "address"; value: string } | null { + const v = q.trim(); + if (!v) return null; + if (/^0x[a-fA-F0-9]{40}$/.test(v)) return { kind: "address", value: v }; + if (/^0x[a-fA-F0-9]{64}$/.test(v)) return { kind: "tx", value: v }; + if (/^\d+$/.test(v)) return { kind: "block", value: v }; + return null; +} + +function SearchBar() { + const router = useRouter(); + const [query, setQuery] = useState(""); + const [error, setError] = useState(null); + + const onSubmit = async (e: React.FormEvent) => { + e.preventDefault(); + setError(null); + const cls = classifyQuery(query); + if (!cls) { + setError("Enter a block #, hash, or address"); + return; + } + if (cls.kind === "address") { + router.push(`/explorer/address/${cls.value}`); + return; + } + if (cls.kind === "block") { + router.push(`/explorer/block/${cls.value}`); + return; + } + // 64-char hash: try tx first, fall through to block + try { + const res = await fetch(`/api/vibenet/explorer/tx/${cls.value}`); + if (res.ok) router.push(`/explorer/tx/${cls.value}`); + else router.push(`/explorer/block/${cls.value}`); + } catch { + router.push(`/explorer/block/${cls.value}`); + } + }; + + return ( +
+ setQuery(e.target.value)} + placeholder="Block #, block hash, tx hash, or address" + /> + + {error && ( + + {error} + + )} +
+ ); +} + +export default function ExplorerPage() { + const [blocks, setBlocks] = useState([]); + const [txs, setTxs] = useState([]); + const [stats, setStats] = useState(null); + const [loading, setLoading] = useState(true); + const [homeUrl, setHomeUrl] = useState("/"); + const [faucetUrl, setFaucetUrl] = useState("/faucet"); + + // Track which rows / stats just appeared so we can flash them once. + // Cleared after the CSS animation runs (~1.2s). + const [newKeys, setNewKeys] = useState>(new Set()); + const [statHighlight, setStatHighlight] = useState>(new Set()); + const seenBlocks = useRef>(new Set()); + const seenTxs = useRef>(new Set()); + const lastStats = useRef(null); + + useEffect(() => { + setHomeUrl(buildHomeUrl()); + setFaucetUrl(buildFaucetUrl()); + + const load = async () => { + const [blocksRes, statsRes] = await Promise.all([ + fetch("/api/vibenet/explorer/blocks").then((r) => r.json()), + fetch("/api/vibenet/explorer/stats").then((r) => r.json()), + ]); + const nextBlocks: BlockRow[] = blocksRes.blocks ?? []; + const nextTxs: TxRow[] = blocksRes.txs ?? []; + const nextStats: Stats = statsRes; + + // Detect new rows and stat changes (skip on first load — everything + // is "new" then which would flash the whole table). + const isFirstLoad = seenBlocks.current.size === 0; + if (!isFirstLoad) { + const fresh = new Set(); + for (const b of nextBlocks) { + if (!seenBlocks.current.has(b.hash)) fresh.add(`block-${b.hash}`); + } + for (const t of nextTxs) { + if (!seenTxs.current.has(t.hash)) fresh.add(`tx-${t.hash}`); + } + if (fresh.size > 0) { + setNewKeys(fresh); + window.setTimeout(() => setNewKeys(new Set()), 1300); + } + const statChanges = new Set(); + if (lastStats.current) { + if (lastStats.current.blocks !== nextStats.blocks) + statChanges.add("blocks"); + if (lastStats.current.txs !== nextStats.txs) statChanges.add("txs"); + if (lastStats.current.addresses !== nextStats.addresses) + statChanges.add("addresses"); + } + if (statChanges.size > 0) { + setStatHighlight(statChanges); + window.setTimeout(() => setStatHighlight(new Set()), 1000); + } + } + seenBlocks.current = new Set(nextBlocks.map((b) => b.hash)); + seenTxs.current = new Set(nextTxs.map((t) => t.hash)); + lastStats.current = nextStats; + + setBlocks(nextBlocks); + setTxs(nextTxs); + setStats(nextStats); + setLoading(false); + }; + load().catch(() => setLoading(false)); + const t = setInterval(load, 5_000); + return () => clearInterval(t); + }, []); + + return ( + <> +
+ + + +
+ +
+ + + {stats && ( +
+
+ Blocks + {stats.blocks.toLocaleString()} +
+
+ Transactions + {stats.txs.toLocaleString()} +
+
+ Addresses + {stats.addresses.toLocaleString()} +
+
+ )} + +
+
+

Latest Blocks

+ {loading ? ( +
Indexing…
+ ) : blocks.length === 0 ? ( +
No blocks yet
+ ) : ( + + + + + + + + + + {blocks.slice(0, 10).map((b) => ( + + + + + + ))} + +
BlockTxsAge
+ + {b.number.toLocaleString()} + + {b.tx_count} + {timeAgo(b.timestamp)} +
+ )} +
+ +
+

Latest Transactions

+ {loading ? ( +
Indexing…
+ ) : txs.length === 0 ? ( +
No transactions yet
+ ) : ( + + + + + + + + + + + {txs.slice(0, 10).map((tx) => ( + + + + + + + ))} + +
HashFromToBlock
+ + {shortHash(tx.hash, 12)} + + + + + {tx.from_addr.slice(0, 8)}… + + + + {tx.to_addr ? ( + + + {tx.to_addr.slice(0, 8)}… + + + ) : ( + (create) + )} + + + {tx.block_num.toLocaleString()} + +
+ )} +
+
+
+ + ); +} diff --git a/src/app/(vibenet)/explorer/tx/[hash]/page.tsx b/src/app/(vibenet)/explorer/tx/[hash]/page.tsx new file mode 100644 index 00000000..5936a972 --- /dev/null +++ b/src/app/(vibenet)/explorer/tx/[hash]/page.tsx @@ -0,0 +1,387 @@ +"use client"; + +import Link from "next/link"; +import { useEffect, useState } from "react"; + +interface PageProps { + params: Promise<{ hash: string }>; +} + +interface LogEntry { + address: string; + topics: string[]; + data: string; + logIndex: number; +} + +interface TxDetail { + hash: string; + blockHash: string; + blockNumber: string; + timestamp: string | null; + from: string; + to: string | null; + value: string; + gas: string; + gasUsed: string | null; + gasPrice: string; + effectiveGasPrice: string | null; + fee: string | null; + type: number | string | null; + typeHex?: string | null; + nonce: string; + input: string; + transactionIndex: string; + status: "ok" | "fail" | "pending"; + contractAddress: string | null; + logs: LogEntry[]; +} + +const ERC20_TRANSFER_TOPIC = + "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"; + +function fmtHexInt(hex: string | null): string { + if (!hex) return "—"; + try { + return Number.parseInt(hex, 16).toLocaleString(); + } catch { + return hex; + } +} + +function weiToEth(hex: string | null): string { + if (!hex) return "—"; + const n = BigInt(hex); + if (n === 0n) return "0 ETH"; + const eth = Number(n) / 1e18; + return `${eth.toFixed(6)} ETH`; +} + +function weiToGwei(hex: string | null): string { + if (!hex) return "—"; + const n = BigInt(hex); + const gwei = Number(n) / 1e9; + return `${gwei.toFixed(4)} Gwei`; +} + +function tsHumanAndAge( + hex: string | null, +): { human: string; age: string } | null { + if (!hex) return null; + const ts = Number.parseInt(hex, 16); + const date = new Date(ts * 1000); + const seconds = Math.max(0, Math.floor(Date.now() / 1000) - ts); + const age = + seconds < 60 + ? `${seconds}s ago` + : seconds < 3600 + ? `${Math.floor(seconds / 60)}m ago` + : seconds < 86400 + ? `${Math.floor(seconds / 3600)}h ago` + : `${Math.floor(seconds / 86400)}d ago`; + return { human: date.toLocaleString(), age }; +} + +function shortHash(h: string, n = 12): string { + if (!h || h.length <= n + 4) return h; + return `${h.slice(0, n)}…${h.slice(-4)}`; +} + +const TYPE_BY_HEX: Record = { + "0x0": "Legacy", + "0x1": "EIP-2930 (Access List)", + "0x2": "EIP-1559", + "0x3": "EIP-4844 (Blob)", + "0x4": "EIP-7702 (Set Code)", + "0x7e": "Deposit (OP-stack)", +}; + +const TYPE_BY_NAME: Record = { + legacy: { hex: "0x0", label: "Legacy" }, + eip2930: { hex: "0x1", label: "EIP-2930 (Access List)" }, + eip1559: { hex: "0x2", label: "EIP-1559" }, + eip4844: { hex: "0x3", label: "EIP-4844 (Blob)" }, + eip7702: { hex: "0x4", label: "EIP-7702 (Set Code)" }, + deposit: { hex: "0x7e", label: "Deposit (OP-stack)" }, +}; + +function txTypeLabel( + type: number | string | null, + typeHex: string | null, +): { hex: string; label: string } | null { + if (typeof type === "string" && TYPE_BY_NAME[type]) return TYPE_BY_NAME[type]; + if (typeof type === "number") { + const hex = `0x${type.toString(16)}`; + return { hex, label: TYPE_BY_HEX[hex] ?? "Unknown" }; + } + if (typeHex) { + return { hex: typeHex, label: TYPE_BY_HEX[typeHex] ?? "Unknown" }; + } + return null; +} + +function decodeErc20Transfer(log: LogEntry) { + if (log.topics[0] !== ERC20_TRANSFER_TOPIC || log.topics.length < 3) + return null; + return { + token: log.address, + from: `0x${log.topics[1].slice(26)}`, + to: `0x${log.topics[2].slice(26)}`, + amount: log.data && log.data !== "0x" ? BigInt(log.data).toString() : "0", + }; +} + +export default function ExplorerTxPage({ params }: PageProps) { + const [hash, setHash] = useState(""); + const [tx, setTx] = useState(null); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(null); + + useEffect(() => { + params.then((p) => setHash(p.hash)); + }, [params]); + + useEffect(() => { + if (!hash) return; + setLoading(true); + fetch(`/api/vibenet/explorer/tx/${hash}`) + .then(async (r) => { + if (!r.ok) + throw new Error( + r.status === 404 + ? "Transaction not found" + : "Failed to fetch transaction", + ); + return r.json(); + }) + .then(setTx) + .catch((e) => setError(e.message)) + .finally(() => setLoading(false)); + }, [hash]); + + const blockNum = tx ? Number.parseInt(tx.blockNumber, 16) : null; + const tsInfo = tx ? tsHumanAndAge(tx.timestamp) : null; + const inputBytes = + tx?.input && tx.input !== "0x" ? (tx.input.length - 2) / 2 : 0; + const selector = + tx?.input && tx.input.length >= 10 ? tx.input.slice(0, 10) : null; + + return ( + <> +
+ + + +
+ +
+

Transaction

+ {loading &&

Loading…

} + {error &&
{error}
} + {tx && ( + <> +

+ {tx.hash} +

+ +
+
Block
+
+ + {blockNum?.toLocaleString()} + +
+ {tsInfo && ( + <> +
Timestamp
+
+ {tsInfo.human} ({tsInfo.age}) +
+ + )} +
Status
+
+ + {tx.status === "ok" + ? "success" + : tx.status === "fail" + ? "failed" + : "pending"} + +
+ {(() => { + const tt = txTypeLabel(tx.type, tx.typeHex ?? null); + if (!tt) return null; + return ( + <> +
Type
+
+ {tt.hex}{" "} + ({tt.label}) +
+ + ); + })()} +
From
+
+ + {tx.from} + +
+
To
+
+ {tx.to ? ( + + {tx.to} + + ) : tx.contractAddress ? ( + <> + contract created:{" "} + + + {tx.contractAddress} + + + + ) : ( + (contract create, not yet mined) + )} +
+
Value
+
{weiToEth(tx.value)}
+
Nonce
+
{Number.parseInt(tx.nonce, 16).toString()}
+ {tx.fee && ( + <> +
Fee
+
{weiToEth(tx.fee)}
+ + )} +
Gas limit
+
{fmtHexInt(tx.gas)}
+ {tx.gasUsed && ( + <> +
Gas used
+
+ {fmtHexInt(tx.gasUsed)} {(() => { + const used = Number.parseInt(tx.gasUsed, 16); + const limit = Number.parseInt(tx.gas, 16); + if (!limit) return null; + const pct = ((used / limit) * 100).toFixed(1); + return ({pct}% of limit); + })()} +
+ + )} + {tx.effectiveGasPrice && ( + <> +
Effective gas price
+
{weiToGwei(tx.effectiveGasPrice)}
+ + )} + {selector && ( + <> +
Selector
+
+ {selector} +
+ + )} +
Input
+
+ {inputBytes === 0 ? ( + (empty) + ) : ( + <> + {inputBytes} bytes +
+                      {tx.input}
+                    
+ + )} +
+
+ +

Logs ({tx.logs.length})

+ {tx.logs.length === 0 ? ( +

No logs emitted.

+ ) : ( + tx.logs.map((log) => { + const transfer = decodeErc20Transfer(log); + return ( +
+
+ #{log.logIndex} + + + {shortHash(log.address, 8)} + + + {transfer && ( + Transfer + )} +
+ {transfer && ( +
+
Token
+
+ + + {shortHash(transfer.token, 8)} + + +
+
From
+
+ + + {transfer.from} + + +
+
To
+
+ + + {transfer.to} + + +
+
Amount
+
+ {transfer.amount}{" "} + raw token units +
+
+ )} +
    + {log.topics.map((t, i) => ( +
  • + {t} +
  • + ))} +
+ {log.data && log.data !== "0x" && ( + <> +
+ Data ({(log.data.length - 2) / 2} bytes) +
+
+                          {log.data}
+                        
+ + )} +
+ ); + }) + )} + + )} +
+ + ); +} diff --git a/src/app/(vibenet)/faucet/page.tsx b/src/app/(vibenet)/faucet/page.tsx new file mode 100644 index 00000000..5f7b2b5d --- /dev/null +++ b/src/app/(vibenet)/faucet/page.tsx @@ -0,0 +1,380 @@ +"use client"; + +import { useEffect, useState } from "react"; + +interface FaucetStatus { + address: string; + chain_id: number; + drip_wei: string; + balance_wei: string; + ip_cooldown_secs: number; + addr_cooldown_secs: number; + usdv_address?: string; + usdv_drip_units?: string; + nfv_address?: string; +} + +type Token = "eth" | "usdv" | "nfv"; + +interface DripBody { + tx_hash?: string; + to?: string; + amount_wei?: string; + usdv_address?: string; + nfv_address?: string; + error?: string; +} + +interface DripResult { + state: "pending" | "success" | "error"; + token?: Token; + message?: string; + body?: DripBody; +} + +const PROD_HOSTS = { + ui: "vibes.base.org", + faucet: "faucet.vibes.base.org", + explorer: "explorer.vibes.base.org", +}; + +function isProdHost(host: string) { + return host === PROD_HOSTS.ui || host.endsWith(".vibes.base.org"); +} + +function buildHomeUrl() { + if (typeof window === "undefined") return "/"; + return isProdHost(window.location.hostname) + ? `https://${PROD_HOSTS.ui}` + : "/"; +} + +function buildExplorerUrl() { + if (typeof window === "undefined") return "/explorer"; + return isProdHost(window.location.hostname) + ? `https://${PROD_HOSTS.explorer}` + : "/explorer"; +} + +function formatEth(wei: string) { + return (Number(BigInt(wei)) / 1e18).toFixed(4); +} + +function formatUsdv(units: string) { + const n = Number(BigInt(units)) / 1e6; + return n.toLocaleString(undefined, { maximumFractionDigits: 2 }); +} + +function shortAddress(value: string) { + if (!value || value.length <= 14) return value || ""; + return `${value.slice(0, 6)}…${value.slice(-4)}`; +} + +const ENDPOINTS: Record = { + eth: "/api/vibenet/faucet/drip", + usdv: "/api/vibenet/faucet/drip-usdv", + nfv: "/api/vibenet/faucet/drip-nfv", +}; + +const ASSET_LABEL: Record = { + eth: "ETH", + usdv: "USDV", + nfv: "NFV", +}; + +export default function FaucetPage() { + const [status, setStatus] = useState(null); + const [statusError, setStatusError] = useState(null); + const [address, setAddress] = useState(""); + const [busy, setBusy] = useState(false); + const [result, setResult] = useState(null); + const [homeUrl, setHomeUrl] = useState("/"); + const [explorerUrl, setExplorerUrl] = useState("/explorer"); + + useEffect(() => { + setHomeUrl(buildHomeUrl()); + setExplorerUrl(buildExplorerUrl()); + + const load = () => + fetch("/api/vibenet/faucet/status") + .then(async (r) => { + if (!r.ok) throw new Error(`HTTP ${r.status}`); + return r.json(); + }) + .then((s) => { + setStatus(s); + setStatusError(null); + }) + .catch((e) => setStatusError(String(e.message ?? e))); + load(); + const t = setInterval(load, 15_000); + return () => clearInterval(t); + }, []); + + const drip = async (token: Token) => { + if (!address.match(/^0x[a-fA-F0-9]{40}$/)) { + setResult({ state: "error", token, message: "Invalid address" }); + return; + } + setBusy(true); + setResult({ state: "pending", token }); + try { + const res = await fetch(ENDPOINTS[token], { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ address }), + }); + const body: DripBody = await res.json().catch(() => ({})); + if (!res.ok) { + const reason = + body.error ?? + (res.status === 429 + ? "rate limited — wait a minute and try again" + : `HTTP ${res.status}`); + setResult({ state: "error", token, message: reason }); + } else { + setResult({ state: "success", token, body }); + } + } catch (err) { + setResult({ + state: "error", + token, + message: err instanceof Error ? err.message : String(err), + }); + } finally { + setBusy(false); + // Refresh balance after a drip + fetch("/api/vibenet/faucet/status") + .then((r) => r.json()) + .then(setStatus) + .catch(() => null); + } + }; + + const ethDripLabel = status + ? `Request ${formatEth(status.drip_wei)} ETH` + : "Request ETH"; + const usdvDripLabel = + status?.usdv_drip_units != null + ? `Request ${formatUsdv(status.usdv_drip_units)} USDV` + : "Request USDV"; + + return ( + <> +
+ + + +
+ +
+
+

Faucet

+

+ Drip testnet ETH or mint USDV (Vibe USD) / NFV (NFT) to any address. +

+ +
+
+ {statusError ? ( + + Could not load faucet status: {statusError} + + ) : !status ? ( + Loading status… + ) : ( +
+
+ ETH + + {formatEth(status.balance_wei)} ETH + +
+
+ USDV + + {status.usdv_address ? "Ready to print" : "Not deployed"} + +
+
+ NFV + + {status.nfv_address ? "Ready to mint" : "Not deployed"} + +
+
+ )} +
+ +
{ + e.preventDefault(); + drip("eth"); + }} + > + + setAddress(e.target.value)} + placeholder="0x…" + pattern="^0x[a-fA-F0-9]{40}$" + required + /> +
+ + + {status?.nfv_address && ( + + )} +
+
+ + {result && ( +
+ {result.state === "pending" && result.token && ( + + {result.token === "eth" + ? "Requesting ETH…" + : `Minting ${ASSET_LABEL[result.token]}…`} + + )} + {result.state === "error" && ( + + {result.token + ? `${ASSET_LABEL[result.token]} request failed` + : "Request failed"} + : {result.message} + + )} + {result.state === "success" && result.body && result.token && ( + <> +
+ {ASSET_LABEL[result.token]} request submitted +
+
+ Transaction{" "} + + {shortAddress(result.body.tx_hash ?? "")} + + {" → "} + + {shortAddress(result.body.to ?? "")} + + {result.token === "usdv" && result.body.usdv_address && ( + <> + {" via "} + + USDV + + + )} + {result.token === "nfv" && result.body.nfv_address && ( + <> + {" via "} + + NFV + + + )} +
+ + )} +
+ )} +
+
+
+ + + + ); +} diff --git a/src/app/(vibenet)/layout.tsx b/src/app/(vibenet)/layout.tsx new file mode 100644 index 00000000..6e18ae8c --- /dev/null +++ b/src/app/(vibenet)/layout.tsx @@ -0,0 +1,9 @@ +import "@/styles/vibenet.css"; + +export default function VibenetLayout({ + children, +}: { + children: React.ReactNode; +}) { + return
{children}
; +} diff --git a/src/app/(vibenet)/page.tsx b/src/app/(vibenet)/page.tsx new file mode 100644 index 00000000..6293e360 --- /dev/null +++ b/src/app/(vibenet)/page.tsx @@ -0,0 +1,365 @@ +"use client"; + +import { useEffect, useState } from "react"; +import { createWalletClient, custom } from "viem"; + +declare global { + interface Window { + // biome-ignore lint/suspicious/noExplicitAny: EIP-1193 provider + ethereum?: any; + } +} + +interface Feature { + title: string; + description: string; + link?: string; +} + +interface VibeConfig { + title?: string; + subtitle?: string; + features?: Feature[]; + branch?: string; + commit?: string; +} + +const PROD_HOSTS = { + ui: "vibes.base.org", + rpc: "rpc.vibes.base.org", + faucet: "faucet.vibes.base.org", + explorer: "explorer.vibes.base.org", +}; + +function isProd() { + if (typeof window === "undefined") return false; + const h = window.location.hostname; + return h === PROD_HOSTS.ui || h.endsWith(".vibes.base.org"); +} + +// In production each subdomain is reachable on its own host. Locally we +// surface vibescan + faucet as path-routed siblings of the landing page. +function buildRpcUrl() { + if (isProd()) return `https://${PROD_HOSTS.rpc}`; + if (typeof window === "undefined") return "http://localhost:18082"; + const port = Number(window.location.port || 80); + return `${window.location.protocol}//${window.location.hostname}:${port + 2}`; +} + +function buildFaucetUrl() { + if (isProd()) return `https://${PROD_HOSTS.faucet}`; + return "/faucet"; +} + +function buildExplorerUrl() { + if (isProd()) return `https://${PROD_HOSTS.explorer}`; + return "/explorer"; +} + +const CONTRACT_LABELS: Record = { + faucetAddress: "Faucet", + usdv: "USDV (ERC-20)", + nfv: "NFV (ERC-721)", +}; + +const WATCHABLE_TOKENS: Record< + string, + { type: "ERC20"; symbol: string; decimals: number } +> = { + usdv: { type: "ERC20", symbol: "USDV", decimals: 6 }, +}; + +export default function VibeHomePage() { + const [config, setConfig] = useState({}); + const [contracts, setContracts] = useState | null>( + null, + ); + const [chainId, setChainId] = useState(""); + const [rpcUrl, setRpcUrl] = useState(""); + const [faucetUrl, setFaucetUrl] = useState(""); + const [explorerUrl, setExplorerUrl] = useState(""); + const [copied, setCopied] = useState(null); + const [walletStatus, setWalletStatus] = useState(""); + const [watchStatus, setWatchStatus] = useState>({}); + + useEffect(() => { + setRpcUrl(buildRpcUrl()); + setFaucetUrl(buildFaucetUrl()); + setExplorerUrl(buildExplorerUrl()); + + fetch("/api/vibenet/config") + .then((r) => r.json()) + .then(setConfig) + .catch(() => null); + + fetch("/api/vibenet/contracts") + .then((r) => r.json()) + .then(setContracts) + .catch(() => setContracts(null)); + + fetch("/api/vibenet/faucet/status") + .then((r) => r.json()) + .then((d: { chain_id?: number }) => { + if (d.chain_id) setChainId(String(d.chain_id)); + }) + .catch(() => null); + }, []); + + const copy = async (text: string, key: string) => { + try { + await navigator.clipboard.writeText(text); + setCopied(key); + setTimeout(() => setCopied(null), 1500); + } catch { + /* noop */ + } + }; + + const addToWallet = async () => { + if (!window.ethereum) { + setWalletStatus("No browser wallet detected on this page."); + return; + } + try { + const wallet = createWalletClient({ transport: custom(window.ethereum) }); + await wallet.addChain({ + chain: { + id: Number(chainId), + name: "base vibenet", + nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 }, + rpcUrls: { default: { http: [rpcUrl] } }, + blockExplorers: { + default: { name: "vibescan", url: explorerUrl }, + }, + }, + }); + setWalletStatus( + "Network added. Your wallet should now be on base vibenet.", + ); + } catch (err) { + const e = err as { shortMessage?: string; message?: string }; + setWalletStatus( + `Wallet did not add the network: ${e.shortMessage ?? e.message ?? String(err)}`, + ); + } + }; + + const watchAsset = async ( + address: string, + meta: (typeof WATCHABLE_TOKENS)[string], + ) => { + if (!window.ethereum) { + setWatchStatus((s) => ({ ...s, [address]: "No wallet detected" })); + setTimeout(() => setWatchStatus((s) => ({ ...s, [address]: "" })), 1500); + return; + } + try { + const wallet = createWalletClient({ transport: custom(window.ethereum) }); + await wallet.watchAsset({ + type: meta.type, + options: { + address: address as `0x${string}`, + symbol: meta.symbol, + decimals: meta.decimals, + }, + }); + setWatchStatus((s) => ({ ...s, [address]: `${meta.symbol} added` })); + } catch (err) { + const e = err as { shortMessage?: string }; + setWatchStatus((s) => ({ + ...s, + [address]: e.shortMessage ?? "Rejected", + })); + } finally { + setTimeout(() => setWatchStatus((s) => ({ ...s, [address]: "" })), 1800); + } + }; + + const features = config.features ?? []; + const contractEntries = contracts + ? Object.entries(contracts).filter( + ([k, v]) => + !k.startsWith("_") && + k !== "faucetAddress" && + typeof v === "string" && + /^0x[0-9a-fA-F]{40}$/.test(v), + ) + : null; + + return ( + <> +
+ + + +
+ +
+
+

{config.title ?? "base vibenet"}

+

+ {config.subtitle ?? + "An ephemeral Base devnet for trying out in-flight features."} +

+
+ +
+

Features

+ {features.length === 0 ? ( +

+ No branch-specific features declared for this vibe. +

+ ) : ( +
+ {features.map((f) => ( +
+
{f.title}
+ {f.description && ( +
{f.description}
+ )} + {f.link && ( + + Learn more → + + )} +
+ ))} +
+ )} +
+ +
+

Connect

+
+
+ Chain ID + +
+
+ RPC URL + +
+
+ Explorer + + {explorerUrl} + +
+

+ Public RPC access is IP rate limited. +

+
+ +
+ {walletStatus && ( +

+ {walletStatus} +

+ )} +
+
+ +
+

Deployed Contracts

+
+ {!contractEntries ? ( +

+ Loading… +

+ ) : contractEntries.length === 0 ? ( +

+ No contracts deployed on this vibe. +

+ ) : ( + contractEntries.map(([k, v]) => { + const meta = WATCHABLE_TOKENS[k]; + return ( +
+ + {CONTRACT_LABELS[k] ?? k} + + + {v} + + {meta ? ( + + ) : ( + + )} +
+ ); + }) + )} +
+
+
+ +
+ + branch {config.branch ?? "unknown"} + + + commit {(config.commit ?? "unknown").slice(0, 12)} + + + + base.org + +
+ + ); +} diff --git a/src/app/api/vibenet/config/route.ts b/src/app/api/vibenet/config/route.ts new file mode 100644 index 00000000..c0e96e65 --- /dev/null +++ b/src/app/api/vibenet/config/route.ts @@ -0,0 +1,29 @@ +import { readFile } from "node:fs/promises"; +import { NextResponse } from "next/server"; + +export const dynamic = "force-dynamic"; + +const CONFIG_PATH = process.env.VIBENET_CONFIG_PATH ?? "/config/config.json"; + +export async function GET() { + try { + const raw = await readFile(CONFIG_PATH, "utf8"); + return new NextResponse(raw, { + headers: { + "Content-Type": "application/json", + "Cache-Control": "no-store", + }, + }); + } catch { + return NextResponse.json( + { + title: "base vibenet", + subtitle: "An ephemeral Base devnet.", + features: [], + branch: "unknown", + commit: "unknown", + }, + { headers: { "Cache-Control": "no-store" } }, + ); + } +} diff --git a/src/app/api/vibenet/contracts/route.ts b/src/app/api/vibenet/contracts/route.ts new file mode 100644 index 00000000..079b5a9a --- /dev/null +++ b/src/app/api/vibenet/contracts/route.ts @@ -0,0 +1,23 @@ +import { readFile } from "node:fs/promises"; +import { NextResponse } from "next/server"; + +export const dynamic = "force-dynamic"; + +const CONTRACTS_PATH = + process.env.VIBENET_CONTRACTS_PATH ?? "/shared/contracts.json"; + +export async function GET() { + try { + const raw = await readFile(CONTRACTS_PATH, "utf8"); + return new NextResponse(raw, { + headers: { + "Content-Type": "application/json", + "Cache-Control": "no-store", + }, + }); + } catch { + // contracts.json is written by vibenet-setup after chain is ready; + // return empty object during the boot window + return NextResponse.json({}, { headers: { "Cache-Control": "no-store" } }); + } +} diff --git a/src/app/api/vibenet/explorer/address/[addr]/route.ts b/src/app/api/vibenet/explorer/address/[addr]/route.ts new file mode 100644 index 00000000..ade546a3 --- /dev/null +++ b/src/app/api/vibenet/explorer/address/[addr]/route.ts @@ -0,0 +1,52 @@ +import { NextResponse } from "next/server"; +import { createPublicClient, defineChain, http, isAddress } from "viem"; +import { getAddressActivity } from "@/lib/vibenet/db"; + +const rpcUrl = process.env.VIBESCAN_RPC_HTTP_URL ?? "http://localhost:8545"; +const chainId = Number(process.env.VIBESCAN_CHAIN_ID ?? "84538453"); + +function getClient() { + return createPublicClient({ + chain: defineChain({ + id: chainId, + name: "vibenet", + nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 }, + rpcUrls: { default: { http: [rpcUrl] } }, + }), + transport: http(rpcUrl), + }); +} + +export async function GET( + _req: Request, + { params }: { params: Promise<{ addr: string }> }, +) { + const { addr } = await params; + if (!isAddress(addr)) { + return NextResponse.json({ error: "Invalid address" }, { status: 400 }); + } + + try { + const client = getClient(); + const [balance, code, nonce, activity] = await Promise.all([ + client.getBalance({ address: addr }), + client.getCode({ address: addr }).catch(() => undefined), + client.getTransactionCount({ address: addr }).catch(() => 0), + Promise.resolve(getAddressActivity(addr)), + ]); + + const codeBytes = code && code !== "0x" ? (code.length - 2) / 2 : 0; + const isContract = codeBytes > 0; + + return NextResponse.json({ + address: addr, + balance_wei: `0x${balance.toString(16)}`, + nonce, + is_contract: isContract, + code_size: codeBytes, + activity, + }); + } catch (e) { + return NextResponse.json({ error: String(e) }, { status: 500 }); + } +} diff --git a/src/app/api/vibenet/explorer/block/[hash]/route.ts b/src/app/api/vibenet/explorer/block/[hash]/route.ts new file mode 100644 index 00000000..d1835726 --- /dev/null +++ b/src/app/api/vibenet/explorer/block/[hash]/route.ts @@ -0,0 +1,62 @@ +import { NextResponse } from "next/server"; +import { createPublicClient, defineChain, http } from "viem"; + +const rpcUrl = process.env.VIBESCAN_RPC_HTTP_URL ?? "http://localhost:8545"; +const chainId = Number(process.env.VIBESCAN_CHAIN_ID ?? "84538453"); + +function getClient() { + return createPublicClient({ + chain: defineChain({ + id: chainId, + name: "vibenet", + nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 }, + rpcUrls: { default: { http: [rpcUrl] } }, + }), + transport: http(rpcUrl), + }); +} + +export async function GET( + _req: Request, + { params }: { params: Promise<{ hash: string }> }, +) { + const { hash } = await params; + try { + const client = getClient(); + // Accepts block hash or block number + const block = + hash.startsWith("0x") && hash.length === 66 + ? await client.getBlock({ + blockHash: hash as `0x${string}`, + includeTransactions: false, + }) + : await client.getBlock({ + blockNumber: BigInt(hash), + includeTransactions: false, + }); + + if (!block) { + return NextResponse.json({ error: "Block not found" }, { status: 404 }); + } + // Serialize bigints as hex strings (matching go-ethereum RPC format) + return NextResponse.json({ + number: `0x${block.number?.toString(16)}`, + hash: block.hash, + parentHash: block.parentHash, + timestamp: `0x${block.timestamp.toString(16)}`, + miner: block.miner, + gasUsed: `0x${block.gasUsed.toString(16)}`, + gasLimit: `0x${block.gasLimit.toString(16)}`, + baseFeePerGas: block.baseFeePerGas + ? `0x${block.baseFeePerGas.toString(16)}` + : null, + transactions: block.transactions, + }); + } catch (e) { + const msg = String(e); + if (msg.includes("not found") || msg.includes("null")) { + return NextResponse.json({ error: "Block not found" }, { status: 404 }); + } + return NextResponse.json({ error: msg }, { status: 500 }); + } +} diff --git a/src/app/api/vibenet/explorer/blocks/route.ts b/src/app/api/vibenet/explorer/blocks/route.ts new file mode 100644 index 00000000..5cc53c81 --- /dev/null +++ b/src/app/api/vibenet/explorer/blocks/route.ts @@ -0,0 +1,15 @@ +import { NextResponse } from "next/server"; +import { getRecentBlocks, getRecentTxs } from "@/lib/vibenet/db"; + +export const dynamic = "force-dynamic"; + +export async function GET() { + try { + return NextResponse.json({ + blocks: getRecentBlocks(20), + txs: getRecentTxs(20), + }); + } catch { + return NextResponse.json({ blocks: [], txs: [] }); + } +} diff --git a/src/app/api/vibenet/explorer/stats/route.ts b/src/app/api/vibenet/explorer/stats/route.ts new file mode 100644 index 00000000..c00f3f33 --- /dev/null +++ b/src/app/api/vibenet/explorer/stats/route.ts @@ -0,0 +1,12 @@ +import { NextResponse } from "next/server"; +import { getStats } from "@/lib/vibenet/db"; + +export const dynamic = "force-dynamic"; + +export async function GET() { + try { + return NextResponse.json(getStats()); + } catch { + return NextResponse.json({ blocks: 0, txs: 0, addresses: 0 }); + } +} diff --git a/src/app/api/vibenet/explorer/tx/[hash]/route.ts b/src/app/api/vibenet/explorer/tx/[hash]/route.ts new file mode 100644 index 00000000..9ac30b72 --- /dev/null +++ b/src/app/api/vibenet/explorer/tx/[hash]/route.ts @@ -0,0 +1,105 @@ +import { NextResponse } from "next/server"; +import { createPublicClient, defineChain, http } from "viem"; + +const rpcUrl = process.env.VIBESCAN_RPC_HTTP_URL ?? "http://localhost:8545"; +const chainId = Number(process.env.VIBESCAN_CHAIN_ID ?? "84538453"); + +function getClient() { + return createPublicClient({ + chain: defineChain({ + id: chainId, + name: "vibenet", + nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 }, + rpcUrls: { default: { http: [rpcUrl] } }, + }), + transport: http(rpcUrl), + }); +} + +export async function GET( + _req: Request, + { params }: { params: Promise<{ hash: string }> }, +) { + const { hash } = await params; + try { + const client = getClient(); + const [tx, receipt, block] = await Promise.all([ + client.getTransaction({ hash: hash as `0x${string}` }), + client + .getTransactionReceipt({ hash: hash as `0x${string}` }) + .catch(() => null), + // We need the block timestamp for the tx detail page + client + .getTransaction({ hash: hash as `0x${string}` }) + .then((t) => + t.blockNumber + ? client.getBlock({ blockNumber: t.blockNumber }).catch(() => null) + : null, + ), + ]); + + if (!tx) { + return NextResponse.json( + { error: "Transaction not found" }, + { status: 404 }, + ); + } + + const gasUsed = receipt?.gasUsed + ? `0x${receipt.gasUsed.toString(16)}` + : null; + const effectiveGasPrice = receipt?.effectiveGasPrice + ? `0x${receipt.effectiveGasPrice.toString(16)}` + : null; + const fee = + receipt?.gasUsed && receipt?.effectiveGasPrice + ? `0x${(receipt.gasUsed * receipt.effectiveGasPrice).toString(16)}` + : null; + const contractAddress = receipt?.contractAddress ?? null; + + return NextResponse.json({ + hash: tx.hash, + blockHash: tx.blockHash, + blockNumber: tx.blockNumber ? `0x${tx.blockNumber.toString(16)}` : null, + timestamp: block?.timestamp ? `0x${block.timestamp.toString(16)}` : null, + from: tx.from, + to: tx.to, + value: `0x${tx.value.toString(16)}`, + gas: `0x${tx.gas.toString(16)}`, + gasPrice: tx.gasPrice ? `0x${tx.gasPrice.toString(16)}` : "0x0", + gasUsed, + effectiveGasPrice, + fee, + type: tx.type ?? null, + typeHex: tx.typeHex ?? (typeof tx.type === "string" ? tx.type : null), + nonce: `0x${tx.nonce.toString(16)}`, + input: tx.input, + transactionIndex: + tx.transactionIndex !== null + ? `0x${tx.transactionIndex.toString(16)}` + : null, + status: + receipt?.status === "success" + ? "ok" + : receipt?.status === "reverted" + ? "fail" + : "pending", + contractAddress, + logs: (receipt?.logs ?? []).map((log) => ({ + address: log.address, + topics: log.topics, + data: log.data, + logIndex: log.logIndex, + })), + }); + } catch (e) { + const msg = String(e); + if (msg.includes("not found") || msg.includes("null")) { + return NextResponse.json( + { error: "Transaction not found" }, + { status: 404 }, + ); + } + return NextResponse.json({ error: msg }, { status: 500 }); + } +} diff --git a/src/app/api/vibenet/faucet/drip-nfv/route.ts b/src/app/api/vibenet/faucet/drip-nfv/route.ts new file mode 100644 index 00000000..5c672c37 --- /dev/null +++ b/src/app/api/vibenet/faucet/drip-nfv/route.ts @@ -0,0 +1,67 @@ +import { NextResponse } from "next/server"; +import { encodeFunctionData, isAddress, parseAbi } from "viem"; +import { + checkCooldown, + clientIp, + getAddrCooldownSecs, + getContractAddress, + getIpCooldownSecs, + getPublicClient, + getWalletClient, + recordDrip, +} from "@/lib/vibenet/faucet"; + +export const dynamic = "force-dynamic"; + +const MINT_ABI = parseAbi([ + "function mint(address to) external returns (uint256)", +]); + +export async function POST(req: Request) { + const body = await req.json().catch(() => ({})); + const { address } = body as { address?: string }; + + if (!address || !isAddress(address)) { + return NextResponse.json({ error: "Invalid address" }, { status: 400 }); + } + + const nfvAddress = await getContractAddress("nfv"); + if (!nfvAddress) { + return NextResponse.json( + { error: "NFV contract not yet deployed. Try again shortly." }, + { status: 503 }, + ); + } + + const ip = clientIp(req); + const cooldownErr = checkCooldown( + "nfv", + ip, + address, + getIpCooldownSecs(), + getAddrCooldownSecs(), + ); + if (cooldownErr) { + return NextResponse.json({ error: cooldownErr }, { status: 429 }); + } + + try { + const wallet = getWalletClient(); + const publicClient = getPublicClient(); + const data = encodeFunctionData({ + abi: MINT_ABI, + functionName: "mint", + args: [address], + }); + const hash = await wallet.sendTransaction({ to: nfvAddress, data }); + await publicClient.waitForTransactionReceipt({ hash }); + recordDrip("nfv", ip, address); + return NextResponse.json({ + tx_hash: hash, + to: address, + nfv_address: nfvAddress, + }); + } catch (e) { + return NextResponse.json({ error: String(e) }, { status: 500 }); + } +} diff --git a/src/app/api/vibenet/faucet/drip-usdv/route.ts b/src/app/api/vibenet/faucet/drip-usdv/route.ts new file mode 100644 index 00000000..007298ff --- /dev/null +++ b/src/app/api/vibenet/faucet/drip-usdv/route.ts @@ -0,0 +1,68 @@ +import { NextResponse } from "next/server"; +import { encodeFunctionData, isAddress, parseAbi } from "viem"; +import { + checkCooldown, + clientIp, + getAddrCooldownSecs, + getContractAddress, + getIpCooldownSecs, + getPublicClient, + getUsdvDripUnits, + getWalletClient, + recordDrip, +} from "@/lib/vibenet/faucet"; + +export const dynamic = "force-dynamic"; + +const MINT_ABI = parseAbi([ + "function mint(address to, uint256 amount) external", +]); + +export async function POST(req: Request) { + const body = await req.json().catch(() => ({})); + const { address } = body as { address?: string }; + + if (!address || !isAddress(address)) { + return NextResponse.json({ error: "Invalid address" }, { status: 400 }); + } + + const usdvAddress = await getContractAddress("usdv"); + if (!usdvAddress) { + return NextResponse.json( + { error: "USDV contract not yet deployed. Try again shortly." }, + { status: 503 }, + ); + } + + const ip = clientIp(req); + const cooldownErr = checkCooldown( + "usdv", + ip, + address, + getIpCooldownSecs(), + getAddrCooldownSecs(), + ); + if (cooldownErr) { + return NextResponse.json({ error: cooldownErr }, { status: 429 }); + } + + try { + const wallet = getWalletClient(); + const publicClient = getPublicClient(); + const data = encodeFunctionData({ + abi: MINT_ABI, + functionName: "mint", + args: [address, getUsdvDripUnits()], + }); + const hash = await wallet.sendTransaction({ to: usdvAddress, data }); + await publicClient.waitForTransactionReceipt({ hash }); + recordDrip("usdv", ip, address); + return NextResponse.json({ + tx_hash: hash, + to: address, + usdv_address: usdvAddress, + }); + } catch (e) { + return NextResponse.json({ error: String(e) }, { status: 500 }); + } +} diff --git a/src/app/api/vibenet/faucet/drip/route.ts b/src/app/api/vibenet/faucet/drip/route.ts new file mode 100644 index 00000000..a8973196 --- /dev/null +++ b/src/app/api/vibenet/faucet/drip/route.ts @@ -0,0 +1,53 @@ +import { NextResponse } from "next/server"; +import { isAddress } from "viem"; +import { + checkCooldown, + clientIp, + getAddrCooldownSecs, + getDripWei, + getIpCooldownSecs, + getPublicClient, + getWalletClient, + recordDrip, +} from "@/lib/vibenet/faucet"; + +export const dynamic = "force-dynamic"; + +export async function POST(req: Request) { + const body = await req.json().catch(() => ({})); + const { address } = body as { address?: string }; + + if (!address || !isAddress(address)) { + return NextResponse.json({ error: "Invalid address" }, { status: 400 }); + } + + const ip = clientIp(req); + const cooldownErr = checkCooldown( + "eth", + ip, + address, + getIpCooldownSecs(), + getAddrCooldownSecs(), + ); + if (cooldownErr) { + return NextResponse.json({ error: cooldownErr }, { status: 429 }); + } + + try { + const wallet = getWalletClient(); + const publicClient = getPublicClient(); + const hash = await wallet.sendTransaction({ + to: address, + value: getDripWei(), + }); + await publicClient.waitForTransactionReceipt({ hash }); + recordDrip("eth", ip, address); + return NextResponse.json({ + tx_hash: hash, + amount_wei: getDripWei().toString(), + to: address, + }); + } catch (e) { + return NextResponse.json({ error: String(e) }, { status: 500 }); + } +} diff --git a/src/app/api/vibenet/faucet/status/route.ts b/src/app/api/vibenet/faucet/status/route.ts new file mode 100644 index 00000000..8bdf1421 --- /dev/null +++ b/src/app/api/vibenet/faucet/status/route.ts @@ -0,0 +1,40 @@ +import { NextResponse } from "next/server"; +import { + getAddrCooldownSecs, + getContractAddress, + getDripWei, + getFaucetAddress, + getIpCooldownSecs, + getPublicClient, + getUsdvDripUnits, +} from "@/lib/vibenet/faucet"; + +export const dynamic = "force-dynamic"; + +export async function GET() { + try { + const address = getFaucetAddress(); + const client = getPublicClient(); + const balance = await client.getBalance({ address }); + const [usdvAddress, nfvAddress] = await Promise.all([ + getContractAddress("usdv"), + getContractAddress("nfv"), + ]); + + return NextResponse.json({ + address, + chain_id: client.chain.id, + drip_wei: getDripWei().toString(), + balance_wei: balance.toString(), + ip_cooldown_secs: getIpCooldownSecs(), + addr_cooldown_secs: getAddrCooldownSecs(), + ...(usdvAddress && { + usdv_address: usdvAddress, + usdv_drip_units: getUsdvDripUnits().toString(), + }), + ...(nfvAddress && { nfv_address: nfvAddress }), + }); + } catch (e) { + return NextResponse.json({ error: String(e) }, { status: 500 }); + } +} diff --git a/src/app/layout.tsx b/src/app/layout.tsx index bc9a9f21..70210617 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -13,8 +13,8 @@ const geistMono = Geist_Mono({ }); export const metadata: Metadata = { - title: "TIPS", - description: "A beautiful UI for interacting with TIPS", + title: "base vibenet", + description: "An ephemeral Base devnet for trying out in-flight features.", }; export default function RootLayout({ diff --git a/src/app/block/[hash]/page.tsx b/src/app/tips/block/[hash]/page.tsx similarity index 98% rename from src/app/block/[hash]/page.tsx rename to src/app/tips/block/[hash]/page.tsx index c5d0a4a0..95a5ee7c 100644 --- a/src/app/block/[hash]/page.tsx +++ b/src/app/tips/block/[hash]/page.tsx @@ -181,7 +181,7 @@ function TransactionRow({ ); if (hasBundle) { - return {content}; + return {content}; } return content; @@ -331,7 +331,7 @@ export default function BlockPage({ params }: PageProps) {
@@ -352,7 +352,7 @@ export default function BlockPage({ params }: PageProps) {
TIPS @@ -363,7 +363,7 @@ export default function BlockPage({ params }: PageProps) {
{Number(data.number) > 0 ? ( @@ -401,7 +401,7 @@ export default function BlockPage({ params }: PageProps) { )} diff --git a/src/app/bundles/[hash]/page.tsx b/src/app/tips/bundles/[hash]/page.tsx similarity index 99% rename from src/app/bundles/[hash]/page.tsx rename to src/app/tips/bundles/[hash]/page.tsx index 9ea8602a..57522888 100644 --- a/src/app/bundles/[hash]/page.tsx +++ b/src/app/tips/bundles/[hash]/page.tsx @@ -415,7 +415,7 @@ function TimelineEventDetails({
{event.event} Block #{event.data.block_number} @@ -542,7 +542,7 @@ export default function BundlePage({ params }: PageProps) {
@@ -563,7 +563,7 @@ export default function BundlePage({ params }: PageProps) {
TIPS diff --git a/src/app/page.tsx b/src/app/tips/page.tsx similarity index 99% rename from src/app/page.tsx rename to src/app/tips/page.tsx index 1b031193..80693324 100644 --- a/src/app/page.tsx +++ b/src/app/tips/page.tsx @@ -3,13 +3,13 @@ import Link from "next/link"; import { useRouter } from "next/navigation"; import { useCallback, useEffect, useState } from "react"; +import type { BlockSummary, BlocksResponse } from "@/app/api/blocks/route"; +import type { RejectedTransactionsResponse } from "@/app/api/rejected/route"; import { formatRejectionReason, type MeterBundleResponse, type RejectedTransaction, } from "@/lib/s3"; -import type { BlockSummary, BlocksResponse } from "./api/blocks/route"; -import type { RejectedTransactionsResponse } from "./api/rejected/route"; type Tab = "blocks" | "rejected"; @@ -66,7 +66,7 @@ function SearchBar({ onError }: { onError: (error: string | null) => void }) { const result = await response.json(); if (result.bundle_ids && result.bundle_ids.length > 0) { - router.push(`/bundles/${result.bundle_ids[0]}`); + router.push(`/tips/bundles/${result.bundle_ids[0]}`); } else { onError("No bundle found for this transaction"); } @@ -112,7 +112,7 @@ function BlockRow({ block, index }: { block: BlockSummary; index: number }) { return ( diff --git a/src/app/txn/[hash]/page.tsx b/src/app/tips/txn/[hash]/page.tsx similarity index 97% rename from src/app/txn/[hash]/page.tsx rename to src/app/tips/txn/[hash]/page.tsx index 76f1dda3..e98211b0 100644 --- a/src/app/txn/[hash]/page.tsx +++ b/src/app/tips/txn/[hash]/page.tsx @@ -39,7 +39,7 @@ export default function TransactionRedirectPage({ params }: PageProps) { const result: TransactionHistoryResponse = await response.json(); if (result.bundle_ids && result.bundle_ids.length > 0) { - router.push(`/bundles/${result.bundle_ids[0]}`); + router.push(`/tips/bundles/${result.bundle_ids[0]}`); } else { setError("No bundle found for this transaction"); } diff --git a/src/lib/vibenet/db.ts b/src/lib/vibenet/db.ts new file mode 100644 index 00000000..d78bc5f7 --- /dev/null +++ b/src/lib/vibenet/db.ts @@ -0,0 +1,115 @@ +import { readFileSync } from "node:fs"; +import path from "node:path"; +import Database from "better-sqlite3"; + +const DB_PATH = process.env.VIBESCAN_DB_PATH ?? "/data/vibescan.db"; +const MIGRATION_PATH = path.join( + process.cwd(), + "docker/migrations/0001_init.sql", +); + +let _db: Database.Database | null = null; + +export function getDb(): Database.Database { + if (_db) return _db; + _db = new Database(DB_PATH); + _db.pragma("journal_mode = WAL"); + _db.pragma("synchronous = NORMAL"); + const migration = readFileSync(MIGRATION_PATH, "utf8"); + _db.exec(migration); + return _db; +} + +export interface BlockRow { + number: number; + hash: string; + timestamp: number; + miner: string; + tx_count: number; + gas_used: number; + gas_limit: number; + base_fee: string | null; +} + +export interface TxRow { + hash: string; + block_num: number; + tx_index: number; + from_addr: string; + to_addr: string | null; + value: string; + status: number; + created: string | null; +} + +export interface ActivityRow { + address: string; + block_num: number; + tx_index: number; + log_index: number; + tx_hash: string; + role: number; + token: string | null; +} + +export interface StatsRow { + blocks: number; + txs: number; + addresses: number; +} + +export function getStats(): StatsRow { + const db = getDb(); + return db + .prepare("SELECT blocks, txs, addresses FROM explorer_stats WHERE id = 0") + .get() as StatsRow; +} + +export function getRecentBlocks(limit = 20): BlockRow[] { + const db = getDb(); + return db + .prepare("SELECT * FROM blocks ORDER BY number DESC LIMIT ?") + .all(limit) as BlockRow[]; +} + +export function getRecentTxs(limit = 20): TxRow[] { + const db = getDb(); + return db + .prepare("SELECT * FROM txs ORDER BY block_num DESC, tx_index DESC LIMIT ?") + .all(limit) as TxRow[]; +} + +export function getBlockHash(number: number): string | null { + const db = getDb(); + const row = db + .prepare("SELECT hash FROM blocks WHERE number = ?") + .get(number) as { hash: string } | undefined; + return row?.hash ?? null; +} + +export function getAddressActivity(address: string, limit = 50): ActivityRow[] { + const db = getDb(); + return db + .prepare( + `SELECT * FROM address_activity + WHERE address = ? + ORDER BY block_num DESC, tx_index DESC, log_index DESC + LIMIT ?`, + ) + .all(address.toLowerCase(), limit) as ActivityRow[]; +} + +export function getCursor(): { + last_indexed_block: number; + last_indexed_hash: string; +} | null { + const db = getDb(); + return (db + .prepare( + "SELECT last_indexed_block, last_indexed_hash FROM cursor WHERE id = 0", + ) + .get() ?? null) as { + last_indexed_block: number; + last_indexed_hash: string; + } | null; +} diff --git a/src/lib/vibenet/faucet.ts b/src/lib/vibenet/faucet.ts new file mode 100644 index 00000000..4f753880 --- /dev/null +++ b/src/lib/vibenet/faucet.ts @@ -0,0 +1,133 @@ +import { readFile } from "node:fs/promises"; +import { + type Address, + createPublicClient, + createWalletClient, + defineChain, + type Hex, + http, + parseEther, +} from "viem"; +import { privateKeyToAccount } from "viem/accounts"; + +// Rate limiting: last drip timestamp per IP / per address, per asset. +// Module-level state — resets on container restart (intentional for devnet). +const ipCooldowns = new Map>(); // asset → ip → ts +const addrCooldowns = new Map>(); // asset → addr → ts + +function cooldownMap(store: Map>, asset: string) { + let m = store.get(asset); + if (!m) { + m = new Map(); + store.set(asset, m); + } + return m; +} + +export function checkCooldown( + asset: string, + ip: string, + address: string, + ipSecs: number, + addrSecs: number, +): string | null { + const now = Date.now() / 1000; + const ipMap = cooldownMap(ipCooldowns, asset); + const addrMap = cooldownMap(addrCooldowns, asset); + + const lastIp = ipMap.get(ip) ?? 0; + const lastAddr = addrMap.get(address.toLowerCase()) ?? 0; + + if (now - lastIp < ipSecs) { + const wait = Math.ceil(ipSecs - (now - lastIp)); + return `IP rate limited. Try again in ${wait}s.`; + } + if (now - lastAddr < addrSecs) { + const wait = Math.ceil(addrSecs - (now - lastAddr)); + return `Address rate limited. Try again in ${wait}s.`; + } + return null; +} + +export function recordDrip(asset: string, ip: string, address: string) { + const now = Date.now() / 1000; + cooldownMap(ipCooldowns, asset).set(ip, now); + cooldownMap(addrCooldowns, asset).set(address.toLowerCase(), now); +} + +function getChain() { + const chainId = Number(process.env.VIBENET_FAUCET_CHAIN_ID ?? "84538453"); + const rpcUrl = process.env.VIBENET_FAUCET_RPC_URL ?? "http://localhost:8545"; + return defineChain({ + id: chainId, + name: "vibenet", + nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 }, + rpcUrls: { default: { http: [rpcUrl] } }, + }); +} + +function getAccount() { + const pk = process.env.VIBENET_FAUCET_PRIVATE_KEY; + if (!pk) throw new Error("VIBENET_FAUCET_PRIVATE_KEY is not set"); + return privateKeyToAccount(pk as Hex); +} + +export function getPublicClient() { + const chain = getChain(); + return createPublicClient({ chain, transport: http() }); +} + +export function getWalletClient() { + const chain = getChain(); + return createWalletClient({ + account: getAccount(), + chain, + transport: http(), + }); +} + +export function getFaucetAddress(): Address { + return getAccount().address; +} + +export function getDripWei(): bigint { + return BigInt( + process.env.VIBENET_FAUCET_DRIP_WEI ?? String(parseEther("0.1")), + ); +} + +export function getUsdvDripUnits(): bigint { + return BigInt(process.env.VIBENET_FAUCET_USDV_DRIP_UNITS ?? "1000000000"); +} + +export function getIpCooldownSecs(): number { + return Number(process.env.VIBENET_FAUCET_IP_COOLDOWN_SECS ?? "3600"); +} + +export function getAddrCooldownSecs(): number { + return Number(process.env.VIBENET_FAUCET_ADDR_COOLDOWN_SECS ?? "3600"); +} + +export async function getContractAddress( + name: string, +): Promise
{ + const path = + process.env.VIBENET_FAUCET_CONTRACTS_PATH ?? "/shared/contracts.json"; + try { + const raw = await readFile(path, "utf8"); + const contracts = JSON.parse(raw) as Record; + const addr = contracts[name]; + return addr ? (addr as Address) : null; + } catch { + return null; + } +} + +export function clientIp(req: Request): string { + return ( + req.headers.get("x-real-ip") ?? + req.headers.get("cf-connecting-ip") ?? + req.headers.get("x-forwarded-for")?.split(",")[0]?.trim() ?? + "unknown" + ); +} diff --git a/src/proxy.ts b/src/proxy.ts index 6759d1de..bb777d04 100644 --- a/src/proxy.ts +++ b/src/proxy.ts @@ -1,25 +1,49 @@ import type { NextRequest } from "next/server"; import { NextResponse } from "next/server"; +const DOMAIN = "vibes.base.org"; + export function proxy(request: NextRequest) { + const host = request.headers.get("host") ?? ""; + const path = request.nextUrl.pathname; + + // OPTIONS preflight — reply immediately if (request.method === "OPTIONS") { return new NextResponse(null, { status: 204, headers: { "Access-Control-Allow-Origin": "*", - "Access-Control-Allow-Methods": "GET, OPTIONS", + "Access-Control-Allow-Methods": "GET, POST, OPTIONS", "Access-Control-Allow-Headers": "Content-Type", }, }); } + // Subdomain routing — only rewrite page paths, not /api/* which routes + // correctly regardless of which subdomain the request originates from. + if (!path.startsWith("/api")) { + // faucet.vibes.base.org/* → /faucet/* + if (host === `faucet.${DOMAIN}` && !path.startsWith("/faucet")) { + const url = request.nextUrl.clone(); + url.pathname = `/faucet${path === "/" ? "" : path}`; + return NextResponse.rewrite(url); + } + + // explorer.vibes.base.org/* → /explorer/* + if (host === `explorer.${DOMAIN}` && !path.startsWith("/explorer")) { + const url = request.nextUrl.clone(); + url.pathname = `/explorer${path === "/" ? "" : path}`; + return NextResponse.rewrite(url); + } + } + const response = NextResponse.next(); response.headers.set("Access-Control-Allow-Origin", "*"); - response.headers.set("Access-Control-Allow-Methods", "GET, OPTIONS"); + response.headers.set("Access-Control-Allow-Methods", "GET, POST, OPTIONS"); response.headers.set("Access-Control-Allow-Headers", "Content-Type"); return response; } export const config = { - matcher: "/api/:path*", + matcher: ["/((?!_next/static|_next/image|favicon.ico).*)"], }; diff --git a/src/styles/vibenet.css b/src/styles/vibenet.css new file mode 100644 index 00000000..9f96a064 --- /dev/null +++ b/src/styles/vibenet.css @@ -0,0 +1,880 @@ +/* base vibenet — landing, faucet, explorer. + * + * Palette + type approximates docs.base.org: near-black canvas, Base Blue + * accent (#0052FF), thin borders, generous whitespace, system sans for + * prose and a mono stack for anything hex. + * + * Body styles are scoped to .vibenet-app so they don't bleed into + * non-vibenet routes (e.g. /tips). + */ + +.vibenet-app { + --bg: #0a0b0f; + --bg-elev: #0f121a; + --card: #12151d; + --card-hover: #161a24; + --border: #1f2330; + --border-strong: #2a3040; + --fg: #ffffff; + --fg-dim: #8a93a6; + --fg-dimmer: #5b6478; + --accent: #0052ff; + --accent-hover: #3d75ff; + --accent-dim: #002a80; + --ok: #4ade80; + --err: #f87171; + --mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace; + --sans: + -apple-system, BlinkMacSystemFont, "Inter", "Segoe UI", system-ui, + sans-serif; + --radius: 8px; + --radius-lg: 12px; + + min-height: 100vh; + background: var(--bg); + color: var(--fg); + font-family: var(--sans); + line-height: 1.55; + font-size: 15px; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.vibenet-app *, +.vibenet-app *::before, +.vibenet-app *::after { + box-sizing: border-box; +} + +.vibenet-app a { + color: var(--accent-hover); + text-decoration: none; +} +.vibenet-app a:hover { + color: #6e92ff; + text-decoration: underline; +} + +/* ---------- header / nav ------------------------------------------------ */ + +.vibenet-app .site-header { + display: flex; + align-items: center; + justify-content: space-between; + gap: 1.5rem; + padding: 18px 28px; + border-bottom: 1px solid var(--border); + background: var(--bg); + position: sticky; + top: 0; + z-index: 10; + backdrop-filter: blur(6px); +} + +.vibenet-app .brand { + display: inline-flex; + align-items: center; + gap: 10px; + color: var(--fg); + font-weight: 700; + font-size: 17px; + letter-spacing: 0.01em; +} +.vibenet-app .brand:hover { + color: var(--fg); + text-decoration: none; +} + +.vibenet-app .brand-mark { + display: inline-block; + width: 20px; + height: 20px; + background: var(--accent); + border-radius: 4px; +} + +.vibenet-app .site-nav { + display: flex; + align-items: center; + gap: 1.25rem; + font-size: 14px; +} +.vibenet-app .site-nav a, +.vibenet-app .site-nav .current { + color: var(--fg-dim); + padding: 4px 2px; + border-bottom: 1px solid transparent; +} +.vibenet-app .site-nav a:hover { + color: var(--fg); + border-bottom-color: var(--accent); + text-decoration: none; +} +.vibenet-app .site-nav .current { + color: var(--fg); +} + +/* ---------- layout ------------------------------------------------------ */ + +.vibenet-app main { + max-width: 960px; + margin: 0 auto; + padding: 2.5rem 28px 3rem; +} +.vibenet-app main.wide { + max-width: 1200px; +} + +/* Only top-level sections get the spacing — sections inside grids + * (e.g. .two-col on the explorer home) align to the top of their cell. */ +.vibenet-app main > section + section { + margin-top: 2.5rem; +} +.vibenet-app main h2 { + font-size: 1.25rem; + font-weight: 600; + margin: 0 0 1rem; + letter-spacing: -0.01em; +} +.vibenet-app main h3 { + font-size: 1.05rem; + font-weight: 600; + margin: 1.5rem 0 0.5rem; +} + +.vibenet-app .muted { + color: var(--fg-dim); +} +.vibenet-app .small { + font-size: 13px; +} + +/* ---------- hero / chain card ------------------------------------------- */ + +.vibenet-app .hero { + margin-bottom: 0.5rem; +} + +.vibenet-app .page-title { + font-size: 2rem; + margin: 0 0 0.25rem; + letter-spacing: -0.02em; + font-weight: 700; +} + +.vibenet-app .subtitle { + margin: 0 0 1.25rem; + color: var(--fg-dim); + font-size: 1.05rem; +} + +.vibenet-app .chain-card { + background: var(--card); + border: 1px solid var(--border); + border-radius: var(--radius-lg); + padding: 1.15rem 1.5rem; + display: flex; + flex-direction: column; + gap: 0.5rem; +} + +.vibenet-app .chain-row { + display: grid; + grid-template-columns: 110px 1fr; + gap: 1rem; + align-items: center; + font-size: 14px; + min-height: 28px; +} + +.vibenet-app .chain-label { + color: var(--fg-dim); + text-transform: uppercase; + font-size: 11px; + letter-spacing: 0.08em; + font-weight: 600; +} + +.vibenet-app .chain-value { + font-family: var(--mono); + font-size: 13px; + color: var(--fg); + overflow: hidden; +} + +.vibenet-app code { + font-family: var(--mono); + background: transparent; + padding: 0; + color: var(--fg); +} + +.vibenet-app button.chain-value.copyable { + display: flex; + align-items: center; + justify-content: space-between; + gap: 0.75rem; + width: 100%; + background: transparent; + border: 1px solid transparent; + padding: 4px 8px; + margin: 0; + border-radius: 6px; + color: var(--fg); + text-align: left; + font-weight: 400; + cursor: pointer; + min-width: 0; + transition: + background 0.1s ease, + border-color 0.1s ease; +} +.vibenet-app button.chain-value.copyable:hover { + background: var(--bg-elev); + border-color: var(--border); +} +.vibenet-app button.chain-value.copyable.copied { + border-color: var(--ok); +} +.vibenet-app .copy-hint { + font-family: var(--sans); + font-size: 11px; + color: var(--fg-dimmer); + text-transform: uppercase; + letter-spacing: 0.08em; + opacity: 0; + transition: + opacity 0.1s ease, + color 0.1s ease; + flex-shrink: 0; +} +.vibenet-app button.chain-value.copyable:hover .copy-hint, +.vibenet-app button.chain-value.copyable:focus-visible .copy-hint, +.vibenet-app button.chain-value.copyable.copied .copy-hint { + opacity: 1; +} +.vibenet-app button.chain-value.copyable.copied .copy-hint { + color: var(--ok); +} +.vibenet-app a.chain-value { + display: block; + padding: 4px 8px; + border: 1px solid transparent; + border-radius: 6px; +} + +.vibenet-app .truncate { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + display: block; + min-width: 0; +} + +.vibenet-app .chain-actions { + display: flex; + gap: 0.5rem; + flex-wrap: wrap; + margin-top: 0.4rem; +} + +.vibenet-app .notice { + margin: 0.25rem 0 0; + color: var(--fg-dim); +} + +/* ---------- features grid ----------------------------------------------- */ + +.vibenet-app .features-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); + gap: 0.75rem; +} + +.vibenet-app .feature-card { + background: var(--card); + border: 1px solid var(--border); + border-radius: var(--radius); + padding: 1rem 1.1rem; + transition: + border-color 0.1s ease, + background 0.1s ease; + display: flex; + flex-direction: column; + gap: 0.4rem; +} +.vibenet-app .feature-card:hover { + border-color: var(--border-strong); + background: var(--card-hover); +} +.vibenet-app .feature-card .feature-title { + font-weight: 600; + color: var(--fg); + font-size: 14px; +} +.vibenet-app .feature-card .feature-desc { + color: var(--fg-dim); + font-size: 13px; + line-height: 1.5; +} +.vibenet-app .feature-card a { + font-size: 13px; +} + +/* ---------- contracts list ---------------------------------------------- */ + +.vibenet-app .contracts-list { + background: var(--card); + border: 1px solid var(--border); + border-radius: var(--radius); + overflow: hidden; +} +.vibenet-app .contract-row { + display: grid; + grid-template-columns: 160px 1fr auto; + gap: 1rem; + padding: 0.75rem 1rem; + align-items: center; + border-bottom: 1px solid var(--border); +} +.vibenet-app .contract-row:last-child { + border-bottom: none; +} +.vibenet-app .contract-label { + color: var(--fg-dim); + font-size: 13px; + font-weight: 500; +} +.vibenet-app .contract-addr { + font-family: var(--mono); + font-size: 13px; + word-break: break-all; + color: var(--accent-hover); +} + +/* ---------- forms / buttons --------------------------------------------- */ + +.vibenet-app input, +.vibenet-app button, +.vibenet-app textarea, +.vibenet-app select { + font: inherit; +} + +.vibenet-app input[type="text"], +.vibenet-app input:not([type]) { + padding: 0.55rem 0.75rem; + border-radius: 6px; + border: 1px solid var(--border); + background: var(--bg-elev); + color: var(--fg); + font-family: var(--mono); + font-size: 13px; + width: 100%; +} +.vibenet-app input:focus { + outline: none; + border-color: var(--accent); + box-shadow: 0 0 0 2px rgba(0, 82, 255, 0.25); +} + +.vibenet-app button { + cursor: pointer; + background: var(--accent); + color: #ffffff; + border: 1px solid var(--accent); + padding: 0.55rem 1rem; + border-radius: 6px; + font-weight: 600; + font-size: 14px; + transition: + background 0.1s ease, + border-color 0.1s ease; +} +.vibenet-app button:hover:not(:disabled) { + background: var(--accent-hover); + border-color: var(--accent-hover); +} +.vibenet-app button:disabled { + opacity: 0.5; + cursor: not-allowed; +} + +.vibenet-app button.secondary { + background: var(--card); + color: var(--fg); + border-color: var(--border); +} +.vibenet-app button.secondary:hover:not(:disabled) { + background: var(--card-hover); + border-color: var(--accent); +} +.vibenet-app button.small { + padding: 0.35rem 0.75rem; + font-size: 12px; +} + +/* ---------- faucet -------------------------------------------------------- */ + +.vibenet-app .faucet-status { + font-size: 13px; + line-height: 1.6; +} +.vibenet-app .faucet-summary { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); + gap: 0.75rem; +} +.vibenet-app .faucet-pill { + display: flex; + justify-content: space-between; + gap: 1rem; + align-items: center; + padding: 0.75rem 0.9rem; + border: 1px solid var(--border); + border-radius: var(--radius); + background: var(--bg-elev); +} +.vibenet-app .faucet-pill-key { + color: var(--fg-dim); + font-family: var(--mono); +} +.vibenet-app .faucet-pill-value { + color: var(--fg); + font-family: var(--mono); + font-weight: 600; +} +.vibenet-app .faucet-footer-links { + display: flex; + gap: 0.5rem; + flex-wrap: wrap; +} +.vibenet-app .address-chip { + display: inline-flex; + border: 1px solid var(--border); + border-radius: 999px; + padding: 0.25rem 0.65rem; + background: var(--card); + color: var(--accent-hover); + font-size: 12px; +} +.vibenet-app .address-chip:hover { + border-color: var(--accent); + text-decoration: none; +} + +.vibenet-app .faucet-form { + display: flex; + flex-direction: column; + gap: 0.5rem; + margin-top: 1rem; +} +.vibenet-app .faucet-form label { + font-size: 12px; + color: var(--fg-dim); + text-transform: uppercase; + letter-spacing: 0.06em; + font-weight: 600; +} + +.vibenet-app .drip-buttons { + display: flex; + gap: 0.75rem; + flex-wrap: wrap; + margin-top: 0.5rem; +} +.vibenet-app .request-btn { + min-height: 48px; + padding: 0.75rem 1.2rem; + font-size: 15px; + flex: 1 1 220px; +} + +.vibenet-app .drip-result { + margin-top: 0.75rem; + border: 1px solid transparent; + border-radius: var(--radius); + padding: 0; +} +.vibenet-app .drip-result:empty { + display: none; +} +.vibenet-app .drip-result.pending, +.vibenet-app .drip-result.success, +.vibenet-app .drip-result.error { + padding: 0.8rem 0.9rem; + background: var(--bg-elev); + border-color: var(--border); +} +.vibenet-app .drip-result.pending { + color: var(--fg-dim); +} +.vibenet-app .drip-result.success { + border-color: rgba(74, 222, 128, 0.35); +} +.vibenet-app .drip-result.error { + border-color: rgba(248, 113, 113, 0.45); + color: var(--err); +} +.vibenet-app .drip-result-title { + font-weight: 600; + margin-bottom: 0.25rem; +} +.vibenet-app .drip-result-meta { + color: var(--fg-dim); + font-size: 13px; + word-break: break-all; +} +.vibenet-app .tx-link { + font-family: var(--mono); +} + +/* ---------- explorer ----------------------------------------------------- */ + +.vibenet-app .stats { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); + gap: 12px; + margin-bottom: 24px; +} +.vibenet-app .stat { + background: var(--card); + border: 1px solid var(--border); + border-left: 3px solid var(--accent); + border-radius: 6px; + padding: 12px 16px; + display: flex; + flex-direction: column; + gap: 4px; +} +.vibenet-app .stat .label { + color: var(--fg-dim); + font-size: 12px; + text-transform: uppercase; + letter-spacing: 0.06em; +} +.vibenet-app .stat .value { + font-family: var(--mono); + font-size: 20px; +} + +.vibenet-app .search { + display: flex; + gap: 8px; + margin-bottom: 24px; +} +.vibenet-app .search input { + width: 100%; +} +.vibenet-app .search button { + padding: 6px 14px; +} + +.vibenet-app .two-col { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 24px; +} +@media (max-width: 900px) { + .vibenet-app .two-col { + grid-template-columns: 1fr; + } +} + +.vibenet-app table { + width: 100%; + border-collapse: collapse; + background: var(--card); + border: 1px solid var(--border); + border-radius: 6px; + overflow: hidden; +} +.vibenet-app th, +.vibenet-app td { + text-align: left; + padding: 8px 12px; + border-bottom: 1px solid var(--border); + vertical-align: top; +} +.vibenet-app th { + font-weight: 500; + color: var(--fg-dim); + font-size: 12px; + text-transform: uppercase; + letter-spacing: 0.06em; + background: var(--bg-elev); +} +.vibenet-app tr:last-child td { + border-bottom: none; +} + +.vibenet-app code.addr { + font-size: 11.5px; + letter-spacing: -0.01em; + word-break: break-all; + overflow-wrap: anywhere; +} + +/* Link affordance inside tables: subtle dotted underline by default, + * solid + brighter on hover. Makes block numbers and tx hashes obviously + * clickable without screaming for attention. */ +.vibenet-app td a, +.vibenet-app .row-link { + color: var(--accent-hover); + text-decoration: underline; + text-decoration-color: rgba(61, 117, 255, 0.4); + text-decoration-thickness: 1px; + text-underline-offset: 3px; + transition: + color 0.1s ease, + text-decoration-color 0.1s ease; +} +.vibenet-app td a:hover, +.vibenet-app .row-link:hover { + color: #6e92ff; + text-decoration-color: #6e92ff; +} + +/* Hover affordance on whole rows in live tables */ +.vibenet-app .live-table tbody tr:hover { + background: var(--card-hover); +} + +/* New-row flash when a block / tx appears via polling refresh */ +.vibenet-app .live-row-new td { + animation: live-row-highlight 1.2s ease-out; +} +@keyframes live-row-highlight { + 0% { + background: rgba(0, 82, 255, 0.24); + } + 100% { + background: transparent; + } +} + +/* New-stat flash when a stat counter changes */ +.vibenet-app .live-stat-updated { + animation: live-stat-highlight 0.9s ease-out; +} +@keyframes live-stat-highlight { + 0% { + border-color: rgba(0, 82, 255, 0.9); + box-shadow: 0 0 0 2px rgba(0, 82, 255, 0.18); + } + 100% { + border-color: var(--border); + box-shadow: none; + } +} + +.vibenet-app .nowrap { + white-space: nowrap; +} + +/* Detail pages: dl with 160px label column + 1fr value column. + * Used on tx, address, and block detail pages. */ +.vibenet-app .detail { + display: grid; + grid-template-columns: 160px 1fr; + gap: 8px 16px; + background: var(--card); + border: 1px solid var(--border); + border-radius: 6px; + padding: 16px 20px; + margin: 16px 0; +} +.vibenet-app .detail dt { + color: var(--fg-dim); +} +.vibenet-app .detail dd { + margin: 0; + overflow-wrap: anywhere; +} + +/* Subtitle / hash header under

*/ +.vibenet-app p.hash { + font-family: var(--mono); + color: var(--fg-dim); + overflow-wrap: anywhere; + margin: 4px 0 0; +} + +.vibenet-app .dim { + color: var(--fg-dim); +} + +/* Status pill colors used on tx detail */ +.vibenet-app .status-ok, +.vibenet-app .status-success { + color: #4ade80; +} +.vibenet-app .status-fail { + color: #f87171; +} +.vibenet-app .status-pending { + color: var(--fg-dim); +} + +/* Action button row above the detail block */ +.vibenet-app .button-row { + display: flex; + flex-wrap: wrap; + gap: 8px; + margin: 8px 0 16px; +} +.vibenet-app .btn { + background: var(--card); + border: 1px solid var(--border); + color: var(--fg); + padding: 6px 12px; + border-radius: 4px; + font-size: 13px; + text-decoration: none; + transition: border-color 0.1s ease; + cursor: pointer; + display: inline-block; +} +.vibenet-app .btn:hover { + border-color: var(--accent); + color: var(--fg); + text-decoration: none; +} + +/* Expandable input field on the tx page */ +.vibenet-app .input-details summary { + cursor: pointer; + list-style: revert; + color: var(--fg); +} +.vibenet-app .input-details summary code { + color: var(--fg-dim); +} +.vibenet-app .input-details[open] summary { + margin-bottom: 8px; +} + +.vibenet-app pre.raw { + background: var(--bg-elev); + border: 1px solid var(--border); + border-radius: 6px; + padding: 12px 14px; + margin: 8px 0; + font-family: var(--mono); + font-size: 12px; + line-height: 1.55; + overflow-x: auto; + white-space: pre-wrap; + word-break: break-all; + max-height: 70vh; +} + +/* Logs section on tx page */ +.vibenet-app .log { + background: var(--card); + border: 1px solid var(--border); + border-radius: 6px; + padding: 10px 14px; + margin: 8px 0; +} +.vibenet-app .log-header { + display: flex; + gap: 12px; + align-items: center; + flex-wrap: wrap; +} +.vibenet-app .log-index { + color: var(--fg-dim); + font-family: var(--mono); +} +.vibenet-app .log .topics { + list-style: none; + padding: 0; + margin: 8px 0; +} +.vibenet-app .log .topics li { + font-family: var(--mono); + font-size: 12px; + color: var(--fg-dim); + margin: 2px 0; + overflow-wrap: anywhere; +} +.vibenet-app .log .data { + font-size: 12px; + color: var(--fg-dim); + overflow-wrap: anywhere; +} +.vibenet-app .event-badge { + display: inline-flex; + align-items: center; + border: 1px solid rgba(0, 82, 255, 0.45); + background: rgba(0, 82, 255, 0.14); + color: var(--fg); + border-radius: 999px; + padding: 2px 8px; + font-size: 11px; + font-weight: 600; + letter-spacing: 0.02em; +} + +.vibenet-app .empty { + padding: 24px; + text-align: center; + color: var(--fg-dim); + font-style: italic; + background: var(--card); + border: 1px solid var(--border); + border-radius: 6px; +} + +/* ---------- footer ------------------------------------------------------- */ + +.vibenet-app .site-footer { + max-width: 960px; + margin: 2rem auto 0; + padding: 1.5rem 28px 2rem; + border-top: 1px solid var(--border); + color: var(--fg-dim); + font-size: 13px; + display: flex; + gap: 1.5rem; + align-items: center; + flex-wrap: wrap; +} +.vibenet-app .site-footer code { + font-family: var(--mono); + font-size: 12px; + background: var(--bg-elev); + padding: 0.05em 0.35em; + border-radius: 3px; + border: 1px solid var(--border); +} +.vibenet-app .footer-spacer { + flex: 1; +} + +/* ---------- responsive --------------------------------------------------- */ + +@media (max-width: 640px) { + .vibenet-app main { + padding: 1.5rem 18px 2rem; + } + .vibenet-app .site-header { + padding: 14px 18px; + } + .vibenet-app .site-nav { + gap: 0.75rem; + } + .vibenet-app .chain-row { + grid-template-columns: 80px 1fr; + gap: 0.5rem; + font-size: 13px; + } + .vibenet-app .contract-row { + grid-template-columns: 1fr; + gap: 0.25rem; + } + .vibenet-app .page-title { + font-size: 1.6rem; + } +}