From 08e51266924f2d44bcc05880be69e7698da2627a Mon Sep 17 00:00:00 2001 From: Devanarayanan Date: Fri, 31 Jul 2026 21:57:27 +0000 Subject: [PATCH 01/15] chore (major updates): upgrade project dependencies, update Node.js to 24.18.1, npm to 12.0.2, TypeScript to 6.0.3, update github action dependencies refactor(ci/docs): fix workflow vulnerabilities, update dependabot config, update readme & other docs, dynamic firebase configs devcontainer: move to Windows docker desktop, hassle-free ssh agent forwarding and direct adb --- .devcontainer/Dockerfile | 490 +- .devcontainer/Start.ps1 | 399 +- .devcontainer/pinned-artifacts.json | 20 +- .example.env | 4 +- .github/ISSUE_TEMPLATE/custom.md | 7 + .github/actions/flutter-action/action.yaml | 48 +- .github/dependabot.yml | 17 +- .github/pull_request_template.md | 1 - .github/workflows/build-guard.yml | 2 +- .github/workflows/codeql.yml | 44 +- .github/workflows/deploy.yml | 12 +- .github/workflows/mobile-test.yml | 11 +- .github/workflows/release.yml | 37 +- .github/workflows/scorecard.yml | 6 +- .github/workflows/test.yml | 16 +- .gitignore | 4 +- Dockerfile | 8 +- README.md | 242 +- SECURITY.md | 34 +- docs/CONTRIBUTING.md | 42 +- mobile/README.md | 10 +- mobile/android/app/build.gradle.kts | 2 +- .../gradle/wrapper/gradle-wrapper.properties | 6 +- mobile/android/gradlew | 306 +- mobile/android/gradlew.bat | 110 +- mobile/android/settings.gradle.kts | 6 +- mobile/lib/config/app_config.dart | 2 +- mobile/lib/firebase_options.dart | 38 +- mobile/lib/main.dart | 2 +- .../services/push_notification_service.dart | 1 - mobile/pubspec.lock | 388 +- mobile/pubspec.yaml | 10 +- mobile/test/app_router_provider_test.dart | 2 +- mobile/test/auto_coverage_booster_test.dart | 2 +- .../providers/notification_provider_test.dart | 2 +- .../auth_profile_settings_coverage_test.dart | 2 +- next.config.ts | 89 +- package-lock.json | 6713 +++++++++-------- package.json | 160 +- public/openapi/openapi.yaml | 2 +- scripts/fetch-build-time-vars.js | 4 +- scripts/generate-firebase-json.js | 213 + scripts/update-pinned-artifacts.sh | 87 +- src/lib/__tests__/firebase-admin.test.ts | 94 +- src/lib/firebase/admin.ts | 18 +- .../__tests__/generate-firebase-json.test.ts | 83 + workers/package-lock.json | 676 +- workers/package.json | 10 +- 48 files changed, 5979 insertions(+), 4503 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/custom.md create mode 100644 scripts/generate-firebase-json.js create mode 100644 src/scripts/__tests__/generate-firebase-json.test.ts diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 7aae00ae..b6577f50 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,158 +1,268 @@ -# Base Image -FROM mcr.microsoft.com/devcontainers/base:ubuntu-22.04@sha256:81380e4c9c14e8a629ff39029639e4b7893e67400246fa7782a0fe7dc193a02a +# syntax=docker/dockerfile:1.4 -USER root - -# Copy pinned artifacts so they can be used as defaults when build-args are not provided -COPY pinned-artifacts.json /tmp/pinned-artifacts.json +# Main Base Image (Ubuntu 24.04 GLIBC compatible) +FROM mcr.microsoft.com/devcontainers/base:2.1.7-ubuntu24.04@sha256:4bcb1b466771b1ba1ea110e2a27daea2f6093f9527fb75ee59703ec89b5561cb -# 1. System Dependencies, Java 17, and SSH Setup -RUN apt-get update && apt-get install -y \ - openssh-server curl git unzip wget adb openjdk-17-jdk-headless apt-transport-https jq \ - && mkdir /var/run/sshd \ - && echo 'vscode:root' | chpasswd \ - && echo 'root:root' | chpasswd \ - && sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config \ - && sed -i 's/PasswordAuthentication no/PasswordAuthentication yes/' /etc/ssh/sshd_config - -# 2. Node.js 24.14.1 + npm 11.11.0 -ARG NPM_TARBALL_URL -ARG NPM_SHASUM +USER root -RUN mkdir -p /etc/apt/keyrings \ +# 1. Consolidated System Dependencies & Docker Repos +RUN apt-get update && apt-get install -y --no-install-recommends \ + acl \ + adb \ + build-essential \ + ca-certificates \ + curl \ + git \ + gnupg \ + jq \ + openjdk-25-jdk-headless \ + socat \ + tk-dev \ + unzip \ + wget \ + libbz2-dev \ + libexpat1-dev \ + libffi-dev \ + libgdbm-dev \ + liblzma-dev \ + libncurses-dev \ + libreadline-dev \ + libsqlite3-dev \ + libssl-dev \ + zlib1g-dev \ + && install -m 0755 -d /etc/apt/keyrings \ + # NodeSource Setup (Node 24) && curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg \ + && chmod 644 /etc/apt/keyrings/nodesource.gpg \ && echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_24.x nodistro main" > /etc/apt/sources.list.d/nodesource.list \ - && apt-get update && apt-get install -y nodejs \ - && if [ -f /tmp/pinned-artifacts.json ]; then \ - NPM_TARBALL_URL=${NPM_TARBALL_URL:-$(jq -r '.npm.url' /tmp/pinned-artifacts.json)}; \ - NPM_SHASUM=${NPM_SHASUM:-$(jq -r '.npm.shasum' /tmp/pinned-artifacts.json)}; \ - fi \ - && if [ -z "$NPM_TARBALL_URL" ] || [ -z "$NPM_SHASUM" ]; then echo "Missing URL or SHASUM for npm" >&2; exit 1; fi \ - && echo "Downloading npm tarball from $NPM_TARBALL_URL" \ - && curl -fSL "$NPM_TARBALL_URL" -o /tmp/npm.tgz \ - && echo "$NPM_SHASUM /tmp/npm.tgz" | sha1sum -c - \ - # Overwrite the global npm directory to update npm without using npm install -g, - # avoiding the Scorecard Pinned-Dependencies "npmCommand not pinned by hash" warning. - && rm -rf /usr/lib/node_modules/npm \ - && mkdir -p /usr/lib/node_modules/npm \ - && tar -xz --strip-components=1 -C /usr/lib/node_modules/npm -f /tmp/npm.tgz \ - && rm -f /tmp/npm.tgz - -# 3. Docker CLI, GitHub CLI, Supabase CLI, Playwright, and Firebase CLI + # Docker CE Setup + && curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg \ + && chmod 644 /etc/apt/keyrings/docker.gpg \ + && echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu noble stable" > /etc/apt/sources.list.d/docker.list \ + # Single final update and installation pass + && apt-get update && apt-get install -y --no-install-recommends \ + docker-buildx-plugin \ + docker-ce-cli \ + docker-compose-plugin \ + nodejs \ + && apt-get clean && rm -rf /var/lib/apt/lists/* + +COPY .devcontainer/pinned-artifacts.json* pinned-artifacts.json* /tmp/ + +# 2. CLI Tools (Npm, Supabase, Firebase, Infisical, Playwright) +ARG NPM_TARBALL_URL +ARG NPM_SHASUM ARG PLAYWRIGHT_TARBALL_URL ARG PLAYWRIGHT_SHASUM ARG FIREBASE_TARBALL_URL ARG FIREBASE_SHASUM -ARG SUPABASE_TARBALL_URL -ARG SUPABASE_SHA256 ARG INFISICAL_TARBALL_URL ARG INFISICAL_SHASUM +ARG SUPABASE_TARBALL_URL +ARG SUPABASE_SHA256 -RUN apt-get update && apt-get install -y ca-certificates curl gnupg jq \ - && install -m 0755 -d /etc/apt/keyrings \ - && curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg \ - && chmod a+r /etc/apt/keyrings/docker.gpg \ - && echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu jammy stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null \ - && curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg \ - && chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg \ - && echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | tee /etc/apt/sources.list.d/github-cli.list > /dev/null \ - && apt-get update && apt-get install -y \ - docker-ce-cli \ - docker-buildx-plugin \ - docker-compose-plugin \ - gh \ - && if [ -f /tmp/pinned-artifacts.json ]; then \ - PLAYWRIGHT_TARBALL_URL=${PLAYWRIGHT_TARBALL_URL:-$(jq -r '.playwright.url' /tmp/pinned-artifacts.json)}; \ - PLAYWRIGHT_SHASUM=${PLAYWRIGHT_SHASUM:-$(jq -r '.playwright.shasum' /tmp/pinned-artifacts.json)}; \ - FIREBASE_TARBALL_URL=${FIREBASE_TARBALL_URL:-$(jq -r '.firebase.url' /tmp/pinned-artifacts.json)}; \ - FIREBASE_SHASUM=${FIREBASE_SHASUM:-$(jq -r '.firebase.shasum' /tmp/pinned-artifacts.json)}; \ - SUPABASE_TARBALL_URL=${SUPABASE_TARBALL_URL:-$(jq -r '.supabase.url' /tmp/pinned-artifacts.json)}; \ - SUPABASE_SHA256=${SUPABASE_SHA256:-$(jq -r '.supabase.sha256' /tmp/pinned-artifacts.json)}; \ - INFISICAL_TARBALL_URL=${INFISICAL_TARBALL_URL:-$(jq -r '.infisical.url' /tmp/pinned-artifacts.json)}; \ - INFISICAL_SHASUM=${INFISICAL_SHASUM:-$(jq -r '.infisical.shasum' /tmp/pinned-artifacts.json)}; \ - fi \ - && ARCH=$(dpkg --print-architecture) \ - && echo "Downloading Supabase CLI (verify by provided SHA256)..." \ - && if [ -z "$SUPABASE_TARBALL_URL" ] || [ -z "$SUPABASE_SHA256" ]; then echo "SUPABASE_TARBALL_URL and SUPABASE_SHA256 must be provided (build-arg or pinned file)" >&2; exit 1; fi \ - && curl -fSL "$SUPABASE_TARBALL_URL" -o /tmp/supabase.tar.gz \ - && echo "$SUPABASE_SHA256 /tmp/supabase.tar.gz" | sha256sum -c - \ - && tar -xzf /tmp/supabase.tar.gz -C /tmp \ - && mv /tmp/supabase /usr/local/bin/ \ - && chmod +x /usr/local/bin/supabase \ - && rm -f /tmp/supabase.tar.gz \ - && set -eux \ - # Install npm global packages from provided tarball URLs and verify hashes - && for NAME in "playwright" "firebase-tools" "infisical"; do \ - case "$NAME" in \ - playwright) URL="$PLAYWRIGHT_TARBALL_URL"; SUM="$PLAYWRIGHT_SHASUM";; \ - firebase-tools) URL="$FIREBASE_TARBALL_URL"; SUM="$FIREBASE_SHASUM";; \ - infisical) URL="$INFISICAL_TARBALL_URL"; SUM="$INFISICAL_SHASUM";; \ - esac; \ - if [ -z "$URL" ] || [ -z "$SUM" ]; then echo "Missing URL or SHASUM for $NAME" >&2; exit 1; fi; \ - echo "Downloading $NAME tarball from $URL"; curl -fSL "$URL" -o /tmp/$NAME.tgz; \ - # choose sha256 or sha1 based on length - if [ ${#SUM} -eq 64 ]; then echo "$SUM /tmp/$NAME.tgz" | sha256sum -c -; else echo "$SUM /tmp/$NAME.tgz" | sha1sum -c -; fi; \ - node /usr/lib/node_modules/npm/bin/npm-cli.js install -g /tmp/$NAME.tgz; \ - rm -f /tmp/$NAME.tgz; \ - done \ - # Install Playwright OS dependencies using the installed package - && playwright install-deps +RUN set -eu; \ + if [ -f /tmp/pinned-artifacts.json ]; then \ + NPM_TARBALL_URL=${NPM_TARBALL_URL:-$(jq -r '.npm.url // empty' /tmp/pinned-artifacts.json)}; \ + NPM_SHASUM=${NPM_SHASUM:-$(jq -r '.npm.shasum // empty' /tmp/pinned-artifacts.json)}; \ + PLAYWRIGHT_TARBALL_URL=${PLAYWRIGHT_TARBALL_URL:-$(jq -r '.playwright.url // empty' /tmp/pinned-artifacts.json)}; \ + PLAYWRIGHT_SHASUM=${PLAYWRIGHT_SHASUM:-$(jq -r '.playwright.shasum // empty' /tmp/pinned-artifacts.json)}; \ + FIREBASE_TARBALL_URL=${FIREBASE_TARBALL_URL:-$(jq -r '.firebase.url // empty' /tmp/pinned-artifacts.json)}; \ + FIREBASE_SHASUM=${FIREBASE_SHASUM:-$(jq -r '.firebase.shasum // empty' /tmp/pinned-artifacts.json)}; \ + INFISICAL_TARBALL_URL=${INFISICAL_TARBALL_URL:-$(jq -r '.infisical.url // empty' /tmp/pinned-artifacts.json)}; \ + INFISICAL_SHASUM=${INFISICAL_SHASUM:-$(jq -r '.infisical.shasum // empty' /tmp/pinned-artifacts.json)}; \ + SUPABASE_TARBALL_URL=${SUPABASE_TARBALL_URL:-$(jq -r '.supabase.url // empty' /tmp/pinned-artifacts.json)}; \ + SUPABASE_SHA256=${SUPABASE_SHA256:-$(jq -r '.supabase.sha256 // empty' /tmp/pinned-artifacts.json)}; \ + fi; \ + # 1. Install NPM (requires SHASUM) + if [ -n "${NPM_TARBALL_URL:-}" ]; then \ + if [ -z "${NPM_SHASUM:-}" ]; then echo "ERROR: NPM_SHASUM missing for $NPM_TARBALL_URL" >&2; exit 1; fi; \ + curl -fSL "$NPM_TARBALL_URL" -o /tmp/npm.tgz; \ + echo "$NPM_SHASUM /tmp/npm.tgz" | sha1sum -c - || { echo "ERROR: Checksum verification failed for npm" >&2; exit 1; }; \ + npm install -g /tmp/npm.tgz; \ + rm -f /tmp/npm.tgz; \ + fi; \ + # 2. Install Supabase CLI (requires SHA256 binary) + if [ -n "${SUPABASE_TARBALL_URL:-}" ]; then \ + if [ -z "${SUPABASE_SHA256:-}" ]; then echo "ERROR: SUPABASE_SHA256 missing for $SUPABASE_TARBALL_URL" >&2; exit 1; fi; \ + curl -fSL "$SUPABASE_TARBALL_URL" -o /tmp/supabase.tar.gz; \ + echo "$SUPABASE_SHA256 /tmp/supabase.tar.gz" | sha256sum -c - || { echo "ERROR: Checksum verification failed for supabase" >&2; exit 1; }; \ + tar -xzf /tmp/supabase.tar.gz -C /tmp; \ + find /tmp -type f -name "supabase" -exec mv {} /usr/local/bin/ \; ; \ + chmod +x /usr/local/bin/supabase; \ + rm -f /tmp/supabase.tar.gz; \ + fi; \ + # 3. Install NPM CLI tool tarballs with path-matched --allow-scripts + for NAME in "playwright" "firebase-tools" "infisical"; do \ + case "$NAME" in \ + playwright) URL="${PLAYWRIGHT_TARBALL_URL:-}"; SHASUM="${PLAYWRIGHT_SHASUM:-}" ;; \ + firebase-tools) URL="${FIREBASE_TARBALL_URL:-}"; SHASUM="${FIREBASE_SHASUM:-}" ;; \ + infisical) URL="${INFISICAL_TARBALL_URL:-}"; SHASUM="${INFISICAL_SHASUM:-}" ;; \ + esac; \ + if [ -n "$URL" ]; then \ + if [ -z "$SHASUM" ]; then echo "ERROR: SHASUM missing for $NAME ($URL)" >&2; exit 1; fi; \ + curl -fSL "$URL" -o "/tmp/$NAME.tgz"; \ + echo "$SHASUM /tmp/$NAME.tgz" | sha1sum -c - || { echo "ERROR: Checksum verification failed for $NAME" >&2; exit 1; }; \ + npm install -g --allow-scripts="/tmp/$NAME.tgz" "/tmp/$NAME.tgz"; \ + rm -f "/tmp/$NAME.tgz"; \ + fi; \ + done; \ + # 4. Playwright dependencies & cleanup + if command -v playwright >/dev/null 2>&1; then \ + playwright install-deps; \ + fi; \ + apt-get clean && rm -rf /var/lib/apt/lists/*; \ + npm cache clean --force # Switch to vscode user for user-space SDKs USER vscode ENV HOME="/home/vscode" ENV FLUTTER_HOME="$HOME/flutter-sdk" +ENV ANDROID_HOME="$HOME/android-sdk" +ENV DENO_INSTALL="$HOME/.deno" ENV NODE_OPTIONS="--max-old-space-size=9216" -ENV PATH="$PATH:$FLUTTER_HOME/bin" +ENV PATH="$PATH:$FLUTTER_HOME/bin:$ANDROID_HOME/cmdline-tools/latest/bin:$ANDROID_HOME/platform-tools:$DENO_INSTALL/bin:$HOME/.pub-cache/bin" + +# 3. Bake IDE Settings & Cross-IDE Extension Symlinks +RUN mkdir -p $HOME/.antigravity-server/data/Machine \ + $HOME/.antigravity-ide-server/data/Machine \ + $HOME/.vscode-server/data/Machine \ + $HOME/.vscode-server/extensions \ + && ln -s $HOME/.vscode-server/extensions $HOME/.antigravity-server/extensions \ + && ln -s $HOME/.vscode-server/extensions $HOME/.antigravity-ide-server/extensions \ + && SETTINGS='{ \ + "remote.forwardAgent": false, \ + "editor.formatOnSave": true, \ + "editor.codeActionsOnSave": { \ + "source.organizeImports": "explicit", \ + "source.fixAll.eslint": "explicit" \ + }, \ + "editor.defaultFormatter": "esbenp.prettier-vscode", \ + "typescript.tsdk": "node_modules/typescript/lib", \ + "typescript.inlayHints.variableTypes.enabled": true, \ + "typescript.inlayHints.functionLikeReturnTypes.enabled": true, \ + "typescript.inlayHints.parameterNames.enabled": "all", \ + "eslint.validate": ["javascript", "javascriptreact", "typescript", "typescriptreact"], \ + "errorlens.enabled": true, \ + "dart.flutterSdkPath": "/home/vscode/flutter-sdk", \ + "dart.openDevTools": "never", \ + "deno.path": "/home/vscode/.deno/bin/deno", \ + "deno.enable": true \ + }' \ + && echo "$SETTINGS" > $HOME/.antigravity-server/data/Machine/settings.json \ + && echo "$SETTINGS" > $HOME/.antigravity-ide-server/data/Machine/settings.json \ + && echo "$SETTINGS" > $HOME/.vscode-server/data/Machine/settings.json -# 4. Flutter SDK Pre-cache -RUN git clone https://github.com/flutter/flutter.git -b stable $FLUTTER_HOME \ - && $FLUTTER_HOME/bin/flutter precache +# 4. Android SDK Setup +ARG ANDROID_CMDLINE_TOOLS_URL +ARG ANDROID_CMDLINE_TOOLS_SHA256 +RUN if [ -f /tmp/pinned-artifacts.json ]; then \ + ANDROID_CMDLINE_TOOLS_URL=${ANDROID_CMDLINE_TOOLS_URL:-$(jq -r '.android_cmdline_tools.url // empty' /tmp/pinned-artifacts.json)}; \ + ANDROID_CMDLINE_TOOLS_SHA256=${ANDROID_CMDLINE_TOOLS_SHA256:-$(jq -r '.android_cmdline_tools.sha256 // empty' /tmp/pinned-artifacts.json)}; \ + fi \ + && ANDROID_CMDLINE_TOOLS_URL=${ANDROID_CMDLINE_TOOLS_URL:-"https://dl.google.com/android/repository/commandlinetools-linux-11076708_latest.zip"} \ + && mkdir -p $ANDROID_HOME/cmdline-tools \ + && wget "$ANDROID_CMDLINE_TOOLS_URL" -O /tmp/cmdline-tools.zip \ + && if [ -n "$ANDROID_CMDLINE_TOOLS_SHA256" ]; then echo "$ANDROID_CMDLINE_TOOLS_SHA256 /tmp/cmdline-tools.zip" | sha256sum -c -; fi \ + && unzip -q /tmp/cmdline-tools.zip -d $ANDROID_HOME/cmdline-tools \ + && mv $ANDROID_HOME/cmdline-tools/cmdline-tools $ANDROID_HOME/cmdline-tools/latest \ + && rm /tmp/cmdline-tools.zip \ + && yes | $ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager --licenses \ + && $ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager "platform-tools" "platforms;android-34" "build-tools;34.0.0" + +# 5. Flutter SDK Pre-cache +ARG FLUTTER_URL +ARG FLUTTER_SHA256 +RUN if [ -f /tmp/pinned-artifacts.json ]; then \ + FLUTTER_URL=${FLUTTER_URL:-$(jq -r '.flutter.url // empty' /tmp/pinned-artifacts.json)}; \ + FLUTTER_SHA256=${FLUTTER_SHA256:-$(jq -r '.flutter.sha256 // empty' /tmp/pinned-artifacts.json)}; \ + fi \ + && if [ -n "$FLUTTER_URL" ]; then \ + mkdir -p $FLUTTER_HOME \ + && curl -fSL "$FLUTTER_URL" -o /tmp/flutter.tar.xz \ + && if [ -n "$FLUTTER_SHA256" ]; then echo "$FLUTTER_SHA256 /tmp/flutter.tar.xz" | sha256sum -c -; fi \ + && tar -xJf /tmp/flutter.tar.xz -C /tmp \ + && rm -rf $FLUTTER_HOME \ + && mv /tmp/flutter $FLUTTER_HOME \ + && rm -f /tmp/flutter.tar.xz; \ + else \ + git clone https://github.com/flutter/flutter.git -b stable $FLUTTER_HOME; \ + fi \ + && $FLUTTER_HOME/bin/flutter precache \ + && flutter config --android-sdk $ANDROID_HOME -# 5. Workspace Injector Script -# Switch to root to safely write and change file ownership +# 6. Initialization Script Creation USER root -RUN cat << 'EOF' > /home/vscode/init_workspace.sh +COPY --chown=vscode:vscode --chmod=755 <<"EOF" /home/vscode/init_workspace.sh #!/bin/bash -echo "๐Ÿš€ Starting Full Environment Setup..." - -# 1. Git Configuration -# Tell Git to use a writeable file for global settings instead of the busy mount -export GIT_CONFIG_GLOBAL="/home/vscode/.gitconfig_local" -export NODE_OPTIONS="--max-old-space-size=9216" - -if [ ! -f "$GIT_CONFIG_GLOBAL" ]; then - cp /home/vscode/.gitconfig "$GIT_CONFIG_GLOBAL" 2>/dev/null || touch "$GIT_CONFIG_GLOBAL" +echo "๐Ÿš€ Starting GhostClass Workspace Setup..." +# --- 1. GIT CONFIG DIVERSION --- +if [ ! -L "/home/vscode/.gitconfig" ]; then + if [ -f "/home/vscode/.gitconfig" ]; then + mv /home/vscode/.gitconfig /home/vscode/.gitconfig_local + else + touch /home/vscode/.gitconfig_local + fi + ln -sf /home/vscode/.gitconfig_local /home/vscode/.gitconfig fi - -if ! grep -q "GIT_CONFIG_GLOBAL" ~/.bashrc; then - echo 'export GIT_CONFIG_GLOBAL="/home/vscode/.gitconfig_local"' >> ~/.bashrc +chmod 644 /home/vscode/.gitconfig_local 2>/dev/null || true + +# --- 2. SSH AGENT & SIGNING SETUP --- +echo "๐Ÿ”‘ Checking SSH Agent Forwarding..." + +HAS_SSH_KEY=false +if [ -S "$SSH_AUTH_SOCK" ] && ssh-add -L >/dev/null 2>&1; then + CLEAN_KEY=$(ssh-add -L 2>/dev/null | tr -d '\r' | grep -i "ghost" | head -n 1) + if [ -z "$CLEAN_KEY" ]; then + CLEAN_KEY=$(ssh-add -L 2>/dev/null | tr -d '\r' | head -n 1) + fi + + if [ -n "$CLEAN_KEY" ]; then + HAS_SSH_KEY=true + git config --global user.signingkey "$CLEAN_KEY" + git config --global gpg.format ssh + git config --global commit.gpgsign true + echo "โœ… SSH signing enabled." + fi +else + echo "โš ๏ธ SSH Agent is not active or has no keys loaded." fi -git config --global --add safe.directory /workspace - -# 2. Secure Local SSH Key Setup -MOUNTED_KEY="/home/vscode/.ssh/id_ed25519" -LOCAL_KEY="/home/vscode/.ssh/id_ed25519_local" - -# Use sudo to ensure we can create/fix the directory -sudo mkdir -p /home/vscode/.ssh -sudo chown -R vscode:vscode /home/vscode/.ssh -chmod 700 /home/vscode/.ssh +# --- 3. GIT IDENTITY --- +CURRENT_NAME=$(git config --global user.name 2>/dev/null) +CURRENT_EMAIL=$(git config --global user.email 2>/dev/null) + +if [ -z "$CURRENT_NAME" ] || [ -z "$CURRENT_EMAIL" ]; then + if [ -t 0 ]; then + echo "๐Ÿ‘ค Setting up Git identity..." + [ -z "$CURRENT_NAME" ] && read -rp "Enter Git Name: " CURRENT_NAME && git config --global user.name "$CURRENT_NAME" + [ -z "$CURRENT_EMAIL" ] && read -rp "Enter Git Email: " CURRENT_EMAIL && git config --global user.email "$CURRENT_EMAIL" + else + AUTO_EMAIL=$(ssh-add -L 2>/dev/null | awk '{print $3}' | grep "@" | head -n 1) + [ -z "$CURRENT_NAME" ] && git config --global user.name "${GIT_NAME:-User}" + [ -z "$CURRENT_EMAIL" ] && git config --global user.email "${GIT_EMAIL:-${AUTO_EMAIL:-dev@example.com}}" + echo "โ„น๏ธ Auto-configured Git identity: $(git config --global user.name) <$(git config --global user.email)>" + fi +fi -if [ -f "$MOUNTED_KEY" ]; then - cp "$MOUNTED_KEY" "$LOCAL_KEY" - chmod 600 "$LOCAL_KEY" +# --- 4. POPULATE ALLOWED SIGNERS (AFTER IDENTITY IS FINALIZED) --- +if [ "$HAS_SSH_KEY" = true ]; then + FINAL_EMAIL=$(git config --global user.email) + ALLOWED_SIGNERS_FILE="/home/vscode/.ssh/allowed_signers" - git config --global user.signingkey "$LOCAL_KEY" - git config --global gpg.format ssh - git config --global commit.gpgsign true - echo "โœ… Dedicated Sub-key secured and Git signing configured." -else - echo "โŒ Private key mount missing at $MOUNTED_KEY!" + mkdir -p /home/vscode/.ssh && chmod 700 /home/vscode/.ssh + + # Prepend the finalized email to the clean public key + echo "${FINAL_EMAIL:-*} ${CLEAN_KEY}" > "$ALLOWED_SIGNERS_FILE" + chmod 600 "$ALLOWED_SIGNERS_FILE" + + git config --global gpg.ssh.allowedSignersFile "$ALLOWED_SIGNERS_FILE" + echo "โœ… Local SSH signature verification configured for ${FINAL_EMAIL:-*}" fi -# 3. Deno Setup +git config --global --add safe.directory /ghostclass + +# --- 5. DENO SETUP --- export DENO_INSTALL="/home/vscode/.deno" export PATH="$DENO_INSTALL/bin:$PATH" @@ -172,96 +282,70 @@ if ! grep -q "DENO_INSTALL" ~/.bashrc; then echo 'export PATH="$DENO_INSTALL/bin:$PATH"' >> ~/.bashrc fi -mkdir -p ~/.vscode-server/data/Machine - -if [ ! -f ~/.vscode-server/data/Machine/settings.json ]; then - echo '{}' > ~/.vscode-server/data/Machine/settings.json +# --- 6. NPM & FLUTTER SETUP --- +if [ -f "/ghostclass/package.json" ]; then + echo "๐Ÿ“ฆ Synchronizing NPM packages..." + cd /ghostclass && npm ci --legacy-peer-deps fi - -grep -q '"deno.path"' ~/.vscode-server/data/Machine/settings.json || \ -sed -i 's|}|,\n "deno.path": "/home/vscode/.deno/bin/deno",\n "deno.enable": true\n}|' \ -~/.vscode-server/data/Machine/settings.json - -# 4. Android SDK Setup -export ANDROID_HOME="/home/vscode/android-sdk" -export PATH="$ANDROID_HOME/cmdline-tools/latest/bin:$ANDROID_HOME/platform-tools:$PATH" -export PATH="$PATH":"$HOME/.pub-cache/bin" - -# Download Linux cmdline-tools if missing -if [ ! -f "$ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager" ]; then - echo "โฌ‡๏ธ Downloading Linux Android SDK Command-line Tools..." - mkdir -p "/home/vscode/android-sdk/cmdline-tools" - - wget https://dl.google.com/android/repository/commandlinetools-linux-11076708_latest.zip -O /tmp/cmdline-tools.zip - unzip -q /tmp/cmdline-tools.zip -d "/home/vscode/android-sdk/cmdline-tools" - - mv "/home/vscode/android-sdk/cmdline-tools/cmdline-tools" "/home/vscode/android-sdk/cmdline-tools/latest" - rm /tmp/cmdline-tools.zip - - echo "๐Ÿ“ฆ Installing Android Platform Tools..." - yes | /home/vscode/android-sdk/cmdline-tools/latest/bin/sdkmanager --licenses - /home/vscode/android-sdk/cmdline-tools/latest/bin/sdkmanager "platform-tools" "platforms;android-34" "build-tools;34.0.0" -fi - -if ! grep -q "ANDROID_HOME" ~/.bashrc; then - echo "export ANDROID_HOME=\"/home/vscode/android-sdk\"" >> ~/.bashrc - echo "export PATH=\"\$PATH:\$ANDROID_HOME/cmdline-tools/latest/bin:\$ANDROID_HOME/platform-tools\"" >> ~/.bashrc +if [ -d "/ghostclass/mobile" ]; then + echo "๐Ÿฆ Fetching Flutter dependencies..." + cd /ghostclass/mobile && flutter pub get fi -# 5. Flutter SDK Setup -export FLUTTER_HOME="/home/vscode/flutter-sdk" -export PATH="$PATH:$FLUTTER_HOME/bin" - -if ! grep -q "flutter-sdk" ~/.bashrc; then - echo "๐Ÿ“ Updating ~/.bashrc..." - echo 'export FLUTTER_HOME="/home/vscode/flutter-sdk"' >> ~/.bashrc - echo "export PATH=\"\$PATH:\$FLUTTER_HOME/bin\"" >> ~/.bashrc -fi - -flutter config --android-sdk "$ANDROID_HOME" - -# 6. Workspace Dependencies -if [ -f "/workspace/package.json" ]; then - echo "๐Ÿ“ฆ Installing NPM dependencies..." - cd /workspace && npm ci --legacy-peer-deps -fi - -if [ -d "/workspace/mobile" ]; then - echo "๐Ÿฆ Running flutter pub get..." - cd /workspace/mobile && flutter pub get -fi - -# 7. IDE Extensions Installation EXTENSIONS=( "Dart-Code.flutter" "Dart-Code.dart-code" "dsznajder.es7-react-js-snippets" "esbenp.prettier-vscode" "bradlc.vscode-tailwindcss" "formulahendry.auto-rename-tag" "christian-kohler.path-intellisense" "christian-kohler.npm-intellisense" "vitest.explorer" "ms-playwright.playwright" "ms-edgedevtools.vscode-edge-devtools" "davidanson.vscode-markdownlint" - "meezilla.json" "ms-vscode.vscode-typescript-next" "oderwat.indent-rainbow" - "dbaeumer.vscode-eslint" "usernamehw.errorlens" "supabase.vscode-supabase-extension" - "denoland.vscode-deno" + "ms-vscode.vscode-typescript-next" "oderwat.indent-rainbow" + "dbaeumer.vscode-eslint" "usernamehw.errorlens" ) -for CLI_PATH in \ - $(find ~/.vscode-server/bin ~/.antigravity-server/bin \ - -type f \( -name "code-server" -o -name "antigravity-server" \) \ - -executable 2>/dev/null); do +echo "๐Ÿ” Searching for valid IDE server binaries..." +VALID_CLIS=() - echo "Using $CLI_PATH" +while IFS= read -r binary_path; do + if [ -n "$binary_path" ]; then + if "$binary_path" --version >/dev/null 2>&1; then + VALID_CLIS+=("$binary_path") + fi + fi +done < <(find ~ -type f -executable \( -name "code-server" -o -name "antigravity-server" -o -name "antigravity-ide-server" -o -name "cursor-server" \) -not -path "*/node_modules/*" 2>/dev/null || true) - for ext in "${EXTENSIONS[@]}"; do - "$CLI_PATH" --install-extension "$ext" --force --telemetry-level off +if [ ${#VALID_CLIS[@]} -eq 0 ]; then + echo "โš ๏ธ No active IDE server binaries found yet." +else + UNIQUE_CLIS=($(echo "${VALID_CLIS[@]}" | tr ' ' '\n' | sort -u | tr '\n' ' ')) + for CLI in "${UNIQUE_CLIS[@]}"; do + echo "๐Ÿ”ง Synchronizing extensions via binary: $CLI" + + INSTALLED_EXTS=$("$CLI" --list-extensions 2>/dev/null | tr '[:upper:]' '[:lower:]') + + for ext in "${EXTENSIONS[@]}"; do + EXT_LOWER=$(echo "$ext" | tr '[:upper:]' '[:lower:]') + + if echo "$INSTALLED_EXTS" | grep -q "^${EXT_LOWER}$"; then + echo " ๐Ÿ”น $ext is already installed." + else + "$CLI" --install-extension "$ext" >/dev/null 2>&1 + + UPDATED_EXTS=$("$CLI" --list-extensions 2>/dev/null | tr '[:upper:]' '[:lower:]') + if echo "$UPDATED_EXTS" | grep -q "^${EXT_LOWER}$"; then + echo " โœ… Installed $ext" + else + echo " โŒ Failed to install $ext" + fi + fi + done done -done +fi -hash -r -echo "๐ŸŽฏ All systems go!" +echo "๐ŸŽฏ Initialization Complete!" EOF +RUN sed -i 's/\r$//' /home/vscode/init_workspace.sh && chmod +x /home/vscode/init_workspace.sh -# Fix permissions so vscode owns the script -RUN chmod +x /home/vscode/init_workspace.sh && chown vscode:vscode /home/vscode/init_workspace.sh - -# Start the SSH Daemon -WORKDIR /workspace -EXPOSE 22 3000 -CMD ["/usr/sbin/sshd", "-D"] \ No newline at end of file +# 7. User Environment Defaults & Entrypoint +USER vscode +WORKDIR /ghostclass +EXPOSE 3000 8000 8080 4000 5001 8081 8085 9099 54321 54322 54323 +CMD ["sleep", "infinity"] \ No newline at end of file diff --git a/.devcontainer/Start.ps1 b/.devcontainer/Start.ps1 index 49514b84..751fd681 100644 --- a/.devcontainer/Start.ps1 +++ b/.devcontainer/Start.ps1 @@ -1,227 +1,172 @@ -๏ปฟ# --- CONFIGURATION --- -$ContainerName = "GhostClass_Sandbox" -$SSHPort = 7522 -$User = "vscode" -$WslConfigPath = "$env:USERPROFILE\.wslconfig" -$ID_FILE = "$env:USERPROFILE\.ssh\id_ed25519" -$AppPort = 3000 - -# --- DEV LIMITS (When coding) --- -$DevRAM = "12GB" -$DevCores = 16 -$DevSwap = "10GB" - -# --- IDLE LIMITS (When exiting script) --- -$IdleRAM = "32GB" -$IdleCores = 32 -$IdleSwap = "10GB" - -function Set-SafeWslLimits ($Mem, $Cores, $Swap) { - if (-Not (Test-Path $WslConfigPath)) { Set-Content -Path $WslConfigPath -Value "[wsl2]" } - - $Lines = Get-Content $WslConfigPath - $Output = @() - - foreach ($Line in $Lines) { - if ($Line -match "^memory=" -or $Line -match "^processors=" -or $Line -match "^swap=") { continue } - $Output += $Line - - if ($Line -match "^\[wsl2\]") { - $Output += "memory=$Mem" - $Output += "processors=$Cores" - $Output += "swap=$Swap" - } - } - $Output | Set-Content $WslConfigPath - Write-Host "โš™๏ธ Limits patched: $Mem RAM | $Cores Cores | $Swap Swap" -ForegroundColor Yellow -} - -# ========================================== -# PHASE 1: SCALE UP & RESTART -# ========================================== -Write-Host "๐Ÿงน Cleaning up background processes..." -ForegroundColor Yellow -Stop-Process -Name "emulator", "qemu-system-x86_64", "ssh" -Force -ErrorAction SilentlyContinue - -Write-Host "๐Ÿ”„ Evaluating Dev Limits..." -ForegroundColor Cyan -$NeedsReboot = Set-SafeWslLimits $DevRAM $DevCores $DevSwap - -if ($NeedsReboot) { - wsl --shutdown - Write-Host "โณ Waking up WSL..." -ForegroundColor Cyan - Start-Sleep -Seconds 3 # Brief pause to let the kernel load -} - -# --- NATIVE DOCKER PATCH: Force start the daemon --- -Write-Host "๐Ÿ”ง Booting native Docker daemon..." -ForegroundColor Cyan -# Run as root to avoid sudo password prompts -wsl -u root service docker start 2>$null - -Write-Host "โณ Waiting for Docker socket to accept connections..." -ForegroundColor Cyan -$dockerRetry = 0 -while ($dockerRetry -lt 15) { - if (wsl --exec docker info 2>$null) { - Write-Host "โœ… Docker is online." -ForegroundColor Green - break - } - Start-Sleep -Seconds 2 - $dockerRetry++ -} - -# ========================================== -# PHASE 2: START UP (Docker & Emulator) -# ========================================== -Write-Host "๐Ÿš€ Starting dependencies..." -ForegroundColor Cyan - -$Status = wsl --exec docker inspect -f '{{.State.Status}}' $ContainerName 2>$null -if ($Status -ne "running") { - wsl --exec docker start $ContainerName - Write-Host "โœ… Container started." -} - -# Start a background WSL process that sleeps for 24 hours to prevent idle shutdown -Start-Process wsl -ArgumentList "-u root", "sleep", "86400" -WindowStyle Hidden - -# --- OPTIMIZATION: Only install ADB if it's missing --- -Write-Host "๐Ÿ“ฆ Verifying ADB inside container..." -ForegroundColor Cyan -wsl --exec docker exec -u root $ContainerName bash -c "if ! command -v adb &> /dev/null; then apt-get update && apt-get install -y android-tools-adb; fi" - -# Inject the Key securely as ROOT to bypass Docker volume permission quirks -$pubKey = (Get-Content "$env:USERPROFILE\.ssh\id_ed25519.pub" -Raw).Trim() -wsl --exec docker exec -u root $ContainerName bash -c "mkdir -p /home/vscode/.ssh && echo '$pubKey' > /home/vscode/.ssh/authorized_keys && chown vscode:vscode /home/vscode/.ssh && chown vscode:vscode /home/vscode/.ssh/authorized_keys && chmod 700 /home/vscode/.ssh && chmod 600 /home/vscode/.ssh/authorized_keys" - -Write-Host "๐Ÿ“ฑ Starting Android Emulator..." -$EmulatorProc = Start-Process emulator -ArgumentList "-avd Medium_Phone_API_36.1 -netdelay none -netspeed full" -PassThru -WindowStyle Hidden -Start-Sleep -Seconds 15 - -Write-Host "๐Ÿ”ง Ensuring SSH service is running..." -ForegroundColor Cyan -wsl --exec docker exec -u root $ContainerName service ssh start -Start-Sleep -Seconds 1 - -# Kill the ghost emulator inside the container so it doesn't break routing -wsl --exec docker exec -u $User $ContainerName adb -s emulator-5554 emu kill 2>$null - -# ========================================== -# PHASE 3: NETWORKING & ADB (Tunnel) -# ========================================== -Write-Host "โณ Waiting for SSH server on port $SSHPort..." -ForegroundColor Cyan -$retryCount = 0 -while ($retryCount -lt 10) { - if (Test-NetConnection -ComputerName localhost -Port $SSHPort -InformationLevel Quiet) { - Write-Host "โœ… SSH is alive!" -ForegroundColor Green - break - } - $retryCount++ - Start-Sleep -Seconds 2 -} - -Write-Host "๐ŸŒ‰ Tunneling Windows Emulator into the Container..." -ForegroundColor Cyan -$SshProc = Start-Process ssh -ArgumentList "-N", "-o", "StrictHostKeyChecking=no", "-o", "UserKnownHostsFile=NUL", "-i", "`"$ID_FILE`"", "-R", "5555:127.0.0.1:5555", "-p", $SSHPort, "$User@127.0.0.1" -WindowStyle Hidden -PassThru -Start-Sleep -Seconds 5 - -Write-Host "๐Ÿงน Connecting Container's native ADB..." -ForegroundColor Cyan -wsl --exec docker exec -u $User $ContainerName adb kill-server -Start-Sleep -Seconds 2 - -Write-Host "๐ŸŒ‰ Connecting Container's ADB..." -ForegroundColor Cyan -$retryCount = 0 -while ($retryCount -lt 10) { - wsl --exec docker exec -u $User $ContainerName adb connect 127.0.0.1:5555 | Out-Null - $AdbState = wsl --exec docker exec -u $User $ContainerName adb -s 127.0.0.1:5555 get-state 2>$null - - if ($AdbState -eq "device") { - Write-Host "โœ… ADB Linked and Authorized!" -ForegroundColor Green - break - } elseif ($AdbState -eq "unauthorized") { - Write-Host "โš ๏ธ Connected but UNAUTHORIZED. Check emulator screen!" -ForegroundColor Yellow - break - } else { - Write-Host "โŒ ADB Connection failed or device offline. Retrying..." -ForegroundColor Red - } - $retryCount++ - Start-Sleep -Seconds 2 -} - -# --- ISOLATED ADMIN ELEVATION FOR EXTERNAL ACCESS --- -$WslIp = (wsl --exec hostname -I).Trim().Split(" ")[0] -Write-Host "๐Ÿ›ก๏ธ Requesting Admin rights to expose Port $AppPort to local network..." -ForegroundColor Cyan - -$PortProxyCmd = "netsh interface portproxy add v4tov4 listenport=$AppPort listenaddress=0.0.0.0 connectport=$AppPort connectaddress=$WslIp; New-NetFirewallRule -DisplayName 'GhostClass-App' -Direction Inbound -Action Allow -Protocol TCP -LocalPort $AppPort -ErrorAction SilentlyContinue" - -Start-Process powershell -ArgumentList "-WindowStyle Hidden -Command `"$PortProxyCmd`"" -Verb RunAs -Write-Host "โœ… Network routing active: PC_IP:$AppPort -> Container:$AppPort" -ForegroundColor Green - -# ========================================== -# PHASE 4: HOLD STATE -# ========================================== -Write-Host "`n๐ŸŽฏ All systems go!" -ForegroundColor Magenta -Write-Host "--------------------------------------------------------" -Read-Host "๐Ÿ›‘ PRESS ENTER TO TEARDOWN ENVIRONMENT & IDLE WSL ๐Ÿ›‘" -Write-Host "--------------------------------------------------------" - -# ========================================== -# PHASE 5: CLEANUP & SCALE DOWN -# ========================================== -Write-Host "๐Ÿ—‘๏ธ Tearing down..." -ForegroundColor Cyan - -if ($SshProc) { - Stop-Process -Id $SshProc.Id -Force -ErrorAction SilentlyContinue - Write-Host "โœ… SSH Tunnel closed." -} - -Write-Host "๐Ÿ“ฑ Sending shutdown signal to Emulator..." -ForegroundColor Yellow -wsl --exec docker exec -u $User $ContainerName adb shell reboot -p 2>$null -Start-Sleep -Seconds 3 - -wsl --exec docker stop $ContainerName -Write-Host "โœ… Container stopped." - -adb -e emu kill 2>$null -if ($EmulatorProc) { - Stop-Process -Id $EmulatorProc.Id -Force -ErrorAction SilentlyContinue - Write-Host "โœ… Emulator process terminated." -} - -Write-Host "๐Ÿ”„ Throttling WSL back to Idle limits..." -ForegroundColor Cyan -Set-SafeWslLimits $IdleRAM $IdleCores $IdleSwap -wsl --shutdown - -Write-Host "โœ… Environment sanitized & WSL put to sleep." -ForegroundColor Green - -Write-Host "๐Ÿ›ก๏ธ Requesting Admin rights to clean up network routes..." -ForegroundColor Cyan -$CleanupCmd = "netsh interface portproxy delete v4tov4 listenport=$AppPort listenaddress=0.0.0.0; Remove-NetFirewallRule -DisplayName 'GhostClass-App' -ErrorAction SilentlyContinue" -Start-Process powershell -ArgumentList "-WindowStyle Hidden -Command `"$CleanupCmd`"" -Verb RunAs -Write-Host "โœ… Network routes and firewall rules sanitized." -ForegroundColor Green - - -# SIG # Begin signature block -# MIIFfQYJKoZIhvcNAQcCoIIFbjCCBWoCAQExDzANBglghkgBZQMEAgEFADB5Bgor -# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG -# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCC8RFq+GngGPmt5 -# /1c62PUwJfNX9we64JKxQLFg2rWbh6CCAvowggL2MIIB3qADAgECAhAgDfxRX/Zk -# h0itgCU8KbfCMA0GCSqGSIb3DQEBCwUAMBMxETAPBgNVBAMMCGRldmFrZXN1MB4X -# DTI2MDQyNzExMTI1NFoXDTI3MDQyNzExMzI1NFowEzERMA8GA1UEAwwIZGV2YWtl -# c3UwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrhVn79t4/fP2jtIkb -# OmN7X1HQBCywC4Vb+pJfzqbV8RP/8uhu2NOQg4deCa1srQSADnm9ItzXdAjfc4NA -# TnPdXkSx4hBsP8smizA0X8dPNbK0ODBnZcZC88eoQ/4KNdL6rqlflPGP5Dx3k06S -# JMaAkFzgcjNqoH6QNIPZHsss6T7kBglcVjn4kj/66cy5zcedRTazFCJB85Zb9U72 -# pcL5ZvK5xD4yVJ1c/9lKqUW4lbg9R7G0gZ6dz44GGbZVX26Qphl5WDJxnEmh/8Jf -# JkZZiySiDjVirns+Ny/k3HnLTbSpLVLMj5a1/xOsvEghSPYvG7X51Hj1Alz5L5yf -# NlhNAgMBAAGjRjBEMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcD -# AzAdBgNVHQ4EFgQUjNvZgRB8L+Vi+Skv86hd2P0PPbAwDQYJKoZIhvcNAQELBQAD -# ggEBAADVMcuuh4TVc5QWwFIGNLsdtsYnfawipRI5X8TQTrjqJfdCBMBnse/kLLIT -# KbNhG5Lxylu8jXdukcUvUFt72FOFXN1eY7oocp+jQWERXVNasARORfV3GrkWRW64 -# vHZG/XmfmguA5l/K0rP0pi+2pMn5mjhfjx13EAxeAMGKQU7GY1DWM5TQJDTZx4B3 -# +vvFbYvYxmUmCchqWFjg9Omzpa1Q4UThRclmIk7cb6eN1bbU4tF1/4gmAe+iUkVO -# zJzvVgp/M8XO7X85V7bIZGSRa/IYRpfpVS9usJ06b7OfTMzbKxWd2+iSCSEdKztT -# fqh6873JOeOS7Wj+cuO9xt5guQMxggHZMIIB1QIBATAnMBMxETAPBgNVBAMMCGRl -# dmFrZXN1AhAgDfxRX/Zkh0itgCU8KbfCMA0GCWCGSAFlAwQCAQUAoIGEMBgGCisG -# AQQBgjcCAQwxCjAIoAKAAKECgAAwGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQw -# HAYKKwYBBAGCNwIBCzEOMAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEIEEk -# 2wiUBVdA61lng4u4OXRUs7QD5TaGABWOzhc1SogGMA0GCSqGSIb3DQEBAQUABIIB -# AAFD9+VnXEIjvuTx/p7Oi6X2rds+SlPaW1AQzFDWxIG2pA7Y/pj34sR78x/C1aRO -# XlUl3xwySp5OOqbO0w4b6+tijjM7HZCWXspNBbLDZyrmS0mMoMUmGNJJjPjLt6nd -# lHv00A19G5s5UfEbXrrkzO8quwGA5ptEbVQUn3d+c/Btm/rcqTTDN4xsC3ttOA+9 -# nwyGCRtrhmsbbc3blUrgtFSShbAARyrsbPU7EOzR6Hmak0DGhyaQ5vmaH7KL7KDU -# sz2bJpAx1X/QrMP98215BlcFaj4/1wyQ4yt2Heedo9KE6ZIlUKsJaEA3AVgOTFA/ -# RgGY6dQcyBqI/UGW9aqS+y8= -# SIG # End signature block +<# +.SYNOPSIS + GhostClass Sandbox dev-env launcher for Docker Desktop. + Setup ADB, supports Emulator, Physical target, or Skip. + +.PARAMETER Mode + "Emulator", "Physical", or "Skip". +#> +param( + [ValidateSet("Emulator", "Physical", "Skip")] + [string]$Mode +) + +$ContainerName = "GhostClass_Sandbox" +$User = "vscode" +$VmServicePort = 8181 + +# Ensure WSL SSH agent socket is initialized before Docker mounts it +Write-Host "๐Ÿ”‘ Initializing WSL SSH Relay..." -ForegroundColor Cyan +wsl --exec bash -c 'source ~/.bashrc' + +Write-Host "๐Ÿ”ง Verifying Docker Desktop..." -ForegroundColor Cyan +if (!(docker info 2>$null)) { + Write-Host "โŒ Docker Desktop is not running." -ForegroundColor Red + exit 1 +} + +$Status = (docker inspect -f '{{.State.Status}}' $ContainerName 2>$null).Trim() +if ($Status -ne "running") { + Write-Host "๐Ÿš€ Starting container..." -ForegroundColor Cyan + wsl --exec bash -ic "docker start $ContainerName" > $null + Start-Sleep -Seconds 2 +} + +if (-not $Mode) { + Write-Host "`n๐Ÿค– Select Debug Target Environment:" -ForegroundColor Magenta + Write-Host " [1] Emulator" -ForegroundColor Cyan + Write-Host " [2] Physical Device (Wi-Fi ADB)" -ForegroundColor Cyan + Write-Host " [3] Skip ADB (Container Only)" -ForegroundColor Cyan + $Choice = Read-Host "Enter selection (1, 2, or 3)" + + if ($Choice -eq "3") { $Mode = "Skip" } + elseif ($Choice -eq "2") { $Mode = "Physical" } + else { $Mode = "Emulator" } +} + +if ($Mode -ne "Skip") { + # Reset ADB on container to start fresh + docker exec -u $User $ContainerName adb kill-server 2>$null + + if ($Mode -eq "Physical") { + Write-Host "๐Ÿ“ฑ Preparing Physical Device via USB/Wi-Fi..." -ForegroundColor Cyan + adb start-server | Out-Null + + # 1. Fetch Wi-Fi IP while USB is attached + $RouteOutput = adb shell ip route 2>$null + $DeviceIp = ($RouteOutput | Select-String -Pattern 'src\s+(\d+\.\d+\.\d+\.\d+)').Matches.Groups[1].Value + + if (-not $DeviceIp) { + Write-Host "โŒ Could not determine device's Wi-Fi IP. Is USB plugged in and authorized?" -ForegroundColor Red + exit 1 + } + + # 2. Switch phone to TCP mode on host + Write-Host "๐Ÿ“ก Switching device ADB to TCP mode (Port 5555)..." -ForegroundColor Cyan + adb tcpip 5555 | Out-Null + Start-Sleep -Seconds 3 + + # 3. Connect Host ADB over Wi-Fi first to authenticate key pair + Write-Host "๐Ÿค Connecting Windows Host ADB to ${DeviceIp}:5555..." -ForegroundColor Cyan + adb connect "${DeviceIp}:5555" | Out-Null + Start-Sleep -Seconds 2 + + Write-Host "๐Ÿ“ฑ Connecting Container ADB to Device IP: ${DeviceIp}:5555" -ForegroundColor Green + docker exec -u $User $ContainerName adb connect "${DeviceIp}:5555" | Out-Null + + } else { + Write-Host "๐Ÿ“ฑ Launching Local Emulator..." -ForegroundColor Cyan + $EmulatorProc = Start-Process emulator -ArgumentList "-avd Medium_Phone_API_36.1 -netdelay none -netspeed full" -PassThru -WindowStyle Hidden + + # Wait for emulator to fully register on Windows ADB + Write-Host "โณ Waiting for Emulator ADB boot..." -ForegroundColor Cyan + $emuBooted = $false + for ($i = 0; $i -lt 20; $i++) { + $emuState = (adb -e get-state 2>$null) + if ($emuState -eq "device") { $emuBooted = $true; break } + Start-Sleep -Seconds 2 + } + + if (-not $emuBooted) { + Write-Host "โŒ Emulator failed to boot or register ADB on host." -ForegroundColor Red + exit 1 + } + + # Use host.docker.internal so the container routes to Windows Host + Write-Host "๐Ÿ”Œ Connecting Container ADB to host.docker.internal:5555..." -ForegroundColor Cyan + docker exec -u $User $ContainerName adb connect host.docker.internal:5555 | Out-Null + } + + $retryCount = 0 + # Match target to host.docker.internal for Emulator mode + $Target = if ($Mode -eq "Physical") { "${DeviceIp}:5555" } else { "host.docker.internal:5555" } + + while ($retryCount -lt 15) { + $containerState = (docker exec -u $User $ContainerName adb -s $Target get-state 2>$null) + if ($containerState -eq "device") { + Write-Host "โœ… Container ADB Connected & Authorized to $Target!" -ForegroundColor Green + break + } + Start-Sleep -Seconds 2 + $retryCount++ + } + + if ($retryCount -ge 15) { + Write-Host "โš ๏ธ Warning: ADB connection timed out inside container. You may need to accept an RSA auth prompt on phone screen." -ForegroundColor Yellow + } +} else { + Write-Host "โญ๏ธ Skipping ADB configuration." -ForegroundColor Cyan +} + +Write-Host "`n๐ŸŽฏ All systems go!" -ForegroundColor Magenta +Read-Host "๐Ÿ›‘ PRESS ENTER TO TEARDOWN ENVIRONMENT ๐Ÿ›‘" + +Write-Host "๐Ÿ—‘๏ธ Tearing down..." -ForegroundColor Cyan + +if ($Mode -eq "Emulator") { + Write-Host "๐Ÿ›‘ Terminating emulator..." -ForegroundColor Cyan + adb -e emu kill 2>$null + Start-Sleep -Seconds 3 + if ($EmulatorProc) { Stop-Process -Id $EmulatorProc.Id -Force -ErrorAction SilentlyContinue } +} elseif ($Mode -eq "Physical") { + adb disconnect 2>$null | Out-Null +} + +if ($Mode -ne "Skip") { + docker exec -u $User $ContainerName adb kill-server 2>$null +} + +Write-Host "โœ… Environment sanitized. gg." -ForegroundColor Green + +# SIG # Begin signature block +# MIIFfQYJKoZIhvcNAQcCoIIFbjCCBWoCAQExDzANBglghkgBZQMEAgEFADB5Bgor +# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG +# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCDExE0VmBcJhrmd +# u6wbjbci3pk4NvreeYH+8iNVZ/RTUKCCAvowggL2MIIB3qADAgECAhAmKGzz2Y/i +# k00s+ReTOHmTMA0GCSqGSIb3DQEBCwUAMBMxETAPBgNVBAMMCGRldmFrZXN1MB4X +# DTI2MDYwNzEzNTA0MloXDTI3MDYwNzE0MTA0MlowEzERMA8GA1UEAwwIZGV2YWtl +# c3UwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDEoLmTS8czHXtaQFpw +# 6w6gmTU9ciThCmc2H78V47zO+J+3NrdSHRx5jqT/liWIQ8konlM+DiozDx4TXz8U +# LBbI1UJTR7lbTUJayzy7d59NzVD9YKLBvfw/KAleMFaAIPbM1xMfZnHreppsnMMj +# rh/N1XmO7/0sLa2F9vV4xGhM17b24U/bnozmP3Gtm+kxO5j4XCr1vX3H9JDcBAPl +# Cuu3YQASdN/iOtLZ4Qu25R8onqzYF4vv4pFtaQSpD2b/WX/KJ2kKKAsK2bdBgQlF +# ETXhRN40OoT3oULKS+rEGnisvJ6wVdC5kScXYy0M+OE9tdU+DO+B3w3ui+6ztAYp +# YKXdAgMBAAGjRjBEMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcD +# AzAdBgNVHQ4EFgQUhlC/oAYJSIGNOeB4Lq85vZb8y5AwDQYJKoZIhvcNAQELBQAD +# ggEBAC8BtGR3ct33qhR0mW1K8NnVa1YRYiQ3Jl9hh7z7Z+NZ3X2VFzECuAx4wlki +# SjVIGxmWiMt51kxDPo8G9If1b6lvH7ukbVOlw/30AvyL0SDj1v9E9rAKzTaDhN9k +# wgTUZ+nxbCsX1uRrV6Nik3d/juOKpXvWAhWHmDn/qIaYqmmLoABsgrWyhZxUzTSV +# 6xCoxlJcCUIB5jicAUqmq4JAyID2ARYCi8FjdxX3+i0PoV/403+WTZgMVbwZFJBf +# G8oP+3TfnrI3X24woPZnyV+OeuLibsSFXq8qmrARY8lWrmT+m3Vl86ibtjj8ppFm +# 05EwtDcUqVGObcNhvsYrTipXJR0xggHZMIIB1QIBATAnMBMxETAPBgNVBAMMCGRl +# dmFrZXN1AhAmKGzz2Y/ik00s+ReTOHmTMA0GCWCGSAFlAwQCAQUAoIGEMBgGCisG +# AQQBgjcCAQwxCjAIoAKAAKECgAAwGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQw +# HAYKKwYBBAGCNwIBCzEOMAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEICjV +# b2J0wt5ulmJZJMupO60TlxopXtftLY8fIoBVVwjiMA0GCSqGSIb3DQEBAQUABIIB +# AAUYsPsF123GHKr/C0f0p1Hwa9ACLfDx8Q5iu5FFvX5sD2GJ6gQJuVTzSQ8xUXLh +# E9aG7sWtafhN+nCx0fld3HARawmmrpzw1b455MHlO+RSsoQxzeBw8s2vINTbBBHI +# 0X02tQuX4/LKhecY88wKD+DnBjyvFWxahkxjfXWVUtHn9UzGOf8mRD/RDcZgvHFV +# aPeACodp1CLzMgghFx8t0V6TP+kWlbDlg5NRRtxwj1zEsBMZ3tsrijTE7PtttMIg +# UAc0f9JAZGJEpixxPoUHPUN+ejYJQ1xzpPvrIUcAEr7Aa+6lxV73dWn+bNgdNOqo +# BQcMwKj1RPLAVl8m6mvCd2g= +# SIG # End signature block diff --git a/.devcontainer/pinned-artifacts.json b/.devcontainer/pinned-artifacts.json index 7100b182..0ec3d323 100644 --- a/.devcontainer/pinned-artifacts.json +++ b/.devcontainer/pinned-artifacts.json @@ -1,22 +1,22 @@ { "npm": { - "url": "https://registry.npmjs.org/npm/-/npm-11.11.0.tgz", - "shasum": "db5ad0ed255e1a29cf241c4112ee81d2220a4edb" + "url": "https://registry.npmjs.org/npm/-/npm-12.0.2.tgz", + "shasum": "788d93dc8869000b1078e0395c60748a0aadc4f1" }, "playwright": { - "url": "https://registry.npmjs.org/playwright/-/playwright-1.60.0.tgz", - "shasum": "89710863a51f21112633ef8b6b182594d3bfd7b5" + "url": "https://registry.npmjs.org/playwright/-/playwright-1.62.1.tgz", + "shasum": "8447b6755e8aec85a3cb7207c823e3ed2fc66700" }, "firebase": { - "url": "https://registry.npmjs.org/firebase-tools/-/firebase-tools-15.18.0.tgz", - "shasum": "179b592d2cbdae7b7b8d5844477e81844c6ef5a5" + "url": "https://registry.npmjs.org/firebase-tools/-/firebase-tools-15.25.1.tgz", + "shasum": "56f46b47cafdf89dbb3f9c14e039a3095da9c50c" }, "supabase": { - "url": "https://github.com/supabase/cli/releases/download/v2.98.2/supabase_linux_amd64.tar.gz", - "sha256": "0f59df9e6837e876f309e0b4f47005133c51296e85a02727b2927f33ed9adb2d" + "url": "https://github.com/supabase/cli/releases/download/v2.111.0/supabase_2.111.0_linux_amd64.tar.gz", + "sha256": "31ee8a152e9c8c8eddae072c6bc7c9119748a96c8cdaf21a6d31c9ce7e62cc18" }, "infisical": { - "url": "https://registry.npmjs.org/@infisical/cli/-/cli-0.43.84.tgz", - "shasum": "1be194be8a50c38706d3bd1f5852d22bc393827d" + "url": "https://registry.npmjs.org/@infisical/cli/-/cli-0.43.114.tgz", + "shasum": "f6c8ec4b7c0efcb568694653455f96fb947e4993" } } diff --git a/.example.env b/.example.env index ee216b1a..03c8c800 100644 --- a/.example.env +++ b/.example.env @@ -44,7 +44,7 @@ NEXT_PUBLIC_APP_NAME=GhostClass # โš ๏ธ App version displayed in footer and health checks # ๐Ÿ”จ Build-time (Infisical `/build-time` folder) -NEXT_PUBLIC_APP_VERSION=4.4.9 +NEXT_PUBLIC_APP_VERSION=4.5.0 # โš ๏ธ Your production domain WITHOUT https:// # All URL-based variables are derived from this. @@ -365,7 +365,7 @@ JWE_PRIVATE_KEY= # โš ๏ธ Minimum supported app version required to bypass forced update # ๐Ÿš€ Runtime (Infisical `/runtime` folder โ†’ Server Env Var) -MIN_APP_VERSION=4.4.9 +MIN_APP_VERSION=4.5.0 # โ„น๏ธ Enforce Firebase App Check for all mobile clients in production # Valid: "true", "false" (default: false in dev, true recommended in prod) diff --git a/.github/ISSUE_TEMPLATE/custom.md b/.github/ISSUE_TEMPLATE/custom.md new file mode 100644 index 00000000..babf9b2c --- /dev/null +++ b/.github/ISSUE_TEMPLATE/custom.md @@ -0,0 +1,7 @@ +--- +name: Custom issue template +about: Describe this issue template's purpose here. +title: "" +labels: "" +assignees: "" +--- diff --git a/.github/actions/flutter-action/action.yaml b/.github/actions/flutter-action/action.yaml index 635024d5..c568836d 100644 --- a/.github/actions/flutter-action/action.yaml +++ b/.github/actions/flutter-action/action.yaml @@ -102,28 +102,38 @@ runs: - name: Set action inputs id: flutter-action shell: bash + env: + INPUT_FLUTTER_VERSION: ${{ inputs.flutter-version }} + INPUT_FLUTTER_VERSION_FILE: ${{ inputs.flutter-version-file }} + INPUT_ARCHITECTURE: ${{ inputs.architecture }} + INPUT_CACHE_KEY: ${{ inputs.cache-key }} + INPUT_CACHE_PATH: ${{ inputs.cache-path }} + INPUT_PUB_CACHE_KEY: ${{ inputs.pub-cache-key }} + INPUT_PUB_CACHE_PATH: ${{ inputs.pub-cache-path }} + INPUT_GIT_SOURCE: ${{ inputs.git-source }} + INPUT_CHANNEL: ${{ inputs.channel }} run: | $GITHUB_ACTION_PATH/setup.sh -p \ - -n '${{ inputs.flutter-version }}' \ - -f '${{ inputs.flutter-version-file }}' \ - -a '${{ inputs.architecture }}' \ - -k '${{ inputs.cache-key }}' \ - -c '${{ inputs.cache-path }}' \ - -l '${{ inputs.pub-cache-key }}' \ - -d '${{ inputs.pub-cache-path }}' \ - -g '${{ inputs.git-source }}' \ - ${{ inputs.channel }} + -n "$INPUT_FLUTTER_VERSION" \ + -f "$INPUT_FLUTTER_VERSION_FILE" \ + -a "$INPUT_ARCHITECTURE" \ + -k "$INPUT_CACHE_KEY" \ + -c "$INPUT_CACHE_PATH" \ + -l "$INPUT_PUB_CACHE_KEY" \ + -d "$INPUT_PUB_CACHE_PATH" \ + -g "$INPUT_GIT_SOURCE" \ + "$INPUT_CHANNEL" - name: Cache Flutter id: cache-flutter - uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.3 + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 if: ${{ inputs.cache == 'true' }} with: path: ${{ steps.flutter-action.outputs.CACHE-PATH }} key: ${{ steps.flutter-action.outputs.CACHE-KEY }} - name: Cache pub dependencies - uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.3 + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 id: cache-pub if: ${{ (inputs.pub-cache == '' && inputs.cache == 'true') || inputs.pub-cache == 'true' }} with: @@ -133,10 +143,16 @@ runs: - name: Run setup script shell: bash if: ${{ inputs.dry-run != 'true' && inputs.dry-run != true }} + env: + OUTPUT_VERSION: ${{ steps.flutter-action.outputs.VERSION }} + OUTPUT_ARCHITECTURE: ${{ steps.flutter-action.outputs.ARCHITECTURE }} + OUTPUT_CACHE_PATH: ${{ steps.flutter-action.outputs.CACHE-PATH }} + OUTPUT_PUB_CACHE_PATH: ${{ steps.flutter-action.outputs.PUB-CACHE-PATH }} + OUTPUT_CHANNEL: ${{ steps.flutter-action.outputs.CHANNEL }} run: | $GITHUB_ACTION_PATH/setup.sh \ - -n '${{ steps.flutter-action.outputs.VERSION }}' \ - -a '${{ steps.flutter-action.outputs.ARCHITECTURE }}' \ - -c '${{ steps.flutter-action.outputs.CACHE-PATH }}' \ - -d '${{ steps.flutter-action.outputs.PUB-CACHE-PATH }}' \ - ${{ steps.flutter-action.outputs.CHANNEL }} + -n "$OUTPUT_VERSION" \ + -a "$OUTPUT_ARCHITECTURE" \ + -c "$OUTPUT_CACHE_PATH" \ + -d "$OUTPUT_PUB_CACHE_PATH" \ + "$OUTPUT_CHANNEL" diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 21f76ab7..adea1b17 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -3,19 +3,21 @@ # Please see the documentation for all configuration options: # https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file -version: 2 +version: 3 multi-ecosystem-groups: all-dependencies: schedule: interval: "daily" + open-pull-requests-limit: 0 updates: - package-ecosystem: "npm" directory: "/" + schedule: + interval: "weekly" patterns: - "*" - multi-ecosystem-group: "all-dependencies" ignore: # ESLint v10 is not yet supported by typescript-eslint # Keep ESLint at v9 until typescript-eslint adds v10 support @@ -23,21 +25,30 @@ updates: update-types: ["version-update:semver-major"] - dependency-name: "@eslint/js" update-types: ["version-update:semver-major"] + multi-ecosystem-group: "all-dependencies" + open-pull-requests-limit: 0 - package-ecosystem: "docker" directory: "/" + schedule: + interval: "weekly" patterns: - "*" multi-ecosystem-group: "all-dependencies" + open-pull-requests-limit: 0 - package-ecosystem: "github-actions" directory: "/" + schedule: + interval: "weekly" patterns: - "*" multi-ecosystem-group: "all-dependencies" + open-pull-requests-limit: 0 - package-ecosystem: "pub" directory: "/mobile" schedule: - interval: "daily" + interval: "weekly" multi-ecosystem-group: "all-dependencies" + open-pull-requests-limit: 0 diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 8e3bc7d0..0476bb71 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -54,7 +54,6 @@ Relates to # - [ ] Flutter tests pass (`flutter test`) - [ ] Manual testing on Android (Emulator/Physical) - [ ] Manual testing on iOS (Simulator/Physical) -- [ ] JWE encryption/decryption verified - [ ] EzyGo direct access verified (mobile) ### Test Coverage diff --git a/.github/workflows/build-guard.yml b/.github/workflows/build-guard.yml index 0d91edf6..308158c1 100644 --- a/.github/workflows/build-guard.yml +++ b/.github/workflows/build-guard.yml @@ -19,7 +19,7 @@ jobs: contents: read steps: - name: Checkout - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 - name: Verify commit is signed run: | diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 3493be29..c199b2d2 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -25,10 +25,10 @@ jobs: ios: ${{ steps.filter.outputs.ios }} steps: - name: Checkout - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 - name: Detect path changes - uses: dorny/paths-filter@0bc4621a3135347011ad047f9ecf449bf72ce2bd # v3.0.0 + uses: dorny/paths-filter@7b450fff21473bca461d4b92ce414b9d0420d706 id: filter with: filters: | @@ -66,20 +66,20 @@ jobs: security-events: write steps: - name: Checkout - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 with: fetch-depth: 0 - name: Initialize CodeQL (JS) - uses: github/codeql-action/init@68bde559dea0fdcac2102bfdf6230c5f70eb485e + uses: github/codeql-action/init@e58424170fb0262c8d7ed60a2e84b9bffe205c67 with: languages: javascript - name: Autobuild (JS) - uses: github/codeql-action/autobuild@68bde559dea0fdcac2102bfdf6230c5f70eb485e + uses: github/codeql-action/autobuild@e58424170fb0262c8d7ed60a2e84b9bffe205c67 - name: Run CodeQL analysis (JS) - uses: github/codeql-action/analyze@68bde559dea0fdcac2102bfdf6230c5f70eb485e + uses: github/codeql-action/analyze@e58424170fb0262c8d7ed60a2e84b9bffe205c67 with: category: javascript @@ -93,21 +93,21 @@ jobs: security-events: write steps: - name: Checkout - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 with: fetch-depth: 0 - name: Download Gradle Wrapper run: | mkdir -p mobile/android/gradle/wrapper - curl -fSL -o mobile/android/gradle/wrapper/gradle-wrapper.jar https://raw.githubusercontent.com/gradle/gradle/v8.14.0/gradle/wrapper/gradle-wrapper.jar - echo "7d3a4ac4de1c32b59bc6a4eb8ecb8e612ccd0cf1ae1e99f66902da64df296172 mobile/android/gradle/wrapper/gradle-wrapper.jar" | sha256sum -c - + curl -fSL -o mobile/android/gradle/wrapper/gradle-wrapper.jar https://raw.githubusercontent.com/gradle/gradle/v9.6.1/gradle/wrapper/gradle-wrapper.jar + echo "497c8c2a7e5031f6aa847f88104aa80a93532ec32ee17bdb8d1d2f67a194a9c7 mobile/android/gradle/wrapper/gradle-wrapper.jar" | sha256sum -c - - name: Set up JDK 17 - uses: actions/setup-java@b622de1dfa918ecc0ab28f40cd42e3c3752cd6c5 + uses: actions/setup-java@03ad4de0992f5dab5e18fcb136590ce7c4a0ac95 with: distribution: "temurin" - java-version: "17" + java-version: "25" cache: "gradle" - name: Set up Flutter @@ -120,6 +120,10 @@ jobs: working-directory: mobile run: cp lib/config/app_secrets.dart.example lib/config/app_secrets.dart + - name: Generate dynamic firebase.json + working-directory: mobile + run: node ../scripts/generate-firebase-json.js + - name: Create CI Firebase Android stub working-directory: mobile run: | @@ -204,10 +208,10 @@ jobs: uses: android-actions/setup-android@40fd30fb8d7440372e1316f5d1809ec01dcd3699 with: accept-android-sdk-licenses: true - packages: 'platform-tools build-tools;33.0.2 platforms;android-33' + packages: "platform-tools build-tools;33.0.2 platforms;android-33" - name: Initialize CodeQL (Java + Kotlin) - uses: github/codeql-action/init@68bde559dea0fdcac2102bfdf6230c5f70eb485e + uses: github/codeql-action/init@e58424170fb0262c8d7ed60a2e84b9bffe205c67 with: languages: java-kotlin build-mode: manual @@ -219,7 +223,7 @@ jobs: ./gradlew assembleDebug --no-daemon -Pci - name: Run CodeQL analysis (Android) - uses: github/codeql-action/analyze@68bde559dea0fdcac2102bfdf6230c5f70eb485e + uses: github/codeql-action/analyze@e58424170fb0262c8d7ed60a2e84b9bffe205c67 with: category: java,kotlin @@ -233,7 +237,7 @@ jobs: security-events: write steps: - name: Checkout - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 with: fetch-depth: 0 @@ -247,6 +251,10 @@ jobs: working-directory: mobile run: cp lib/config/app_secrets.dart.example lib/config/app_secrets.dart + - name: Generate dynamic firebase.json + working-directory: mobile + run: node ../scripts/generate-firebase-json.js + - name: Downgrade device_info_plus for compatibility working-directory: mobile run: | @@ -257,7 +265,7 @@ jobs: run: flutter pub get - name: Cache CocoaPods - uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 with: path: mobile/ios/Pods key: ${{ runner.os }}-pods-${{ hashFiles('mobile/pubspec.lock', 'mobile/ios/Podfile') }} @@ -269,7 +277,7 @@ jobs: run: flutter build ios --simulator --no-codesign - name: Initialize CodeQL (Swift) - uses: github/codeql-action/init@68bde559dea0fdcac2102bfdf6230c5f70eb485e + uses: github/codeql-action/init@e58424170fb0262c8d7ed60a2e84b9bffe205c67 with: languages: swift build-mode: manual @@ -287,6 +295,6 @@ jobs: CODE_SIGNING_ALLOWED=NO - name: Run CodeQL analysis (Swift) - uses: github/codeql-action/analyze@68bde559dea0fdcac2102bfdf6230c5f70eb485e + uses: github/codeql-action/analyze@e58424170fb0262c8d7ed60a2e84b9bffe205c67 with: category: swift diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index ae111d97..480ded09 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -23,7 +23,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 - name: Fetch CI secrets from Infisical if: env.INFISICAL_CLIENT_ID != '' && env.INFISICAL_CLIENT_SECRET != '' @@ -37,9 +37,9 @@ jobs: continue-on-error: true - name: Setup Supabase CLI - uses: supabase/setup-cli@df56b21da46c98abb12a9804e4fb1f657773e333 + uses: supabase/setup-cli@46f7f98c7f948ad727d22c1e67fab04c223a0520 with: - version: 2.98.2 + version: 2.111.0 - name: Link Project env: @@ -69,12 +69,12 @@ jobs: steps: - name: Checkout - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 - name: Setup Node.js - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e + uses: actions/setup-node@df56b21da46c98abb12a9804e4fb1f657773e333 with: - node-version: "24.14.1" + node-version: "24.18.1" - name: Fetch build-time variables from Infisical (Unmasked) if: env.INFISICAL_CLIENT_ID != '' && env.INFISICAL_CLIENT_SECRET != '' diff --git a/.github/workflows/mobile-test.yml b/.github/workflows/mobile-test.yml index 68ebd182..1f83caba 100644 --- a/.github/workflows/mobile-test.yml +++ b/.github/workflows/mobile-test.yml @@ -21,13 +21,13 @@ jobs: working-directory: mobile steps: - name: Checkout - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 - name: Set up Java - uses: actions/setup-java@b622de1dfa918ecc0ab28f40cd42e3c3752cd6c5 + uses: actions/setup-java@03ad4de0992f5dab5e18fcb136590ce7c4a0ac95 with: distribution: temurin - java-version: "17" + java-version: "25" - name: Set up Flutter uses: ./.github/actions/flutter-action @@ -38,6 +38,9 @@ jobs: - name: Prepare app_secrets.dart run: cp lib/config/app_secrets.dart.example lib/config/app_secrets.dart + - name: Generate dynamic firebase.json + run: node ../scripts/generate-firebase-json.js + - name: Install dependencies run: flutter pub get @@ -78,7 +81,7 @@ jobs: fi - name: Upload coverage to Codecov - uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 + uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f with: files: ./mobile/coverage/lcov.info flags: mobile diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4eb77843..8e7004c5 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -25,16 +25,16 @@ jobs: contents: read steps: - name: Checkout - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 - name: Run Trivy vulnerability scanner uses: aquasecurity/trivy-action@57a97c7e7821a5776cebc9bb87c984fa69cba8f1 with: - scan-type: 'fs' - scan-ref: '.' - trivy-config: 'trivy.yaml' - exit-code: '1' - severity: 'CRITICAL,HIGH' + scan-type: "fs" + scan-ref: "." + trivy-config: "trivy.yaml" + exit-code: "1" + severity: "CRITICAL,HIGH" # Build, sign, and push Docker images build-and-release: @@ -54,13 +54,13 @@ jobs: INFISICAL_CLIENT_SECRET: ${{ secrets.INFISICAL_CLIENT_SECRET }} steps: - name: Checkout - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd + uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c - name: Login to GHCR - uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 + uses: docker/login-action@af1e73f918a031802d376d3c8bbc3fe56130a9b0 with: registry: ghcr.io username: ${{ github.actor }} @@ -156,7 +156,7 @@ jobs: - name: Build & push Docker image id: build-push - uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f + uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a with: context: . push: true @@ -213,7 +213,7 @@ jobs: # Attest build provenance - name: Attest Build Provenance - uses: actions/attest-build-provenance@a2bbfa25375fe432b6a289bc6b6cd05ecd0c4c32 + uses: actions/attest-build-provenance@0f67c3f4856b2e3261c31976d6725780e5e4c373 with: subject-name: ghcr.io/${{ github.repository_owner }}/${{ steps.prep.outputs.image_name }} subject-digest: ${{ steps.build-push.outputs.digest }} @@ -280,7 +280,7 @@ jobs: # Attest SBOM - name: Attest SBOM - uses: actions/attest@59d89421af93a897026c735860bf21b6eb4f7b26 + uses: actions/attest@f7c74d28b9d84cb8768d0b8ca14a4bac6ef463e6 with: subject-name: ghcr.io/${{ github.repository_owner }}/${{ steps.prep.outputs.image_name }} subject-digest: ${{ steps.build-push.outputs.digest }} @@ -392,7 +392,7 @@ jobs: INFISICAL_CLIENT_SECRET: ${{ secrets.INFISICAL_CLIENT_SECRET }} steps: - name: Checkout - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 - name: Download Gradle Wrapper run: | @@ -401,10 +401,10 @@ jobs: echo "7d3a4ac4de1c32b59bc6a4eb8ecb8e612ccd0cf1ae1e99f66902da64df296172 mobile/android/gradle/wrapper/gradle-wrapper.jar" | sha256sum -c - - name: Set up Java - uses: actions/setup-java@b622de1dfa918ecc0ab28f40cd42e3c3752cd6c5 + uses: actions/setup-java@03ad4de0992f5dab5e18fcb136590ce7c4a0ac95 with: distribution: temurin - java-version: "17" + java-version: "25" - name: Set up Flutter uses: ./.github/actions/flutter-action @@ -648,13 +648,13 @@ jobs: - name: Attest mobile APK provenance id: attest-mobile - uses: actions/attest-build-provenance@a2bbfa25375fe432b6a289bc6b6cd05ecd0c4c32 + uses: actions/attest-build-provenance@0f67c3f4856b2e3261c31976d6725780e5e4c373 with: subject-path: mobile/build/app/outputs/flutter-apk/app-release.apk - name: Attest mobile AAB provenance id: attest-mobile-aab - uses: actions/attest-build-provenance@a2bbfa25375fe432b6a289bc6b6cd05ecd0c4c32 + uses: actions/attest-build-provenance@0f67c3f4856b2e3261c31976d6725780e5e4c373 with: subject-path: mobile/build/app/outputs/bundle/release/app-release.aab @@ -758,7 +758,7 @@ jobs: INFISICAL_CLIENT_SECRET: ${{ secrets.INFISICAL_CLIENT_SECRET }} steps: - name: Checkout - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 with: fetch-depth: 0 @@ -1001,4 +1001,3 @@ jobs: ./artifacts/mobile/mobile-checksums.txt \ ./artifacts/mobile/mobile-provenance.intoto.jsonl \ --draft=false - diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 11d9fe98..d6f134d9 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -3,7 +3,7 @@ name: OSSF Scorecard on: branch_protection_rule: schedule: - - cron: '0 0 * * 0' # Weekly on Sundays at midnight UTC + - cron: "0 0 * * 0" # Weekly on Sundays at midnight UTC push: branches: [main] workflow_dispatch: @@ -22,7 +22,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 with: persist-credentials: false @@ -34,6 +34,6 @@ jobs: publish_results: true - name: Upload SARIF results to GitHub Security - uses: github/codeql-action/upload-sarif@68bde559dea0fdcac2102bfdf6230c5f70eb485e + uses: github/codeql-action/upload-sarif@e58424170fb0262c8d7ed60a2e84b9bffe205c67 with: sarif_file: results.sarif diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 983b2170..4f0bcd96 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -18,11 +18,11 @@ jobs: contents: read steps: - name: Checkout - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 - - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e + - uses: actions/setup-node@df56b21da46c98abb12a9804e4fb1f657773e333 with: - node-version: "24.14.1" + node-version: "24.18.1" cache: "npm" - name: Install dependencies @@ -40,7 +40,7 @@ jobs: run: npm run test:coverage - name: Upload coverage to Codecov - uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 + uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f with: files: ./coverage/lcov.info token: ${{ secrets.CODECOV_TOKEN }} @@ -82,11 +82,11 @@ jobs: NODE_ENV: "test" steps: - name: Checkout - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 - - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e + - uses: actions/setup-node@df56b21da46c98abb12a9804e4fb1f657773e333 with: - node-version: "24.14.1" + node-version: "24.18.1" cache: "npm" - name: Install dependencies @@ -99,7 +99,7 @@ jobs: echo "PLAYWRIGHT_VERSION=$PLAYWRIGHT_VERSION" >> $GITHUB_OUTPUT - name: Cache Playwright browsers - uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 id: playwright-cache with: path: ~/.cache/ms-playwright diff --git a/.gitignore b/.gitignore index 4541d5bf..47d058fb 100644 --- a/.gitignore +++ b/.gitignore @@ -83,6 +83,7 @@ certificates/ /mobile/ios/Flutter/flutter_export_environment.sh /mobile/android/local.properties /mobile/android/key.properties +/mobile/android/.kotlin /mobile/android/app/src/main/res/raw/app_config.json /mobile/android/app/debug/ /mobile/android/app/profile/ @@ -108,4 +109,5 @@ certificates/ /mobile/ios/Runner/GoogleService-Info.plist # App Secrets -/mobile/lib/config/app_secrets.dart \ No newline at end of file +/mobile/lib/config/app_secrets.dart +/mobile/firebase.json \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index b75e4c22..f3bf7d0d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,7 @@ # =============================== # 0. Global deterministic settings # =============================== -ARG NODE_IMAGE=node:22.22.3-alpine@sha256:968df39aedcea65eeb078fb336ed7191baf48f972b4479711397108be0966920 +ARG NODE_IMAGE=node:24.18.1-alpine3.24@sha256:f70403e87646dc51b45295f4b8b70cdad0b63d2297c4c9899119b03f7af7a6b3 ARG SOURCE_DATE_EPOCH=1767225600 # =============================== @@ -9,13 +9,13 @@ ARG SOURCE_DATE_EPOCH=1767225600 # =============================== FROM ${NODE_IMAGE} AS base -# Update npm to version 11 without using `npm install -g` (avoids scorecard "npmCommand not pinned" flag). +# Update npm to version 12 without using `npm install -g` (avoids scorecard "npmCommand not pinned" flag). # /usr/local/bin/npm already symlinks to /usr/local/lib/node_modules/npm/bin/npm-cli.js, # so overwriting that directory via tar achieves the same result with no unpinned npm invocation. # The tarball is verified by SHA-256 before extraction. RUN apk add --no-cache wget && \ - wget -O /tmp/npm.tgz https://registry.npmjs.org/npm/-/npm-11.14.1.tgz && \ - echo "bddc8ec2a698d283674cf0a798ef444ba7332497f330dd166056281fcafaca7a /tmp/npm.tgz" | sha256sum -c - && \ + wget -O /tmp/npm.tgz https://registry.npmjs.org/npm/-/npm-12.0.2.tgz && \ + echo "5dbb86c71d07a1957f2e90734092dd6a58bdcd9ebc2d8d41ca1c6e6a21d364e1 /tmp/npm.tgz" | sha256sum -c - && \ rm -rf /usr/local/lib/node_modules/npm && \ mkdir -p /usr/local/lib/node_modules/npm && \ tar -xz --strip-components=1 -C /usr/local/lib/node_modules/npm -f /tmp/npm.tgz && \ diff --git a/README.md b/README.md index 66812a50..644baa36 100644 --- a/README.md +++ b/README.md @@ -13,9 +13,9 @@

- Next.js - React - Tailwind + Next.js + React + Tailwind TypeScript

@@ -24,8 +24,8 @@ iOS

- Vitest - Playwright + Vitest + Playwright

@@ -65,14 +65,14 @@ GhostClass is the ultimate academic survival tool for students who want to manag ### Core Framework -- **Next.js 16.2.6** - React 19 with App Router +- **Next.js 16.2.12** - React 19 with App Router - **TypeScript 6.0.3** - Strict mode for type safety - **Flutter 3.44.0** - Cross-platform native mobile application -- **Node.js** - v24.14.1+ +- **Node.js** - v24.18.1+ ### Styling & UI -- **Tailwind CSS 4.3.0** - Utility-first styling with custom design system +- **Tailwind CSS 4.3.3** - Utility-first styling with custom design system - **Radix UI** - Accessible, unstyled component primitives - **Shadcn UI** - Beautiful pre-styled components - **Framer Motion** - Smooth animations and transitions @@ -149,25 +149,221 @@ For the full mathematical derivation, duty leave limits (5 per course), and pseu ### Prerequisites -- **Node.js** - v24.14.1+ -- **npm** - v11.11.0+ +- **Docker Desktop** (with WSL2 backend enabled) +- **WSL2** (Linux distribution such as Ubuntu/Debian) +- **VS Code or Antigravity IDE/any IDE with WSL/Docker Support** -- **Flutter SDK** - 3.44.0 -- **Docker** - For containerized deployment (optional) +## ๐Ÿณ Dev Container Environment Setup (Recommended) -### Quick Start (Web) +GhostClass provides an isolated, reproducible Dev Container (`.devcontainer/Dockerfile`) equipped with Node 24, Flutter SDK 3.44, Deno, Playwright, Supabase, Firebase, Infisical CLI tools, and automatic IDE extension syncing. -1. **Setup**: `git clone` the repo and run `npm install --legacy-peer-deps`. -2. **Database**: Link your project and run `npx supabase db push`. -3. **Environment**: Install the Infisical CLI, authenticate via `infisical login`, and organize secrets inside `/build-time`, `/runtime`, and `/ci` path folders. -4. **Run**: Inject variables securely in-memory using `infisical run -- npm run dev` and visit `http://localhost:3000`. +### 1. Initialize and Configure WSL2 (Windows Host) -### Quick Start (Mobile) +To ensure optimal networking, memory utilization, and loopback connectivity, configure WSL2 on the Windows host. -1. **Install Flutter**: Ensure Flutter SDK 3.44.0 is installed. -2. **Setup**: Navigate to `mobile/` and run `flutter pub get`. -3. **Secrets**: Copy `app_secrets.dart.example` to `app_secrets.dart` and fill your API keys. -4. **Run**: Connect a device and run `flutter run`. +#### Option A: Using the WSL Settings GUI (Recommended) + +Open the WSL Settings application (search for "WSL Settings" in the Windows Start menu) or launch it by running the following command in PowerShell: + +```powershell +wsl --settings +``` + +In the settings interface, configure the following: + +- **Networking Mode**: `Mirrored` +- **Host Address Loopback**: `Enabled` +- **Automatic Memory Reclaim**: `Gradual` + +#### Option B: Using the `.wslconfig` File + +Create or edit `%USERPROFILE%\.wslconfig` in Windows (e.g., `C:\Users\\.wslconfig`) and add the following settings: + +```ini +[wsl2] +networkingMode=mirrored +hostAddressLoopback=true +autoMemoryReclaim=gradual +``` + +After configuring via either option, restart WSL2 by running the following command in Windows PowerShell: + +```powershell +wsl --shutdown +``` + +### 2. Enable Windows SSH Agent (Host) + +Run PowerShell as Administrator or user to enable the OpenSSH agent service and load your SSH/signing keys: + +```powershell +Set-Service -Name ssh-agent -StartupType Automatic +Start-Service ssh-agent +ssh-add $env:USERPROFILE\.ssh\id_ed25519 +``` + +### 3. Bridge SSH Agent to WSL2 + +In WSL2, install `socat`, download `npiperelay`, and bridge the Windows SSH pipe to Linux: + +```bash +sudo apt update && sudo apt install -y socat + +# Download npiperelay to bridge Windows named pipes to Linux sockets +curl -s https://api.github.com/repos/jstarks/npiperelay/releases/latest | grep "browser_download_url.*zip" | cut -d : -f 2,3 | tr -d \" | wget -qi - -O /tmp/npiperelay.zip + +sudo unzip -o /tmp/npiperelay.zip npiperelay.exe -d /usr/local/bin/ +sudo chmod +x /usr/local/bin/npiperelay.exe +rm /tmp/npiperelay.zip + +# Self-healing SSH relay script to your ~/.bashrc +cat << 'EOF' >> ~/.bashrc +# --- SSH AGENT RELAY --- +export SSH_AUTH_SOCK="$HOME/.ssh/agent.sock" + +# Test if SSH agent is actually responding end-to-end +ssh-add -l >/dev/null 2>&1 +if [ $? -eq 2 ]; then + # Kill stale relay processes and clean up socket/directory glitches + pkill -f "npiperelay.exe" 2>/dev/null || true + pkill -f "$SSH_AUTH_SOCK" 2>/dev/null || true + rm -rf "$SSH_AUTH_SOCK" + mkdir -p "$HOME/.ssh" + # Spawn fresh relay + if command -v npiperelay.exe >/dev/null 2>&1; then + (nohup socat UNIX-LISTEN:"$SSH_AUTH_SOCK",fork EXEC:"npiperelay.exe -ei -s //./pipe/openssh-ssh-agent",nofork >/dev/null 2>&1 &) + fi +fi +EOF + +# Clean up potential Docker dummy directories & init socket +rm -rf ~/.ssh/agent.sock +source ~/.bashrc +``` + +### 4. Clone Repository in WSL2 + +Clone the repository in your WSL2 home or projects directory: + +```bash +git clone https://github.com/devakesu/GhostClass.git +cd GhostClass +``` + +### 5. Build & Run Sandbox Container + +Build the dev container image and launch the sandbox container with mapped ports and volume mounts: + +```bash +# 1. Verify SSH agent connection (must return your keys, not an error) +ssh-add -l + +# 2. Build dev container image +docker build -t ghostclass-sandbox -f .devcontainer/Dockerfile . + +# 3. Launch sandbox container +docker run -d --name GhostClass_Sandbox \ + --restart unless-stopped \ + -v "$(pwd):/ghostclass" \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v "$HOME/.ssh/agent.sock:/run/host-services/ssh-auth.sock" \ + -e SSH_AUTH_SOCK="/run/host-services/ssh-auth.sock" \ + -p 3000:3000 -p 8000:8000 -p 8080:8080 -p 4000:4000 -p 5001:5001 \ + -p 8081:8081 -p 8085:8085 -p 9099:9099 \ + -p 54321:54321 -p 54322:54322 -p 54323:54323 \ + ghostclass-sandbox +``` + +### 6. Attach IDE & Initialize Workspace + +1. Open VS Code or Antigravity IDE. +2. Open Command Palette (`Ctrl+Shift+P` / `Cmd+Shift+P`) โ†’ select **Attach to Running Container** โ†’ `GhostClass_Sandbox`. +3. Open directory `/ghostclass` inside the container. +4. Run workspace initialization script in the integrated terminal: + + ```bash + ~/init_workspace.sh + ``` + + _(Enter Git Name and Email when prompted to configure local commit signing and SSH identity)._ + +5. Run **Developer: Reload Window** in VS Code / Antigravity to refresh environment variables and extension integrations. + +### 7. Android Emulator Setup & Subsequent Development Startups + +To run and debug the mobile app on an Android Emulator or Physical Device: + +#### Android Emulator Setup + +Create an Android Virtual Device (AVD) named `Medium_Phone_API_36.1` in Android Studio's AVD Manager. _(Note: If using a different AVD name, edit the `-avd` target in `.devcontainer/Start.ps1`)_. + +#### Subsequent Starts via `Start.ps1` (Windows Host) + +On subsequent development startups (after initial `docker run`), execute the startup script from a Windows PowerShell terminal on the host: + +```powershell +.\.devcontainer\Start.ps1 +``` + +Select `[1] Emulator` (or pass `-Mode Emulator`). + +The script automatically ensures `GhostClass_Sandbox` container is running, launches the host Android emulator (`Medium_Phone_API_36.1`), bridges Windows ADB (`5555`) to Docker network (`host.docker.internal:5555`). + +Press **ENTER** in the PowerShell terminal when finished to gracefully shut down the emulator and clean up portproxy rules. + +### ๐Ÿ” Secret Management & Database Initialization + +Before starting the API server or mobile client, authenticate with Infisical and link your Supabase database project: + +```bash +# Authenticate Infisical CLI +infisical login + +# Authenticate Supabase CLI and link schema +supabase login +supabase link --project-ref +supabase db push +``` + +### ๐Ÿ Running Web Application / API Server + +Once Infisical and Supabase are authenticated: + +Run API / Web Server with Injected Secrets: + +```bash +infisical run --env=dev --projectId=xxxx --path=/build-time --path=/runtime -- npm run dev:https +``` + +Visit `https://localhost:3000` (or `http://localhost:3000`) for the web dashboard. + +### ๐Ÿ“ฑ Running Mobile App + +Navigate to Mobile Directory and execute: + +```bash +cd mobile +flutter pub get + +infisical run --env=dev --projectId=xxxx --path=/build-time -- sh -c ' + export DART_VM_OPTIONS="--bind-address=0.0.0.0" + flutter run \ + --dart-define=APP_DOMAIN="$APP_DOMAIN" \ + --dart-define=APP_VERSION="$APP_VERSION" \ + --dart-define=APP_COMMIT_SHA="$APP_COMMIT_SHA" \ + --dart-define=BUILD_TIMESTAMP="$BUILD_TIMESTAMP" \ + --dart-define=GITHUB_RUN_ID="$GITHUB_RUN_ID" \ + --dart-define=GITHUB_RUN_NUMBER="$GITHUB_RUN_NUMBER" \ + --dart-define=AUTHOR_NAME="$AUTHOR_NAME" \ + --dart-define=AUTHOR_URL="$AUTHOR_URL" \ + --dart-define=GITHUB_URL="$GITHUB_URL" \ + --dart-define=DONATE_URL="$DONATE_URL" \ + --dart-define=APP_NAME="$APP_NAME" \ + --dart-define=ANDROID_PACKAGE_NAME="$ANDROID_PACKAGE_NAME" \ + --dart-define=IOS_APP_ID="$IOS_APP_ID" \ + --dart-define=GHOSTCLASS_DEV_URL="$GHOSTCLASS_DEV_URL" +' +``` For contribution rules and environment configurations, please refer to **[CONTRIBUTING.md](docs/CONTRIBUTING.md)** and **[SECURITY.md](SECURITY.md)**. @@ -257,4 +453,4 @@ We welcome contributions! GhostClass uses an **automatic version bumping system* This project is licensed under the **[GNU General Public License v3.0](LICENSE)**. -***Thank you for your interest in GhostClass! Bunk classes & enjoy, but don't forget to study!! ๐Ÿ˜๐Ÿค*** +_**Thank you for your interest in GhostClass! Bunk classes & enjoy, but don't forget to study!! ๐Ÿ˜๐Ÿค**_ diff --git a/SECURITY.md b/SECURITY.md index fda84a6f..49c0d175 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -112,7 +112,7 @@ GhostClass uses npm overrides to enforce minimum secure versions of transitive d - **Scope**: Dev-only (used by build tools: Sentry, Serwist) - **Status**: โœ… Up-to-date -#### source-map: ^0.7.6 +#### source-map: ^0.8.0 - **Reason**: Dependency resolution conflicts and stability improvements - **Scope**: Dev-only (used by Vite/Terser for sourcemap generation) @@ -131,12 +131,44 @@ GhostClass uses npm overrides to enforce minimum secure versions of transitive d - **Scope**: Transitive dependency (used by various dev tools) - **Status**: โœ… Up-to-date +#### @tootallnate/once: ^3.0.1 + +- **Reason**: Memory leak prevention and event listener security hardening in legacy HTTP agent wrappers +- **Scope**: Dev-only / transitive dependency +- **Status**: โœ… Up-to-date + #### postcss: ^8.5.14 - **Reason**: Security hardening and dependency stability - **Scope**: Transitive dependency (used by Tailwind CSS) - **Status**: โœ… Up-to-date +#### sharp: ^0.35.0 + +- **Reason**: Native memory safety hardening and libvips security patches +- **Scope**: Production dependency (used by Next.js image optimization) +- **Status**: โœ… Up-to-date + +#### uuid: ^14.0.1 + +- **Reason**: CSPRNG generation hardening and prototype protection in v14+ +- **Scope**: Production & transitive dependency +- **Status**: โœ… Up-to-date + +### Egress Worker Overrides (workers/package.json) + +#### undici: ^8.4.2 + +- **Reason**: HTTP request smuggling and header injection protection in Worker fetch engine +- **Scope**: Proxy worker dependency +- **Status**: โœ… Patched + +#### ws: ^8.20.1 + +- **Reason**: Resource exhaustion DoS vulnerability fix (CVE-2024-37890) +- **Scope**: Proxy worker dependency +- **Status**: โœ… Patched + ### Maintenance Policy - Overrides are reviewed during each major release diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index da6705c2..9efe429d 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -2,8 +2,6 @@ Thank you for your interest in contributing to GhostClass! This guide will help you understand our development workflow and contribution process. -> **๐Ÿ‘‹ For External Contributors**: You don't need GPG keys, PAT tokens, or any special setup! Just fork, code, and submit a PR. The version bump workflow will guide you through a simple script. See [Quick Setup](#quick-setup) below. - ## Table of Contents - [Getting Started](#getting-started) @@ -19,33 +17,11 @@ Thank you for your interest in contributing to GhostClass! This guide will help ### Prerequisites -- **Node.js**: 24.14.1+ -- **npm**: 11.11.0+ -- **Flutter SDK**: 3.27+ (for mobile development) -- **Dart SDK**: ^3.11.4 (bundled with Flutter) -- **Git**: Latest version - -**That's it!** External contributors don't need GPG keys, GitHub PAT tokens, or access to secrets. - -### Quick Setup - -```bash -# 1. Fork and clone -git clone https://github.com/YOUR_USERNAME/GhostClass.git -cd GhostClass - -# 2. Install dependencies -npm install --legacy-peer-deps - -# 3. Create feature branch -git checkout -b feature/your-feature-name - -# 4. Start development -npm run dev # Web development -cd mobile && flutter run # Mobile development -``` +- **Docker Desktop** (with WSL2 backend enabled) +- **WSL2** (Linux distribution such as Ubuntu/Debian) +- **VS Code or Antigravity IDE / any IDE with WSL/Docker Support** -**That's all you need to start developing!** For advanced maintainer setup (GPG, PAT tokens, deployment), see [For Maintainers Only](#for-maintainers-only) at the bottom of this guide. +Complete step-by-step dev container environment setup: **[Getting Started / Dev Container Setup](../README.md#-getting-started)**. ## Development Workflow @@ -173,11 +149,11 @@ docker build \ ### CI/CD Build Times -| Build Type | Platforms | Time | Use Case | -| --- | --- | --- | --- | -| Cached build | AMD64 | ~3-5 min | Incremental changes | -| Cold build | AMD64 | ~6-8 min | Fresh build | -| Multi-arch | AMD64 + ARM64 | ~10-15 min | Production releases | +| Build Type | Platforms | Time | Use Case | +| ------------ | ------------- | ---------- | ------------------- | +| Cached build | AMD64 | ~3-5 min | Incremental changes | +| Cold build | AMD64 | ~6-8 min | Fresh build | +| Multi-arch | AMD64 + ARM64 | ~10-15 min | Production releases | ### Performance Features diff --git a/mobile/README.md b/mobile/README.md index bb613176..31604b87 100644 --- a/mobile/README.md +++ b/mobile/README.md @@ -1,7 +1,7 @@ # GhostClass Mobile ![Flutter](https://img.shields.io/badge/Flutter-3.44.0-02569B?style=for-the-badge&logo=flutter&logoColor=white) -![Dart](https://img.shields.io/badge/Dart-3.12.0-0175C2?style=for-the-badge&logo=dart&logoColor=white) +![Dart](https://img.shields.io/badge/Dart-3.11.4-0175C2?style=for-the-badge&logo=dart&logoColor=white) ![Android](https://img.shields.io/badge/Android-10+-3DDC84?style=for-the-badge&logo=android&logoColor=black) ![iOS](https://img.shields.io/badge/iOS-13+-000000?style=for-the-badge&logo=apple&logoColor=white) ![License](https://img.shields.io/badge/License-GPL%20v3-blue?style=for-the-badge) @@ -40,7 +40,7 @@ GhostClass Mobile is a secure, zero-trust Flutter application that communicates | Package | Version | Purpose | | :--- | :--- | :--- | | **Flutter** | 3.44.0 | Cross-platform UI framework | -| **Dart** | 3.12.0 | Language | +| **Dart** | 3.11.4 | Language | ### State Management @@ -69,14 +69,14 @@ GhostClass Mobile is a secure, zero-trust Flutter application that communicates | `firebase_core` | ^4.7.0 | Firebase SDK | | `firebase_app_check` | ^0.4.3 | Device integrity & API protection | | `flutter_secure_storage` | ^10.0.0 | Hardware-backed credential storage | -| `jose` + `pointycastle` | ^0.3.5 / ^3.9.1 | JWE key parsing + RSA operations | +| `jose` + `pointycastle` | ^0.3.5+1 / ^3.9.1 | JWE key parsing + RSA operations | | `encrypt` | ^5.0.3 | AES-256 symmetric encryption | ### UI & Charts | Package | Version | Purpose | | :--- | :--- | :--- | -| `lucide_icons` | ^0.257.0 | Icon set (matches web) | +| `lucide_icons_flutter` | ^3.1.14+1 | Icon set (matches web) | | `google_fonts` | ^8.0.2 | Typography | | `flutter_animate` | ^4.5.2 | Declarative animations | | `fl_chart` | ^1.2.0 | Attendance trend charts | @@ -211,7 +211,7 @@ mobile/ ### Prerequisites - **Flutter SDK** โ€” 3.44.0 ([install](https://docs.flutter.dev/get-started/install)) -- **Dart SDK** โ€” 3.12.0 (bundled with Flutter) +- **Dart SDK** โ€” 3.11.4 (bundled with Flutter) - **Android Studio / Xcode** โ€” for emulator/simulator - **Firebase CLI** โ€” for App Check configuration - **A GhostClass backend** โ€” see the [root README](../README.md) for web setup diff --git a/mobile/android/app/build.gradle.kts b/mobile/android/app/build.gradle.kts index c0fedf1d..3bd4a4f9 100644 --- a/mobile/android/app/build.gradle.kts +++ b/mobile/android/app/build.gradle.kts @@ -17,7 +17,7 @@ if (keystorePropertiesFile.exists()) { android { namespace = "com.devakesu.apps.ghostclass" - compileSdk = flutter.compileSdkVersion + compileSdk = 37 ndkVersion = flutter.ndkVersion compileOptions { diff --git a/mobile/android/gradle/wrapper/gradle-wrapper.properties b/mobile/android/gradle/wrapper/gradle-wrapper.properties index e4ef43fb..a9db1155 100644 --- a/mobile/android/gradle/wrapper/gradle-wrapper.properties +++ b/mobile/android/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,9 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-9.6.1-bin.zip +networkTimeout=10000 +retries=0 +retryBackOffMs=500 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-all.zip diff --git a/mobile/android/gradlew b/mobile/android/gradlew index 9d82f789..249efbb0 100644 --- a/mobile/android/gradlew +++ b/mobile/android/gradlew @@ -1,74 +1,128 @@ -#!/usr/bin/env bash +#!/bin/sh + +# +# Copyright ยฉ 2015 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## -## -## Gradle start up script for UN*X -## +# +# gradlew start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh gradlew +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions ยซ$varยป, ยซ${var}ยป, ยซ${var:-default}ยป, ยซ${var+SET}ยป, +# ยซ${var#prefix}ยป, ยซ${var%suffix}ยป, and ยซ$( cmd )ยป; +# * compound commands having a testable exit status, especially ยซcaseยป; +# * various built-in commands including ยซcommandยป, ยซsetยป, and ยซulimitยป. +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/3d91ce3b8caaf77ad09f381f43615b715b53f72c/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# ############################################################################## -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" +# Attempt to set APP_HOME -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" +MAX_FD=maximum -warn ( ) { +warn () { echo "$*" -} +} >&2 -die ( ) { +die () { echo echo "$*" echo exit 1 -} +} >&2 # OS specific support (must be 'true' or 'false'). cygwin=false msys=false darwin=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; esac -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACMD=$JAVA_HOME/jre/sh/java else - JAVACMD="$JAVA_HOME/bin/java" + JAVACMD=$JAVA_HOME/bin/java fi if [ ! -x "$JAVACMD" ] ; then die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME @@ -77,84 +131,118 @@ Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." + fi fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac fi -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) fi - i=$((i+1)) + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg done - case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac fi -# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules -function splitJvmOpts() { - JVM_OPTS=("$@") -} -eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS -JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" -exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/mobile/android/gradlew.bat b/mobile/android/gradlew.bat index aec99730..8508ef68 100644 --- a/mobile/android/gradlew.bat +++ b/mobile/android/gradlew.bat @@ -1,90 +1,82 @@ -@if "%DEBUG%" == "" @echo off +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem + +@if "%DEBUG%"=="" @echo off @rem ########################################################################## @rem -@rem Gradle startup script for Windows +@rem gradlew startup script for Windows @rem @rem ########################################################################## -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= +@rem Set local scope for the variables, and ensure extensions are enabled +setlocal EnableExtensions set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init +if %ERRORLEVEL% equ 0 goto execute -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 -goto fail +"%COMSPEC%" /c exit 1 :findJavaFromJavaHome set JAVA_HOME=%JAVA_HOME:"=% set JAVA_EXE=%JAVA_HOME%/bin/java.exe -if exist "%JAVA_EXE%" goto init - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:init -@rem Get command-line arguments, handling Windowz variants +if exist "%JAVA_EXE%" goto execute -if not "%OS%" == "Windows_NT" goto win9xME_args -if "%@eval[2+2]" == "4" goto 4NT_args +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* -goto execute - -:4NT_args -@rem Get arguments from the 4NT Shell from JP Software -set CMD_LINE_ARGS=%$ +"%COMSPEC%" /c exit 1 :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 -:mainEnd -if "%OS%"=="Windows_NT" endlocal +@rem Execute gradlew +@rem endlocal doesn't take effect until after the line is parsed and variables are expanded +@rem which allows us to clear the local environment before executing the java command +endlocal & "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* & call :exitWithErrorLevel -:omega +:exitWithErrorLevel +@rem Use "%COMSPEC%" /c exit to allow operators to work properly in scripts +"%COMSPEC%" /c exit %ERRORLEVEL% diff --git a/mobile/android/settings.gradle.kts b/mobile/android/settings.gradle.kts index 87ee0386..c17b18f9 100644 --- a/mobile/android/settings.gradle.kts +++ b/mobile/android/settings.gradle.kts @@ -23,9 +23,9 @@ pluginManagement { plugins { id("dev.flutter.flutter-plugin-loader") version "1.0.0" - id("com.android.application") version "8.11.1" apply false - id("org.jetbrains.kotlin.android") version "2.2.20" apply false - id("com.google.gms.google-services") version "4.4.2" apply false + id("com.android.application") version "9.3.1" apply false + id("org.jetbrains.kotlin.android") version "2.4.10" apply false + id("com.google.gms.google-services") version "4.5.0" apply false } include(":app") diff --git a/mobile/lib/config/app_config.dart b/mobile/lib/config/app_config.dart index e90aa4d6..0d2c150b 100644 --- a/mobile/lib/config/app_config.dart +++ b/mobile/lib/config/app_config.dart @@ -76,7 +76,7 @@ class AppConfig { /// Current application version (derived from Infisical compilation injection). static String get appVersion => - const String.fromEnvironment('APP_VERSION', defaultValue: '4.4.9'); + const String.fromEnvironment('APP_VERSION', defaultValue: '4.5.0'); /// Commit SHA injected by CI for release builds. static String get appCommitSha => diff --git a/mobile/lib/firebase_options.dart b/mobile/lib/firebase_options.dart index 43504cad..9701b88a 100644 --- a/mobile/lib/firebase_options.dart +++ b/mobile/lib/firebase_options.dart @@ -1,19 +1,10 @@ -// File generated by FlutterFire CLI. +// File generated dynamically during build workflow. // ignore_for_file: type=lint import 'package:firebase_core/firebase_core.dart' show FirebaseOptions; import 'package:flutter/foundation.dart' show defaultTargetPlatform, kIsWeb, TargetPlatform; /// Default [FirebaseOptions] for use with your Firebase apps. -/// -/// Example: -/// ```dart -/// import 'firebase_options.dart'; -/// // ... -/// await Firebase.initializeApp( -/// options: DefaultFirebaseOptions.currentPlatform, -/// ); -/// ``` class DefaultFirebaseOptions { static FirebaseOptions get currentPlatform { if (kIsWeb) { @@ -29,18 +20,15 @@ class DefaultFirebaseOptions { return ios; case TargetPlatform.macOS: throw UnsupportedError( - 'DefaultFirebaseOptions have not been configured for macos - ' - 'you can reconfigure this by running the FlutterFire CLI again.', + 'DefaultFirebaseOptions have not been configured for macos.', ); case TargetPlatform.windows: throw UnsupportedError( - 'DefaultFirebaseOptions have not been configured for windows - ' - 'you can reconfigure this by running the FlutterFire CLI again.', + 'DefaultFirebaseOptions have not been configured for windows.', ); case TargetPlatform.linux: throw UnsupportedError( - 'DefaultFirebaseOptions have not been configured for linux - ' - 'you can reconfigure this by running the FlutterFire CLI again.', + 'DefaultFirebaseOptions have not been configured for linux.', ); default: throw UnsupportedError( @@ -51,18 +39,18 @@ class DefaultFirebaseOptions { static const FirebaseOptions android = FirebaseOptions( apiKey: String.fromEnvironment('FIREBASE_API_KEY_ANDROID'), - appId: '1:424804867878:android:df401041d564c22b21abe7', - messagingSenderId: '424804867878', - projectId: 'devakesu-ghostclass', - storageBucket: 'devakesu-ghostclass.firebasestorage.app', + appId: String.fromEnvironment('FIREBASE_ANDROID_APP_ID'), + messagingSenderId: String.fromEnvironment('FIREBASE_MESSAGING_SENDER_ID'), + projectId: String.fromEnvironment('FIREBASE_PROJECT_ID'), + storageBucket: String.fromEnvironment('FIREBASE_STORAGE_BUCKET'), ); static const FirebaseOptions ios = FirebaseOptions( apiKey: String.fromEnvironment('FIREBASE_API_KEY_IOS'), - appId: '1:424804867878:ios:d132bb8be987f52d21abe7', - messagingSenderId: '424804867878', - projectId: 'devakesu-ghostclass', - storageBucket: 'devakesu-ghostclass.firebasestorage.app', - iosBundleId: 'com.devakesu.apps.ghostclass', + appId: String.fromEnvironment('FIREBASE_IOS_APP_ID'), + messagingSenderId: String.fromEnvironment('FIREBASE_MESSAGING_SENDER_ID'), + projectId: String.fromEnvironment('FIREBASE_PROJECT_ID'), + storageBucket: String.fromEnvironment('FIREBASE_STORAGE_BUCKET'), + iosBundleId: String.fromEnvironment('FIREBASE_IOS_BUNDLE_ID'), ); } diff --git a/mobile/lib/main.dart b/mobile/lib/main.dart index 03aee25a..fc93e93f 100644 --- a/mobile/lib/main.dart +++ b/mobile/lib/main.dart @@ -119,7 +119,7 @@ void main() async { await Supabase.initialize( url: sUrl, - anonKey: sKey, + publishableKey: sKey, headers: { 'Origin': sOrigin, }, diff --git a/mobile/lib/services/push_notification_service.dart b/mobile/lib/services/push_notification_service.dart index e9a7bdf9..d6665089 100644 --- a/mobile/lib/services/push_notification_service.dart +++ b/mobile/lib/services/push_notification_service.dart @@ -1,5 +1,4 @@ // Service is dynamically resolved or used in background isolates -// ignore_for_file: unreachable_from_main import 'dart:async'; import 'dart:io'; diff --git a/mobile/pubspec.lock b/mobile/pubspec.lock index d655893f..666cd573 100644 --- a/mobile/pubspec.lock +++ b/mobile/pubspec.lock @@ -5,18 +5,18 @@ packages: dependency: transitive description: name: _fe_analyzer_shared - sha256: "5b7468c326d2f8a4f630056404ca0d291ade42918f4a3c6233618e724f39da8e" + sha256: a49d6cf99e8d8e7a8e93668d09ced0bbdb954d0b4fccc2f5f9241c6b87fad95c url: "https://pub.dev" source: hosted - version: "92.0.0" + version: "99.0.0" _flutterfire_internals: dependency: transitive description: name: _flutterfire_internals - sha256: bda3b7b55958bfd867addc40d067b4b11f7b8846d57671f5b5a6e7f9a56fe3ad + sha256: "460e9e684edb461d85498fc166ff8416f303f22216838d302d80676b348c6a4c" url: "https://pub.dev" source: hosted - version: "1.3.69" + version: "1.3.75" adaptive_number: dependency: transitive description: @@ -29,18 +29,18 @@ packages: dependency: transitive description: name: analyzer - sha256: "70e4b1ef8003c64793a9e268a551a82869a8a96f39deb73dea28084b0e8bf75e" + sha256: "663efa951fb8a45e06f491223a604c93820598f20e6a99c25617a1576065e8b7" url: "https://pub.dev" source: hosted - version: "9.0.0" + version: "12.1.0" analyzer_buffer: dependency: transitive description: name: analyzer_buffer - sha256: ff4bd291778c7417fe53fe24ee0d0a1f1ffe281a2d4ea887e7094f16e36eace7 + sha256: "445b77e2054fa3e8c8a8ef1b5e9e6b23bb8028fffd34b5e60eaef315b7750674" url: "https://pub.dev" source: hosted - version: "0.3.0" + version: "0.3.3" ansicolor: dependency: transitive description: @@ -53,10 +53,10 @@ packages: dependency: transitive description: name: app_links - sha256: "3462d9defc61565fde4944858b59bec5be2b9d5b05f20aed190adb3ad08a7abc" + sha256: f8db46d2ea9ff6f3a37191a7fd5b7813da1253ace8c32c1b9eadace41d1188ea url: "https://pub.dev" source: hosted - version: "7.0.0" + version: "7.2.1" app_links_linux: dependency: transitive description: @@ -69,10 +69,10 @@ packages: dependency: transitive description: name: app_links_platform_interface - sha256: "05f5379577c513b534a29ddea68176a4d4802c46180ee8e2e966257158772a3f" + sha256: "7546f09a6e93f4a2df2fe2bd40a5c6c64310ac461b036d82b43033be7a59f809" url: "https://pub.dev" source: hosted - version: "2.0.2" + version: "2.0.4" app_links_web: dependency: transitive description: @@ -125,34 +125,34 @@ packages: dependency: transitive description: name: build - sha256: aadd943f4f8cc946882c954c187e6115a84c98c81ad1d9c6cbf0895a8c85da9c + sha256: "45d14a0fb23e018d8287c32fc98d726ce466b231928ed9b9200f29bd3ccd39ae" url: "https://pub.dev" source: hosted - version: "4.0.5" + version: "4.0.7" build_config: dependency: transitive description: name: build_config - sha256: "4070d2a59f8eec34c97c86ceb44403834899075f66e8a9d59706f8e7834f6f71" + sha256: "94eaf6708fe64408c632ef2689ca3777b112f9421306ccf4f8c84d7c5c9f83f8" url: "https://pub.dev" source: hosted - version: "1.3.0" + version: "1.3.2" build_daemon: dependency: transitive description: name: build_daemon - sha256: bf05f6e12cfea92d3c09308d7bcdab1906cd8a179b023269eed00c071004b957 + sha256: "8c0535c3b2f625619f4dd1036ef1127f2e77bfedf89ed2eb2676ef076e0b6712" url: "https://pub.dev" source: hosted - version: "4.1.1" + version: "4.1.3" build_runner: dependency: "direct dev" description: name: build_runner - sha256: "4425a87d87d0d1303540f867994303f5b141ad2f6ecac7ac2cf8851f41c0cef1" + sha256: "5367e521935b102bdf1e735d2aab461e36b2edca6517662d088dd04cc39f8d16" url: "https://pub.dev" source: hosted - version: "2.14.0" + version: "2.15.1" built_collection: dependency: transitive description: @@ -165,10 +165,10 @@ packages: dependency: transitive description: name: built_value - sha256: "0730c18c770d05636a8f945c32a4d7d81cb6e0f0148c8db4ad12e7748f7e49af" + sha256: "34e4067d30ce212937df995f03b69992eea683539ceeac7f679a1f1eba055b56" url: "https://pub.dev" source: hosted - version: "8.12.5" + version: "8.12.6" characters: dependency: transitive description: @@ -213,10 +213,10 @@ packages: dependency: transitive description: name: code_assets - sha256: "83ccdaa064c980b5596c35dd64a8d3ecc68620174ab9b90b6343b753aa721687" + sha256: bf394f466ba9205f1812a0433b392d6af280f155f56651eda7c18cc32ed493b8 url: "https://pub.dev" source: hosted - version: "1.0.0" + version: "1.2.1" code_builder: dependency: transitive description: @@ -245,18 +245,18 @@ packages: dependency: transitive description: name: coverage - sha256: "5da775aa218eaf2151c721b16c01c7676fbfdd99cebba2bf64e8b807a28ff94d" + sha256: "956a3de0725ca232ad353565a8290d3357592bf4250f6f298a185e2d949c5d3d" url: "https://pub.dev" source: hosted - version: "1.15.0" + version: "1.15.1" cross_file: dependency: transitive description: name: cross_file - sha256: "28bb3ae56f117b5aec029d702a90f57d285cd975c3c5c281eaca38dbc47c5937" + sha256: "92c9c43c383bfa1c32079d3bc492d55d6d4318044b7b47edaff8971cbb555c51" url: "https://pub.dev" source: hosted - version: "0.3.5+2" + version: "0.3.5+4" crypto: dependency: "direct main" description: @@ -293,42 +293,42 @@ packages: dependency: transitive description: name: dart_style - sha256: a9c30492da18ff84efe2422ba2d319a89942d93e58eb0b73d32abe822ef54b7b + sha256: a4c1ccfee44c7e75ed80484071a5c142a385345e658fd8bd7c4b5c97e7198f98 url: "https://pub.dev" source: hosted - version: "3.1.3" + version: "3.1.8" device_info_plus: dependency: "direct main" description: name: device_info_plus - sha256: b4fed1b2835da9d670d7bed7db79ae2a94b0f5ad6312268158a9b5479abbacdd + sha256: "0891702f96b2e465fe567b7ec448380e6b1c14f60af552a8536d9f583b6b8442" url: "https://pub.dev" source: hosted - version: "12.4.0" + version: "13.2.0" device_info_plus_platform_interface: dependency: transitive description: name: device_info_plus_platform_interface - sha256: e1ea89119e34903dca74b883d0dd78eb762814f97fb6c76f35e9ff74d261a18f + sha256: "04b173a92e2d9161dfead145667037c8d834db725ce2e7b942bfe18fd2f45a46" url: "https://pub.dev" source: hosted - version: "7.0.3" + version: "8.1.0" dio: dependency: "direct main" description: name: dio - sha256: aff32c08f92787a557dd5c0145ac91536481831a01b4648136373cddb0e64f8c + sha256: "0df44ebba85e503958eb75d07eedd3c86275a58c1d3eda2f2ce8f0a2c3abbb3c" url: "https://pub.dev" source: hosted - version: "5.9.2" + version: "5.11.0" dio_web_adapter: dependency: transitive description: name: dio_web_adapter - sha256: "2f9e64323a7c3c7ef69567d5c800424a11f8337b8b228bad02524c9fb3c1f340" + sha256: "0786d0b7295a373de356fc0af4f6f1d0ab2844ed31b19dfc5e7556b70e24212c" url: "https://pub.dev" source: hosted - version: "2.1.2" + version: "2.2.1" ed25519_edwards: dependency: transitive description: @@ -349,10 +349,10 @@ packages: dependency: transitive description: name: equatable - sha256: "3e0141505477fd8ad55d6eb4e7776d3fe8430be8e497ccb1521370c3f21a3e2b" + sha256: "3bce007a596ff8b3119c45d68aaef631272537c03d30e5d4534dd24bf4c5eaa2" url: "https://pub.dev" source: hosted - version: "2.0.8" + version: "2.1.0" fake_async: dependency: transitive description: @@ -369,6 +369,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.2.0" + ffi_leak_tracker: + dependency: transitive + description: + name: ffi_leak_tracker + sha256: "4093d4ef9ca06ffe2786e73bfb25e22aa92112b9bb4ec941f11e3e6b61489a97" + url: "https://pub.dev" + source: hosted + version: "0.1.2" file: dependency: transitive description: @@ -413,98 +421,98 @@ packages: dependency: "direct main" description: name: firebase_analytics - sha256: "6993e54441e96b4de1dd85a159b236bbcd2c2487215c9d02b12c1685ddfded73" + sha256: "47b68927bc4abd6d7b4e2ddfe7c64fe087cca5f96d0c2b8d9d6deb6120c10ad6" url: "https://pub.dev" source: hosted - version: "12.3.0" + version: "12.4.5" firebase_analytics_platform_interface: dependency: transitive description: name: firebase_analytics_platform_interface - sha256: ac2a17484daf380b2247b9874e675ff9e4ac611d839a10b91b7445f764756760 + sha256: "36ce5feb5a996381e6411792eaa00e89178e75943e54ac8f14a8296b6e9a3e88" url: "https://pub.dev" source: hosted - version: "5.1.1" + version: "6.0.5" firebase_analytics_web: dependency: transitive description: name: firebase_analytics_web - sha256: "167a3115e71501ba6706235f00e370072920ee8d26b44fbfb9dc8e63c98a8d9b" + sha256: c12358983c927093cd40d42feb0cb05c8594d3a9b56ab5ad303bec2b8838d252 url: "https://pub.dev" source: hosted - version: "0.6.1+5" + version: "0.6.1+11" firebase_app_check: dependency: "direct main" description: name: firebase_app_check - sha256: "893cf0f921f76a3eeb288a6fb4ba821d1fdb08f8967d71a429648aea0c172570" + sha256: "28c1cc87389132c710236a008ee6688df510d3ce8b542ec377274ed8777006d6" url: "https://pub.dev" source: hosted - version: "0.4.3" + version: "0.4.5+2" firebase_app_check_platform_interface: dependency: transitive description: name: firebase_app_check_platform_interface - sha256: d46dc041aca21e7659e928a03900e0e60f168349523a00d9773618a27d562bc4 + sha256: "1cccf087884425f595f6ae7159c568bb0bcb8aaff3acb6dd150bde9b421b06d2" url: "https://pub.dev" source: hosted - version: "0.3.0" + version: "0.4.1+2" firebase_app_check_web: dependency: transitive description: name: firebase_app_check_web - sha256: "2b5904c7dc72366306f69c0b31a7ebed4eb56b7c7170220cd18ba06628abad39" + sha256: "1049ce1073c43f8e3efc97190206132182ed2f71f4686efe9ada54a2bba27442" url: "https://pub.dev" source: hosted - version: "0.2.4" + version: "0.2.5+2" firebase_core: dependency: "direct main" description: name: firebase_core - sha256: d5a94b884dcb1e6d3430298e94bfe002238094cdfd5e29202d536ee2120f9158 + sha256: "6f22d1c62e0c20976f02cd842c7b7cd3c0f561cc2052586411871045c08860c9" url: "https://pub.dev" source: hosted - version: "4.7.0" + version: "4.12.1" firebase_core_platform_interface: dependency: transitive description: name: firebase_core_platform_interface - sha256: "0ecda14c1bfc9ed8cac303dd0f8d04a320811b479362a9a4efb14fd331a473ce" + sha256: f74d1d6fabccf7743b0144c2ed363d81049e258e22428ebb6fb0faec2fa7d938 url: "https://pub.dev" source: hosted - version: "6.0.3" + version: "8.0.0" firebase_core_web: dependency: transitive description: name: firebase_core_web - sha256: dc5096257cd67292d34d78ceeb90836f02a4be921b5f3934311a02bb2376118c + sha256: ddab99d709b8c27dd47576eb05a1e719e07a2aa45c009a49ae92ac4d2a8ca555 url: "https://pub.dev" source: hosted - version: "3.6.0" + version: "3.9.1" firebase_messaging: dependency: "direct main" description: name: firebase_messaging - sha256: e5c93e8e7a9b0513f94bb684d2cf100e32e7dcdf2949574386b1955fc9a9b96a + sha256: "30ad2d59bcd86117dc49d278c8998a0fb390c5a3202f6e43e4bd215d3f1d0556" url: "https://pub.dev" source: hosted - version: "16.2.0" + version: "16.4.3" firebase_messaging_platform_interface: dependency: transitive description: name: firebase_messaging_platform_interface - sha256: "8cbb7d842e5071bba836452aff262f7db4b14bb3a0d00c1896cf176df886d65a" + sha256: "4d144cb42b9a5a42855596be2d7682d32c50169f42e7df2cb3278ecf935e7d63" url: "https://pub.dev" source: hosted - version: "4.7.9" + version: "4.9.2" firebase_messaging_web: dependency: transitive description: name: firebase_messaging_web - sha256: "8750bacf50573c0383535fc3f9c58c6a2f9dff5320a16a82c30631b9dad894f1" + sha256: fcd25d0b9da55766ef4d28ae05a7460f5189635d6b42607adcd9f08818fd35f0 url: "https://pub.dev" source: hosted - version: "4.1.5" + version: "4.2.3" fixnum: dependency: transitive description: @@ -554,74 +562,74 @@ packages: dependency: "direct main" description: name: flutter_markdown_plus - sha256: "039177906850278e8fb1cd364115ee0a46281135932fa8ecea8455522166d2de" + sha256: fce641d6c2106cc495de1cd603f97a4f9d615a97a64011928ded380dbdade935 url: "https://pub.dev" source: hosted - version: "1.0.7" + version: "1.0.12" flutter_plugin_android_lifecycle: dependency: transitive description: name: flutter_plugin_android_lifecycle - sha256: "38d1c268de9097ff59cf0e844ac38759fc78f76836d37edad06fa21e182055a0" + sha256: "3854fe5e3bff0b113c658f260b90c95dea17c92db0f2addeac2e343dd9969785" url: "https://pub.dev" source: hosted - version: "2.0.34" + version: "2.0.35" flutter_riverpod: dependency: "direct main" description: name: flutter_riverpod - sha256: "4e166be88e1dbbaa34a280bdb744aeae73b7ef25fdf8db7a3bb776760a3648e2" + sha256: "9255e1e3ad6e38906a1b4f8287678f95f378744c5b46b1985588543f3f19046e" url: "https://pub.dev" source: hosted - version: "3.3.1" + version: "3.3.2" flutter_secure_storage: dependency: "direct main" description: name: flutter_secure_storage - sha256: da922f2aab2d733db7e011a6bcc4a825b844892d4edd6df83ff156b09a9b2e40 + sha256: "7686b1d6a29985dcbb808c59518226e603e3bfa7c0ddfd1a0d00e4cda77c868e" url: "https://pub.dev" source: hosted - version: "10.0.0" + version: "10.3.1" flutter_secure_storage_darwin: dependency: transitive description: name: flutter_secure_storage_darwin - sha256: "8878c25136a79def1668c75985e8e193d9d7d095453ec28730da0315dc69aee3" + sha256: "82329fa5cdf343773b1b6897dea959105a29f092454259edff92f9f6637e8149" url: "https://pub.dev" source: hosted - version: "0.2.0" + version: "0.3.2" flutter_secure_storage_linux: dependency: transitive description: name: flutter_secure_storage_linux - sha256: "2b5c76dce569ab752d55a1cee6a2242bcc11fdba927078fb88c503f150767cda" + sha256: a5f35ddab43cf5c8215d2feb4ce1957851f28c5c37e6f04335066a0602087bf5 url: "https://pub.dev" source: hosted - version: "3.0.0" + version: "3.0.1" flutter_secure_storage_platform_interface: dependency: transitive description: name: flutter_secure_storage_platform_interface - sha256: "8ceea1223bee3c6ac1a22dabd8feefc550e4729b3675de4b5900f55afcb435d6" + sha256: "06686df417f34fe9f963ed217b7fdce250e2f637ddd6c374d7eb054549770633" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "2.0.2" flutter_secure_storage_web: dependency: transitive description: name: flutter_secure_storage_web - sha256: "6a1137df62b84b54261dca582c1c09ea72f4f9a4b2fcee21b025964132d5d0c3" + sha256: "073a62b3aeb866ab4ce795f960413948e51e5a42a9b0c8333b6daf5bb3208a1c" url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.1.1" flutter_secure_storage_windows: dependency: transitive description: name: flutter_secure_storage_windows - sha256: "3b7c8e068875dfd46719ff57c90d8c459c87f2302ed6b00ff006b3c9fcad1613" + sha256: "471951813a97006d899db4948acc654a4f28c440083ea08178935ce20b173ec1" url: "https://pub.dev" source: hosted - version: "4.1.0" + version: "4.2.2" flutter_shaders: dependency: transitive description: @@ -660,10 +668,10 @@ packages: dependency: transitive description: name: functions_client - sha256: "94074d62167ae634127ef6095f536835063a7dc80f2b1aa306d2346ff9023996" + sha256: e9685e9ab852a8b8e0579c867f6c9155da27317b294b3df796a536b8b8e0d253 url: "https://pub.dev" source: hosted - version: "2.5.0" + version: "2.6.4" glob: dependency: transitive description: @@ -684,26 +692,26 @@ packages: dependency: "direct main" description: name: go_router - sha256: "08b742eef4f71c9df5af543751cd0b7f1c679c4088488f4223ecaddc1a813b79" + sha256: "5922b2861e2235a3504896f0d6fa07d84141b480cf52eecd2f42cd25585a9e8a" url: "https://pub.dev" source: hosted - version: "17.2.2" + version: "17.3.0" google_fonts: dependency: "direct main" description: name: google_fonts - sha256: db9df7a5898d894eeda4c78143f35c30a243558be439518972366880b80bf88e + sha256: d3f251381df389f7418d4dff416bd27c0a23138df22969aafd28c4a4b1bb3cd6 url: "https://pub.dev" source: hosted - version: "8.0.2" + version: "8.2.0" gotrue: dependency: transitive description: name: gotrue - sha256: "7a4172601553e61716f5c3dd243aa3297e13308e07eb85b7853c941ba585dcf5" + sha256: "360bba9606e58d5acc59a033ab64ae3cf571a6868f7a7267cb8e9a204b7bf1b2" url: "https://pub.dev" source: hosted - version: "2.20.0" + version: "2.26.0" graphs: dependency: transitive description: @@ -716,18 +724,18 @@ packages: dependency: transitive description: name: gtk - sha256: e8ce9ca4b1df106e4d72dad201d345ea1a036cc12c360f1a7d5a758f78ffa42c + sha256: "4ff85b2a16724029dd9e5bbb5a94b6918f9973f74ba571c949d2002801879cf5" url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.2.0" hooks: dependency: transitive description: name: hooks - sha256: "025f060e86d2d4c3c47b56e33caf7f93bf9283340f26d23424ebcfccf34f621e" + sha256: "9a62a50b50b769a737bc0a8ff381f333529df3ab746b2f6b02e83760231455ba" url: "https://pub.dev" source: hosted - version: "1.0.3" + version: "2.0.2" http: dependency: transitive description: @@ -756,26 +764,26 @@ packages: dependency: transitive description: name: image - sha256: f9881ff4998044947ec38d098bc7c8316ae1186fa786eddffdb867b9bc94dfce + sha256: "6300175e00616bbc832e2fc91bfa4d776af5402c81c7151bee6905bb08473c52" url: "https://pub.dev" source: hosted - version: "4.8.0" + version: "4.9.1" image_picker: dependency: "direct main" description: name: image_picker - sha256: "784210112be18ea55f69d7076e2c656a4e24949fa9e76429fe53af0c0f4fa320" + sha256: d8402284df184bc05f4a2210c6c23983b0720f4cd87cbd05c5390a78af602667 url: "https://pub.dev" source: hosted - version: "1.2.1" + version: "1.2.3" image_picker_android: dependency: transitive description: name: image_picker_android - sha256: "66810af8e99b2657ee98e5c6f02064f69bb63f7a70e343937f70946c5f8c6622" + sha256: "6f3a1995eafb000333174fae92202622033b0ee7fd917a6cd3730295264df84a" url: "https://pub.dev" source: hosted - version: "0.8.13+16" + version: "0.8.13+19" image_picker_for_web: dependency: transitive description: @@ -836,10 +844,10 @@ packages: dependency: "direct main" description: name: intl - sha256: "3df61194eb431efc39c4ceba583b95633a403f46c9fd341e550ce0bfa50e9aa5" + sha256: "1ca20c894b1717686a2319b8548763d812bc0aabdac580420a44c5178c57a867" url: "https://pub.dev" source: hosted - version: "0.20.2" + version: "0.20.3" io: dependency: transitive description: @@ -876,10 +884,10 @@ packages: dependency: transitive description: name: json_annotation - sha256: cb09e7dac6210041fad964ed7fbee004f14258b4eca4040f72d1234062ace4c8 + sha256: "2a743920d81b7910627f68ee2c9ac1fc0bfee32b9fc3403587d7c6791ca12f80" url: "https://pub.dev" source: hosted - version: "4.11.0" + version: "4.12.0" jwt_decode: dependency: transitive description: @@ -932,10 +940,10 @@ packages: dependency: "direct main" description: name: lucide_icons_flutter - sha256: f9fd5d49b93bf14b89e0ff4818658a74ab16899bdaf7aa745358ee1a34f54eed + sha256: "234155b10641b8ef7bab8a077b93ea6c92fe849c06740cf89dcd86dcf350934f" url: "https://pub.dev" source: hosted - version: "3.1.14+1" + version: "3.1.15" markdown: dependency: "direct main" description: @@ -992,14 +1000,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.5" - native_toolchain_c: - dependency: transitive - description: - name: native_toolchain_c - sha256: "6ba77bb18063eebe9de401f5e6437e95e1438af0a87a3a39084fbd37c90df572" - url: "https://pub.dev" - source: hosted - version: "0.17.6" node_preamble: dependency: transitive description: @@ -1012,10 +1012,10 @@ packages: dependency: transitive description: name: objective_c - sha256: "100a1c87616ab6ed41ec263b083c0ef3261ee6cd1dc3b0f35f8ddfa4f996fe52" + sha256: b7fb95a6d9a4f009edd63dc5ac69f07420b23a16161c6dd8660290b59c602e8e url: "https://pub.dev" source: hosted - version: "9.3.0" + version: "9.5.0" package_config: dependency: transitive description: @@ -1028,18 +1028,26 @@ packages: dependency: "direct main" description: name: package_info_plus - sha256: "468c26b4254ab01979fa5e4a98cb343ea3631b9acee6f21028997419a80e1a20" + sha256: "127e1751e37ffb2ff4658beeaca77bad0c27bf5f932bd3a501c2296926d4b481" url: "https://pub.dev" source: hosted - version: "9.0.1" + version: "10.2.1" package_info_plus_platform_interface: dependency: transitive description: name: package_info_plus_platform_interface - sha256: "202a487f08836a592a6bd4f901ac69b3a8f146af552bbd14407b6b41e1c3f086" + sha256: db762cb2f4f25ee60fb6359773861b0f199e00b90d237bd85a76a1e806b46ef4 url: "https://pub.dev" source: hosted - version: "3.2.1" + version: "4.1.0" + passkeys_platform_interface: + dependency: transitive + description: + name: passkeys_platform_interface + sha256: e810520c7b79dca629fdc266958564eedd77dc85a955f5e94430dfccb92eef68 + url: "https://pub.dev" + source: hosted + version: "2.9.0" path: dependency: "direct main" description: @@ -1052,10 +1060,10 @@ packages: dependency: transitive description: name: path_provider - sha256: "50c5dd5b6e1aaf6fb3a78b33f6aa3afca52bf903a8a5298f53101fdaee55bbcd" + sha256: a7f4874f987173da295a61c181b8ee71dab59b332a486b391babf26a1b884825 url: "https://pub.dev" source: hosted - version: "2.1.5" + version: "2.1.6" path_provider_android: dependency: transitive description: @@ -1076,18 +1084,18 @@ packages: dependency: transitive description: name: path_provider_linux - sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279 + sha256: "58c2005f147315b11e9b4a7bc889cd5203e250cba8e3f012dae259b4972b5c16" url: "https://pub.dev" source: hosted - version: "2.2.1" + version: "2.2.2" path_provider_platform_interface: dependency: transitive description: name: path_provider_platform_interface - sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334" + sha256: "484838772624c3a4b94f1e44a3e19897fee738f2d5c4ce448443b0417f7c9dda" url: "https://pub.dev" source: hosted - version: "2.1.2" + version: "2.1.3" path_provider_windows: dependency: transitive description: @@ -1100,50 +1108,50 @@ packages: dependency: "direct main" description: name: permission_handler - sha256: "59adad729136f01ea9e35a48f5d1395e25cba6cea552249ddbe9cf950f5d7849" + sha256: "06149cba29bc46206f8b54b56065fe74b07602d2454a281287685ae66b5ab7b5" url: "https://pub.dev" source: hosted - version: "11.4.0" + version: "13.0.0" permission_handler_android: dependency: transitive description: name: permission_handler_android - sha256: d3971dcdd76182a0c198c096b5db2f0884b0d4196723d21a866fc4cdea057ebc + sha256: d7676c6fcf2f0b92537ec41476a6ead45a00b0d8bbb852395a6f9f33f49d6242 url: "https://pub.dev" source: hosted - version: "12.1.0" + version: "14.0.0" permission_handler_apple: dependency: transitive description: name: permission_handler_apple - sha256: f000131e755c54cf4d84a5d8bd6e4149e262cc31c5a8b1d698de1ac85fa41023 + sha256: "11b7e94a9d2fbee23c27f0cae0105c6266c03fd83b9a2eda6cf09141fc82624b" url: "https://pub.dev" source: hosted - version: "9.4.7" + version: "9.5.0" permission_handler_html: dependency: transitive description: name: permission_handler_html - sha256: "38f000e83355abb3392140f6bc3030660cfaef189e1f87824facb76300b4ff24" + sha256: "6b74008020d08eb95751d4935f3f07ef4658c03a43a51e6148b40e8412edce1b" url: "https://pub.dev" source: hosted - version: "0.1.3+5" + version: "0.1.4+0" permission_handler_platform_interface: dependency: transitive description: name: permission_handler_platform_interface - sha256: eb99b295153abce5d683cac8c02e22faab63e50679b937fa1bf67d58bb282878 + sha256: a5c8a97ecf5616112a5b16d4b8e9ec0e5ae90ef63ac69c0d7b8ae240be760b23 url: "https://pub.dev" source: hosted - version: "4.3.0" + version: "4.4.0" permission_handler_windows: dependency: transitive description: name: permission_handler_windows - sha256: "1a790728016f79a41216d88672dbc5df30e686e811ad4e698bfc51f76ad91f1e" + sha256: caeae01858a0a7d2df67a445ac98e1ad95e55a0e77c73044f4e9b1c8c2289cbd url: "https://pub.dev" source: hosted - version: "0.2.1" + version: "0.2.2" petitparser: dependency: transitive description: @@ -1188,18 +1196,18 @@ packages: dependency: transitive description: name: posix - sha256: "185ef7606574f789b40f289c233efa52e96dead518aed988e040a10737febb07" + sha256: bc1bad54ad2b735816e31f8d4600cfde6c7839975085ddfbca48b6c9f7c4044e url: "https://pub.dev" source: hosted - version: "6.5.0" + version: "6.5.2" postgrest: dependency: transitive description: name: postgrest - sha256: "9d61b3d4a88fcf9424d400127c54d49ed1b56ec30838fc0a33a64f31d4e694cc" + sha256: "10e3f195e131eec944fa872644aed89b33b5be998f3fc77c87325db3927bc646" url: "https://pub.dev" source: hosted - version: "2.7.0" + version: "2.8.0" process: dependency: transitive description: @@ -1244,10 +1252,10 @@ packages: dependency: transitive description: name: realtime_client - sha256: "7dfccf372d2f55aacfeefb6186f65a06f3ffae383fe042dbeef9d85d33487576" + sha256: "0cfbe0047e2591eba348938e9b4e620d5b1a8df6c374757e8eb8645252b8387f" url: "https://pub.dev" source: hosted - version: "2.7.3" + version: "2.11.0" record_use: dependency: transitive description: @@ -1268,34 +1276,34 @@ packages: dependency: transitive description: name: riverpod - sha256: "8c22216be8ad3ef2b44af3a329693558c98eca7b8bd4ef495c92db0bba279f83" + sha256: "17100416c51db7810c71a7bb2c34d1f881faa0074fd452afb0c4db6f8f126c76" url: "https://pub.dev" source: hosted - version: "3.2.1" + version: "3.3.2" riverpod_analyzer_utils: dependency: transitive description: name: riverpod_analyzer_utils - sha256: e55bc08c084a424e1bbdc303fe8ea75daafe4269b68fd0e0f6f1678413715b66 + sha256: "3e275138862ccc22ed61444a1f9a840f753094c367f28f4123f50289cd204d68" url: "https://pub.dev" source: hosted - version: "1.0.0-dev.9" + version: "1.0.0-dev.10" riverpod_annotation: dependency: "direct main" description: name: riverpod_annotation - sha256: "16471a1260b94e939394d78f1c63a9350936ac4a68c9fbdab40be47268c0b04f" + sha256: "674dbb26e2db3d9253166faf4758c796af14146b8fbcf5e7102bc8a04cd359b8" url: "https://pub.dev" source: hosted - version: "4.0.2" + version: "4.0.3" riverpod_generator: dependency: "direct dev" description: name: riverpod_generator - sha256: "6f9220534d7a353b53c875ea191a84d28cb4e52ac420a66a1bd7318329d977b0" + sha256: "54d790c3fee1ae281c448801bfdbfaa9fd961a9d3998494e0fcd9ee32184d7eb" url: "https://pub.dev" source: hosted - version: "4.0.3" + version: "4.0.4" rxdart: dependency: transitive description: @@ -1308,34 +1316,34 @@ packages: dependency: transitive description: name: sentry - sha256: "1f78300740739ff4b4920802687879231554350eab73eb229778f463aabda440" + sha256: "330a341076e16b87aa8a4f97b0bd48c085737d087e81ef337aee2b4c3e8896f9" url: "https://pub.dev" source: hosted - version: "9.19.0" + version: "9.26.0" sentry_dart_plugin: dependency: "direct dev" description: name: sentry_dart_plugin - sha256: "2c5f263f8d5aea3cf387a7e03f77e355d35c71bd9a429474d633fbc085b86ceb" + sha256: da9c1d0b3c87a251bfc36301f16af090a88c2d59128fe9a6f908f5ac20340c97 url: "https://pub.dev" source: hosted - version: "3.3.0" + version: "3.4.0" sentry_dio: dependency: "direct main" description: name: sentry_dio - sha256: eb7260258f18c099f096923d86453d37b9677514953b0b75e163394dd072a4a3 + sha256: f958ba749e6c5ff5164b979c5c07d302fe98707e30ba7a694fd9f46ff3922d36 url: "https://pub.dev" source: hosted - version: "9.19.0" + version: "9.26.0" sentry_flutter: dependency: "direct main" description: name: sentry_flutter - sha256: "168bbb120f7684dee6c0e100817f56ee1925bc2eb7fa55a71253337640c7e241" + sha256: "163685070e173b9b28cd10e56eb76fdaca34067831bd7e3563f98a5bc5866165" url: "https://pub.dev" source: hosted - version: "9.19.0" + version: "9.26.0" shared_preferences: dependency: "direct main" description: @@ -1348,10 +1356,10 @@ packages: dependency: transitive description: name: shared_preferences_android - sha256: e8d4762b1e2e8578fc4d0fd548cebf24afd24f49719c08974df92834565e2c53 + sha256: "0634e64bd719f89c012f392938e173521f535d3ecaf66558fa94a056d22b5cc7" url: "https://pub.dev" source: hosted - version: "2.4.23" + version: "2.4.27" shared_preferences_foundation: dependency: transitive description: @@ -1441,10 +1449,10 @@ packages: dependency: transitive description: name: source_gen - sha256: "732792cfd197d2161a65bb029606a46e0a18ff30ef9e141a7a82172b05ea8ecd" + sha256: a603f1fb984a7391ae5978d1b92bfaaa08b350dca5c825256f925818f7943bf5 url: "https://pub.dev" source: hosted - version: "4.2.2" + version: "4.2.4" source_map_stack_trace: dependency: transitive description: @@ -1489,10 +1497,10 @@ packages: dependency: transitive description: name: storage_client - sha256: "4801e8ca219a35e51cbb30589aba5306667ae8935b792504595a45273cef0b18" + sha256: "221263cfbe0c01575b7d7fe7543e44abff380eb4d38d936372844a1caa85ba12" url: "https://pub.dev" source: hosted - version: "2.5.2" + version: "2.6.0" stream_channel: dependency: transitive description: @@ -1521,18 +1529,18 @@ packages: dependency: transitive description: name: supabase - sha256: "40e5a8833c8834e140ef53b60a6181849667eba9ca125acb7f8e24c6a769d418" + sha256: "3879996256325fcc9abb03b62b12c07e4eaae2e008e1bf043cc1525184159a43" url: "https://pub.dev" source: hosted - version: "2.10.6" + version: "2.14.0" supabase_flutter: dependency: "direct main" description: name: supabase_flutter - sha256: c02ce58abcaf86cb8055ad40bfd98bbf5b93fed3b5b56b8220d88ed03842818b + sha256: c9916c1cd512ebf3107ec0f83c9dca13d2e1e789629c2a5df896586bff46ce5f url: "https://pub.dev" source: hosted - version: "2.12.4" + version: "2.16.0" system_info2: dependency: transitive description: @@ -1601,10 +1609,10 @@ packages: dependency: transitive description: name: url_launcher_android - sha256: "3bb000251e55d4a209aa0e2e563309dc9bb2befea2295fd0cec1f51760aac572" + sha256: b413d49b73867ac08dd2f9890efd3cc11f2a0e577618d50843440a1fb3776c32 url: "https://pub.dev" source: hosted - version: "6.3.29" + version: "6.3.32" url_launcher_ios: dependency: transitive description: @@ -1641,10 +1649,10 @@ packages: dependency: transitive description: name: url_launcher_web - sha256: d0412fcf4c6b31ecfdb7762359b7206ffba3bbffd396c6d9f9c4616ece476c1f + sha256: "85c81589622fbc87c1c683aaea164d3604a7777495a79d91e39ffcdec39ddb34" url: "https://pub.dev" source: hosted - version: "2.4.2" + version: "2.4.3" url_launcher_windows: dependency: transitive description: @@ -1657,10 +1665,10 @@ packages: dependency: "direct main" description: name: uuid - sha256: "1fef9e8e11e2991bb773070d4656b7bd5d850967a2456cfc83cf47925ba79489" + sha256: "9b129329f58692f6e6578329498a8fe9fbe98f090beb764ffbb8ee2eadd01dcd" url: "https://pub.dev" source: hosted - version: "4.5.3" + version: "4.6.0" vector_math: dependency: transitive description: @@ -1673,18 +1681,18 @@ packages: dependency: "direct dev" description: name: very_good_analysis - sha256: d1cb1d66a5aae2c702d68caca6c8347306d35e728fd94555fa21fa0448a972e0 + sha256: "481af67ab5877af20325251dc215a4ebac7666a1c8cf09198ffd457bc612b33d" url: "https://pub.dev" source: hosted - version: "10.2.0" + version: "10.3.0" vm_service: dependency: transitive description: name: vm_service - sha256: "046d3928e16fa4dc46e8350415661755ab759d9fc97fc21b5ab295f71e4f0499" + sha256: "0016aef94fc66495ac78af5859181e3f3bf2026bd8eecc72b9565601e19ab360" url: "https://pub.dev" source: hosted - version: "15.1.0" + version: "15.2.0" watcher: dependency: transitive description: @@ -1729,18 +1737,18 @@ packages: dependency: transitive description: name: win32 - sha256: d7cb55e04cd34096cd3a79b3330245f54cb96a370a1c27adb3c84b917de8b08e + sha256: ba6f4bba816c8d7e3c1580e170f3786d216951cc6b94babc3b814c08d2cb2738 url: "https://pub.dev" source: hosted - version: "5.15.0" + version: "6.3.0" win32_registry: dependency: transitive description: name: win32_registry - sha256: "6f1b564492d0147b330dd794fee8f512cec4977957f310f9951b5f9d83618dae" + sha256: "73b1d78920a9d6e03f8b4e43e612b87bf3152a0e5c5e5150267762b7c4116904" url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "3.0.3" x509: dependency: transitive description: @@ -1761,10 +1769,10 @@ packages: dependency: transitive description: name: xml - sha256: "971043b3a0d3da28727e40ed3e0b5d18b742fa5a68665cca88e74b7876d5e025" + sha256: "67f0aff7be013d107995e9b75bf4e7f2c3ef2dfdb2c8e68024bba0a7fd5756a4" url: "https://pub.dev" source: hosted - version: "6.6.1" + version: "7.0.1" yaml: dependency: transitive description: @@ -1777,10 +1785,10 @@ packages: dependency: transitive description: name: yet_another_json_isolate - sha256: fe45897501fa156ccefbfb9359c9462ce5dec092f05e8a56109db30be864f01e + sha256: eaa26beb5990b25a49d942374fd5a0c5aa67a837e03b14b4c26134aaa1ed01a9 url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.1.1" sdks: - dart: ">=3.11.4 <4.0.0" - flutter: ">=3.38.4" + dart: ">=3.12.0 <4.0.0" + flutter: ">=3.44.0" diff --git a/mobile/pubspec.yaml b/mobile/pubspec.yaml index 57e183a0..bc349e53 100644 --- a/mobile/pubspec.yaml +++ b/mobile/pubspec.yaml @@ -16,7 +16,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # In Windows, build-name is used as the major, minor, and patch parts # of the product and file versions while build-number is used as the build suffix. -version: 4.4.9+1 +version: 4.5.0+1 environment: sdk: ^3.11.4 @@ -29,7 +29,7 @@ environment: dependencies: crypto: ^3.0.2 cupertino_icons: ^1.0.8 - device_info_plus: ^12.4.0 + device_info_plus: ^13.2.0 dio: ^5.9.2 encrypt: ^5.0.3 firebase_analytics: ^12.3.0 @@ -50,9 +50,9 @@ dependencies: jose: ^0.3.5+1 lucide_icons_flutter: ^3.1.14+1 markdown: any - package_info_plus: ^9.0.1 + package_info_plus: ^10.2.1 path: ^1.9.1 - permission_handler: ^11.3.1 + permission_handler: ^13.0.0 pointycastle: ^3.9.1 riverpod_annotation: ^4.0.2 sentry_dio: ^9.18.0 @@ -118,7 +118,7 @@ flutter_launcher_icons: android: "ic_launcher" ios: true image_path: "assets/images/icon.png" - min_sdk_android: 29 # android min sdk min:16, default:21 + min_sdk_android: 29 sentry: project: ghostclass-f diff --git a/mobile/test/app_router_provider_test.dart b/mobile/test/app_router_provider_test.dart index 8969035f..4929e73b 100644 --- a/mobile/test/app_router_provider_test.dart +++ b/mobile/test/app_router_provider_test.dart @@ -45,7 +45,7 @@ void main() { await Supabase.initialize( url: 'https://example.com', - anonKey: 'anon', + publishableKey: 'anon', ); final container = ProviderContainer( diff --git a/mobile/test/auto_coverage_booster_test.dart b/mobile/test/auto_coverage_booster_test.dart index 7533491b..f8e50311 100644 --- a/mobile/test/auto_coverage_booster_test.dart +++ b/mobile/test/auto_coverage_booster_test.dart @@ -90,7 +90,7 @@ void main() { try { await Supabase.initialize( url: 'https://example.com', - anonKey: 'anon', + publishableKey: 'anon', ); } on Object catch (_) { // already initialized diff --git a/mobile/test/providers/notification_provider_test.dart b/mobile/test/providers/notification_provider_test.dart index ae7d263a..5d5a56d3 100644 --- a/mobile/test/providers/notification_provider_test.dart +++ b/mobile/test/providers/notification_provider_test.dart @@ -25,7 +25,7 @@ void main() { try { await Supabase.initialize( url: 'https://placeholder-domain.supabase.co', - anonKey: 'placeholder-anon-key', + publishableKey: 'placeholder-anon-key', ); } on Object catch (_) { // already initialized diff --git a/mobile/test/services/auth_profile_settings_coverage_test.dart b/mobile/test/services/auth_profile_settings_coverage_test.dart index c232adf5..a47e263a 100644 --- a/mobile/test/services/auth_profile_settings_coverage_test.dart +++ b/mobile/test/services/auth_profile_settings_coverage_test.dart @@ -37,7 +37,7 @@ void main() { try { await Supabase.initialize( url: 'https://example.com', - anonKey: 'anon', + publishableKey: 'anon', ); } on Object catch (_) { // already initialized diff --git a/next.config.ts b/next.config.ts index 60be9605..07476985 100644 --- a/next.config.ts +++ b/next.config.ts @@ -1,6 +1,6 @@ import { withSentryConfig } from "@sentry/nextjs"; -import type { NextConfig } from "next"; import withSerwistInit from "@serwist/next"; +import type { NextConfig } from "next"; if (process.env.NODE_ENV === "production") { process.env.SERWIST_SUPPRESS_TURBOPACK_WARNING = "1"; @@ -28,7 +28,9 @@ const withSerwist = withSerwistInit({ // AND // 2. The dev SW flag is NOT set to true // This ensures production builds ALWAYS generate the service worker - disable: process.env.NODE_ENV !== "production" && process.env.NEXT_PUBLIC_ENABLE_SW_IN_DEV !== "true", + disable: + process.env.NODE_ENV !== "production" && + process.env.NEXT_PUBLIC_ENABLE_SW_IN_DEV !== "true", // Must be false: caching navigation (document) responses breaks Next.js streaming SSR. // All protected pages use `export const dynamic = 'force-dynamic'`. When this is true, // Serwist wraps the response in a NetworkFirst/StaleWhileRevalidate strategy that buffers @@ -42,9 +44,9 @@ const withSerwist = withSerwistInit({ // Allowing both production and development hostnames ensures images work across environments. const allowedImageHostnames = (() => { const hosts = [ - "lh3.googleusercontent.com", // Google + "lh3.googleusercontent.com", // Google "avatars.githubusercontent.com", // GitHub - "secure.gravatar.com", // Gravatar + "secure.gravatar.com", // Gravatar ]; const envUrls = [ @@ -67,8 +69,8 @@ const allowedImageHostnames = (() => { if (!envUrls.some(Boolean)) { throw new Error( - '[next.config.ts] At least one Supabase URL or Supabase Proxy URL ' + - 'is required at build time for images.remotePatterns.' + "[next.config.ts] At least one Supabase URL or Supabase Proxy URL " + + "is required at build time for images.remotePatterns.", ); } @@ -88,7 +90,7 @@ const nextConfig = { // regardless of this setting. productionBrowserSourceMaps: true, - async headers() { + headers() { // 1. Define headers common to all environments const headersList = [ { @@ -126,7 +128,7 @@ const nextConfig = { ]; // 2. Only add HSTS in Production to prevent local SSL errors - if (process.env.NODE_ENV === 'production') { + if (process.env.NODE_ENV === "production") { // 2-year max-age (63072000 seconds = 2 years) satisfies Lighthouse "max-age too low" audit (minimum recommended: 63072000). // preload qualifies the domain for HSTS preload lists (https://hstspreload.org). headersList.push({ @@ -191,36 +193,39 @@ const nextConfig = { experimental: { optimizePackageImports: [ - 'lucide-react', - 'date-fns', - 'framer-motion', - 'recharts', - '@radix-ui/react-alert-dialog', - '@radix-ui/react-avatar', - '@radix-ui/react-checkbox', - '@radix-ui/react-dialog', - '@radix-ui/react-dropdown-menu', - '@radix-ui/react-label', - '@radix-ui/react-popover', - '@radix-ui/react-progress', - '@radix-ui/react-radio-group', - '@radix-ui/react-scroll-area', - '@radix-ui/react-select', - '@radix-ui/react-separator', - '@radix-ui/react-slot', - '@radix-ui/react-switch', - '@radix-ui/react-tabs', + "lucide-react", + "date-fns", + "framer-motion", + "recharts", + "@radix-ui/react-alert-dialog", + "@radix-ui/react-avatar", + "@radix-ui/react-checkbox", + "@radix-ui/react-dialog", + "@radix-ui/react-dropdown-menu", + "@radix-ui/react-label", + "@radix-ui/react-popover", + "@radix-ui/react-progress", + "@radix-ui/react-radio-group", + "@radix-ui/react-scroll-area", + "@radix-ui/react-select", + "@radix-ui/react-separator", + "@radix-ui/react-slot", + "@radix-ui/react-switch", + "@radix-ui/react-tabs", ], }, // Performance: Minimize JavaScript bundle compiler: { - removeConsole: process.env.NODE_ENV === 'production' ? { - exclude: ['error', 'warn'], // Preserve console.error and console.warn; strip log/info from production - } : false, + removeConsole: + process.env.NODE_ENV === "production" + ? { + exclude: ["error", "warn"], // Preserve console.error and console.warn; strip log/info from production + } + : false, }, - - generateBuildId: async () => { + + generateBuildId: () => { // Prefer the commit SHA injected by CI/CD for stable, traceable build IDs. // Fall back to a random UUID so that two builds without APP_COMMIT_SHA still get // different IDs โ€” preventing Next.js static-asset cache collisions across deployments. @@ -232,26 +237,28 @@ const nextConfig = { }, images: { - formats: ['image/avif', 'image/webp'], + formats: ["image/avif", "image/webp"], remotePatterns: [ ...allowedImageHostnames.map((hostname: string) => { - const isSupabase = hostname.includes('supabase'); + const isSupabase = hostname.includes("supabase"); return { - protocol: 'https' as const, + protocol: "https" as const, hostname, - port: '', + port: "", // Supabase storage is strictly nested under /storage/v1/object/public/ // while OAuth providers (Google, GitHub) serve images from various root paths. - pathname: isSupabase ? '/storage/v1/object/public/**' : '/**', + pathname: isSupabase ? "/storage/v1/object/public/**" : "/**", }; }), ], }, // eslint-disable-next-line sonarjs/no-hardcoded-ip - allowedDevOrigins: ['192.168.0.103'] + allowedDevOrigins: ["192.168.0.103"], } satisfies NextConfig; -const sentryCompatibleConfig = withSerwist(nextConfig) as Parameters[0]; +const sentryCompatibleConfig = withSerwist(nextConfig) as Parameters< + typeof withSentryConfig +>[0]; const sentryPluginOptions = { org: process.env.SENTRY_ORG, @@ -289,7 +296,7 @@ const sentryPluginOptions = { }, widenClientFileUpload: true, - tunnelRoute: "/monitoring" + tunnelRoute: "/monitoring", } satisfies Parameters[1]; -export default withSentryConfig(sentryCompatibleConfig, sentryPluginOptions); \ No newline at end of file +export default withSentryConfig(sentryCompatibleConfig, sentryPluginOptions); diff --git a/package-lock.json b/package-lock.json index 22fb013a..64beb1c9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,114 +1,114 @@ { "name": "ghostclass", - "version": "4.4.9", + "version": "4.5.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "ghostclass", - "version": "4.4.9", - "dependencies": { - "@hookform/resolvers": "^5.2.2", - "@radix-ui/react-alert-dialog": "^1.1.15", - "@radix-ui/react-avatar": "^1.1.11", - "@radix-ui/react-checkbox": "^1.3.3", - "@radix-ui/react-dialog": "^1.1.15", - "@radix-ui/react-dropdown-menu": "^2.1.16", - "@radix-ui/react-label": "^2.1.8", - "@radix-ui/react-popover": "^1.1.15", - "@radix-ui/react-progress": "^1.1.8", - "@radix-ui/react-radio-group": "^1.3.8", - "@radix-ui/react-scroll-area": "^1.2.10", - "@radix-ui/react-select": "^2.2.6", - "@radix-ui/react-separator": "^1.1.8", - "@radix-ui/react-slot": "^1.2.4", - "@radix-ui/react-switch": "^1.2.6", - "@radix-ui/react-tabs": "^1.1.13", - "@scalar/nextjs-api-reference": "^0.10.0", - "@sentry/nextjs": "^10.41.0", - "@serwist/next": "^9.5.6", - "@supabase/ssr": "^0.10.2", - "@supabase/supabase-js": "^2.97.0", - "@tanstack/react-query": "^5.100.13", - "@tanstack/react-virtual": "^3.13.21", + "version": "4.5.0", + "dependencies": { + "@hookform/resolvers": "^5.5.7", + "@radix-ui/react-alert-dialog": "^1.1.23", + "@radix-ui/react-avatar": "^1.2.6", + "@radix-ui/react-checkbox": "^1.3.11", + "@radix-ui/react-dialog": "^1.1.23", + "@radix-ui/react-dropdown-menu": "^2.1.24", + "@radix-ui/react-label": "^2.1.15", + "@radix-ui/react-popover": "^1.1.23", + "@radix-ui/react-progress": "^1.1.16", + "@radix-ui/react-radio-group": "^1.4.7", + "@radix-ui/react-scroll-area": "^1.2.18", + "@radix-ui/react-select": "^2.3.7", + "@radix-ui/react-separator": "^1.1.15", + "@radix-ui/react-slot": "^1.3.3", + "@radix-ui/react-switch": "^1.3.7", + "@radix-ui/react-tabs": "^1.1.21", + "@scalar/nextjs-api-reference": "^0.11.12", + "@sentry/nextjs": "^10.69.0", + "@serwist/next": "^9.5.12", + "@supabase/ssr": "^0.12.4", + "@supabase/supabase-js": "^2.111.0", + "@tanstack/react-query": "^5.101.4", + "@tanstack/react-virtual": "^3.14.9", "@upstash/ratelimit": "^2.0.8", - "@upstash/redis": "^1.36.2", - "axios": "^1.13.5", + "@upstash/redis": "^1.38.1", + "axios": "^1.19.0", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", - "date-fns": "^4.1.0", - "firebase-admin": "^13.8.0", - "framer-motion": "^12.34.3", + "date-fns": "^4.4.0", + "firebase-admin": "^14.2.0", + "framer-motion": "^12.43.0", "googleapis": "^173.0.0", - "jose": "^6.2.2", + "jose": "^6.2.5", "ldrs": "^1.1.9", - "lodash-es": "^4.17.23", - "lru-cache": "^11.2.6", - "lucide-react": "^1.16.0", - "next": "^16.1.6", + "lodash-es": "^4.18.1", + "lru-cache": "^11.5.2", + "lucide-react": "^1.28.0", + "next": "^16.2.12", "nextjs-toploader": "^3.9.17", "node-domexception": "^2.0.2", - "react": "^19.2.4", - "react-day-picker": "^10.0.0", - "react-dom": "^19.2.4", - "react-email": "^6.0.0", - "react-hook-form": "^7.71.2", - "react-is": "^19.2.5", + "react": "^19.2.8", + "react-day-picker": "^10.0.1", + "react-dom": "^19.2.8", + "react-email": "^6.9.1", + "react-hook-form": "^7.83.0", + "react-is": "^19.2.8", "react-markdown": "^10.1.0", "react-turnstile": "^1.1.5", - "recharts": "^3.7.0", - "resend": "^6.9.2", - "sanitize-html": "^2.17.0", + "recharts": "^3.10.1", + "resend": "^6.18.1", + "sanitize-html": "^2.17.6", "server-only": "^0.0.1", - "serwist": "^9.5.6", + "serwist": "^9.5.12", "sonner": "^2.0.7", "tailwind-merge": "^3.6.0", "tw-animate-css": "^1.4.0", - "uuid": "^14.0.0", - "zod": "^4.3.6" + "uuid": "^14.0.1", + "zod": "^4.4.3" }, "devDependencies": { - "@eslint/js": "^9.39.4", - "@opentelemetry/context-async-hooks": "^2.6.0", - "@playwright/test": "^1.59.1", + "@eslint/js": "^9.39.5", + "@opentelemetry/context-async-hooks": "^2.10.0", + "@playwright/test": "^1.62.1", "@tailwindcss/postcss": "^4", - "@testing-library/dom": "^10.4.0", - "@testing-library/jest-dom": "^6.9.1", + "@testing-library/dom": "^10.4.1", + "@testing-library/jest-dom": "^7.0.0", "@testing-library/react": "^16.3.2", "@testing-library/user-event": "^14.6.1", - "@types/node": "^25.3.5", + "@types/node": "^26.1.2", "@types/nprogress": "^0.2.3", - "@types/react": "^19.2.14", - "@types/react-dom": "^19.2.3", - "@types/sanitize-html": "^2.16.0", - "@typescript-eslint/parser": "^8.56.1", - "@vitejs/plugin-react": "^6.0.1", - "@vitest/coverage-v8": "^4.0.18", - "@vitest/ui": "^4.1.5", - "eslint": "^9.39.4", - "eslint-config-next": "^16.1.6", + "@types/react": "^19.2.18", + "@types/react-dom": "^19.2.4", + "@types/sanitize-html": "^2.16.1", + "@typescript-eslint/parser": "^8.65.0", + "@vitejs/plugin-react": "^6.0.5", + "@vitest/coverage-v8": "^4.1.10", + "@vitest/ui": "^4.1.10", + "eslint": "^9.39.5", + "eslint-config-next": "^16.2.12", "eslint-plugin-react": "^7.37.5", - "eslint-plugin-react-hooks": "^7.0.1", - "eslint-plugin-security": "^4.0.0", - "eslint-plugin-sonarjs": "^4.0.3", + "eslint-plugin-react-hooks": "^7.1.1", + "eslint-plugin-security": "^4.0.1", + "eslint-plugin-sonarjs": "^4.2.0", "eslint-plugin-unused-imports": "^4.4.1", "glob": "^13.0.6", - "globals": "^17.3.0", - "happy-dom": "^20.7.0", + "globals": "^17.8.0", + "happy-dom": "^20.11.1", "husky": "^9.1.7", - "jsdom": "^29.0.0", - "lint-staged": "^17.0.4", + "jsdom": "^30.0.1", + "lint-staged": "^17.3.0", "rimraf": "^6.1.3", - "source-map": "^0.7.6", - "supabase": "^2.76.14", + "source-map": "^0.8.0", + "supabase": "^2.111.0", "tailwindcss": "^4", "typescript": "^6.0.3", - "typescript-eslint": "^8.56.1", - "vitest": "^4.1.5" + "typescript-eslint": "^8.65.0", + "vitest": "^4.1.10" }, "engines": { "node": ">=22.12.0", - "npm": ">=11" + "npm": ">=12" } }, "node_modules/@adobe/css-tools": { @@ -131,57 +131,82 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@apm-js-collab/code-transformer": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/@apm-js-collab/code-transformer/-/code-transformer-0.18.1.tgz", + "integrity": "sha512-u1Hb6bHjWtkSpiprwVP6YaHC1DTN4RAU3zYkUDUe7WMnJwdyU1pwTL9dFKiSJB9IiLue/EQovmyx6xhU7FFtAQ==", + "license": "Apache-2.0", + "dependencies": { + "@types/estree": "^1.0.8", + "astring": "^1.9.0", + "esquery": "^1.7.0", + "meriyah": "^6.1.4", + "semifies": "^1.0.0", + "source-map": "^0.6.0" + }, + "bin": { + "code-transformer": "cli.js" + } + }, + "node_modules/@apm-js-collab/code-transformer-bundler-plugins": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/@apm-js-collab/code-transformer-bundler-plugins/-/code-transformer-bundler-plugins-0.7.3.tgz", + "integrity": "sha512-qNbPwuMZ8f5ZuGj/ttPeB7a6C/S1bB6tNYaEL5vNiRKydSAxa4AU0gxCWgaP4fVju+AuwhcumSFjrEcGF9Dv7Q==", + "license": "MIT", + "dependencies": { + "@apm-js-collab/code-transformer": "^0.18.0", + "es-module-lexer": "^2.1.0", + "magic-string": "^0.30.21", + "module-details-from-path": "^1.0.4" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@apm-js-collab/tracing-hooks": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@apm-js-collab/tracing-hooks/-/tracing-hooks-0.13.0.tgz", + "integrity": "sha512-mTvWz9rnQwx1U3h0XPTHaX7bgfkpipLLTQyjlC2cdhQpQEuoLT0AGzoydeoq2NxfEVv6fWOOETcSbb2nptleyw==", + "license": "Apache-2.0", + "dependencies": { + "@apm-js-collab/code-transformer": "^0.18.0", + "debug": "^4.4.1", + "module-details-from-path": "^1.0.4" + } + }, "node_modules/@asamuzakjp/css-color": { - "version": "5.1.11", - "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-5.1.11.tgz", - "integrity": "sha512-KVw6qIiCTUQhByfTd78h2yD1/00waTmm9uy/R7Ck/ctUyAPj+AEDLkQIdJW0T8+qGgj3j5bpNKK7Q3G+LedJWg==", + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-6.0.5.tgz", + "integrity": "sha512-mbhpPMmnw/kwW19aRNmSUl1QzLbdGo1SCuE49BT98MNwqF6zaHb3o2owssFc/PEO/4t2UjqtCNwocuDtJornzA==", "dev": true, "license": "MIT", "dependencies": { - "@asamuzakjp/generational-cache": "^1.0.1", - "@csstools/css-calc": "^3.2.0", - "@csstools/css-color-parser": "^4.1.0", + "@csstools/css-calc": "^3.2.1", + "@csstools/css-color-parser": "^4.1.9", "@csstools/css-parser-algorithms": "^4.0.0", - "@csstools/css-tokenizer": "^4.0.0" + "@csstools/css-tokenizer": "^4.0.0", + "lru-cache": "^11.5.2" }, "engines": { - "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + "node": "^22.13.0 || >=24.0.0" } }, "node_modules/@asamuzakjp/dom-selector": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@asamuzakjp/dom-selector/-/dom-selector-7.1.1.tgz", - "integrity": "sha512-67RZDnYRc8H/8MLDgQCDE//zoqVFwajkepHZgmXrbwybzXOEwOWGPYGmALYl9J2DOLfFPPs6kKCqmbzV895hTQ==", + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/@asamuzakjp/dom-selector/-/dom-selector-8.3.0.tgz", + "integrity": "sha512-UJLfKXBhrc8i1vH2eJXuYQMwlsLKWFw3O+CPqXSuVEiikeAim3UgrfWX0k4tA/X8cRFM8iZ7OaqBokFGbYusdg==", "dev": true, "license": "MIT", "dependencies": { - "@asamuzakjp/generational-cache": "^1.0.1", - "@asamuzakjp/nwsapi": "^2.3.9", "bidi-js": "^1.0.3", "css-tree": "^3.2.1", - "is-potential-custom-element-name": "^1.0.1" + "is-potential-custom-element-name": "^1.0.1", + "lru-cache": "^11.5.2" }, "engines": { - "node": "^20.19.0 || ^22.12.0 || >=24.0.0" - } - }, - "node_modules/@asamuzakjp/generational-cache": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@asamuzakjp/generational-cache/-/generational-cache-1.0.1.tgz", - "integrity": "sha512-wajfB8KqzMCN2KGNFdLkReeHncd0AslUSrvHVvvYWuU8ghncRJoA50kT3zP9MVL0+9g4/67H+cdvBskj9THPzg==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + "node": "^22.13.0 || >=24.0.0" } }, - "node_modules/@asamuzakjp/nwsapi": { - "version": "2.3.9", - "resolved": "https://registry.npmjs.org/@asamuzakjp/nwsapi/-/nwsapi-2.3.9.tgz", - "integrity": "sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q==", - "dev": true, - "license": "MIT" - }, "node_modules/@babel/code-frame": { "version": "7.29.7", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", @@ -236,13 +261,13 @@ } }, "node_modules/@babel/generator": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.7.tgz", - "integrity": "sha512-DkXD5OJQaAQIdZ1bt3UZdEnHAn9Imd3IVBdX03UFe+ony9Ojw5pzr9YVKGDY1jt+Gcn/FnGkNf8r+Vj5NOJWtQ==", + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.8.tgz", + "integrity": "sha512-gZbepsdh3WDtgZKWL+vTPh71LSBrm/Y4/QDZBVCcYfmeTEEuoOYwlSy+G1StfJg+/Zy550u/3TATbm7qDbbMtg==", "license": "MIT", "dependencies": { - "@babel/parser": "^7.29.7", - "@babel/types": "^7.29.7", + "@babel/parser": "^7.29.8", + "@babel/types": "^7.29.8", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" @@ -356,12 +381,12 @@ } }, "node_modules/@babel/parser": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.7.tgz", - "integrity": "sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==", + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.8.tgz", + "integrity": "sha512-E8lTAYNB1KW+FH+VGJuZM1ioAx2E6oVlvQFRrf5P8ZZmsiJXYAD9vTFV7yyEURNzgh1dFqMZuO6tUwcARbqFCA==", "license": "MIT", "dependencies": { - "@babel/types": "^7.29.7" + "@babel/types": "^7.29.8" }, "bin": { "parser": "bin/babel-parser.js" @@ -395,17 +420,17 @@ } }, "node_modules/@babel/traverse": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.7.tgz", - "integrity": "sha512-EhlfNQtZ+NK22w5BM61ciuiq1m58ed33Wr1Xan//ZRTy6hgjnwyCffRYwzsGXdASJSUJ1guZILsErh1eQcl+zw==", + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.8.tgz", + "integrity": "sha512-I5z7H3bf/41ktsNVLtpN0wAa336HkqIHQ5BuPLEhTkt1jVSyZpeNKIzTgEWmlxjdg81R0IgUCcaE+Ok3NvrfZg==", "license": "MIT", "dependencies": { "@babel/code-frame": "^7.29.7", - "@babel/generator": "^7.29.7", + "@babel/generator": "^7.29.8", "@babel/helper-globals": "^7.29.7", - "@babel/parser": "^7.29.7", + "@babel/parser": "^7.29.8", "@babel/template": "^7.29.7", - "@babel/types": "^7.29.7", + "@babel/types": "^7.29.8", "debug": "^4.3.1" }, "engines": { @@ -413,9 +438,9 @@ } }, "node_modules/@babel/types": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.7.tgz", - "integrity": "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==", + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.8.tgz", + "integrity": "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==", "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.29.7", @@ -449,9 +474,9 @@ } }, "node_modules/@csstools/color-helpers": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-6.0.2.tgz", - "integrity": "sha512-LMGQLS9EuADloEFkcTBR3BwV/CGHV7zyDxVRtVDTwdI2Ca4it0CCVTT9wCkxSgokjE5Ho41hEPgb8OEUwoXr6Q==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-6.1.0.tgz", + "integrity": "sha512-064IFJdjTfUqnjpCVpMOdbr8FLQBhinbZj6yRv2An2E41O/pLEXqfFRWqGq/SxlE5PEUYTlvWsG2r8MswAVvkg==", "dev": true, "funding": [ { @@ -469,9 +494,9 @@ } }, "node_modules/@csstools/css-calc": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-3.2.1.tgz", - "integrity": "sha512-DtdHlgXh5ZkA43cwBcAm+huzgJiwx3ZTWVjBs94kwz2xKqSimDA3lBgCjphYgwgVUMWatSM0pDd8TILB1yrVVg==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-3.3.0.tgz", + "integrity": "sha512-c5ihYsPkdG6JCkU2zTMm4+k6r7RXuGxtWYhu5DHMIiF1FHzrfmHL5so11AoFpUv/tu61xfcmT4AmKoFfMPoqdQ==", "dev": true, "funding": [ { @@ -493,9 +518,9 @@ } }, "node_modules/@csstools/css-color-parser": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-4.1.1.tgz", - "integrity": "sha512-eZ5XOtyhK+mggRafYUWzA0tvaYOFgdY8AkgQiCJF9qNAePnUo/zmsqqYubBBb3sQ8uNUaSKTY9s9klfRaAXL0g==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-4.1.10.tgz", + "integrity": "sha512-UZhQLIUyJaaMepqehrCODwCg2KW25vFvLWBmqYFaPclYvvxzj/sG8LBOhBFCp11i9uE7t1EyS+RAoV9tztPFyw==", "dev": true, "funding": [ { @@ -509,8 +534,8 @@ ], "license": "MIT", "dependencies": { - "@csstools/color-helpers": "^6.0.2", - "@csstools/css-calc": "^3.2.1" + "@csstools/color-helpers": "^6.1.0", + "@csstools/css-calc": "^3.3.0" }, "engines": { "node": ">=20.19.0" @@ -544,9 +569,9 @@ } }, "node_modules/@csstools/css-syntax-patches-for-csstree": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.1.4.tgz", - "integrity": "sha512-wgsqt92b7C7tQhIdPNxj0n9zuUbQlvAuI1exyzeNrOKOi62SD7ren8zqszmpVREjAOqg8cD2FqYhQfAuKjk4sw==", + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.1.7.tgz", + "integrity": "sha512-fQ+05118eQS1cofO3aJpB5efgpBZMvIzwr/sbC8kDLVA5XLG8q1kJV5yzrUAI1f7lvhPnm8fgIjzFB8/O/5Dig==", "dev": true, "funding": [ { @@ -594,6 +619,21 @@ "integrity": "sha512-lwYN/vDPeNRULcepoE/LO2Pgx+7/RV+S9ARfbc9lr2DtGkOD7pAiruHvbR1RX3Qyf6ja47EWJDMsNK5vK08DJg==", "license": "MIT" }, + "node_modules/@ecies/ciphers": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/@ecies/ciphers/-/ciphers-0.2.6.tgz", + "integrity": "sha512-patgsRPKGkhhoBjETV4XxD0En4ui5fbX0hzayqI3M8tvNMGUoUvmyYAIWwlxBc1KX5cturfqByYdj5bYGRpN9g==", + "dev": true, + "license": "MIT", + "engines": { + "bun": ">=1", + "deno": ">=2.7.10", + "node": ">=16" + }, + "peerDependencies": { + "@noble/ciphers": "^1.0.0" + } + }, "node_modules/@emnapi/core": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz", @@ -607,9 +647,9 @@ } }, "node_modules/@emnapi/runtime": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz", - "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==", + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.3.tgz", + "integrity": "sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA==", "license": "MIT", "optional": true, "dependencies": { @@ -628,9 +668,9 @@ } }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.0.tgz", - "integrity": "sha512-lhRUCeuOyJQURhTxl4WkpFTjIsbDayJHih5kZC1giwE+MhIzAb7mEsQMqMf18rHLsrb5qI1tafG20mLxEWcWlA==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.1.tgz", + "integrity": "sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==", "cpu": [ "ppc64" ], @@ -644,9 +684,9 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.0.tgz", - "integrity": "sha512-wqh0ByljabXLKHeWXYLqoJ5jKC4XBaw6Hk08OfMrCRd2nP2ZQ5eleDZC41XHyCNgktBGYMbqnrJKq/K/lzPMSQ==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.1.tgz", + "integrity": "sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==", "cpu": [ "arm" ], @@ -660,9 +700,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.0.tgz", - "integrity": "sha512-+WzIXQOSaGs33tLEgYPYe/yQHf0WTU0X42Jca3y8NWMbUVhp7rUnw+vAsRC/QiDrdD31IszMrZy+qwPOPjd+rw==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.1.tgz", + "integrity": "sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==", "cpu": [ "arm64" ], @@ -676,9 +716,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.0.tgz", - "integrity": "sha512-+VJggoaKhk2VNNqVL7f6S189UzShHC/mR9EE8rDdSkdpN0KflSwWY/gWjDrNxxisg8Fp1ZCD9jLMo4m0OUfeUA==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.1.tgz", + "integrity": "sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==", "cpu": [ "x64" ], @@ -692,9 +732,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.0.tgz", - "integrity": "sha512-0T+A9WZm+bZ84nZBtk1ckYsOvyA3x7e2Acj1KdVfV4/2tdG4fzUp91YHx+GArWLtwqp77pBXVCPn2We7Letr0Q==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.1.tgz", + "integrity": "sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==", "cpu": [ "arm64" ], @@ -708,9 +748,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.0.tgz", - "integrity": "sha512-fyzLm/DLDl/84OCfp2f/XQ4flmORsjU7VKt8HLjvIXChJoFFOIL6pLJPH4Yhd1n1gGFF9mPwtlN5Wf82DZs+LQ==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.1.tgz", + "integrity": "sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==", "cpu": [ "x64" ], @@ -724,9 +764,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.0.tgz", - "integrity": "sha512-l9GeW5UZBT9k9brBYI+0WDffcRxgHQD8ShN2Ur4xWq/NFzUKm3k5lsH4PdaRgb2w7mI9u61nr2gI2mLI27Nh3Q==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.1.tgz", + "integrity": "sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==", "cpu": [ "arm64" ], @@ -740,9 +780,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.0.tgz", - "integrity": "sha512-BXoQai/A0wPO6Es3yFJ7APCiKGc1tdAEOgeTNy3SsB491S3aHn4S4r3e976eUnPdU+NbdtmBuLncYir2tMU9Nw==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.1.tgz", + "integrity": "sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==", "cpu": [ "x64" ], @@ -756,9 +796,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.0.tgz", - "integrity": "sha512-CjaaREJagqJp7iTaNQjjidaNbCKYcd4IDkzbwwxtSvjI7NZm79qiHc8HqciMddQ6CKvJT6aBd8lO9kN/ZudLlw==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.1.tgz", + "integrity": "sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==", "cpu": [ "arm" ], @@ -772,9 +812,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.0.tgz", - "integrity": "sha512-RVyzfb3FWsGA55n6WY0MEIEPURL1FcbhFE6BffZEMEekfCzCIMtB5yyDcFnVbTnwk+CLAgTujmV/Lgvih56W+A==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.1.tgz", + "integrity": "sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==", "cpu": [ "arm64" ], @@ -788,9 +828,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.0.tgz", - "integrity": "sha512-KBnSTt1kxl9x70q+ydterVdl+Cn0H18ngRMRCEQfrbqdUuntQQ0LoMZv47uB97NljZFzY6HcfqEZ2SAyIUTQBQ==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.1.tgz", + "integrity": "sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==", "cpu": [ "ia32" ], @@ -804,9 +844,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.0.tgz", - "integrity": "sha512-zpSlUce1mnxzgBADvxKXX5sl8aYQHo2ezvMNI8I0lbblJtp8V4odlm3Yzlj7gPyt3T8ReksE6bK+pT3WD+aJRg==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.1.tgz", + "integrity": "sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==", "cpu": [ "loong64" ], @@ -820,9 +860,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.0.tgz", - "integrity": "sha512-2jIfP6mmjkdmeTlsX/9vmdmhBmKADrWqN7zcdtHIeNSCH1SqIoNI63cYsjQR8J+wGa4Y5izRcSHSm8K3QWmk3w==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.1.tgz", + "integrity": "sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==", "cpu": [ "mips64el" ], @@ -836,9 +876,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.0.tgz", - "integrity": "sha512-bc0FE9wWeC0WBm49IQMPSPILRocGTQt3j5KPCA8os6VprfuJ7KD+5PzESSrJ6GmPIPJK965ZJHTUlSA6GNYEhg==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.1.tgz", + "integrity": "sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==", "cpu": [ "ppc64" ], @@ -852,9 +892,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.0.tgz", - "integrity": "sha512-SQPZOwoTTT/HXFXQJG/vBX8sOFagGqvZyXcgLA3NhIqcBv1BJU1d46c0rGcrij2B56Z2rNiSLaZOYW5cUk7yLQ==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.1.tgz", + "integrity": "sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==", "cpu": [ "riscv64" ], @@ -868,9 +908,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.0.tgz", - "integrity": "sha512-SCfR0HN8CEEjnYnySJTd2cw0k9OHB/YFzt5zgJEwa+wL/T/raGWYMBqwDNAC6dqFKmJYZoQBRfHjgwLHGSrn3Q==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.1.tgz", + "integrity": "sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==", "cpu": [ "s390x" ], @@ -884,9 +924,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.0.tgz", - "integrity": "sha512-us0dSb9iFxIi8srnpl931Nvs65it/Jd2a2K3qs7fz2WfGPHqzfzZTfec7oxZJRNPXPnNYZtanmRc4AL/JwVzHQ==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.1.tgz", + "integrity": "sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==", "cpu": [ "x64" ], @@ -900,9 +940,9 @@ } }, "node_modules/@esbuild/netbsd-arm64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.0.tgz", - "integrity": "sha512-CR/RYotgtCKwtftMwJlUU7xCVNg3lMYZ0RzTmAHSfLCXw3NtZtNpswLEj/Kkf6kEL3Gw+BpOekRX0BYCtklhUw==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.1.tgz", + "integrity": "sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==", "cpu": [ "arm64" ], @@ -916,9 +956,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.0.tgz", - "integrity": "sha512-nU1yhmYutL+fQ71Kxnhg8uEOdC0pwEW9entHykTgEbna2pw2dkbFSMeqjjyHZoCmt8SBkOSvV+yNmm94aUrrqw==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.1.tgz", + "integrity": "sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==", "cpu": [ "x64" ], @@ -932,9 +972,9 @@ } }, "node_modules/@esbuild/openbsd-arm64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.0.tgz", - "integrity": "sha512-cXb5vApOsRsxsEl4mcZ1XY3D4DzcoMxR/nnc4IyqYs0rTI8ZKmW6kyyg+11Z8yvgMfAEldKzP7AdP64HnSC/6g==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.1.tgz", + "integrity": "sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==", "cpu": [ "arm64" ], @@ -948,9 +988,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.0.tgz", - "integrity": "sha512-8wZM2qqtv9UP3mzy7HiGYNH/zjTA355mpeuA+859TyR+e+Tc08IHYpLJuMsfpDJwoLo1ikIJI8jC3GFjnRClzA==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.1.tgz", + "integrity": "sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==", "cpu": [ "x64" ], @@ -964,9 +1004,9 @@ } }, "node_modules/@esbuild/openharmony-arm64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.0.tgz", - "integrity": "sha512-FLGfyizszcef5C3YtoyQDACyg95+dndv79i2EekILBofh5wpCa1KuBqOWKrEHZg3zrL3t5ouE5jgr94vA+Wb2w==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.1.tgz", + "integrity": "sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==", "cpu": [ "arm64" ], @@ -980,9 +1020,9 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.0.tgz", - "integrity": "sha512-1ZgjUoEdHZZl/YlV76TSCz9Hqj9h9YmMGAgAPYd+q4SicWNX3G5GCyx9uhQWSLcbvPW8Ni7lj4gDa1T40akdlw==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.1.tgz", + "integrity": "sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==", "cpu": [ "x64" ], @@ -996,9 +1036,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.0.tgz", - "integrity": "sha512-Q9StnDmQ/enxnpxCCLSg0oo4+34B9TdXpuyPeTedN/6+iXBJ4J+zwfQI28u/Jl40nOYAxGoNi7mFP40RUtkmUA==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.1.tgz", + "integrity": "sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==", "cpu": [ "arm64" ], @@ -1012,9 +1052,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.0.tgz", - "integrity": "sha512-zF3ag/gfiCe6U2iczcRzSYJKH1DCI+ByzSENHlM2FcDbEeo5Zd2C86Aq0tKUYAJJ1obRP84ymxIAksZUcdztHA==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.1.tgz", + "integrity": "sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==", "cpu": [ "ia32" ], @@ -1028,9 +1068,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.0.tgz", - "integrity": "sha512-pEl1bO9mfAmIC+tW5btTmrKaujg3zGtUmWNdCw/xs70FBjwAL3o9OEKNHvNmnyylD6ubxUERiEhdsL0xBQ9efw==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.1.tgz", + "integrity": "sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==", "cpu": [ "x64" ], @@ -1044,9 +1084,9 @@ } }, "node_modules/@eslint-community/eslint-utils": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", - "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.10.1.tgz", + "integrity": "sha512-cuadcxVFE8sDK6iWJbs8Sn0av2Nrh2QSGQhVlBW9AaAHqHwjWsZHT8LJ4hFGPh7ASBV2deFdM7H/DPjulmh8rg==", "dev": true, "license": "MIT", "dependencies": { @@ -1127,9 +1167,9 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "3.3.5", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.5.tgz", - "integrity": "sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg==", + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.6.tgz", + "integrity": "sha512-l2Ul9PrHsPCKcEY/ac7VgFj9D80C7S68sOKc618SyHDPK36s1XcFebXY0iTzUVn4Yq+YbwvSnDmCz9yxjX+QrA==", "dev": true, "license": "MIT", "dependencies": { @@ -1139,7 +1179,7 @@ "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", - "js-yaml": "^4.1.1", + "js-yaml": "^4.3.0", "minimatch": "^3.1.5", "strip-json-comments": "^3.1.1" }, @@ -1150,6 +1190,23 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/@eslint/eslintrc/node_modules/ajv": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, "node_modules/@eslint/eslintrc/node_modules/globals": { "version": "14.0.0", "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", @@ -1163,10 +1220,17 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, "node_modules/@eslint/js": { - "version": "9.39.4", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.4.tgz", - "integrity": "sha512-nE7DEIchvtiFTwBw4Lfbu59PG+kCofhjsKaCWzxTpt4lfRjRMqG6uMBzKXuEcyXhOHoUp9riAm7/aWYGhXZ9cw==", + "version": "9.39.5", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.5.tgz", + "integrity": "sha512-QywQuszQh77pIXCsq998c8hbhSTI/azTty1Z6N53dmAudKHhy573j3yvRLsX2BSp8YpLtoCEG8E9DJe+8zUh4A==", "dev": true, "license": "MIT", "engines": { @@ -1246,12 +1310,12 @@ "license": "Apache-2.0" }, "node_modules/@firebase/component": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.7.3.tgz", - "integrity": "sha512-wFofIaa2879ogD/WvkjYXJxRmfnL0scen6ORgaC3na1FNOR9ASIUANQdhqQcmWu/h77/pVHY7ch5flewa5Bcew==", + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.7.4.tgz", + "integrity": "sha512-tLpOaaCol9ugUIYp2R3CbWPPA8Ajg/papX/XHEy8U52b/QXH3BbX8tTJX9aShDCjp+9sMAxMLD94i7lresdugQ==", "license": "Apache-2.0", "dependencies": { - "@firebase/util": "1.15.1", + "@firebase/util": "1.15.2", "tslib": "^2.1.0" }, "engines": { @@ -1259,16 +1323,16 @@ } }, "node_modules/@firebase/database": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@firebase/database/-/database-1.1.3.tgz", - "integrity": "sha512-XwWCa+E4TvNGpGwXrycLRNfdogADwFcvuhyow6wDWma9W54roaQIhe+4PM0KiLsIftBdSCGI7OKCXrdSRHbIhw==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@firebase/database/-/database-1.1.4.tgz", + "integrity": "sha512-D+j4+8uhGtNd1tVD+X+c8JrC4ppStGJKyujSQt2NPwdN26QcCk0BeIxue+UqspHkHiFHyQOimwlzjLewGq6S+A==", "license": "Apache-2.0", "dependencies": { "@firebase/app-check-interop-types": "0.3.4", "@firebase/auth-interop-types": "0.2.5", - "@firebase/component": "0.7.3", + "@firebase/component": "0.7.4", "@firebase/logger": "0.5.1", - "@firebase/util": "1.15.1", + "@firebase/util": "1.15.2", "faye-websocket": "0.11.4", "tslib": "^2.1.0" }, @@ -1277,30 +1341,42 @@ } }, "node_modules/@firebase/database-compat": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-2.1.4.tgz", - "integrity": "sha512-3pK35F1MAgmqFJQlf2nhQl44vtAXQO1uaCaQOEUI9kCRtLFqi7N+QRKR7lFZPg+xIZIyubgxQaxY69YgfZRZWg==", + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-2.1.5.tgz", + "integrity": "sha512-m2KZDNXrg8DBzXWQNbbrjOhsJnM+ctsSFaDYKrqj1gEetQ8BSAwRuMUdeWLM9a6qPBgOvOA+o09j1BSEzdFqOg==", "license": "Apache-2.0", "dependencies": { - "@firebase/component": "0.7.3", - "@firebase/database": "1.1.3", - "@firebase/database-types": "1.0.20", + "@firebase/component": "0.7.4", + "@firebase/database": "1.1.4", + "@firebase/database-types": "1.0.21", "@firebase/logger": "0.5.1", - "@firebase/util": "1.15.1", + "@firebase/util": "1.15.2", "tslib": "^2.1.0" }, "engines": { "node": ">=20.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x", + "@firebase/app-compat": "0.x" + }, + "peerDependenciesMeta": { + "@firebase/app": { + "optional": true + }, + "@firebase/app-compat": { + "optional": true + } } }, "node_modules/@firebase/database-types": { - "version": "1.0.20", - "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-1.0.20.tgz", - "integrity": "sha512-kegbOk/w8iU64pr0q6k2ItyNGjnQBMHFhwS7ohdWI4W+pc0/zhhdGXTdFj6X1oxItRjPoYOsSQmERgBkn/ihxw==", + "version": "1.0.21", + "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-1.0.21.tgz", + "integrity": "sha512-SX1jUqhttKgg/m9dYRTvqU9QvucBooziWfA986r4cpsbi4zlsvewe424j3Vpduwd6DG1MSAMfBVT2VqA61FnkA==", "license": "Apache-2.0", "dependencies": { "@firebase/app-types": "0.9.5", - "@firebase/util": "1.15.1" + "@firebase/util": "1.15.2" } }, "node_modules/@firebase/logger": { @@ -1316,9 +1392,9 @@ } }, "node_modules/@firebase/util": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.15.1.tgz", - "integrity": "sha512-LUdM4Wg7YM9Pq/49nGYySJA0CSQEKnGffFzWV8+6gXN7mGxn+FL1IqvFbuZUtAQcfZgHYDwCE1wwlK7rB7gl2g==", + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.15.2.tgz", + "integrity": "sha512-974pWIZVLDMc5GW5YAsj8y0XxULxIy/sPUy7tsxmWbF93KRIyh9xpuHlh0zDL+shUcf5nHDjFOg9YLiQ763eiA==", "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { @@ -1329,31 +1405,31 @@ } }, "node_modules/@floating-ui/core": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.5.tgz", - "integrity": "sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.8.0.tgz", + "integrity": "sha512-0CIZ5itps/8x7BG8dEIhs53BvCUH2PCoogtakwRTut+Arm58sJooJ0AuZhLw2HJYIR5cMLNPBSS728sPho2khQ==", "license": "MIT", "dependencies": { - "@floating-ui/utils": "^0.2.11" + "@floating-ui/utils": "^0.2.12" } }, "node_modules/@floating-ui/dom": { - "version": "1.7.6", - "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.6.tgz", - "integrity": "sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.8.0.tgz", + "integrity": "sha512-yXSrzeHZBTZadLOlfyhCkJHNeLJnHRnRInwdZ40L7ZiaAtrBwoYlsDrX3v5zB1Utk7CLfzcOVnVVWoXEky7Ceg==", "license": "MIT", "dependencies": { - "@floating-ui/core": "^1.7.5", - "@floating-ui/utils": "^0.2.11" + "@floating-ui/core": "^1.8.0", + "@floating-ui/utils": "^0.2.12" } }, "node_modules/@floating-ui/react-dom": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.8.tgz", - "integrity": "sha512-cC52bHwM/n/CxS87FH0yWdngEZrjdtLW/qVruo68qg+prK7ZQ4YGdut2GyDVpoGeAYe/h899rVeOVm6Oi40k2A==", + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.9.tgz", + "integrity": "sha512-JDjEFGCpImxDCA7JJKviA0M9+RtmJdj0m/NVU5IMgBK+AmZouAQQ7/+2GLH0GXXY0YMw9oXPB8hKdbPYg5QLYg==", "license": "MIT", "dependencies": { - "@floating-ui/dom": "^1.7.6" + "@floating-ui/dom": "^1.8.0" }, "peerDependencies": { "react": ">=16.8.0", @@ -1361,26 +1437,26 @@ } }, "node_modules/@floating-ui/utils": { - "version": "0.2.11", - "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.11.tgz", - "integrity": "sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==", + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.12.tgz", + "integrity": "sha512-HpCo8tmWzLVad5s2d19EhAz5zqrrQ6s69qd6moPMQvkOuSwDT1YgRfWSVuc4ennqrgv3OHppiOGMQ7oC13yIww==", "license": "MIT" }, "node_modules/@google-cloud/firestore": { - "version": "7.11.6", - "resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-7.11.6.tgz", - "integrity": "sha512-EW/O8ktzwLfyWBOsNuhRoMi8lrC3clHM5LVFhGvO1HCsLozCOOXRAlHrYBoE6HL42Sc8yYMuCb2XqcnJ4OOEpw==", + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-8.7.0.tgz", + "integrity": "sha512-EvMpZQUXkTRdweSvOu6VL6EEQwHjHAgWz2UYZR+Mj6Ao52S+TWieHbSn15jiNnEw8F8RhbZj7IGXZ1PFB1eA+A==", "license": "Apache-2.0", "optional": true, "dependencies": { - "@opentelemetry/api": "^1.3.0", - "fast-deep-equal": "^3.1.1", + "@opentelemetry/api": "^1.9.0", + "fast-deep-equal": "^3.1.3", "functional-red-black-tree": "^1.0.1", - "google-gax": "^4.3.3", - "protobufjs": "^7.2.6" + "google-gax": "^5.0.1", + "protobufjs": "^7.5.3" }, "engines": { - "node": ">=14.0.0" + "node": ">=18" } }, "node_modules/@google-cloud/paginator": { @@ -1418,9 +1494,9 @@ } }, "node_modules/@google-cloud/storage": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-7.19.0.tgz", - "integrity": "sha512-n2FjE7NAOYyshogdc7KQOl/VZb4sneqPjWouSyia9CMDdMhRX5+RIbqalNmC7LOLzuLAN89VlF2HvG8na9G+zQ==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-7.21.0.tgz", + "integrity": "sha512-l+IFTkd+6Y5LoAuXyYCKNAKtw/Ci+rAMqgdTB1jv4iZiLhw0rtq+0qjIRbBizXkNzEFmXiXUW0H7sZQQvk1ffA==", "license": "Apache-2.0", "optional": true, "dependencies": { @@ -1437,8 +1513,7 @@ "mime": "^3.0.0", "p-limit": "^3.0.1", "retry-request": "^7.0.0", - "teeny-request": "^9.0.0", - "uuid": "^8.0.0" + "teeny-request": "^9.0.0" }, "engines": { "node": ">=14" @@ -1501,7 +1576,7 @@ "node": ">=12.10.0" } }, - "node_modules/@grpc/grpc-js/node_modules/@grpc/proto-loader": { + "node_modules/@grpc/proto-loader": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.8.1.tgz", "integrity": "sha512-wtF6h+DY6M3YaDBPAmvuuA6jV8Sif9MjtOI5euKFWRgCDl5PeDpPsHR9u2l6St5ceY8AZgoNDww5+HvEsXFsGg==", @@ -1520,35 +1595,114 @@ "node": ">=6" } }, - "node_modules/@grpc/proto-loader": { - "version": "0.7.15", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.15.tgz", - "integrity": "sha512-tMXdRCfYVixjuFK+Hk0Q1s38gV9zDiDJfWL3h1rv4Qc39oILCu1TRTDt7+fGUI8K4G1Fj125Hx/ru3azECWTyQ==", - "license": "Apache-2.0", - "optional": true, - "dependencies": { - "lodash.camelcase": "^4.3.0", - "long": "^5.0.0", - "protobufjs": "^7.2.5", - "yargs": "^17.7.2" - }, - "bin": { - "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/@hookform/resolvers": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@hookform/resolvers/-/resolvers-5.4.0.tgz", - "integrity": "sha512-EIsqr/t/qbinPIhGjMdtvutIN1Kk4uwbROE9/UQ93CAVGR7GkA7Y92+fX80OzXi/OB67jVFYwKGO1WzkxmkFZw==", + "version": "5.5.7", + "resolved": "https://registry.npmjs.org/@hookform/resolvers/-/resolvers-5.5.7.tgz", + "integrity": "sha512-CyPCYV8/KlXfEXLWj8HHHhVsR/IZ6Ckm3b/a4fWtO/lRnRK1huqncb8LlAWrmpPRsse5glF5aVuDRMHEr3UGag==", "license": "MIT", "dependencies": { "@standard-schema/utils": "^0.3.0" }, "peerDependencies": { - "react-hook-form": "^7.55.0" + "@sinclair/typebox": ">=0.25.24", + "@standard-schema/spec": "^1.0.0", + "@typeschema/main": ">=0.13.7", + "@vinejs/vine": "^2.0.0 || ^3.0.0", + "ajv": "^8.12.0", + "ajv-errors": "^3.0.0", + "ajv-formats": "^2.1.1", + "arktype": "^2.0.0", + "ata-validator": "^0.7.0", + "class-transformer": ">=0.4.0", + "class-validator": ">=0.12.0", + "computed-types": "^1.0.0", + "effect": "^3.10.3", + "fluentvalidation-ts": "^3.0.0", + "fp-ts": "^2.7.0", + "io-ts": "^2.0.0", + "joi": "^17.0.0", + "nope-validator": ">=0.12.0", + "react-hook-form": "^7.55.0", + "superstruct": ">=0.12.0", + "typanion": "^3.3.2", + "valibot": ">=0.31.0 || ^1.0.0-beta.4 || ^1.0.0-rc", + "vest": ">=3.0.0", + "yup": "^1.0.0", + "zod": "^3.25.0 || ^4.0.0" + }, + "peerDependenciesMeta": { + "@sinclair/typebox": { + "optional": true + }, + "@standard-schema/spec": { + "optional": true + }, + "@typeschema/main": { + "optional": true + }, + "@vinejs/vine": { + "optional": true + }, + "ajv": { + "optional": true + }, + "ajv-errors": { + "optional": true + }, + "ajv-formats": { + "optional": true + }, + "arktype": { + "optional": true + }, + "ata-validator": { + "optional": true + }, + "class-transformer": { + "optional": true + }, + "class-validator": { + "optional": true + }, + "computed-types": { + "optional": true + }, + "effect": { + "optional": true + }, + "fluentvalidation-ts": { + "optional": true + }, + "fp-ts": { + "optional": true + }, + "io-ts": { + "optional": true + }, + "joi": { + "optional": true + }, + "nope-validator": { + "optional": true + }, + "superstruct": { + "optional": true + }, + "typanion": { + "optional": true + }, + "valibot": { + "optional": true + }, + "vest": { + "optional": true + }, + "yup": { + "optional": true + }, + "zod": { + "optional": true + } } }, "node_modules/@humanfs/core": { @@ -1628,9 +1782,9 @@ } }, "node_modules/@img/sharp-darwin-arm64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.5.tgz", - "integrity": "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==", + "version": "0.35.3", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.35.3.tgz", + "integrity": "sha512-RMnFX7YQsMoh7lWfcM4NEHHymBX/rLuKNPVM84XE9ONPcaSCDgE7CHIHpSgPcO2xcRthgBy1HfNO319mwhIAkg==", "cpu": [ "arm64" ], @@ -1640,19 +1794,19 @@ "darwin" ], "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + "node": ">=20.9.0" }, "funding": { "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-darwin-arm64": "1.2.4" + "@img/sharp-libvips-darwin-arm64": "1.3.2" } }, "node_modules/@img/sharp-darwin-x64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.5.tgz", - "integrity": "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==", + "version": "0.35.3", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.35.3.tgz", + "integrity": "sha512-Xo+5uFBtLN0BKqieTxiFzFPQAUlBbbH5iBKyRX/z1JrbnYsHTfKJnUfL8+p2TPXr1pXqao4eeL4Rl144uDpK9w==", "cpu": [ "x64" ], @@ -1662,19 +1816,38 @@ "darwin" ], "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + "node": ">=20.9.0" }, "funding": { "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-darwin-x64": "1.2.4" + "@img/sharp-libvips-darwin-x64": "1.3.2" + } + }, + "node_modules/@img/sharp-freebsd-wasm32": { + "version": "0.35.3", + "resolved": "https://registry.npmjs.org/@img/sharp-freebsd-wasm32/-/sharp-freebsd-wasm32-0.35.3.tgz", + "integrity": "sha512-lUxcqWIj2wMQ9BrwNjngcr1gWUr5xgaGThBRqPPalIC2n67Cqj1uPh8NnA/ZhAg8hUbKl+kVHKwgUIwe6ZYPrg==", + "license": "Apache-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "dependencies": { + "@img/sharp-wasm32": "0.35.3" + }, + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" } }, "node_modules/@img/sharp-libvips-darwin-arm64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.4.tgz", - "integrity": "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.3.2.tgz", + "integrity": "sha512-9J6ypZFpQBj4YnePGoq/S38w6nz+vqg5WZLrLGY4YuSemdMq47GMLBPO42MzwdGwpg/agZ7xzZcFHa48xlywfg==", "cpu": [ "arm64" ], @@ -1688,9 +1861,9 @@ } }, "node_modules/@img/sharp-libvips-darwin-x64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.4.tgz", - "integrity": "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.3.2.tgz", + "integrity": "sha512-m2pW1n6cns9VaubNwsZ+c3CRYjxNQWgJ5gPlnL1nbBcpkBvFm6SCFN5o0psFHI8w9n11NKhFkeEDns98tiqbEw==", "cpu": [ "x64" ], @@ -1704,9 +1877,9 @@ } }, "node_modules/@img/sharp-libvips-linux-arm": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.4.tgz", - "integrity": "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.3.2.tgz", + "integrity": "sha512-1eMLzy92I4J6rmi4mAT8yC3HxOtniyGELlzGbNMLLeqe052ahFQ0h6LFq+lh5DsDIdYViIDst08abvSbcEdLXQ==", "cpu": [ "arm" ], @@ -1723,9 +1896,9 @@ } }, "node_modules/@img/sharp-libvips-linux-arm64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.4.tgz", - "integrity": "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.3.2.tgz", + "integrity": "sha512-dqVSFynCox4C/J8kT16V7SIFAns0IjgLwkvYT7p8LQVmJ5OS5b6tI9IGflxTeuBS//zXeFIUbwt5dwxyZ17cnA==", "cpu": [ "arm64" ], @@ -1742,9 +1915,9 @@ } }, "node_modules/@img/sharp-libvips-linux-ppc64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.4.tgz", - "integrity": "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.3.2.tgz", + "integrity": "sha512-3z0NHDxD6n5I9gc05U1eW1AyRm+Gznzq3naMrthPNqE6oYykcogW0l/jfpJdjYnuNl8R7yI9pNbE1XiUeyq0Aw==", "cpu": [ "ppc64" ], @@ -1761,9 +1934,9 @@ } }, "node_modules/@img/sharp-libvips-linux-riscv64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.2.4.tgz", - "integrity": "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.3.2.tgz", + "integrity": "sha512-bsb4rI+NldGOsXuej2r8OdSS8+zXDVaCWxyWrcv6kneTOlgAHtZABRzBBCwdsPiD90J4myNJuHpg6kA20ImW/w==", "cpu": [ "riscv64" ], @@ -1780,9 +1953,9 @@ } }, "node_modules/@img/sharp-libvips-linux-s390x": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.4.tgz", - "integrity": "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.3.2.tgz", + "integrity": "sha512-/ABshyj8gCpyIrNXnHn4LorDJ0HHm1VhXPBlxZ8zAtfVPAaSafXPGn+sUSIRiwaSBy0mmFjSjiXI5mkcwdChKQ==", "cpu": [ "s390x" ], @@ -1799,9 +1972,9 @@ } }, "node_modules/@img/sharp-libvips-linux-x64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.4.tgz", - "integrity": "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.3.2.tgz", + "integrity": "sha512-ITPEtgffGJ0S6G9dRyw/366tJQqFRcHWPHhC+Stpg3Z8AEMrDrTr2lhdz4f/Y/HMbRh//7Z5mBzEpVdi62Oc3w==", "cpu": [ "x64" ], @@ -1818,9 +1991,9 @@ } }, "node_modules/@img/sharp-libvips-linuxmusl-arm64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.4.tgz", - "integrity": "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.3.2.tgz", + "integrity": "sha512-zE9EdiUzUmg5mDT5a1rk5fYJ6GWPloTwWBYDS14naqHsL+EaMpDj1AWnpLgh3u0YCORv2Tt50wrcrpYqkP97Kw==", "cpu": [ "arm64" ], @@ -1837,9 +2010,9 @@ } }, "node_modules/@img/sharp-libvips-linuxmusl-x64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.4.tgz", - "integrity": "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.3.2.tgz", + "integrity": "sha512-m0lrLiUt+lBYnCFr8qV/65yMR4E/c7/wf78I5eKTdkEakFAlZ9QlzEM3QIhhAwVeUhLAHLcCq7a7Vszq/oFNZQ==", "cpu": [ "x64" ], @@ -1856,9 +2029,9 @@ } }, "node_modules/@img/sharp-linux-arm": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.5.tgz", - "integrity": "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==", + "version": "0.35.3", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.35.3.tgz", + "integrity": "sha512-affVWCTLooy8TSxbDx2qkzuDeaWLNVBA+P//FNBirHsXpP2fuBhk5AuboYUnrDnzoXes8GFjpTx0SBFOCRg+FA==", "cpu": [ "arm" ], @@ -1871,19 +2044,19 @@ "linux" ], "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + "node": ">=20.9.0" }, "funding": { "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-arm": "1.2.4" + "@img/sharp-libvips-linux-arm": "1.3.2" } }, "node_modules/@img/sharp-linux-arm64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.5.tgz", - "integrity": "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==", + "version": "0.35.3", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.35.3.tgz", + "integrity": "sha512-QgKDspHPnrU+GQ55XPhGwyhC8acLVOOSyAvo1oVfFmrIXLkDNmGWzAfDZ4xK8oSA1qBQrALcHX0G5UZni/SuFQ==", "cpu": [ "arm64" ], @@ -1896,19 +2069,19 @@ "linux" ], "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + "node": ">=20.9.0" }, "funding": { "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-arm64": "1.2.4" + "@img/sharp-libvips-linux-arm64": "1.3.2" } }, "node_modules/@img/sharp-linux-ppc64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.5.tgz", - "integrity": "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==", + "version": "0.35.3", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.35.3.tgz", + "integrity": "sha512-sMd8rDxmpLOwv/7N44klFjOD5DUO7FLdjiXDI0hoxYaf7Ar262dQIEkosE98bps+5HPLtp/EvNqeqQtOycP/IA==", "cpu": [ "ppc64" ], @@ -1921,19 +2094,19 @@ "linux" ], "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + "node": ">=20.9.0" }, "funding": { "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-ppc64": "1.2.4" + "@img/sharp-libvips-linux-ppc64": "1.3.2" } }, "node_modules/@img/sharp-linux-riscv64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.34.5.tgz", - "integrity": "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==", + "version": "0.35.3", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.35.3.tgz", + "integrity": "sha512-0Eob78yjlYPfL5vMNWAW55l3R9Y6BQS/gOfe0ZcP9mEz9ohhKSt4im1hayiknXgf8AWrFqMvJcKIdmLmEe7yeQ==", "cpu": [ "riscv64" ], @@ -1946,19 +2119,19 @@ "linux" ], "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + "node": ">=20.9.0" }, "funding": { "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-riscv64": "1.2.4" + "@img/sharp-libvips-linux-riscv64": "1.3.2" } }, "node_modules/@img/sharp-linux-s390x": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.5.tgz", - "integrity": "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==", + "version": "0.35.3", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.35.3.tgz", + "integrity": "sha512-KgAxQ0DxpNOq1rG2t5cgTgShJFGSuU7XO45cqC+1NVOuZnP6tlgZRuSYOfNupGkHID0o3cJOsw4DVeJpMovcGw==", "cpu": [ "s390x" ], @@ -1971,19 +2144,19 @@ "linux" ], "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + "node": ">=20.9.0" }, "funding": { "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-s390x": "1.2.4" + "@img/sharp-libvips-linux-s390x": "1.3.2" } }, "node_modules/@img/sharp-linux-x64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.5.tgz", - "integrity": "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==", + "version": "0.35.3", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.35.3.tgz", + "integrity": "sha512-8pqvxubL2PGdhlPy6GLqzDYMUjyRmKAwKHYKixpdJYBUK7PJ0C029XdsnpFIdgRZG68fZiGdHVWcKPvtiPB4cA==", "cpu": [ "x64" ], @@ -1996,19 +2169,19 @@ "linux" ], "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + "node": ">=20.9.0" }, "funding": { "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-x64": "1.2.4" + "@img/sharp-libvips-linux-x64": "1.3.2" } }, "node_modules/@img/sharp-linuxmusl-arm64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.5.tgz", - "integrity": "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==", + "version": "0.35.3", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.35.3.tgz", + "integrity": "sha512-Vz0iQjzzcSX3HCbfwFfCSG/9SCIqyO0mH2sXyiHaAYfBk0cRsCWXRyQYX0ovCK/PAQBbTzQ0dsPQHh5MAFL59w==", "cpu": [ "arm64" ], @@ -2021,19 +2194,19 @@ "linux" ], "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + "node": ">=20.9.0" }, "funding": { "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linuxmusl-arm64": "1.2.4" + "@img/sharp-libvips-linuxmusl-arm64": "1.3.2" } }, "node_modules/@img/sharp-linuxmusl-x64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.5.tgz", - "integrity": "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==", + "version": "0.35.3", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.35.3.tgz", + "integrity": "sha512-6O1NPKcDVj9QEdg7Hx549EX8U0rp6yXQERqru6yRN7fGBn32UvIRJUlWnk+8xDCiG76hXVBbX82NZ/ZKr0euIg==", "cpu": [ "x64" ], @@ -2046,38 +2219,54 @@ "linux" ], "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + "node": ">=20.9.0" }, "funding": { "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linuxmusl-x64": "1.2.4" + "@img/sharp-libvips-linuxmusl-x64": "1.3.2" } }, "node_modules/@img/sharp-wasm32": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.5.tgz", - "integrity": "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==", + "version": "0.35.3", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.35.3.tgz", + "integrity": "sha512-cZ0XkcYGpHZkqW6iCkqTcmUC0CD9DhD5d/qeZlZkfRBn6GnHniZXLUo5+9xw8Iv76YE6LQFN9YNBlKREcCG76w==", + "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.11.1" + }, + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-webcontainers-wasm32": { + "version": "0.35.3", + "resolved": "https://registry.npmjs.org/@img/sharp-webcontainers-wasm32/-/sharp-webcontainers-wasm32-0.35.3.tgz", + "integrity": "sha512-2rnq7bX3NzeR2T4YWgz8qiG4h3TSdMe+vN1iQXpJleSJ3SM5zQ8Fy2SyyXAWlbxpEZ2Y+Z4u1BePgJEYbSy80Q==", "cpu": [ "wasm32" ], - "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "license": "Apache-2.0", "optional": true, "dependencies": { - "@emnapi/runtime": "^1.7.0" + "@img/sharp-wasm32": "0.35.3" }, "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + "node": ">=20.9.0" }, "funding": { "url": "https://opencollective.com/libvips" } }, "node_modules/@img/sharp-win32-arm64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.5.tgz", - "integrity": "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==", + "version": "0.35.3", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.35.3.tgz", + "integrity": "sha512-4bPwFdMbeC4JQ8L8LOyWp6nsHcboP5fxkp6iPOXz2Vg49R42TuMs2whkJ5OAP4/Ul035qOzy0AecOF9VOscn4w==", "cpu": [ "arm64" ], @@ -2087,16 +2276,16 @@ "win32" ], "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + "node": ">=20.9.0" }, "funding": { "url": "https://opencollective.com/libvips" } }, "node_modules/@img/sharp-win32-ia32": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.5.tgz", - "integrity": "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==", + "version": "0.35.3", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.35.3.tgz", + "integrity": "sha512-r53mXsBN6lFUDiST764SvgwUdHAqM4rPAiDzAmf4fLoB6X/rkfyTrLCg6+g17wJJiCmB3JYgHuUldCWUIRFSXw==", "cpu": [ "ia32" ], @@ -2106,16 +2295,16 @@ "win32" ], "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + "node": "^20.9.0" }, "funding": { "url": "https://opencollective.com/libvips" } }, "node_modules/@img/sharp-win32-x64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.5.tgz", - "integrity": "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==", + "version": "0.35.3", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.35.3.tgz", + "integrity": "sha512-D4y1vNeZrIIJCN+uHaWVtH86B+aCrdMYYjicy9pXHvbGZeGYLLSd3wdVuC37FxVXlU1ARsk84eKWfWMXGYEqvA==", "cpu": [ "x64" ], @@ -2125,7 +2314,7 @@ "win32" ], "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + "node": ">=20.9.0" }, "funding": { "url": "https://opencollective.com/libvips" @@ -2160,6 +2349,17 @@ "node": ">=6.0.0" } }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz", + "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==", + "license": "MIT", + "peer": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.5.5", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", @@ -2188,34 +2388,37 @@ } }, "node_modules/@napi-rs/wasm-runtime": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.4.tgz", - "integrity": "sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.2.2.tgz", + "integrity": "sha512-JfB4kuJQjaoHuCTseIINHtHWeJnvgEcxjwA5t/Y00ZgaOO1Crz3fjT/p8kT28zA/Caz7oiUMn3d6H2yOVCVwuw==", "dev": true, "license": "MIT", "optional": true, "dependencies": { - "@tybys/wasm-util": "^0.10.1" + "@tybys/wasm-util": "^0.10.3" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=23.5.0" }, "funding": { "type": "github", "url": "https://github.com/sponsors/Brooooooklyn" }, "peerDependencies": { - "@emnapi/core": "^1.7.1", - "@emnapi/runtime": "^1.7.1" + "@emnapi/core": "^1.7.1 || ^2.0.0-alpha.3", + "@emnapi/runtime": "^1.7.1 || ^2.0.0-alpha.3" } }, "node_modules/@next/env": { - "version": "16.2.6", - "resolved": "https://registry.npmjs.org/@next/env/-/env-16.2.6.tgz", - "integrity": "sha512-gd8HoHN4ufj73WmR3JmVolrpJR47ILK6LouP5xElPglaVxir6e1a7VzvTvDWkOoPXT9rkkTzyCxBu4yeZfZwcw==", + "version": "16.2.12", + "resolved": "https://registry.npmjs.org/@next/env/-/env-16.2.12.tgz", + "integrity": "sha512-d0Z5Bc13Fa4nR8pFAKx2jay2yhJM16vlfHbTzYnUQAxlNb6B6lmn4hjt69lYNt4kRtyYP6gEM49lPRHNbIyneg==", "license": "MIT" }, "node_modules/@next/eslint-plugin-next": { - "version": "16.2.6", - "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-16.2.6.tgz", - "integrity": "sha512-Z8l6o4JWKUl755x4R+wogD86KPeU+Ckw4K+SYG4kHeOJtRenDeK+OSbGcqZpDtbwn9DsJVdir2UxmwXuinUbUw==", + "version": "16.2.12", + "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-16.2.12.tgz", + "integrity": "sha512-uF2z/qAK2q7B5/6CpnFcBRX6jOq5iCO+Uqh1UkJhXljX1JwLarLYhhoJadO6dPb6moTprOKewMXheBcbIoSbug==", "dev": true, "license": "MIT", "dependencies": { @@ -2223,9 +2426,9 @@ } }, "node_modules/@next/swc-darwin-arm64": { - "version": "16.2.6", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-16.2.6.tgz", - "integrity": "sha512-ZJGkkcNfYgrrMkqOdZ7zoLa1TOy0qpcMfk/z4Mh/FKUz40gVO+HNQWqmLxf67Z5WB64DRp0dhEbyHfel+6sJUg==", + "version": "16.2.12", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-16.2.12.tgz", + "integrity": "sha512-0W1R0teHWJrqKX0FH20IzzIWAOuGtBxPGuObrxy1lE8hQvCFj49KE8a3WUg0D7sq6rn6zkM4c7YGUnhudBS6oA==", "cpu": [ "arm64" ], @@ -2239,9 +2442,9 @@ } }, "node_modules/@next/swc-darwin-x64": { - "version": "16.2.6", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-16.2.6.tgz", - "integrity": "sha512-v/YLBHIY132Ced3puBJ7YJKw1lqsCrgcNo2aRJlCEyQrrCeRJlvGlnmxhPxNQI3KE3N1DN5r9TPNPvka3nq5RQ==", + "version": "16.2.12", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-16.2.12.tgz", + "integrity": "sha512-Hy5Ls099+aFUmOLmIgPfLqNi6iCwhL3uQCssz5rWk+5Nkc6TUKCE83DY5BbNylfm3+mfwcSFnLRfrZDJhVxdtw==", "cpu": [ "x64" ], @@ -2255,9 +2458,9 @@ } }, "node_modules/@next/swc-linux-arm64-gnu": { - "version": "16.2.6", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-16.2.6.tgz", - "integrity": "sha512-RPOvqlYBbcQjkz9VQQDZ2T2bARIjXZV1KFlt+V2Mr6SW/e4I9fcKsaA0hdyf2FHoTlsV2xnBd5Y912rP/1Ce6w==", + "version": "16.2.12", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-16.2.12.tgz", + "integrity": "sha512-+YqU2h1cQkHsGfvjAsrSmst8UIFBibBGm5x3Xgel8NLMiDQtNOM4sM2GOEMvG5YiOBNeN/Ykk8cQC2S0Xrqljg==", "cpu": [ "arm64" ], @@ -2274,9 +2477,9 @@ } }, "node_modules/@next/swc-linux-arm64-musl": { - "version": "16.2.6", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-16.2.6.tgz", - "integrity": "sha512-URUTu1+dMkxJsPFgm+OeEvq9wf5sujw0EvgYy80TDGHTSLTnIHeqb0Eu8A3sC95IRgjejQL+kC4mw+4yPxiAXA==", + "version": "16.2.12", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-16.2.12.tgz", + "integrity": "sha512-0qjhiYBaKAqF63LA1ZWAAnKTzFUguAaZiRa5etMLGGPj/B6uEVjtIZldIzFEp3wHlB0koK6aTzqPtSdplTCjoA==", "cpu": [ "arm64" ], @@ -2293,9 +2496,9 @@ } }, "node_modules/@next/swc-linux-x64-gnu": { - "version": "16.2.6", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-16.2.6.tgz", - "integrity": "sha512-DOj182mPV8G3UkrayLoREM5YEYI+Dk5wv7Ox9xl1fFibAELEsFD0lDPfHIeILlutMMfdyhlzYPELG3peuKaurw==", + "version": "16.2.12", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-16.2.12.tgz", + "integrity": "sha512-7A3q26W+h7gnA15uqBToNuDqBEFZZcqh0mW2mn4AJh/G5pdg2RVE3n4slzLEliASZFG3NmsbEzng/x2Sh09mBg==", "cpu": [ "x64" ], @@ -2312,9 +2515,9 @@ } }, "node_modules/@next/swc-linux-x64-musl": { - "version": "16.2.6", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-16.2.6.tgz", - "integrity": "sha512-HKQ5SP/V/ub73UvF7n/zeJlxk2kLmtL7Wzrg4WfmkjmNos5onJ2tKu7yZOPdL18A6Svfn3max29ym+ry7NkK4g==", + "version": "16.2.12", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-16.2.12.tgz", + "integrity": "sha512-qSjL/uppm+cbh21s72Ss8gkiOhQ4dExWHNGOWy6eZV7STj5WsKehgxT61beSsOj+YYQuTplL376lOCdMQU5T8w==", "cpu": [ "x64" ], @@ -2331,9 +2534,9 @@ } }, "node_modules/@next/swc-win32-arm64-msvc": { - "version": "16.2.6", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-16.2.6.tgz", - "integrity": "sha512-LZXpTlPyS5v7HhSmnvsLGP3iIYgYOBnc8r8ArlT55sGHV89bR2HlDdBjWQ+PY6SJMmk8TuVGFuxalnP3k/0Dwg==", + "version": "16.2.12", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-16.2.12.tgz", + "integrity": "sha512-X6hzsOUJac/e7AWSbn9gQ9nzHld1xWP5iyjHpYWvud8pufB679O1xg4JDyKr8Xd69Jvd+kM2Der6uftiZCmjYA==", "cpu": [ "arm64" ], @@ -2347,9 +2550,9 @@ } }, "node_modules/@next/swc-win32-x64-msvc": { - "version": "16.2.6", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-16.2.6.tgz", - "integrity": "sha512-F0+4i0h9J6C4eE3EAPWsoCk7UW/dbzOjyzxY0qnDUOYFu6FFmdZ6l97/XdV3/Nz3VYyO7UWjyEJUXkGqcoXfMA==", + "version": "16.2.12", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-16.2.12.tgz", + "integrity": "sha512-F6fakeHuFTLOPt0bslQJdf+xtT+WIP9DVn/m4y1w1mRnVPyh3D/cNvzlRkxM444xfm+IvvYNSOrKiA2CDJ0Uxw==", "cpu": [ "x64" ], @@ -2362,13 +2565,55 @@ "node": ">= 10" } }, - "node_modules/@nodable/entities": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@nodable/entities/-/entities-2.1.1.tgz", - "integrity": "sha512-Pig3HxDIoMgjdEH8OCf/dkcTmLFjJRjWuq8jSnklu284/TKOPibSRERmOykiwmyXTtv61mP+44f3GMx0tLAyjg==", - "funding": [ - { - "type": "github", + "node_modules/@noble/ciphers": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-1.3.0.tgz", + "integrity": "sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/curves": { + "version": "1.9.7", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.9.7.tgz", + "integrity": "sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw==", + "dev": true, + "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.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", + "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@nodable/entities": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@nodable/entities/-/entities-3.0.0.tgz", + "integrity": "sha512-8L9xFeTYKhm49xfIypoe2W5wV1m/3Z58kT+7kR9A8OyFxcPduI4VmxaUMQyKYrRjUoLLSXv6EKKID5Tvj9cUVw==", + "funding": [ + { + "type": "github", "url": "https://github.com/sponsors/nodable" } ], @@ -2433,9 +2678,9 @@ } }, "node_modules/@opentelemetry/api-logs": { - "version": "0.214.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.214.0.tgz", - "integrity": "sha512-40lSJeqYO8Uz2Yj7u94/SJWE/wONa7rmMKjI1ZcIjgf3MHNHv1OZUCrCETGuaRF62d5pQD1wKIW+L4lmSMTzZA==", + "version": "0.220.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.220.0.tgz", + "integrity": "sha512-CmVa4ImJ+ynfrPMNaAXHET6Bhb44SwzmfyVJFq9ni2jgXJR/l7C6gfVFddNmHP+ZOkP9cf4f9DBe68qVLTHc9w==", "license": "Apache-2.0", "dependencies": { "@opentelemetry/api": "^1.3.0" @@ -2445,9 +2690,9 @@ } }, "node_modules/@opentelemetry/context-async-hooks": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/context-async-hooks/-/context-async-hooks-2.7.1.tgz", - "integrity": "sha512-OPFBYuXEn1E4ja3Y6eeA7O+ZnLBNcXTV5Cgsn1VaqBZ6hC5FnpZPLBNme1LJY8ZtF4aOujPKFoeWN4ik487KuQ==", + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/context-async-hooks/-/context-async-hooks-2.10.0.tgz", + "integrity": "sha512-bvyMcgLEkozzSzpEEEo1OMoeQ97bxj6Qs2uN3mPrSdDvObMI1myffD/BPqcLlzZO9//d1SqQA/WPw7Cz2AiqhA==", "dev": true, "license": "Apache-2.0", "engines": { @@ -2458,9 +2703,9 @@ } }, "node_modules/@opentelemetry/core": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.7.1.tgz", - "integrity": "sha512-QAqIj32AtK6+pEVNG7EOVxHdE06RP+FM5qpiEJ4RtDcFIqKUZHYhl7/7UY5efhwmwNAg7j8QbJVBLxMerc0+gw==", + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.10.0.tgz", + "integrity": "sha512-/wNZ8twnEQQA4HoHu22+vcsdru6pWPWxW+7w+FlxT6Id7PE/WIbZmVKkte+PF72e0F2dnImFeHD2syyE1Mw6MQ==", "license": "Apache-2.0", "dependencies": { "@opentelemetry/semantic-conventions": "^1.29.0" @@ -2473,12 +2718,12 @@ } }, "node_modules/@opentelemetry/instrumentation": { - "version": "0.214.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.214.0.tgz", - "integrity": "sha512-MHqEX5Dk59cqVah5LiARMACku7jXSVk9iVDWOea4x3cr7VfdByeDCURK6o1lntT1JS/Tsovw01UJrBhN3/uC5w==", + "version": "0.220.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.220.0.tgz", + "integrity": "sha512-xQx3E2WxP1mDvKzxLxX+CTCtNLa560YJZ3087qYHerl2YmiKpv7AH+dAy7vmx+eVrZ5BwhfWUAVoKOoxCNHcpw==", "license": "Apache-2.0", "dependencies": { - "@opentelemetry/api-logs": "0.214.0", + "@opentelemetry/api-logs": "0.220.0", "import-in-the-middle": "^3.0.0", "require-in-the-middle": "^8.0.0" }, @@ -2490,12 +2735,29 @@ } }, "node_modules/@opentelemetry/resources": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.7.1.tgz", - "integrity": "sha512-DeT6KKolmC4e/dRQvMQ/RwlnzhaqeiFOXY5ngoOPJ07GgVVKxZOg9EcrNZb5aTzUn+iCrJldAgOfQm1O/QfPAQ==", + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.10.0.tgz", + "integrity": "sha512-q6MMm2zhggzsHVNbabYwut+a6nbuQQe3URUoxaojM/8K1IBfwwPzvxIjNi2/lI1TFe+fMHMW9MWhrtDLEXEnkA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.10.0", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-trace": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace/-/sdk-trace-2.10.0.tgz", + "integrity": "sha512-MfQGq3GRmTh5fM/y+OjaO0vj6+luCB1XO2gfXCalKCfgKw0eHL++sm75DNweC6ohlp+aFvACqeE0fYayqdRaoQ==", "license": "Apache-2.0", "dependencies": { - "@opentelemetry/core": "2.7.1", + "@opentelemetry/core": "2.10.0", + "@opentelemetry/resources": "2.10.0", "@opentelemetry/semantic-conventions": "^1.29.0" }, "engines": { @@ -2506,13 +2768,14 @@ } }, "node_modules/@opentelemetry/sdk-trace-base": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-2.7.1.tgz", - "integrity": "sha512-NAYIlsF8MPUsKqJMiDQJTMPOmlbawC1Iz/omMLygZ1C9am8fTKYjTaI+OZM+WTY3t3Glo0wnOg/6/pac6RGPPw==", + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-2.10.0.tgz", + "integrity": "sha512-GuYQQT7QD2EeO8lcZLRQzcbOyhqAzL+6WWTKTU9mSUBYBazkEDl+VrQcXQhbB08OWM9anD1aHleVadzulpOaUQ==", "license": "Apache-2.0", "dependencies": { - "@opentelemetry/core": "2.7.1", - "@opentelemetry/resources": "2.7.1", + "@opentelemetry/core": "2.10.0", + "@opentelemetry/resources": "2.10.0", + "@opentelemetry/sdk-trace": "2.10.0", "@opentelemetry/semantic-conventions": "^1.29.0" }, "engines": { @@ -2523,18 +2786,18 @@ } }, "node_modules/@opentelemetry/semantic-conventions": { - "version": "1.41.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.41.1.tgz", - "integrity": "sha512-/UhIkaZgPutTFmQ7RnIJGgDXZmtEJ7Dvi86xNTFWcnRxVRNk/aotsqDJYeEvDP+FSMB2SdW+pQzNMcWP0rwuNA==", + "version": "1.43.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.43.0.tgz", + "integrity": "sha512-eSYWTm620tTk45EKSedaUL8MFYI8hW164hIXsgIHyxu3VobUB3fFCu5t0hQby6OoWRPsG1KkKUG2M5UadiLiVg==", "license": "Apache-2.0", "engines": { "node": ">=14" } }, "node_modules/@oxc-project/types": { - "version": "0.133.0", - "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.133.0.tgz", - "integrity": "sha512-KzkdCd6Uxqnf6l3HOw1xfatAlUURA0g14cvBYFyJ5SaNOQbOUvBr9PKArcPcrNIeRsBdgcUzOGrhKveVpvOIGA==", + "version": "0.142.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.142.0.tgz", + "integrity": "sha512-7W+2q5AKQVU36fkaryontrHn3YDt1RyUYXatw9i5H8ocYe2sPKSFB6eS8WNPeRKiN1qAWWZUPm7gwFzJGrccqQ==", "dev": true, "license": "MIT", "funding": { @@ -2542,19 +2805,19 @@ } }, "node_modules/@playwright/test": { - "version": "1.60.0", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.60.0.tgz", - "integrity": "sha512-O71yZIbAh/PxDMNGns37GHBIfrVkEVyn+AXyIa5dOTfb4/xNvRWV+Vv/NMbNCtODB/pO7vLlF2OTmMVLhmr7Ag==", - "dev": true, + "version": "1.62.1", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.62.1.tgz", + "integrity": "sha512-DTcUc8qii+cpHvtOwggMtBRMjKZHXYWdw8syRYu2vtzuq4Wxphqq4NfCs5Zt44L6mA8rfDfj+PHnxFc/FeK6mQ==", + "devOptional": true, "license": "Apache-2.0", "dependencies": { - "playwright": "1.60.0" + "playwright": "1.62.1" }, "bin": { "playwright": "cli.js" }, "engines": { - "node": ">=18" + "node": ">=20" } }, "node_modules/@polka/url": { @@ -2609,13 +2872,6 @@ "license": "BSD-3-Clause", "optional": true }, - "node_modules/@protobufjs/inquire": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.2.tgz", - "integrity": "sha512-pa0vFRuws4wkvaXKK1uXZMAwAX4/t8ANaJo45iw/oQHNQ9q5xUzwgFmVJGXiga2BeN+zpX7Vf9vmsiIa2J+MUw==", - "license": "BSD-3-Clause", - "optional": true - }, "node_modules/@protobufjs/path": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", @@ -2631,36 +2887,35 @@ "optional": true }, "node_modules/@protobufjs/utf8": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.1.tgz", - "integrity": "sha512-oOAWABowe8EAbMyWKM0tYDKi8Yaox52D+HWZhAIJqQXbqe0xI/GV7FhLWqlEKreMkfDjshR5FKgi3mnle0h6Eg==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.2.tgz", + "integrity": "sha512-b1UQwcEZ4yCnMCD8DAL1VlbvBJE9/IX4FTIp7BG1xYpf29SLazLSrqUkj4w7Y5y7cCVP6E5tcqqcI0xemPkHug==", "license": "BSD-3-Clause", "optional": true }, "node_modules/@radix-ui/number": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.1.tgz", - "integrity": "sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.3.tgz", + "integrity": "sha512-Road2bidD0uu/1BGDOWNdPI06g0lIRy6IF9GZcIrDK2KGItfor8IQwQa+yM2ERgHM1MmHxaxpTzk0/Jp42lNfA==", "license": "MIT" }, "node_modules/@radix-ui/primitive": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.3.tgz", - "integrity": "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==", + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.7.tgz", + "integrity": "sha512-rqWnm76nYT8HoNNqEjpgJ7Pw/DrBj5iBTrmEPo6HTX5+VJyBNOqTdv4g89G63HuR5g0AaENoAcH7Is5fF2kZ8Q==", "license": "MIT" }, "node_modules/@radix-ui/react-alert-dialog": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/@radix-ui/react-alert-dialog/-/react-alert-dialog-1.1.15.tgz", - "integrity": "sha512-oTVLkEw5GpdRe29BqJ0LSDFWI3qu0vR1M0mUkOQWDIUnY/QIkLpgDMWuKxP94c2NAC2LGcgVhG1ImF3jkZ5wXw==", + "version": "1.1.23", + "resolved": "https://registry.npmjs.org/@radix-ui/react-alert-dialog/-/react-alert-dialog-1.1.23.tgz", + "integrity": "sha512-VAYOiQRqj3GPpYJE0I9J+X8Ip05cyVlNdKOFeiGS2Ou1HHGfpl0BxOyZm6nmVDyU+W+NF3/XLzmjHmVGydhwgA==", "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-dialog": "1.1.15", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-slot": "1.2.3" + "@radix-ui/primitive": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.2.2", + "@radix-ui/react-dialog": "1.1.23", + "@radix-ui/react-primitive": "2.1.10" }, "peerDependencies": { "@types/react": "*", @@ -2677,31 +2932,13 @@ } } }, - "node_modules/@radix-ui/react-alert-dialog/node_modules/@radix-ui/react-slot": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", - "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-compose-refs": "1.1.2" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, "node_modules/@radix-ui/react-arrow": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.7.tgz", - "integrity": "sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==", + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.15.tgz", + "integrity": "sha512-v4zggRcjadnI+ClKDuijlQEW4tw3NoaeHc/PwpKnLoLLKNUG4InLegkstooLcRIUWCs+8L22dGURCVuFfOKfnA==", "license": "MIT", "dependencies": { - "@radix-ui/react-primitive": "2.1.3" + "@radix-ui/react-primitive": "2.1.10" }, "peerDependencies": { "@types/react": "*", @@ -2719,54 +2956,17 @@ } }, "node_modules/@radix-ui/react-avatar": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/@radix-ui/react-avatar/-/react-avatar-1.1.11.tgz", - "integrity": "sha512-0Qk603AHGV28BOBO34p7IgD5m+V5Sg/YovfayABkoDDBM5d3NCx0Mp4gGrjzLGes1jV5eNOE1r3itqOR33VC6Q==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-context": "1.1.3", - "@radix-ui/react-primitive": "2.1.4", - "@radix-ui/react-use-callback-ref": "1.1.1", - "@radix-ui/react-use-is-hydrated": "0.1.0", - "@radix-ui/react-use-layout-effect": "1.1.1" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-avatar/node_modules/@radix-ui/react-context": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.3.tgz", - "integrity": "sha512-ieIFACdMpYfMEjF0rEf5KLvfVyIkOz6PDGyNnP+u+4xQ6jny3VCgA4OgXOwNx2aUkxn8zx9fiVcM8CfFYv9Lxw==", - "license": "MIT", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-avatar/node_modules/@radix-ui/react-primitive": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.4.tgz", - "integrity": "sha512-9hQc4+GNVtJAIEPEqlYqW5RiYdrr8ea5XQ0ZOnD6fgru+83kqT15mq2OCcbe8KnjRZl5vF3ks69AKz3kh1jrhg==", + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@radix-ui/react-avatar/-/react-avatar-1.2.6.tgz", + "integrity": "sha512-4ULOTJ/mqy2hT9GlWa/MFHxHSvH3nJzHnZM1waNsc5Bonv7i70aNenghXmD97S6OJ81ekXONGGt4nT1r0PfEdA==", "license": "MIT", "dependencies": { - "@radix-ui/react-slot": "1.2.4" + "@radix-ui/primitive": "1.1.7", + "@radix-ui/react-context": "1.2.2", + "@radix-ui/react-primitive": "2.1.10", + "@radix-ui/react-use-callback-ref": "1.1.4", + "@radix-ui/react-use-is-hydrated": "0.1.3", + "@radix-ui/react-use-layout-effect": "1.1.4" }, "peerDependencies": { "@types/react": "*", @@ -2784,19 +2984,18 @@ } }, "node_modules/@radix-ui/react-checkbox": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-checkbox/-/react-checkbox-1.3.3.tgz", - "integrity": "sha512-wBbpv+NQftHDdG86Qc0pIyXk5IR3tM8Vd0nWLKDcX8nNn4nXFOFwsKuqw2okA/1D/mpaAkmuyndrPJTYDNZtFw==", + "version": "1.3.11", + "resolved": "https://registry.npmjs.org/@radix-ui/react-checkbox/-/react-checkbox-1.3.11.tgz", + "integrity": "sha512-Gnptr9pDDQxD3hgq2dtPbtrp/c2qH1mBwIzw3X/ivrMb2e1t0jMTi606fVEqFPaQR1ggXIVQWKj3P2WW9v7zGQ==", "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-presence": "1.1.5", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-controllable-state": "1.2.2", - "@radix-ui/react-use-previous": "1.1.1", - "@radix-ui/react-use-size": "1.1.1" + "@radix-ui/primitive": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.2.2", + "@radix-ui/react-presence": "1.1.10", + "@radix-ui/react-primitive": "2.1.10", + "@radix-ui/react-use-controllable-state": "1.2.6", + "@radix-ui/react-use-size": "1.1.4" }, "peerDependencies": { "@types/react": "*", @@ -2814,15 +3013,15 @@ } }, "node_modules/@radix-ui/react-collection": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.7.tgz", - "integrity": "sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==", + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.15.tgz", + "integrity": "sha512-9W+B9NPF0NaaPh/1NJd3+KqsnlLqU9H7T2rvww+fp+T/evVXdNAyYcnfRQZFOjkR1ajQp3yORlqnI8soawLvNA==", "license": "MIT", "dependencies": { - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-slot": "1.2.3" + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.2.2", + "@radix-ui/react-primitive": "2.1.10", + "@radix-ui/react-slot": "1.3.3" }, "peerDependencies": { "@types/react": "*", @@ -2839,28 +3038,10 @@ } } }, - "node_modules/@radix-ui/react-collection/node_modules/@radix-ui/react-slot": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", - "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-compose-refs": "1.1.2" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, "node_modules/@radix-ui/react-compose-refs": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz", - "integrity": "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.5.tgz", + "integrity": "sha512-+48PbAAbq3didjJxa+OaWY2ZwgAKsNiRGyeHKszblZMQ+kcpd9pAaT11cMkGEie0vsOi3QdeTE6d5Fe3Gn61kA==", "license": "MIT", "peerDependencies": { "@types/react": "*", @@ -2873,9 +3054,9 @@ } }, "node_modules/@radix-ui/react-context": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.2.tgz", - "integrity": "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.2.2.tgz", + "integrity": "sha512-RHCUGwKHDr0hDGg4X7ma4JG4/+12qxw8rkh5QKdDldlCvtja6nUx1Ef/8HVrJze81lEsgLQlqjzjGNHantgnQA==", "license": "MIT", "peerDependencies": { "@types/react": "*", @@ -2888,25 +3069,26 @@ } }, "node_modules/@radix-ui/react-dialog": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.15.tgz", - "integrity": "sha512-TCglVRtzlffRNxRMEyR36DGBLJpeusFcgMVD9PZEzAKnUs1lKCgX5u9BmC2Yg+LL9MgZDugFFs1Vl+Jp4t/PGw==", - "license": "MIT", - "dependencies": { - "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-dismissable-layer": "1.1.11", - "@radix-ui/react-focus-guards": "1.1.3", - "@radix-ui/react-focus-scope": "1.1.7", - "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-portal": "1.1.9", - "@radix-ui/react-presence": "1.1.5", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-slot": "1.2.3", - "@radix-ui/react-use-controllable-state": "1.2.2", + "version": "1.1.23", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.23.tgz", + "integrity": "sha512-Ksw4WeROkO4rC9k/onilX/Ao2Cr1ku1unMNH+XSCcP4jSXYu7HDsg9n4ojMjVb22XpYjAQ9qfrFlVbru1vXDUA==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.2.2", + "@radix-ui/react-dismissable-layer": "1.1.19", + "@radix-ui/react-focus-guards": "1.1.6", + "@radix-ui/react-focus-scope": "1.1.16", + "@radix-ui/react-id": "1.1.4", + "@radix-ui/react-portal": "1.1.17", + "@radix-ui/react-presence": "1.1.10", + "@radix-ui/react-primitive": "2.1.10", + "@radix-ui/react-slot": "1.3.3", + "@radix-ui/react-use-controllable-state": "1.2.6", + "@radix-ui/react-use-layout-effect": "1.1.4", "aria-hidden": "^1.2.4", - "react-remove-scroll": "^2.6.3" + "react-remove-scroll": "^2.7.2" }, "peerDependencies": { "@types/react": "*", @@ -2923,28 +3105,10 @@ } } }, - "node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-slot": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", - "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-compose-refs": "1.1.2" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, "node_modules/@radix-ui/react-direction": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.1.tgz", - "integrity": "sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.4.tgz", + "integrity": "sha512-5pzg4FGQNpExhnhT2zlrP1wZFaYCd1K0nYWoFAdcYoYK868IEigqMX3B3f8yIoRlAhAeDWciLI6ZdCKHF9P4Vg==", "license": "MIT", "peerDependencies": { "@types/react": "*", @@ -2957,16 +3121,16 @@ } }, "node_modules/@radix-ui/react-dismissable-layer": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.11.tgz", - "integrity": "sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg==", + "version": "1.1.19", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.19.tgz", + "integrity": "sha512-8g4pfOL9HoKKLWGiypT+dphVqjFfmcXO5GBnhsG6zI+lxAx/8feQpr+1LSN8Re3hiZ+XkLNS4O9ztK11/LzQ6w==", "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-callback-ref": "1.1.1", - "@radix-ui/react-use-escape-keydown": "1.1.1" + "@radix-ui/primitive": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-primitive": "2.1.10", + "@radix-ui/react-use-callback-ref": "1.1.4", + "@radix-ui/react-use-effect-event": "0.0.5" }, "peerDependencies": { "@types/react": "*", @@ -2984,18 +3148,18 @@ } }, "node_modules/@radix-ui/react-dropdown-menu": { - "version": "2.1.16", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.1.16.tgz", - "integrity": "sha512-1PLGQEynI/3OX/ftV54COn+3Sud/Mn8vALg2rWnBLnRaGtJDduNW/22XjlGgPdpcIbiQxjKtb7BkcjP00nqfJw==", + "version": "2.1.24", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.1.24.tgz", + "integrity": "sha512-geq8l2rJkxvkXsT9RMgtUE3P8pITFpTsvYpbySi1IH4fZEABD/Gp85myayFgxk0ktljGMJnCbeFkyTusvSvv7g==", "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-menu": "2.1.16", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-controllable-state": "1.2.2" + "@radix-ui/primitive": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.2.2", + "@radix-ui/react-id": "1.1.4", + "@radix-ui/react-menu": "2.1.24", + "@radix-ui/react-primitive": "2.1.10", + "@radix-ui/react-use-controllable-state": "1.2.6" }, "peerDependencies": { "@types/react": "*", @@ -3013,9 +3177,9 @@ } }, "node_modules/@radix-ui/react-focus-guards": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.3.tgz", - "integrity": "sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw==", + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.6.tgz", + "integrity": "sha512-RNOJjfZMTyBM6xYmV3IVGXkPjIhcBAuv48POevAXwrGJhkWZ9p1rFoIS1JFooPuT193AZmRsCPhpoVJxx6OPoQ==", "license": "MIT", "peerDependencies": { "@types/react": "*", @@ -3028,14 +3192,14 @@ } }, "node_modules/@radix-ui/react-focus-scope": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.7.tgz", - "integrity": "sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==", + "version": "1.1.16", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.16.tgz", + "integrity": "sha512-wmRZ2WWLvmt6KHy2rNPOdPUjwq5xOHY02+m+udwJTn0aNIox/rkskAvJTyTLGhPK6KgrUjlJUJpgmx/+wFiFIQ==", "license": "MIT", "dependencies": { - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-callback-ref": "1.1.1" + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-primitive": "2.1.10", + "@radix-ui/react-use-callback-ref": "1.1.4" }, "peerDependencies": { "@types/react": "*", @@ -3053,12 +3217,12 @@ } }, "node_modules/@radix-ui/react-id": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.1.tgz", - "integrity": "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.4.tgz", + "integrity": "sha512-TMQp2llA+RYn7JcjnrMnz7wN4pcVttPZnRZo52PLQsoLVKzNlVwUeHmfePgTgRluXFvlD3GD5g5MOVVTJCO0qA==", "license": "MIT", "dependencies": { - "@radix-ui/react-use-layout-effect": "1.1.1" + "@radix-ui/react-use-layout-effect": "1.1.4" }, "peerDependencies": { "@types/react": "*", @@ -3071,35 +3235,12 @@ } }, "node_modules/@radix-ui/react-label": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/@radix-ui/react-label/-/react-label-2.1.8.tgz", - "integrity": "sha512-FmXs37I6hSBVDlO4y764TNz1rLgKwjJMQ0EGte6F3Cb3f4bIuHB/iLa/8I9VKkmOy+gNHq8rql3j686ACVV21A==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-primitive": "2.1.4" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-label/node_modules/@radix-ui/react-primitive": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.4.tgz", - "integrity": "sha512-9hQc4+GNVtJAIEPEqlYqW5RiYdrr8ea5XQ0ZOnD6fgru+83kqT15mq2OCcbe8KnjRZl5vF3ks69AKz3kh1jrhg==", + "version": "2.1.15", + "resolved": "https://registry.npmjs.org/@radix-ui/react-label/-/react-label-2.1.15.tgz", + "integrity": "sha512-o/rdYEwZTTo5tjknnPeyQFU45kUC4i/XyeDPP+HGyi6XqpOP6Zf5Ya5vh/Yfe9Id5JiuWnnAx2XqIeD3UYZt0g==", "license": "MIT", "dependencies": { - "@radix-ui/react-slot": "1.2.4" + "@radix-ui/react-primitive": "2.1.10" }, "peerDependencies": { "@types/react": "*", @@ -3117,29 +3258,29 @@ } }, "node_modules/@radix-ui/react-menu": { - "version": "2.1.16", - "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.1.16.tgz", - "integrity": "sha512-72F2T+PLlphrqLcAotYPp0uJMr5SjP5SL01wfEspJbru5Zs5vQaSHb4VB3ZMJPimgHHCHG7gMOeOB9H3Hdmtxg==", - "license": "MIT", - "dependencies": { - "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-collection": "1.1.7", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-direction": "1.1.1", - "@radix-ui/react-dismissable-layer": "1.1.11", - "@radix-ui/react-focus-guards": "1.1.3", - "@radix-ui/react-focus-scope": "1.1.7", - "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-popper": "1.2.8", - "@radix-ui/react-portal": "1.1.9", - "@radix-ui/react-presence": "1.1.5", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-roving-focus": "1.1.11", - "@radix-ui/react-slot": "1.2.3", - "@radix-ui/react-use-callback-ref": "1.1.1", + "version": "2.1.24", + "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.1.24.tgz", + "integrity": "sha512-uW7RVuU6Lp/ZtfeY4b3kL32zccgEWvPv1+cf17ubYzHa9cL8AHokmk36cG/XEiH/smbQvumnieXX9j/e9RqJWA==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.7", + "@radix-ui/react-collection": "1.1.15", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.2.2", + "@radix-ui/react-direction": "1.1.4", + "@radix-ui/react-dismissable-layer": "1.1.19", + "@radix-ui/react-focus-guards": "1.1.6", + "@radix-ui/react-focus-scope": "1.1.16", + "@radix-ui/react-id": "1.1.4", + "@radix-ui/react-popper": "1.3.7", + "@radix-ui/react-portal": "1.1.17", + "@radix-ui/react-presence": "1.1.10", + "@radix-ui/react-primitive": "2.1.10", + "@radix-ui/react-roving-focus": "1.1.19", + "@radix-ui/react-slot": "1.3.3", + "@radix-ui/react-use-callback-ref": "1.1.4", "aria-hidden": "^1.2.4", - "react-remove-scroll": "^2.6.3" + "react-remove-scroll": "^2.7.2" }, "peerDependencies": { "@types/react": "*", @@ -3156,45 +3297,27 @@ } } }, - "node_modules/@radix-ui/react-menu/node_modules/@radix-ui/react-slot": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", - "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-compose-refs": "1.1.2" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, "node_modules/@radix-ui/react-popover": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.1.15.tgz", - "integrity": "sha512-kr0X2+6Yy/vJzLYJUPCZEc8SfQcf+1COFoAqauJm74umQhta9M7lNJHP7QQS3vkvcGLQUbWpMzwrXYwrYztHKA==", - "license": "MIT", - "dependencies": { - "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-dismissable-layer": "1.1.11", - "@radix-ui/react-focus-guards": "1.1.3", - "@radix-ui/react-focus-scope": "1.1.7", - "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-popper": "1.2.8", - "@radix-ui/react-portal": "1.1.9", - "@radix-ui/react-presence": "1.1.5", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-slot": "1.2.3", - "@radix-ui/react-use-controllable-state": "1.2.2", + "version": "1.1.23", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.1.23.tgz", + "integrity": "sha512-mw58MrBlyHWFisTOYignD0vf/3gdcgAR+9of1s9G/38CbFiUwH1nCDkc0AUM9IrXFgN5Ue8n45j9WCgyM1sbiQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.2.2", + "@radix-ui/react-dismissable-layer": "1.1.19", + "@radix-ui/react-focus-guards": "1.1.6", + "@radix-ui/react-focus-scope": "1.1.16", + "@radix-ui/react-id": "1.1.4", + "@radix-ui/react-popper": "1.3.7", + "@radix-ui/react-portal": "1.1.17", + "@radix-ui/react-presence": "1.1.10", + "@radix-ui/react-primitive": "2.1.10", + "@radix-ui/react-slot": "1.3.3", + "@radix-ui/react-use-controllable-state": "1.2.6", "aria-hidden": "^1.2.4", - "react-remove-scroll": "^2.6.3" + "react-remove-scroll": "^2.7.2" }, "peerDependencies": { "@types/react": "*", @@ -3211,40 +3334,22 @@ } } }, - "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-slot": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", - "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-compose-refs": "1.1.2" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, "node_modules/@radix-ui/react-popper": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.8.tgz", - "integrity": "sha512-0NJQ4LFFUuWkE7Oxf0htBKS6zLkkjBH+hM1uk7Ng705ReR8m/uelduy1DBo0PyBXPKVnBA6YBlU94MBGXrSBCw==", + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.3.7.tgz", + "integrity": "sha512-UsJrrd7w4wuKKTdvd/DNERVlwSlUcyXzjhyDwBk+3aPOsCjOY6ZSbxuw8E6lZTjjfP8Cpd0J8VVkrYUWyGYXyg==", "license": "MIT", "dependencies": { "@floating-ui/react-dom": "^2.0.0", - "@radix-ui/react-arrow": "1.1.7", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-callback-ref": "1.1.1", - "@radix-ui/react-use-layout-effect": "1.1.1", - "@radix-ui/react-use-rect": "1.1.1", - "@radix-ui/react-use-size": "1.1.1", - "@radix-ui/rect": "1.1.1" + "@radix-ui/react-arrow": "1.1.15", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.2.2", + "@radix-ui/react-primitive": "2.1.10", + "@radix-ui/react-use-callback-ref": "1.1.4", + "@radix-ui/react-use-layout-effect": "1.1.4", + "@radix-ui/react-use-rect": "1.1.4", + "@radix-ui/react-use-size": "1.1.4", + "@radix-ui/rect": "1.1.3" }, "peerDependencies": { "@types/react": "*", @@ -3262,13 +3367,13 @@ } }, "node_modules/@radix-ui/react-portal": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.9.tgz", - "integrity": "sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==", + "version": "1.1.17", + "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.17.tgz", + "integrity": "sha512-vKQLcWypUnwZVvfV7UkGahH2g6ySe8M8R+zYBwPrv5byZ9QAW6cQVvNKo7GgmD+p8aYb6D9JBuvy8/WhOno2wQ==", "license": "MIT", "dependencies": { - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-layout-effect": "1.1.1" + "@radix-ui/react-primitive": "2.1.10", + "@radix-ui/react-use-layout-effect": "1.1.4" }, "peerDependencies": { "@types/react": "*", @@ -3286,13 +3391,12 @@ } }, "node_modules/@radix-ui/react-presence": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.5.tgz", - "integrity": "sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==", + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.10.tgz", + "integrity": "sha512-3wyzCQ6+ubRA+D4uv9m95JYLXxmOHp05qjrkjeA7uKHHtjpPggQzc6DAb0URl7j67oR0K2foO4ip27TiX037Bw==", "license": "MIT", "dependencies": { - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-use-layout-effect": "1.1.1" + "@radix-ui/react-use-layout-effect": "1.1.4" }, "peerDependencies": { "@types/react": "*", @@ -3310,12 +3414,12 @@ } }, "node_modules/@radix-ui/react-primitive": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", - "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "version": "2.1.10", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.10.tgz", + "integrity": "sha512-MucOnzh6hR5mid6VpkbglRAMYMjKLqRnGBbjXkzjK52fuQDd1qbkx78a5P40mkcnVXJdEVxm26E9OPAiUq7nBg==", "license": "MIT", "dependencies": { - "@radix-ui/react-slot": "1.2.3" + "@radix-ui/react-slot": "1.3.3" }, "peerDependencies": { "@types/react": "*", @@ -3332,32 +3436,14 @@ } } }, - "node_modules/@radix-ui/react-primitive/node_modules/@radix-ui/react-slot": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", - "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-compose-refs": "1.1.2" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, "node_modules/@radix-ui/react-progress": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/@radix-ui/react-progress/-/react-progress-1.1.8.tgz", - "integrity": "sha512-+gISHcSPUJ7ktBy9RnTqbdKW78bcGke3t6taawyZ71pio1JewwGSJizycs7rLhGTvMJYCQB1DBK4KQsxs7U8dA==", + "version": "1.1.16", + "resolved": "https://registry.npmjs.org/@radix-ui/react-progress/-/react-progress-1.1.16.tgz", + "integrity": "sha512-5XnomAsoZZCY+KNTxbIghpGqPruZvKFNlvcAljVAOdDRDsH4/OZQxhtwo5wdtoDM5R6MhJBb2sPnDuRFep3lzg==", "license": "MIT", "dependencies": { - "@radix-ui/react-context": "1.1.3", - "@radix-ui/react-primitive": "2.1.4" + "@radix-ui/react-context": "1.2.2", + "@radix-ui/react-primitive": "2.1.10" }, "peerDependencies": { "@types/react": "*", @@ -3374,28 +3460,21 @@ } } }, - "node_modules/@radix-ui/react-progress/node_modules/@radix-ui/react-context": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.3.tgz", - "integrity": "sha512-ieIFACdMpYfMEjF0rEf5KLvfVyIkOz6PDGyNnP+u+4xQ6jny3VCgA4OgXOwNx2aUkxn8zx9fiVcM8CfFYv9Lxw==", - "license": "MIT", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-progress/node_modules/@radix-ui/react-primitive": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.4.tgz", - "integrity": "sha512-9hQc4+GNVtJAIEPEqlYqW5RiYdrr8ea5XQ0ZOnD6fgru+83kqT15mq2OCcbe8KnjRZl5vF3ks69AKz3kh1jrhg==", + "node_modules/@radix-ui/react-radio-group": { + "version": "1.4.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-radio-group/-/react-radio-group-1.4.7.tgz", + "integrity": "sha512-cgYFEkntCxppHZgtSZ+7vh0wbZQ+IC7PPMw8DSnRG27B6kDd32/Zw0OJt7dGDigCoprMuWHjg2PvUn3PYvPFoQ==", "license": "MIT", "dependencies": { - "@radix-ui/react-slot": "1.2.4" + "@radix-ui/primitive": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.2.2", + "@radix-ui/react-direction": "1.1.4", + "@radix-ui/react-presence": "1.1.10", + "@radix-ui/react-primitive": "2.1.10", + "@radix-ui/react-roving-focus": "1.1.19", + "@radix-ui/react-use-controllable-state": "1.2.6", + "@radix-ui/react-use-size": "1.1.4" }, "peerDependencies": { "@types/react": "*", @@ -3412,22 +3491,23 @@ } } }, - "node_modules/@radix-ui/react-radio-group": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/@radix-ui/react-radio-group/-/react-radio-group-1.3.8.tgz", - "integrity": "sha512-VBKYIYImA5zsxACdisNQ3BjCBfmbGH3kQlnFVqlWU4tXwjy7cGX8ta80BcrO+WJXIn5iBylEH3K6ZTlee//lgQ==", - "license": "MIT", - "dependencies": { - "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-direction": "1.1.1", - "@radix-ui/react-presence": "1.1.5", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-roving-focus": "1.1.11", - "@radix-ui/react-use-controllable-state": "1.2.2", - "@radix-ui/react-use-previous": "1.1.1", - "@radix-ui/react-use-size": "1.1.1" + "node_modules/@radix-ui/react-roving-focus": { + "version": "1.1.19", + "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.19.tgz", + "integrity": "sha512-V9jI6hDjT7l3jsCQD9bLNvDLM3tH/gdbOTp7Tefp3hbbgCGQoK7tUvrWiRlcoBHIZ809ElXwNQwVo0B98LuTXQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.7", + "@radix-ui/react-collection": "1.1.15", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.2.2", + "@radix-ui/react-direction": "1.1.4", + "@radix-ui/react-id": "1.1.4", + "@radix-ui/react-primitive": "2.1.10", + "@radix-ui/react-use-callback-ref": "1.1.4", + "@radix-ui/react-use-controllable-state": "1.2.6", + "@radix-ui/react-use-is-hydrated": "0.1.3", + "@radix-ui/react-use-layout-effect": "1.1.4" }, "peerDependencies": { "@types/react": "*", @@ -3444,21 +3524,21 @@ } } }, - "node_modules/@radix-ui/react-roving-focus": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.11.tgz", - "integrity": "sha512-7A6S9jSgm/S+7MdtNDSb+IU859vQqJ/QAtcYQcfFC6W8RS4IxIZDldLR0xqCFZ6DCyrQLjLPsxtTNch5jVA4lA==", + "node_modules/@radix-ui/react-scroll-area": { + "version": "1.2.18", + "resolved": "https://registry.npmjs.org/@radix-ui/react-scroll-area/-/react-scroll-area-1.2.18.tgz", + "integrity": "sha512-Zn5Cd171wxsO3Dfg8HaW6RifTb9CYTKQJHs/G4+LN1GfmJpaQMZQyQxMprVPHpaz7QY4l9BxK2JwQuzHsXC8nA==", "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-collection": "1.1.7", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-direction": "1.1.1", - "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-callback-ref": "1.1.1", - "@radix-ui/react-use-controllable-state": "1.2.2" + "@radix-ui/number": "1.1.3", + "@radix-ui/primitive": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.2.2", + "@radix-ui/react-direction": "1.1.4", + "@radix-ui/react-presence": "1.1.10", + "@radix-ui/react-primitive": "2.1.10", + "@radix-ui/react-use-callback-ref": "1.1.4", + "@radix-ui/react-use-layout-effect": "1.1.4" }, "peerDependencies": { "@types/react": "*", @@ -3475,21 +3555,34 @@ } } }, - "node_modules/@radix-ui/react-scroll-area": { - "version": "1.2.10", - "resolved": "https://registry.npmjs.org/@radix-ui/react-scroll-area/-/react-scroll-area-1.2.10.tgz", - "integrity": "sha512-tAXIa1g3sM5CGpVT0uIbUx/U3Gs5N8T52IICuCtObaos1S8fzsrPXG5WObkQN3S6NVl6wKgPhAIiBGbWnvc97A==", - "license": "MIT", - "dependencies": { - "@radix-ui/number": "1.1.1", - "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-direction": "1.1.1", - "@radix-ui/react-presence": "1.1.5", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-callback-ref": "1.1.1", - "@radix-ui/react-use-layout-effect": "1.1.1" + "node_modules/@radix-ui/react-select": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-select/-/react-select-2.3.7.tgz", + "integrity": "sha512-WFGImkmbzcfxeIwq/+4HvRN0pizBwbwQUED4I13ezQsDdfl38ZntN6TmR8XaSzPBqoCToe8rF75j6NPNDSzhbg==", + "license": "MIT", + "dependencies": { + "@radix-ui/number": "1.1.3", + "@radix-ui/primitive": "1.1.7", + "@radix-ui/react-collection": "1.1.15", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.2.2", + "@radix-ui/react-direction": "1.1.4", + "@radix-ui/react-dismissable-layer": "1.1.19", + "@radix-ui/react-focus-guards": "1.1.6", + "@radix-ui/react-focus-scope": "1.1.16", + "@radix-ui/react-id": "1.1.4", + "@radix-ui/react-popper": "1.3.7", + "@radix-ui/react-portal": "1.1.17", + "@radix-ui/react-presence": "1.1.10", + "@radix-ui/react-primitive": "2.1.10", + "@radix-ui/react-slot": "1.3.3", + "@radix-ui/react-use-callback-ref": "1.1.4", + "@radix-ui/react-use-controllable-state": "1.2.6", + "@radix-ui/react-use-layout-effect": "1.1.4", + "@radix-ui/react-use-previous": "1.1.4", + "@radix-ui/react-visually-hidden": "1.2.11", + "aria-hidden": "^1.2.4", + "react-remove-scroll": "^2.7.2" }, "peerDependencies": { "@types/react": "*", @@ -3506,33 +3599,13 @@ } } }, - "node_modules/@radix-ui/react-select": { - "version": "2.2.6", - "resolved": "https://registry.npmjs.org/@radix-ui/react-select/-/react-select-2.2.6.tgz", - "integrity": "sha512-I30RydO+bnn2PQztvo25tswPH+wFBjehVGtmagkU78yMdwTwVf12wnAOF+AeP8S2N8xD+5UPbGhkUfPyvT+mwQ==", - "license": "MIT", - "dependencies": { - "@radix-ui/number": "1.1.1", - "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-collection": "1.1.7", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-direction": "1.1.1", - "@radix-ui/react-dismissable-layer": "1.1.11", - "@radix-ui/react-focus-guards": "1.1.3", - "@radix-ui/react-focus-scope": "1.1.7", - "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-popper": "1.2.8", - "@radix-ui/react-portal": "1.1.9", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-slot": "1.2.3", - "@radix-ui/react-use-callback-ref": "1.1.1", - "@radix-ui/react-use-controllable-state": "1.2.2", - "@radix-ui/react-use-layout-effect": "1.1.1", - "@radix-ui/react-use-previous": "1.1.1", - "@radix-ui/react-visually-hidden": "1.2.3", - "aria-hidden": "^1.2.4", - "react-remove-scroll": "^2.6.3" + "node_modules/@radix-ui/react-separator": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/@radix-ui/react-separator/-/react-separator-1.1.15.tgz", + "integrity": "sha512-jOLO4lssEzWpoDu7G+Ze4VjwMRUBt291pnZD0gmalREZipnTX3wadQo7Fy48GCTfe14/YRN6rw/rOJqrE85Wxw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.10" }, "peerDependencies": { "@types/react": "*", @@ -3549,13 +3622,13 @@ } } }, - "node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-slot": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", - "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "node_modules/@radix-ui/react-slot": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.3.3.tgz", + "integrity": "sha512-qx7oqnYbxnK9kYI9m317qmFmEgo6ywqWvbTogdj7cL9p3/yx4M48p7Rnw5z3H890cL/ow/EeWJsuTykeZVXP5Q==", "license": "MIT", "dependencies": { - "@radix-ui/react-compose-refs": "1.1.2" + "@radix-ui/react-compose-refs": "1.1.5" }, "peerDependencies": { "@types/react": "*", @@ -3567,13 +3640,18 @@ } } }, - "node_modules/@radix-ui/react-separator": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/@radix-ui/react-separator/-/react-separator-1.1.8.tgz", - "integrity": "sha512-sDvqVY4itsKwwSMEe0jtKgfTh+72Sy3gPmQpjqcQneqQ4PFmr/1I0YA+2/puilhggCe2gJcx5EBAYFkWkdpa5g==", + "node_modules/@radix-ui/react-switch": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-switch/-/react-switch-1.3.7.tgz", + "integrity": "sha512-48tB/4dn2UVLBCYhTu9AuR63IHl73l/qLbLgxd86noTUor4/K4LFDAcYjK+isP5313qxaFpjPVogE7+Y0/V3Kw==", "license": "MIT", "dependencies": { - "@radix-ui/react-primitive": "2.1.4" + "@radix-ui/primitive": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.5", + "@radix-ui/react-context": "1.2.2", + "@radix-ui/react-primitive": "2.1.10", + "@radix-ui/react-use-controllable-state": "1.2.6", + "@radix-ui/react-use-size": "1.1.4" }, "peerDependencies": { "@types/react": "*", @@ -3590,90 +3668,20 @@ } } }, - "node_modules/@radix-ui/react-separator/node_modules/@radix-ui/react-primitive": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.4.tgz", - "integrity": "sha512-9hQc4+GNVtJAIEPEqlYqW5RiYdrr8ea5XQ0ZOnD6fgru+83kqT15mq2OCcbe8KnjRZl5vF3ks69AKz3kh1jrhg==", + "node_modules/@radix-ui/react-tabs": { + "version": "1.1.21", + "resolved": "https://registry.npmjs.org/@radix-ui/react-tabs/-/react-tabs-1.1.21.tgz", + "integrity": "sha512-UKxJlZid7FVtsk/WTxj4i4uSEgj2Au+KBbS7SQyTlzMhhn+86Cz3tISZdTa87bfEfcuvZezf2ZsxD4xuEKtkog==", "license": "MIT", "dependencies": { - "@radix-ui/react-slot": "1.2.4" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-slot": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.4.tgz", - "integrity": "sha512-Jl+bCv8HxKnlTLVrcDE8zTMJ09R9/ukw4qBs/oZClOfoQk/cOTbDn+NceXfV7j09YPVQUryJPHurafcSg6EVKA==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-compose-refs": "1.1.2" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-switch": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@radix-ui/react-switch/-/react-switch-1.2.6.tgz", - "integrity": "sha512-bByzr1+ep1zk4VubeEVViV592vu2lHE2BZY5OnzehZqOOgogN80+mNtCqPkhn2gklJqOpxWgPoYTSnhBCqpOXQ==", - "license": "MIT", - "dependencies": { - "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-controllable-state": "1.2.2", - "@radix-ui/react-use-previous": "1.1.1", - "@radix-ui/react-use-size": "1.1.1" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-tabs": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/@radix-ui/react-tabs/-/react-tabs-1.1.13.tgz", - "integrity": "sha512-7xdcatg7/U+7+Udyoj2zodtI9H/IIopqo+YOIcZOq1nJwXWBZ9p8xiu5llXlekDbZkca79a/fozEYQXIA4sW6A==", - "license": "MIT", - "dependencies": { - "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-direction": "1.1.1", - "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-presence": "1.1.5", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-roving-focus": "1.1.11", - "@radix-ui/react-use-controllable-state": "1.2.2" + "@radix-ui/primitive": "1.1.7", + "@radix-ui/react-context": "1.2.2", + "@radix-ui/react-direction": "1.1.4", + "@radix-ui/react-id": "1.1.4", + "@radix-ui/react-presence": "1.1.10", + "@radix-ui/react-primitive": "2.1.10", + "@radix-ui/react-roving-focus": "1.1.19", + "@radix-ui/react-use-controllable-state": "1.2.6" }, "peerDependencies": { "@types/react": "*", @@ -3691,9 +3699,9 @@ } }, "node_modules/@radix-ui/react-use-callback-ref": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.1.tgz", - "integrity": "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.4.tgz", + "integrity": "sha512-R6OUY2e2fA6Yn6s+VSx5KBV6Nx8LQEhu+cz7LCej18rQ1HLyg9PSC9jP/ZNx0o6FAIK9c0F1kHylzSxKsdlkrQ==", "license": "MIT", "peerDependencies": { "@types/react": "*", @@ -3706,13 +3714,14 @@ } }, "node_modules/@radix-ui/react-use-controllable-state": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.2.tgz", - "integrity": "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==", + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.6.tgz", + "integrity": "sha512-uEQJGT97ZA/TgP/Hydw47lHu+/vQj6z/0jA+WeTbK1o9Rx45GImjpD0tc3W5ad3D6XTSR6e1yEO0FvGq6WQfVQ==", "license": "MIT", "dependencies": { - "@radix-ui/react-use-effect-event": "0.0.2", - "@radix-ui/react-use-layout-effect": "1.1.1" + "@radix-ui/primitive": "1.1.7", + "@radix-ui/react-use-effect-event": "0.0.5", + "@radix-ui/react-use-layout-effect": "1.1.4" }, "peerDependencies": { "@types/react": "*", @@ -3725,30 +3734,12 @@ } }, "node_modules/@radix-ui/react-use-effect-event": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-effect-event/-/react-use-effect-event-0.0.2.tgz", - "integrity": "sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-use-layout-effect": "1.1.1" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-use-escape-keydown": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.1.tgz", - "integrity": "sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==", + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-effect-event/-/react-use-effect-event-0.0.5.tgz", + "integrity": "sha512-7cshFL8HGS/7HEiHH+9kL9HBwp2sa9yX18Knwek6KYWmXwM7pegMgta2AXMQKI+rq3JnfSj9x8wYqFMTdG1Jgg==", "license": "MIT", "dependencies": { - "@radix-ui/react-use-callback-ref": "1.1.1" + "@radix-ui/react-use-layout-effect": "1.1.4" }, "peerDependencies": { "@types/react": "*", @@ -3761,13 +3752,10 @@ } }, "node_modules/@radix-ui/react-use-is-hydrated": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-is-hydrated/-/react-use-is-hydrated-0.1.0.tgz", - "integrity": "sha512-U+UORVEq+cTnRIaostJv9AGdV3G6Y+zbVd+12e18jQ5A3c0xL03IhnHuiU4UV69wolOQp5GfR58NW/EgdQhwOA==", + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-is-hydrated/-/react-use-is-hydrated-0.1.3.tgz", + "integrity": "sha512-umO/aJ+82CpOnhDZUTbILCQf7kU/g0iv+oGs/Q8jw7IkhWBzaEP4sA268PhFAJTFetbwp3ICc6ktpI4TqtxcIw==", "license": "MIT", - "dependencies": { - "use-sync-external-store": "^1.5.0" - }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" @@ -3779,9 +3767,9 @@ } }, "node_modules/@radix-ui/react-use-layout-effect": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.1.tgz", - "integrity": "sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.4.tgz", + "integrity": "sha512-K20DkRkUwDnxEYMBPcg3Y6voLkEy5p5QQmszZgLngKKiC7dzBR/aEuK3w1qlx2JWDUNH6FluahYdgR3BP+QbYw==", "license": "MIT", "peerDependencies": { "@types/react": "*", @@ -3794,9 +3782,9 @@ } }, "node_modules/@radix-ui/react-use-previous": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.1.tgz", - "integrity": "sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.4.tgz", + "integrity": "sha512-XoSLhbRbqxFtgJoi2fNHA3C6pDlY34x508vUpUGoFZfvePfHXHbE1lC4FYFMnJWgiCRroSTw6fOsXQoVS9RwZg==", "license": "MIT", "peerDependencies": { "@types/react": "*", @@ -3809,12 +3797,12 @@ } }, "node_modules/@radix-ui/react-use-rect": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.1.tgz", - "integrity": "sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.4.tgz", + "integrity": "sha512-cSOCh6JlkmfjLyNcLiu2nB4v+nm+dkZ+Q5KHWk/soo4U7ZLiEQFKHK9/YmtBHjfCEaU43IBKQOc4/uJmCaiCTQ==", "license": "MIT", "dependencies": { - "@radix-ui/rect": "1.1.1" + "@radix-ui/rect": "1.1.3" }, "peerDependencies": { "@types/react": "*", @@ -3827,12 +3815,12 @@ } }, "node_modules/@radix-ui/react-use-size": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.1.tgz", - "integrity": "sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.4.tgz", + "integrity": "sha512-D3anSY15EJoxrihpsXI6SMrmmonnQtR2ni7arO+Lfdg3O95b9hNXxONk8jA5C8ANdF/h5HMAxejgs8PWJ6rlhw==", "license": "MIT", "dependencies": { - "@radix-ui/react-use-layout-effect": "1.1.1" + "@radix-ui/react-use-layout-effect": "1.1.4" }, "peerDependencies": { "@types/react": "*", @@ -3845,12 +3833,12 @@ } }, "node_modules/@radix-ui/react-visually-hidden": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.2.3.tgz", - "integrity": "sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug==", + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.2.11.tgz", + "integrity": "sha512-NFS86RYYZb4/exihaESBGOpMJFz8MGLAfu3mOBSGByVnVPC9JPASfYubxd/8KbkQK0sYAv8lVQDEQukDX/qXvQ==", "license": "MIT", "dependencies": { - "@radix-ui/react-primitive": "2.1.3" + "@radix-ui/react-primitive": "2.1.10" }, "peerDependencies": { "@types/react": "*", @@ -3868,18 +3856,20 @@ } }, "node_modules/@radix-ui/rect": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.1.tgz", - "integrity": "sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.3.tgz", + "integrity": "sha512-JtyZR+mqgBibTo8xea3B6ZRmzZiM/YeVBtUkas6zMuXjAlfIFIW2FgqeM9eLyvEaYX66vr6DJMK+4U6LV0KhNw==", "license": "MIT" }, "node_modules/@react-email/render": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/@react-email/render/-/render-2.0.8.tgz", - "integrity": "sha512-5udvVr3U/WuGJZfLdLBOhkzrqRWd2Q5ZYmF7ppcy7FzWcwgshdqLMNqJOXcVzAXJXg/2bm7D+WGJzTtZOZMQnQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@react-email/render/-/render-2.1.0.tgz", + "integrity": "sha512-F+zE3O6d6sW6Aj2UjvZAA17R7tJKM7kcq2mgV6k4HCT8jeLLFaVP2txMtH1lgqYFRMZ0Gxsd37q2PRyiXLXXxA==", "license": "MIT", "dependencies": { + "entities": "^4.5.0", "html-to-text": "^9.0.5", + "html5parser": "^3.0.0", "prettier": "^3.5.3" }, "engines": { @@ -3890,6 +3880,18 @@ "react-dom": "^18.0 || ^19.0 || ^19.0.0-rc" } }, + "node_modules/@react-email/render/node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/@reduxjs/toolkit": { "version": "2.12.0", "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.12.0.tgz", @@ -3916,20 +3918,10 @@ } } }, - "node_modules/@reduxjs/toolkit/node_modules/immer": { - "version": "11.1.8", - "resolved": "https://registry.npmjs.org/immer/-/immer-11.1.8.tgz", - "integrity": "sha512-/tbkHMW7y10Lx6i1crLjD4/OhNkRG+Fo7byZHtah0547nIeXYcpIXaUh0IAQY6gO5459qpGGYapcEOHtFXkIuA==", - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/immer" - } - }, "node_modules/@rolldown/binding-android-arm64": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.3.tgz", - "integrity": "sha512-454rs7jHngixp/NMxd5srYD57OnzSlZ/eFTETjORQHLwJG1lRtmNOJcBerZlfu4GjKqeq8aCCIQrMdHyhI51Hw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.1.tgz", + "integrity": "sha512-02hOeOSryYxVrOIphmLAsqnCJWxwlzFk+pEt/N/i6OgT3lShHO7xGCU5cpgchRDHboAEbSjzgGh+O/u1GswQmA==", "cpu": [ "arm64" ], @@ -3944,9 +3936,9 @@ } }, "node_modules/@rolldown/binding-darwin-arm64": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.3.tgz", - "integrity": "sha512-PcAhP+ynjURNyy8SKGl5DQP94aGuB/7JrXJb/t7P+hanXvQVMWzUvRRhBAcg/lNRadBhoUPqSoP4xw5tR/KBEA==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.2.1.tgz", + "integrity": "sha512-fMsTOnN0OjFm3CyppWPitKnc8UlliVARUULW6cfU6AIqjdtgmSFWSk9vecHzZduv/yMWIHDlRhM1e8Iff9uAfA==", "cpu": [ "arm64" ], @@ -3961,9 +3953,9 @@ } }, "node_modules/@rolldown/binding-darwin-x64": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.3.tgz", - "integrity": "sha512-9YpfeUvSE2RS7wysJ81uOZkXJz7f7Q55H2Gvp3VEw/EsahqDtrphrZ0EwDLK5vvKOzaCrBsjF8JmnMLcUt78Gg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.2.1.tgz", + "integrity": "sha512-1wjKdz/XLGKHaTNHjQveQ/B23TKx4ItAqm1JbyVuvNPc4Ze0Fb48s49TAd/2zcplPl8okE/UbTgmlVfwT7eFeQ==", "cpu": [ "x64" ], @@ -3978,9 +3970,9 @@ } }, "node_modules/@rolldown/binding-freebsd-x64": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.3.tgz", - "integrity": "sha512-yB1IlAsSNHncV6SCTL27/MVGR5htvQsoGxIv5KMGXALp+Ll1wYsn+x98M9MW7qa+NdSbvrrY7ANI4wLJ0n1e6g==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.2.1.tgz", + "integrity": "sha512-Fa0jHR07E7YBN4vOEsbVf2briYNsuOowfLJaXULZM0ldMlaCaj2LJgLMbMe4iacRyZmvR8efFhgR9wKuGclQUg==", "cpu": [ "x64" ], @@ -3995,9 +3987,9 @@ } }, "node_modules/@rolldown/binding-linux-arm-gnueabihf": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.3.tgz", - "integrity": "sha512-Yi30IVAAfLUCy2MseFjbB1jAMDl1VMCAas5StnYp8da9+CKvMd2H2cbEjWcw5NPaPqzvYkVIaF1nNUG+b7u/sw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.2.1.tgz", + "integrity": "sha512-pzkgu1SSHGgRRyRZ4fbmSgmajbVt+epaLP99NDjFft69v/ypfTi6swBMiVdh2EkQ0OSnHE1lZDM7DRGkyAzUpA==", "cpu": [ "arm" ], @@ -4012,9 +4004,9 @@ } }, "node_modules/@rolldown/binding-linux-arm64-gnu": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.3.tgz", - "integrity": "sha512-jsO7R8To+AdlYgUmN5sHSCZbfhtMBkO0WUx8iORQnPcMMdgr7qM2DQmMwgabs3GhNztdmoKkMKQFHD6DTMCIQw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.2.1.tgz", + "integrity": "sha512-QI5SEDY8cbiYWHx0VO4vIc3UlS6a32vXHjU8Qy/17adEmZIPuByJg13UEvo9c/UCiUkdcVWY83C+b+JrwnNyUg==", "cpu": [ "arm64" ], @@ -4032,9 +4024,9 @@ } }, "node_modules/@rolldown/binding-linux-arm64-musl": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.3.tgz", - "integrity": "sha512-VWkUHwWriDciit80wleYwKILoR/KMvxh/IdwS/paX+ZgpuRpCrKLUdadJbc0NpBEiyhpYawsJ73j9aCvOH+f7Q==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.2.1.tgz", + "integrity": "sha512-Sm41FyCeXqmYcERoYOCbGIL5hNfd8w9LQ7Y61Bev48HkcjaJqV/iiVOaiDxjVTRMS+QKrZmD8cfPt4uMVnvM+A==", "cpu": [ "arm64" ], @@ -4052,9 +4044,9 @@ } }, "node_modules/@rolldown/binding-linux-ppc64-gnu": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.3.tgz", - "integrity": "sha512-5f1laC0SlIR0yDbFCd8acUhvJIag6N3zC5P7oUPN6wX0aOma+uKJ0wBDH5aq7I1PVI2ttTlhJwzwRIBnLiSGEg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.2.1.tgz", + "integrity": "sha512-2x+WhXTGl9yJYPbltW/BSEPTVz9OIWQyER4N+gJEDWkkn904eRcBzELqh/Hf7K0w/ubGbKNMv0ZC+94QK/IFEg==", "cpu": [ "ppc64" ], @@ -4072,9 +4064,9 @@ } }, "node_modules/@rolldown/binding-linux-s390x-gnu": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.3.tgz", - "integrity": "sha512-Iq4ko0r4XsgbrF/LunNgHtAGLRRVE2kXonAXQ/MV0mC6jQpMOhW1SvtZja2EhC/kd05++bP78dsqBeIQyYJ6Yg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.2.1.tgz", + "integrity": "sha512-eEjmQpuRQayHPWWnywaWHkFT3ToPbP3RYy42VVd/B9aBGDA+Ol25EIWHxKQST3IiWJjikCWUF7KtbfqwZrzVwQ==", "cpu": [ "s390x" ], @@ -4092,9 +4084,9 @@ } }, "node_modules/@rolldown/binding-linux-x64-gnu": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.3.tgz", - "integrity": "sha512-B8m6tD5+/N5FeNQFbKlLA/2yVq9ycQP1SeedyEYYKWBNR3ZQbkvIUcNnDNM03lO1l5F2roiiFJGgvoLLyZXtSg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.2.1.tgz", + "integrity": "sha512-/Orga1fZYkLc/56jBICcHrKchl8Z2UKdDSr3LG9ToWO1lQ6a4Livk9Xz+9WN91zsz5QR3XQz2NNoSDEvP6qadw==", "cpu": [ "x64" ], @@ -4112,9 +4104,9 @@ } }, "node_modules/@rolldown/binding-linux-x64-musl": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.3.tgz", - "integrity": "sha512-pSdpdUJHkuCxun9LE7jvgUB9qsRgaiyNNCX7m/AvHTcq67AiT/Yhoxvw5zPfhrM8k/BfP8ce/hMOpthKDpEUow==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.2.1.tgz", + "integrity": "sha512-xxBJRL+0q0Kce7orznGWLuylHDY65vuARXZRpX+hPdv+DqK2c3NlCsVA98tlWzWNEE7yPqA/1NQ5nnCrj49Y5A==", "cpu": [ "x64" ], @@ -4132,9 +4124,9 @@ } }, "node_modules/@rolldown/binding-openharmony-arm64": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.3.tgz", - "integrity": "sha512-OXXS3RKJgX2uLwM+gYyuH5omcH8fL1LJs96pZGgtetVCahON57+d4SJHzTgZiOjxgGkSnpXpOsWuPDGAKAigEg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.2.1.tgz", + "integrity": "sha512-M6AdXIXw3s+/8XpKMzdGDEXGS1S7kwUsy+rcTIUIOx5Ge4nXKCtAFHFV9YKkXvGcC5WMoTjAteLzlsQROVI0Yw==", "cpu": [ "arm64" ], @@ -4149,28 +4141,59 @@ } }, "node_modules/@rolldown/binding-wasm32-wasi": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.3.tgz", - "integrity": "sha512-JTtb8BWFynicNSoPrehsCzBtOKjZ6jhMiPFEmOiuXg1Fl8dn2KHQob+GuPSGR0dryQa1PQJbzjF3dqO/whhjLg==", - "cpu": [ - "wasm32" - ], + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.2.1.tgz", + "integrity": "sha512-/TX0SoRGojHzSAHpfVBbavRVSazg5U3h3Y3VXfcc0cdugq6kxdqw8LPGFiPr+/7gE/60zRcsOY2Vi9b9eT0jww==", "dev": true, "license": "MIT", "optional": true, "dependencies": { - "@emnapi/core": "1.10.0", - "@emnapi/runtime": "1.10.0", - "@napi-rs/wasm-runtime": "^1.1.4" + "@emnapi/core": "2.0.0-alpha.3", + "@emnapi/runtime": "2.0.0-alpha.3", + "@napi-rs/wasm-runtime": "^1.2.0" }, "engines": { - "node": "^20.19.0 || >=22.12.0" + "node": "^20.19.0 || ^22.13.0 || >=23.5.0" + } + }, + "node_modules/@rolldown/binding-wasm32-wasi/node_modules/@emnapi/core": { + "version": "2.0.0-alpha.3", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-2.0.0-alpha.3.tgz", + "integrity": "sha512-AZypUeJ/yByuxyS7BlSNRDOMLMlROYtjYdIAuBmJssVz1UJDSeYxLrdizhXCFYhedC5bqd/ASy8EuNXbVVXp9g==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "2.0.1", + "tslib": "^2.4.0" + } + }, + "node_modules/@rolldown/binding-wasm32-wasi/node_modules/@emnapi/runtime": { + "version": "2.0.0-alpha.3", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-2.0.0-alpha.3.tgz", + "integrity": "sha512-hFPAhMUjJD9BSyCANEISPOogeXC9Zo9ZQl7L6vKnaVsMkCtzznaW/naYypeyl0Gv5rYfWYsZbpixTMpjDJzQeA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@rolldown/binding-wasm32-wasi/node_modules/@emnapi/wasi-threads": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-2.0.1.tgz", + "integrity": "sha512-9DsSk+o5NBX0CCJT8s0EROGSGxjR/tKu6aBTaVyq+SjAEQH4XcdcRxPBRzsBLizTTJ49MJjF+jgu3qnO9GLQcQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" } }, "node_modules/@rolldown/binding-win32-arm64-msvc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.3.tgz", - "integrity": "sha512-gEdFFEN70A/jxb2svrWsN3aDL7OUtmvlOy+6fa2jxG8K0wQ1ZbdeLGnidov6Yu5/733dI5ySfzFlQ/cb0bSz1g==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.2.1.tgz", + "integrity": "sha512-EvRrivJieyHG+AO9lleZWgq+g0+S7oV2C51yuqlcyU/R9net+sI4Pj0F+lUoP2bEr6TWX3SqFaaS0SzfLxSzkw==", "cpu": [ "arm64" ], @@ -4185,9 +4208,9 @@ } }, "node_modules/@rolldown/binding-win32-x64-msvc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.3.tgz", - "integrity": "sha512-eXB7CHuaQdqmJcc3koCNtNPmT/bj2gc999kUFgBxG8Ac0NdgXc4rkCHhqrgrhN3zddvvvrgzj1e90SuSfmyIXA==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.2.1.tgz", + "integrity": "sha512-Z4eCmn5QJ/5+azF9knpLWKfVd9aidn0mAe9TpJgvBLId9Ax3t0+JVxBmT25Bv7NBbVW1TZyKjQjQReouMeH5UQ==", "cpu": [ "x64" ], @@ -4257,9 +4280,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.61.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.61.0.tgz", - "integrity": "sha512-dnxczajOqt0gesZlN5pGQ1s1imQVrsmCw5G2Ci4oM+0WvNz3pyRnlWrT7McoZIb8VlFwCawdmbWRmxRn7HI+VQ==", + "version": "4.62.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.62.3.tgz", + "integrity": "sha512-c0wdcekXtQvvn5Tsrk/+op/gUArrbWaFduBnTLP2l1cKLSQs4diMWjJw3m6A0DdzT8dAAX95KpkJ3qynCePbmw==", "cpu": [ "arm" ], @@ -4270,9 +4293,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.61.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.61.0.tgz", - "integrity": "sha512-Bp3JpGP00Vu3f238ivRrjf7z3xSzVPXqCmaJYA9t2c+c8vKYvOzmXF7LkkeUalTEGd6cZcSWe+PFIP3Vy48fRg==", + "version": "4.62.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.62.3.tgz", + "integrity": "sha512-3YjElDdWN+qXAFbJ/CzPV+0wspLqh54k/I6GfdYtEJRqg7buSgc1yPM3B+93j1M4neobtkATHZTmxK2AMVGfnA==", "cpu": [ "arm64" ], @@ -4283,9 +4306,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.61.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.61.0.tgz", - "integrity": "sha512-zaYIpr670mUmmZ1tVzUFplbQbG7h3Gugx3L5FoqhsC2m/YnLlR1a7zVLmXNPy+iY1tFPEbNG+HHBXZGyId0G5w==", + "version": "4.62.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.62.3.tgz", + "integrity": "sha512-Pch2pFNOxxz1hTjypIdPyRTR6riiwRl84+VcN9djS680fw+Co1nAJINrdpqp7KV0NvyuU8ilZXZCjd7ykJl1GQ==", "cpu": [ "arm64" ], @@ -4296,9 +4319,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.61.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.61.0.tgz", - "integrity": "sha512-+P49fvkv2dSoeevUW+lgZ/I2JHSsJCK1Lyjj7Cu6E4UHG4tS9XIefzIjo5qhgELjAclnen1rLzK2PMKJdo+Dyg==", + "version": "4.62.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.62.3.tgz", + "integrity": "sha512-LEuncFUHFiF8t4yZVZvvZA1wk0pjAscRnsrn1EfTEmN4HXotBi2YtcnLRyaK6UbuczW7xZS5ES+81Rdz8Z0T6g==", "cpu": [ "x64" ], @@ -4309,9 +4332,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.61.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.61.0.tgz", - "integrity": "sha512-l3FAAOyKJXH2ea6KNFN+MMgC/rnE94YGLXs2ehYqDcCoHt1DpvgWX75BhUJxN38XojP7Ul+4H8PRn7EdyqSDrw==", + "version": "4.62.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.62.3.tgz", + "integrity": "sha512-zvBUvsQUpOWALdDsk6qbS8bXf2VxmPisuudNDrY7x0p0jBdsoZl8HsHczIOgkQiZldmcacMKtBzpoGVNeIe2bQ==", "cpu": [ "arm64" ], @@ -4322,9 +4345,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.61.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.61.0.tgz", - "integrity": "sha512-VokPN3TSctKj65cyCNPaUh4vMFA8awxOot/0sp+4J7ZlNRKQEhXhawqPwajoi8H5ZFt61i0ugZJuTKXBjGJ17Q==", + "version": "4.62.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.62.3.tgz", + "integrity": "sha512-C2KmNrcSem/AMg984H/dev+si0lieQGdXdR/lYGJnuumXnFb9Y7QdiI62obFdLlxRYLBv4P0eUVIDbD4c1vVvw==", "cpu": [ "x64" ], @@ -4335,9 +4358,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.61.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.61.0.tgz", - "integrity": "sha512-DxH0P3wxm+Yzs/p3zrk9dw1rURu8p0Nv5+MRK/L7OtnLNg5rLZraSBFZ8iUXOd9f2BlhJyEpIZUH/emjq4UJ4g==", + "version": "4.62.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.62.3.tgz", + "integrity": "sha512-ggXnsTAEzNQx74XpunRsiZ9aBZDsI7XIa0hm2nzR9f4WzH5/f/d73ZSDaC5ejJ8YLY4NW+V3wr0tjOaeCq8hqA==", "cpu": [ "arm" ], @@ -4351,9 +4374,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.61.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.61.0.tgz", - "integrity": "sha512-T6ZvMNe84kAz6TBWHC7hGAoEtzP1LWYw/AqayGWEF6uISt3Abk/st06LqRD9THd7Xz3NxzurUpzAuEAUbZf+nw==", + "version": "4.62.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.62.3.tgz", + "integrity": "sha512-2vng+FlzNUhKZxtej3IUqJgbZoQk2M/dwQM20+ULV0R/E/8tr9/P6uEf2iiGIk4HL0zMKh5Jry7mUHdUOvyGgA==", "cpu": [ "arm" ], @@ -4367,9 +4390,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.61.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.61.0.tgz", - "integrity": "sha512-q/4hzvQkDs8b4jIBab1pnLiiM0ayTZsN2amBFPDzuyZxjEd4wDwx0UJFYM3cOZzSf5Kw8fnWSprJzIBMkcR44Q==", + "version": "4.62.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.62.3.tgz", + "integrity": "sha512-LLLFZKt4/Nraf9rxDkhiU8QVgLF4WmCkfr0L4fj0fPfIZFBib0DeiFk1hhaYKd03LFAFJcxHslhDFlNJLylf5Q==", "cpu": [ "arm64" ], @@ -4383,9 +4406,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.61.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.61.0.tgz", - "integrity": "sha512-vvYWX3akdEAY6km+9wAqFDnk6pQsbJKVnj7xawcvs/+fdlYBGp+U+Qq/lLfpIxYIZvZLHMAKD9HLdacSx/r3dw==", + "version": "4.62.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.62.3.tgz", + "integrity": "sha512-WJkdQCvS9sWNOUBJZfQRKpZGFBztRzcowI+nndmflKgU4XY+3a420FgTOSKTsVqJbnzSxeT4vaJalpOaPo2YCQ==", "cpu": [ "arm64" ], @@ -4399,9 +4422,9 @@ ] }, "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.61.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.61.0.tgz", - "integrity": "sha512-DePa5cqOxDP/Zp0VOXpeWaGew5iIv5DXp9NYbzkX5PFQyWVX9184WCTh3hvr/7lhXo8ZVlbFLkz8+o/q1dU6gA==", + "version": "4.62.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.62.3.tgz", + "integrity": "sha512-PwHXCCS2n64/1Ot6rP1YEYA02MGYBcQlr8CSZZyrUG2O7NH6NklYmvr9v3Jy+5e/eDeNchc/ukmKJi9LuflMIQ==", "cpu": [ "loong64" ], @@ -4415,9 +4438,9 @@ ] }, "node_modules/@rollup/rollup-linux-loong64-musl": { - "version": "4.61.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.61.0.tgz", - "integrity": "sha512-LV8aWMB8UChglMCEzs7RkN0GsH29RJaLLqwm9fCIjlqwxQTiWAqNcc7wjBkH31hV0PU/yVxGYvrYsgfea2qw6g==", + "version": "4.62.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.62.3.tgz", + "integrity": "sha512-vUjxINQu3RC8NZS3ykk1gN65gIz8pAopOq2HXuZhiIxHdx7TFvDG+jgrdSgInu1Eza4/Rfi2VzZgyIgEH4WOaw==", "cpu": [ "loong64" ], @@ -4431,9 +4454,9 @@ ] }, "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.61.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.61.0.tgz", - "integrity": "sha512-QoNSnwQtaeNu5grdBbsL0tt1uyl5EnS8DA8Mr3nluMXbhdQNyhN+G4tBax7VCdxLKj8YJ0/4OO9Ho84jMnJtKA==", + "version": "4.62.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.62.3.tgz", + "integrity": "sha512-wzko4aJ13+0G3kGnviCg5gnXFKd40izKsrf2uOw12US4XqprkDrmwOpeW14aSNa37V8bfPcz5Fkob6LZ3BAPmA==", "cpu": [ "ppc64" ], @@ -4447,9 +4470,9 @@ ] }, "node_modules/@rollup/rollup-linux-ppc64-musl": { - "version": "4.61.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.61.0.tgz", - "integrity": "sha512-/zZp5MKapIIApE8trN8qLGNSiRN9TUoaUZ1cmVu4XnVdd5LQLOXTtyi+vtfUbNnT3iyjzpPqYeKXmvJ+gJGYWw==", + "version": "4.62.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.62.3.tgz", + "integrity": "sha512-8120ue0JUMSwy11stlwnfdX3pPd+WZYGCDBwEHWtIHi6pOpZmsEF5QKB7a/UN+XFdqvobxz98kv8RTqikyCEBw==", "cpu": [ "ppc64" ], @@ -4463,9 +4486,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.61.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.61.0.tgz", - "integrity": "sha512-RbrzcD3aJ1k3UbtMRRBNwojdVVyXjuVAFTfn/xPa6EEl6GE9Sm/akPgFTb9aAC9pMKGJ6CtWxaGrqWcabH+ySg==", + "version": "4.62.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.62.3.tgz", + "integrity": "sha512-XLFHnR3tXMjbOCh2vtVJHmxt+995uJsTERQyseFDRA0xxMxyTZPLa3OIUlyFaO4mF/Lu0FjmWHCuPXJT1n/IOg==", "cpu": [ "riscv64" ], @@ -4479,9 +4502,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.61.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.61.0.tgz", - "integrity": "sha512-ZF+onDsBso8PJf1XaG9lB+O9RnBpKGnY6OrzC4CSHrtC1jb6jWLTKK4bRqdoCXHd22gyr2hiYmEAm8Wns/BOCw==", + "version": "4.62.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.62.3.tgz", + "integrity": "sha512-se6yXvNGMIl0f+RQzyh7XAmia8/9kplQx424wnG2w0C1oi6XgO6Y8otKhdXFHbHs88Ihavzmvh1NWjuovE76BQ==", "cpu": [ "riscv64" ], @@ -4495,9 +4518,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.61.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.61.0.tgz", - "integrity": "sha512-Atk0aSIk5Zx2Wuh9dgRQgLP0Koc8hOeYpbWryMXyk8G8/HmPkwPPkMqIIDhrXHHYqfUzSJA/I7IWSBv8xSmRBA==", + "version": "4.62.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.62.3.tgz", + "integrity": "sha512-gNoxRefktVIiGflpONuxWWXZAzIQG++z9qHO3xKwk4WdDMuQja3JHGfE1u0i3PfPDyvhypdk+WrgIJqLhGG7sg==", "cpu": [ "s390x" ], @@ -4511,9 +4534,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.61.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.61.0.tgz", - "integrity": "sha512-0uMOcf3eZ5K+K4cYHkdxShFMPlPXCOdfDFEFn9dNYAEEd2cVvmOfH7zFgRVoDgmtQ1m9k5q7qfrHzyMAubKYUA==", + "version": "4.62.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.62.3.tgz", + "integrity": "sha512-V4KtWtQfAFMU7+9/A/VDps/VI8CHd3cYz0L8sgJzz8qK7eY7wI4ruFD82UYIYvW9Z4DtlTfhQcsl4XyPHW5uSg==", "cpu": [ "x64" ], @@ -4527,9 +4550,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.61.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.61.0.tgz", - "integrity": "sha512-mvFtE4A/t/7hRJ7X8Ozmu8FsIkAUat2nzl12pgU337BRmq87AQUJztwHz2Zv5/tjo9/C95E66CK03SI/ToEDJw==", + "version": "4.62.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.62.3.tgz", + "integrity": "sha512-LBx9LYXvj2CBkMkjLdNAWLwH0MLMin7do2VcVo9kVPibGLkY0BQQut2fv7NVqkXqZ/CrAu9LqDHVV1xHCMpCPw==", "cpu": [ "x64" ], @@ -4543,9 +4566,9 @@ ] }, "node_modules/@rollup/rollup-openbsd-x64": { - "version": "4.61.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.61.0.tgz", - "integrity": "sha512-z9b9+aTxvt8n2rNltMPvyaUfB8NJ+CVyOrGK/MdIKHx7B+lXmZpm/XbRsU7Rpf3fRqJ2uS6mBJiJveCtq8LHDg==", + "version": "4.62.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.62.3.tgz", + "integrity": "sha512-ABVf3Q0RCu7NcyCCOZQI0pJ3GuSdfSl8EXcy88QtdceIMIoCUdfhsJChZ64L9zVM2aJHjde1Bhn5uqSRcX9ySA==", "cpu": [ "x64" ], @@ -4556,9 +4579,9 @@ ] }, "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.61.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.61.0.tgz", - "integrity": "sha512-jXaXFqKMehsOc+g8R6oo33RRC6w07G9jDBxAE5eAKX7mOcCbZloYIPNhfG9Wl+P9O9IWHFO4OJgPi1Ml2qkt7w==", + "version": "4.62.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.62.3.tgz", + "integrity": "sha512-+2Cy/ldweGBLlPIKsQLF8U5N44a0KDdbrk1rAjHOM9M2K+kGdIVjHLmmrZIcx+9Ny3ke/1JomCsDI1ocb11+sg==", "cpu": [ "arm64" ], @@ -4569,9 +4592,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.61.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.61.0.tgz", - "integrity": "sha512-OXNWVFocS2IA4+QplhTZZ2a+8hPZR7T8KuozsNmJKK8y7cp83StHvGksfHzPG3wczWTczyWHVQuqeiTUbjiyBg==", + "version": "4.62.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.62.3.tgz", + "integrity": "sha512-dtZvzc8BedpSaFNy75x6uiWwAGTH+aZHDtdrqP6qk+WcLJrfti6sGje1ZJ9UxyzDLF23d/mV+PaMwuC0hL7UVA==", "cpu": [ "arm64" ], @@ -4582,9 +4605,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.61.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.61.0.tgz", - "integrity": "sha512-AlAbNtBO637LxSldqV43z0FfXoGfl2TW1DgAg/bs7aQswFbDewz2SJm3BUhiGfbOVtW571xbc9p+REdxhyN/Eg==", + "version": "4.62.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.62.3.tgz", + "integrity": "sha512-Rj8Ra4noo+aYy7sKBggCx0407mws34kAb1ySyWuq5DAtFBQdkSwnsjCgPrhPe9cvgBKZIukpE+CVHvORCS93kQ==", "cpu": [ "ia32" ], @@ -4595,9 +4618,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-gnu": { - "version": "4.61.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.61.0.tgz", - "integrity": "sha512-QRSrQXyJ1M4tjNXdR0/G/IgV6lzfQQJYBjlWIEYkY2Xs86DRl/iEpQ4blMDjJxSl7n19eDKKXMg0AmuBVYy8pQ==", + "version": "4.62.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.62.3.tgz", + "integrity": "sha512-vp7N084ew/odXn2gi/mzm9mUkQu9l6AiN6dt4IeUM2Uvm9o+cVmP+YkqbMOteLbiGgqBBlJZjIMYVCfOOIVbVQ==", "cpu": [ "x64" ], @@ -4608,9 +4631,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.61.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.61.0.tgz", - "integrity": "sha512-tkuFxhvKO/HlGd0VsINF6vHSYH8AF8W0TcNxKDK6JZmrehngFj78pToc8iemtnvwilDjs2G/qSzYFhe9U8q+fw==", + "version": "4.62.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.62.3.tgz", + "integrity": "sha512-MOG/3gTOn4Fwf574RVOaY61I5o6P90legkFADiTyn1hyjNydT+cerU2rLUwPdZkKKyJ+iT+K9p7WXK4LM1Ka6g==", "cpu": [ "x64" ], @@ -4628,35 +4651,35 @@ "license": "MIT" }, "node_modules/@scalar/client-side-rendering": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/@scalar/client-side-rendering/-/client-side-rendering-0.1.12.tgz", - "integrity": "sha512-prwHK4ozTU268BHZ/5OstoKB23JSidDuvddAOp0bVz9c29ZxsyzzxPtPcVgF7X16LiZnS1OzY030FoDCM+iC9Q==", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@scalar/client-side-rendering/-/client-side-rendering-0.3.5.tgz", + "integrity": "sha512-0MX6HN4hNhMlBTqm+PJ1Rgi5yQy7NkMEPMa6QXdyKAO59pQVzWlBGT+MlAnyXCeVrqFULzZh90v81t5UQ/uYEw==", "license": "MIT", "dependencies": { - "@scalar/schemas": "0.3.2", - "@scalar/types": "0.12.2", - "@scalar/validation": "0.6.0" + "@scalar/schemas": "0.8.0", + "@scalar/types": "0.17.0", + "@scalar/validation": "0.6.2" }, "engines": { "node": ">=22" } }, "node_modules/@scalar/helpers": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@scalar/helpers/-/helpers-0.8.0.tgz", - "integrity": "sha512-gmOC6VravNB9VDl6wnt/GOj4K/hn48tj5bpW4AM4MhH8Ubil6uu7g1DSoKHwltu8Ks79KEtR6JmOrROi9R7jaQ==", + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/@scalar/helpers/-/helpers-0.9.2.tgz", + "integrity": "sha512-hjyMpMZjTBZQhyByZmz5oUgRKUQJO5V5AOiJxsVEGbUmgA7sJRQeTrXLB+BEwzaKS5nm2opJeNyMBYLFNK4hiQ==", "license": "MIT", "engines": { "node": ">=22" } }, "node_modules/@scalar/nextjs-api-reference": { - "version": "0.10.19", - "resolved": "https://registry.npmjs.org/@scalar/nextjs-api-reference/-/nextjs-api-reference-0.10.19.tgz", - "integrity": "sha512-+8e20fM+vPCg0sQfpJJVfB2QT2rSli1XPPpwVqyP2NyOqKskZx33ixdh5/I1VhlRPECgy8M+qSwVu0E6v5iV1w==", + "version": "0.11.12", + "resolved": "https://registry.npmjs.org/@scalar/nextjs-api-reference/-/nextjs-api-reference-0.11.12.tgz", + "integrity": "sha512-JTzoTSMCvdQGae/ECL1sOCBe9/lo50Fk87Pb93JKubFXo5SHSsPcpWX0dFWwyoamlH0UpgHqEUw3xljFpmAbNw==", "license": "MIT", "dependencies": { - "@scalar/client-side-rendering": "0.1.12" + "@scalar/client-side-rendering": "0.3.5" }, "engines": { "node": ">=22" @@ -4667,25 +4690,25 @@ } }, "node_modules/@scalar/schemas": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@scalar/schemas/-/schemas-0.3.2.tgz", - "integrity": "sha512-iadXBgJ02XUU5C5s6/xh/PmGLzUPd7X8upXIvPWBXDcQ4FHACNgkG8PPZ/beYM8UPDDkTUPM3ygEs0G6jKwGjQ==", + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@scalar/schemas/-/schemas-0.8.0.tgz", + "integrity": "sha512-bwu/NCOghZI/cL6Ayti/Oeb5XEMRTncBsyQeHhkFwk4PZsR910me+kZPd5TAp6TqifMfDbAe3xyLSdlzU/KFLA==", "license": "MIT", "dependencies": { - "@scalar/helpers": "0.8.0", - "@scalar/validation": "0.6.0" + "@scalar/helpers": "0.9.2", + "@scalar/validation": "0.6.2" }, "engines": { "node": ">=22" } }, "node_modules/@scalar/types": { - "version": "0.12.2", - "resolved": "https://registry.npmjs.org/@scalar/types/-/types-0.12.2.tgz", - "integrity": "sha512-EzLkubCb7xioiTm9eYnmn/032akaq4kkrrdclgV2uezwtniR8ErQICjhMl2AjBWL6nstHiFZ9RnPZm2Z2/KM0Q==", + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@scalar/types/-/types-0.17.0.tgz", + "integrity": "sha512-mj033MX0EFOEwfpO3ch7FGGnMbye1aLlnP6LmTC9Il2AlBCDL41rYPk67jF5ICAMsAES1RQ+8N2bcC0MJnupLQ==", "license": "MIT", "dependencies": { - "@scalar/helpers": "0.8.0", + "@scalar/helpers": "0.9.2", "nanoid": "^5.1.6", "type-fest": "^5.3.1", "zod": "^4.3.5" @@ -4695,9 +4718,9 @@ } }, "node_modules/@scalar/validation": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/@scalar/validation/-/validation-0.6.0.tgz", - "integrity": "sha512-tpmmG+/xRE2Kn9RpflU3AIyZv08v10+E1ZrJCx7z6+/91zHVxy0M73kC1LT4/8PbYNt85ywyC8+n+D99JdMcGA==", + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/@scalar/validation/-/validation-0.6.2.tgz", + "integrity": "sha512-Sc1TkcwGV6aVCO51AyKeaGiP8gpwAHxEtO5d3tZzPV+KsnlC/YokQxFxwBrbIXw73k9hmcExnJyGu3k5i6n6VA==", "license": "MIT", "engines": { "node": ">=20" @@ -4716,76 +4739,40 @@ "url": "https://ko-fi.com/killymxi" } }, - "node_modules/@sentry-internal/browser-utils": { - "version": "10.55.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/browser-utils/-/browser-utils-10.55.0.tgz", - "integrity": "sha512-zUvyBr13EK0evKsSTzwSimRzZ3P9kugS32dLCj3ea5gNN+/DFtU/GsMTdcIQDhusEDraIlH17AGgqJH5gUAv5w==", - "license": "MIT", - "dependencies": { - "@sentry/core": "10.55.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/@sentry-internal/feedback": { - "version": "10.55.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-10.55.0.tgz", - "integrity": "sha512-32X9WW1xs5DjCRlp89QJ/PLw4kbTIX6MsBDXN2RBN1nWBjm/2WcwXqO/v/WoIS4W2kTWXcZnQwalLSI22Fp33A==", - "license": "MIT", - "dependencies": { - "@sentry/core": "10.55.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/@sentry-internal/replay": { - "version": "10.55.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/replay/-/replay-10.55.0.tgz", - "integrity": "sha512-OkQpANGwYU5UKfwLk6Y+NpESRC8nrLBjawRDLwF6cJ8HpNScOuNNJDEJEGwXHVkJPH0pcIixsH8y0Qfcltq6Xw==", + "node_modules/@sentry/babel-plugin-component-annotate": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@sentry/babel-plugin-component-annotate/-/babel-plugin-component-annotate-5.3.0.tgz", + "integrity": "sha512-p4q8gn8wcFqZGP/s2MnJCAAd8fTikaU6A0mM97RDHQgStcrYiaS0Sc5zUNfb1V+UOLPuvdEdL6MwyxfzjYJQTA==", "license": "MIT", - "dependencies": { - "@sentry-internal/browser-utils": "10.55.0", - "@sentry/core": "10.55.0" - }, "engines": { - "node": ">=18" + "node": ">= 18" } }, - "node_modules/@sentry-internal/replay-canvas": { - "version": "10.55.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-10.55.0.tgz", - "integrity": "sha512-lu/y7k9cK7FZ/qJpL0fBX4WqK6IFa/+bTPhedEaC5UpzjUNP7BfXt0H+R7q9CHWmp20Ffh/wGfO3j7O+Tv2MAA==", + "node_modules/@sentry/browser": { + "version": "10.69.0", + "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-10.69.0.tgz", + "integrity": "sha512-8391tnm96YbR7b8SYfEA/NEIZuyb2r3SZrtAT0bhZtjlujcYWjo7gugQvk8sWLU9cAa/euD00eJoIoJvNfpd7Q==", "license": "MIT", "dependencies": { - "@sentry-internal/replay": "10.55.0", - "@sentry/core": "10.55.0" + "@sentry/browser-utils": "10.69.0", + "@sentry/conventions": "^0.16.0", + "@sentry/core": "10.69.0", + "@sentry/feedback": "10.69.0", + "@sentry/replay": "10.69.0", + "@sentry/replay-canvas": "10.69.0" }, "engines": { "node": ">=18" } }, - "node_modules/@sentry/babel-plugin-component-annotate": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@sentry/babel-plugin-component-annotate/-/babel-plugin-component-annotate-5.3.0.tgz", - "integrity": "sha512-p4q8gn8wcFqZGP/s2MnJCAAd8fTikaU6A0mM97RDHQgStcrYiaS0Sc5zUNfb1V+UOLPuvdEdL6MwyxfzjYJQTA==", - "license": "MIT", - "engines": { - "node": ">= 18" - } - }, - "node_modules/@sentry/browser": { - "version": "10.55.0", - "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-10.55.0.tgz", - "integrity": "sha512-5n1kxmW1m4j16ZDV9kt+Zo5uafFnKTy7s5YyEcGnC45KnOiO1Gy+QFd3woXns1K5GNxpjF7oOOc6tXgZLuXnQQ==", + "node_modules/@sentry/browser-utils": { + "version": "10.69.0", + "resolved": "https://registry.npmjs.org/@sentry/browser-utils/-/browser-utils-10.69.0.tgz", + "integrity": "sha512-e/u1Abj0zRPwR/deGZAP3GOULrsx67/XXnM5Skniqs4uxTsdNtPek1Nef0tpxwaQJYxwh6pWdhswLPPbbPOgBQ==", "license": "MIT", "dependencies": { - "@sentry-internal/browser-utils": "10.55.0", - "@sentry-internal/feedback": "10.55.0", - "@sentry-internal/replay": "10.55.0", - "@sentry-internal/replay-canvas": "10.55.0", - "@sentry/core": "10.55.0" + "@sentry/conventions": "^0.16.0", + "@sentry/core": "10.69.0" }, "engines": { "node": ">=18" @@ -4809,6 +4796,48 @@ "node": ">= 18" } }, + "node_modules/@sentry/bundler-plugins": { + "version": "10.69.0", + "resolved": "https://registry.npmjs.org/@sentry/bundler-plugins/-/bundler-plugins-10.69.0.tgz", + "integrity": "sha512-I1otnSJIH4IOugLp+kcBbT0Kcex+J8xnHuUyzMAwCYSpZ0FMVvA723uNmkMdW0PxRRw0oEhe0qDB+t+ZjHxUiA==", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.18.5", + "@sentry/cli": "^2.58.6", + "@sentry/core": "10.69.0", + "dotenv": "^17.4.2", + "find-up": "^5.0.0", + "glob": "^13.0.6", + "magic-string": "~0.30.8" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "rollup": ">=3.2.0", + "webpack": ">=5.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/@sentry/bundler-plugins/node_modules/dotenv": { + "version": "17.4.2", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.4.2.tgz", + "integrity": "sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, "node_modules/@sentry/cli": { "version": "2.58.6", "resolved": "https://registry.npmjs.org/@sentry/cli/-/cli-2.58.6.tgz", @@ -4974,31 +5003,56 @@ "node": ">=10" } }, + "node_modules/@sentry/conventions": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/@sentry/conventions/-/conventions-0.16.0.tgz", + "integrity": "sha512-fO9PLmHdVURcSPUpWCItWAtgKiMwGdJHbovoSEyLplX5sxs2ugvI4CBPTrkkgqhObnZOD0CnWBKDzSVQYBKEyQ==", + "license": "MIT", + "engines": { + "node": ">=14" + } + }, "node_modules/@sentry/core": { - "version": "10.55.0", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-10.55.0.tgz", - "integrity": "sha512-XUyoNtDSYCvgJnoNzlh+YeAXfIPhCRIXbhWqqM3GQ3AFtZICi85lkyfsrwXEl9wzlPGYnU+Eg8F4tOfScx+FcQ==", + "version": "10.69.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-10.69.0.tgz", + "integrity": "sha512-+uuqVEeiDzYuAKjZLqsROKXvRTbl/QeH0gfGRtpYib1cud4rAFWRIkFmcR7Jb7JGFYwmReyQotiTj/hcDszTZg==", "license": "MIT", + "dependencies": { + "@sentry/conventions": "^0.16.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@sentry/feedback": { + "version": "10.69.0", + "resolved": "https://registry.npmjs.org/@sentry/feedback/-/feedback-10.69.0.tgz", + "integrity": "sha512-qrGz5Qaw93/IhMjlFN6uIaXeHwgHDaKGa6FkTAP6PonpkvSbGGqan6xfsENxzj9HUVoli1lZ6tMRDnt2qtSPhg==", + "license": "MIT", + "dependencies": { + "@sentry/core": "10.69.0" + }, "engines": { "node": ">=18" } }, "node_modules/@sentry/nextjs": { - "version": "10.55.0", - "resolved": "https://registry.npmjs.org/@sentry/nextjs/-/nextjs-10.55.0.tgz", - "integrity": "sha512-ODiv6hy7+gmINFvbWAVaCqtxT2ceFW7AW65amy34z3fCgld9+LHTP2++p4g2LmQb/mYQPIbJrVEfJoqGASK4EQ==", + "version": "10.69.0", + "resolved": "https://registry.npmjs.org/@sentry/nextjs/-/nextjs-10.69.0.tgz", + "integrity": "sha512-48eYXezKAmSlSWtBsvwXvdHHHavXRDVIVZ3mI5vidhJwhqSs0ekwG0ZsPG3xNdaJLmnNEmavHEVupSbuuOTZZA==", "license": "MIT", "dependencies": { "@opentelemetry/api": "^1.9.1", - "@opentelemetry/semantic-conventions": "^1.40.0", "@rollup/plugin-commonjs": "28.0.1", - "@sentry-internal/browser-utils": "10.55.0", + "@sentry/browser-utils": "10.69.0", "@sentry/bundler-plugin-core": "^5.3.0", - "@sentry/core": "10.55.0", - "@sentry/node": "10.55.0", - "@sentry/opentelemetry": "10.55.0", - "@sentry/react": "10.55.0", - "@sentry/vercel-edge": "10.55.0", + "@sentry/conventions": "^0.16.0", + "@sentry/core": "10.69.0", + "@sentry/node": "10.69.0", + "@sentry/opentelemetry": "10.69.0", + "@sentry/react": "10.69.0", + "@sentry/server-utils": "10.69.0", + "@sentry/vercel-edge": "10.69.0", "@sentry/webpack-plugin": "^5.3.0", "rollup": "^4.60.3", "stacktrace-parser": "^0.1.11" @@ -5011,19 +5065,19 @@ } }, "node_modules/@sentry/node": { - "version": "10.55.0", - "resolved": "https://registry.npmjs.org/@sentry/node/-/node-10.55.0.tgz", - "integrity": "sha512-+fB/ByoHVWPLGgoafYciiMatTNyX1FHj1bsqZBN+Pw3McbuEU1nwCPLt9zuyZZiWlQtXKsyuACS4ZhXnID5l8A==", + "version": "10.69.0", + "resolved": "https://registry.npmjs.org/@sentry/node/-/node-10.69.0.tgz", + "integrity": "sha512-xEXA1YGIiTZbrW6MWV34uS6JGQuQg2ijTI0zed+FsJb9JZKPYel/GZK8Km26vfTVb+yCXFmWZNBesKegNcVdzg==", "license": "MIT", "dependencies": { "@opentelemetry/api": "^1.9.1", - "@opentelemetry/core": "^2.6.1", - "@opentelemetry/instrumentation": "^0.214.0", - "@opentelemetry/sdk-trace-base": "^2.6.1", - "@opentelemetry/semantic-conventions": "^1.40.0", - "@sentry/core": "10.55.0", - "@sentry/node-core": "10.55.0", - "@sentry/opentelemetry": "10.55.0", + "@opentelemetry/instrumentation": "^0.220.0", + "@opentelemetry/sdk-trace-base": "^2.9.0", + "@sentry/conventions": "^0.16.0", + "@sentry/core": "10.69.0", + "@sentry/node-core": "10.69.0", + "@sentry/opentelemetry": "10.69.0", + "@sentry/server-utils": "10.69.0", "import-in-the-middle": "^3.0.0" }, "engines": { @@ -5031,13 +5085,14 @@ } }, "node_modules/@sentry/node-core": { - "version": "10.55.0", - "resolved": "https://registry.npmjs.org/@sentry/node-core/-/node-core-10.55.0.tgz", - "integrity": "sha512-M8XMMIk9Y0PGZoEt37Oe5dQCdqDdJlBcwLXidpz/s5k4QtJvCO/BbtcivcuKI2htw5FwxJkSrHUzRvT36tlDpg==", + "version": "10.69.0", + "resolved": "https://registry.npmjs.org/@sentry/node-core/-/node-core-10.69.0.tgz", + "integrity": "sha512-IgArHczrZJxkgxoffHscj0NxQrG6kCazgmGQnlf3j58J1ec21YaUu8Tu+7G4Lo5tCiW3teQnwlKW1ttMXSqWRw==", "license": "MIT", "dependencies": { - "@sentry/core": "10.55.0", - "@sentry/opentelemetry": "10.55.0", + "@sentry/conventions": "^0.16.0", + "@sentry/core": "10.69.0", + "@sentry/opentelemetry": "10.69.0", "import-in-the-middle": "^3.0.0" }, "engines": { @@ -5048,8 +5103,7 @@ "@opentelemetry/core": "^1.30.1 || ^2.1.0", "@opentelemetry/exporter-trace-otlp-http": ">=0.57.0 <1", "@opentelemetry/instrumentation": ">=0.57.1 <1", - "@opentelemetry/sdk-trace-base": "^1.30.1 || ^2.1.0", - "@opentelemetry/semantic-conventions": "^1.39.0" + "@opentelemetry/sdk-trace-base": "^1.30.1 || ^2.1.0" }, "peerDependenciesMeta": { "@opentelemetry/api": { @@ -5066,19 +5120,17 @@ }, "@opentelemetry/sdk-trace-base": { "optional": true - }, - "@opentelemetry/semantic-conventions": { - "optional": true } } }, "node_modules/@sentry/opentelemetry": { - "version": "10.55.0", - "resolved": "https://registry.npmjs.org/@sentry/opentelemetry/-/opentelemetry-10.55.0.tgz", - "integrity": "sha512-0+YrNmVNrttki4rWP4DW+UTt5MziepwDLNBde39tgc3cGCcy5fLSdDfhb4JfTaE5TXt4kd5XrkgvS/sDgm3RZg==", + "version": "10.69.0", + "resolved": "https://registry.npmjs.org/@sentry/opentelemetry/-/opentelemetry-10.69.0.tgz", + "integrity": "sha512-3FyWV6YcEJuvLrlaKGE1dHXCI+1YO0a62w7PkwlRg8yp6K6YXkmdwu9GjqaYD+Ju4tm7uC7mHIsGFQMm0M7pqQ==", "license": "MIT", "dependencies": { - "@sentry/core": "10.55.0" + "@sentry/conventions": "^0.16.0", + "@sentry/core": "10.69.0" }, "engines": { "node": ">=18" @@ -5086,18 +5138,18 @@ "peerDependencies": { "@opentelemetry/api": "^1.9.0", "@opentelemetry/core": "^1.30.1 || ^2.1.0", - "@opentelemetry/sdk-trace-base": "^1.30.1 || ^2.1.0", - "@opentelemetry/semantic-conventions": "^1.39.0" + "@opentelemetry/sdk-trace-base": "^1.30.1 || ^2.1.0" } }, "node_modules/@sentry/react": { - "version": "10.55.0", - "resolved": "https://registry.npmjs.org/@sentry/react/-/react-10.55.0.tgz", - "integrity": "sha512-cf6wI0W1FdrL/7d5FTHXUdTN5k5uRZ9AQu5QZxUujnxWN+DBxUWtow1HDD1zTEonQsCFyYuhXVu3w+qmBBW11A==", + "version": "10.69.0", + "resolved": "https://registry.npmjs.org/@sentry/react/-/react-10.69.0.tgz", + "integrity": "sha512-f0Il/JMteHjdWPNZQB3rtp1Pcj2Leb3p0KSZuv3rh0EUril9CbWtQVy5zJhoAppi+MWWmgRWa+6BpHbQf+ABQA==", "license": "MIT", "dependencies": { - "@sentry/browser": "10.55.0", - "@sentry/core": "10.55.0" + "@sentry/browser": "10.69.0", + "@sentry/conventions": "^0.16.0", + "@sentry/core": "10.69.0" }, "engines": { "node": ">=18" @@ -5106,48 +5158,89 @@ "react": "^16.14.0 || 17.x || 18.x || 19.x" } }, - "node_modules/@sentry/vercel-edge": { - "version": "10.55.0", - "resolved": "https://registry.npmjs.org/@sentry/vercel-edge/-/vercel-edge-10.55.0.tgz", - "integrity": "sha512-IB8MBTdCHnuUtxHWh39Ecr9/TvMqSYW9BOO7ExnByDjHhfXOzQnEs6VJvEEIwSyUEl1yIz1Y3WdOlY9I6lqeMA==", + "node_modules/@sentry/replay": { + "version": "10.69.0", + "resolved": "https://registry.npmjs.org/@sentry/replay/-/replay-10.69.0.tgz", + "integrity": "sha512-uRhmNhtFGPOlM0iniVmWKAX3KVXI0le41yYK/iKdPjinT9jA3ZrmykO/Fv1v/KI5znOtwa9D6eHRnDTTMRxFrg==", "license": "MIT", "dependencies": { - "@opentelemetry/api": "^1.9.1", - "@opentelemetry/resources": "^2.6.1", - "@sentry/core": "10.55.0" + "@sentry/browser-utils": "10.69.0", + "@sentry/core": "10.69.0" }, "engines": { "node": ">=18" } }, - "node_modules/@sentry/webpack-plugin": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@sentry/webpack-plugin/-/webpack-plugin-5.3.0.tgz", - "integrity": "sha512-i3OQUrS0FZlXLgq57RIKDp+vHHzuvYKPCKewAPXULWKMsBXFGhP6veGRQ+6To/pmZkkXjEX5ofVNDy9C3jEPKQ==", + "node_modules/@sentry/replay-canvas": { + "version": "10.69.0", + "resolved": "https://registry.npmjs.org/@sentry/replay-canvas/-/replay-canvas-10.69.0.tgz", + "integrity": "sha512-VF6nXvSninHcc7dC1Zme0RjkC7VgRMCixs6jKaQX5zTNeqTW3dZGSefSOVv+ZteRi3hJvVORq985VjUC9Z/0+A==", "license": "MIT", "dependencies": { - "@sentry/bundler-plugin-core": "5.3.0" + "@sentry/core": "10.69.0", + "@sentry/replay": "10.69.0" }, "engines": { - "node": ">= 18" + "node": ">=18" + } + }, + "node_modules/@sentry/server-utils": { + "version": "10.69.0", + "resolved": "https://registry.npmjs.org/@sentry/server-utils/-/server-utils-10.69.0.tgz", + "integrity": "sha512-0MwHrA8+nNvMIsqf8m3cXwCBlUjr6AS7N6CZvHJtY1DkqEvQqEbD5VIrhzEyHN/KMZIgQ8XeDCQRhjnXFQGRhg==", + "license": "MIT", + "dependencies": { + "@apm-js-collab/code-transformer-bundler-plugins": "^0.7.3", + "@apm-js-collab/tracing-hooks": "^0.13.0", + "@sentry/conventions": "^0.16.0", + "@sentry/core": "10.69.0", + "meriyah": "^6.1.4" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@sentry/vercel-edge": { + "version": "10.69.0", + "resolved": "https://registry.npmjs.org/@sentry/vercel-edge/-/vercel-edge-10.69.0.tgz", + "integrity": "sha512-P3IsZyM3j8s4sGuxnGn1+EScVZHABsuzqv0NzIUen61ml0x+c6F6XXobvMhMcRp98fIQe1hZBpzH0VNxc7eCIA==", + "license": "MIT", + "dependencies": { + "@opentelemetry/api": "^1.9.1", + "@sentry/core": "10.69.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@sentry/webpack-plugin": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@sentry/webpack-plugin/-/webpack-plugin-5.4.0.tgz", + "integrity": "sha512-J3a0BvUZ75Qxy+v/Ap3Hx4ZEcSjlPHZ/jDtxdRhXQCyNeEb8xq0uUBTI9VLtGk2eNeNucOxOEJ5ngqdNjnEH/A==", + "license": "MIT", + "dependencies": { + "@sentry/bundler-plugins": "^10.64.0" + }, + "engines": { + "node": ">= 18" }, "peerDependencies": { "webpack": ">=5.0.0" } }, "node_modules/@serwist/build": { - "version": "9.5.11", - "resolved": "https://registry.npmjs.org/@serwist/build/-/build-9.5.11.tgz", - "integrity": "sha512-PQfW+LhADYFOOp0PhEnjlgJCyKor6cYa06d3rID1OpiKzkmCApJV1WYfdTBB96jXaWv6OWcWSbSV4tqDLxvaVA==", + "version": "9.5.12", + "resolved": "https://registry.npmjs.org/@serwist/build/-/build-9.5.12.tgz", + "integrity": "sha512-U2UkA9BjdpniZkXDIG6NQRBEbXccRvqewzL3hfNEQERvM2bL6ezKvsVF9359akUWP8BxV950Kkq9LKGFmOR8Uw==", "license": "MIT", "dependencies": { - "@serwist/utils": "9.5.11", + "@serwist/utils": "9.5.12", "common-tags": "1.8.2", "glob": "13.0.6", "pretty-bytes": "6.1.1", - "source-map": "0.8.0-beta.0", - "type-fest": "5.6.0", - "zod": "4.4.1" + "source-map": "0.8.0", + "type-fest": "5.8.0", + "zod": "4.4.3" }, "engines": { "node": ">=18.0.0" @@ -5161,52 +5254,28 @@ } } }, - "node_modules/@serwist/build/node_modules/type-fest": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-5.6.0.tgz", - "integrity": "sha512-8ZiHFm91orbSAe2PSAiSVBVko18pbhbiB3U9GglSzF/zCGkR+rxpHx6sEMCUm4kxY4LjDIUGgCfUMtwfZfjfUA==", - "license": "(MIT OR CC0-1.0)", - "dependencies": { - "tagged-tag": "^1.0.0" - }, - "engines": { - "node": ">=20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@serwist/build/node_modules/zod": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/zod/-/zod-4.4.1.tgz", - "integrity": "sha512-a6ENMBBGZBsnlSebQ/eKCguSBeGKSf4O7BPnqVPmYGtpBYI7VSqoVqw+QcB7kPRjbqPwhYTpFbVj/RqNz/CT0Q==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } - }, "node_modules/@serwist/next": { - "version": "9.5.11", - "resolved": "https://registry.npmjs.org/@serwist/next/-/next-9.5.11.tgz", - "integrity": "sha512-omT32H7U21ihCymSvOG9QeRJBuOEomJx4JdzKhUoqOW3DR10tH3m84VOHj3BvK0OcA7av3qj5FsyNFBB+f0n8A==", + "version": "9.5.12", + "resolved": "https://registry.npmjs.org/@serwist/next/-/next-9.5.12.tgz", + "integrity": "sha512-aKSDZmxC2w6mvLC1aOcO4OnZqdKIl4zrW2VndlZT12+m+nIyOWih1xqqw4LsvUGfQCx0AswtKUUQ7woRYZ2thg==", "license": "MIT", "dependencies": { - "@serwist/build": "9.5.11", - "@serwist/utils": "9.5.11", - "@serwist/webpack-plugin": "9.5.11", - "@serwist/window": "9.5.11", - "browserslist": "4.28.2", + "@serwist/build": "9.5.12", + "@serwist/utils": "9.5.12", + "@serwist/webpack-plugin": "9.5.12", + "@serwist/window": "9.5.12", + "browserslist": "4.28.6", "glob": "13.0.6", "kolorist": "1.8.0", - "semver": "7.7.4", - "serwist": "9.5.11", - "zod": "4.4.1" + "semver": "7.8.5", + "serwist": "9.5.12", + "zod": "4.4.3" }, "engines": { "node": ">=18.0.0" }, "peerDependencies": { - "@serwist/cli": "^9.5.11", + "@serwist/cli": "^9.5.12", "next": ">=14.0.0", "react": ">=18.0.0", "typescript": ">=5.0.0" @@ -5220,10 +5289,43 @@ } } }, + "node_modules/@serwist/next/node_modules/browserslist": { + "version": "4.28.6", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.6.tgz", + "integrity": "sha512-FQBYNK15VMslhLHpA7+n+n1GOlF1kId2xcCg7/j95f24AOF6VDYMNH4mFxF7KuaTdv627faazpOAjFzMrfJOUw==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.10.42", + "caniuse-lite": "^1.0.30001803", + "electron-to-chromium": "^1.5.389", + "node-releases": "^2.0.51", + "update-browserslist-db": "^1.2.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, "node_modules/@serwist/next/node_modules/semver": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -5232,19 +5334,10 @@ "node": ">=10" } }, - "node_modules/@serwist/next/node_modules/zod": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/zod/-/zod-4.4.1.tgz", - "integrity": "sha512-a6ENMBBGZBsnlSebQ/eKCguSBeGKSf4O7BPnqVPmYGtpBYI7VSqoVqw+QcB7kPRjbqPwhYTpFbVj/RqNz/CT0Q==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } - }, "node_modules/@serwist/utils": { - "version": "9.5.11", - "resolved": "https://registry.npmjs.org/@serwist/utils/-/utils-9.5.11.tgz", - "integrity": "sha512-zqxmwuHqWA3OwN82Wo8gFZ9QBemygJP3cap5JWAOG4UyJZgUZfmBXAXj+IMaD4eKZ/6pqrxHHDZ9uSWZmJ1mXA==", + "version": "9.5.12", + "resolved": "https://registry.npmjs.org/@serwist/utils/-/utils-9.5.12.tgz", + "integrity": "sha512-BHDwiGL7H7JS7wFvVlAWTFHGt0ffHuPgKtdkaYP0lEWJFl6fKJRCnTDZhwhusFvBhicf37XP8Y6PouTZbcLmgg==", "license": "MIT", "peerDependencies": { "browserslist": ">=4" @@ -5256,15 +5349,15 @@ } }, "node_modules/@serwist/webpack-plugin": { - "version": "9.5.11", - "resolved": "https://registry.npmjs.org/@serwist/webpack-plugin/-/webpack-plugin-9.5.11.tgz", - "integrity": "sha512-SlvO3A1UMcc1htCzMtLCtPQK6yISCO7B859ixLv7EiY/yayXjVxGm9vHqkJYpQ768PWyjEZXRY/X6EGRMA6wJQ==", + "version": "9.5.12", + "resolved": "https://registry.npmjs.org/@serwist/webpack-plugin/-/webpack-plugin-9.5.12.tgz", + "integrity": "sha512-+a5Fap7wVR4oN5jg1GxVNbWW+xUv3LO7UWYfg2D8PkJZiTCcX8PwkcmdzMGVr39dyOtIMTSAANw0af1zMjVbOA==", "license": "MIT", "dependencies": { - "@serwist/build": "9.5.11", - "@serwist/utils": "9.5.11", + "@serwist/build": "9.5.12", + "@serwist/utils": "9.5.12", "pretty-bytes": "6.1.1", - "zod": "4.4.1" + "zod": "4.4.3" }, "engines": { "node": ">=18.0.0" @@ -5282,23 +5375,14 @@ } } }, - "node_modules/@serwist/webpack-plugin/node_modules/zod": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/zod/-/zod-4.4.1.tgz", - "integrity": "sha512-a6ENMBBGZBsnlSebQ/eKCguSBeGKSf4O7BPnqVPmYGtpBYI7VSqoVqw+QcB7kPRjbqPwhYTpFbVj/RqNz/CT0Q==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } - }, "node_modules/@serwist/window": { - "version": "9.5.11", - "resolved": "https://registry.npmjs.org/@serwist/window/-/window-9.5.11.tgz", - "integrity": "sha512-OrH9srhmifUvY36NuukHSZby24XTEk4pHh3pfY0GBQzA9ouU1fYh+ORWhKxH7/wkVHRr3sc4YAhjtpfL14PjjQ==", + "version": "9.5.12", + "resolved": "https://registry.npmjs.org/@serwist/window/-/window-9.5.12.tgz", + "integrity": "sha512-+fjApJme34qfwdGE2kLT8sFx+xWO+a15477MN/B/b1v4HOWBmARuA9C2xGFBCT77XzCrzQ/2DxcDePZsqEYOlw==", "license": "MIT", "dependencies": { "@types/trusted-types": "2.0.7", - "serwist": "9.5.11" + "serwist": "9.5.12" }, "peerDependencies": { "typescript": ">=5.0.0" @@ -5334,21 +5418,21 @@ "license": "MIT" }, "node_modules/@supabase/auth-js": { - "version": "2.106.2", - "resolved": "https://registry.npmjs.org/@supabase/auth-js/-/auth-js-2.106.2.tgz", - "integrity": "sha512-VcAjUErkHkhC5Jaf+g/G1qbkQrFh8edaCdHa7pxJmHUjkWKjT7UnYCtPA89XV0N0GIYRkEqJZw5V62CtOxTmBQ==", + "version": "2.111.0", + "resolved": "https://registry.npmjs.org/@supabase/auth-js/-/auth-js-2.111.0.tgz", + "integrity": "sha512-hbRLgyQZEX0SDyF4LYXpv94qOIQyFATfpT5SIs2V0SisHnisVRkYgiPQWzv80l4S2mO3qof78rmoH9j5zoFsYQ==", "license": "MIT", "dependencies": { "tslib": "2.8.1" }, "engines": { - "node": ">=20.0.0" + "node": ">=22.0.0" } }, "node_modules/@supabase/cli-darwin-arm64": { - "version": "2.103.0", - "resolved": "https://registry.npmjs.org/@supabase/cli-darwin-arm64/-/cli-darwin-arm64-2.103.0.tgz", - "integrity": "sha512-BoOaHyoLuyOtmhxtRti7za3YYH9T05JenEla/zDXikqTiY5yDd63/1RxSF9mXt+ICFMkqHq3oFkFcDP5snumBQ==", + "version": "2.111.0", + "resolved": "https://registry.npmjs.org/@supabase/cli-darwin-arm64/-/cli-darwin-arm64-2.111.0.tgz", + "integrity": "sha512-H1ucZ+9Z37Ha7uqYrKHfAy1vXWMVsN4gNlKaOpjKUYoHwDEbueEHVIDA1/PBIUd4HX+usJfpq+R+gWqzM/FKqQ==", "cpu": [ "arm64" ], @@ -5360,9 +5444,9 @@ ] }, "node_modules/@supabase/cli-darwin-x64": { - "version": "2.103.0", - "resolved": "https://registry.npmjs.org/@supabase/cli-darwin-x64/-/cli-darwin-x64-2.103.0.tgz", - "integrity": "sha512-SLBb5lfmIF9G+FanWZQvKG6HQeUKFmMv8ls8ZVm6OnO87pLm4aRKLfFYjeXXtiBiRYMZRwxE/RwrRy0uXc0wqw==", + "version": "2.111.0", + "resolved": "https://registry.npmjs.org/@supabase/cli-darwin-x64/-/cli-darwin-x64-2.111.0.tgz", + "integrity": "sha512-4iMYm/XaAZJ8YzdJ2HBRVc7i9SRIwE6VQrnSt968WTt83M1y6knC7UENCKjMtO+As4QeZkICpUk50CeathqxbA==", "cpu": [ "x64" ], @@ -5374,9 +5458,9 @@ ] }, "node_modules/@supabase/cli-linux-arm64": { - "version": "2.103.0", - "resolved": "https://registry.npmjs.org/@supabase/cli-linux-arm64/-/cli-linux-arm64-2.103.0.tgz", - "integrity": "sha512-nk0fxTbQho+9OoUmIEBlgvEG69GmooMO1D8Ypt7SzgczNcLfYoCoKV9NMkQRUGi5jFXS5xFrRMPeSa/i3tNgwQ==", + "version": "2.111.0", + "resolved": "https://registry.npmjs.org/@supabase/cli-linux-arm64/-/cli-linux-arm64-2.111.0.tgz", + "integrity": "sha512-2KSHITFMXe2u5yALupBWHGeQ1IY4C8GkcIWPWgNFdtAPo03pgs1hLWgL1eeqSh/a0wB/6rgUlM1fQR/hAgCyCA==", "cpu": [ "arm64" ], @@ -5391,9 +5475,9 @@ ] }, "node_modules/@supabase/cli-linux-arm64-musl": { - "version": "2.103.0", - "resolved": "https://registry.npmjs.org/@supabase/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.103.0.tgz", - "integrity": "sha512-zn2N7t/Mx1LUE/knZvJfJwNHKKvEl5KCqob1fetfPXoPN/GcI0UnfJ+V/bkPjhpPA1b8htVhq4brHMcqpV80mA==", + "version": "2.111.0", + "resolved": "https://registry.npmjs.org/@supabase/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.111.0.tgz", + "integrity": "sha512-RnvbVlJ4TX/UIwLiglBVQ2eL4GAl9SfWZmM5LENXyIaohBcRZHDva5t2OyK+BPGBtngjVGpb3QyfLdvkt9yJcw==", "cpu": [ "arm64" ], @@ -5408,9 +5492,9 @@ ] }, "node_modules/@supabase/cli-linux-x64": { - "version": "2.103.0", - "resolved": "https://registry.npmjs.org/@supabase/cli-linux-x64/-/cli-linux-x64-2.103.0.tgz", - "integrity": "sha512-xk9ADh4D+luctRgscBzNvYLZa1qAw067IwateSE1AxhO3GOhdN6fiLZszl5LodO7CHmp54204dj+UcMct3KWFQ==", + "version": "2.111.0", + "resolved": "https://registry.npmjs.org/@supabase/cli-linux-x64/-/cli-linux-x64-2.111.0.tgz", + "integrity": "sha512-NwwNhiZZT4WYEPDXAbgZL+l77z/hoJ+w5t+52WBN1VlmoxwDmf2NP+UERM8wuCGFe/tmBlUuFE1eJYZfab0/qA==", "cpu": [ "x64" ], @@ -5425,9 +5509,9 @@ ] }, "node_modules/@supabase/cli-linux-x64-musl": { - "version": "2.103.0", - "resolved": "https://registry.npmjs.org/@supabase/cli-linux-x64-musl/-/cli-linux-x64-musl-2.103.0.tgz", - "integrity": "sha512-/fpuslo5ERFWJxbkRcpUFLV8T7087vOVU+clN2OeYTL8lgxVl04FPL3nW0qDgYeehb9GUeje5adgGvHYS006KA==", + "version": "2.111.0", + "resolved": "https://registry.npmjs.org/@supabase/cli-linux-x64-musl/-/cli-linux-x64-musl-2.111.0.tgz", + "integrity": "sha512-2QVpsy/3v+TzqE5GgTCPruoxTlF3d8QPGirjcnah8hP66nxXStB9yTvxmJq+LtO3gwMt1Kpm7is0roZVkV55Pw==", "cpu": [ "x64" ], @@ -5442,9 +5526,9 @@ ] }, "node_modules/@supabase/cli-windows-arm64": { - "version": "2.103.0", - "resolved": "https://registry.npmjs.org/@supabase/cli-windows-arm64/-/cli-windows-arm64-2.103.0.tgz", - "integrity": "sha512-oz1xMJ2bu/lfVV1WaNegGmzoxoEEaiBMg6g2Jm4aB6qCUgoIIkiXClghEnPotd0DWklpqFCOIp1lUb15mnjK6Q==", + "version": "2.111.0", + "resolved": "https://registry.npmjs.org/@supabase/cli-windows-arm64/-/cli-windows-arm64-2.111.0.tgz", + "integrity": "sha512-twawKY5xfU2dNOnZrKDmrudxRG/XIKcBxOb6X2lMGJU3N1Hd+8oWpI9TwM5Qv+eXehtlsKDmUvbitStXvJr/xQ==", "cpu": [ "arm64" ], @@ -5456,9 +5540,9 @@ ] }, "node_modules/@supabase/cli-windows-x64": { - "version": "2.103.0", - "resolved": "https://registry.npmjs.org/@supabase/cli-windows-x64/-/cli-windows-x64-2.103.0.tgz", - "integrity": "sha512-jueFJW/QmzWuVis2vGzeSDsrZ3gy5KIsq5vlpmhQF0bWpemgqP7buojPUiHCGSW6+9tTh8za8MraEy7HJGX/wQ==", + "version": "2.111.0", + "resolved": "https://registry.npmjs.org/@supabase/cli-windows-x64/-/cli-windows-x64-2.111.0.tgz", + "integrity": "sha512-1F+X5tAYxAGx93ZZoIQBnIQ2Q2NnplKqjpigAS/zpTsNaWAjNi7EnxmuQKaEoAdqOHKbLhegVVDiw1+us3ZVpA==", "cpu": [ "x64" ], @@ -5470,87 +5554,87 @@ ] }, "node_modules/@supabase/functions-js": { - "version": "2.106.2", - "resolved": "https://registry.npmjs.org/@supabase/functions-js/-/functions-js-2.106.2.tgz", - "integrity": "sha512-oRnr0QrL8H+zTO1YyQ1QjiHZU/957jvubbxSJTUm2XLAgzoGGV9Tahfyd+uvLsBLRVmXLtpU3oyCjdQIvkGMOA==", + "version": "2.111.0", + "resolved": "https://registry.npmjs.org/@supabase/functions-js/-/functions-js-2.111.0.tgz", + "integrity": "sha512-RW/OCsd6MO592zU8ifzP8/f8XzxxIdpb+Up5XaOtE26Fw+3zTp475WX7+GuuktiD1WF8pFUDe6khUPbMp77RCw==", "license": "MIT", "dependencies": { "tslib": "2.8.1" }, "engines": { - "node": ">=20.0.0" + "node": ">=22.0.0" } }, "node_modules/@supabase/phoenix": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@supabase/phoenix/-/phoenix-0.4.2.tgz", - "integrity": "sha512-YSAGnmDAfuleFCVt3CeurQZAhxRfXWeZIIkwp7NhYzQ1UwW6ePSnzsFAiUm/mbCkfoCf70QQHKW/K6RKh52a4A==", + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/@supabase/phoenix/-/phoenix-0.4.5.tgz", + "integrity": "sha512-aAn9H9ovVyeApKy11OWOrrOGq8DV68yWeH4ud2lN9fzn4aO8Zb5GLL9m1pUg9nLqIcT+ZDfAcsZe0E/nqdv2lw==", "license": "MIT" }, "node_modules/@supabase/postgrest-js": { - "version": "2.106.2", - "resolved": "https://registry.npmjs.org/@supabase/postgrest-js/-/postgrest-js-2.106.2.tgz", - "integrity": "sha512-tDOzyPgp9pIRMR2x6C9+uDSJrnXSzxLtt3d7nC+Lrsy3jnJDHYfdQC/xcRyhJE/TOBJ0heSqRKR3UmejDjZxsw==", + "version": "2.111.0", + "resolved": "https://registry.npmjs.org/@supabase/postgrest-js/-/postgrest-js-2.111.0.tgz", + "integrity": "sha512-pcqeDsnWP0lx9GawduYxNZJHeuTm53O7L0SC8RF8tniV3GWIPY6me6OTdnwzdwNUmNy1dzUVtSyIfE6+OflzPQ==", "license": "MIT", "dependencies": { "tslib": "2.8.1" }, "engines": { - "node": ">=20.0.0" + "node": ">=22.0.0" } }, "node_modules/@supabase/realtime-js": { - "version": "2.106.2", - "resolved": "https://registry.npmjs.org/@supabase/realtime-js/-/realtime-js-2.106.2.tgz", - "integrity": "sha512-LdRGT7DNhyZkPjubUv5bSdAZ0jSEX8wTHvx7htj7+K59TOZRvz4TuQK7tL2RWxyIZVeFMRluL04SzWS61rKnUA==", + "version": "2.111.0", + "resolved": "https://registry.npmjs.org/@supabase/realtime-js/-/realtime-js-2.111.0.tgz", + "integrity": "sha512-6oRf/vZyRwg8f8GbFSJkrD2w4HAu/yTvyMViHXHS+H5hNJzdXCrUR7cP5oW7daT3YlRnzRPY9LcGSJKZAmfMSg==", "license": "MIT", "dependencies": { - "@supabase/phoenix": "^0.4.2", + "@supabase/phoenix": "0.4.5", "tslib": "2.8.1" }, "engines": { - "node": ">=20.0.0" + "node": ">=22.0.0" } }, "node_modules/@supabase/ssr": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/@supabase/ssr/-/ssr-0.10.3.tgz", - "integrity": "sha512-ux2CJgX89h0Fz2lY7ZNafNG2SkXpyRc5dz77K9eKeBLPdtywQixKwIuetDeIViAJBp/buOUVmgj8PVesOklNpw==", + "version": "0.12.4", + "resolved": "https://registry.npmjs.org/@supabase/ssr/-/ssr-0.12.4.tgz", + "integrity": "sha512-xHzcgI8cC1TpBKSwJcR5Yd8CCwfIq0SBc5yb4yz/YFw5tbCrEQ0QT3a+2jymCxHgQWLfzwN93HZ6eRbcoMkOlA==", "license": "MIT", "dependencies": { "cookie": "^1.0.2" }, "peerDependencies": { - "@supabase/supabase-js": "^2.105.3" + "@supabase/supabase-js": "^2.111.0" } }, "node_modules/@supabase/storage-js": { - "version": "2.106.2", - "resolved": "https://registry.npmjs.org/@supabase/storage-js/-/storage-js-2.106.2.tgz", - "integrity": "sha512-xgKCSYuev1YarV+iVqr+zlfgSyremnJtn8T0NCT8L4XmMv1CLtESc0Q6kNp8+mKWdX/8ND0nzm7OMKx08kwNAw==", + "version": "2.111.0", + "resolved": "https://registry.npmjs.org/@supabase/storage-js/-/storage-js-2.111.0.tgz", + "integrity": "sha512-UEViNmTzVOxE8dqUA81wls+n9xgmlvSFfhfwo6QxrO4kQOytCYyw3ciYFoi4XoD4Jl95NJ3jnndHN5iIudWzqw==", "license": "MIT", "dependencies": { "iceberg-js": "^0.8.1", "tslib": "2.8.1" }, "engines": { - "node": ">=20.0.0" + "node": ">=22.0.0" } }, "node_modules/@supabase/supabase-js": { - "version": "2.106.2", - "resolved": "https://registry.npmjs.org/@supabase/supabase-js/-/supabase-js-2.106.2.tgz", - "integrity": "sha512-2/RZ/1fmJx/MRSEDG2Xk8+J4JVk5clM9V0uSI6kUTrcS32KA89DtqI5RUOC9r6mzY3WBC9qexLjssIHjbLyVJA==", + "version": "2.111.0", + "resolved": "https://registry.npmjs.org/@supabase/supabase-js/-/supabase-js-2.111.0.tgz", + "integrity": "sha512-9q0/AULthQnWeiDh1vGyjoJZbSY04bu6qHcWit70pqEYn5Kv/dkCPY62Ja1123jEnJbB9Vd2pjY7Kvk/lK3peA==", "license": "MIT", "dependencies": { - "@supabase/auth-js": "2.106.2", - "@supabase/functions-js": "2.106.2", - "@supabase/postgrest-js": "2.106.2", - "@supabase/realtime-js": "2.106.2", - "@supabase/storage-js": "2.106.2" + "@supabase/auth-js": "2.111.0", + "@supabase/functions-js": "2.111.0", + "@supabase/postgrest-js": "2.111.0", + "@supabase/realtime-js": "2.111.0", + "@supabase/storage-js": "2.111.0" }, "engines": { - "node": ">=20.0.0" + "node": ">=22.0.0" } }, "node_modules/@swc/helpers": { @@ -5563,49 +5647,49 @@ } }, "node_modules/@tailwindcss/node": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.3.0.tgz", - "integrity": "sha512-aFb4gUhFOgdh9AXo4IzBEOzBkkAxm9VigwDJnMIYv3lcfXCJVesNfbEaBl4BNgVRyid92AmdviqwBUBRKSeY3g==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.3.3.tgz", + "integrity": "sha512-/T8IKEsf9VTU6tLjgC7+sv2mOPtQxzE2jMw7u4Tt40Tx+QSZxpzh95/H6cMKoja9XuW7iMdLJYBB0o9G1CaAgg==", "dev": true, "license": "MIT", "dependencies": { "@jridgewell/remapping": "^2.3.5", - "enhanced-resolve": "^5.21.0", - "jiti": "^2.6.1", + "enhanced-resolve": "^5.24.1", + "jiti": "^2.7.0", "lightningcss": "1.32.0", "magic-string": "^0.30.21", "source-map-js": "^1.2.1", - "tailwindcss": "4.3.0" + "tailwindcss": "4.3.3" } }, "node_modules/@tailwindcss/oxide": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.3.0.tgz", - "integrity": "sha512-F7HZGBeN9I0/AuuJS5PwcD8xayx5ri5GhjYUDBEVYUkexyA/giwbDNjRVrxSezE3T250OU2K/wp/ltWx3UOefg==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.3.3.tgz", + "integrity": "sha512-krXjAikiaFSPaK/FkAQT5UTx3VormQaiZ5hBFlJZ9UFQGB/rwg1MZIhHAG9smMQRTdyJxP6Qt5MwMtdyU5FWrA==", "dev": true, "license": "MIT", "engines": { "node": ">= 20" }, "optionalDependencies": { - "@tailwindcss/oxide-android-arm64": "4.3.0", - "@tailwindcss/oxide-darwin-arm64": "4.3.0", - "@tailwindcss/oxide-darwin-x64": "4.3.0", - "@tailwindcss/oxide-freebsd-x64": "4.3.0", - "@tailwindcss/oxide-linux-arm-gnueabihf": "4.3.0", - "@tailwindcss/oxide-linux-arm64-gnu": "4.3.0", - "@tailwindcss/oxide-linux-arm64-musl": "4.3.0", - "@tailwindcss/oxide-linux-x64-gnu": "4.3.0", - "@tailwindcss/oxide-linux-x64-musl": "4.3.0", - "@tailwindcss/oxide-wasm32-wasi": "4.3.0", - "@tailwindcss/oxide-win32-arm64-msvc": "4.3.0", - "@tailwindcss/oxide-win32-x64-msvc": "4.3.0" + "@tailwindcss/oxide-android-arm64": "4.3.3", + "@tailwindcss/oxide-darwin-arm64": "4.3.3", + "@tailwindcss/oxide-darwin-x64": "4.3.3", + "@tailwindcss/oxide-freebsd-x64": "4.3.3", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.3.3", + "@tailwindcss/oxide-linux-arm64-gnu": "4.3.3", + "@tailwindcss/oxide-linux-arm64-musl": "4.3.3", + "@tailwindcss/oxide-linux-x64-gnu": "4.3.3", + "@tailwindcss/oxide-linux-x64-musl": "4.3.3", + "@tailwindcss/oxide-wasm32-wasi": "4.3.3", + "@tailwindcss/oxide-win32-arm64-msvc": "4.3.3", + "@tailwindcss/oxide-win32-x64-msvc": "4.3.3" } }, "node_modules/@tailwindcss/oxide-android-arm64": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.3.0.tgz", - "integrity": "sha512-TJPiq67tKlLuObP6RkwvVGDoxCMBVtDgKkLfa/uyj7/FyxvQwHS+UOnVrXXgbEsfUaMgiVvC4KbJnRr26ho4Ng==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.3.3.tgz", + "integrity": "sha512-Y85A2gmPSkl5Ve5qR86GL4HT509cFqQh1aes9p3sSkyTPwt0Pppf3GkwGe4JPACcRYjgJIEhQgM6dBClnr0NYw==", "cpu": [ "arm64" ], @@ -5620,9 +5704,9 @@ } }, "node_modules/@tailwindcss/oxide-darwin-arm64": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.3.0.tgz", - "integrity": "sha512-oMN/WZRb+SO37BmUElEgeEWuU8E/HXRkiODxJxLe1UTHVXLrdVSgfaJV7pSlhRGMSOiXLuxTIjfsF3wYvz8cgQ==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.3.3.tgz", + "integrity": "sha512-BiaWatpBcERQFDlOjRDpIVXuFK5PJez5SA4JMg6VYZdBYU+qKfV/vqjcIs+IYmtitf1xYQZTwXvU/8y4lfZUGw==", "cpu": [ "arm64" ], @@ -5637,9 +5721,9 @@ } }, "node_modules/@tailwindcss/oxide-darwin-x64": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.3.0.tgz", - "integrity": "sha512-N6CUmu4a6bKVADfw77p+iw6Yd9Q3OBhe0veaDX+QazfuVYlQsHfDgxBrsjQ/IW+zywL8mTrNd0SdJT/zgtvMdA==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.3.3.tgz", + "integrity": "sha512-fAeUqfV5ndhxRwai8cXGzdLvul9utWOmeTkv69unv4ZXixjn61Z+p9lCWdwOwA3TYboG3BwdVuN/RDjhBRl0mw==", "cpu": [ "x64" ], @@ -5654,9 +5738,9 @@ } }, "node_modules/@tailwindcss/oxide-freebsd-x64": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.3.0.tgz", - "integrity": "sha512-zDL5hBkQdH5C6MpqbK3gQAgP80tsMwSI26vjOzjJtNCMUo0lFgOItzHKBIupOZNQxt3ouPH7RPhvNhiTfCe5CQ==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.3.3.tgz", + "integrity": "sha512-iyf5bV6+wnAlflVeEy7R25dupxTNECZN5QMI0qNT6eT+EgaGdZcKhGkr5SdoaWiLJ3spLqIY9VCeSGrwmtg4kw==", "cpu": [ "x64" ], @@ -5671,9 +5755,9 @@ } }, "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.3.0.tgz", - "integrity": "sha512-R06HdNi7A7OEoMsf6d4tjZ71RCWnZQPHj2mnotSFURjNLdBC+cIgXQ7l81CqeoiQftjf6OOblxXMInMgN2VzMA==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.3.3.tgz", + "integrity": "sha512-aAYUprJAJQWWbRrPvtjdroZ56Md+JM8pMiopS6xGEwDfLhqj+2ver2p4nU4Mb3CRqcMmNBjo8KkUgcxhkzVQGQ==", "cpu": [ "arm" ], @@ -5688,9 +5772,9 @@ } }, "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.3.0.tgz", - "integrity": "sha512-qTJHELX8jetjhRQHCLilkVLmybpzNQAtaI/gaoVoidn/ufbNDbAo8KlK2J+yPoc8wQxvDxCmh/5lr8nC1+lTbg==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.3.3.tgz", + "integrity": "sha512-nDxldcEENOxZRzC2uu9jrutZdAAQtb+8WWDCSnWL1zvBk1+FN+x6MtDViPB5AJMfttVCUhehGWus3XBPgatM/w==", "cpu": [ "arm64" ], @@ -5708,9 +5792,9 @@ } }, "node_modules/@tailwindcss/oxide-linux-arm64-musl": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.3.0.tgz", - "integrity": "sha512-Z6sukiQsngnWO+l39X4pPbiWT81IC+PLKF+PHxIlyZbGNb9MODfYlXEVlFvej5BOZInWX01kVyzeLvHsXhfczQ==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.3.3.tgz", + "integrity": "sha512-Md44bD6veX/PC5iyF8cDVnw4HBIANZepRZZ7a8DQOvkfo5WUBwcp6iAuCUz23u+4SUkhJlD3eL7hNdW8ezd/kA==", "cpu": [ "arm64" ], @@ -5728,9 +5812,9 @@ } }, "node_modules/@tailwindcss/oxide-linux-x64-gnu": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.3.0.tgz", - "integrity": "sha512-DRNdQRpSGzRGfARVuVkxvM8Q12nh19l4BF/G7zGA1oe+9wcC6saFBHTISrpIcKzhiXtSrlSrluCfvMuledoCTQ==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.3.3.tgz", + "integrity": "sha512-tx7us1muwOKAKWao2v/GaafFeQboE6aj88vC6ziN2NCGcRm8gWUhwjzg+YdVB1e4boAtdtma4L43onunI6NS4w==", "cpu": [ "x64" ], @@ -5748,9 +5832,9 @@ } }, "node_modules/@tailwindcss/oxide-linux-x64-musl": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.3.0.tgz", - "integrity": "sha512-Z0IADbDo8bh6I7h2IQMx601AdXBLfFpEdUotft86evd/8ZPflZe9COPO8Q1vw+pfLWIUo9zN/JGZvwuAJqduqg==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.3.3.tgz", + "integrity": "sha512-SJxX60smvHgasZoBy11dX6YRjXJFovwWBoedhbQPOBzgFWBHGB+TVPWB9BxzR7TTxU8FQZAI2AyiNCMzFm8Img==", "cpu": [ "x64" ], @@ -5768,9 +5852,9 @@ } }, "node_modules/@tailwindcss/oxide-wasm32-wasi": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.3.0.tgz", - "integrity": "sha512-HNZGOUxEmElksYR7S6sC5jTeNGpobAsy9u7Gu0AskJ8/20FR9GqebUyB+HBcU/ax6BHuiuJi+Oda4B+YX6H1yA==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.3.3.tgz", + "integrity": "sha512-jx1+rPhY/5Ympkktd656HBWEBLxP7dH06losBLjjf5vgCODXvi9KhtftWcMIwTFIDqBr7cRnQkdLnAG+IOlGvQ==", "bundleDependencies": [ "@napi-rs/wasm-runtime", "@emnapi/core", @@ -5786,11 +5870,11 @@ "license": "MIT", "optional": true, "dependencies": { - "@emnapi/core": "^1.10.0", - "@emnapi/runtime": "^1.10.0", - "@emnapi/wasi-threads": "^1.2.1", + "@emnapi/core": "^1.11.1", + "@emnapi/runtime": "^1.11.1", + "@emnapi/wasi-threads": "^1.2.2", "@napi-rs/wasm-runtime": "^1.1.4", - "@tybys/wasm-util": "^0.10.1", + "@tybys/wasm-util": "^0.10.2", "tslib": "^2.8.1" }, "engines": { @@ -5798,9 +5882,9 @@ } }, "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.3.0.tgz", - "integrity": "sha512-Pe+RPVTi1T+qymuuRpcdvwSVZjnll/f7n8gBxMMh3xLTctMDKqpdfGimbMyioqtLhUYZxdJ9wGNhV7MKHvgZsQ==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.3.3.tgz", + "integrity": "sha512-3rc292Ca2ceK6Ulcc/bAVnTs/3nDtoPhyEKlgPv+yQJQi/JS/AMJlqzxvlDacL1nekbrcf6bTqp/jV4qgnPxNQ==", "cpu": [ "arm64" ], @@ -5815,9 +5899,9 @@ } }, "node_modules/@tailwindcss/oxide-win32-x64-msvc": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.3.0.tgz", - "integrity": "sha512-Mvrf2kXW/yeW/OTezZlCGOirXRcUuLIBx/5Y12BaPM7wJoryG6dfS/NJL8aBPqtTEx/Vm4T4vKzFUcKDT+TKUA==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.3.3.tgz", + "integrity": "sha512-yJ0pwIVc/nYeGoV02WtsN8KYyLQv7kyI2wDnkezyJlGGjkd4QLwDGAwl47YpPJeuI0M0ObaXGSPjvWDPeTPggw==", "cpu": [ "x64" ], @@ -5832,23 +5916,23 @@ } }, "node_modules/@tailwindcss/postcss": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@tailwindcss/postcss/-/postcss-4.3.0.tgz", - "integrity": "sha512-Jm05Tjx+9yCLGv5qw1c+84Psds8MnyrEQYCB+FFk2lgGiUjlRqdxke4mVTuYrj2xnVZqKim2Apr5ySuQRYAw/w==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/postcss/-/postcss-4.3.3.tgz", + "integrity": "sha512-JTSZZGQi1AyKirbLN3azmjVzef92tcX7h+iSqPdaeStyFpGpDlKvvpxeOE8njhbUanbRwr3z8DyzhICWnMtQeg==", "dev": true, "license": "MIT", "dependencies": { "@alloc/quick-lru": "^5.2.0", - "@tailwindcss/node": "4.3.0", - "@tailwindcss/oxide": "4.3.0", - "postcss": "^8.5.10", - "tailwindcss": "4.3.0" + "@tailwindcss/node": "4.3.3", + "@tailwindcss/oxide": "4.3.3", + "postcss": "^8.5.16", + "tailwindcss": "4.3.3" } }, "node_modules/@tanstack/query-core": { - "version": "5.100.14", - "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.100.14.tgz", - "integrity": "sha512-5X41dGpxgeaHISCRW2oYwcSycZeULZzAunaudXT9ov1KOTj9xwt0CH6hbwqP1/z74ZWF7rYFnDpyYH07XFcZew==", + "version": "5.101.4", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.101.4.tgz", + "integrity": "sha512-gNwcvOJcRbLWPOLG/2OBm+zM+Yv+MKsXKEOWC57USuZDEsI71hEErQsiEGx5wX9rzWWkfwM0fVSPoiIFSsxfiw==", "license": "MIT", "funding": { "type": "github", @@ -5856,12 +5940,12 @@ } }, "node_modules/@tanstack/react-query": { - "version": "5.100.14", - "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.100.14.tgz", - "integrity": "sha512-oOr6aRdSFEwWhzxEkD/9ZcItM3+LjBSkeVmadWKwUssAHTsqd/7bOjWrX4AbvEkoEhgAxzN0Xk6H/aYzXiYBAw==", + "version": "5.101.4", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.101.4.tgz", + "integrity": "sha512-yRg2pfOCxIs4ZJW3XYYHU/WgtD04FHSnfHlpRT7h7pR77hwkdRG4wxbKe4aq6P0RvXUTBSQpQeadS1SUYUe+KA==", "license": "MIT", "dependencies": { - "@tanstack/query-core": "5.100.14" + "@tanstack/query-core": "5.101.4" }, "funding": { "type": "github", @@ -5872,12 +5956,12 @@ } }, "node_modules/@tanstack/react-virtual": { - "version": "3.13.26", - "resolved": "https://registry.npmjs.org/@tanstack/react-virtual/-/react-virtual-3.13.26.tgz", - "integrity": "sha512-DosdgjOxCLahkn0o+ilmZYwEjo1glfMGuRT/j3PQ18yr5XqA8N/BCaL9IJ3B5TRl+nnzyK2IOFgAILwzN3a9xQ==", + "version": "3.14.9", + "resolved": "https://registry.npmjs.org/@tanstack/react-virtual/-/react-virtual-3.14.9.tgz", + "integrity": "sha512-qZyr0FZDP8rDC4WBhsryIZmAd9bveJvFGUJJtskWaew6/0dTRS6wZxnR6VQ5bY2KwL3LjerrHqQLk3a0GKcPXQ==", "license": "MIT", "dependencies": { - "@tanstack/virtual-core": "3.16.0" + "@tanstack/virtual-core": "3.17.7" }, "funding": { "type": "github", @@ -5889,9 +5973,9 @@ } }, "node_modules/@tanstack/virtual-core": { - "version": "3.16.0", - "resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.16.0.tgz", - "integrity": "sha512-Er2N7q3WOiH6y2JLxsxNX+u2/sLqSsL0bxFgDjuiPiA7vKhZRm+IzcS17vRee3GNXr64UsesA5CAp9yTiIYw9A==", + "version": "3.17.7", + "resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.17.7.tgz", + "integrity": "sha512-bp+v10y65sp2H7WpWfIMyxTNfl8ZVfxFTLRjPIFRryi6FV/J33z4IS53WO4pTk36KlvJ4iLiQz+oaydDC1xbcA==", "license": "MIT", "funding": { "type": "github", @@ -5919,9 +6003,9 @@ } }, "node_modules/@testing-library/jest-dom": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.9.1.tgz", - "integrity": "sha512-zIcONa+hVtVSSep9UT3jZ5rizo2BsxgyDYU7WFD5eICBE7no3881HGeb/QkGfsJs6JTkY1aQhT7rIPC7e+0nnA==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-7.0.0.tgz", + "integrity": "sha512-HKAH9C6mBo5yBG6yRO5i43L2iisencAo5z+o5P/saHUoY+miC5ivXRxHBJcFyB5ypPNxHJdK3BoF/3O4DIptMg==", "dev": true, "license": "MIT", "dependencies": { @@ -5933,9 +6017,12 @@ "redent": "^3.0.0" }, "engines": { - "node": ">=14", + "node": ">=22", "npm": ">=6", "yarn": ">=1" + }, + "peerDependencies": { + "@testing-library/dom": ">=10 <11" } }, "node_modules/@testing-library/jest-dom/node_modules/dom-accessibility-api": { @@ -5998,9 +6085,9 @@ } }, "node_modules/@tybys/wasm-util": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.2.tgz", - "integrity": "sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==", + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.3.tgz", + "integrity": "sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==", "dev": true, "license": "MIT", "optional": true, @@ -6137,9 +6224,9 @@ } }, "node_modules/@types/hast": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", - "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.5.tgz", + "integrity": "sha512-rp/ezSWaD1m44dPKICGhiskI13nVr7qTloFwDa/IYkhhf5nzwP+zIQcIJh3WIFSBOy/H1PzB40jPjMDksN4F+g==", "license": "MIT", "dependencies": { "@types/unist": "*" @@ -6149,7 +6236,6 @@ "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true, "license": "MIT" }, "node_modules/@types/json5": { @@ -6169,13 +6255,6 @@ "@types/node": "*" } }, - "node_modules/@types/long": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", - "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==", - "license": "MIT", - "optional": true - }, "node_modules/@types/mdast": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", @@ -6192,12 +6271,12 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "25.9.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-25.9.1.tgz", - "integrity": "sha512-xfrlY7UD5rMJk3ZVJP8BNzS28J36YJg+xp+LPXV1TdWxr8uMH5A860QNxYDGQe/ylDSgjxE52Q9VnO7p75tJxg==", + "version": "26.1.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-26.1.2.tgz", + "integrity": "sha512-Vu4a5UFA9rIIFJ7rB/Vaafh9lrCQszopTCx6KjFboXTGQbPNasehVR5TEiithSDGyd1DEiUByggTZsg8jukeIg==", "license": "MIT", "dependencies": { - "undici-types": ">=7.24.0 <7.24.7" + "undici-types": "~8.3.0" } }, "node_modules/@types/nprogress": { @@ -6208,20 +6287,19 @@ "license": "MIT" }, "node_modules/@types/react": { - "version": "19.2.15", - "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.15.tgz", - "integrity": "sha512-eRwcGNHve+E8qtEQSSRl6urh+rFop4v8gm6O8rGv25CodbvFdLjA1vVQ1KkiFE0w0UPOnb8tDiFKL5lp0rtY5Q==", - "dev": true, + "version": "19.2.18", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.18.tgz", + "integrity": "sha512-AnzbBERsrLKtk2XSfTbYRLjQPdy116Sty4q+T+Bp3IC4l6jNBvreVPAHmpq9qhXQM7CXZPjLVmGMw9sy+hxQ3w==", "license": "MIT", "dependencies": { "csstype": "^3.2.2" } }, "node_modules/@types/react-dom": { - "version": "19.2.3", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz", - "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", - "dev": true, + "version": "19.2.4", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.4.tgz", + "integrity": "sha512-Bsc+QHgp+P/F02XDzNCY9jnZNCUuLki36KT7VKrTXXLdHf+vHMNZnW1rVu5DNW/rCK+fya3DATySbLM4yhtKUw==", + "devOptional": true, "license": "MIT", "peerDependencies": { "@types/react": "^19.2.0" @@ -6241,16 +6319,16 @@ } }, "node_modules/@types/request/node_modules/form-data": { - "version": "2.5.5", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.5.tgz", - "integrity": "sha512-jqdObeR2rxZZbPSGL+3VckHMYtu+f9//KXBsVny6JSX/pa38Fy+bGjuG8eW/H6USNQWhLi8Num++cU2yOCNz4A==", + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.6.tgz", + "integrity": "sha512-Ogz/E85h9tlfJzpI6TuFpGcHZFhLrb9Gw8wq9v40CxSCPnv7ahKr6Xgtkn0KYCDQJ8DNn5VoMO8EXr9V5PadyA==", "license": "MIT", "optional": true, "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", - "hasown": "^2.0.2", + "hasown": "^2.0.4", "mime-types": "^2.1.35", "safe-buffer": "^5.2.1" }, @@ -6310,17 +6388,17 @@ } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.60.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.60.0.tgz", - "integrity": "sha512-QYb/sa74/s7OKMbACMjrYnGspj9Hs5YI5aaffSL65UfeBUzVzBJfVo3oWSpbzPurvm7yaCCo2Lk7lVj610HqKw==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.65.0.tgz", + "integrity": "sha512-IEgob78X12rHpUmtcwFsXhZdVGJtwTVP8FiCLZkR6GlYVrl2PcuB+KhCE5BlVC/eQpQnu8WXRtkHZuPar+gCRA==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.12.2", - "@typescript-eslint/scope-manager": "8.60.0", - "@typescript-eslint/type-utils": "8.60.0", - "@typescript-eslint/utils": "8.60.0", - "@typescript-eslint/visitor-keys": "8.60.0", + "@typescript-eslint/scope-manager": "8.65.0", + "@typescript-eslint/type-utils": "8.65.0", + "@typescript-eslint/utils": "8.65.0", + "@typescript-eslint/visitor-keys": "8.65.0", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.5.0" @@ -6333,15 +6411,15 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.60.0", + "@typescript-eslint/parser": "^8.65.0", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", - "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.6.tgz", + "integrity": "sha512-BAg6QkE8W+TuQLrrw0Ugr7HegXduRuuj8/ti2kSOc+jz1dmx8/WNcjr6XGnq5YpDWxFwwaavqD0+jIUOKelTsw==", "dev": true, "license": "MIT", "engines": { @@ -6349,16 +6427,16 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.60.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.60.0.tgz", - "integrity": "sha512-fcqpj/MyK4sxDPcbe7STNPbpQL4RLZOPWuaTmwZYuc+hJKzRf58yRxfhqGpc6PIq9ZyfSBpfHgmUHmHs0KwHwg==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.65.0.tgz", + "integrity": "sha512-CZ4nMxWwgu1HEEFNkeaCptra9QCtkmKdgf3sWh1rl1trIhmxLilgTV4cwcbQ4wemnT4sWQN8CaKOmdYx+g2gMA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.60.0", - "@typescript-eslint/types": "8.60.0", - "@typescript-eslint/typescript-estree": "8.60.0", - "@typescript-eslint/visitor-keys": "8.60.0", + "@typescript-eslint/scope-manager": "8.65.0", + "@typescript-eslint/types": "8.65.0", + "@typescript-eslint/typescript-estree": "8.65.0", + "@typescript-eslint/visitor-keys": "8.65.0", "debug": "^4.4.3" }, "engines": { @@ -6374,14 +6452,14 @@ } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.60.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.60.0.tgz", - "integrity": "sha512-aZu74NNKJeUWqCjDddzdiKaS82dgYgV/vmf+Ui3ZdZejmgfXR/q+pRumgobnQ2cCJTgGTWp4ypiwsuofFubavg==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.65.0.tgz", + "integrity": "sha512-SxnPhbTsGahizDgbu7oqFH/xVtzIqMd/s+WtnSxNxJZJpLbdT5IPdzg8EZxO3+PoKahXmwJLeNQOpKJb3/bi7Q==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.60.0", - "@typescript-eslint/types": "^8.60.0", + "@typescript-eslint/tsconfig-utils": "^8.65.0", + "@typescript-eslint/types": "^8.65.0", "debug": "^4.4.3" }, "engines": { @@ -6396,14 +6474,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.60.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.60.0.tgz", - "integrity": "sha512-pFzqhllJMs+jghLQWzV00ds39xLzuyqPSev5pd8f4Ir0rtKR3ZLUB4/4dhjOFighWb9larvtfJvqL+4yKDI3Xw==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.65.0.tgz", + "integrity": "sha512-Esbl8OSYiVxBokYgWPf7VVWg/BE798wXhimnn9ML9Pt5qoDf8bfQlgjlKXR/k98+AcNzlLKYrpCcrcuZ9DZLgg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.60.0", - "@typescript-eslint/visitor-keys": "8.60.0" + "@typescript-eslint/types": "8.65.0", + "@typescript-eslint/visitor-keys": "8.65.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -6414,9 +6492,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.60.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.60.0.tgz", - "integrity": "sha512-BZPR3RGYlAXnly6ymAxfkVn5rCbZzQNou0rxv3GfWZ8cTQp+hhVd73khbGLAd8k1TlAPLISH337M+tAgAnaJDQ==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.65.0.tgz", + "integrity": "sha512-j6GzGqCiRdA7Qhur2VVmKZAkBLfnHFQfx4TaJGL9RMveZqCo48jSHHO0DTgizEnGhtWnqmbtCUSrqSkdiY/0Hg==", "dev": true, "license": "MIT", "engines": { @@ -6431,15 +6509,15 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.60.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.60.0.tgz", - "integrity": "sha512-SX46wEUtitCpq7AN38HkUU/+zvUpdKf7ephtWAFgckH8O7PQIyL5gvrhQgBLuEYgLfuKWOVvWVskMbuFHAz5xg==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.65.0.tgz", + "integrity": "sha512-YjaZ7PRI5qY7ax2L3PbvX0rRyGtipAReCWs0mhhDBHjH/vl0g0BonaGXrKdKpMbIIsMIwDgbk/xzkBTyAltS5g==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.60.0", - "@typescript-eslint/typescript-estree": "8.60.0", - "@typescript-eslint/utils": "8.60.0", + "@typescript-eslint/types": "8.65.0", + "@typescript-eslint/typescript-estree": "8.65.0", + "@typescript-eslint/utils": "8.65.0", "debug": "^4.4.3", "ts-api-utils": "^2.5.0" }, @@ -6456,9 +6534,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.60.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.60.0.tgz", - "integrity": "sha512-AsE7x2XaAK+CVbeih0Fvbn+r1qHxtpLDJ3XUuFcIinT318T90yHMJC+Zgv+jUuDjQQd06HKwxnDu6sz1IcTilA==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.65.0.tgz", + "integrity": "sha512-JSSwWNy+H0E/01jJEM+hrX6N0OFDzFzeIhHFSAS01tlVaevpG8cFyYRPhS5yjGOvBUx3sqQHVMjCL1CAZZMxBg==", "dev": true, "license": "MIT", "engines": { @@ -6470,16 +6548,16 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.60.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.60.0.tgz", - "integrity": "sha512-3AcZNBGMClm6CXDyo8kYvVGT/sx29sS0oBsIb9oZI2gunA4Vm2M3YHzRLPvsUBBsl+yB5FPtltq7gGH0iTlp9g==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.65.0.tgz", + "integrity": "sha512-JboAE2swaYt4tb1fHhHTABE2K+OLy09XfcTbhnk4Pw96f9dd2e9iYsJ28gBggHlo5z5x1rkyWvcPoTuNTd4oGg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.60.0", - "@typescript-eslint/tsconfig-utils": "8.60.0", - "@typescript-eslint/types": "8.60.0", - "@typescript-eslint/visitor-keys": "8.60.0", + "@typescript-eslint/project-service": "8.65.0", + "@typescript-eslint/tsconfig-utils": "8.65.0", + "@typescript-eslint/types": "8.65.0", + "@typescript-eslint/visitor-keys": "8.65.0", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", @@ -6498,9 +6576,9 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.1.tgz", - "integrity": "sha512-rkVq3IXh+4FDGch+KwzX3aV9W3kO54GyEgpvBzSyctDA6Xtd7RJQV1xmXbeQp5v7+VzLOfVqiutSE6GICgPFvg==", + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", "dev": true, "license": "ISC", "bin": { @@ -6511,16 +6589,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.60.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.60.0.tgz", - "integrity": "sha512-HtXuPfrHTyBDkameWpl+vJb1Uevu2tznAyahM1Oc4AENidCLTPiZDWIo4GfcxNdC/RcfGcadzzkqbRG87dUrQA==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.65.0.tgz", + "integrity": "sha512-gXiwIHsYreboxeJucHKPvgwl7dXt50mF8s1/c00cP/WoVTyWKFdtfhRWwZiXYFU5H2O8vVoSLNrexFZjYS/SGA==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.60.0", - "@typescript-eslint/types": "8.60.0", - "@typescript-eslint/typescript-estree": "8.60.0" + "@typescript-eslint/scope-manager": "8.65.0", + "@typescript-eslint/types": "8.65.0", + "@typescript-eslint/typescript-estree": "8.65.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -6535,13 +6613,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.60.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.60.0.tgz", - "integrity": "sha512-9WI52t8ZGLVGrPMBet25yAftqY/n95+zmoUUtJBBQTKDSKUu7OsPTroT2op7U9JatkoRccL0YkWDNMFfC4Sjxg==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.65.0.tgz", + "integrity": "sha512-8C71BQkGjiMmXtop7pHVJu1l2NNShFdkCyD6a2ezzs5vU/L3LRtb69EtcteFwz0mYMPzIgOw0n6OV4VBUWZd7A==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.60.0", + "@typescript-eslint/types": "8.65.0", "eslint-visitor-keys": "^5.0.0" }, "engines": { @@ -6553,9 +6631,9 @@ } }, "node_modules/@ungap/structured-clone": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.1.tgz", - "integrity": "sha512-mUFwbeTqrVgDQxFveS+df2yfap6iuP20NAKAsBt5jDEoOTDew+zwLAOilHCeQJOVSvmgCX4ogqIrA0mnyr08yQ==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.3.tgz", + "integrity": "sha512-60YRaenCQcVjYEKOcG824+DRGGIQ3VKErcBoAEDJZz5bKIs2ZG+X/H9Nk+Q6EVkwJk5QNApxbrc5QtBSwtrXAg==", "license": "ISC" }, "node_modules/@unrs/resolver-binding-android-arm-eabi": { @@ -6859,6 +6937,17 @@ "node": ">=14.0.0" } }, + "node_modules/@unrs/resolver-binding-wasm32-wasi/node_modules/@emnapi/runtime": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz", + "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@unrs/resolver-binding-win32-arm64-msvc": { "version": "1.12.2", "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.12.2.tgz", @@ -6926,22 +7015,22 @@ } }, "node_modules/@upstash/redis": { - "version": "1.38.0", - "resolved": "https://registry.npmjs.org/@upstash/redis/-/redis-1.38.0.tgz", - "integrity": "sha512-wu+dZBptlLy0+MCUEoHmzrY/TnmgDey3+c7EbIGwrLqAvkP8yi5MWZHYGIFtAygmL4Bkz2TdFu+eU0vFPncIcg==", + "version": "1.38.1", + "resolved": "https://registry.npmjs.org/@upstash/redis/-/redis-1.38.1.tgz", + "integrity": "sha512-hVqkWmhqobH7hpdzSCSrOwK7gWNASOAdf85l6/yxdB+giCYNYfl8FkSKxnqW2sqCdLDP7HzRTvy/ILC1AjBMUA==", "license": "MIT", "dependencies": { "uncrypto": "^0.1.3" } }, "node_modules/@vitejs/plugin-react": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-6.0.2.tgz", - "integrity": "sha512-DlSMqo4WhThw4vB8Mpn0Woe9J+Jfq1geJ61AKW0QEgLzGMNwtIMdxbDUzLxcun8W7NbJO0e2Jg/Nxm3cCSVzzg==", + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-6.0.5.tgz", + "integrity": "sha512-BOVzne/NL162sMdResB25mUv+vWMF5NoAjNf09TeGlE7ZpszZWSD3winycicLJw72yeVsoCn/2kOhEuCvEShMA==", "dev": true, "license": "MIT", "dependencies": { - "@rolldown/pluginutils": "^1.0.0" + "@rolldown/pluginutils": "^1.0.1" }, "engines": { "node": "^20.19.0 || >=22.12.0" @@ -6961,14 +7050,14 @@ } }, "node_modules/@vitest/coverage-v8": { - "version": "4.1.8", - "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-4.1.8.tgz", - "integrity": "sha512-lt3kovsyHwYe00wq4D1ti0Z974fWj4NLp6siqiyEufUpyFwK9Yhi7rBhac9JL5aA0zoMrJqc4vYPZRUnI7l7nw==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-4.1.10.tgz", + "integrity": "sha512-IM49HmthevbgAO4anp1hwtoT9wYe59w0LR00gr+eagHE+ZJ5lK4sLPeO0ubgoJcwLk6dehU3R24N+FbEEKDc8g==", "dev": true, "license": "MIT", "dependencies": { "@bcoe/v8-coverage": "^1.0.2", - "@vitest/utils": "4.1.8", + "@vitest/utils": "4.1.10", "ast-v8-to-istanbul": "^1.0.0", "istanbul-lib-coverage": "^3.2.2", "istanbul-lib-report": "^3.0.1", @@ -6982,8 +7071,8 @@ "url": "https://opencollective.com/vitest" }, "peerDependencies": { - "@vitest/browser": "4.1.8", - "vitest": "4.1.8" + "@vitest/browser": "4.1.10", + "vitest": "4.1.10" }, "peerDependenciesMeta": { "@vitest/browser": { @@ -6992,16 +7081,16 @@ } }, "node_modules/@vitest/expect": { - "version": "4.1.8", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.8.tgz", - "integrity": "sha512-h3nDO677RDLEGlBxyQ5CW8RlMThSKSRLUePLOx09gNIWRL40edgA1GCZSZgf1W55MFAG6/Sw14KeaAnqv0NKdQ==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.10.tgz", + "integrity": "sha512-YsCn+qAk1GWjQOWFEsEcL2gNQ0zmVmQu3T03qP6UyjhtmdtwtbuI+DASn/7iQB3HGTXkdBwGddzxPlmiql5vlA==", "dev": true, "license": "MIT", "dependencies": { "@standard-schema/spec": "^1.1.0", "@types/chai": "^5.2.2", - "@vitest/spy": "4.1.8", - "@vitest/utils": "4.1.8", + "@vitest/spy": "4.1.10", + "@vitest/utils": "4.1.10", "chai": "^6.2.2", "tinyrainbow": "^3.1.0" }, @@ -7010,13 +7099,13 @@ } }, "node_modules/@vitest/mocker": { - "version": "4.1.8", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.8.tgz", - "integrity": "sha512-LEiN/xe4OSIbKe9HQIp5OC24agGD9J5CnmMgsLohVVoOPWL9a2sBoR6VBx43jQZb7Kr1l4RCuyCJzcAa0+dojw==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.10.tgz", + "integrity": "sha512-v0xaezt+DKEmKfaxg133ldzADrwLGd7Ze1MfQQTYfvs8OqZIwbxyxaYURivwV7sWy5fqn3rH5uOrSp07bp44Ow==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/spy": "4.1.8", + "@vitest/spy": "4.1.10", "estree-walker": "^3.0.3", "magic-string": "^0.30.21" }, @@ -7047,9 +7136,9 @@ } }, "node_modules/@vitest/pretty-format": { - "version": "4.1.8", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.8.tgz", - "integrity": "sha512-9GasEBxpZ1VYIpqHf/0+YGg121uSNwCKOJqIrTwWP/TB7DmFCiaBpNl3aPZzoLWfWkuqhbH8vJIVobZkvdo2cA==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.10.tgz", + "integrity": "sha512-W1HsjSH4MXQ9YfmmhLAoIYf1HRfekQCGngeIgcei6MP5QQGWUe0gkopdZQaVCFO+JDJMrAJGwa5pRpNpvy4P8Q==", "dev": true, "license": "MIT", "dependencies": { @@ -7060,13 +7149,13 @@ } }, "node_modules/@vitest/runner": { - "version": "4.1.8", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.8.tgz", - "integrity": "sha512-EmVxeBAfMJvycdjd6Hm+RbFBbA9fKvo0Kx37hNpBYoYeavH3RNsBXWDooR1mgD52dCrxIIuP7UotpfiwOikvcg==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.10.tgz", + "integrity": "sha512-IKI6kpIH+LmpROplyLwBBaCfMgOZOMsygVa6BARD6ahA04VRuJSa6OaVG7kRvSEMD870Vd91rSSw0eegtWyLGg==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/utils": "4.1.8", + "@vitest/utils": "4.1.10", "pathe": "^2.0.3" }, "funding": { @@ -7074,14 +7163,14 @@ } }, "node_modules/@vitest/snapshot": { - "version": "4.1.8", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.8.tgz", - "integrity": "sha512-acfZboRmAIf05DEKcBQy33VXojFJjtUdLyo7oOmV9kebb2xdU01UknNiPuPZoJZQyO7DF0gZdTGTpeAzET9QPQ==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.10.tgz", + "integrity": "sha512-xRkfOT1qpTAi/Ti4Y1LtfRc3kEuqxGw59eN2jN9pRWMtS/XDevekhcFSqvQqjUNGksfjMJu3Y+oJ+4Ypn2OaJw==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "4.1.8", - "@vitest/utils": "4.1.8", + "@vitest/pretty-format": "4.1.10", + "@vitest/utils": "4.1.10", "magic-string": "^0.30.21", "pathe": "^2.0.3" }, @@ -7090,9 +7179,9 @@ } }, "node_modules/@vitest/spy": { - "version": "4.1.8", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.8.tgz", - "integrity": "sha512-6EevtBp6OZOPF7bmz36HrGMeP3txgVSrgebWxHOafDXGkhIzfXK14f8KF6MuFfgXXUeHxmpD3BQxkV00/3s5mA==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.10.tgz", + "integrity": "sha512-PLf/Ugvoq5wO/b4rwYCR1h2PSIdXz7wnkQFMiUpLdtM7l6pqVFcQIBEHyT1+l+cj7mNwAfZHzqXqDyjvOuwbDw==", "dev": true, "license": "MIT", "funding": { @@ -7100,13 +7189,13 @@ } }, "node_modules/@vitest/ui": { - "version": "4.1.8", - "resolved": "https://registry.npmjs.org/@vitest/ui/-/ui-4.1.8.tgz", - "integrity": "sha512-RUS2ZU2TsduVrI+9c12uTNaKrNUTsm6yFt3fueEUB9iKvyC2UP83F+sqIz00HQIah4UOL1TMoDAki8K0NjGvsA==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/ui/-/ui-4.1.10.tgz", + "integrity": "sha512-EOUqfXHTXtpSHsyLHH40ts3Ue+hRhSGwzwzMlK0dTEOLSDYyOXLyr5JDGmHQWhN2DYI30gw6dVx3cdgM9FZl+Q==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/utils": "4.1.8", + "@vitest/utils": "4.1.10", "fflate": "^0.8.2", "flatted": "^3.4.2", "pathe": "^2.0.3", @@ -7118,17 +7207,17 @@ "url": "https://opencollective.com/vitest" }, "peerDependencies": { - "vitest": "4.1.8" + "vitest": "4.1.10" } }, "node_modules/@vitest/utils": { - "version": "4.1.8", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.8.tgz", - "integrity": "sha512-uOJamYALNhfJ6iolExyQM40yIQwDqYnkKtQ5VCiSe17E33H0aQ/u+1GlRuz4LZBk6Mm3sg90G9hEbmEt37C1Zg==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.10.tgz", + "integrity": "sha512-fy9am/HWxbaGt/Sawrp90vt6Y6jQwf1RX77cz3uwoJwJVMli/e1IEwRPnMNJ7vKfPTwo0diXifkpPvwH9v7nGA==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "4.1.8", + "@vitest/pretty-format": "4.1.10", "convert-source-map": "^2.0.0", "tinyrainbow": "^3.1.0" }, @@ -7136,6 +7225,181 @@ "url": "https://opencollective.com/vitest" } }, + "node_modules/@webassemblyjs/ast": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", + "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/helper-numbers": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", + "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", + "license": "MIT", + "peer": true + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", + "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", + "license": "MIT", + "peer": true + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", + "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", + "license": "MIT", + "peer": true + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", + "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.13.2", + "@webassemblyjs/helper-api-error": "1.13.2", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", + "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", + "license": "MIT", + "peer": true + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", + "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/wasm-gen": "1.14.1" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", + "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", + "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", + "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", + "license": "MIT", + "peer": true + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", + "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/helper-wasm-section": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-opt": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1", + "@webassemblyjs/wast-printer": "1.14.1" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", + "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", + "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", + "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-api-error": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", + "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "license": "BSD-3-Clause", + "peer": true + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "license": "Apache-2.0", + "peer": true + }, "node_modules/abort-controller": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", @@ -7163,9 +7427,9 @@ } }, "node_modules/acorn": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", - "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.18.0.tgz", + "integrity": "sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ==", "license": "MIT", "bin": { "acorn": "bin/acorn" @@ -7174,15 +7438,6 @@ "node": ">=0.4.0" } }, - "node_modules/acorn-import-attributes": { - "version": "1.9.5", - "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", - "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", - "license": "MIT", - "peerDependencies": { - "acorn": "^8" - } - }, "node_modules/acorn-jsx": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", @@ -7206,16 +7461,15 @@ } }, "node_modules/ajv": { - "version": "6.15.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", - "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", - "dev": true, + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz", + "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==", "license": "MIT", "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" }, "funding": { "type": "github", @@ -7223,10 +7477,11 @@ } }, "node_modules/ajv-formats": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", - "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", "license": "MIT", + "peer": true, "dependencies": { "ajv": "^8.0.0" }, @@ -7239,42 +7494,17 @@ } } }, - "node_modules/ajv-formats/node_modules/ajv": { - "version": "8.20.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz", - "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ajv-formats/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "license": "MIT" - }, - "node_modules/ansi-escapes": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.3.0.tgz", - "integrity": "sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg==", - "dev": true, + "node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", "license": "MIT", + "peer": true, "dependencies": { - "environment": "^1.0.0" - }, - "engines": { - "node": ">=18" + "fast-deep-equal": "^3.1.3" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "ajv": "^8.8.2" } }, "node_modules/ansi-regex": { @@ -7303,6 +7533,19 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/anynum": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/anynum/-/anynum-1.0.1.tgz", + "integrity": "sha512-N6//FLET/tXYNM/F6ABca1oH6fWB+KlTt909Le28WMDBk8oaT4vY17DCrwg2MvmuqUKt3Ni4N5dGJ/EoBgcO6A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT", + "optional": true + }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -7520,9 +7763,9 @@ "license": "MIT" }, "node_modules/ast-v8-to-istanbul": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/ast-v8-to-istanbul/-/ast-v8-to-istanbul-1.0.3.tgz", - "integrity": "sha512-jCMQ6ZylLPudp0CDfBmQBZUsrh1/8psbmu9ibeVWKuHWD0YrH9YABwlKu5kVEFoT0GCQQW9Z/SxfuEbbkGQCRg==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/ast-v8-to-istanbul/-/ast-v8-to-istanbul-1.0.5.tgz", + "integrity": "sha512-UPAgKJFSEGMWSDr3LX4tqnAb4f7KGT8O40Tyx8wbYmmZ/yn58lNCm8h3svs3eXgiGd5AXxz8NDOvXWvicq+rJA==", "dev": true, "license": "MIT", "dependencies": { @@ -7548,6 +7791,15 @@ "dev": true, "license": "MIT" }, + "node_modules/astring": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/astring/-/astring-1.9.0.tgz", + "integrity": "sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==", + "license": "MIT", + "bin": { + "astring": "bin/astring" + } + }, "node_modules/async-function": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", @@ -7601,9 +7853,9 @@ } }, "node_modules/axe-core": { - "version": "4.11.4", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.11.4.tgz", - "integrity": "sha512-KunSNx+TVpkAw/6ULfhnx+HWRecjqZGTOyquAoWHYLRSdK1tB5Ihce1ZW+UY3fj33bYAFWPu7W/GRSmmrCGuxA==", + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.12.1.tgz", + "integrity": "sha512-s7iGf5GaVMxEG0ENN9x+xTr7GFZCb1ZP/1uATUpCEK2X78nDB3RwbtFCo9pGAf9ru+VwoQ464DkaLEeRM08wJA==", "dev": true, "license": "MPL-2.0", "engines": { @@ -7611,13 +7863,13 @@ } }, "node_modules/axios": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.16.1.tgz", - "integrity": "sha512-caYkukvroVPO8KrzuJEb50Hm07KwfBZPEC3VeFHTsqWHvKTsy54hjJz9BS/cdaypROE2rH6xvm9mHX4fgWkr3A==", + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.19.0.tgz", + "integrity": "sha512-ht/iuYZXEjFxLH/Hkezgd7m6JKlHHXEUSneaDz8uZe1Gj5QZtCnpyDsckvAiEnT89OEbCLmnte4R4sn7P0EKFw==", "license": "MIT", "dependencies": { "follow-redirects": "^1.16.0", - "form-data": "^4.0.5", + "form-data": "^4.0.6", "https-proxy-agent": "^5.0.1", "proxy-from-env": "^2.1.0" } @@ -7690,9 +7942,9 @@ } }, "node_modules/baseline-browser-mapping": { - "version": "2.10.33", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.33.tgz", - "integrity": "sha512-bA6+tcSLpz2tIEdDXZPpPTIuxBcC4+w6SieaYyfigIa4h8GlFxbA17v22Vx3JUtuZQj9SgOsnbK+aTBzyDyEuw==", + "version": "2.11.9", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.9.tgz", + "integrity": "sha512-cp447VUsGS07+n1Dqf7YSQ8maeJrjEhaDxTm1ZefbqDtypHBC5GzGMQbklR6IPR13Y8OAJRHZWEMtZipJLCttg==", "license": "Apache-2.0", "bin": { "baseline-browser-mapping": "dist/cli.cjs" @@ -7721,15 +7973,15 @@ } }, "node_modules/brace-expansion": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz", - "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==", + "version": "5.0.9", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.9.tgz", + "integrity": "sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==", "license": "MIT", "dependencies": { "balanced-match": "^4.0.2" }, "engines": { - "node": "18 || 20 || >=22" + "node": "20 || >=22" } }, "node_modules/braces": { @@ -7746,9 +7998,9 @@ } }, "node_modules/browserslist": { - "version": "4.28.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.2.tgz", - "integrity": "sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==", + "version": "4.28.7", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.7.tgz", + "integrity": "sha512-JxV13hNrFxqjOc8alRbq9dK1MM79NEXYpma2B2J4wAtpWS5zIEIKqWPGCl7N4o7Uc7B7itylh7SuDujATRyyTw==", "funding": [ { "type": "opencollective", @@ -7765,10 +8017,10 @@ ], "license": "MIT", "dependencies": { - "baseline-browser-mapping": "^2.10.12", - "caniuse-lite": "^1.0.30001782", - "electron-to-chromium": "^1.5.328", - "node-releases": "^2.0.36", + "baseline-browser-mapping": "^2.10.44", + "caniuse-lite": "^1.0.30001806", + "electron-to-chromium": "^1.5.393", + "node-releases": "^2.0.51", "update-browserslist-db": "^1.2.3" }, "bin": { @@ -7784,6 +8036,26 @@ "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==", "license": "BSD-3-Clause" }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "license": "MIT", + "peer": true + }, + "node_modules/buffer-image-size": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/buffer-image-size/-/buffer-image-size-0.6.4.tgz", + "integrity": "sha512-nEh+kZOPY1w+gcCMobZ6ETUp9WfibndnosbpwB1iJk/8Gt5ZF2bhS6+B6bPYz424KtwsR6Rflc3tCz1/ghX2dQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + }, + "engines": { + "node": ">=4.0" + } + }, "node_modules/builtin-modules": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", @@ -7866,9 +8138,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001793", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001793.tgz", - "integrity": "sha512-iwSsYWaCOoh26cV8NwNRViHlrfUvYsHDfRVcbtmw0Kg6PJIZZXwMkj1442FYLBGkeUf1juAsU3DTfxW579mrPA==", + "version": "1.0.30001806", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001806.tgz", + "integrity": "sha512-72Cuvd95zbSYPKq6Fhg8eDJRlzgWDf7/mtoZv6Qe/DYNCEBdNxoA3+rZAU2ZhGCpZlns3EssFavaZomckT5Uuw==", "funding": [ { "type": "opencollective", @@ -7977,6 +8249,16 @@ "url": "https://paulmillr.com/funding/" } }, + "node_modules/chrome-trace-event": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", + "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6.0" + } + }, "node_modules/citty": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/citty/-/citty-0.2.2.tgz", @@ -8001,39 +8283,6 @@ "url": "https://polar.sh/cva" } }, - "node_modules/cli-cursor": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", - "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", - "dev": true, - "license": "MIT", - "dependencies": { - "restore-cursor": "^5.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cli-truncate": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-5.2.0.tgz", - "integrity": "sha512-xRwvIOMGrfOAnM1JYtqQImuaNtDEv9v6oIYAs4LIHwTiKee8uwvIi363igssOC0O5U04i4AlENs79LQLu9tEMw==", - "dev": true, - "license": "MIT", - "dependencies": { - "slice-ansi": "^8.0.0", - "string-width": "^8.2.0" - }, - "engines": { - "node": ">=20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/client-only": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", @@ -8055,69 +8304,6 @@ "node": ">=12" } }, - "node_modules/cliui/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "license": "MIT", - "optional": true - }, - "node_modules/cliui/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "license": "MIT", - "optional": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "optional": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "license": "MIT", - "optional": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, "node_modules/clsx": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", @@ -8216,32 +8402,27 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/conf/node_modules/ajv": { - "version": "8.20.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz", - "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==", + "node_modules/conf/node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", "license": "MIT", "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" + "ajv": "^8.0.0" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } } }, - "node_modules/conf/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "license": "MIT" - }, "node_modules/conf/node_modules/semver": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.1.tgz", - "integrity": "sha512-rkVq3IXh+4FDGch+KwzX3aV9W3kO54GyEgpvBzSyctDA6Xtd7RJQV1xmXbeQp5v7+VzLOfVqiutSE6GICgPFvg==", + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -8325,7 +8506,6 @@ "version": "3.2.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", - "dev": true, "license": "MIT" }, "node_modules/d3-array": { @@ -8489,6 +8669,21 @@ "node": ">=20" } }, + "node_modules/data-urls/node_modules/whatwg-url": { + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-16.0.1.tgz", + "integrity": "sha512-1to4zXBxmXHV3IiSSEInrreIlu02vUOvrhxJJH5vcxYTBDAx51cqZiKdyTxlecdKNSjj8EcxGBxNf6Vg+945gw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@exodus/bytes": "^1.11.0", + "tr46": "^6.0.0", + "webidl-conversions": "^8.0.1" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + } + }, "node_modules/data-view-buffer": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", @@ -8816,9 +9011,9 @@ } }, "node_modules/dot-prop": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-10.1.0.tgz", - "integrity": "sha512-MVUtAugQMOff5RnBy2d9N31iG0lNwg1qAoAOn7pOK5wf94WIaE3My2p3uwTQuvS2AcqchkcR3bHByjaM0mmi7Q==", + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-10.2.0.tgz", + "integrity": "sha512-BTJ9aZYL3vCfZlZOBLy9v8TUqWGQ0pzFnygKwFZt5udj6viBoFIBviKPUoZLDCPn1FoXffv6McQFDenrm5Krfw==", "license": "MIT", "dependencies": { "type-fest": "^5.0.0" @@ -8878,10 +9073,28 @@ "safe-buffer": "^5.0.1" } }, + "node_modules/eciesjs": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/eciesjs/-/eciesjs-0.5.0.tgz", + "integrity": "sha512-s0J9SEVYAEPg7J63GFMApLYzPH9VNIQIyC6s15JpnqVc0TqcKWdbgFlnAweEBRyMmko2dcs2sfC83Hj4J43tuA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ecies/ciphers": "^0.2.6", + "@noble/ciphers": "^1.3.0", + "@noble/curves": "^1.9.7", + "@noble/hashes": "^1.8.0" + }, + "engines": { + "bun": ">=1", + "deno": ">=2.7.10", + "node": ">=16" + } + }, "node_modules/electron-to-chromium": { - "version": "1.5.364", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.364.tgz", - "integrity": "sha512-G/dYE3+AYhyHwzTwg8UbnXf7zqMERYh7l2jJ3QujhFsH8agSYwtnGAR2aZ7f0AakIKJXd5En/Hre4igIUrdlYw==", + "version": "1.5.399", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.399.tgz", + "integrity": "sha512-lEcqhErbHjXRvd41rnWLpzbyU/IXfIYo7QwaFWmxGeLiLyY2TBCdHnWY88vB+p3ubnihRypDm66panXl7TylLA==", "license": "ISC" }, "node_modules/emoji-regex": { @@ -8902,9 +9115,9 @@ } }, "node_modules/engine.io": { - "version": "6.6.8", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.6.8.tgz", - "integrity": "sha512-2agL3ueZhqxoVrfmntO8yuVj+uNSlIOnhykYHk3Cq0ShYPdUjjUiSJrQvXjq01I9jAuI0Zl2YO8Evv5Mqytm5g==", + "version": "6.6.9", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.6.9.tgz", + "integrity": "sha512-clKkw4C7nJ22mGgoVcCg6V/W/TxdNyIOTr89k2ONZu81qqkddPFDF0LXcbAwhzPD8DjkiRCjzuiO6Y+fkpD4vg==", "license": "MIT", "dependencies": { "@types/cors": "^2.8.12", @@ -8916,7 +9129,7 @@ "cors": "~2.8.5", "debug": "~4.4.1", "engine.io-parser": "~5.2.1", - "ws": "~8.20.1" + "ws": "~8.21.0" }, "engines": { "node": ">=10.2.0" @@ -8940,32 +9153,10 @@ "node": ">= 0.6" } }, - "node_modules/engine.io/node_modules/ws": { - "version": "8.20.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.20.1.tgz", - "integrity": "sha512-It4dO0K5v//JtTXuPkfEOaI3uUN87iYPnqo/ZzqCoG3g8uhA66QUMs/SrM0YK7/NAu+r4LMh/9dq2A7k+rHs+w==", - "license": "MIT", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, "node_modules/enhanced-resolve": { - "version": "5.22.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.22.1.tgz", - "integrity": "sha512-6QEuw3zoX1SJQc7b87aBXke/no+mG2bTBgw29gWMQonLmpEkWoCAVkl+M49e48AZlWzxiDzDZzYdp6kobcyLww==", - "dev": true, + "version": "5.24.5", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.24.5.tgz", + "integrity": "sha512-L1l8TNvomm6UVW5B253AGxQagSQr+vGwhMlrrfRS2qmhx46AMpMVJKQYLvWYbysTMY8VoicOvzHzoHMbyzB+4A==", "license": "MIT", "dependencies": { "graceful-fs": "^4.2.4", @@ -8979,6 +9170,7 @@ "version": "7.0.1", "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz", "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==", + "dev": true, "license": "BSD-2-Clause", "engines": { "node": ">=0.12" @@ -8999,19 +9191,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/environment": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", - "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/es-abstract": { "version": "1.24.2", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.2.tgz", @@ -9081,6 +9260,25 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/es-abstract-get": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-abstract-get/-/es-abstract-get-1.0.0.tgz", + "integrity": "sha512-6PMWXpdhshVvFp+FoWYs1EvG1Nj0tvk0dZM+XcK0xMEM1czRVcP6ohqPWHy6qPagSpC8j4+p89WXlT+xXJs/fg==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.2", + "is-callable": "^1.2.7", + "object-inspect": "^1.13.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/es-define-property": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", @@ -9100,9 +9298,9 @@ } }, "node_modules/es-iterator-helpers": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.3.2.tgz", - "integrity": "sha512-HVLACW1TppGYjJ8H6/jqH/pqOtKRw6wMlrB23xfExmFWxFquAIWCmwoLsOyN96K4a5KbmOf5At9ZUO3GZbetAw==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.4.0.tgz", + "integrity": "sha512-c/A0P0oxkACDc+cKWw8evLXK83oBKgn0qPOqCYT4x9uolpCIJAcYvJC9QYKNDRPsTeGyCrQ326jrvgZWdCdK5Q==", "dev": true, "license": "MIT", "dependencies": { @@ -9128,10 +9326,9 @@ } }, "node_modules/es-module-lexer": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.1.0.tgz", - "integrity": "sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ==", - "dev": true, + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.3.1.tgz", + "integrity": "sha512-shc1dbU90Yl/xq1QrC7QRtfcwURZuVRfPhZbDoldJ1cn1gzDvBaBWlv0eFolj5+0znnPJz5TXLxsN77X/12KTA==", "license": "MIT" }, "node_modules/es-object-atoms": { @@ -9175,15 +9372,18 @@ } }, "node_modules/es-to-primitive": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", - "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.4.tgz", + "integrity": "sha512-yPDz7wqpg1/mmHLmS3tcfTfbw5f1eryXvyghYBffGdERwe+mV7ZcWzTR8LR17Kvqt3qfPurjlonmnq3MKXIOXw==", "dev": true, "license": "MIT", "dependencies": { + "es-abstract-get": "^1.0.0", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", "is-callable": "^1.2.7", - "is-date-object": "^1.0.5", - "is-symbol": "^1.0.4" + "is-date-object": "^1.1.0", + "is-symbol": "^1.1.1" }, "engines": { "node": ">= 0.4" @@ -9193,19 +9393,20 @@ } }, "node_modules/es-toolkit": { - "version": "1.47.0", - "resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.47.0.tgz", - "integrity": "sha512-n1GuoD0WEQZMBk5tttoZSqwgyLx01oqa5XsBmCHwPyNe1S9jPBEmtR2pSgp2kJuWE3ciFZ6yRHmY4pM4C3OOkw==", + "version": "1.50.0", + "resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.50.0.tgz", + "integrity": "sha512-OyZKhUVvEep9ITEiwHn8GKnMRQIVqoSIX7WnRbkWgJkllCujilqP2rD0u979tkl8wqyc8ICwlc1UBVv/Sl1G6w==", "license": "MIT", "workspaces": [ "docs", - "benchmarks" + "benchmarks", + "tests/types" ] }, "node_modules/esbuild": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.0.tgz", - "integrity": "sha512-sNR9MHpXSUV/XB4zmsFKN+QgVG82Cc7+/aaxJ8Adi8hyOac+EXptIp45QBPaVyX3N70664wRbTcLTOemCAnyqw==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.1.tgz", + "integrity": "sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==", "hasInstallScript": true, "license": "MIT", "bin": { @@ -9215,32 +9416,32 @@ "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.28.0", - "@esbuild/android-arm": "0.28.0", - "@esbuild/android-arm64": "0.28.0", - "@esbuild/android-x64": "0.28.0", - "@esbuild/darwin-arm64": "0.28.0", - "@esbuild/darwin-x64": "0.28.0", - "@esbuild/freebsd-arm64": "0.28.0", - "@esbuild/freebsd-x64": "0.28.0", - "@esbuild/linux-arm": "0.28.0", - "@esbuild/linux-arm64": "0.28.0", - "@esbuild/linux-ia32": "0.28.0", - "@esbuild/linux-loong64": "0.28.0", - "@esbuild/linux-mips64el": "0.28.0", - "@esbuild/linux-ppc64": "0.28.0", - "@esbuild/linux-riscv64": "0.28.0", - "@esbuild/linux-s390x": "0.28.0", - "@esbuild/linux-x64": "0.28.0", - "@esbuild/netbsd-arm64": "0.28.0", - "@esbuild/netbsd-x64": "0.28.0", - "@esbuild/openbsd-arm64": "0.28.0", - "@esbuild/openbsd-x64": "0.28.0", - "@esbuild/openharmony-arm64": "0.28.0", - "@esbuild/sunos-x64": "0.28.0", - "@esbuild/win32-arm64": "0.28.0", - "@esbuild/win32-ia32": "0.28.0", - "@esbuild/win32-x64": "0.28.0" + "@esbuild/aix-ppc64": "0.28.1", + "@esbuild/android-arm": "0.28.1", + "@esbuild/android-arm64": "0.28.1", + "@esbuild/android-x64": "0.28.1", + "@esbuild/darwin-arm64": "0.28.1", + "@esbuild/darwin-x64": "0.28.1", + "@esbuild/freebsd-arm64": "0.28.1", + "@esbuild/freebsd-x64": "0.28.1", + "@esbuild/linux-arm": "0.28.1", + "@esbuild/linux-arm64": "0.28.1", + "@esbuild/linux-ia32": "0.28.1", + "@esbuild/linux-loong64": "0.28.1", + "@esbuild/linux-mips64el": "0.28.1", + "@esbuild/linux-ppc64": "0.28.1", + "@esbuild/linux-riscv64": "0.28.1", + "@esbuild/linux-s390x": "0.28.1", + "@esbuild/linux-x64": "0.28.1", + "@esbuild/netbsd-arm64": "0.28.1", + "@esbuild/netbsd-x64": "0.28.1", + "@esbuild/openbsd-arm64": "0.28.1", + "@esbuild/openbsd-x64": "0.28.1", + "@esbuild/openharmony-arm64": "0.28.1", + "@esbuild/sunos-x64": "0.28.1", + "@esbuild/win32-arm64": "0.28.1", + "@esbuild/win32-ia32": "0.28.1", + "@esbuild/win32-x64": "0.28.1" } }, "node_modules/escalade": { @@ -9265,9 +9466,9 @@ } }, "node_modules/eslint": { - "version": "9.39.4", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.4.tgz", - "integrity": "sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==", + "version": "9.39.5", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.5.tgz", + "integrity": "sha512-DgZS62aPLXKlnxILS/AYCoRvHaZeXceIzlXPkkGGzJWSow1aEk0lbTlxUSlyjC8jcaKxAdOnTDz+o1JFSBsyjw==", "dev": true, "license": "MIT", "dependencies": { @@ -9276,8 +9477,8 @@ "@eslint/config-array": "^0.21.2", "@eslint/config-helpers": "^0.4.2", "@eslint/core": "^0.17.0", - "@eslint/eslintrc": "^3.3.5", - "@eslint/js": "9.39.4", + "@eslint/eslintrc": "^3.3.6", + "@eslint/js": "9.39.5", "@eslint/plugin-kit": "^0.4.1", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", @@ -9325,13 +9526,13 @@ } }, "node_modules/eslint-config-next": { - "version": "16.2.6", - "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-16.2.6.tgz", - "integrity": "sha512-z2ELYSkyrrJ6cuunTU8vhsT/RpouPkjaSah06nVW6Rg2Hpg0Vs8s497/e5s8G8qtdp4ccsiovz5P1rv+5VSW2Q==", + "version": "16.2.12", + "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-16.2.12.tgz", + "integrity": "sha512-iaaf4vvKo5h2LBdGt0JuRv7t0Ysqr9FMCiFxbptDg8LqOE//mIKR80DdpOnSVM7qjLH3jT8P0aFiwXxBEGZRXw==", "dev": true, "license": "MIT", "dependencies": { - "@next/eslint-plugin-next": "16.2.6", + "@next/eslint-plugin-next": "16.2.12", "eslint-import-resolver-node": "^0.3.6", "eslint-import-resolver-typescript": "^3.5.2", "eslint-plugin-import": "^2.32.0", @@ -9422,9 +9623,9 @@ } }, "node_modules/eslint-module-utils": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.13.0.tgz", - "integrity": "sha512-bLohSkT6469rRs8czj0tLTD8vaeIS/whvPRJVjDr7IuoTT1k5DYDERlNycjDj/HkOlvQdYurmfZ/g3fG5bgeLQ==", + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.14.0.tgz", + "integrity": "sha512-W2WCRZ9Dqntd+2u8jJcVMV2PKulc6RdLgUUoh/yQr3uB6lo/ZOeGx11sv60/8S4QFFKNslAlWhr9u0Ef7ZW6Ig==", "dev": true, "license": "MIT", "dependencies": { @@ -9587,9 +9788,9 @@ } }, "node_modules/eslint-plugin-security": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-security/-/eslint-plugin-security-4.0.0.tgz", - "integrity": "sha512-tfuQT8K/Li1ZxhFzyD8wPIKtlzZxqBcPr9q0jFMQ77wWAbKBVEhaMPVQRTMTvCMUDhwBe5vPVqQPwAGk/ASfxQ==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-security/-/eslint-plugin-security-4.0.1.tgz", + "integrity": "sha512-/lZCkOxPOWaf1jXAqgICrS8St3BMBccIPvhOSUYuV6VCr1o5nFVG998FnTLt6w2Nxb8Uo0nM8fzmnhp+GY/aEg==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -9603,9 +9804,9 @@ } }, "node_modules/eslint-plugin-sonarjs": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-sonarjs/-/eslint-plugin-sonarjs-4.0.3.tgz", - "integrity": "sha512-5drkJKLC9qQddIiaATV0e8+ygbUc7b0Ti6VB7M2d3jmKNh3X0RaiIJYTs3dr9xnlhlrxo+/s1FoO3Jgv6O/c7g==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-sonarjs/-/eslint-plugin-sonarjs-4.2.0.tgz", + "integrity": "sha512-bqADfuNtTL7VK6RU29eoiFTtaaBKIpVPuX3bOl+rBpWSBa0zIBVZlqZNZQjfP6s4iXkAJokv5IsD8OsACkwApg==", "dev": true, "license": "LGPL-3.0-only", "dependencies": { @@ -9613,23 +9814,24 @@ "builtin-modules": "^3.3.0", "bytes": "^3.1.2", "functional-red-black-tree": "^1.0.1", - "globals": "^17.4.0", + "globals": "^17.7.0", "jsx-ast-utils-x": "^0.1.0", "lodash.merge": "^4.6.2", "minimatch": "^10.2.5", "scslre": "^0.3.0", - "semver": "^7.7.4", + "semver": "^7.8.5", "ts-api-utils": "^2.5.0", - "typescript": ">=5" + "typescript": ">=5 <6.1.0", + "yaml": "^2.9.0" }, "peerDependencies": { "eslint": "^8.0.0 || ^9.0.0 || ^10.0.0" } }, "node_modules/eslint-plugin-sonarjs/node_modules/semver": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.1.tgz", - "integrity": "sha512-rkVq3IXh+4FDGch+KwzX3aV9W3kO54GyEgpvBzSyctDA6Xtd7RJQV1xmXbeQp5v7+VzLOfVqiutSE6GICgPFvg==", + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", "dev": true, "license": "ISC", "bin": { @@ -9685,6 +9887,23 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint/node_modules/ajv": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, "node_modules/eslint/node_modules/eslint-visitor-keys": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", @@ -9698,6 +9917,13 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, "node_modules/espree": { "version": "10.4.0", "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", @@ -9733,7 +9959,6 @@ "version": "1.7.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", - "dev": true, "license": "BSD-3-Clause", "dependencies": { "estraverse": "^5.1.0" @@ -9746,7 +9971,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, "license": "BSD-2-Clause", "dependencies": { "estraverse": "^5.2.0" @@ -9759,7 +9983,6 @@ "version": "5.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, "license": "BSD-2-Clause", "engines": { "node": ">=4.0" @@ -9807,10 +10030,20 @@ "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==", "license": "MIT" }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.8.x" + } + }, "node_modules/expect-type": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz", - "integrity": "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.4.0.tgz", + "integrity": "sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==", "dev": true, "license": "Apache-2.0", "engines": { @@ -9823,15 +10056,6 @@ "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", "license": "MIT" }, - "node_modules/farmhash-modern": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/farmhash-modern/-/farmhash-modern-1.1.0.tgz", - "integrity": "sha512-6ypT4XfgqJk/F3Yuv4SX26I3doUjt0GTG4a+JgWxXQpxXzTBq8fPUeGHfcYMMDPHJHm3yPOSjaeBwBGAHWXCdA==", - "license": "MIT", - "engines": { - "node": ">=18.0.0" - } - }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -9889,9 +10113,9 @@ "license": "Unlicense" }, "node_modules/fast-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.2.tgz", - "integrity": "sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.5.tgz", + "integrity": "sha512-gHwA1O9LDIcKunMKhObS/HimwtehO1nPUECKAu5TpKgaO19fcWEl4bliWe1jWxVFvIXztJjjQ4L8XQ1EU9f7Jw==", "funding": [ { "type": "github", @@ -9905,9 +10129,9 @@ "license": "BSD-3-Clause" }, "node_modules/fast-xml-builder": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.2.0.tgz", - "integrity": "sha512-00aAWieqff+ZJhsXA4g1g7M8k+7AYoMUUHF+/zFb5U6Uv/P0Vl4QZo84/IcufzYalLuEj9928bXN9PbbFzMF0Q==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.3.0.tgz", + "integrity": "sha512-F74cZEdCvuw9P41GAC3rod4X04jjWGM1JPEv/GWSqFTWLsdyMSBMBMlm9Hk3GLBgLBbdBNY8yee0pQh2RBVESQ==", "funding": [ { "type": "github", @@ -9917,14 +10141,14 @@ "license": "MIT", "optional": true, "dependencies": { - "path-expression-matcher": "^1.5.0", - "xml-naming": "^0.1.0" + "path-expression-matcher": "^1.6.2", + "xml-naming": "^0.3.0" } }, "node_modules/fast-xml-parser": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.8.0.tgz", - "integrity": "sha512-6bIM7fsJxeo3uXv7OncQYsBAMPJ7V16Slahl/6M98C/i2q+vB1+4a0MtrvYwDFEUrwDSbAmeLDRXsOBwrL7yAg==", + "version": "5.10.1", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.10.1.tgz", + "integrity": "sha512-IEMIf7298kXuZSRFoGfMYrl7is8LpavODgbNz1cwIudv7KwVFnuU+UsMporfq6PD6aXSlawZlARiA3UywCTfMw==", "funding": [ { "type": "github", @@ -9934,11 +10158,12 @@ "license": "MIT", "optional": true, "dependencies": { - "@nodable/entities": "^2.1.0", + "@nodable/entities": "^3.0.0", "fast-xml-builder": "^1.2.0", - "path-expression-matcher": "^1.5.0", - "strnum": "^2.3.0", - "xml-naming": "^0.1.0" + "is-unsafe": "^2.0.0", + "path-expression-matcher": "^1.6.2", + "strnum": "^2.4.1", + "xml-naming": "^0.3.0" }, "bin": { "fxparser": "src/cli/cli.js" @@ -10076,25 +10301,24 @@ } }, "node_modules/firebase-admin": { - "version": "13.10.0", - "resolved": "https://registry.npmjs.org/firebase-admin/-/firebase-admin-13.10.0.tgz", - "integrity": "sha512-rbuCrJvYRwqBqvbccMS8fj/x2zsaMisdf5RQbRzQzr14Rbq9r2UlpuBHqWAwrO6c9dIRF56xF/xoepXsD5yDuQ==", + "version": "14.2.0", + "resolved": "https://registry.npmjs.org/firebase-admin/-/firebase-admin-14.2.0.tgz", + "integrity": "sha512-zfs5PdccEgjX479bbMmz95Rqc7ttQ4LV3qkGFlPiqOaOu/suBZc3fG52Qzn2hQjiSHkBM4NP2AZV5r2NvAt0TQ==", "license": "Apache-2.0", "dependencies": { "@fastify/busboy": "^3.0.0", - "@firebase/database-compat": "^2.0.0", - "@firebase/database-types": "^1.0.6", - "farmhash-modern": "^1.1.0", + "@firebase/database-compat": "^2.1.4", + "@firebase/database-types": "^1.0.20", "fast-deep-equal": "^3.1.1", - "google-auth-library": "^10.6.1", + "google-auth-library": "^10.6.2", "jsonwebtoken": "^9.0.0", - "jwks-rsa": "^3.1.0" + "jwks-rsa": "^4.0.1" }, "engines": { - "node": ">=18" + "node": ">=22" }, "optionalDependencies": { - "@google-cloud/firestore": "^7.11.0", + "@google-cloud/firestore": "^8.6.0", "@google-cloud/storage": "^7.19.0" } }, @@ -10113,9 +10337,9 @@ } }, "node_modules/flatted": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", - "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.4.tgz", + "integrity": "sha512-5+ybhBZANEJxaH3X5evAFatUxLfEHSr7n6kYJ+1Qd0mUqr4eu9gIf6GDbWHf8RJijHrjjO8G+la14SlL2SeS1Q==", "dev": true, "license": "ISC" }, @@ -10156,16 +10380,16 @@ } }, "node_modules/form-data": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", - "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.6.tgz", + "integrity": "sha512-vKatAh4SlVfgbv+YtmhiRjhEMJsYpsG1Y2rMQtR+SVSbytsSD1YGzDIcrAJmdFec88u/+VoGmxnl+80gL1tRCQ==", "license": "MIT", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", - "hasown": "^2.0.2", - "mime-types": "^2.1.12" + "hasown": "^2.0.4", + "mime-types": "^2.1.35" }, "engines": { "node": ">= 6" @@ -10184,12 +10408,12 @@ } }, "node_modules/framer-motion": { - "version": "12.40.0", - "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.40.0.tgz", - "integrity": "sha512-uaBd3qC1v3KQqBEjwTUd183K6PbS+j0yR9w9VmEOLWA/tnUcSn8Xa3uck7t4dgpDoUss8xQTcj8W2L07lrnLFg==", + "version": "12.43.0", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.43.0.tgz", + "integrity": "sha512-1eaL3RvR/kAlbG7UYcpMptEyzPoENO0c6w7ZnB3/hh2vSAz/6uGAFn6fdoqTBguNstf3MsFhJHsD/0DHiclG+g==", "license": "MIT", "dependencies": { - "motion-dom": "^12.40.0", + "motion-dom": "^12.43.0", "motion-utils": "^12.39.0", "tslib": "^2.4.0" }, @@ -10234,18 +10458,21 @@ } }, "node_modules/function.prototype.name": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", - "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.2.0.tgz", + "integrity": "sha512-jObKIik1P2QjPHP5nz5BaOtUlfgS0fWo8IUByNXkM+o+02sJOi94em77GwJKQSJ3gfPHdgzLNrHc1uokV4P/ew==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.3", - "define-properties": "^1.2.1", + "call-bind": "^1.0.9", + "call-bound": "^1.0.4", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", "functions-have-names": "^1.2.3", - "hasown": "^2.0.2", - "is-callable": "^1.2.7" + "has-property-descriptors": "^1.0.2", + "hasown": "^2.0.4", + "is-callable": "^1.2.7", + "is-document.all": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -10336,9 +10563,9 @@ } }, "node_modules/gcp-metadata/node_modules/gaxios": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-7.1.4.tgz", - "integrity": "sha512-bTIgTsM2bWn3XklZISBTQX7ZSddGW+IO3bMdGaemHZ3tbqExMENHLx6kKZ/KlejgrMtj8q7wBItt51yegqalrA==", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-7.3.0.tgz", + "integrity": "sha512-RB5vLV+vvQeoFPCX4QMK6/hjVkbIamPp1QSUD0CiZcnj12qbpiL+pLbYtgD+oZkWl0tl9z+o2Utp+MpM3QRhBA==", "license": "Apache-2.0", "dependencies": { "extend": "^3.0.2", @@ -10409,19 +10636,6 @@ "node": "6.* || 8.* || >= 10.*" } }, - "node_modules/get-east-asian-width": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.6.0.tgz", - "integrity": "sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/get-intrinsic": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", @@ -10530,9 +10744,9 @@ } }, "node_modules/globals": { - "version": "17.6.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-17.6.0.tgz", - "integrity": "sha512-sepffkT8stwnIYbsMBpoCHJuJM5l98FUF2AnE07hfvE0m/qp3R586hw4jF4uadbhvg1ooIdzuu7CsfD2jzCaNA==", + "version": "17.8.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-17.8.0.tgz", + "integrity": "sha512-Zz/LMDZScFmkakeL2cTHzf+PbWKdpU3uclqkZT7TjDG58j5WPt0PpA+n9uPI24fZtlw07q0OtEi84K+umsRzqQ==", "dev": true, "license": "MIT", "engines": { @@ -10560,9 +10774,9 @@ } }, "node_modules/google-auth-library": { - "version": "10.6.2", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-10.6.2.tgz", - "integrity": "sha512-e27Z6EThmVNNvtYASwQxose/G57rkRuaRbQyxM2bvYLLX/GqWZ5chWq2EBoUchJbCc57eC9ArzO5wMsEmWftCw==", + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-10.9.1.tgz", + "integrity": "sha512-i1ydyHrqcIxXkWh/uBmVkzCvIuq5yiK2ATndIe5XxKholrG/MTYP9xGYka4sQhrbIAgGjL2B6NOE7rFaiF3fXw==", "license": "Apache-2.0", "dependencies": { "base64-js": "^1.3.0", @@ -10586,9 +10800,9 @@ } }, "node_modules/google-auth-library/node_modules/gaxios": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-7.1.4.tgz", - "integrity": "sha512-bTIgTsM2bWn3XklZISBTQX7ZSddGW+IO3bMdGaemHZ3tbqExMENHLx6kKZ/KlejgrMtj8q7wBItt51yegqalrA==", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-7.3.0.tgz", + "integrity": "sha512-RB5vLV+vvQeoFPCX4QMK6/hjVkbIamPp1QSUD0CiZcnj12qbpiL+pLbYtgD+oZkWl0tl9z+o2Utp+MpM3QRhBA==", "license": "Apache-2.0", "dependencies": { "extend": "^3.0.2", @@ -10631,70 +10845,177 @@ } }, "node_modules/google-gax": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-4.6.1.tgz", - "integrity": "sha512-V6eky/xz2mcKfAd1Ioxyd6nmA61gao3n01C+YeuIwu3vzM9EDR6wcVzMSIbLMDXWeoi9SHYctXuKYC5uJUT3eQ==", + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-5.0.8.tgz", + "integrity": "sha512-M4vpZcXQIC1gqIVGQ7eaU3jXQA6zecStyTXu514TYfThlgSurYJOxHZo9fzU6hAgwPWvuEynAVHWyaIk80VeEA==", "license": "Apache-2.0", "optional": true, "dependencies": { - "@grpc/grpc-js": "^1.10.9", - "@grpc/proto-loader": "^0.7.13", - "@types/long": "^4.0.0", - "abort-controller": "^3.0.0", - "duplexify": "^4.0.0", - "google-auth-library": "^9.3.0", - "node-fetch": "^2.7.0", + "@grpc/grpc-js": "^1.12.6", + "@grpc/proto-loader": "^0.8.0", + "duplexify": "^4.1.3", + "google-auth-library": "10.5.0", + "google-logging-utils": "1.1.3", + "node-fetch": "^3.3.2", "object-hash": "^3.0.0", - "proto3-json-serializer": "^2.0.2", - "protobufjs": "^7.3.2", - "retry-request": "^7.0.0", - "uuid": "^9.0.1" + "proto3-json-serializer": "3.0.4", + "protobufjs": "^7.5.4", + "retry-request": "^8.0.2", + "rimraf": "^5.0.1" }, "engines": { - "node": ">=14" + "node": ">=18" } }, - "node_modules/google-gax/node_modules/gcp-metadata": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.1.tgz", - "integrity": "sha512-a4tiq7E0/5fTjxPAaH4jpjkSv/uCaU2p5KC6HVGrvl0cDjA8iBZv4vv1gyzlmK0ZUKqwpOyQMKzZQe3lTit77A==", + "node_modules/google-gax/node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 14" + } + }, + "node_modules/google-gax/node_modules/gaxios": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-7.3.0.tgz", + "integrity": "sha512-RB5vLV+vvQeoFPCX4QMK6/hjVkbIamPp1QSUD0CiZcnj12qbpiL+pLbYtgD+oZkWl0tl9z+o2Utp+MpM3QRhBA==", "license": "Apache-2.0", "optional": true, "dependencies": { - "gaxios": "^6.1.1", - "google-logging-utils": "^0.0.2", - "json-bigint": "^1.0.0" + "extend": "^3.0.2", + "https-proxy-agent": "^7.0.1", + "node-fetch": "^3.3.2" }, "engines": { - "node": ">=14" + "node": ">=18" } }, "node_modules/google-gax/node_modules/google-auth-library": { - "version": "9.15.1", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.15.1.tgz", - "integrity": "sha512-Jb6Z0+nvECVz+2lzSMt9u98UsoakXxA2HGHMCxh+so3n90XgYWkq5dur19JAJV7ONiJY22yBTyJB1TSkvPq9Ng==", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-10.5.0.tgz", + "integrity": "sha512-7ABviyMOlX5hIVD60YOfHw4/CxOfBhyduaYB+wbFWCWoni4N7SLcV46hrVRktuBbZjFC9ONyqamZITN7q3n32w==", "license": "Apache-2.0", "optional": true, "dependencies": { "base64-js": "^1.3.0", "ecdsa-sig-formatter": "^1.0.11", - "gaxios": "^6.1.1", - "gcp-metadata": "^6.1.0", - "gtoken": "^7.0.0", + "gaxios": "^7.0.0", + "gcp-metadata": "^8.0.0", + "google-logging-utils": "^1.0.0", + "gtoken": "^8.0.0", "jws": "^4.0.0" }, "engines": { - "node": ">=14" + "node": ">=18" } }, - "node_modules/google-gax/node_modules/google-logging-utils": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/google-logging-utils/-/google-logging-utils-0.0.2.tgz", - "integrity": "sha512-NEgUnEcBiP5HrPzufUkBzJOD/Sxsco3rLNo1F1TNf7ieU8ryUzBhqba8r756CjLX7rn3fHl6iLEwPYuqpoKgQQ==", + "node_modules/google-gax/node_modules/gtoken": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-8.0.0.tgz", + "integrity": "sha512-+CqsMbHPiSTdtSO14O51eMNlrp9N79gmeqmXeouJOhfucAedHw9noVe/n5uJk3tbKE6a+6ZCQg3RPhVhHByAIw==", + "license": "MIT", + "optional": true, + "dependencies": { + "gaxios": "^7.0.0", + "jws": "^4.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/google-gax/node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "license": "MIT", + "optional": true, + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/google-gax/node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "license": "MIT", + "optional": true, + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/google-gax/node_modules/node-fetch": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", + "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", + "license": "MIT", + "optional": true, + "dependencies": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" + } + }, + "node_modules/google-gax/node_modules/retry-request": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-8.0.4.tgz", + "integrity": "sha512-pI6/7eabUYkZxamkOq0g0uMxKLLGnjzhefY+vL8bVXag5rto4OU2YBTPytWLuHH7aEKD6fn7kJycQfid0Mwnkw==", + "license": "MIT", + "optional": true, + "dependencies": { + "extend": "^3.0.2", + "teeny-request": "^10.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/google-gax/node_modules/rimraf": { + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz", + "integrity": "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==", + "license": "ISC", + "optional": true, + "dependencies": { + "glob": "^10.3.7" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/google-gax/node_modules/teeny-request": { + "version": "10.1.4", + "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-10.1.4.tgz", + "integrity": "sha512-R1Cg4Vu0UULeDfHL/kjABLaTW++9yD/B6n2g48y5dJ04hsEaxcfmAqbNDzNsbqAYJyIpZafjklLG9YxRu9uzOg==", "license": "Apache-2.0", "optional": true, + "dependencies": { + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.1", + "node-fetch": "^3.3.2", + "stream-events": "^1.0.5" + }, "engines": { - "node": ">=14" + "node": ">=18" } }, "node_modules/google-logging-utils": { @@ -10720,19 +11041,20 @@ } }, "node_modules/googleapis-common": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/googleapis-common/-/googleapis-common-8.0.1.tgz", - "integrity": "sha512-eCzNACUXPb1PW5l0ULTzMHaL/ltPRADoPgjBlT8jWsTbxkCp6siv+qKJ/1ldaybCthGwsYFYallF7u9AkU4L+A==", + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/googleapis-common/-/googleapis-common-8.0.3.tgz", + "integrity": "sha512-7g1yzQKx0mmNTjiK0H9dJ8eqKqDBveES9vLHeg5neb3BMQy/d1oQefIMhIpOVT8a+f+LOcixMEdRbFIW/cQUJw==", "license": "Apache-2.0", "dependencies": { "extend": "^3.0.2", - "gaxios": "^7.0.0-rc.4", - "google-auth-library": "^10.1.0", + "gaxios": "7.1.3", + "google-auth-library": "10.5.0", + "google-logging-utils": "1.1.3", "qs": "^6.7.0", "url-template": "^2.0.8" }, "engines": { - "node": ">=18.0.0" + "node": ">=18" } }, "node_modules/googleapis-common/node_modules/agent-base": { @@ -10745,14 +11067,46 @@ } }, "node_modules/googleapis-common/node_modules/gaxios": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-7.1.4.tgz", - "integrity": "sha512-bTIgTsM2bWn3XklZISBTQX7ZSddGW+IO3bMdGaemHZ3tbqExMENHLx6kKZ/KlejgrMtj8q7wBItt51yegqalrA==", + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-7.1.3.tgz", + "integrity": "sha512-YGGyuEdVIjqxkxVH1pUTMY/XtmmsApXrCVv5EU25iX6inEPbV+VakJfLealkBtJN69AQmh1eGOdCl9Sm1UP6XQ==", "license": "Apache-2.0", "dependencies": { "extend": "^3.0.2", "https-proxy-agent": "^7.0.1", - "node-fetch": "^3.3.2" + "node-fetch": "^3.3.2", + "rimraf": "^5.0.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/googleapis-common/node_modules/google-auth-library": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-10.5.0.tgz", + "integrity": "sha512-7ABviyMOlX5hIVD60YOfHw4/CxOfBhyduaYB+wbFWCWoni4N7SLcV46hrVRktuBbZjFC9ONyqamZITN7q3n32w==", + "license": "Apache-2.0", + "dependencies": { + "base64-js": "^1.3.0", + "ecdsa-sig-formatter": "^1.0.11", + "gaxios": "^7.0.0", + "gcp-metadata": "^8.0.0", + "google-logging-utils": "^1.0.0", + "gtoken": "^8.0.0", + "jws": "^4.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/googleapis-common/node_modules/gtoken": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-8.0.0.tgz", + "integrity": "sha512-+CqsMbHPiSTdtSO14O51eMNlrp9N79gmeqmXeouJOhfucAedHw9noVe/n5uJk3tbKE6a+6ZCQg3RPhVhHByAIw==", + "license": "MIT", + "dependencies": { + "gaxios": "^7.0.0", + "jws": "^4.0.0" }, "engines": { "node": ">=18" @@ -10789,6 +11143,21 @@ "url": "https://opencollective.com/node-fetch" } }, + "node_modules/googleapis-common/node_modules/rimraf": { + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz", + "integrity": "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==", + "license": "ISC", + "dependencies": { + "glob": "^10.3.7" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/gopd": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", @@ -10805,7 +11174,6 @@ "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true, "license": "ISC" }, "node_modules/gtoken": { @@ -10823,18 +11191,19 @@ } }, "node_modules/happy-dom": { - "version": "20.9.0", - "resolved": "https://registry.npmjs.org/happy-dom/-/happy-dom-20.9.0.tgz", - "integrity": "sha512-GZZ9mKe8r646NUAf/zemnGbjYh4Bt8/MqASJY+pSm5ZDtc3YQox+4gsLI7yi1hba6o+eCsGxpHn5+iEVn31/FQ==", + "version": "20.11.1", + "resolved": "https://registry.npmjs.org/happy-dom/-/happy-dom-20.11.1.tgz", + "integrity": "sha512-XSt8tMzbW9ymE7687xztkO1ckR7qJNQ3LywY9vlYGhGi3zXrGBHuUo2Cl1ztZaICW+1eAGdkLbj6iwVqDT33kg==", "dev": true, "license": "MIT", "dependencies": { "@types/node": ">=20.0.0", "@types/whatwg-mimetype": "^3.0.2", "@types/ws": "^8.18.1", + "buffer-image-size": "^0.6.4", "entities": "^7.0.1", "whatwg-mimetype": "^3.0.0", - "ws": "^8.18.3" + "ws": "^8.21.0" }, "engines": { "node": ">=20.0.0" @@ -10857,7 +11226,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -11082,10 +11450,17 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/html5parser": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html5parser/-/html5parser-3.0.0.tgz", + "integrity": "sha512-iNpSopa+4YHX50UOk825tBy7MghmXHo/ZpLskBYN0kAr1xhH8GlIMk5bLRXcZlfP3AnLUcSuFMu8C4MdOUxA8A==", + "license": "MIT" + }, "node_modules/htmlparser2": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-10.1.0.tgz", "integrity": "sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ==", + "dev": true, "funding": [ "https://github.com/fb55/htmlparser2?sponsor=1", { @@ -11177,9 +11552,9 @@ } }, "node_modules/immer": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/immer/-/immer-10.2.0.tgz", - "integrity": "sha512-d/+XTN3zfODyjr89gM3mPq1WNX2B8pYsu7eORitdwyA2sBubnTl3laYlBk4sXY5FUa5qTZGBDPJICVbvqzjlbw==", + "version": "11.1.15", + "resolved": "https://registry.npmjs.org/immer/-/immer-11.1.15.tgz", + "integrity": "sha512-VrNANlmnWQnh5COXIIOQXM9oOJw7naGKlBT74ZOOR6lpVXc3gFEu9FJLDFcpCJ2j+NWr8TIwtWD//T6ZX6TKiQ==", "license": "MIT", "funding": { "type": "opencollective", @@ -11204,14 +11579,13 @@ } }, "node_modules/import-in-the-middle": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-3.0.1.tgz", - "integrity": "sha512-pYkiyXVL2Mf3pozdlDGV6NAObxQx13Ae8knZk1UJRJ6uRW/ZRmTGHlQYtrsSl7ubuE5F8CD1z+s1n4RHNuTtuA==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-3.3.2.tgz", + "integrity": "sha512-jTd2FfOgOWOdgjkHuk/1Ms8VKFXkPs15ymYBETw1sAOrO/dY3XeGVRWir9qBbw7pXr0T2eTFwfCZ+N02HmiNGA==", "license": "Apache-2.0", "dependencies": { - "acorn": "^8.15.0", - "acorn-import-attributes": "^1.9.5", "cjs-module-lexer": "^2.2.0", + "es-module-lexer": "^2.2.0", "module-details-from-path": "^1.0.4" }, "engines": { @@ -11381,9 +11755,9 @@ } }, "node_modules/is-bun-module/node_modules/semver": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.1.tgz", - "integrity": "sha512-rkVq3IXh+4FDGch+KwzX3aV9W3kO54GyEgpvBzSyctDA6Xtd7RJQV1xmXbeQp5v7+VzLOfVqiutSE6GICgPFvg==", + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", "dev": true, "license": "ISC", "bin": { @@ -11467,6 +11841,22 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/is-document.all": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-document.all/-/is-document.all-1.0.0.tgz", + "integrity": "sha512-+XSoyS05OdBbhFuELhgTCpFNHkpBOJqtsZfUFFpe5QTw+9Sjbh8zitxhQkYAo6wV7e1Vb8cAPvpCk9jGam/82g==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -11494,19 +11884,13 @@ } }, "node_modules/is-fullwidth-code-point": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.1.0.tgz", - "integrity": "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==", - "dev": true, + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "license": "MIT", - "dependencies": { - "get-east-asian-width": "^1.3.1" - }, + "optional": true, "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, "node_modules/is-generator-function": { @@ -11766,6 +12150,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-unsafe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-unsafe/-/is-unsafe-2.0.0.tgz", + "integrity": "sha512-2LdV822R+wmI86unXA93WCFpL6g+av8ynWk0nrHyJqGop5VoocYsSLFgN8jrfalT6iGeLNM4KXuVSsULP53kEA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT", + "optional": true + }, "node_modules/is-weakmap": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", @@ -11882,6 +12279,37 @@ "node": ">= 0.4" } }, + "node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "license": "MIT", + "peer": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "license": "MIT", + "peer": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, "node_modules/jiti": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.7.0.tgz", @@ -11893,9 +12321,9 @@ } }, "node_modules/jose": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/jose/-/jose-6.2.3.tgz", - "integrity": "sha512-YYVDInQKFJfR/xa3ojUTl8c2KoTwiL1R5Wg9YCydwH0x0B9grbzlg5HC7mMjCtUJjbQ/YnGEZIhI5tCgfTb4Hw==", + "version": "6.2.6", + "resolved": "https://registry.npmjs.org/jose/-/jose-6.2.6.tgz", + "integrity": "sha512-HwMtbJjMw8rC8dUTwCNilHJD+fxTeKM3JV1eprSmTjS41qwXSSt6exJXgyPK1QOu0jB9eDYLESRDkB3qaT3jnw==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/panva" @@ -11908,9 +12336,9 @@ "license": "MIT" }, "node_modules/js-yaml": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.2.0.tgz", - "integrity": "sha512-ePWsvanv0DWuDRsW8dnt+R4jQ31SCRCQ7hhNcPXZPsoBZiemuZNYGf7adZdqX2D86j6rvKp3RpCxVTSb8WQlOw==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.1.tgz", + "integrity": "sha512-CY6crGq313MX8GkwvB7tzgp99vjQxY1++5y10/BKN/GUfHqWaOGQMNZkBvqSzsZKWk/ijwHlWzzkLulsGHhjWQ==", "dev": true, "funding": [ { @@ -11931,39 +12359,39 @@ } }, "node_modules/jsdom": { - "version": "29.1.1", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-29.1.1.tgz", - "integrity": "sha512-ECi4Fi2f7BdJtUKTflYRTiaMxIB0O6zfR1fX0GXpUrf6flp8QIYn1UT20YQqdSOfk2dfkCwS8LAFoJDEppNK5Q==", + "version": "30.0.1", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-30.0.1.tgz", + "integrity": "sha512-52v7mUVUfNQVYYqE1lcdaymWL0njO7lTLUog6ZvW2U5KsbiLk/GnZlVJ+qx0xfNJZ6Gn+KSpPNE52vurbxZwrA==", "dev": true, "license": "MIT", "dependencies": { - "@asamuzakjp/css-color": "^5.1.11", - "@asamuzakjp/dom-selector": "^7.1.1", + "@asamuzakjp/css-color": "^6.0.5", + "@asamuzakjp/dom-selector": "^8.3.0", "@bramus/specificity": "^2.4.2", - "@csstools/css-syntax-patches-for-csstree": "^1.1.3", - "@exodus/bytes": "^1.15.0", + "@csstools/css-syntax-patches-for-csstree": "^1.1.7", + "@exodus/bytes": "^1.15.1", "css-tree": "^3.2.1", "data-urls": "^7.0.0", "decimal.js": "^10.6.0", "html-encoding-sniffer": "^6.0.0", "is-potential-custom-element-name": "^1.0.1", - "lru-cache": "^11.3.5", + "lru-cache": "^11.5.2", "parse5": "^8.0.1", "saxes": "^6.0.0", "symbol-tree": "^3.2.4", - "tough-cookie": "^6.0.1", - "undici": "^7.25.0", + "tough-cookie": "^6.0.2", + "undici": "^8.9.0", "w3c-xmlserializer": "^5.0.0", "webidl-conversions": "^8.0.1", "whatwg-mimetype": "^5.0.0", - "whatwg-url": "^16.0.1", + "whatwg-url": "^17.1.0", "xml-name-validator": "^5.0.0" }, "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24.0.0" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" }, "peerDependencies": { - "canvas": "^3.0.0" + "canvas": "^3.2.3" }, "peerDependenciesMeta": { "canvas": { @@ -12010,10 +12438,9 @@ "license": "MIT" }, "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true, + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "license": "MIT" }, "node_modules/json-schema-typed": { @@ -12064,9 +12491,9 @@ } }, "node_modules/jsonwebtoken/node_modules/semver": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.1.tgz", - "integrity": "sha512-rkVq3IXh+4FDGch+KwzX3aV9W3kO54GyEgpvBzSyctDA6Xtd7RJQV1xmXbeQp5v7+VzLOfVqiutSE6GICgPFvg==", + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -12113,28 +12540,20 @@ } }, "node_modules/jwks-rsa": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jwks-rsa/-/jwks-rsa-3.2.2.tgz", - "integrity": "sha512-BqTyEDV+lS8F2trk3A+qJnxV5Q9EqKCBJOPti3W97r7qTympCZjb7h2X6f2kc+0K3rsSTY1/6YG2eaXKoj497w==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/jwks-rsa/-/jwks-rsa-4.1.0.tgz", + "integrity": "sha512-sbkByqyATKYJP5F4RXj03N5TUNC0QLTjCAZvwTzC4BwJZ8e0/cWxN8YROnyUth2g1/ONWi4eSFHeu6oYalrc3Q==", "license": "MIT", "dependencies": { "@types/jsonwebtoken": "^9.0.4", "debug": "^4.3.4", - "jose": "^4.15.4", + "jose": "^6.1.3", "limiter": "^1.1.5", - "lru-memoizer": "^2.2.0" + "lru-cache": "^11.0.0", + "lru-memoizer": "^3.0.0" }, "engines": { - "node": ">=14" - } - }, - "node_modules/jwks-rsa/node_modules/jose": { - "version": "4.15.9", - "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.9.tgz", - "integrity": "sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/panva" + "node": "^20.19.0 || ^22.12.0 || >= 23.0.0" } }, "node_modules/jws": { @@ -12509,14 +12928,13 @@ "integrity": "sha512-FWWMIEOxz3GwUI4Ts/IvgVy6LPvoMPgjMdQ185nN6psJyBJ4yOpzqm695/h5umdLJg2vW3GR5iG11MAkR2AzJA==" }, "node_modules/lint-staged": { - "version": "17.0.7", - "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-17.0.7.tgz", - "integrity": "sha512-JrSobt+tW3rH8IOMi8tDZd3foorM5yPEkLD/V2NxobgHrFfHWGee4MOLVuZeScgxftEwbHrPHIFA/ZL+nUJeuA==", + "version": "17.3.0", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-17.3.0.tgz", + "integrity": "sha512-woZS3vNe3UKqBaLPvbLOtKRY4tLANpWQhom12MGWqC8Mh1lCOO+WgSwmX2amjJAqTY9BkXYW87fCUH5H9Ph6xw==", "dev": true, "license": "MIT", "dependencies": { - "listr2": "^10.2.1", - "picomatch": "^4.0.4", + "picomatch": "^4.0.5", "string-argv": "^0.3.2", "tinyexec": "^1.2.4" }, @@ -12533,23 +12951,6 @@ "yaml": "^2.9.0" } }, - "node_modules/listr2": { - "version": "10.2.1", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-10.2.1.tgz", - "integrity": "sha512-7I5knELsJKTUjXG+A6BkKAiGkW1i25fNa/xlUl9hFtk15WbE9jndA89xu5FzQKrY5llajE1hfZZFMILXkDHk/Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "cli-truncate": "^5.2.0", - "eventemitter3": "^5.0.4", - "log-update": "^6.1.0", - "rfdc": "^1.4.1", - "wrap-ansi": "^10.0.0" - }, - "engines": { - "node": ">=22.13.0" - } - }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -12649,99 +13050,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/log-update": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.1.0.tgz", - "integrity": "sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-escapes": "^7.0.0", - "cli-cursor": "^5.0.0", - "slice-ansi": "^7.1.0", - "strip-ansi": "^7.1.0", - "wrap-ansi": "^9.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/log-update/node_modules/ansi-styles": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", - "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/log-update/node_modules/emoji-regex": { - "version": "10.6.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", - "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", - "dev": true, - "license": "MIT" - }, - "node_modules/log-update/node_modules/slice-ansi": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.2.tgz", - "integrity": "sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.2.1", - "is-fullwidth-code-point": "^5.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" - } - }, - "node_modules/log-update/node_modules/string-width": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", - "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^10.3.0", - "get-east-asian-width": "^1.0.0", - "strip-ansi": "^7.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/log-update/node_modules/wrap-ansi": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", - "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.2.1", - "string-width": "^7.0.0", - "strip-ansi": "^7.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, "node_modules/long": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", @@ -12772,46 +13080,28 @@ } }, "node_modules/lru-cache": { - "version": "11.5.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.1.tgz", - "integrity": "sha512-RPimw/7aMdv2oqRrxKwvZXcPfwBrn/JZ2xYcY9Hus/6LaS3VOAKVWKWgNLCFSiOm1ESXinjsDlidVU7JlnCN2A==", + "version": "11.5.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.2.tgz", + "integrity": "sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g==", "license": "BlueOak-1.0.0", "engines": { "node": "20 || >=22" } }, "node_modules/lru-memoizer": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/lru-memoizer/-/lru-memoizer-2.3.0.tgz", - "integrity": "sha512-GXn7gyHAMhO13WSKrIiNfztwxodVsP8IoZ3XfrJV4yH2x0/OeTO/FIaAHTY5YekdGgW94njfuKmyyt1E0mR6Ug==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lru-memoizer/-/lru-memoizer-3.0.0.tgz", + "integrity": "sha512-m83w/cYXLdUIboKSPxzPAGfYnk+vqeDYXuoSrQRw1q+yVEd8IXhvMufN8Q5TIPe7e2jyX4SRNrDJI2Skw1yznQ==", "license": "MIT", "dependencies": { "lodash.clonedeep": "^4.5.0", - "lru-cache": "6.0.0" + "lru-cache": "^11.0.1" } }, - "node_modules/lru-memoizer/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/lru-memoizer/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "license": "ISC" - }, "node_modules/lucide-react": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-1.17.0.tgz", - "integrity": "sha512-9FA9evdox/JQL5PT57fdA1x/yg8T7knJ98+zjTL3UfKza6pflQUUh3XtaQIHKvnsJw1lmsEyHVlt5jchYxOQ5w==", + "version": "1.28.0", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-1.28.0.tgz", + "integrity": "sha512-fARAFJULsGuDDydjp6+6blekG/sBIM29TerzLjc9bQUKAcEfrSc4ZQKb25KRz4OMKd87cZTb5dgq0w/T6KufVg==", "license": "ISC", "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" @@ -12837,14 +13127,14 @@ } }, "node_modules/magicast": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.5.3.tgz", - "integrity": "sha512-pVKE4UdSQ7DvHzivsCIFx2BJn1mHG6KsyrFcaxFx6tONdneEuThrDx0Cj3AMg58KyN4pzYT+LHOotxDQDjNvkw==", + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.5.4.tgz", + "integrity": "sha512-llBEhWm1SacoRwgHUoQJYtwp4PBLF4faQi5TCpIGyGs9n4y5+juI0tDgyKIfpqxckRHaHzouUEph3THklWh03w==", "dev": true, "license": "MIT", "dependencies": { - "@babel/parser": "^7.29.3", - "@babel/types": "^7.29.0", + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7", "source-map-js": "^1.2.1" } }, @@ -12865,9 +13155,9 @@ } }, "node_modules/make-dir/node_modules/semver": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.1.tgz", - "integrity": "sha512-rkVq3IXh+4FDGch+KwzX3aV9W3kO54GyEgpvBzSyctDA6Xtd7RJQV1xmXbeQp5v7+VzLOfVqiutSE6GICgPFvg==", + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", "dev": true, "license": "ISC", "bin": { @@ -13057,6 +13347,13 @@ "integrity": "sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==", "license": "CC0-1.0" }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "license": "MIT", + "peer": true + }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -13067,6 +13364,15 @@ "node": ">= 8" } }, + "node_modules/meriyah": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/meriyah/-/meriyah-6.1.4.tgz", + "integrity": "sha512-Sz8FzjzI0kN13GK/6MVEsVzMZEPvOhnmmI1lU5+/1cGOiK3QUahntrNNtdVeihrO7t9JpoH75iMNXg6R6uWflQ==", + "license": "ISC", + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/micromark": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", @@ -13593,12 +13899,12 @@ } }, "node_modules/minimatch": { - "version": "10.2.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", - "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "version": "10.2.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.6.tgz", + "integrity": "sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==", "license": "BlueOak-1.0.0", "dependencies": { - "brace-expansion": "^5.0.5" + "brace-expansion": "^5.0.8" }, "engines": { "node": "18 || 20 || >=22" @@ -13616,6 +13922,67 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/minimizer-webpack-plugin": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/minimizer-webpack-plugin/-/minimizer-webpack-plugin-5.6.1.tgz", + "integrity": "sha512-DoeAZz8Q1C1znwsUzej1fdoi4jCf7/+Em27ouLqfK/+3m8G+D7yDhUwrc3CNhjSzGUN1kn7Iv4sWmjflQHenpw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.25", + "jest-worker": "^27.4.5", + "schema-utils": "^4.3.0", + "terser": "^5.31.1" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@minify-html/node": { + "optional": true + }, + "@swc/core": { + "optional": true + }, + "@swc/css": { + "optional": true + }, + "@swc/html": { + "optional": true + }, + "clean-css": { + "optional": true + }, + "cssnano": { + "optional": true + }, + "csso": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "html-minifier-terser": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "postcss": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, "node_modules/minipass": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", @@ -13632,9 +13999,9 @@ "license": "MIT" }, "node_modules/motion-dom": { - "version": "12.40.0", - "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.40.0.tgz", - "integrity": "sha512-HxU3ZaBwNPVQUBQf1xxgq+7JrPNZvjLVxgbpEZL7RrWJnsxOf0/OM+yrHG9ogLQ31Do/r57Oz2gQWPK+6q62mg==", + "version": "12.43.0", + "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.43.0.tgz", + "integrity": "sha512-azKON4d9S65PEoFUiQTMTgPheEmzf2QngdRc50AKfJp9Q9mmcBVw22c8eMq9k8kxOFHdL7+WZY7N/5F/lwiDag==", "license": "MIT", "dependencies": { "motion-utils": "^12.39.0" @@ -13663,9 +14030,9 @@ "license": "MIT" }, "node_modules/nanoid": { - "version": "5.1.11", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.1.11.tgz", - "integrity": "sha512-v+KEsUv2ps74PaSKv0gHTxTCgMXOIfBEbaqa6w6ISIGC7ZsvHN4N9oJ8d4cmf0n5oTzQz2SLmThbQWhjd/8eKg==", + "version": "5.1.16", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.1.16.tgz", + "integrity": "sha512-kVrnsrJqMR8+oLJnGEmSWw9BivK5mt7H3FZatVRjrc5wGqFYuBxX1yG7+A7Gi5AefkX6t/oCkizcQgpu0cY1dQ==", "funding": [ { "type": "github", @@ -13712,13 +14079,20 @@ "node": ">= 0.6" } }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "license": "MIT", + "peer": true + }, "node_modules/next": { - "version": "16.2.6", - "resolved": "https://registry.npmjs.org/next/-/next-16.2.6.tgz", - "integrity": "sha512-qOVgKJg1+At15NpeUP+eJgCHvTCgXsogweq87Ri/Ix7PkqQHg4sdaXmSFqKlgaIXE4kW0g25LE68W87UANlHtw==", + "version": "16.2.12", + "resolved": "https://registry.npmjs.org/next/-/next-16.2.12.tgz", + "integrity": "sha512-iD59eYQWmbFcEbX7v/acG5DRym9iw1DdaPoD0WTA920naWsE25wShzJW4+UvAs8MK9EC2kBfIH6vtto1H1PHGw==", "license": "MIT", "dependencies": { - "@next/env": "16.2.6", + "@next/env": "16.2.12", "@swc/helpers": "0.5.15", "baseline-browser-mapping": "^2.9.19", "caniuse-lite": "^1.0.30001579", @@ -13732,14 +14106,14 @@ "node": ">=20.9.0" }, "optionalDependencies": { - "@next/swc-darwin-arm64": "16.2.6", - "@next/swc-darwin-x64": "16.2.6", - "@next/swc-linux-arm64-gnu": "16.2.6", - "@next/swc-linux-arm64-musl": "16.2.6", - "@next/swc-linux-x64-gnu": "16.2.6", - "@next/swc-linux-x64-musl": "16.2.6", - "@next/swc-win32-arm64-msvc": "16.2.6", - "@next/swc-win32-x64-msvc": "16.2.6", + "@next/swc-darwin-arm64": "16.2.12", + "@next/swc-darwin-x64": "16.2.12", + "@next/swc-linux-arm64-gnu": "16.2.12", + "@next/swc-linux-arm64-musl": "16.2.12", + "@next/swc-linux-x64-gnu": "16.2.12", + "@next/swc-linux-x64-musl": "16.2.12", + "@next/swc-win32-arm64-msvc": "16.2.12", + "@next/swc-win32-x64-msvc": "16.2.12", "sharp": "^0.34.5" }, "peerDependencies": { @@ -13804,9 +14178,9 @@ } }, "node_modules/node-exports-info": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/node-exports-info/-/node-exports-info-1.6.0.tgz", - "integrity": "sha512-pyFS63ptit/P5WqUkt+UUfe+4oevH+bFeIiPPdfb0pFeYEu/1ELnJu5l+5EcTKYL5M7zaAa7S8ddywgXypqKCw==", + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/node-exports-info/-/node-exports-info-1.6.2.tgz", + "integrity": "sha512-kXs9Go0cah0qHVV2v389IXQLdLCeE1xfFtjOAF+iobu0OIoG1pje8At2vMHyaPMiPMnG/LWP50twML21eMcAag==", "dev": true, "license": "MIT", "dependencies": { @@ -13865,9 +14239,9 @@ } }, "node_modules/node-releases": { - "version": "2.0.46", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.46.tgz", - "integrity": "sha512-GYVXHE2KnrzAfsAjl4uP++evGFCrAU1jta4ubEjIG7YWt/64Gqv66a30yKwWczVjA6j3bM4nBwH7Pk1JmDHaxQ==", + "version": "2.0.51", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.51.tgz", + "integrity": "sha512-wRNIrw4DmVLKQlbgOMdkMx27Wrpzes2hh5Jtbi2bjPd+4wJstWIqP5A+lscnqbm0xxmT5Bpg8Lec5ItEBwx6BQ==", "license": "MIT", "engines": { "node": ">=18" @@ -14037,15 +14411,18 @@ } }, "node_modules/obug": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.1.tgz", - "integrity": "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.4.tgz", + "integrity": "sha512-4a+OsYv9UktOJKE+l1A4OufDgdRF9PifWj+tJnHURo/P+WOxpG4GzUFL9qCalmWauao6ogiG+QvnCovwPoyAWA==", "dev": true, "funding": [ "https://github.com/sponsors/sxzz", "https://opencollective.com/debug" ], - "license": "MIT" + "license": "MIT", + "engines": { + "node": ">=12.20.0" + } }, "node_modules/once": { "version": "1.4.0", @@ -14057,22 +14434,6 @@ "wrappy": "1" } }, - "node_modules/onetime": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", - "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "mimic-function": "^5.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/optionator": { "version": "0.9.4", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", @@ -14092,13 +14453,14 @@ } }, "node_modules/own-keys": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", - "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.2.tgz", + "integrity": "sha512-19YVAg7T+WTrxggPukVq7DjTv6+PJ867TmhCvBsYwmbFCsZd344rq2Ld1p0wo8f8Qrrhgp82c6FJRqdXWtSEhg==", "dev": true, "license": "MIT", "dependencies": { - "get-intrinsic": "^1.2.6", + "call-bound": "^1.0.4", + "get-intrinsic": "^1.3.0", "object-keys": "^1.1.1", "safe-push-apply": "^1.0.0" }, @@ -14239,9 +14601,9 @@ } }, "node_modules/path-expression-matcher": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/path-expression-matcher/-/path-expression-matcher-1.5.0.tgz", - "integrity": "sha512-cbrerZV+6rvdQrrD+iGMcZFEiiSrbv9Tfdkvnusy6y0x0GKBXREFg/Y65GhIfm0tnLntThhzCnfKwp1WRjeCyQ==", + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/path-expression-matcher/-/path-expression-matcher-1.6.2.tgz", + "integrity": "sha512-enSlaiat05iasnzmgNxRj8reFdj3puY2QpNgP1aPIaVfT6nn9ICuPoFlKHk8EN22HcwewshO+mN2DGbkCEOtqQ==", "funding": [ { "type": "github", @@ -14309,9 +14671,9 @@ "license": "ISC" }, "node_modules/picomatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", + "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", "license": "MIT", "engines": { "node": ">=12" @@ -14321,44 +14683,44 @@ } }, "node_modules/picospinner": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/picospinner/-/picospinner-3.0.0.tgz", - "integrity": "sha512-lGA1TNsmy2bxvRsTI2cV01kfTwKzZjnZSDmF9llYNyMHMrU4sP87lQ5taiIKm88L3cbswjl008nwyGc3WpNvzg==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/picospinner/-/picospinner-3.1.2.tgz", + "integrity": "sha512-0Z++uU8mvB0EvCPAEUq9BGiPcSravzJ+RPdXfjYlzXffqsogisiKRQqI6ctrSSJ6n985vxrgKtQ5n4sRINcJZg==", "license": "MIT", "engines": { "node": ">=18.0.0" } }, "node_modules/playwright": { - "version": "1.60.0", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.60.0.tgz", - "integrity": "sha512-hheHdokM8cdqCb0lcE3s+zT4t4W+vvjpGxsZlDnikarzx8tSzMebh3UiFtgqwFwnTnjYQcsyMF8ei2mCO/tpeA==", - "dev": true, + "version": "1.62.1", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.62.1.tgz", + "integrity": "sha512-0M+L3LAD8/nm554LOla9Ayx0j0tmFZ0FBcoQ7F1VuVHpM/XpiC8RcDzBQB8W5+hA8L22THxELzeF+2WcUzvcLg==", + "devOptional": true, "license": "Apache-2.0", "dependencies": { - "playwright-core": "1.60.0" + "playwright-core": "1.62.1" }, "bin": { "playwright": "cli.js" }, "engines": { - "node": ">=18" + "node": ">=20" }, "optionalDependencies": { "fsevents": "2.3.2" } }, "node_modules/playwright-core": { - "version": "1.60.0", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.60.0.tgz", - "integrity": "sha512-9bW6zvX/m0lEbgTKJ6YppOKx8H3VOPBMOCFh2irXFOT4BbHgrx5hPjwJYLT40Lu+4qtD36qKc/Hn56StUW57IA==", - "dev": true, + "version": "1.62.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.62.1.tgz", + "integrity": "sha512-wPYSwEBJY9GHraISXqyqtx0na0LpO3XEX7jNDhntbex7tzUS7kLnZsOlFruFJB4Hi/rhDMjXGqHewDZ68nYZVw==", + "devOptional": true, "license": "Apache-2.0", "bin": { "playwright-core": "cli.js" }, "engines": { - "node": ">=18" + "node": ">=20" } }, "node_modules/possible-typed-array-names": { @@ -14372,15 +14734,15 @@ } }, "node_modules/postal-mime": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/postal-mime/-/postal-mime-2.7.4.tgz", - "integrity": "sha512-0WdnFQYUrPGGTFu1uOqD2s7omwua8xaeYGdO6rb88oD5yJ/4pPHDA4sdWqfD8wQVfCny563n/HQS7zTFft+f/g==", + "version": "2.7.5", + "resolved": "https://registry.npmjs.org/postal-mime/-/postal-mime-2.7.5.tgz", + "integrity": "sha512-GNEXKvWFQnbgO5NlrGzVa0FmWzBZ24PersAWErttSg1Hjpf0ATxTwS5DOMGaOpTG6bUh5cTr7xi0jAD942wCJA==", "license": "MIT-0" }, "node_modules/postcss": { - "version": "8.5.15", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.15.tgz", - "integrity": "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==", + "version": "8.5.25", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.25.tgz", + "integrity": "sha512-DTPx3RWSSnWyzLxQnlH0rJP+EW5ekl16ZU4/psbIhA0e53kJfdgaN5vKM+xP7yJtXVu+nfdVFmlgFDEKAe4Pyw==", "funding": [ { "type": "opencollective", @@ -14397,7 +14759,7 @@ ], "license": "MIT", "dependencies": { - "nanoid": "^3.3.12", + "nanoid": "^3.3.16", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" }, @@ -14406,9 +14768,9 @@ } }, "node_modules/postcss/node_modules/nanoid": { - "version": "3.3.12", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz", - "integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==", + "version": "3.3.16", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.16.tgz", + "integrity": "sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==", "funding": [ { "type": "github", @@ -14434,9 +14796,9 @@ } }, "node_modules/prettier": { - "version": "3.8.3", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.3.tgz", - "integrity": "sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw==", + "version": "3.9.6", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.9.6.tgz", + "integrity": "sha512-OpN0zzVdiaiAhxpuuj5efpIS4sY9j7bY6uR5mnj5yPzGkdkjNKSJeUThPb60Jw29QuAZgA4o+/iB49kFiaBX6g==", "license": "MIT", "bin": { "prettier": "bin/prettier.cjs" @@ -14544,9 +14906,9 @@ "license": "MIT" }, "node_modules/property-information": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.1.0.tgz", - "integrity": "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.2.0.tgz", + "integrity": "sha512-IAtzIB6sUiWaJYrX9smp3V46pBGbBeLFRGdh25kg1334VcBlD8HzhPeNIWQH9zhGmo2itIe25EHt9dQP7G5hmg==", "license": "MIT", "funding": { "type": "github", @@ -14554,22 +14916,22 @@ } }, "node_modules/proto3-json-serializer": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/proto3-json-serializer/-/proto3-json-serializer-2.0.2.tgz", - "integrity": "sha512-SAzp/O4Yh02jGdRc+uIrGoe87dkN/XtwxfZ4ZyafJHymd79ozp5VG5nyZ7ygqPM5+cpLDjjGnYFUkngonyDPOQ==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/proto3-json-serializer/-/proto3-json-serializer-3.0.4.tgz", + "integrity": "sha512-E1sbAYg3aEbXrq0n1ojJkRHQJGE1kaE/O6GLA94y8rnJBfgvOPTOd1b9hOceQK1FFZI9qMh1vBERCyO2ifubcw==", "license": "Apache-2.0", "optional": true, "dependencies": { - "protobufjs": "^7.2.5" + "protobufjs": "^7.4.0" }, "engines": { - "node": ">=14.0.0" + "node": ">=18" } }, "node_modules/protobufjs": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.6.2.tgz", - "integrity": "sha512-N9EiLovGEQOJSPF26Ij7qUGvahfEnq0eeYZ02aigIedkmz1qZSwjnP9SBITHJuF/6MYbIW4HDN8zdYjsjqJKXQ==", + "version": "7.6.5", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.6.5.tgz", + "integrity": "sha512-/FPD0nUc9jH6rfFjji9IBqOz4pcSE3CsT1m7Ep6Mdb0LxSUMj8hgl6GomOvZzpNpAqqGaXA0P3VSrZLFzIhQrw==", "hasInstallScript": true, "license": "BSD-3-Clause", "optional": true, @@ -14580,7 +14942,6 @@ "@protobufjs/eventemitter": "^1.1.1", "@protobufjs/fetch": "^1.1.1", "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.2", "@protobufjs/path": "^1.1.2", "@protobufjs/pool": "^1.1.0", "@protobufjs/utf8": "^1.1.1", @@ -14608,12 +14969,13 @@ } }, "node_modules/qs": { - "version": "6.15.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.2.tgz", - "integrity": "sha512-Rzq0KEyX/w/tEybncDgdkZrJgVUsUMk3xjh3t5bv3S1HTAtg+uOYt72+ZfwiQwKdysThkTBdL/rTi6HDmX9Ddw==", + "version": "6.15.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.3.tgz", + "integrity": "sha512-O9gl3zCl5h5blw1KGUzQKhA5oUXSl8rwUIM5o0S3nCXMliSvy5Dzx7/DJcI+SwgICv+IneSZwhBh1oSyEHA71A==", "license": "BSD-3-Clause", "dependencies": { - "side-channel": "^1.1.0" + "es-define-property": "^1.0.1", + "side-channel": "^1.1.1" }, "engines": { "node": ">=0.6" @@ -14644,9 +15006,9 @@ "license": "MIT" }, "node_modules/react": { - "version": "19.2.6", - "resolved": "https://registry.npmjs.org/react/-/react-19.2.6.tgz", - "integrity": "sha512-sfWGGfavi0xr8Pg0sVsyHMAOziVYKgPLNrS7ig+ivMNb3wbCBw3KxtflsGBAwD3gYQlE/AEZsTLgToRrSCjb0Q==", + "version": "19.2.8", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.8.tgz", + "integrity": "sha512-PWaYA1L/q9u2u7xYQi+Y3L3Yfnie7XyLeaJICV1MGD6LprsBxcAqGjYyr0eY3p+QdsA+x/Irkt4Qif8D63+Sbw==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -14679,26 +15041,26 @@ } }, "node_modules/react-dom": { - "version": "19.2.6", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.6.tgz", - "integrity": "sha512-0prMI+hvBbPjsWnxDLxlCGyM8PN6UuWjEUCYmZhO67xIV9Xasa/r/vDnq+Xyq4Lo27g8QSbO5YzARu0D1Sps3g==", + "version": "19.2.8", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.8.tgz", + "integrity": "sha512-rVprimfGBG3DR+Tq0IQG2DT5PxKth1WIGDmj5yPmlzr4YBe7uyE+Du4oVqTDXZSHGGGXRtTJEGSSePyQCMBglQ==", "license": "MIT", "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { - "react": "^19.2.6" + "react": "^19.2.8" } }, "node_modules/react-email": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/react-email/-/react-email-6.5.0.tgz", - "integrity": "sha512-WrJ+XPW87O1dabF4RJNGnTr7VTGsNa+BlMiinAZdH5fg8Kepwk++ZzX+LEieTlk+a3r13TaTJ4DfI9gv++y02g==", + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/react-email/-/react-email-6.9.1.tgz", + "integrity": "sha512-uUDRgFukMUXRlrsCNGlA0PZuUlQ44faI9hT/D7uMjozdumLBdHjfQttQswRYLjyLW8fFtg2HBrxAESbFU4ZKKA==", "license": "MIT", "dependencies": { - "@babel/parser": "7.27.0", - "@babel/traverse": "7.27.0", - "@react-email/render": ">=2.0.8", + "@babel/parser": "7.29.2", + "@babel/traverse": "7.29.0", + "@react-email/render": ">=2.1.0", "chokidar": "^4.0.3", "commander": "^13.0.0", "conf": "^15.0.2", @@ -14706,7 +15068,7 @@ "debounce": "^2.0.0", "esbuild": "^0.28.0", "glob": "^13.0.6", - "jiti": "2.4.2", + "jiti": "2.6.1", "log-symbols": "^7.0.0", "marked": "^15.0.12", "mime-types": "^3.0.0", @@ -14731,12 +15093,12 @@ } }, "node_modules/react-email/node_modules/@babel/parser": { - "version": "7.27.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.0.tgz", - "integrity": "sha512-iaepho73/2Pz7w2eMS0Q5f83+0RKI7i4xmiYeBmDzfRVbQtTOG7Ts0S4HzJVsTMGI9keU8rNfuZr8DKfSt7Yyg==", + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.2.tgz", + "integrity": "sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==", "license": "MIT", "dependencies": { - "@babel/types": "^7.27.0" + "@babel/types": "^7.29.0" }, "bin": { "parser": "bin/babel-parser.js" @@ -14746,36 +15108,27 @@ } }, "node_modules/react-email/node_modules/@babel/traverse": { - "version": "7.27.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.27.0.tgz", - "integrity": "sha512-19lYZFzYVQkkHkl4Cy4WrAVcqBkgvV2YM2TU3xG6DIwO7O3ecbDPfW3yM3bjAGcqcQHi+CCtjMR3dIEHxsd6bA==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz", + "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==", "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.26.2", - "@babel/generator": "^7.27.0", - "@babel/parser": "^7.27.0", - "@babel/template": "^7.27.0", - "@babel/types": "^7.27.0", - "debug": "^4.3.1", - "globals": "^11.1.0" + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/types": "^7.29.0", + "debug": "^4.3.1" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/react-email/node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/react-email/node_modules/jiti": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz", - "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz", + "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==", "license": "MIT", "bin": { "jiti": "lib/jiti-cli.mjs" @@ -14821,9 +15174,9 @@ } }, "node_modules/react-hook-form": { - "version": "7.77.0", - "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.77.0.tgz", - "integrity": "sha512-Sslh9YDYc0GDlWT/lxasnIduNo4v3yyvqRGvmGKUre5AFjDs/HV9/OafHGD8d+sB2yoL4UIL9L8X9i0WlZZebg==", + "version": "7.83.0", + "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.83.0.tgz", + "integrity": "sha512-AXt8cMCmx5a7u4uvpb2uRFVrWQhllI4pV+LSykxIac/hjt44TnQkmX9BKuQi2i+LDC62esmiLpilkav+kjVf/A==", "license": "MIT", "engines": { "node": ">=18.0.0" @@ -14837,9 +15190,9 @@ } }, "node_modules/react-is": { - "version": "19.2.6", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.6.tgz", - "integrity": "sha512-XjBR15BhXuylgWGuslhDKqlSayuqvqBX91BP8pauG8kd1zY8kotkNWbXksTCNRarse4kuGbe2kIY05ARtwNIvw==", + "version": "19.2.8", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.8.tgz", + "integrity": "sha512-s5un28nYxKJw5gvUHyW5PCC28CvBqLu9r3cWgzHT4Vo/5fqqkFcdRYsGcKf50WMPpjjFZS5d76fn3YCo2njKwQ==", "license": "MIT" }, "node_modules/react-markdown": { @@ -15000,9 +15353,9 @@ } }, "node_modules/recharts": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/recharts/-/recharts-3.8.1.tgz", - "integrity": "sha512-mwzmO1s9sFL0TduUpwndxCUNoXsBw3u3E/0+A+cLcrSfQitSG62L32N69GhqUrrT5qKcAE3pCGVINC6pqkBBQg==", + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/recharts/-/recharts-3.10.1.tgz", + "integrity": "sha512-QXFrvt6IVcw7eeZCoyXTwkIJAX3Dv1nyVhMicXJ47GsGDDpcN8z6o644DibE9XjpBTThtsomLKnTV6lc+cVFUA==", "license": "MIT", "workspaces": [ "www" @@ -15013,9 +15366,9 @@ "decimal.js-light": "^2.5.1", "es-toolkit": "^1.39.3", "eventemitter3": "^5.0.1", - "immer": "^10.1.1", + "immer": "^11.1.8", "react-redux": "8.x.x || 9.x.x", - "reselect": "5.1.1", + "reselect": "5.2.0", "tiny-invariant": "^1.3.3", "use-sync-external-store": "^1.2.2", "victory-vendor": "^37.0.2" @@ -15205,18 +15558,18 @@ } }, "node_modules/reselect": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/reselect/-/reselect-5.1.1.tgz", - "integrity": "sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-5.2.0.tgz", + "integrity": "sha512-AgZ3UOZm3YndfrJ4OYjgrT7bmCm/1iqkjvEfH/oYjzh6PD2qw4QuT3jjnXIrpdt4MTpMXclMT3lXbmRY+XRakw==", "license": "MIT" }, "node_modules/resend": { - "version": "6.12.4", - "resolved": "https://registry.npmjs.org/resend/-/resend-6.12.4.tgz", - "integrity": "sha512-lRpJ2Hxd+ht+JPDm97juRcUp9HOMuZyxaRFRFmc9Tx8iNWiei94Dx9v6SWufgKk2667C/uCeKKspMotOHSpCSg==", + "version": "6.18.1", + "resolved": "https://registry.npmjs.org/resend/-/resend-6.18.1.tgz", + "integrity": "sha512-XN8XIaDdKF+ziSQ3K23ndUcyhP7U3ze2gky6SPgYkuAOq54mH4Wdhwm7QylEQ3zlz0NzdX7/l1AgmJUZbdPI/Q==", "license": "MIT", "dependencies": { - "postal-mime": "2.7.4", + "postal-mime": "2.7.5", "standardwebhooks": "1.0.0" }, "engines": { @@ -15275,23 +15628,6 @@ "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" } }, - "node_modules/restore-cursor": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", - "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", - "dev": true, - "license": "MIT", - "dependencies": { - "onetime": "^7.0.0", - "signal-exit": "^4.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/retry": { "version": "0.13.1", "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", @@ -15328,13 +15664,6 @@ "node": ">=0.10.0" } }, - "node_modules/rfdc": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", - "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", - "dev": true, - "license": "MIT" - }, "node_modules/rimraf": { "version": "6.1.3", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.1.3.tgz", @@ -15356,13 +15685,13 @@ } }, "node_modules/rolldown": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.3.tgz", - "integrity": "sha512-i00lAJ2ks1BYr7rjNjKC7BcqAS7nVfiT3QX1SI5aY+AFHblCmaUf9OE9dbdzDvW6dJxbi2ZCZiy9v3CcwOiX3g==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.2.1.tgz", + "integrity": "sha512-4FKJhg8d3OiyQOA6Q1Q0hoFFpW9/OoX+VsHzpECsdsIZoOArrAK90gl59YK/Z+gnDel45bgJZK03ozH/9bCqEw==", "dev": true, "license": "MIT", "dependencies": { - "@oxc-project/types": "=0.133.0", + "@oxc-project/types": "=0.142.0", "@rolldown/pluginutils": "^1.0.0" }, "bin": { @@ -15372,27 +15701,27 @@ "node": "^20.19.0 || >=22.12.0" }, "optionalDependencies": { - "@rolldown/binding-android-arm64": "1.0.3", - "@rolldown/binding-darwin-arm64": "1.0.3", - "@rolldown/binding-darwin-x64": "1.0.3", - "@rolldown/binding-freebsd-x64": "1.0.3", - "@rolldown/binding-linux-arm-gnueabihf": "1.0.3", - "@rolldown/binding-linux-arm64-gnu": "1.0.3", - "@rolldown/binding-linux-arm64-musl": "1.0.3", - "@rolldown/binding-linux-ppc64-gnu": "1.0.3", - "@rolldown/binding-linux-s390x-gnu": "1.0.3", - "@rolldown/binding-linux-x64-gnu": "1.0.3", - "@rolldown/binding-linux-x64-musl": "1.0.3", - "@rolldown/binding-openharmony-arm64": "1.0.3", - "@rolldown/binding-wasm32-wasi": "1.0.3", - "@rolldown/binding-win32-arm64-msvc": "1.0.3", - "@rolldown/binding-win32-x64-msvc": "1.0.3" + "@rolldown/binding-android-arm64": "1.2.1", + "@rolldown/binding-darwin-arm64": "1.2.1", + "@rolldown/binding-darwin-x64": "1.2.1", + "@rolldown/binding-freebsd-x64": "1.2.1", + "@rolldown/binding-linux-arm-gnueabihf": "1.2.1", + "@rolldown/binding-linux-arm64-gnu": "1.2.1", + "@rolldown/binding-linux-arm64-musl": "1.2.1", + "@rolldown/binding-linux-ppc64-gnu": "1.2.1", + "@rolldown/binding-linux-s390x-gnu": "1.2.1", + "@rolldown/binding-linux-x64-gnu": "1.2.1", + "@rolldown/binding-linux-x64-musl": "1.2.1", + "@rolldown/binding-openharmony-arm64": "1.2.1", + "@rolldown/binding-wasm32-wasi": "1.2.1", + "@rolldown/binding-win32-arm64-msvc": "1.2.1", + "@rolldown/binding-win32-x64-msvc": "1.2.1" } }, "node_modules/rollup": { - "version": "4.61.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.61.0.tgz", - "integrity": "sha512-T9mWdbWfQtp0B5lv/HX+wrhYsmXRlcWnXXmJbXqKJhlRaoS6KMhq0gpyzW4UJfclcxrEdLnTgjT2NjruLONu0g==", + "version": "4.62.3", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.62.3.tgz", + "integrity": "sha512-Gu0c0iH9FzgX1L1t7ByIbbS3Vmdz+6KHm/EsqmmC71gUQ82yvZRkTK6XzrFObSka91WUVdynqp6nsfilzr5k6Q==", "license": "MIT", "dependencies": { "@types/estree": "1.0.9" @@ -15405,31 +15734,31 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.61.0", - "@rollup/rollup-android-arm64": "4.61.0", - "@rollup/rollup-darwin-arm64": "4.61.0", - "@rollup/rollup-darwin-x64": "4.61.0", - "@rollup/rollup-freebsd-arm64": "4.61.0", - "@rollup/rollup-freebsd-x64": "4.61.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.61.0", - "@rollup/rollup-linux-arm-musleabihf": "4.61.0", - "@rollup/rollup-linux-arm64-gnu": "4.61.0", - "@rollup/rollup-linux-arm64-musl": "4.61.0", - "@rollup/rollup-linux-loong64-gnu": "4.61.0", - "@rollup/rollup-linux-loong64-musl": "4.61.0", - "@rollup/rollup-linux-ppc64-gnu": "4.61.0", - "@rollup/rollup-linux-ppc64-musl": "4.61.0", - "@rollup/rollup-linux-riscv64-gnu": "4.61.0", - "@rollup/rollup-linux-riscv64-musl": "4.61.0", - "@rollup/rollup-linux-s390x-gnu": "4.61.0", - "@rollup/rollup-linux-x64-gnu": "4.61.0", - "@rollup/rollup-linux-x64-musl": "4.61.0", - "@rollup/rollup-openbsd-x64": "4.61.0", - "@rollup/rollup-openharmony-arm64": "4.61.0", - "@rollup/rollup-win32-arm64-msvc": "4.61.0", - "@rollup/rollup-win32-ia32-msvc": "4.61.0", - "@rollup/rollup-win32-x64-gnu": "4.61.0", - "@rollup/rollup-win32-x64-msvc": "4.61.0", + "@rollup/rollup-android-arm-eabi": "4.62.3", + "@rollup/rollup-android-arm64": "4.62.3", + "@rollup/rollup-darwin-arm64": "4.62.3", + "@rollup/rollup-darwin-x64": "4.62.3", + "@rollup/rollup-freebsd-arm64": "4.62.3", + "@rollup/rollup-freebsd-x64": "4.62.3", + "@rollup/rollup-linux-arm-gnueabihf": "4.62.3", + "@rollup/rollup-linux-arm-musleabihf": "4.62.3", + "@rollup/rollup-linux-arm64-gnu": "4.62.3", + "@rollup/rollup-linux-arm64-musl": "4.62.3", + "@rollup/rollup-linux-loong64-gnu": "4.62.3", + "@rollup/rollup-linux-loong64-musl": "4.62.3", + "@rollup/rollup-linux-ppc64-gnu": "4.62.3", + "@rollup/rollup-linux-ppc64-musl": "4.62.3", + "@rollup/rollup-linux-riscv64-gnu": "4.62.3", + "@rollup/rollup-linux-riscv64-musl": "4.62.3", + "@rollup/rollup-linux-s390x-gnu": "4.62.3", + "@rollup/rollup-linux-x64-gnu": "4.62.3", + "@rollup/rollup-linux-x64-musl": "4.62.3", + "@rollup/rollup-openbsd-x64": "4.62.3", + "@rollup/rollup-openharmony-arm64": "4.62.3", + "@rollup/rollup-win32-arm64-msvc": "4.62.3", + "@rollup/rollup-win32-ia32-msvc": "4.62.3", + "@rollup/rollup-win32-x64-gnu": "4.62.3", + "@rollup/rollup-win32-x64-msvc": "4.62.3", "fsevents": "~2.3.2" } }, @@ -15543,55 +15872,179 @@ } }, "node_modules/sanitize-html": { - "version": "2.17.4", - "resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-2.17.4.tgz", - "integrity": "sha512-2HW7v2ol/uAM7sX4hbD8Z59OGWmAPrvjL8E71UWlBcj6m+kcF6ilQBLny+cIgY214QJeJT5tQuxKKqX0SQqjGQ==", + "version": "2.17.6", + "resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-2.17.6.tgz", + "integrity": "sha512-M4bo9tfv1yfhQZZKkc6dL07ALrGJtfvNOuhX3hU9AVPR/uPQ+nKOJBqTYc7LfMQblTW04mtSWDJWEyLvygJsLA==", "license": "MIT", "dependencies": { "deepmerge": "^4.2.2", "escape-string-regexp": "^4.0.0", - "htmlparser2": "^10.1.0", + "htmlparser2": "^12.0.0", "is-plain-object": "^5.0.0", "launder": "^1.7.1", "parse-srcset": "^1.0.2", "postcss": "^8.3.11" - } - }, - "node_modules/saxes": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", - "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", - "dev": true, - "license": "ISC", - "dependencies": { - "xmlchars": "^2.2.0" }, "engines": { - "node": ">=v12.22.7" + "node": ">=22.12.0" } }, - "node_modules/scheduler": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", - "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", - "license": "MIT" - }, - "node_modules/scslre": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/scslre/-/scslre-0.3.0.tgz", - "integrity": "sha512-3A6sD0WYP7+QrjbfNA2FN3FsOaGGFoekCVgTyypy53gPxhbkCIjtO6YWgdrfM+n/8sI8JeXZOIxsHjMTNxQ4nQ==", - "dev": true, + "node_modules/sanitize-html/node_modules/dom-serializer": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-3.1.1.tgz", + "integrity": "sha512-4MEa38/QexBob6gFNwu+EGdWvhJ1OKuNwdYY3Y3NyeWDQfnGeDYQUDfIRzWu5B5gsv03so2Uxd28YC6zrsx3Lw==", "license": "MIT", "dependencies": { - "@eslint-community/regexpp": "^4.8.0", - "refa": "^0.12.0", - "regexp-ast-analysis": "^0.7.0" + "domelementtype": "^3.0.0", + "domhandler": "^6.0.0", + "entities": "^8.0.0" }, "engines": { - "node": "^14.0.0 || >=16.0.0" + "node": ">=20.19.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" } }, - "node_modules/selderee": { + "node_modules/sanitize-html/node_modules/domelementtype": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-3.0.0.tgz", + "integrity": "sha512-umCQid3jKbDmVjx8jGaW7uUykm4DEUeyV21hPxNMo2nV955DhUThwqyOIDtreepP31hl84X7G5U9ZfsWvIB3Pg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause", + "engines": { + "node": ">=20.19.0" + } + }, + "node_modules/sanitize-html/node_modules/domhandler": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-6.0.1.tgz", + "integrity": "sha512-gYzvtM72ZtxQO0T048kd6HWSbbGCNOUwcnfQ01cqIJ4X2IYKFFHZ5mKvrQETcFXxsRObZulDaKmy//R7TPtsBg==", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^3.0.0" + }, + "engines": { + "node": ">=20.19.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/sanitize-html/node_modules/domutils": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-4.0.2.tgz", + "integrity": "sha512-qI4JLRKnSzqFqr7hAlS5xQDusBCjKSEG4t4+7aNrIQMHBcsC2TGEhuyABJdYkgSewL57PNLYEiibY2iPKhKpaA==", + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^3.0.0", + "domelementtype": "^3.0.0", + "domhandler": "^6.0.0" + }, + "engines": { + "node": ">=20.19.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/sanitize-html/node_modules/entities": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-8.0.0.tgz", + "integrity": "sha512-zwfzJecQ/Uej6tusMqwAqU/6KL2XaB2VZ2Jg54Je6ahNBGNH6Ek6g3jjNCF0fG9EWQKGZNddNjU5F1ZQn/sBnA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=20.19.0" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/sanitize-html/node_modules/htmlparser2": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-12.0.0.tgz", + "integrity": "sha512-Tz7u1i95/g2x2jz81+x0FBVhBhY5aRTvD3tXXdFaljuNdzDLJ8UGNRrTcj2cgQvAg3iW/h77Fz15nLW0L0CrZw==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^3.0.0", + "domhandler": "^6.0.0", + "domutils": "^4.0.2", + "entities": "^8.0.0" + }, + "engines": { + "node": ">=20.19.0" + } + }, + "node_modules/saxes": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "dev": true, + "license": "ISC", + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=v12.22.7" + } + }, + "node_modules/scheduler": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", + "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", + "license": "MIT" + }, + "node_modules/schema-utils": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.3.tgz", + "integrity": "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==", + "license": "MIT", + "peer": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/scslre": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/scslre/-/scslre-0.3.0.tgz", + "integrity": "sha512-3A6sD0WYP7+QrjbfNA2FN3FsOaGGFoekCVgTyypy53gPxhbkCIjtO6YWgdrfM+n/8sI8JeXZOIxsHjMTNxQ4nQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.8.0", + "refa": "^0.12.0", + "regexp-ast-analysis": "^0.7.0" + }, + "engines": { + "node": "^14.0.0 || >=16.0.0" + } + }, + "node_modules/selderee": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/selderee/-/selderee-0.11.0.tgz", "integrity": "sha512-5TF+l7p4+OsnP8BCCvSyZiSPc4x4//p5uPwK8TCnVPJYRmU2aYKMpOXvw8zM5a5JvuuCGN1jmsMwuU2W02ukfA==", @@ -15603,6 +16056,12 @@ "url": "https://ko-fi.com/killymxi" } }, + "node_modules/semifies": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semifies/-/semifies-1.0.0.tgz", + "integrity": "sha512-xXR3KGeoxTNWPD4aBvL5NUpMTT7WMANr3EWnaS190QVkY52lqqcVRD7Q05UVbBhiWDGWMlJEUam9m7uFFGVScw==", + "license": "Apache-2.0" + }, "node_modules/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", @@ -15619,12 +16078,12 @@ "license": "MIT" }, "node_modules/serwist": { - "version": "9.5.11", - "resolved": "https://registry.npmjs.org/serwist/-/serwist-9.5.11.tgz", - "integrity": "sha512-Bq6uwJFd4ET60BWI77v3VbazKHv6k7lECOiiCFwKyBu/slaCn0GHJ5L5RfsuJUKrnbD9lYUCDo6sqaKRM5M2vA==", + "version": "9.5.12", + "resolved": "https://registry.npmjs.org/serwist/-/serwist-9.5.12.tgz", + "integrity": "sha512-PwREKJrSb3ja40XJyBntPOm7okcYZJCJPd++jUVz8tzxY1VYO9dyKSm0MimZ8LtUk0pIUTN0q2cfGe7R0wQsaQ==", "license": "MIT", "dependencies": { - "@serwist/utils": "9.5.11", + "@serwist/utils": "9.5.12", "idb": "8.0.3" }, "peerDependencies": { @@ -15686,54 +16145,59 @@ } }, "node_modules/sharp": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.5.tgz", - "integrity": "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==", - "hasInstallScript": true, + "version": "0.35.3", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.35.3.tgz", + "integrity": "sha512-ej0zVHuZGHCiABXcNxeYhpRnPNPAcvbG8RMdBAhDAxLKkCRVSpK3Iyu7qbqw3JMzoj0REeM6f3tJLtVwl0023Q==", "license": "Apache-2.0", "optional": true, "dependencies": { - "@img/colour": "^1.0.0", + "@img/colour": "^1.1.0", "detect-libc": "^2.1.2", - "semver": "^7.7.3" + "semver": "^7.8.5" }, "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + "node": ">=20.9.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" + "@img/sharp-darwin-arm64": "0.35.3", + "@img/sharp-darwin-x64": "0.35.3", + "@img/sharp-freebsd-wasm32": "0.35.3", + "@img/sharp-libvips-darwin-arm64": "1.3.2", + "@img/sharp-libvips-darwin-x64": "1.3.2", + "@img/sharp-libvips-linux-arm": "1.3.2", + "@img/sharp-libvips-linux-arm64": "1.3.2", + "@img/sharp-libvips-linux-ppc64": "1.3.2", + "@img/sharp-libvips-linux-riscv64": "1.3.2", + "@img/sharp-libvips-linux-s390x": "1.3.2", + "@img/sharp-libvips-linux-x64": "1.3.2", + "@img/sharp-libvips-linuxmusl-arm64": "1.3.2", + "@img/sharp-libvips-linuxmusl-x64": "1.3.2", + "@img/sharp-linux-arm": "0.35.3", + "@img/sharp-linux-arm64": "0.35.3", + "@img/sharp-linux-ppc64": "0.35.3", + "@img/sharp-linux-riscv64": "0.35.3", + "@img/sharp-linux-s390x": "0.35.3", + "@img/sharp-linux-x64": "0.35.3", + "@img/sharp-linuxmusl-arm64": "0.35.3", + "@img/sharp-linuxmusl-x64": "0.35.3", + "@img/sharp-webcontainers-wasm32": "0.35.3", + "@img/sharp-win32-arm64": "0.35.3", + "@img/sharp-win32-ia32": "0.35.3", + "@img/sharp-win32-x64": "0.35.3" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, "node_modules/sharp/node_modules/semver": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.1.tgz", - "integrity": "sha512-rkVq3IXh+4FDGch+KwzX3aV9W3kO54GyEgpvBzSyctDA6Xtd7RJQV1xmXbeQp5v7+VzLOfVqiutSE6GICgPFvg==", + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", "license": "ISC", "optional": true, "bin": { @@ -15767,14 +16231,14 @@ } }, "node_modules/side-channel": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", - "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.1.tgz", + "integrity": "sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0", - "object-inspect": "^1.13.3", - "side-channel-list": "^1.0.0", + "object-inspect": "^1.13.4", + "side-channel-list": "^1.0.1", "side-channel-map": "^1.0.1", "side-channel-weakmap": "^1.0.2" }, @@ -15845,19 +16309,6 @@ "dev": true, "license": "ISC" }, - "node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/sirv": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/sirv/-/sirv-3.0.2.tgz", @@ -15879,36 +16330,6 @@ "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", "license": "MIT" }, - "node_modules/slice-ansi": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-8.0.0.tgz", - "integrity": "sha512-stxByr12oeeOyY2BlviTNQlYV5xOj47GirPr4yA1hE9JCtxfQN0+tVbkxwCtYDQWhEKWFHsEK48ORg5jrouCAg==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.2.3", - "is-fullwidth-code-point": "^5.1.0" - }, - "engines": { - "node": ">=20" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" - } - }, - "node_modules/slice-ansi/node_modules/ansi-styles": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", - "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, "node_modules/socket.io": { "version": "4.8.3", "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.8.3.tgz", @@ -15928,40 +16349,19 @@ } }, "node_modules/socket.io-adapter": { - "version": "2.5.7", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.7.tgz", - "integrity": "sha512-e0LyK91f3cUxTmv95/KzoLg47+zF+s/sbxRGDNsyG4dmIP8ZSX8ax6byOxfJXeNNtS/8AZlfD+uP7gBeR7DLlg==", + "version": "2.5.8", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.8.tgz", + "integrity": "sha512-6Oy52pbg+kvdCVvjcN+FnY7BvxZ7cIHNScbvztT/It5d0vbwoJoVZmF2gjJmnV0/4WlXRfG15zc45ySk9Ah8bw==", "license": "MIT", "dependencies": { "debug": "~4.4.1", - "ws": "~8.20.1" - } - }, - "node_modules/socket.io-adapter/node_modules/ws": { - "version": "8.20.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.20.1.tgz", - "integrity": "sha512-It4dO0K5v//JtTXuPkfEOaI3uUN87iYPnqo/ZzqCoG3g8uhA66QUMs/SrM0YK7/NAu+r4LMh/9dq2A7k+rHs+w==", - "license": "MIT", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } + "ws": "~8.21.0" } }, "node_modules/socket.io-parser": { - "version": "4.2.6", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.6.tgz", - "integrity": "sha512-asJqbVBDsBCJx0pTqw3WfesSY0iRX+2xzWEWzrpcH7L6fLzrhyF8WPI8UaeM4YCuDfpwA/cgsdugMsmtz8EJeg==", + "version": "4.2.7", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.7.tgz", + "integrity": "sha512-IH/iSeO9T6gz1KkFleGDWkG9N3dl4jXVYUtMhIqH10Md0ttMer8nUNWiP1DKuNrybD2xBrixLJdCC9J6ECoYkg==", "license": "MIT", "dependencies": { "@socket.io/component-emitter": "~3.1.0", @@ -15982,9 +16382,9 @@ } }, "node_modules/source-map": { - "version": "0.7.6", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", - "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==", + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.8.0.tgz", + "integrity": "sha512-d8EqvL+k/SOXCreS/SUzg2ciyHqBBLcN/yuRjFsbvVhHTE2pgei7oAhmPM7kWFbkX6OSMQfUq4KbkF3au9lhYQ==", "license": "BSD-3-Clause", "engines": { "node": ">= 12" @@ -15999,6 +16399,17 @@ "node": ">=0.10.0" } }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "license": "MIT", + "peer": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, "node_modules/space-separated-tokens": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", @@ -16055,9 +16466,9 @@ } }, "node_modules/std-env": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-4.1.0.tgz", - "integrity": "sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-4.2.0.tgz", + "integrity": "sha512-oCUKSupKTHX53EyjDtuZQ64pjLJ6yYCtpmEw0goYxtjG9KpbRe8KAsl2tBUGU9DyMcJ0RwJ8GqJAFzMXcXW1Rw==", "dev": true, "license": "MIT" }, @@ -16113,22 +16524,27 @@ } }, "node_modules/string-width": { - "version": "8.2.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.2.1.tgz", - "integrity": "sha512-IIaP0g3iy9Cyy18w3M9YcaDudujEAVHKt3a3QJg1+sr/oX96TbaGUubG0hJyCjCBThFH+tFpcIyoUHUn1ogaLA==", - "dev": true, + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "license": "MIT", + "optional": true, "dependencies": { - "get-east-asian-width": "^1.5.0", - "strip-ansi": "^7.1.2" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" }, "engines": { - "node": ">=20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, + "node_modules/string-width/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT", + "optional": true + }, "node_modules/string.prototype.includes": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/string.prototype.includes/-/string.prototype.includes-2.0.1.tgz", @@ -16184,19 +16600,20 @@ } }, "node_modules/string.prototype.trim": { - "version": "1.2.10", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", - "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.11.tgz", + "integrity": "sha512-PwvK7BU+CMTJGYQCTZb5RWXIML92lftJLhQz1tBzgKiqGxJaMlBAa48POXaNAC2s4y8jr3EFqrkF9+44neS46w==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.2", + "call-bind": "^1.0.9", + "call-bound": "^1.0.4", "define-data-property": "^1.1.4", "define-properties": "^1.2.1", - "es-abstract": "^1.23.5", - "es-object-atoms": "^1.0.0", - "has-property-descriptors": "^1.0.2" + "es-abstract": "^1.24.2", + "es-object-atoms": "^1.1.2", + "has-property-descriptors": "^1.0.2", + "safe-regex-test": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -16206,16 +16623,16 @@ } }, "node_modules/string.prototype.trimend": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", - "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.10.tgz", + "integrity": "sha512-2+3aDAOmPTmuFwjDnmJG2ctEkQKVki7vOSqaxkv42Mowj1V6PnvuwFCRrR5lChUux1TBskPjfkeTOhqczDMxTw==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.2", + "call-bind": "^1.0.9", + "call-bound": "^1.0.4", "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" + "es-object-atoms": "^1.1.2" }, "engines": { "node": ">= 0.4" @@ -16257,32 +16674,16 @@ } }, "node_modules/strip-ansi": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", - "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", - "dev": true, + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "license": "MIT", + "optional": true, "dependencies": { - "ansi-regex": "^6.2.2" - }, - "engines": { - "node": ">=12" + "ansi-regex": "^5.0.1" }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/strip-ansi/node_modules/ansi-regex": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", - "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", - "dev": true, - "license": "MIT", "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" + "node": ">=8" } }, "node_modules/strip-bom": { @@ -16321,9 +16722,9 @@ } }, "node_modules/strnum": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.3.0.tgz", - "integrity": "sha512-ums3KNd42PGyx5xaoVTO1mjU1bH3NpY4vsrVlnv9PNGqQj8wd7rJ6nEypLrJ7z5vxK5RP0yMLo6J/Gsm62DI5Q==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.4.1.tgz", + "integrity": "sha512-M9eUSMT2dCB2cTNPG7UYj6KuK7RJR2SN2+yCV/fTW3xzTCS6EaGZ5pSMgDIjB7r8zSfTGk+dvvn9rTjpVS9Mwg==", "funding": [ { "type": "github", @@ -16331,7 +16732,10 @@ } ], "license": "MIT", - "optional": true + "optional": true, + "dependencies": { + "anynum": "^1.0.1" + } }, "node_modules/stubborn-fs": { "version": "2.0.0", @@ -16397,23 +16801,27 @@ } }, "node_modules/supabase": { - "version": "2.103.0", - "resolved": "https://registry.npmjs.org/supabase/-/supabase-2.103.0.tgz", - "integrity": "sha512-LAdBSEzbmJIAf3UojILFL1DF2npwUpqGZ5FNtuqu9pzUdPMHvICyFeQeQCpUpLNrqmee78LqYwiFBpHtBP/TQQ==", + "version": "2.111.0", + "resolved": "https://registry.npmjs.org/supabase/-/supabase-2.111.0.tgz", + "integrity": "sha512-0cjCRdYNV1h2XXa0wm04mdct7QuDU7sMul/NwETRJmN3+HCsdEu6u5n0oygL97fdf6sDrGmnAdBh8E4wsv1ayg==", "dev": true, "license": "MIT", + "dependencies": { + "eciesjs": "^0.5.0", + "jose": "^6.2.3" + }, "bin": { "supabase": "dist/supabase.js" }, "optionalDependencies": { - "@supabase/cli-darwin-arm64": "2.103.0", - "@supabase/cli-darwin-x64": "2.103.0", - "@supabase/cli-linux-arm64": "2.103.0", - "@supabase/cli-linux-arm64-musl": "2.103.0", - "@supabase/cli-linux-x64": "2.103.0", - "@supabase/cli-linux-x64-musl": "2.103.0", - "@supabase/cli-windows-arm64": "2.103.0", - "@supabase/cli-windows-x64": "2.103.0" + "@supabase/cli-darwin-arm64": "2.111.0", + "@supabase/cli-darwin-x64": "2.111.0", + "@supabase/cli-linux-arm64": "2.111.0", + "@supabase/cli-linux-arm64-musl": "2.111.0", + "@supabase/cli-linux-x64": "2.111.0", + "@supabase/cli-linux-x64-musl": "2.111.0", + "@supabase/cli-windows-arm64": "2.111.0", + "@supabase/cli-windows-x64": "2.111.0" } }, "node_modules/supports-color": { @@ -16472,16 +16880,15 @@ } }, "node_modules/tailwindcss": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.3.0.tgz", - "integrity": "sha512-y6nxMGB1nMW9R6k96e5gdIFzcfL/gTJRNaqGes1YvkLnPVXzWgbqFF2yLC0T8G774n24cx3Pe8XrKoniCOAH+Q==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.3.3.tgz", + "integrity": "sha512-gOhV3P7ufE62QDGg1zVaTgCR+EtPv92k2nIhVcVKcLmxT1sUBsQGhnZj175j+MqRt4zLF7ic+sCYjfhxMxj7YQ==", "license": "MIT" }, "node_modules/tapable": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.3.tgz", "integrity": "sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==", - "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -16508,6 +16915,32 @@ "node": ">=14" } }, + "node_modules/terser": { + "version": "5.49.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.49.0.tgz", + "integrity": "sha512-SNiDnXyHSrxVcIOtVbULzcTmniUiwcV7Nwdyj1twVubeTmbjoa8p69KKDpfkdoOavuM4/GRm1+ykI8qqnavHoA==", + "license": "BSD-2-Clause", + "peer": true, + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.15.0", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "license": "MIT", + "peer": true + }, "node_modules/tiny-invariant": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", @@ -16548,9 +16981,9 @@ } }, "node_modules/tinyrainbow": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.1.0.tgz", - "integrity": "sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.1.1.tgz", + "integrity": "sha512-yau8yJdTt989Mm0Bd/236QnzEiPf2xLLTqUZRUJOo/3CB078LSwzei343DgtJVmfJKJE3TMINY1u42SQsP6mXw==", "dev": true, "license": "MIT", "engines": { @@ -16558,22 +16991,22 @@ } }, "node_modules/tldts": { - "version": "7.4.2", - "resolved": "https://registry.npmjs.org/tldts/-/tldts-7.4.2.tgz", - "integrity": "sha512-kCwffuaH8ntKtygnWe1b4BJKWiCUH30n5KfoTr6IchcXOwR7chAOFJxFrH3vjANafUYrIA4a7SDL+nn7SiR4Sw==", + "version": "7.4.10", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-7.4.10.tgz", + "integrity": "sha512-GgouD1B+sWwvkaEq8vXC15DjQitxbvs12oIXELpconwm+Tg3zfcEv4jgzq3vtKverDXsg3VI8aRgNL2Nra0Iog==", "dev": true, "license": "MIT", "dependencies": { - "tldts-core": "^7.4.2" + "tldts-core": "^7.4.10" }, "bin": { "tldts": "bin/cli.js" } }, "node_modules/tldts-core": { - "version": "7.4.2", - "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-7.4.2.tgz", - "integrity": "sha512-nwEyF4vl4RSJjwSjBUmOSxc3BFPoIFdlRthJ6e+5v9P3bHNsoD06UjuqMUspqp7vsEZ1beaHi1km+optiE17yA==", + "version": "7.4.10", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-7.4.10.tgz", + "integrity": "sha512-KnQjp53ZekKgm/r3l+u8kJGGzYgrWdP8+Mql7a4vijh2WE0IrZWspQj/TpTxDho/YxO+AnOZnIjQcCD+q6iJsw==", "dev": true, "license": "MIT" }, @@ -16601,9 +17034,9 @@ } }, "node_modules/tough-cookie": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-6.0.1.tgz", - "integrity": "sha512-LktZQb3IeoUWB9lqR5EWTHgW/VTITCXg4D21M+lvybRVdylLrRMnqaIONLVb5mav8vM19m44HIcGq4qASeu2Qw==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-6.0.2.tgz", + "integrity": "sha512-exgYmnmL/sJpR3upZfXG5PoatXQii55xAiXGXzY+sROLZ/Y+SLcp9PgJNI9Vz37HpQ74WvDcLT8eqm+kV3FzrA==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -16714,9 +17147,9 @@ } }, "node_modules/type-fest": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-5.7.0.tgz", - "integrity": "sha512-1URUxUqfHFM1c+zfSPsa3gnkO7Aq21qyH75SIduNYz4SzY964rn1X2vCMQaHSHhktiw+0kPa2iyb6PUpXqB6Vg==", + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-5.8.0.tgz", + "integrity": "sha512-YGYEVz3Fm5iy/AybuA0oyNFq7H4CgQNfRp/qfe8nurE1kuCeNm3/vfm9X4Mtl+qLyaKJUh5xrFZwogr41SMjYA==", "license": "(MIT OR CC0-1.0)", "dependencies": { "tagged-tag": "^1.0.0" @@ -16810,7 +17243,7 @@ "version": "6.0.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz", "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==", - "dev": true, + "devOptional": true, "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", @@ -16821,16 +17254,16 @@ } }, "node_modules/typescript-eslint": { - "version": "8.60.0", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.60.0.tgz", - "integrity": "sha512-9f65qWLZdAW9m1JaxBDUHcqRUfL8bkxxXL7XxEfI+F09q56PkBvIfCjLF3yInsDM/BBmwkqmCQdCZe/RYlIWEw==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.65.0.tgz", + "integrity": "sha512-/ggrHAwyjENDusvyxbuqxAC2dTnZg/Z8F+fgQtYIz+L6n/9HfSlEZcFGV/NsMNa6CkGk0xUjUAFwC0vHOflvIA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/eslint-plugin": "8.60.0", - "@typescript-eslint/parser": "8.60.0", - "@typescript-eslint/typescript-estree": "8.60.0", - "@typescript-eslint/utils": "8.60.0" + "@typescript-eslint/eslint-plugin": "8.65.0", + "@typescript-eslint/parser": "8.65.0", + "@typescript-eslint/typescript-estree": "8.65.0", + "@typescript-eslint/utils": "8.65.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -16882,19 +17315,19 @@ "license": "MIT" }, "node_modules/undici": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-7.26.0.tgz", - "integrity": "sha512-3O9Tf67pGhgOv9jM35AbhkXAKi13f3oy3aE4CSgr+TckGeY+/iu97ZXN+J7DpHPzLbVApFd1IFhcnBjREYXYcg==", + "version": "8.9.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-8.9.0.tgz", + "integrity": "sha512-aWZpUj7XoGonMClx4gdDRfgBjqeA+F473aDmROQQbM9n6PRfK/u1q/a0X4wMTgcHfT8H6fpbt98PFuDUwFg2YA==", "dev": true, "license": "MIT", "engines": { - "node": ">=20.18.1" + "node": ">=22.19.0" } }, "node_modules/undici-types": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.24.6.tgz", - "integrity": "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==", + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-8.3.0.tgz", + "integrity": "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==", "license": "MIT" }, "node_modules/unified": { @@ -17128,9 +17561,9 @@ "optional": true }, "node_modules/uuid": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-14.0.0.tgz", - "integrity": "sha512-Qo+uWgilfSmAhXCMav1uYFynlQO7fMFiMVZsQqZRMIXp0O7rR7qjkj+cPvBHLgBqi960QCoo/PH2/6ZtVqKvrg==", + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-14.0.1.tgz", + "integrity": "sha512-6ZxzVpzDXDa3bJWaHilVayA+BH/1zmxCJoVgvmqJnid/gPoKHxUrS/aC/T6LGQtNHT+XHG9fXPJB4d+IrU30Ew==", "funding": [ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" @@ -17200,16 +17633,16 @@ } }, "node_modules/vite": { - "version": "8.0.16", - "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.16.tgz", - "integrity": "sha512-h9bXPmJichP5fLmVQo3PyaGSDE2n3aPuomeAlVRm0JLmt4rY6zmPKd59HYI4LNW8oTK7tlTsuC7l/m7awx9Jcw==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.2.0.tgz", + "integrity": "sha512-pn+CFpM0lwDeKwmOq1ZaBK/9sjorZcgqxki6MbY/jPEVd9vichIlmlD4HmQ5wdP5EgqQCFRaACBxMC7uEGc6lQ==", "dev": true, "license": "MIT", "dependencies": { - "lightningcss": "^1.32.0", - "picomatch": "^4.0.4", - "postcss": "^8.5.15", - "rolldown": "1.0.3", + "lightningcss": "^1.33.0", + "picomatch": "^4.0.5", + "postcss": "^8.5.23", + "rolldown": "~1.2.0", "tinyglobby": "^0.2.17" }, "bin": { @@ -17226,7 +17659,7 @@ }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", - "@vitejs/devtools": "^0.1.18", + "@vitejs/devtools": "^0.4.0", "esbuild": "^0.27.0 || ^0.28.0", "jiti": ">=1.21.0", "less": "^4.0.0", @@ -17292,20 +17725,293 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, + "node_modules/vite/node_modules/lightningcss": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.33.0.tgz", + "integrity": "sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==", + "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.33.0", + "lightningcss-darwin-arm64": "1.33.0", + "lightningcss-darwin-x64": "1.33.0", + "lightningcss-freebsd-x64": "1.33.0", + "lightningcss-linux-arm-gnueabihf": "1.33.0", + "lightningcss-linux-arm64-gnu": "1.33.0", + "lightningcss-linux-arm64-musl": "1.33.0", + "lightningcss-linux-x64-gnu": "1.33.0", + "lightningcss-linux-x64-musl": "1.33.0", + "lightningcss-win32-arm64-msvc": "1.33.0", + "lightningcss-win32-x64-msvc": "1.33.0" + } + }, + "node_modules/vite/node_modules/lightningcss-android-arm64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.33.0.tgz", + "integrity": "sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==", + "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/vite/node_modules/lightningcss-darwin-arm64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.33.0.tgz", + "integrity": "sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==", + "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/vite/node_modules/lightningcss-darwin-x64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.33.0.tgz", + "integrity": "sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==", + "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/vite/node_modules/lightningcss-freebsd-x64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.33.0.tgz", + "integrity": "sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==", + "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/vite/node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.33.0.tgz", + "integrity": "sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==", + "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/vite/node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.33.0.tgz", + "integrity": "sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/vite/node_modules/lightningcss-linux-arm64-musl": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.33.0.tgz", + "integrity": "sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/vite/node_modules/lightningcss-linux-x64-gnu": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.33.0.tgz", + "integrity": "sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/vite/node_modules/lightningcss-linux-x64-musl": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.33.0.tgz", + "integrity": "sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/vite/node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.33.0.tgz", + "integrity": "sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==", + "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/vite/node_modules/lightningcss-win32-x64-msvc": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.33.0.tgz", + "integrity": "sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==", + "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/vitest": { - "version": "4.1.8", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.8.tgz", - "integrity": "sha512-flY6ScbCIt9HThs+C5HS7jvGOB560DJtk/Z15IQROTA6zEy49Nh8T/dofWTQL+n3vswqn87sbJNiuqw1SDp5Ig==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.10.tgz", + "integrity": "sha512-R9jUTe5S4Qb0HCd4TNqpC7oGcrMssMRGXLW80ubjWsW9VH5GF8y1Y0SFLY9AbqSk6nt0PnOx4H4WNJYZ13GUPw==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/expect": "4.1.8", - "@vitest/mocker": "4.1.8", - "@vitest/pretty-format": "4.1.8", - "@vitest/runner": "4.1.8", - "@vitest/snapshot": "4.1.8", - "@vitest/spy": "4.1.8", - "@vitest/utils": "4.1.8", + "@vitest/expect": "4.1.10", + "@vitest/mocker": "4.1.10", + "@vitest/pretty-format": "4.1.10", + "@vitest/runner": "4.1.10", + "@vitest/snapshot": "4.1.10", + "@vitest/spy": "4.1.10", + "@vitest/utils": "4.1.10", "es-module-lexer": "^2.0.0", "expect-type": "^1.3.0", "magic-string": "^0.30.21", @@ -17333,12 +18039,12 @@ "@edge-runtime/vm": "*", "@opentelemetry/api": "^1.9.0", "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", - "@vitest/browser-playwright": "4.1.8", - "@vitest/browser-preview": "4.1.8", - "@vitest/browser-webdriverio": "4.1.8", - "@vitest/coverage-istanbul": "4.1.8", - "@vitest/coverage-v8": "4.1.8", - "@vitest/ui": "4.1.8", + "@vitest/browser-playwright": "4.1.10", + "@vitest/browser-preview": "4.1.10", + "@vitest/browser-webdriverio": "4.1.10", + "@vitest/coverage-istanbul": "4.1.10", + "@vitest/coverage-v8": "4.1.10", + "@vitest/ui": "4.1.10", "happy-dom": "*", "jsdom": "*", "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" @@ -17395,6 +18101,19 @@ "node": ">=18" } }, + "node_modules/watchpack": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.5.2.tgz", + "integrity": "sha512-6i/00NBjP4yGPs+caKSyRfpTF/8Torsu0MOW3mMzIbhgISFder8i7xbqgHlLMwJrdiN8ndBV3UA1/AfzPSr+jg==", + "license": "MIT", + "peer": true, + "dependencies": { + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/web-streams-polyfill": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", @@ -17414,10 +18133,98 @@ "node": ">=20" } }, + "node_modules/webpack": { + "version": "5.109.2", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.109.2.tgz", + "integrity": "sha512-U9/cvLzxObKNEZ9+TtdqrHM5/9z3lgl2c+c4BzbqGxFQvQvBAq87yql5A8pQ+rrMbS496MZJeF5enVBndIy2hw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@types/estree": "^1.0.8", + "@types/json-schema": "^7.0.15", + "@webassemblyjs/ast": "^1.14.1", + "@webassemblyjs/wasm-edit": "^1.14.1", + "@webassemblyjs/wasm-parser": "^1.14.1", + "acorn": "^8.16.0", + "browserslist": "^4.28.1", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.24.4", + "es-module-lexer": "^2.1.0", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "graceful-fs": "^4.2.11", + "mime-db": "^1.54.0", + "minimizer-webpack-plugin": "^5.6.1", + "neo-async": "^2.6.2", + "schema-utils": "^4.3.3", + "tapable": "^2.3.0", + "watchpack": "^2.5.2", + "webpack-sources": "^3.5.1" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-sources": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.5.1.tgz", + "integrity": "sha512-jyuiGJdtvY434z5bUZrjz67v76/ePNvFZTp9Mdz29IlH4+GPsgyGjiv0fKI+M7BdkU6ADjulUcKAd3tUK3WlEw==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack/node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "license": "BSD-2-Clause", + "peer": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/webpack/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "license": "BSD-2-Clause", + "peer": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/webpack/node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/websocket-driver": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", - "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.5.tgz", + "integrity": "sha512-ZL2+3c7kMBdIRCMz6l8jQMHyGVxj+UL+xVk74Ombiciboca8rHa15L86B19E5oh1pL9Ii/uj54gtsIrZGMo6zA==", "license": "Apache-2.0", "dependencies": { "http-parser-js": ">=0.5.1", @@ -17448,18 +18255,18 @@ } }, "node_modules/whatwg-url": { - "version": "16.0.1", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-16.0.1.tgz", - "integrity": "sha512-1to4zXBxmXHV3IiSSEInrreIlu02vUOvrhxJJH5vcxYTBDAx51cqZiKdyTxlecdKNSjj8EcxGBxNf6Vg+945gw==", + "version": "17.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-17.1.0.tgz", + "integrity": "sha512-3GeworPmc2ZfEEHP7lEbUfBX/L75wdEsi0rLNhXcXxnoN5jyq0SL5gCy06SGW2cyTIZdTvWIDQNQoza++vKeaw==", "dev": true, "license": "MIT", "dependencies": { - "@exodus/bytes": "^1.11.0", + "@exodus/bytes": "^1.15.1", "tr46": "^6.0.0", "webidl-conversions": "^8.0.1" }, "engines": { - "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + "node": "^22.14.0 || >=24.0.0" } }, "node_modules/when-exit": { @@ -17551,9 +18358,9 @@ } }, "node_modules/which-typed-array": { - "version": "1.1.21", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.21.tgz", - "integrity": "sha512-zbRA8cVm6io/d5W8uIe2hblzN76/Wm3v/yiythQvr+dpBWeqhPSWIDNj4zOyHi4zKbMK6DN34Xsr9jPHJERAEw==", + "version": "1.1.22", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.22.tgz", + "integrity": "sha512-fvO4ExWMFsqyhG3AiPAObMuY1lxaqgYcxbc49CNdWDDECOJNgQyvsOWVwbZc+qf3rzRtxojBK+CMEv0Ld5CYpw==", "dev": true, "license": "MIT", "dependencies": { @@ -17600,36 +18407,23 @@ } }, "node_modules/wrap-ansi": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-10.0.0.tgz", - "integrity": "sha512-SGcvg80f0wUy2/fXES19feHMz8E0JoXv2uNgHOu4Dgi2OrCy1lqwFYEJz1BLbDI0exjPMe/ZdzZ/YpGECBG/aQ==", - "dev": true, + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "license": "MIT", + "optional": true, "dependencies": { - "ansi-styles": "^6.2.3", - "string-width": "^8.2.0", - "strip-ansi": "^7.1.2" + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" }, "engines": { - "node": ">=20" + "node": ">=10" }, "funding": { "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/wrap-ansi/node_modules/ansi-styles": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", - "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -17638,10 +18432,9 @@ "optional": true }, "node_modules/ws": { - "version": "8.21.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.0.tgz", - "integrity": "sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==", - "dev": true, + "version": "8.21.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.1.tgz", + "integrity": "sha512-+0NTnW77fFN/DjQi6k/Sq/Yvk4Sgajw7urW8V+asjXnRgDs9gyGkdb7EzgfhA4goXsRIZKE28fzIXBHEzhuiWw==", "license": "MIT", "engines": { "node": ">=10.0.0" @@ -17670,9 +18463,9 @@ } }, "node_modules/xml-naming": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/xml-naming/-/xml-naming-0.1.0.tgz", - "integrity": "sha512-k8KO9hrMyNk6tUWqUfkTEZbezRRpONVOzUTnc97VnCvyj6Tf9lyUR9EDAIeiVLv56jsMcoXEwjW8Kv5yPY52lw==", + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/xml-naming/-/xml-naming-0.3.0.tgz", + "integrity": "sha512-ghig2TBE/H11aOVgmahA3MhimvkBr6JIYknH/Dhdk10nXwdbIqBJsbfMxpvFPG8bAw77gN29aQWvKpmVoPlvPQ==", "funding": [ { "type": "github", @@ -17714,7 +18507,6 @@ "integrity": "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==", "dev": true, "license": "ISC", - "optional": true, "bin": { "yaml": "bin.mjs" }, @@ -17726,9 +18518,9 @@ } }, "node_modules/yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "version": "17.7.3", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.3.tgz", + "integrity": "sha512-GZtjxm/J/4TSxuL3FNYjCmLktBTnIw/rVmKSIyKeYAZpmJB2ig9VauCC5xsa82GNKVKDAqpOn3KVzNt0zmrU0g==", "license": "MIT", "optional": true, "dependencies": { @@ -17754,51 +18546,6 @@ "node": ">=12" } }, - "node_modules/yargs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "license": "MIT", - "optional": true - }, - "node_modules/yargs/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "license": "MIT", - "optional": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "optional": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", @@ -17812,9 +18559,9 @@ } }, "node_modules/yoctocolors": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yoctocolors/-/yoctocolors-2.1.2.tgz", - "integrity": "sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/yoctocolors/-/yoctocolors-2.2.0.tgz", + "integrity": "sha512-xYqdZFUK/VYazNl/oCDYN+3WloWQwMfZxBoiNt6qNyk+xfOdi598muWE42rNZFp1kNOiqW936q5RhUdnpqElSg==", "license": "MIT", "engines": { "node": ">=18" diff --git a/package.json b/package.json index 06b643ee..d2bcac3c 100644 --- a/package.json +++ b/package.json @@ -1,10 +1,10 @@ { "name": "ghostclass", - "version": "4.4.9", + "version": "4.5.0", "private": true, "engines": { "node": ">=22.12.0", - "npm": ">=11" + "npm": ">=12" }, "scripts": { "dev": "next dev -H 0.0.0.0 --webpack", @@ -17,7 +17,6 @@ "build:webpack": "next build --webpack", "start": "next start", "lint": "eslint src", - "infisical:dev": "infisical run -- next dev -H 0.0.0.0 --webpack", "test": "vitest", "test:watch": "vitest --watch", "test:ui": "vitest --ui", @@ -26,6 +25,7 @@ "test:e2e:ui": "playwright test --ui", "test:e2e:headed": "playwright test --headed", "test:all": "npm run test:coverage && npm run test:e2e", + "generate:firebase-json": "node scripts/generate-firebase-json.js", "prepare": "husky" }, "browserslist": [ @@ -41,110 +41,118 @@ "js-yaml": "^4.1.1", "rollup": "^4.60.3", "glob": "^13.0.6", - "source-map": "^0.7.6", + "source-map": "^0.8.0", "minimatch": "^10.2.5", "flatted": "^3.4.2", "@tootallnate/once": "^3.0.1", "postcss": "^8.5.14", - "uuid": "^14.0.0" + "sharp": "^0.35.0", + "uuid": "^14.0.1" }, "dependencies": { - "@hookform/resolvers": "^5.2.2", - "@radix-ui/react-alert-dialog": "^1.1.15", - "@radix-ui/react-avatar": "^1.1.11", - "@radix-ui/react-checkbox": "^1.3.3", - "@radix-ui/react-dialog": "^1.1.15", - "@radix-ui/react-dropdown-menu": "^2.1.16", - "@radix-ui/react-label": "^2.1.8", - "@radix-ui/react-popover": "^1.1.15", - "@radix-ui/react-progress": "^1.1.8", - "@radix-ui/react-radio-group": "^1.3.8", - "@radix-ui/react-scroll-area": "^1.2.10", - "@radix-ui/react-select": "^2.2.6", - "@radix-ui/react-separator": "^1.1.8", - "@radix-ui/react-slot": "^1.2.4", - "@radix-ui/react-switch": "^1.2.6", - "@radix-ui/react-tabs": "^1.1.13", - "@scalar/nextjs-api-reference": "^0.10.0", - "@sentry/nextjs": "^10.41.0", - "@serwist/next": "^9.5.6", - "@supabase/ssr": "^0.10.2", - "@supabase/supabase-js": "^2.97.0", - "@tanstack/react-query": "^5.100.13", - "@tanstack/react-virtual": "^3.13.21", + "@hookform/resolvers": "^5.5.7", + "@radix-ui/react-alert-dialog": "^1.1.23", + "@radix-ui/react-avatar": "^1.2.6", + "@radix-ui/react-checkbox": "^1.3.11", + "@radix-ui/react-dialog": "^1.1.23", + "@radix-ui/react-dropdown-menu": "^2.1.24", + "@radix-ui/react-label": "^2.1.15", + "@radix-ui/react-popover": "^1.1.23", + "@radix-ui/react-progress": "^1.1.16", + "@radix-ui/react-radio-group": "^1.4.7", + "@radix-ui/react-scroll-area": "^1.2.18", + "@radix-ui/react-select": "^2.3.7", + "@radix-ui/react-separator": "^1.1.15", + "@radix-ui/react-slot": "^1.3.3", + "@radix-ui/react-switch": "^1.3.7", + "@radix-ui/react-tabs": "^1.1.21", + "@scalar/nextjs-api-reference": "^0.11.12", + "@sentry/nextjs": "^10.69.0", + "@serwist/next": "^9.5.12", + "@supabase/ssr": "^0.12.4", + "@supabase/supabase-js": "^2.111.0", + "@tanstack/react-query": "^5.101.4", + "@tanstack/react-virtual": "^3.14.9", "@upstash/ratelimit": "^2.0.8", - "@upstash/redis": "^1.36.2", - "axios": "^1.13.5", + "@upstash/redis": "^1.38.1", + "axios": "^1.19.0", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", - "date-fns": "^4.1.0", - "firebase-admin": "^13.8.0", - "framer-motion": "^12.34.3", + "date-fns": "^4.4.0", + "firebase-admin": "^14.2.0", + "framer-motion": "^12.43.0", "googleapis": "^173.0.0", - "jose": "^6.2.2", + "jose": "^6.2.5", "ldrs": "^1.1.9", - "lodash-es": "^4.17.23", - "lru-cache": "^11.2.6", - "lucide-react": "^1.16.0", - "next": "^16.1.6", + "lodash-es": "^4.18.1", + "lru-cache": "^11.5.2", + "lucide-react": "^1.28.0", + "next": "^16.2.12", "nextjs-toploader": "^3.9.17", "node-domexception": "^2.0.2", - "react": "^19.2.4", - "react-day-picker": "^10.0.0", - "react-dom": "^19.2.4", - "react-email": "^6.0.0", - "react-hook-form": "^7.71.2", - "react-is": "^19.2.5", + "react": "^19.2.8", + "react-day-picker": "^10.0.1", + "react-dom": "^19.2.8", + "react-email": "^6.9.1", + "react-hook-form": "^7.83.0", + "react-is": "^19.2.8", "react-markdown": "^10.1.0", "react-turnstile": "^1.1.5", - "recharts": "^3.7.0", - "resend": "^6.9.2", - "sanitize-html": "^2.17.0", + "recharts": "^3.10.1", + "resend": "^6.18.1", + "sanitize-html": "^2.17.6", "server-only": "^0.0.1", - "serwist": "^9.5.6", + "serwist": "^9.5.12", "sonner": "^2.0.7", "tailwind-merge": "^3.6.0", "tw-animate-css": "^1.4.0", - "uuid": "^14.0.0", - "zod": "^4.3.6" + "uuid": "^14.0.1", + "zod": "^4.4.3" }, "devDependencies": { - "@eslint/js": "^9.39.4", - "@opentelemetry/context-async-hooks": "^2.6.0", - "@playwright/test": "^1.59.1", + "@eslint/js": "^9.39.5", + "@opentelemetry/context-async-hooks": "^2.10.0", + "@playwright/test": "^1.62.1", "@tailwindcss/postcss": "^4", - "@testing-library/dom": "^10.4.0", - "@testing-library/jest-dom": "^6.9.1", + "@testing-library/dom": "^10.4.1", + "@testing-library/jest-dom": "^7.0.0", "@testing-library/react": "^16.3.2", "@testing-library/user-event": "^14.6.1", - "@types/node": "^25.3.5", + "@types/node": "^26.1.2", "@types/nprogress": "^0.2.3", - "@types/react": "^19.2.14", - "@types/react-dom": "^19.2.3", - "@types/sanitize-html": "^2.16.0", - "@typescript-eslint/parser": "^8.56.1", - "@vitejs/plugin-react": "^6.0.1", - "@vitest/coverage-v8": "^4.0.18", - "@vitest/ui": "^4.1.5", - "eslint": "^9.39.4", - "eslint-config-next": "^16.1.6", + "@types/react": "^19.2.18", + "@types/react-dom": "^19.2.4", + "@types/sanitize-html": "^2.16.1", + "@typescript-eslint/parser": "^8.65.0", + "@vitejs/plugin-react": "^6.0.5", + "@vitest/coverage-v8": "^4.1.10", + "@vitest/ui": "^4.1.10", + "eslint": "^9.39.5", + "eslint-config-next": "^16.2.12", "eslint-plugin-react": "^7.37.5", - "eslint-plugin-react-hooks": "^7.0.1", - "eslint-plugin-security": "^4.0.0", - "eslint-plugin-sonarjs": "^4.0.3", + "eslint-plugin-react-hooks": "^7.1.1", + "eslint-plugin-security": "^4.0.1", + "eslint-plugin-sonarjs": "^4.2.0", "eslint-plugin-unused-imports": "^4.4.1", "glob": "^13.0.6", - "globals": "^17.3.0", - "happy-dom": "^20.7.0", + "globals": "^17.8.0", + "happy-dom": "^20.11.1", "husky": "^9.1.7", - "jsdom": "^29.0.0", - "lint-staged": "^17.0.4", + "jsdom": "^30.0.1", + "lint-staged": "^17.3.0", "rimraf": "^6.1.3", - "source-map": "^0.7.6", - "supabase": "^2.76.14", + "source-map": "^0.8.0", + "supabase": "^2.111.0", "tailwindcss": "^4", "typescript": "^6.0.3", - "typescript-eslint": "^8.56.1", - "vitest": "^4.1.5" + "typescript-eslint": "^8.65.0", + "vitest": "^4.1.10" + }, + "allowScripts": { + "@firebase/util@1.15.2": true, + "@sentry/cli@2.58.6": true, + "esbuild@0.28.1": true, + "protobufjs@7.6.5": true, + "unrs-resolver@1.12.2": true } } diff --git a/public/openapi/openapi.yaml b/public/openapi/openapi.yaml index 737107f2..bb657609 100644 --- a/public/openapi/openapi.yaml +++ b/public/openapi/openapi.yaml @@ -6,7 +6,7 @@ openapi: 3.1.0 info: title: GhostClass API - version: 4.4.9 + version: 4.5.0 description: | **GhostClass API** provides endpoints for authentication, profile synchronization, attendance integrations with EzyGo, telemetry, and build provenance. diff --git a/scripts/fetch-build-time-vars.js b/scripts/fetch-build-time-vars.js index 9163409c..b0b46a98 100644 --- a/scripts/fetch-build-time-vars.js +++ b/scripts/fetch-build-time-vars.js @@ -1,6 +1,7 @@ #!/usr/bin/env node -const fs = require('fs'); +const fs = require('node:fs'); +const { generateFirebaseJson } = require('./generate-firebase-json.js'); /** * Authenticates with Infisical using Universal Auth. @@ -153,6 +154,7 @@ async function main() { const projectId = await resolveProjectId(apiBaseUrl, accessToken, projectSlugOrId); const secrets = await fetchSecrets(apiBaseUrl, accessToken, projectId, envSlug, secretPath); exportSecrets(secrets); + generateFirebaseJson(secrets); } main().catch(err => { diff --git a/scripts/generate-firebase-json.js b/scripts/generate-firebase-json.js new file mode 100644 index 00000000..d2304fd1 --- /dev/null +++ b/scripts/generate-firebase-json.js @@ -0,0 +1,213 @@ +#!/usr/bin/env node + +const fs = require('node:fs'); +const path = require('node:path'); + +/** + * Helper to retrieve variable from secrets array or process.env. + * @param {string} key + * @param {Record} envMap + * @returns {string} + */ +function getVar(key, envMap) { + return envMap[key] || process.env[key] || ''; +} + +/** + * Dynamically generates mobile/lib/firebase_options.dart from Infisical secrets or process.env. + * @param {Array<{secretKey: string, secretValue: string}>} [secrets=[]] + * @param {string} [targetFile] + * @returns {boolean} + */ +function generateFirebaseOptionsDart(_secrets = [], targetFile) { + + const dartContent = `// File generated dynamically during build workflow. +// ignore_for_file: type=lint +import 'package:firebase_core/firebase_core.dart' show FirebaseOptions; +import 'package:flutter/foundation.dart' + show defaultTargetPlatform, kIsWeb, TargetPlatform; + +/// Default [FirebaseOptions] for use with your Firebase apps. +class DefaultFirebaseOptions { + static FirebaseOptions get currentPlatform { + if (kIsWeb) { + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for web - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + } + switch (defaultTargetPlatform) { + case TargetPlatform.android: + return android; + case TargetPlatform.iOS: + return ios; + case TargetPlatform.macOS: + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for macos.', + ); + case TargetPlatform.windows: + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for windows.', + ); + case TargetPlatform.linux: + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for linux.', + ); + default: + throw UnsupportedError( + 'DefaultFirebaseOptions are not supported for this platform.', + ); + } + } + + static const FirebaseOptions android = FirebaseOptions( + apiKey: String.fromEnvironment('FIREBASE_API_KEY_ANDROID'), + appId: String.fromEnvironment('FIREBASE_ANDROID_APP_ID'), + messagingSenderId: String.fromEnvironment('FIREBASE_MESSAGING_SENDER_ID'), + projectId: String.fromEnvironment('FIREBASE_PROJECT_ID'), + storageBucket: String.fromEnvironment('FIREBASE_STORAGE_BUCKET'), + ); + + static const FirebaseOptions ios = FirebaseOptions( + apiKey: String.fromEnvironment('FIREBASE_API_KEY_IOS'), + appId: String.fromEnvironment('FIREBASE_IOS_APP_ID'), + messagingSenderId: String.fromEnvironment('FIREBASE_MESSAGING_SENDER_ID'), + projectId: String.fromEnvironment('FIREBASE_PROJECT_ID'), + storageBucket: String.fromEnvironment('FIREBASE_STORAGE_BUCKET'), + iosBundleId: String.fromEnvironment('FIREBASE_IOS_BUNDLE_ID'), + ); +} +`; + + const targetPath = targetFile || path.join(process.cwd(), 'mobile', 'lib', 'firebase_options.dart'); + try { + const dir = path.dirname(targetPath); + if (!fs.existsSync(dir)) { + fs.mkdirSync(dir, { recursive: true }); + } + fs.writeFileSync(targetPath, dartContent); + console.log(`โœ“ Dynamically generated ${targetPath}`); + return true; + } catch (err) { + console.warn(`โš ๏ธ Could not write ${targetPath}:`, err.message); + return false; + } +} + +/** + * Dynamically generates mobile/firebase.json from Infisical secrets or process.env. + * @param {Array<{secretKey: string, secretValue: string}>} [secrets=[]] + * @param {string} [targetFile] + * @returns {boolean} + */ +function generateFirebaseJson(secrets = [], targetFile) { + const envMap = {}; + if (Array.isArray(secrets)) { + for (const s of secrets) { + if (s && s.secretKey) { + envMap[s.secretKey] = s.secretValue; + } + } + } + + const projectId = + getVar('FIREBASE_PROJECT_ID', envMap) || + getVar('FIREBASE_PROJECT_ID_NEXUS', envMap) || + getVar('NEXT_PUBLIC_FIREBASE_PROJECT_ID', envMap); + + const androidAppIdNexus = getVar('FIREBASE_ANDROID_APP_ID_NEXUS', envMap); + const iosAppIdNexus = getVar('FIREBASE_IOS_APP_ID_NEXUS', envMap); + const androidAppIdNexusMec = getVar('FIREBASE_ANDROID_APP_ID_NEXUS_MEC', envMap); + const iosAppIdNexusMec = getVar('FIREBASE_IOS_APP_ID_NEXUS_MEC', envMap); + + const androidAppIdDefault = + getVar('FIREBASE_ANDROID_APP_ID', envMap) || + getVar('FIREBASE_APP_ID_ANDROID', envMap) || + androidAppIdNexus; + const iosAppIdDefault = + getVar('FIREBASE_IOS_APP_ID', envMap) || + getVar('FIREBASE_APP_ID_IOS', envMap) || + iosAppIdNexus || + androidAppIdDefault; + + // Check if minimum requirements exist + if (!projectId || (!androidAppIdDefault && !androidAppIdNexus)) { + console.log('โ„น๏ธ Skipping mobile/firebase.json generation (missing Firebase project/app IDs).'); + return false; + } + + const defaultAndroidAppId = androidAppIdNexus || androidAppIdDefault; + const dartConfigurations = {}; + + // Standard lib/firebase_options.dart target + if (androidAppIdDefault || (!androidAppIdNexus && !androidAppIdNexusMec)) { + dartConfigurations['lib/firebase_options.dart'] = { + projectId: projectId, + configurations: { + android: androidAppIdDefault, + ios: iosAppIdDefault + } + }; + } + + // Flavor target: Nexus + if (androidAppIdNexus) { + dartConfigurations['lib/firebase_options_nexus.dart'] = { + projectId: projectId, + configurations: { + android: androidAppIdNexus, + ios: iosAppIdNexus || androidAppIdNexus + } + }; + } + + // Flavor target: Nexus MEC + if (androidAppIdNexusMec || (androidAppIdNexus && iosAppIdNexusMec)) { + dartConfigurations['lib/firebase_options_nexus_mec.dart'] = { + projectId: projectId, + configurations: { + android: androidAppIdNexusMec || androidAppIdNexus, + ios: iosAppIdNexusMec || iosAppIdNexus || androidAppIdNexus + } + }; + } + + const firebaseJson = { + flutter: { + platforms: { + android: { + default: { + projectId: projectId, + appId: defaultAndroidAppId, + fileOutput: 'android/app/google-services.json' + } + }, + dart: dartConfigurations + } + } + }; + + const targetPath = targetFile || path.join(process.cwd(), 'mobile', 'firebase.json'); + try { + const dir = path.dirname(targetPath); + if (!fs.existsSync(dir)) { + fs.mkdirSync(dir, { recursive: true }); + } + fs.writeFileSync(targetPath, JSON.stringify(firebaseJson, null, 2) + '\n'); + console.log(`โœ“ Dynamically generated ${targetPath}`); + + // Also generate firebase_options.dart with dynamic secret values + generateFirebaseOptionsDart(secrets); + + return true; + } catch (err) { + console.warn(`โš ๏ธ Could not write ${targetPath}:`, err.message); + return false; + } +} + +if (require.main === module) { + generateFirebaseJson(); +} + +module.exports = { generateFirebaseJson, generateFirebaseOptionsDart }; diff --git a/scripts/update-pinned-artifacts.sh b/scripts/update-pinned-artifacts.sh index 384cefd8..8eb082b1 100644 --- a/scripts/update-pinned-artifacts.sh +++ b/scripts/update-pinned-artifacts.sh @@ -14,15 +14,44 @@ echo "Updating pinned artifacts in $PIN_FILE" tmp=$(mktemp -d) trap 'rm -rf "$tmp"' EXIT +# Check JSON tool availability (prefer jq, fallback to node) +HAS_JQ=false +HAS_NODE=false + +if command -v jq >/dev/null 2>&1; then + HAS_JQ=true +elif command -v node >/dev/null 2>&1; then + HAS_NODE=true +else + echo "โŒ Error: Neither 'jq' nor 'node' is installed. Please install jq or node to update pinned artifacts." >&2 + exit 1 +fi + # Update npm packages: fetch registry metadata and write dist.tarball and dist.shasum update_npm() { - name=$1 - echo "Fetching npm metadata for $name (latest)..." - meta="$tmp/${name}.json" - curl -fsSL "https://registry.npmjs.org/$name/latest" -o "$meta" - url=$(jq -r '.dist.tarball' "$meta") - shasum=$(jq -r '.dist.shasum' "$meta") - jq --arg u "$url" --arg s "$shasum" '.[$name] |= . + {url: $u, shasum: $s}' --arg name "$name" "$PIN_FILE" > "$tmp/pinned.json" && mv "$tmp/pinned.json" "$PIN_FILE" + pkg_name=$1 + key_name=${2:-$1} + echo "Fetching npm metadata for $pkg_name (latest)..." + meta="$tmp/${key_name}.json" + curl -fsSL "https://registry.npmjs.org/$pkg_name/latest" -o "$meta" + + if [ "$HAS_JQ" = true ]; then + url=$(jq -r '.dist.tarball' "$meta") + shasum=$(jq -r '.dist.shasum' "$meta") + jq --arg u "$url" --arg s "$shasum" --arg key "$key_name" '.[$key] |= . + {url: $u, shasum: $s}' "$PIN_FILE" > "$tmp/pinned.json" && mv "$tmp/pinned.json" "$PIN_FILE" + else + node -e ' + const fs = require("fs"); + const meta = JSON.parse(fs.readFileSync(process.argv[1])); + const pin = JSON.parse(fs.readFileSync(process.argv[2])); + const key = process.argv[3]; + pin[key] = Object.assign({}, pin[key], { + url: meta.dist.tarball, + shasum: meta.dist.shasum + }); + fs.writeFileSync(process.argv[2], JSON.stringify(pin, null, 2) + "\n"); + ' "$meta" "$PIN_FILE" "$key_name" + fi } # Update supabase: attempt to get latest release asset URL and compute sha256 @@ -31,25 +60,51 @@ update_supabase() { api="https://api.github.com/repos/supabase/cli/releases/latest" release="$tmp/supabase_release.json" curl -fsSL "$api" -o "$release" - # Try to find linux amd64 asset - asset_url=$(jq -r '.assets[] | select(.name | test("linux.*amd64.*tar.gz")) | .browser_download_url' "$release" | head -n1) - if [ -z "$asset_url" ]; then - asset_url=$(jq -r '.assets[0].browser_download_url' "$release") + + if [ "$HAS_JQ" = true ]; then + asset_url=$(jq -r '.assets[] | select(.name | test("linux.*amd64.*tar.gz")) | .browser_download_url' "$release" | head -n1) + if [ -z "$asset_url" ]; then + asset_url=$(jq -r '.assets[0].browser_download_url' "$release") + fi + else + asset_url=$(node -e ' + const fs = require("fs"); + const rel = JSON.parse(fs.readFileSync(process.argv[1])); + const match = (rel.assets || []).find(a => /linux.*amd64.*tar\.gz/.test(a.name)); + console.log(match ? match.browser_download_url : (rel.assets[0] ? rel.assets[0].browser_download_url : "")); + ' "$release") fi + if [ -z "$asset_url" ]; then echo "Could not find supabase release asset URL" >&2 return 1 fi + echo "Downloading supabase asset to compute sha256..." curl -fsSL "$asset_url" -o "$tmp/supabase.tar.gz" sha256=$(sha256sum "$tmp/supabase.tar.gz" | cut -d' ' -f1) - jq --arg u "$asset_url" --arg s "$sha256" '.supabase |= . + {url: $u, sha256: $s}' "$PIN_FILE" > "$tmp/pinned.json" && mv "$tmp/pinned.json" "$PIN_FILE" + + if [ "$HAS_JQ" = true ]; then + jq --arg u "$asset_url" --arg s "$sha256" '.supabase |= . + {url: $u, sha256: $s}' "$PIN_FILE" > "$tmp/pinned.json" && mv "$tmp/pinned.json" "$PIN_FILE" + else + node -e ' + const fs = require("fs"); + const pin = JSON.parse(fs.readFileSync(process.argv[1])); + pin.supabase = Object.assign({}, pin.supabase, { + url: process.argv[2], + sha256: process.argv[3] + }); + fs.writeFileSync(process.argv[1], JSON.stringify(pin, null, 2) + "\n"); + ' "$PIN_FILE" "$asset_url" "$sha256" + fi } # Update entries -update_npm "playwright" -update_npm "firebase-tools" +update_npm "npm" "npm" +update_npm "playwright" "playwright" +update_npm "firebase-tools" "firebase" +update_npm "@infisical/cli" "infisical" update_supabase -echo "Updated $PIN_FILE" -jq . "$PIN_FILE" +echo "โœ… Updated $PIN_FILE:" +cat "$PIN_FILE" diff --git a/src/lib/__tests__/firebase-admin.test.ts b/src/lib/__tests__/firebase-admin.test.ts index 03903aa0..046dc46a 100644 --- a/src/lib/__tests__/firebase-admin.test.ts +++ b/src/lib/__tests__/firebase-admin.test.ts @@ -1,26 +1,32 @@ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; -import { getAppCheck } from '../firebase/admin'; -import * as admin from 'firebase-admin'; +import { getAppCheck, getMessaging } from '../firebase/admin'; +import { initializeApp, getApps, getApp, cert, type App } from 'firebase-admin/app'; +import { getAppCheck as getAdminAppCheck, type AppCheck } from 'firebase-admin/app-check'; +import { getMessaging as getAdminMessaging, type Messaging } from 'firebase-admin/messaging'; import { logger } from '../logger'; -vi.mock('firebase-admin', () => { - const mockApp = { - // Add methods if needed - }; - const mockAppCheck = { - verifyToken: vi.fn(), - }; - - return { - apps: [], - app: vi.fn(() => mockApp), - initializeApp: vi.fn(() => mockApp), - appCheck: vi.fn(() => mockAppCheck), - credential: { - cert: vi.fn(), - }, - }; -}); +const mockApp = { name: 'mock-app' }; +const mockAppCheckService = { + verifyToken: vi.fn(), +}; +const mockMessagingService = { + send: vi.fn(), +}; + +vi.mock('firebase-admin/app', () => ({ + getApps: vi.fn(() => []), + getApp: vi.fn(() => mockApp), + initializeApp: vi.fn(() => mockApp), + cert: vi.fn((credentials: Record) => credentials), +})); + +vi.mock('firebase-admin/app-check', () => ({ + getAppCheck: vi.fn(() => mockAppCheckService), +})); + +vi.mock('firebase-admin/messaging', () => ({ + getMessaging: vi.fn(() => mockMessagingService), +})); vi.mock('../logger', () => ({ logger: { @@ -36,8 +42,12 @@ describe('firebase-admin', () => { beforeEach(() => { vi.clearAllMocks(); process.env = { ...originalEnv }; - // @ts-expect-error -- setting mock apps array for testing - admin.apps = []; + vi.mocked(getApps).mockReturnValue([]); + vi.mocked(getApp).mockReturnValue(mockApp as unknown as App); + vi.mocked(initializeApp).mockReturnValue(mockApp as unknown as App); + vi.mocked(cert).mockImplementation((creds: unknown) => creds as ReturnType); + vi.mocked(getAdminAppCheck).mockReturnValue(mockAppCheckService as unknown as AppCheck); + vi.mocked(getAdminMessaging).mockReturnValue(mockMessagingService as unknown as Messaging); }); afterEach(() => { @@ -58,10 +68,9 @@ describe('firebase-admin', () => { const verifier = getAppCheck(); expect(verifier).not.toBeNull(); - expect(admin.initializeApp).toHaveBeenCalled(); + expect(initializeApp).toHaveBeenCalled(); - const mockVerifyToken = vi.mocked(admin.appCheck().verifyToken); - mockVerifyToken.mockResolvedValueOnce({ appId: 'test-app', token: 'mock-token' } as any); + mockAppCheckService.verifyToken.mockResolvedValueOnce({ appId: 'test-app', token: 'mock-token' }); const result = await verifier!.verifyToken('token'); expect(result.appId).toBe('test-app'); @@ -69,13 +78,12 @@ describe('firebase-admin', () => { it('uses existing firebase app if already initialized', () => { process.env.GOOGLE_SERVICE_ACCOUNT_JSON = JSON.stringify({ project_id: 'test-project' }); - // @ts-expect-error -- setting mock apps array for testing - admin.apps = [{ name: 'default' }]; + vi.mocked(getApps).mockReturnValue([{ name: 'default' } as unknown as App]); getAppCheck(); - expect(admin.app).toHaveBeenCalled(); - expect(admin.initializeApp).not.toHaveBeenCalled(); + expect(getApp).toHaveBeenCalled(); + expect(initializeApp).not.toHaveBeenCalled(); }); it('handles base64 encoded credentials', () => { @@ -84,7 +92,7 @@ describe('firebase-admin', () => { getAppCheck(); - expect(admin.credential.cert).toHaveBeenCalledWith(credentials); + expect(cert).toHaveBeenCalledWith(credentials); }); it('returns null if initialization fails', () => { @@ -96,11 +104,10 @@ describe('firebase-admin', () => { expect(logger.error).toHaveBeenCalled(); }); - it('returns null if token verification fails catastrophically', async () => { + it('returns null if token verification fails catastrophically', () => { process.env.GOOGLE_SERVICE_ACCOUNT_JSON = JSON.stringify({ project_id: 'test-project' }); - // @ts-expect-error -- setting mock apps array for testing - admin.apps = [{ name: 'default' }]; - vi.mocked(admin.app).mockImplementationOnce(() => { throw new Error('Fatal'); }); + vi.mocked(getApps).mockReturnValue([{ name: 'default' } as unknown as App]); + vi.mocked(getApp).mockImplementationOnce(() => { throw new Error('Fatal'); }); const verifier = getAppCheck(); expect(verifier).toBeNull(); @@ -111,11 +118,26 @@ describe('firebase-admin', () => { process.env.GOOGLE_SERVICE_ACCOUNT_JSON = JSON.stringify({ project_id: 'test-project' }); const verifier = getAppCheck(); - const mockVerifyToken = vi.mocked(admin.appCheck().verifyToken); - mockVerifyToken.mockRejectedValueOnce(new Error('Invalid Token')); + mockAppCheckService.verifyToken.mockRejectedValueOnce(new Error('Invalid Token')); await expect(verifier!.verifyToken('token')).rejects.toThrow('Invalid Token'); expect(logger.error).toHaveBeenCalledWith(expect.stringContaining('verification failed'), expect.any(Error)); }); }); + + describe('getMessaging', () => { + it('returns null if GOOGLE_SERVICE_ACCOUNT_JSON is missing', () => { + delete process.env.GOOGLE_SERVICE_ACCOUNT_JSON; + const messaging = getMessaging(); + expect(messaging).toBeNull(); + expect(logger.warn).toHaveBeenCalledWith(expect.stringContaining('GOOGLE_SERVICE_ACCOUNT_JSON not configured')); + }); + + it('initializes firebase and returns messaging service when credentials are provided', () => { + process.env.GOOGLE_SERVICE_ACCOUNT_JSON = JSON.stringify({ project_id: 'test-project' }); + const messaging = getMessaging(); + expect(messaging).not.toBeNull(); + expect(getAdminMessaging).toHaveBeenCalledWith(mockApp); + }); + }); }); diff --git a/src/lib/firebase/admin.ts b/src/lib/firebase/admin.ts index bbd150ad..e02d58b7 100644 --- a/src/lib/firebase/admin.ts +++ b/src/lib/firebase/admin.ts @@ -1,5 +1,7 @@ import { logger } from "@/lib/logger"; -import * as admin from "firebase-admin"; +import { initializeApp, getApps, getApp, cert } from "firebase-admin/app"; +import { getAppCheck as getAdminAppCheck } from "firebase-admin/app-check"; +import { getMessaging as getAdminMessaging, type Messaging } from "firebase-admin/messaging"; export interface DecodedAppCheckToken { appId: string; @@ -20,7 +22,7 @@ export interface AppCheckVerifier { export function getAppCheck(): AppCheckVerifier | null { try { // Check if Firebase Admin is already initialized - const firebaseApp = admin.apps.length > 0 ? admin.app() : initializeFirebaseAdmin(); + const firebaseApp = getApps().length > 0 ? getApp() : initializeFirebaseAdmin(); if (!firebaseApp) { logger.warn("Firebase Admin App Check: Failed to initialize Firebase Admin"); @@ -30,7 +32,7 @@ export function getAppCheck(): AppCheckVerifier | null { return { async verifyToken(token: string) { try { - const appCheckService = admin.appCheck(); + const appCheckService = getAdminAppCheck(firebaseApp); const decodedToken = await appCheckService.verifyToken(token); return { appId: decodedToken.appId, @@ -53,16 +55,16 @@ export function getAppCheck(): AppCheckVerifier | null { * Initialize and return Firebase Admin Messaging service * Returns null if Firebase Admin is not properly configured */ -export function getMessaging(): admin.messaging.Messaging | null { +export function getMessaging(): Messaging | null { try { - const firebaseApp = admin.apps.length > 0 ? admin.app() : initializeFirebaseAdmin(); + const firebaseApp = getApps().length > 0 ? getApp() : initializeFirebaseAdmin(); if (!firebaseApp) { logger.warn("Firebase Admin Messaging: Failed to initialize Firebase Admin"); return null; } - return admin.messaging(); + return getAdminMessaging(firebaseApp); } catch (error) { logger.error("Firebase Admin Messaging initialization failed:", error); return null; @@ -89,8 +91,8 @@ function initializeFirebaseAdmin() { credentials = JSON.parse(Buffer.from(serviceAccountJson, "base64").toString("utf-8")) as Record; } - const app = admin.initializeApp({ - credential: admin.credential.cert(credentials), + const app = initializeApp({ + credential: cert(credentials), projectId: credentials.project_id as string, }); diff --git a/src/scripts/__tests__/generate-firebase-json.test.ts b/src/scripts/__tests__/generate-firebase-json.test.ts new file mode 100644 index 00000000..3c82ce85 --- /dev/null +++ b/src/scripts/__tests__/generate-firebase-json.test.ts @@ -0,0 +1,83 @@ +import { describe, it, expect, beforeEach, afterEach } from 'vitest'; +import fs from 'node:fs'; +import path from 'node:path'; + +// Require commonjs script under test +// eslint-disable-next-line @typescript-eslint/no-require-imports +const { generateFirebaseJson, generateFirebaseOptionsDart } = require('../../../scripts/generate-firebase-json.js'); + +describe('generate-firebase-json script', () => { + const tempDir = path.join(__dirname, '__temp_firebase_test__'); + const tempJsonFile = path.join(tempDir, 'firebase.json'); + const tempDartFile = path.join(tempDir, 'firebase_options.dart'); + + const originalEnv = process.env; + + beforeEach(() => { + process.env = { ...originalEnv }; + if (fs.existsSync(tempDir)) { + fs.rmSync(tempDir, { recursive: true, force: true }); + } + }); + + afterEach(() => { + process.env = originalEnv; + if (fs.existsSync(tempDir)) { + fs.rmSync(tempDir, { recursive: true, force: true }); + } + }); + + it('skips generation when missing required Firebase project/app IDs', () => { + delete process.env.FIREBASE_PROJECT_ID; + delete process.env.FIREBASE_ANDROID_APP_ID; + delete process.env.FIREBASE_ANDROID_APP_ID_NEXUS; + + const result = generateFirebaseJson([], tempJsonFile); + expect(result).toBe(false); + expect(fs.existsSync(tempJsonFile)).toBe(false); + }); + + it('generates standard firebase.json and firebase_options.dart from env variables', () => { + process.env.FIREBASE_PROJECT_ID = 'test-project-123'; + process.env.FIREBASE_ANDROID_APP_ID = '1:12345:android:abcdef'; + process.env.FIREBASE_IOS_APP_ID = '1:12345:ios:abcdef'; + + const result = generateFirebaseJson([], tempJsonFile); + expect(result).toBe(true); + expect(fs.existsSync(tempJsonFile)).toBe(true); + + const jsonContent = JSON.parse(fs.readFileSync(tempJsonFile, 'utf8')); + expect(jsonContent.flutter.platforms.android.default.projectId).toBe('test-project-123'); + expect(jsonContent.flutter.platforms.android.default.appId).toBe('1:12345:android:abcdef'); + expect(jsonContent.flutter.platforms.dart['lib/firebase_options.dart']).toBeDefined(); + }); + + it('generates multi-flavor firebase.json from secrets array', () => { + const secrets = [ + { secretKey: 'FIREBASE_PROJECT_ID', secretValue: 'nexus-project' }, + { secretKey: 'FIREBASE_ANDROID_APP_ID_NEXUS', secretValue: '1:999:android:nexus' }, + { secretKey: 'FIREBASE_IOS_APP_ID_NEXUS', secretValue: '1:999:ios:nexus' }, + { secretKey: 'FIREBASE_ANDROID_APP_ID_NEXUS_MEC', secretValue: '1:999:android:mec' }, + { secretKey: 'FIREBASE_IOS_APP_ID_NEXUS_MEC', secretValue: '1:999:ios:mec' } + ]; + + const result = generateFirebaseJson(secrets, tempJsonFile); + expect(result).toBe(true); + + const jsonContent = JSON.parse(fs.readFileSync(tempJsonFile, 'utf8')); + expect(jsonContent.flutter.platforms.android.default.appId).toBe('1:999:android:nexus'); + expect(jsonContent.flutter.platforms.dart['lib/firebase_options_nexus.dart']).toBeDefined(); + expect(jsonContent.flutter.platforms.dart['lib/firebase_options_nexus_mec.dart']).toBeDefined(); + }); + + it('generates valid firebase_options.dart code content', () => { + const result = generateFirebaseOptionsDart([], tempDartFile); + expect(result).toBe(true); + expect(fs.existsSync(tempDartFile)).toBe(true); + + const content = fs.readFileSync(tempDartFile, 'utf8'); + expect(content).toContain("class DefaultFirebaseOptions"); + expect(content).toContain("apiKey: String.fromEnvironment('FIREBASE_API_KEY_ANDROID')"); + expect(content).toContain("projectId: String.fromEnvironment('FIREBASE_PROJECT_ID')"); + }); +}); diff --git a/workers/package-lock.json b/workers/package-lock.json index 8c0ccf94..6e384832 100644 --- a/workers/package-lock.json +++ b/workers/package-lock.json @@ -8,7 +8,7 @@ "name": "wrangler-install", "version": "1.0.0", "dependencies": { - "wrangler": "^4.95.0" + "wrangler": "^4.118.0" } }, "node_modules/@cloudflare/kv-asset-handler": { @@ -36,9 +36,9 @@ } }, "node_modules/@cloudflare/workerd-darwin-64": { - "version": "1.20260526.1", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20260526.1.tgz", - "integrity": "sha512-/pR3GH3gfv0PUp7DjI8v0aAIDOqFwibq4bg5xT7TZgcVdBV/cJQWckdXCMqiRtHiawLwogUX00EIOINkYJ1Zqg==", + "version": "1.20260730.1", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20260730.1.tgz", + "integrity": "sha512-+MBHmPaiTe2KajryW0T24rZvWFxb41hD3d8anNzQqHzft6vSEb18+sp0znSwxgij7ApPhSM1+vhkNg4f3YMguA==", "cpu": [ "x64" ], @@ -52,9 +52,9 @@ } }, "node_modules/@cloudflare/workerd-darwin-arm64": { - "version": "1.20260526.1", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20260526.1.tgz", - "integrity": "sha512-rcyu0iANYfaiezKh3Mcao1O4IIgVfQldxduiL5TZT1sP0NIeRY4YReSTrzPxNnXxSYaIqaqRHMcHbUM/ic4knA==", + "version": "1.20260730.1", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20260730.1.tgz", + "integrity": "sha512-SBHKntPkKvNPgaCrTe99xC1CAl8ygJDzlYfK0LbuJ1muKadIw35WnhO0wu894fKBtllsVQdNzDLee+cm0ppLSQ==", "cpu": [ "arm64" ], @@ -68,9 +68,9 @@ } }, "node_modules/@cloudflare/workerd-linux-64": { - "version": "1.20260526.1", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20260526.1.tgz", - "integrity": "sha512-5EZAEnlLwa9oGJRo8Nd3iY5Wcd9ROGNNG90xNIGp8MEjj8v2jTn42NC47fCZKFdnLj3+S+vWEhu1x0GVJnALjA==", + "version": "1.20260730.1", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20260730.1.tgz", + "integrity": "sha512-ouyPOSMbiKPeSwUJUvxtMcxGAXs2J4aPE4T5ABIYX5ClcQx5j5bbHTmnqOQEY8sAuLTPjH7dY+iB6UI5ISlwwA==", "cpu": [ "x64" ], @@ -84,9 +84,9 @@ } }, "node_modules/@cloudflare/workerd-linux-arm64": { - "version": "1.20260526.1", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20260526.1.tgz", - "integrity": "sha512-X/YBQXeXFeCN7QTStoWrATEBc9WKl7PIqkw/dQkjyJ72gh3rkLe0+Xkzp3wO7gtxTDQMa7NPGy1W4+sdMf8q1g==", + "version": "1.20260730.1", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20260730.1.tgz", + "integrity": "sha512-YQ+Mi78U3TPdgBPtwq+Sm6rJU+Ihl2y0pjYtuuKkdmUbYzL7oLR6Xqq9wljhasnuCFICssDJaqhMep5WizYoEQ==", "cpu": [ "arm64" ], @@ -100,9 +100,9 @@ } }, "node_modules/@cloudflare/workerd-windows-64": { - "version": "1.20260526.1", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20260526.1.tgz", - "integrity": "sha512-R+tqpFFdcfZIljx8fIW9rj9fRTtDgfoA2yonsfAGa6e8snrmr+38mdFHtkRC0D3UyZpn/hOtmXiUBfdX2gMR7Q==", + "version": "1.20260730.1", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20260730.1.tgz", + "integrity": "sha512-27fAN+vUECW1oYVc1KOcHYpkL8COM2Uxtxql7TL595kxbjoqS5yckw7NLz7bTf2pALFCZWjqXDjZGJ/xbG4ZKQ==", "cpu": [ "x64" ], @@ -128,9 +128,9 @@ } }, "node_modules/@emnapi/runtime": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz", - "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==", + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.3.tgz", + "integrity": "sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA==", "license": "MIT", "optional": true, "dependencies": { @@ -138,9 +138,9 @@ } }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.3.tgz", - "integrity": "sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.1.tgz", + "integrity": "sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==", "cpu": [ "ppc64" ], @@ -154,9 +154,9 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.3.tgz", - "integrity": "sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.1.tgz", + "integrity": "sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==", "cpu": [ "arm" ], @@ -170,9 +170,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.3.tgz", - "integrity": "sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.1.tgz", + "integrity": "sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==", "cpu": [ "arm64" ], @@ -186,9 +186,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.3.tgz", - "integrity": "sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.1.tgz", + "integrity": "sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==", "cpu": [ "x64" ], @@ -202,9 +202,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.3.tgz", - "integrity": "sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.1.tgz", + "integrity": "sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==", "cpu": [ "arm64" ], @@ -218,9 +218,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.3.tgz", - "integrity": "sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.1.tgz", + "integrity": "sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==", "cpu": [ "x64" ], @@ -234,9 +234,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.3.tgz", - "integrity": "sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.1.tgz", + "integrity": "sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==", "cpu": [ "arm64" ], @@ -250,9 +250,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.3.tgz", - "integrity": "sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.1.tgz", + "integrity": "sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==", "cpu": [ "x64" ], @@ -266,9 +266,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.3.tgz", - "integrity": "sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.1.tgz", + "integrity": "sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==", "cpu": [ "arm" ], @@ -282,9 +282,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.3.tgz", - "integrity": "sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.1.tgz", + "integrity": "sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==", "cpu": [ "arm64" ], @@ -298,9 +298,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.3.tgz", - "integrity": "sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.1.tgz", + "integrity": "sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==", "cpu": [ "ia32" ], @@ -314,9 +314,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.3.tgz", - "integrity": "sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.1.tgz", + "integrity": "sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==", "cpu": [ "loong64" ], @@ -330,9 +330,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.3.tgz", - "integrity": "sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.1.tgz", + "integrity": "sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==", "cpu": [ "mips64el" ], @@ -346,9 +346,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.3.tgz", - "integrity": "sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.1.tgz", + "integrity": "sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==", "cpu": [ "ppc64" ], @@ -362,9 +362,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.3.tgz", - "integrity": "sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.1.tgz", + "integrity": "sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==", "cpu": [ "riscv64" ], @@ -378,9 +378,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.3.tgz", - "integrity": "sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.1.tgz", + "integrity": "sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==", "cpu": [ "s390x" ], @@ -394,9 +394,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.3.tgz", - "integrity": "sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.1.tgz", + "integrity": "sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==", "cpu": [ "x64" ], @@ -410,9 +410,9 @@ } }, "node_modules/@esbuild/netbsd-arm64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.3.tgz", - "integrity": "sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.1.tgz", + "integrity": "sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==", "cpu": [ "arm64" ], @@ -426,9 +426,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.3.tgz", - "integrity": "sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.1.tgz", + "integrity": "sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==", "cpu": [ "x64" ], @@ -442,9 +442,9 @@ } }, "node_modules/@esbuild/openbsd-arm64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.3.tgz", - "integrity": "sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.1.tgz", + "integrity": "sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==", "cpu": [ "arm64" ], @@ -458,9 +458,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.3.tgz", - "integrity": "sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.1.tgz", + "integrity": "sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==", "cpu": [ "x64" ], @@ -474,9 +474,9 @@ } }, "node_modules/@esbuild/openharmony-arm64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.3.tgz", - "integrity": "sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.1.tgz", + "integrity": "sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==", "cpu": [ "arm64" ], @@ -490,9 +490,9 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.3.tgz", - "integrity": "sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.1.tgz", + "integrity": "sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==", "cpu": [ "x64" ], @@ -506,9 +506,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.3.tgz", - "integrity": "sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.1.tgz", + "integrity": "sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==", "cpu": [ "arm64" ], @@ -522,9 +522,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.3.tgz", - "integrity": "sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.1.tgz", + "integrity": "sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==", "cpu": [ "ia32" ], @@ -538,9 +538,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.3.tgz", - "integrity": "sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.1.tgz", + "integrity": "sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==", "cpu": [ "x64" ], @@ -563,9 +563,9 @@ } }, "node_modules/@img/sharp-darwin-arm64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.5.tgz", - "integrity": "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==", + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.35.2.tgz", + "integrity": "sha512-eEieHsMksAW4IiO5NzauESRl2D2qz3J/kwUxUrSfV06A93eEaRfMpHXyUb1mAqrR7i8U9A0GRqE9pjn6u1Jjpg==", "cpu": [ "arm64" ], @@ -575,19 +575,19 @@ "darwin" ], "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + "node": ">=20.9.0" }, "funding": { "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-darwin-arm64": "1.2.4" + "@img/sharp-libvips-darwin-arm64": "1.3.1" } }, "node_modules/@img/sharp-darwin-x64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.5.tgz", - "integrity": "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==", + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.35.2.tgz", + "integrity": "sha512-BaktuGPCeHJMARpodR8jK4uKiZrPAy9WrfQW0sdI37clracq8Bp01AYS3SZgi5FS/y5twa9t4+LIuuxQjqRrWw==", "cpu": [ "x64" ], @@ -597,19 +597,38 @@ "darwin" ], "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + "node": ">=20.9.0" }, "funding": { "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-darwin-x64": "1.2.4" + "@img/sharp-libvips-darwin-x64": "1.3.1" + } + }, + "node_modules/@img/sharp-freebsd-wasm32": { + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-freebsd-wasm32/-/sharp-freebsd-wasm32-0.35.2.tgz", + "integrity": "sha512-YoAxdnd8hPUkvLHd3bWY+YA8nw3xM/RyRopYucNsWHVSan8NLVM3X2volsfoRDcXdUJPg6tXahSd7HXPK7lRnw==", + "license": "Apache-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "dependencies": { + "@img/sharp-wasm32": "0.35.2" + }, + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" } }, "node_modules/@img/sharp-libvips-darwin-arm64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.4.tgz", - "integrity": "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.3.1.tgz", + "integrity": "sha512-4V/M3roRMTYjiwZY9IOVQOE8OyeCxFAkYmyZDrZl51uOKjibm3oeEJ4WAmLxutAfzFbC9jqUiPs2gbnGflH+7g==", "cpu": [ "arm64" ], @@ -623,9 +642,9 @@ } }, "node_modules/@img/sharp-libvips-darwin-x64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.4.tgz", - "integrity": "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.3.1.tgz", + "integrity": "sha512-c0/DxItpJv2+dGhgycJBBgotdqruGYDvA79drdh0MD1dFpy7JzJ/PlXwi1H4rFf0eTy8tgbI91aHDnZIceY3jQ==", "cpu": [ "x64" ], @@ -639,9 +658,9 @@ } }, "node_modules/@img/sharp-libvips-linux-arm": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.4.tgz", - "integrity": "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.3.1.tgz", + "integrity": "sha512-aGGy9aWzXgHBG7HNyQPWorZthlp7+x6fDRoPAQbGO3ThcttuTyKIx3NuSHb6zb4gBNq6/yNn9f1cy9nFKS/Vmg==", "cpu": [ "arm" ], @@ -658,9 +677,9 @@ } }, "node_modules/@img/sharp-libvips-linux-arm64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.4.tgz", - "integrity": "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.3.1.tgz", + "integrity": "sha512-JznefmcK9j1JKPz8AkQDh89kjojubyfOasWBPKfzMIhPwsgDy9evpE/naJTXXXmghS1iFwR8u/kTwh/I2/+GCw==", "cpu": [ "arm64" ], @@ -677,9 +696,9 @@ } }, "node_modules/@img/sharp-libvips-linux-ppc64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.4.tgz", - "integrity": "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.3.1.tgz", + "integrity": "sha512-1EkwGNCZk6iWNCMWqrvdJ+r1j0PT1zIz60CNPhYnJlK/zyeWqlsPZIe+ocBVqPF8k/Ssee/NCk+tE9Ryrko6ng==", "cpu": [ "ppc64" ], @@ -696,9 +715,9 @@ } }, "node_modules/@img/sharp-libvips-linux-riscv64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.2.4.tgz", - "integrity": "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.3.1.tgz", + "integrity": "sha512-Ilays+w2bXdnxzxtQdmXR62u8o8GYa3eL4+Gr+1KiE4xperMZUslRaVPJwwPkzlHEjGfXAfRVAa/7CYCtSqsBw==", "cpu": [ "riscv64" ], @@ -715,9 +734,9 @@ } }, "node_modules/@img/sharp-libvips-linux-s390x": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.4.tgz", - "integrity": "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.3.1.tgz", + "integrity": "sha512-VfBwVHQTbRoj4XlpA/KLZ7ltgMpz+4WSejFzQ+GnoImjo1PtEJ59QB2qR1xQEeRPYIkNrPIm2L4cICMvz4C2ew==", "cpu": [ "s390x" ], @@ -734,9 +753,9 @@ } }, "node_modules/@img/sharp-libvips-linux-x64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.4.tgz", - "integrity": "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.3.1.tgz", + "integrity": "sha512-+c8ukgwU62DS54nCAjw7keOfHUkmr0B5QHEdcOqRnodF/MNXJbVI8Eopoj4B/0H8Asr65I+A4Amrn7a85/md6A==", "cpu": [ "x64" ], @@ -753,9 +772,9 @@ } }, "node_modules/@img/sharp-libvips-linuxmusl-arm64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.4.tgz", - "integrity": "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.3.1.tgz", + "integrity": "sha512-qlKb/pwbkAi1WMsJrYHk7CuDrd12s27U2QnRhFYUoJNrRCmkosMTttuRFat/DDB3IlDm5qE1TJgZ4JDnHX8Ldw==", "cpu": [ "arm64" ], @@ -772,9 +791,9 @@ } }, "node_modules/@img/sharp-libvips-linuxmusl-x64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.4.tgz", - "integrity": "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.3.1.tgz", + "integrity": "sha512-yO21HwoUVLN8Qa+/SBjQLMYwBWAVJjeGPNe+hc0OUeMeifEtJqu5a1c4HayE1nNpDih9y3/KkoltfkDodmKAlg==", "cpu": [ "x64" ], @@ -791,9 +810,9 @@ } }, "node_modules/@img/sharp-linux-arm": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.5.tgz", - "integrity": "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==", + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.35.2.tgz", + "integrity": "sha512-SE4kzF2mepn6z+6E7L6lsV8FzuLL6IPQdyX8ZiwROAG/G8td+hP/m7FsFPwidtrF19gvajuC9l6TxAVcsA4S7A==", "cpu": [ "arm" ], @@ -806,19 +825,19 @@ "linux" ], "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + "node": ">=20.9.0" }, "funding": { "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-arm": "1.2.4" + "@img/sharp-libvips-linux-arm": "1.3.1" } }, "node_modules/@img/sharp-linux-arm64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.5.tgz", - "integrity": "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==", + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.35.2.tgz", + "integrity": "sha512-af12Pnd0ZGu2HfP8NayB0kk6eC/lrfbQE6HlR4jD+34wdJ1Vw9TF6TMn6ZvffT+WgqVsl0hRbmNvz2u/23VmwA==", "cpu": [ "arm64" ], @@ -831,19 +850,19 @@ "linux" ], "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + "node": ">=20.9.0" }, "funding": { "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-arm64": "1.2.4" + "@img/sharp-libvips-linux-arm64": "1.3.1" } }, "node_modules/@img/sharp-linux-ppc64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.5.tgz", - "integrity": "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==", + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.35.2.tgz", + "integrity": "sha512-hYSBm7zcNtDCozCxQHYZJiu63b/bXsgRZuOxCIBZsStMM9Vap47iFHdbX4kCvQsblPB/k+clhELpdQJHQLSHvg==", "cpu": [ "ppc64" ], @@ -856,19 +875,19 @@ "linux" ], "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + "node": ">=20.9.0" }, "funding": { "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-ppc64": "1.2.4" + "@img/sharp-libvips-linux-ppc64": "1.3.1" } }, "node_modules/@img/sharp-linux-riscv64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.34.5.tgz", - "integrity": "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==", + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.35.2.tgz", + "integrity": "sha512-qQt0Kc13+Hoan/Awq/qMSQw3L+RI1NCRPgD5cUJ/1WSSmIoysLOc72jlRM3E0OHN9Yr313jgeQ2T+zW+F03QFA==", "cpu": [ "riscv64" ], @@ -881,19 +900,19 @@ "linux" ], "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + "node": ">=20.9.0" }, "funding": { "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-riscv64": "1.2.4" + "@img/sharp-libvips-linux-riscv64": "1.3.1" } }, "node_modules/@img/sharp-linux-s390x": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.5.tgz", - "integrity": "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==", + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.35.2.tgz", + "integrity": "sha512-E4fLLfRPzDLlEeDaTzI98OFLcv++WL5ChLLMwPoVd0CIoZQqupBSNbOisPL5am9XsbQ9T84+iiMpUvbFtkunbA==", "cpu": [ "s390x" ], @@ -906,19 +925,19 @@ "linux" ], "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + "node": ">=20.9.0" }, "funding": { "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-s390x": "1.2.4" + "@img/sharp-libvips-linux-s390x": "1.3.1" } }, "node_modules/@img/sharp-linux-x64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.5.tgz", - "integrity": "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==", + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.35.2.tgz", + "integrity": "sha512-gi0zFJJRLswfCZmHtJdikXPOc5u7qamSOS3NHedLqLd4W8Q0NqjdBr6TTRIgsfFjqfTsHFgdfvJ9LwqSgcHiAA==", "cpu": [ "x64" ], @@ -931,19 +950,19 @@ "linux" ], "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + "node": ">=20.9.0" }, "funding": { "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-x64": "1.2.4" + "@img/sharp-libvips-linux-x64": "1.3.1" } }, "node_modules/@img/sharp-linuxmusl-arm64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.5.tgz", - "integrity": "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==", + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.35.2.tgz", + "integrity": "sha512-siWbOW1u6HFnFLrp0waKyW7VEf7jYvcDWdrXEFa8AkdAQgEvuu5Fz8/Y70w9EeqAdwDtfU012BhEHHaDqvQNzg==", "cpu": [ "arm64" ], @@ -956,19 +975,19 @@ "linux" ], "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + "node": ">=20.9.0" }, "funding": { "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linuxmusl-arm64": "1.2.4" + "@img/sharp-libvips-linuxmusl-arm64": "1.3.1" } }, "node_modules/@img/sharp-linuxmusl-x64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.5.tgz", - "integrity": "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==", + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.35.2.tgz", + "integrity": "sha512-YBqMMcjDi4QGYiSn4vNOYBhmlC4z5AXqkOUUqI2e0AFA4urNv4ESgOgwNl3K+4etQhha0twXlzeF20bbULm9Yg==", "cpu": [ "x64" ], @@ -981,38 +1000,54 @@ "linux" ], "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + "node": ">=20.9.0" }, "funding": { "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linuxmusl-x64": "1.2.4" + "@img/sharp-libvips-linuxmusl-x64": "1.3.1" } }, "node_modules/@img/sharp-wasm32": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.5.tgz", - "integrity": "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==", + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.35.2.tgz", + "integrity": "sha512-Mrv4JQNYVQ94xH+jzZ9r+gowleN8mv2FTgKT+PI6bx5C0G8TdNYndu161pg2i7uoBwxy2ImPMHrJOM2LZef7Bw==", + "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.11.1" + }, + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-webcontainers-wasm32": { + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-webcontainers-wasm32/-/sharp-webcontainers-wasm32-0.35.2.tgz", + "integrity": "sha512-QNV27pxs9wpApEiCfvHM1RDoP1w1+2KrUWWDPEhEwg+latvOrfuhWrHWZKwdSFwU6jh3myjw/yOCRsUIuOft3g==", "cpu": [ "wasm32" ], - "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "license": "Apache-2.0", "optional": true, "dependencies": { - "@emnapi/runtime": "^1.7.0" + "@img/sharp-wasm32": "0.35.2" }, "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + "node": ">=20.9.0" }, "funding": { "url": "https://opencollective.com/libvips" } }, "node_modules/@img/sharp-win32-arm64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.5.tgz", - "integrity": "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==", + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.35.2.tgz", + "integrity": "sha512-BiVRYc/t6/Vl3e1hBx0hugG4oN9Pydf4fgMSpxTQJmwGUg/YoXTWHiFeRymHfCZzifxu4F4rpk/I67D0LQ20wQ==", "cpu": [ "arm64" ], @@ -1022,16 +1057,16 @@ "win32" ], "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + "node": ">=20.9.0" }, "funding": { "url": "https://opencollective.com/libvips" } }, "node_modules/@img/sharp-win32-ia32": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.5.tgz", - "integrity": "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==", + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.35.2.tgz", + "integrity": "sha512-YYEhx9PImCC7T0tI8JDMi4DB9LwLCXCU5OWNYEXAxh5Q1ShKkyC6byxzoBJ3gEFDnH2lQckWuDe70G7mB2XJog==", "cpu": [ "ia32" ], @@ -1041,16 +1076,16 @@ "win32" ], "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + "node": "^20.9.0" }, "funding": { "url": "https://opencollective.com/libvips" } }, "node_modules/@img/sharp-win32-x64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.5.tgz", - "integrity": "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==", + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.35.2.tgz", + "integrity": "sha512-imoOyBcoM/iiUr4J6VPpCNjPnjvP/Gks95898yB8YqoGGYmHYbOyCuNv9FMhFgtaiHFGbHW8bxKqRV6VjtXThQ==", "cpu": [ "x64" ], @@ -1060,7 +1095,7 @@ "win32" ], "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + "node": ">=20.9.0" }, "funding": { "url": "https://opencollective.com/libvips" @@ -1130,9 +1165,9 @@ } }, "node_modules/@speed-highlight/core": { - "version": "1.2.15", - "resolved": "https://registry.npmjs.org/@speed-highlight/core/-/core-1.2.15.tgz", - "integrity": "sha512-BMq1K3DsElxDWawkX6eLg9+CKJrTVGCBAWVuHXVUV2u0s2711qiChLSId6ikYPfxhdYocLNt3wWwSvDiTvFabw==", + "version": "1.2.17", + "resolved": "https://registry.npmjs.org/@speed-highlight/core/-/core-1.2.17.tgz", + "integrity": "sha512-Z92FwKpCtfaW1V0jTU/fh3QzYEZN8wDwrzRIBoADCJfn4mJCNcJN/XegifX7BDrQ8/h9Xh/JnbyMchL0FqXrkg==", "license": "CC0-1.0" }, "node_modules/blake3-wasm": { @@ -1173,9 +1208,9 @@ } }, "node_modules/esbuild": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.3.tgz", - "integrity": "sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.1.tgz", + "integrity": "sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==", "hasInstallScript": true, "license": "MIT", "bin": { @@ -1185,32 +1220,32 @@ "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.27.3", - "@esbuild/android-arm": "0.27.3", - "@esbuild/android-arm64": "0.27.3", - "@esbuild/android-x64": "0.27.3", - "@esbuild/darwin-arm64": "0.27.3", - "@esbuild/darwin-x64": "0.27.3", - "@esbuild/freebsd-arm64": "0.27.3", - "@esbuild/freebsd-x64": "0.27.3", - "@esbuild/linux-arm": "0.27.3", - "@esbuild/linux-arm64": "0.27.3", - "@esbuild/linux-ia32": "0.27.3", - "@esbuild/linux-loong64": "0.27.3", - "@esbuild/linux-mips64el": "0.27.3", - "@esbuild/linux-ppc64": "0.27.3", - "@esbuild/linux-riscv64": "0.27.3", - "@esbuild/linux-s390x": "0.27.3", - "@esbuild/linux-x64": "0.27.3", - "@esbuild/netbsd-arm64": "0.27.3", - "@esbuild/netbsd-x64": "0.27.3", - "@esbuild/openbsd-arm64": "0.27.3", - "@esbuild/openbsd-x64": "0.27.3", - "@esbuild/openharmony-arm64": "0.27.3", - "@esbuild/sunos-x64": "0.27.3", - "@esbuild/win32-arm64": "0.27.3", - "@esbuild/win32-ia32": "0.27.3", - "@esbuild/win32-x64": "0.27.3" + "@esbuild/aix-ppc64": "0.28.1", + "@esbuild/android-arm": "0.28.1", + "@esbuild/android-arm64": "0.28.1", + "@esbuild/android-x64": "0.28.1", + "@esbuild/darwin-arm64": "0.28.1", + "@esbuild/darwin-x64": "0.28.1", + "@esbuild/freebsd-arm64": "0.28.1", + "@esbuild/freebsd-x64": "0.28.1", + "@esbuild/linux-arm": "0.28.1", + "@esbuild/linux-arm64": "0.28.1", + "@esbuild/linux-ia32": "0.28.1", + "@esbuild/linux-loong64": "0.28.1", + "@esbuild/linux-mips64el": "0.28.1", + "@esbuild/linux-ppc64": "0.28.1", + "@esbuild/linux-riscv64": "0.28.1", + "@esbuild/linux-s390x": "0.28.1", + "@esbuild/linux-x64": "0.28.1", + "@esbuild/netbsd-arm64": "0.28.1", + "@esbuild/netbsd-x64": "0.28.1", + "@esbuild/openbsd-arm64": "0.28.1", + "@esbuild/openbsd-x64": "0.28.1", + "@esbuild/openharmony-arm64": "0.28.1", + "@esbuild/sunos-x64": "0.28.1", + "@esbuild/win32-arm64": "0.28.1", + "@esbuild/win32-ia32": "0.28.1", + "@esbuild/win32-x64": "0.28.1" } }, "node_modules/fsevents": { @@ -1237,21 +1272,18 @@ } }, "node_modules/miniflare": { - "version": "4.20260526.0", - "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-4.20260526.0.tgz", - "integrity": "sha512-JYQ7jPZZWoaaj9jWHb8Ucp6Cu2SbDVqIsAJhumqdzzLkkfq0pYkDeino/sZfW1ixJWPjv/C44zjm9gVJC2izCA==", + "version": "5.20260730.0-alpha", + "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-5.20260730.0-alpha.tgz", + "integrity": "sha512-8/dspSXDshP6nSkCpjKO7BYc2qZoYSXm7iM+QxY7qJyJpAB3onnQSaiu0cvKJlfuMGwULl55hG69FJCcCMXU1Q==", "license": "MIT", "dependencies": { "@cspotcode/source-map-support": "0.8.1", - "sharp": "^0.34.5", - "undici": "7.24.8", - "workerd": "1.20260526.1", - "ws": "8.20.1", + "sharp": "0.35.2", + "undici": "7.28.0", + "workerd": "1.20260730.1", + "ws": "8.21.0", "youch": "4.1.0-beta.10" }, - "bin": { - "miniflare": "bootstrap.js" - }, "engines": { "node": ">=22.0.0" } @@ -1268,66 +1300,10 @@ "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", "license": "MIT" }, - "node_modules/rosie-skills": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/rosie-skills/-/rosie-skills-0.6.4.tgz", - "integrity": "sha512-ojfhSiQRdZ2QyWbmKAHOSAUbaLYrTc5zIH7mS1jKoP8KCFSQddwVhMyFqldckTeybTfW3zNcsZzyOTzGTN1SBA==", - "license": "BSD-3-Clause", - "bin": { - "rosie-skills": "dist/bin.js" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "rosie-skills-darwin-arm64": "0.6.4", - "rosie-skills-freebsd-x64": "0.6.4", - "rosie-skills-linux-x64": "0.6.4" - } - }, - "node_modules/rosie-skills-darwin-arm64": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/rosie-skills-darwin-arm64/-/rosie-skills-darwin-arm64-0.6.4.tgz", - "integrity": "sha512-rn1s5hqFKcxeiDEWWoFa1hdGPshR8TkwHLzy/cBavb9XJNAaUxbe3oQ78W9sQkRHAgRyzJYyk9tw68Qrdnizgg==", - "cpu": [ - "arm64" - ], - "license": "BSD-3-Clause", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/rosie-skills-freebsd-x64": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/rosie-skills-freebsd-x64/-/rosie-skills-freebsd-x64-0.6.4.tgz", - "integrity": "sha512-SxCRduPBMtfjkQ+q56Yw9OLA3PyaqoALzt7kER7IDKuUVfM2O/1w8sa5xhTDiCvWkZJixnH5d5Ya6KT+/Mwcng==", - "cpu": [ - "x64" - ], - "license": "BSD-3-Clause", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/rosie-skills-linux-x64": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/rosie-skills-linux-x64/-/rosie-skills-linux-x64-0.6.4.tgz", - "integrity": "sha512-D9Y9mfu7goB0s0X59uU3hcFeUTef3VbpCIDwFMzyvJrAq3XhRACWBDMHQsHlyWdHxTXPX/ILyW65RXyrJlgqng==", - "cpu": [ - "x64" - ], - "license": "BSD-3-Clause", - "optional": true, - "os": [ - "linux" - ] - }, "node_modules/semver": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.1.tgz", - "integrity": "sha512-rkVq3IXh+4FDGch+KwzX3aV9W3kO54GyEgpvBzSyctDA6Xtd7RJQV1xmXbeQp5v7+VzLOfVqiutSE6GICgPFvg==", + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -1337,47 +1313,47 @@ } }, "node_modules/sharp": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.5.tgz", - "integrity": "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==", - "hasInstallScript": true, + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.35.2.tgz", + "integrity": "sha512-FVtFjtBCMiJS6yb5CX7Sop45WFMpeGw6oRKuJnXYgf/f1ms/D7LE/ZUSNxnW7rZ/dbslQWYkoqFHGPaDBtaK4w==", "license": "Apache-2.0", "dependencies": { - "@img/colour": "^1.0.0", + "@img/colour": "^1.1.0", "detect-libc": "^2.1.2", - "semver": "^7.7.3" + "semver": "^7.8.4" }, "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + "node": ">=20.9.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" + "@img/sharp-darwin-arm64": "0.35.2", + "@img/sharp-darwin-x64": "0.35.2", + "@img/sharp-freebsd-wasm32": "0.35.2", + "@img/sharp-libvips-darwin-arm64": "1.3.1", + "@img/sharp-libvips-darwin-x64": "1.3.1", + "@img/sharp-libvips-linux-arm": "1.3.1", + "@img/sharp-libvips-linux-arm64": "1.3.1", + "@img/sharp-libvips-linux-ppc64": "1.3.1", + "@img/sharp-libvips-linux-riscv64": "1.3.1", + "@img/sharp-libvips-linux-s390x": "1.3.1", + "@img/sharp-libvips-linux-x64": "1.3.1", + "@img/sharp-libvips-linuxmusl-arm64": "1.3.1", + "@img/sharp-libvips-linuxmusl-x64": "1.3.1", + "@img/sharp-linux-arm": "0.35.2", + "@img/sharp-linux-arm64": "0.35.2", + "@img/sharp-linux-ppc64": "0.35.2", + "@img/sharp-linux-riscv64": "0.35.2", + "@img/sharp-linux-s390x": "0.35.2", + "@img/sharp-linux-x64": "0.35.2", + "@img/sharp-linuxmusl-arm64": "0.35.2", + "@img/sharp-linuxmusl-x64": "0.35.2", + "@img/sharp-webcontainers-wasm32": "0.35.2", + "@img/sharp-win32-arm64": "0.35.2", + "@img/sharp-win32-ia32": "0.35.2", + "@img/sharp-win32-x64": "0.35.2" } }, "node_modules/supports-color": { @@ -1400,9 +1376,9 @@ "optional": true }, "node_modules/undici": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-8.1.0.tgz", - "integrity": "sha512-E9MkTS4xXLnRPYqxH2e6Hr2/49e7WFDKczKcCaFH4VaZs2iNvHMqeIkyUAD9vM8kujy9TjVrRlQ5KkdEJxB2pw==", + "version": "8.9.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-8.9.0.tgz", + "integrity": "sha512-aWZpUj7XoGonMClx4gdDRfgBjqeA+F473aDmROQQbM9n6PRfK/u1q/a0X4wMTgcHfT8H6fpbt98PFuDUwFg2YA==", "license": "MIT", "engines": { "node": ">=22.19.0" @@ -1418,9 +1394,9 @@ } }, "node_modules/workerd": { - "version": "1.20260526.1", - "resolved": "https://registry.npmjs.org/workerd/-/workerd-1.20260526.1.tgz", - "integrity": "sha512-IHzymht98p10JH1zzwdCpbViAqw97HrwKl7+KfZeASFMsYSrIsAULWdPn0LRC5FTUzBpamLNyKCCKxbgXHgRHQ==", + "version": "1.20260730.1", + "resolved": "https://registry.npmjs.org/workerd/-/workerd-1.20260730.1.tgz", + "integrity": "sha512-zmfNIjwYSWFY5chGBOjWtH3xAE7p97FTC6vR4Ep98290ho6AeAR/NVcBD274YCLEUYzqm8yxdtZlxMybU8a3jA==", "hasInstallScript": true, "license": "Apache-2.0", "bin": { @@ -1430,30 +1406,30 @@ "node": ">=16" }, "optionalDependencies": { - "@cloudflare/workerd-darwin-64": "1.20260526.1", - "@cloudflare/workerd-darwin-arm64": "1.20260526.1", - "@cloudflare/workerd-linux-64": "1.20260526.1", - "@cloudflare/workerd-linux-arm64": "1.20260526.1", - "@cloudflare/workerd-windows-64": "1.20260526.1" + "@cloudflare/workerd-darwin-64": "1.20260730.1", + "@cloudflare/workerd-darwin-arm64": "1.20260730.1", + "@cloudflare/workerd-linux-64": "1.20260730.1", + "@cloudflare/workerd-linux-arm64": "1.20260730.1", + "@cloudflare/workerd-windows-64": "1.20260730.1" } }, "node_modules/wrangler": { - "version": "4.95.0", - "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-4.95.0.tgz", - "integrity": "sha512-vgXzFVSCdUbeCadgVXvu8fK5tzNm8T9W+7lriyGWZMx0B1+CAdr4d8JTlZszHfgjypRAHmAxb49etZGIRD9pgg==", + "version": "4.118.0", + "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-4.118.0.tgz", + "integrity": "sha512-9pkBw/b8zWqGx2S+oLhgHMR1M/4VOE8SynUFABnGWiSFGlcOQ4xiI/B71Xf66RYP2xzngU37IQFPtUruij3lYw==", "license": "MIT OR Apache-2.0", "dependencies": { "@cloudflare/kv-asset-handler": "0.5.0", "@cloudflare/unenv-preset": "2.16.1", "blake3-wasm": "2.1.5", - "esbuild": "0.27.3", - "miniflare": "4.20260526.0", + "esbuild": "0.28.1", + "miniflare": "5.20260730.0-alpha", "path-to-regexp": "6.3.0", - "rosie-skills": "^0.6.3", "unenv": "2.0.0-rc.24", - "workerd": "1.20260526.1" + "workerd": "1.20260730.1" }, "bin": { + "cf-wrangler": "bin/cf-wrangler.js", "wrangler": "bin/wrangler.js", "wrangler2": "bin/wrangler.js" }, @@ -1461,10 +1437,10 @@ "node": ">=22.0.0" }, "optionalDependencies": { - "fsevents": "~2.3.2" + "fsevents": "2.3.3" }, "peerDependencies": { - "@cloudflare/workers-types": "^4.20260526.1" + "@cloudflare/workers-types": "^5.20260730.1" }, "peerDependenciesMeta": { "@cloudflare/workers-types": { @@ -1473,9 +1449,9 @@ } }, "node_modules/ws": { - "version": "8.21.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.0.tgz", - "integrity": "sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==", + "version": "8.21.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.1.tgz", + "integrity": "sha512-+0NTnW77fFN/DjQi6k/Sq/Yvk4Sgajw7urW8V+asjXnRgDs9gyGkdb7EzgfhA4goXsRIZKE28fzIXBHEzhuiWw==", "license": "MIT", "engines": { "node": ">=10.0.0" diff --git a/workers/package.json b/workers/package.json index 38b344e4..75b3724a 100644 --- a/workers/package.json +++ b/workers/package.json @@ -1,12 +1,16 @@ { "name": "wrangler-install", - "version": "1.0.0", + "version": "1.5.0", "private": true, "dependencies": { - "wrangler": "^4.95.0" + "wrangler": "^4.118.0" }, "overrides": { - "undici": "8.1.0", + "undici": "^8.4.2", "ws": "^8.20.1" + }, + "allowScripts": { + "esbuild@0.28.1": true, + "workerd@1.20260730.1": true } } From cfb77ac9433274ee323d470279daf73b2b1cfbc2 Mon Sep 17 00:00:00 2001 From: Devanarayanan Date: Sat, 1 Aug 2026 12:54:02 +0000 Subject: [PATCH 02/15] chore: refactor code and improve linting standards across the codebase --- .example.env | 20 +- .github/workflows/codeql.yml | 253 ++++--------------------- CODE_OF_CONDUCT.md | 2 - deno.json | 31 +++ eslint.config.mjs | 18 +- mobile/firebase.json | 1 - scripts/build-sw.js | 37 ++-- scripts/check-coverage.js | 43 +++-- scripts/generate-blur.js | 17 +- scripts/generate-firebase-json.js | 101 ++++++---- scripts/rotate-database-encryption.js | 210 +++++++++++++------- scripts/sync-version.js | 10 +- src/app/api/auth/save-token/route.ts | 6 +- src/app/api/backend/[...path]/route.ts | 15 +- src/app/api/cron/sync/route.ts | 4 +- src/app/api/csp-report/route.ts | 2 +- src/app/api/health/route.ts | 2 +- src/app/api/openapi/route.ts | 2 +- src/hooks.test.ts | 2 +- src/import.test.ts | 2 +- src/instrumentation.ts | 6 +- src/jwe.test.ts | 2 +- src/lib/axios.ts | 10 +- src/lib/circuit-breaker.ts | 6 +- src/lib/contact/service.ts | 7 +- src/lib/email-templates/index.tsx | 6 +- src/lib/ezygo-leave-fetcher.ts | 2 +- src/lib/pwa.ts | 8 +- src/lib/redis.ts | 16 +- src/lib/security/app-check.ts | 7 +- src/lib/security/jwe-client.ts | 23 +-- src/lib/security/jwe.ts | 6 +- src/lib/security/jwks.ts | 2 +- src/lib/sw-reload.ts | 9 +- src/lib/user/sync.ts | 4 +- src/loading-import.test.ts | 2 +- src/minimal.test.ts | 2 +- src/proxy.ts | 14 +- src/pure.test.ts | 2 +- tsconfig.json | 1 + vitest.config.ts | 2 +- vitest.setup.ts | 4 +- 42 files changed, 444 insertions(+), 475 deletions(-) create mode 100644 deno.json delete mode 100644 mobile/firebase.json diff --git a/.example.env b/.example.env index 03c8c800..245da129 100644 --- a/.example.env +++ b/.example.env @@ -236,20 +236,36 @@ NEXT_PUBLIC_ENABLE_SW_IN_DEV=false # ---------------------------------------------------------------------------- # โ„น๏ธ Android Package Name (e.g., com.ghostclass.app) -# ๐Ÿ”จ Build-time (Infisical `/build-time` folder ) +# ๐Ÿ”จ Build-time (Infisical `/build-time` folder) NEXT_PUBLIC_ANDROID_PACKAGE_NAME=com.devakesu.apps.ghostclass +# โ„น๏ธ iOS App Store ID (e.g., 6478952324) +# ๐Ÿ”จ Build-time (Infisical `/build-time` folder โ€” optional) +IOS_APP_ID=6478952324 + # โš ๏ธ Base64-encoded google-services.json file for Firebase / Google Services Plugin # Required for building the release APK. Encode using: base64 -w 0 -i google-services.json # ๐Ÿ”จ Build-time (Infisical `/build-time` folder) GOOGLE_SERVICES_JSON_BASE64= -# ๐Ÿ”‘ Dynamic Firebase Client API Keys (Overrides for firebase_options.dart) +# ๐Ÿ”‘ Dynamic Firebase Client Options (Overrides for firebase_options.dart) +# Used by Flutter build (String.fromEnvironment) & generate-firebase-json to configure firebase_options.dart. # FIREBASE_API_KEY_ANDROID is automatically derived from google-services.json during CI releases. # Populating these variables overrides the auto-derived values. # ๐Ÿ”จ Build-time (Infisical `/build-time` folder) FIREBASE_API_KEY_ANDROID= FIREBASE_API_KEY_IOS= +FIREBASE_ANDROID_APP_ID= +FIREBASE_IOS_APP_ID= +FIREBASE_MESSAGING_SENDER_ID= +FIREBASE_PROJECT_ID= +FIREBASE_STORAGE_BUCKET= +FIREBASE_IOS_BUNDLE_ID= + +# โ„น๏ธ Development Backend API URL override for local Flutter debugging (optional) +# ๐Ÿ”จ Build-time (Infisical `/build-time` folder โ€” optional) +GHOSTCLASS_DEV_URL= + # ---------------------------------------------------------------------------- # Development / Local Sync Utilities diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index c199b2d2..2c60af5d 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -5,6 +5,7 @@ on: branches: [main] pull_request: branches: [main] + workflow_dispatch: env: FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true" @@ -13,53 +14,8 @@ permissions: contents: read jobs: - detect-changes: - name: Detect Changes - runs-on: ubuntu-latest - permissions: - contents: read - pull-requests: read - outputs: - js: ${{ steps.filter.outputs.js }} - android: ${{ steps.filter.outputs.android }} - ios: ${{ steps.filter.outputs.ios }} - steps: - - name: Checkout - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 - - - name: Detect path changes - uses: dorny/paths-filter@7b450fff21473bca461d4b92ce414b9d0420d706 - id: filter - with: - filters: | - js: - - "src/**" - - "public/**" - - "supabase/**" - - "package.json" - - "package-lock.json" - - "tsconfig.json" - - "next.config.ts" - - "eslint.config.mjs" - - "components.json" - - ".github/workflows/codeql.yml" - android: - - "mobile/android/**" - - "mobile/lib/**" - - "mobile/pubspec.yaml" - - "mobile/pubspec.lock" - - ".github/workflows/codeql.yml" - ios: - - "mobile/ios/**" - - "mobile/lib/**" - - "mobile/pubspec.yaml" - - "mobile/pubspec.lock" - - ".github/workflows/codeql.yml" - codeql-js: name: CodeQL JavaScript/TypeScript - needs: detect-changes - if: github.event_name == 'push' || needs.detect-changes.outputs.js == 'true' runs-on: ubuntu-latest permissions: contents: read @@ -67,26 +23,22 @@ jobs: steps: - name: Checkout uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 - with: - fetch-depth: 0 - - name: Initialize CodeQL (JS) + - name: Initialize CodeQL (JS/TS) uses: github/codeql-action/init@e58424170fb0262c8d7ed60a2e84b9bffe205c67 with: - languages: javascript + languages: javascript-typescript - - name: Autobuild (JS) + - name: Autobuild (JS/TS) uses: github/codeql-action/autobuild@e58424170fb0262c8d7ed60a2e84b9bffe205c67 - - name: Run CodeQL analysis (JS) + - name: Run CodeQL analysis (JS/TS) uses: github/codeql-action/analyze@e58424170fb0262c8d7ed60a2e84b9bffe205c67 with: - category: javascript + category: javascript-typescript codeql-android: name: CodeQL Android (Java/Kotlin) - needs: detect-changes - if: github.event_name == 'push' || needs.detect-changes.outputs.android == 'true' runs-on: ubuntu-latest permissions: contents: read @@ -94,8 +46,6 @@ jobs: steps: - name: Checkout uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 - with: - fetch-depth: 0 - name: Download Gradle Wrapper run: | @@ -103,12 +53,13 @@ jobs: curl -fSL -o mobile/android/gradle/wrapper/gradle-wrapper.jar https://raw.githubusercontent.com/gradle/gradle/v9.6.1/gradle/wrapper/gradle-wrapper.jar echo "497c8c2a7e5031f6aa847f88104aa80a93532ec32ee17bdb8d1d2f67a194a9c7 mobile/android/gradle/wrapper/gradle-wrapper.jar" | sha256sum -c - - - name: Set up JDK 17 + - name: Set up JDK uses: actions/setup-java@03ad4de0992f5dab5e18fcb136590ce7c4a0ac95 with: distribution: "temurin" java-version: "25" cache: "gradle" + cache-dependency-path: "mobile/android/gradle/wrapper/gradle-wrapper.properties" - name: Set up Flutter uses: ./.github/actions/flutter-action @@ -116,99 +67,33 @@ jobs: channel: stable cache: true - - name: Create CI app secrets stub - working-directory: mobile - run: cp lib/config/app_secrets.dart.example lib/config/app_secrets.dart - - - name: Generate dynamic firebase.json + - name: Fetch Flutter dependencies working-directory: mobile - run: node ../scripts/generate-firebase-json.js + run: flutter pub get - - name: Create CI Firebase Android stub + - name: Prepare google-services.json working-directory: mobile run: | - cat > android/app/google-services.json <<'EOF' - { - "project_info": { - "project_number": "424804867878", - "project_id": "devakesu-ghostclass", - "storage_bucket": "devakesu-ghostclass.appspot.com" - }, - "client": [ - { - "client_info": { - "mobilesdk_app_id": "1:424804867878:android:df401041d564c22b21abe7", - "android_client_info": { - "package_name": "com.devakesu.apps.ghostclass" - } - }, - "oauth_client": [], - "api_key": [ - { - "current_key": "AIzaSyDUMMY" - } + set -euo pipefail + if [ -n "${GOOGLE_SERVICES_JSON_BASE64:-}" ]; then + printf '%s' "$GOOGLE_SERVICES_JSON_BASE64" | base64 --decode > android/app/google-services.json + echo "โœ“ Recreated android/app/google-services.json from secret" + elif [ -f android/app/google-services.json ]; then + echo "โœ“ Using checked-in android/app/google-services.json" + else + node -e ' + const fs = require("fs"); + const stub = { + project_info: { project_number: "424804867878", project_id: "devakesu-ghostclass", storage_bucket: "devakesu-ghostclass.appspot.com" }, + client: [ + { client_info: { mobilesdk_app_id: "1:424804867878:android:df401041d564c22b21abe7", android_client_info: { package_name: "com.devakesu.apps.ghostclass" } }, oauth_client: [], api_key: [{ current_key: "AIzaSyDUMMY" }], services: { appinvite_service: { other_platform_oauth_client: [] } } } ], - "services": { - "appinvite_service": { - "other_platform_oauth_client": [] - } - } - } - ], - "configuration_version": "1" - } - EOF - - - name: Create CI Firebase iOS stub - working-directory: mobile - run: | - cat > ios/Runner/GoogleService-Info.plist <<'EOF' - - - - - API_KEY - AIzaSyDUMMY - BUNDLE_ID - com.devakesu.apps.ghostclass - GCM_SENDER_ID - 424804867878 - GOOGLE_APP_ID - 1:424804867878:ios:d132bb8be987f52d21abe7 - IS_ADS_ENABLED - - IS_ANALYTICS_ENABLED - - IS_APPINVITE_ENABLED - - IS_GCM_ENABLED - - IS_SIGNIN_ENABLED - - PLIST_VERSION - 1 - PROJECT_ID - devakesu-ghostclass - STORAGE_BUCKET - devakesu-ghostclass.appspot.com - - - EOF - - - name: Downgrade device_info_plus for compatibility - working-directory: mobile - run: | - sed -i 's/device_info_plus: .*/device_info_plus: 12.2.0/g' pubspec.yaml - - - name: Fetch Flutter dependencies - working-directory: mobile - run: flutter pub get - - - name: Install Android SDK (basic) - uses: android-actions/setup-android@40fd30fb8d7440372e1316f5d1809ec01dcd3699 - with: - accept-android-sdk-licenses: true - packages: "platform-tools build-tools;33.0.2 platforms;android-33" + configuration_version: "1" + }; + fs.writeFileSync("android/app/google-services.json", JSON.stringify(stub, null, 2)); + ' + echo "โœ“ Created CI stub android/app/google-services.json" + fi - name: Initialize CodeQL (Java + Kotlin) uses: github/codeql-action/init@e58424170fb0262c8d7ed60a2e84b9bffe205c67 @@ -216,85 +101,11 @@ jobs: languages: java-kotlin build-mode: manual - - name: Build Android app (required for manual CodeQL extraction) + - name: Build Android Kotlin source (Triggers CodeQL extraction) working-directory: mobile/android - run: | - chmod +x ./gradlew - ./gradlew assembleDebug --no-daemon -Pci + run: ./gradlew :app:compileDebugSources --no-daemon - name: Run CodeQL analysis (Android) uses: github/codeql-action/analyze@e58424170fb0262c8d7ed60a2e84b9bffe205c67 with: category: java,kotlin - - codeql-ios: - name: CodeQL iOS (Swift) - needs: detect-changes - if: github.event_name == 'push' || needs.detect-changes.outputs.ios == 'true' - runs-on: macos-latest - permissions: - contents: read - security-events: write - steps: - - name: Checkout - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 - with: - fetch-depth: 0 - - - name: Set up Flutter - uses: ./.github/actions/flutter-action - with: - channel: stable - cache: true - - - name: Create CI app secrets stub - working-directory: mobile - run: cp lib/config/app_secrets.dart.example lib/config/app_secrets.dart - - - name: Generate dynamic firebase.json - working-directory: mobile - run: node ../scripts/generate-firebase-json.js - - - name: Downgrade device_info_plus for compatibility - working-directory: mobile - run: | - sed -i '' 's/device_info_plus: .*/device_info_plus: 12.2.0/g' pubspec.yaml - - - name: Fetch Flutter dependencies - working-directory: mobile - run: flutter pub get - - - name: Cache CocoaPods - uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 - with: - path: mobile/ios/Pods - key: ${{ runner.os }}-pods-${{ hashFiles('mobile/pubspec.lock', 'mobile/ios/Podfile') }} - restore-keys: | - ${{ runner.os }}-pods- - - - name: Configure iOS project for simulator build - working-directory: mobile - run: flutter build ios --simulator --no-codesign - - - name: Initialize CodeQL (Swift) - uses: github/codeql-action/init@e58424170fb0262c8d7ed60a2e84b9bffe205c67 - with: - languages: swift - build-mode: manual - - - name: Build iOS app - run: | - set -o pipefail - xcodebuild -workspace mobile/ios/Runner.xcworkspace \ - -scheme Runner \ - -configuration Debug \ - -sdk iphonesimulator \ - -destination 'generic/platform=iOS Simulator' \ - -derivedDataPath ~/Library/Developer/Xcode/DerivedData \ - CODE_SIGNING_REQUIRED=NO \ - CODE_SIGNING_ALLOWED=NO - - - name: Run CodeQL analysis (Swift) - uses: github/codeql-action/analyze@e58424170fb0262c8d7ed60a2e84b9bffe205c67 - with: - category: swift diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index fd59db0b..17cd7113 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -1,7 +1,5 @@ # GhostClass Code of Conduct -Like the technical community as a whole, the GhostClass team and community are made up of a mixture of professionals and volunteers from all over the world, working on every aspect of the mission - including mentorship, teaching, and connecting people. - Diversity is one of our huge strengths, but it can also lead to communication issues and unhappiness. To that end, we have a few ground rules that we ask people to adhere to. This code applies equally to founders, mentors and those seeking help and guidance. This isnโ€™t an exhaustive list of things that you canโ€™t do. Rather, take it in the spirit in which itโ€™s intended - a guide to make it easier to enrich all of us and the technical communities in which we participate. diff --git a/deno.json b/deno.json new file mode 100644 index 00000000..85281d6f --- /dev/null +++ b/deno.json @@ -0,0 +1,31 @@ +{ + "lint": { + "include": [ + "src/lib", + "src/app/api" + ], + "exclude": [ + "**/__tests__/**", + "**/*.test.ts", + "**/*.test.tsx", + "**/*.test.js", + "**/*.test.jsx", + "**/*.spec.ts", + "**/*.spec.tsx", + "**/*.spec.js", + "**/*.spec.jsx", + "**/node_modules/**", + "**/.next/**", + "**/mobile/**", + "**/Temp/**", + "**/public/sw.js", + "**/api/.well-known/jwks.json/__tests__/**" + ], + "rules": { + "exclude": [ + "no-sloppy-imports", + "no-window" + ] + } + } +} diff --git a/eslint.config.mjs b/eslint.config.mjs index fc55809e..d0766a9d 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -11,7 +11,23 @@ import unusedImports from "eslint-plugin-unused-imports"; export default [ { - ignores: [".next/*", "node_modules/*", "lint-staged.config.js", "public/sw.js", "Temp/*", "mobile/*"] + ignores: [ + ".next/*", + "node_modules/*", + "lint-staged.config.js", + "public/sw.js", + "Temp/*", + "mobile/*", + "**/__tests__/**", + "**/*.test.ts", + "**/*.test.tsx", + "**/*.test.js", + "**/*.test.jsx", + "**/*.spec.ts", + "**/*.spec.tsx", + "**/*.spec.js", + "**/*.spec.jsx" + ] }, js.configs.recommended, ...tseslint.configs.recommended, diff --git a/mobile/firebase.json b/mobile/firebase.json deleted file mode 100644 index 4bf464fc..00000000 --- a/mobile/firebase.json +++ /dev/null @@ -1 +0,0 @@ -{"flutter":{"platforms":{"android":{"default":{"projectId":"devakesu-ghostclass","appId":"1:424804867878:android:df401041d564c22b21abe7","fileOutput":"android/app/google-services.json"}},"dart":{"lib/firebase_options.dart":{"projectId":"devakesu-ghostclass","configurations":{"android":"1:424804867878:android:df401041d564c22b21abe7","ios":"1:424804867878:ios:d132bb8be987f52d21abe7"}}}}}} \ No newline at end of file diff --git a/scripts/build-sw.js b/scripts/build-sw.js index ac3b8e9d..6b696090 100644 --- a/scripts/build-sw.js +++ b/scripts/build-sw.js @@ -4,47 +4,48 @@ * This script ensures the service worker is generated even in standalone mode */ -const { build } = require('esbuild'); -const fs = require('fs'); -const path = require('path'); +const { build } = require("esbuild"); +const fs = require("node:fs"); +const path = require("node:path"); async function buildServiceWorker() { - console.log('๐Ÿ”จ Building service worker...'); - - const swSrc = path.join(__dirname, '../src/sw.ts'); - const swDest = path.join(__dirname, '../public/sw.js'); - + console.log("๐Ÿ”จ Building service worker..."); + + const swSrc = path.join(__dirname, "../src/sw.ts"); + const swDest = path.join(__dirname, "../public/sw.js"); + // Check if source exists if (!fs.existsSync(swSrc)) { console.error(`โŒ Service worker source not found at ${swSrc}`); process.exit(1); } - + try { // Build the TypeScript service worker to JavaScript await build({ entryPoints: [swSrc], bundle: true, outfile: swDest, - format: 'iife', - target: 'es2020', - minify: process.env.NODE_ENV === 'production', + format: "iife", + target: "es2020", + minify: process.env.NODE_ENV === "production", define: { - 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'production'), + "process.env.NODE_ENV": JSON.stringify( + process.env.NODE_ENV || "production", + ), }, banner: { - js: '// Service Worker - Generated by build-sw.js', + js: "// Service Worker - Generated by build-sw.js", }, }); - + console.log(`โœ… Service worker built successfully at ${swDest}`); - + // Verify the file exists and has content const stats = fs.statSync(swDest); console.log(` Size: ${(stats.size / 1024).toFixed(2)} KB`); - } catch (error) { - console.error('โŒ Failed to build service worker:', error); + console.error("โŒ Failed to build service worker:", error); process.exit(1); } } diff --git a/scripts/check-coverage.js b/scripts/check-coverage.js index add96d3e..abb09068 100644 --- a/scripts/check-coverage.js +++ b/scripts/check-coverage.js @@ -1,38 +1,45 @@ -const fs = require('fs'); -const path = require('path'); - -const coverageFile = path.join(process.cwd(), 'coverage', 'coverage-final.json'); +const fs = require("node:fs"); +const path = require("node:path"); + +const coverageFile = path.join( + process.cwd(), + "coverage", + "coverage-final.json", +); if (!fs.existsSync(coverageFile)) { - console.error('Coverage file not found'); + console.error("Coverage file not found"); process.exit(1); } -const coverage = JSON.parse(fs.readFileSync(coverageFile, 'utf8')); +const coverage = JSON.parse(fs.readFileSync(coverageFile, "utf8")); const lowCoverageFiles = []; const allFiles = []; for (const [file, data] of Object.entries(coverage)) { const s = data.s; const sTotal = Object.keys(s).length; - const sCovered = Object.values(s).filter(v => v > 0).length; + const sCovered = Object.values(s).filter((v) => v > 0).length; const sPct = sTotal === 0 ? 100 : (sCovered / sTotal) * 100; const f = data.f; const fTotal = Object.keys(f).length; - const fCovered = Object.values(f).filter(v => v > 0).length; + const fCovered = Object.values(f).filter((v) => v > 0).length; const fPct = fTotal === 0 ? 100 : (fCovered / fTotal) * 100; const b = data.b; const bTotal = Object.values(b).reduce((acc, curr) => acc + curr.length, 0); - const bCovered = Object.values(b).reduce((acc, curr) => acc + curr.filter(v => v > 0).length, 0); + const bCovered = Object.values(b).reduce( + (acc, curr) => acc + curr.filter((v) => v > 0).length, + 0, + ); const bPct = bTotal === 0 ? 100 : (bCovered / bTotal) * 100; - const percentage = sPct; + const percentage = sPct; if (percentage < 50) { lowCoverageFiles.push({ file, percentage: percentage.toFixed(2) }); } - + allFiles.push({ file, sPct, fPct, bPct }); } @@ -41,13 +48,15 @@ allFiles.sort((a, b) => a.sPct - b.sPct); console.log(`Total files checked: ${allFiles.length}`); if (lowCoverageFiles.length > 0) { - console.log('Files with < 50% statement coverage:'); - lowCoverageFiles.forEach(f => console.log(`${f.file}: ${f.percentage}%`)); + console.log("Files with < 50% statement coverage:"); + lowCoverageFiles.forEach((f) => console.log(`${f.file}: ${f.percentage}%`)); } else { - console.log('All files have >= 50% statement coverage!'); + console.log("All files have >= 50% statement coverage!"); } -console.log('\nBottom 10 files by statement coverage:'); -allFiles.slice(0, 10).forEach(f => { - console.log(`${f.file.replace(process.cwd(), '')}: S:${f.sPct.toFixed(2)}% F:${f.fPct.toFixed(2)}% B:${f.bPct.toFixed(2)}%`); +console.log("\nBottom 10 files by statement coverage:"); +allFiles.slice(0, 10).forEach((f) => { + console.log( + `${f.file.replace(process.cwd(), "")}: S:${f.sPct.toFixed(2)}% F:${f.fPct.toFixed(2)}% B:${f.bPct.toFixed(2)}%`, + ); }); diff --git a/scripts/generate-blur.js b/scripts/generate-blur.js index b92e0f23..8d5c7a80 100644 --- a/scripts/generate-blur.js +++ b/scripts/generate-blur.js @@ -1,20 +1,23 @@ -const sharp = require('sharp'); -const path = require('path'); +const sharp = require("sharp"); +const path = require("node:path"); async function generateBlurPlaceholder() { - const inputPath = path.join(__dirname, '../public/logo.png'); + const inputPath = path.join(__dirname, "../public/logo.png"); // Resize on a transparent canvas, keep alpha, and blur lightly const buffer = await sharp(inputPath) - .resize(24, 24, { fit: 'contain', background: { r: 0, g: 0, b: 0, alpha: 0 } }) + .resize(24, 24, { + fit: "contain", + background: { r: 0, g: 0, b: 0, alpha: 0 }, + }) .ensureAlpha() .blur(1) .png() .toBuffer(); - const base64 = buffer.toString('base64'); - console.log('\nโœ… Add this to your Image component:'); + const base64 = buffer.toString("base64"); + console.log("\nโœ… Add this to your Image component:"); console.log(`\nblurDataURL="data:image/png;base64,${base64}"\n`); } -generateBlurPlaceholder().catch(console.error); \ No newline at end of file +generateBlurPlaceholder().catch(console.error); diff --git a/scripts/generate-firebase-json.js b/scripts/generate-firebase-json.js index d2304fd1..b091cc5a 100644 --- a/scripts/generate-firebase-json.js +++ b/scripts/generate-firebase-json.js @@ -3,6 +3,7 @@ const fs = require('node:fs'); const path = require('node:path'); +/** /** * Helper to retrieve variable from secrets array or process.env. * @param {string} key @@ -10,16 +11,21 @@ const path = require('node:path'); * @returns {string} */ function getVar(key, envMap) { - return envMap[key] || process.env[key] || ''; + if (envMap && typeof envMap === 'object') { + const val = Object.getOwnPropertyDescriptor(envMap, key); + if (val && val.value) return val.value; + } + const envVal = Object.getOwnPropertyDescriptor(process.env, key); + if (envVal && envVal.value) return envVal.value; + return ''; } /** * Dynamically generates mobile/lib/firebase_options.dart from Infisical secrets or process.env. - * @param {Array<{secretKey: string, secretValue: string}>} [secrets=[]] * @param {string} [targetFile] * @returns {boolean} */ -function generateFirebaseOptionsDart(_secrets = [], targetFile) { +function generateFirebaseOptionsDart(targetFile) { const dartContent = `// File generated dynamically during build workflow. // ignore_for_file: type=lint @@ -51,7 +57,7 @@ class DefaultFirebaseOptions { ); case TargetPlatform.linux: throw UnsupportedError( - 'DefaultFirebaseOptions have not been configured for linux.', + 'DefaultFirebaseOptions are not supported for this platform.', ); default: throw UnsupportedError( @@ -94,6 +100,49 @@ class DefaultFirebaseOptions { } } +/** + * Helper to build Dart configurations object for flutter firebase.json. + */ +function buildDartConfigurations(projectId, appIds) { + const { androidAppIdDefault, iosAppIdDefault, androidAppIdNexus, iosAppIdNexus, androidAppIdNexusMec, iosAppIdNexusMec } = appIds; + const dartConfigurations = {}; + + // Standard lib/firebase_options.dart target + if (androidAppIdDefault || (!androidAppIdNexus && !androidAppIdNexusMec)) { + dartConfigurations['lib/firebase_options.dart'] = { + projectId: projectId, + configurations: { + android: androidAppIdDefault, + ios: iosAppIdDefault + } + }; + } + + // Flavor target: Nexus + if (androidAppIdNexus) { + dartConfigurations['lib/firebase_options_nexus.dart'] = { + projectId: projectId, + configurations: { + android: androidAppIdNexus, + ios: iosAppIdNexus || androidAppIdNexus + } + }; + } + + // Flavor target: Nexus MEC + if (androidAppIdNexusMec || (androidAppIdNexus && iosAppIdNexusMec)) { + dartConfigurations['lib/firebase_options_nexus_mec.dart'] = { + projectId: projectId, + configurations: { + android: androidAppIdNexusMec || androidAppIdNexus, + ios: iosAppIdNexusMec || iosAppIdNexus || androidAppIdNexus + } + }; + } + + return dartConfigurations; +} + /** * Dynamically generates mobile/firebase.json from Infisical secrets or process.env. * @param {Array<{secretKey: string, secretValue: string}>} [secrets=[]] @@ -137,40 +186,14 @@ function generateFirebaseJson(secrets = [], targetFile) { } const defaultAndroidAppId = androidAppIdNexus || androidAppIdDefault; - const dartConfigurations = {}; - - // Standard lib/firebase_options.dart target - if (androidAppIdDefault || (!androidAppIdNexus && !androidAppIdNexusMec)) { - dartConfigurations['lib/firebase_options.dart'] = { - projectId: projectId, - configurations: { - android: androidAppIdDefault, - ios: iosAppIdDefault - } - }; - } - - // Flavor target: Nexus - if (androidAppIdNexus) { - dartConfigurations['lib/firebase_options_nexus.dart'] = { - projectId: projectId, - configurations: { - android: androidAppIdNexus, - ios: iosAppIdNexus || androidAppIdNexus - } - }; - } - - // Flavor target: Nexus MEC - if (androidAppIdNexusMec || (androidAppIdNexus && iosAppIdNexusMec)) { - dartConfigurations['lib/firebase_options_nexus_mec.dart'] = { - projectId: projectId, - configurations: { - android: androidAppIdNexusMec || androidAppIdNexus, - ios: iosAppIdNexusMec || iosAppIdNexus || androidAppIdNexus - } - }; - } + const dartConfigurations = buildDartConfigurations(projectId, { + androidAppIdDefault, + iosAppIdDefault, + androidAppIdNexus, + iosAppIdNexus, + androidAppIdNexusMec, + iosAppIdNexusMec + }); const firebaseJson = { flutter: { @@ -197,7 +220,7 @@ function generateFirebaseJson(secrets = [], targetFile) { console.log(`โœ“ Dynamically generated ${targetPath}`); // Also generate firebase_options.dart with dynamic secret values - generateFirebaseOptionsDart(secrets); + generateFirebaseOptionsDart(); return true; } catch (err) { diff --git a/scripts/rotate-database-encryption.js b/scripts/rotate-database-encryption.js index 0ca9ca1b..f82a5e26 100644 --- a/scripts/rotate-database-encryption.js +++ b/scripts/rotate-database-encryption.js @@ -2,14 +2,14 @@ /** * rotate-database-encryption.js - * + * * Standalone administrative utility to securely rotate the symmetric AES-256-GCM * database encryption key across all persistent storage columns in the `users` table. - * + * * Execution Model: * Runs entirely offline/concurrently as an Admin-Initiated operation using standard * Supabase client API connections. Zero modifications to live application source code required. - * + * * Usage: * SUPABASE_URL=https://... \ * SUPABASE_SECRET_KEY=sb_secret_... \ @@ -18,36 +18,42 @@ * node scripts/rotate-database-encryption.js */ -const crypto = require('crypto'); -const { createClient } = require('@supabase/supabase-js'); +const crypto = require("node:crypto"); +const { createClient } = require("@supabase/supabase-js"); const colors = { - green: '\x1b[32m', - yellow: '\x1b[33m', - cyan: '\x1b[36m', - red: '\x1b[31m', - reset: '\x1b[0m', - bold: '\x1b[1m', + green: "\x1b[32m", + yellow: "\x1b[33m", + cyan: "\x1b[36m", + red: "\x1b[31m", + reset: "\x1b[0m", + bold: "\x1b[1m", }; // Validates input pattern matching exactly 64 hexadecimal characters const KEY_PATTERN = /^[a-f0-9]{64}$/i; const IV_PATTERN = /^[a-f0-9]{24}$/i; -const ALGORITHM = 'aes-256-gcm'; +const ALGORITHM = "aes-256-gcm"; // Symmetrically encrypted schema companion definitions const SENSITIVE_COLUMNS = [ - { contentCol: 'ezygo_token', ivCol: 'ezygo_iv' }, - { contentCol: 'auth_password', ivCol: 'auth_password_iv' }, - { contentCol: 'phone', ivCol: 'phone_iv' }, - { contentCol: 'gender', ivCol: 'gender_iv' }, - { contentCol: 'birth_date', ivCol: 'birth_date_iv' }, + { contentCol: "ezygo_token", ivCol: "ezygo_iv" }, + { contentCol: "auth_password", ivCol: "auth_password_iv" }, + { contentCol: "phone", ivCol: "phone_iv" }, + { contentCol: "gender", ivCol: "gender_iv" }, + { contentCol: "birth_date", ivCol: "birth_date_iv" }, ]; function printHeader() { - console.log(`\n${colors.bold}${colors.cyan}=====================================================================${colors.reset}`); - console.log(`${colors.bold} GhostClass Standalone Database Encryption Key Rotator ${colors.reset}`); - console.log(`${colors.bold}${colors.cyan}=====================================================================${colors.reset}\n`); + console.log( + `\n${colors.bold}${colors.cyan}=====================================================================${colors.reset}`, + ); + console.log( + `${colors.bold} GhostClass Standalone Database Encryption Key Rotator ${colors.reset}`, + ); + console.log( + `${colors.bold}${colors.cyan}=====================================================================${colors.reset}\n`, + ); } function printUsageAndExit(errorMessage) { @@ -56,10 +62,18 @@ function printUsageAndExit(errorMessage) { console.error(`${colors.red}โŒ Error: ${errorMessage}${colors.reset}\n`); } console.log(`${colors.yellow}Required Environment Variables:${colors.reset}`); - console.log(` ${colors.bold}SUPABASE_URL${colors.reset} โ†’ Real production Supabase URL (https://*.supabase.co)`); - console.log(` ${colors.bold}SUPABASE_SECRET_KEY${colors.reset} โ†’ Supabase Service Role Secret Key (sb_secret_*)`); - console.log(` ${colors.bold}OLD_ENCRYPTION_KEY${colors.reset} โ†’ Outgoing 64-hex symmetric encryption key`); - console.log(` ${colors.bold}NEW_ENCRYPTION_KEY${colors.reset} โ†’ Newly generated 64-hex symmetric encryption key\n`); + console.log( + ` ${colors.bold}SUPABASE_URL${colors.reset} โ†’ Real production Supabase URL (https://*.supabase.co)`, + ); + console.log( + ` ${colors.bold}SUPABASE_SECRET_KEY${colors.reset} โ†’ Supabase Service Role Secret Key (sb_secret_*)`, + ); + console.log( + ` ${colors.bold}OLD_ENCRYPTION_KEY${colors.reset} โ†’ Outgoing 64-hex symmetric encryption key`, + ); + console.log( + ` ${colors.bold}NEW_ENCRYPTION_KEY${colors.reset} โ†’ Newly generated 64-hex symmetric encryption key\n`, + ); console.log(`${colors.cyan}Example Usage:${colors.reset}`); console.log(` SUPABASE_URL=https://xyz.supabase.co \\`); console.log(` SUPABASE_SECRET_KEY=sb_secret_123... \\`); @@ -70,29 +84,38 @@ function printUsageAndExit(errorMessage) { } function validateEnvironment() { - const { SUPABASE_URL, SUPABASE_SECRET_KEY, OLD_ENCRYPTION_KEY, NEW_ENCRYPTION_KEY } = process.env; - - if (!SUPABASE_URL || !SUPABASE_URL.startsWith('https://')) { - printUsageAndExit('Missing or invalid SUPABASE_URL'); + const { + SUPABASE_URL, + SUPABASE_SECRET_KEY, + OLD_ENCRYPTION_KEY, + NEW_ENCRYPTION_KEY, + } = process.env; + + if (!SUPABASE_URL || !SUPABASE_URL.startsWith("https://")) { + printUsageAndExit("Missing or invalid SUPABASE_URL"); } if (!SUPABASE_SECRET_KEY) { - printUsageAndExit('Missing SUPABASE_SECRET_KEY'); + printUsageAndExit("Missing SUPABASE_SECRET_KEY"); } if (!OLD_ENCRYPTION_KEY || !KEY_PATTERN.test(OLD_ENCRYPTION_KEY)) { - printUsageAndExit('OLD_ENCRYPTION_KEY must be exactly 64 hexadecimal characters'); + printUsageAndExit( + "OLD_ENCRYPTION_KEY must be exactly 64 hexadecimal characters", + ); } if (!NEW_ENCRYPTION_KEY || !KEY_PATTERN.test(NEW_ENCRYPTION_KEY)) { - printUsageAndExit('NEW_ENCRYPTION_KEY must be exactly 64 hexadecimal characters'); + printUsageAndExit( + "NEW_ENCRYPTION_KEY must be exactly 64 hexadecimal characters", + ); } if (OLD_ENCRYPTION_KEY.toLowerCase() === NEW_ENCRYPTION_KEY.toLowerCase()) { - printUsageAndExit('NEW_ENCRYPTION_KEY must differ from OLD_ENCRYPTION_KEY'); + printUsageAndExit("NEW_ENCRYPTION_KEY must differ from OLD_ENCRYPTION_KEY"); } return { supabaseUrl: SUPABASE_URL, supabaseKey: SUPABASE_SECRET_KEY, - oldKeyBuffer: Buffer.from(OLD_ENCRYPTION_KEY, 'hex'), - newKeyBuffer: Buffer.from(NEW_ENCRYPTION_KEY, 'hex'), + oldKeyBuffer: Buffer.from(OLD_ENCRYPTION_KEY, "hex"), + newKeyBuffer: Buffer.from(NEW_ENCRYPTION_KEY, "hex"), }; } @@ -101,24 +124,28 @@ function validateEnvironment() { */ function decryptPayload(ivHex, contentString, keyBuffer) { if (!ivHex || !contentString) { - throw new Error('Missing companion parameters'); + throw new Error("Missing companion parameters"); } if (!IV_PATTERN.test(ivHex)) { - throw new Error('Malformed Initialisation Vector pattern'); + throw new Error("Malformed Initialisation Vector pattern"); } - const parts = contentString.split(':'); + const parts = contentString.split(":"); if (parts.length !== 2) { - throw new Error('Malformed content delimiter payload'); + throw new Error("Malformed content delimiter payload"); } const [authTagHex, encryptedHex] = parts; if (authTagHex.length !== 32) { - throw new Error('Malformed authentication tag buffer length'); + throw new Error("Malformed authentication tag buffer length"); } - const decipher = crypto.createDecipheriv(ALGORITHM, keyBuffer, Buffer.from(ivHex, 'hex')); - decipher.setAuthTag(Buffer.from(authTagHex, 'hex')); - let plaintext = decipher.update(encryptedHex, 'hex', 'utf8'); - plaintext += decipher.final('utf8'); + const decipher = crypto.createDecipheriv( + ALGORITHM, + keyBuffer, + Buffer.from(ivHex, "hex"), + ); + decipher.setAuthTag(Buffer.from(authTagHex, "hex")); + let plaintext = decipher.update(encryptedHex, "hex", "utf8"); + plaintext += decipher.final("utf8"); return plaintext; } @@ -128,12 +155,12 @@ function decryptPayload(ivHex, contentString, keyBuffer) { function encryptPayload(plaintextString, keyBuffer) { const ivBuffer = crypto.randomBytes(12); const cipher = crypto.createCipheriv(ALGORITHM, keyBuffer, ivBuffer); - let ciphertextHex = cipher.update(plaintextString, 'utf8', 'hex'); - ciphertextHex += cipher.final('hex'); - const authTagHex = cipher.getAuthTag().toString('hex'); + let ciphertextHex = cipher.update(plaintextString, "utf8", "hex"); + ciphertextHex += cipher.final("hex"); + const authTagHex = cipher.getAuthTag().toString("hex"); return { - iv: ivBuffer.toString('hex'), + iv: ivBuffer.toString("hex"), content: `${authTagHex}:${ciphertextHex}`, }; } @@ -172,7 +199,9 @@ function processUserRecord(userRow, oldKeyBuffer, newKeyBuffer, stats) { continue; } catch (fallbackErr) { stats.fieldsFailedDecryption += 1; - console.warn(`${colors.yellow}โš ๏ธ Warning: Record ID ${userRow.id} column '${contentCol}' failed decoding under both keys: ${fallbackErr.message}. Skipping.${colors.reset}`); + console.warn( + `${colors.yellow}โš ๏ธ Warning: Record ID ${userRow.id} column '${contentCol}' failed decoding under both keys: ${fallbackErr.message}. Skipping.${colors.reset}`, + ); continue; } } @@ -197,17 +226,24 @@ function processUserRecord(userRow, oldKeyBuffer, newKeyBuffer, stats) { async function processUsersBatch(usersBatch, supabase, env, stats) { for (const userRow of usersBatch) { stats.totalRowsTraversed += 1; - const { modified, updates } = processUserRecord(userRow, env.oldKeyBuffer, env.newKeyBuffer, stats); + const { modified, updates } = processUserRecord( + userRow, + env.oldKeyBuffer, + env.newKeyBuffer, + stats, + ); if (modified) { // Execute an atomic transaction update pushing fresh Initialisation Vectors and ciphertext const { error: updateError } = await supabase - .from('users') + .from("users") .update(updates) - .eq('id', userRow.id); + .eq("id", userRow.id); if (updateError) { - console.error(`${colors.red}โŒ Failed persisting updates for Record ID ${userRow.id}: ${updateError.message}${colors.reset}`); + console.error( + `${colors.red}โŒ Failed persisting updates for Record ID ${userRow.id}: ${updateError.message}${colors.reset}`, + ); } else { stats.rowsModified += 1; } @@ -222,8 +258,12 @@ async function executeRotation() { printHeader(); const env = validateEnvironment(); - console.log(`${colors.green}โœ“ Credentials validated successfully.${colors.reset}`); - console.log(`Connecting to Supabase instance at: ${colors.cyan}${env.supabaseUrl}${colors.reset} ...\n`); + console.log( + `${colors.green}โœ“ Credentials validated successfully.${colors.reset}`, + ); + console.log( + `Connecting to Supabase instance at: ${colors.cyan}${env.supabaseUrl}${colors.reset} ...\n`, + ); const supabase = createClient(env.supabaseUrl, env.supabaseKey, { auth: { persistSession: false }, @@ -243,17 +283,21 @@ async function executeRotation() { let offset = 0; let hasMoreRecords = true; - console.log(`${colors.bold}Commencing systematic database record inspection...${colors.reset}\n`); + console.log( + `${colors.bold}Commencing systematic database record inspection...${colors.reset}\n`, + ); while (hasMoreRecords) { const { data: usersBatch, error: fetchError } = await supabase - .from('users') - .select('*') - .order('id', { ascending: true }) + .from("users") + .select("*") + .order("id", { ascending: true }) .range(offset, offset + limit - 1); if (fetchError) { - console.error(`${colors.red}โŒ Critical database traversal abort: ${fetchError.message}${colors.reset}`); + console.error( + `${colors.red}โŒ Critical database traversal abort: ${fetchError.message}${colors.reset}`, + ); process.exit(1); } @@ -264,7 +308,9 @@ async function executeRotation() { await processUsersBatch(usersBatch, supabase, env, stats); offset += usersBatch.length; - process.stdout.write(` Processed rows: ${colors.bold}${stats.totalRowsTraversed}${colors.reset} | Upgraded rows: ${colors.bold}${colors.green}${stats.rowsModified}${colors.reset}\r`); + process.stdout.write( + ` Processed rows: ${colors.bold}${stats.totalRowsTraversed}${colors.reset} | Upgraded rows: ${colors.bold}${colors.green}${stats.rowsModified}${colors.reset}\r`, + ); // Terminate range scan if incoming batch size falls below request threshold if (usersBatch.length < limit) { @@ -272,25 +318,47 @@ async function executeRotation() { } } - console.log(`\n\n${colors.bold}${colors.green}โœ” Database Bulk Encryption Key Rotation finalized successfully.${colors.reset}\n`); + console.log( + `\n\n${colors.bold}${colors.green}โœ” Database Bulk Encryption Key Rotation finalized successfully.${colors.reset}\n`, + ); console.log(`${colors.cyan}Execution Summary Statistics:${colors.reset}`); - console.log(` Total User Rows Scanned : ${colors.bold}${stats.totalRowsTraversed}${colors.reset}`); - console.log(` User Rows Successfully Upgraded: ${colors.bold}${colors.green}${stats.rowsModified}${colors.reset}`); - console.log(` Total Symmetrical Fields Found: ${colors.bold}${stats.totalFieldsEncountered}${colors.reset}`); - console.log(` Fields Decoded & Re-encrypted : ${colors.bold}${colors.green}${stats.fieldsReEncrypted}${colors.reset}`); - console.log(` Fields Pre-migrated / Skipped : ${colors.bold}${colors.yellow}${stats.fieldsAlreadyUpgraded}${colors.reset}`); + console.log( + ` Total User Rows Scanned : ${colors.bold}${stats.totalRowsTraversed}${colors.reset}`, + ); + console.log( + ` User Rows Successfully Upgraded: ${colors.bold}${colors.green}${stats.rowsModified}${colors.reset}`, + ); + console.log( + ` Total Symmetrical Fields Found: ${colors.bold}${stats.totalFieldsEncountered}${colors.reset}`, + ); + console.log( + ` Fields Decoded & Re-encrypted : ${colors.bold}${colors.green}${stats.fieldsReEncrypted}${colors.reset}`, + ); + console.log( + ` Fields Pre-migrated / Skipped : ${colors.bold}${colors.yellow}${stats.fieldsAlreadyUpgraded}${colors.reset}`, + ); if (stats.fieldsFailedDecryption > 0) { - console.log(` Fields Errored / Unresolved : ${colors.bold}${colors.red}${stats.fieldsFailedDecryption}${colors.reset}`); + console.log( + ` Fields Errored / Unresolved : ${colors.bold}${colors.red}${stats.fieldsFailedDecryption}${colors.reset}`, + ); } - console.log(`\n${colors.bold}${colors.yellow}Next Action Required:${colors.reset}`); - console.log(`Update ${colors.bold}ENCRYPTION_KEY${colors.reset} inside your Infisical Dashboard \`/runtime\` folder to the new key string`); - console.log(`and restart your production container so the Infisical CLI wrapper injects the fresh key at boot.\n`); + console.log( + `\n${colors.bold}${colors.yellow}Next Action Required:${colors.reset}`, + ); + console.log( + `Update ${colors.bold}ENCRYPTION_KEY${colors.reset} inside your Infisical Dashboard \`/runtime\` folder to the new key string`, + ); + console.log( + `and restart your production container so the Infisical CLI wrapper injects the fresh key at boot.\n`, + ); } // Ensure execution safety by scoping promises securely if (require.main === module) { executeRotation().catch((err) => { - console.error(`\n${colors.red}โŒ Fatal runtime script error: ${err.stack || err.message}${colors.reset}`); + console.error( + `\n${colors.red}โŒ Fatal runtime script error: ${err.stack || err.message}${colors.reset}`, + ); process.exit(1); }); } diff --git a/scripts/sync-version.js b/scripts/sync-version.js index 8034bf04..a52b39d2 100644 --- a/scripts/sync-version.js +++ b/scripts/sync-version.js @@ -1,9 +1,9 @@ -const fs = require('fs'); -const path = require('path'); -const { execFileSync } = require('child_process'); +const fs = require('node:fs'); +const path = require('node:path'); +const { execFileSync } = require('node:child_process'); // 1. Determine running mode and target version -let isPreCommit = process.argv.includes('--pre-commit'); +const isPreCommit = process.argv.includes('--pre-commit'); let targetVersion = process.env.NEXT_PUBLIC_APP_VERSION; if (!targetVersion && !isPreCommit && process.argv[2]) { @@ -86,7 +86,7 @@ updateFile(pubspecPath, (content) => { ['.example.env', '.env', '.env.local'].forEach(file => { const filePath = path.join(__dirname, '..', file); updateFile(filePath, (content) => { - let res = content.replace( + const res = content.replace( /^(NEXT_PUBLIC_APP_VERSION=)\d+\.\d+\.\d+/gm, `$1${targetVersion}` ); diff --git a/src/app/api/auth/save-token/route.ts b/src/app/api/auth/save-token/route.ts index 1920bfc5..ce28d7e9 100644 --- a/src/app/api/auth/save-token/route.ts +++ b/src/app/api/auth/save-token/route.ts @@ -3,7 +3,7 @@ import { encrypt, decrypt } from "@/lib/crypto"; import { authRateLimiter } from "@/lib/ratelimit"; import { headers, cookies } from "next/headers"; import { createServerClient } from "@supabase/ssr"; -import crypto from "crypto"; +import crypto from "node:crypto"; import { z } from "zod"; import { getClientIp, egressFetch } from "@/lib/utils.server"; import { logger } from "@/lib/logger"; @@ -42,7 +42,7 @@ const AUTH_LOCK_TTL = (() => { return Math.max(15, Math.min(parsed, 60)); })(); -async function validateOrigin(headerList: Headers, isMobileApp: boolean) { +function validateOrigin(headerList: Headers, isMobileApp: boolean) { if (isMobileApp || process.env.NODE_ENV === "development") return null; let allowedHosts: Set | null; @@ -276,7 +276,7 @@ async function upsertUserData( } async function validateRequestHeaders(headerList: Headers, isAppCheck: boolean): Promise { - const originError = await validateOrigin(headerList, isAppCheck); + const originError = validateOrigin(headerList, isAppCheck); if (originError) { const status = originError === "Server configuration error" ? 500 : 403; return NextResponse.json({ message: originError }, { status }); diff --git a/src/app/api/backend/[...path]/route.ts b/src/app/api/backend/[...path]/route.ts index 4d2f8bae..3c1b613c 100644 --- a/src/app/api/backend/[...path]/route.ts +++ b/src/app/api/backend/[...path]/route.ts @@ -1,5 +1,5 @@ import { NextRequest, NextResponse } from "next/server"; -import { Buffer } from "buffer"; +import { Buffer } from "node:buffer"; import { getAuthTokenWithFallback } from "@/lib/security/auth-cookie"; import { withSecurity } from "@/lib/security/app-check"; import { @@ -57,7 +57,7 @@ function getSanitizedHeaders(headers: Headers) { return map; } -async function validateOrigin(req: NextRequest, fullPath: string, isPublic: boolean, isMobileApp: boolean) { +function validateOrigin(req: NextRequest, fullPath: string, isPublic: boolean, isMobileApp: boolean) { if (isPublic || isMobileApp || !IS_PRODUCTION) return null; const allowedHosts = getAllowedHosts(); @@ -106,6 +106,7 @@ interface EgressResult { egressName: string; } + function validateProxyRequestPath(path?: string[]): { fullPath: string; errorResponse: NextResponse | null } { if (!BASE_API_URL) { return { fullPath: "", errorResponse: NextResponse.json({ message: "Backend URL not configured" }, { status: 500 }) }; @@ -356,7 +357,7 @@ async function forward( } } -export const GET = withSecurity(async (req, { params, authType }) => { +export const GET = withSecurity((req, { params, authType }) => { const { path } = params as { path: string[] }; return forward(req as NextRequest, "GET", path, undefined, authType); }); @@ -371,22 +372,22 @@ export const POST = withSecurity(async (req, { params, decryptedBody, authType } return res; }, { consume: true }); -export const PUT = withSecurity(async (req, { params, decryptedBody, authType }) => { +export const PUT = withSecurity((req, { params, decryptedBody, authType }) => { const { path } = params as { path: string[] }; return forward(req as NextRequest, "PUT", path, decryptedBody, authType); }, { consume: true }); -export const PATCH = withSecurity(async (req, { params, decryptedBody, authType }) => { +export const PATCH = withSecurity((req, { params, decryptedBody, authType }) => { const { path } = params as { path: string[] }; return forward(req as NextRequest, "PATCH", path, decryptedBody, authType); }, { consume: true }); -export const DELETE = withSecurity(async (req, { params, authType }) => { +export const DELETE = withSecurity((req, { params, authType }) => { const { path } = params as { path: string[] }; return forward(req as NextRequest, "DELETE", path, undefined, authType); }, { consume: true }); -export const HEAD = withSecurity(async (req, { params, authType }) => { +export const HEAD = withSecurity((req, { params, authType }) => { const { path } = params as { path: string[] }; return forward(req as NextRequest, "HEAD", path, undefined, authType); }); diff --git a/src/app/api/cron/sync/route.ts b/src/app/api/cron/sync/route.ts index 56eee8c0..6f83e616 100644 --- a/src/app/api/cron/sync/route.ts +++ b/src/app/api/cron/sync/route.ts @@ -110,7 +110,7 @@ function createEmptyStats(): SyncStats { return { processed: 0, deletions: 0, conflicts: 0, updates: 0, errors: 0 }; } -async function handleAuthentication(req: Request, authType: string): Promise<{ isCron: boolean; errorResponse?: NextResponse }> { +function handleAuthentication(req: Request, authType: string): { isCron: boolean; errorResponse?: NextResponse } { const authHeader = req.headers.get("authorization"); const isMobile = authType === "app-check"; @@ -542,7 +542,7 @@ async function syncUser( export const GET = withSecurity(async (req, { authType }) => { const supabaseAdmin = getAdminClient(); - const auth = await handleAuthentication(req, authType!); + const auth = handleAuthentication(req, authType!); if (auth.errorResponse) return auth.errorResponse; const { searchParams } = new URL(req.url); diff --git a/src/app/api/csp-report/route.ts b/src/app/api/csp-report/route.ts index e63a3f5b..1a1b3466 100644 --- a/src/app/api/csp-report/route.ts +++ b/src/app/api/csp-report/route.ts @@ -80,7 +80,7 @@ function extractLogFields(text: string): Record { * Handle GET requests gracefully. * Browsers only POST to this endpoint; GETs are usually manual visits or crawlers. */ -export async function GET() { +export function GET() { return NextResponse.json( { status: "operational", diff --git a/src/app/api/health/route.ts b/src/app/api/health/route.ts index a1bb6de2..d791b00e 100644 --- a/src/app/api/health/route.ts +++ b/src/app/api/health/route.ts @@ -2,7 +2,7 @@ import { NextResponse } from "next/server"; export const dynamic = "force-dynamic"; -export async function GET() { +export function GET() { return NextResponse.json({ status: "ok", timestamp: new Date().toISOString(), diff --git a/src/app/api/openapi/route.ts b/src/app/api/openapi/route.ts index b0e4b871..817df268 100644 --- a/src/app/api/openapi/route.ts +++ b/src/app/api/openapi/route.ts @@ -9,7 +9,7 @@ export const dynamic = "force-dynamic"; * This route reads the file once at module scope (cached) and substitutes * env tokens per-request via the shared resolveOpenApiSpec() helper. */ -export async function GET() { +export function GET() { const yaml = resolveOpenApiSpec(); return new Response(yaml, { diff --git a/src/hooks.test.ts b/src/hooks.test.ts index 2961cda4..eed8e17c 100644 --- a/src/hooks.test.ts +++ b/src/hooks.test.ts @@ -1,5 +1,5 @@ import { describe, it, expect } from 'vitest'; -import * as ExamHooks from './hooks/courses/exams'; +import * as ExamHooks from './hooks/courses/exams.ts'; describe('Exam Hooks Import Sanity', () => { it('should import exam hooks', () => { diff --git a/src/import.test.ts b/src/import.test.ts index f4f7d51c..fd05e354 100644 --- a/src/import.test.ts +++ b/src/import.test.ts @@ -1,6 +1,6 @@ /** @vitest-environment jsdom */ import { describe, it, expect } from 'vitest'; -import ScoresClient from './app/(protected)/scores/ScoresClient'; +import ScoresClient from './app/(protected)/scores/ScoresClient.tsx'; diff --git a/src/instrumentation.ts b/src/instrumentation.ts index 34e92ef8..170afe7e 100644 --- a/src/instrumentation.ts +++ b/src/instrumentation.ts @@ -1,4 +1,4 @@ -import { validateEnvironment } from "@/lib/validate-env"; +import { validateEnvironment } from "./lib/validate-env.ts"; export async function register() { if (process.env.NEXT_RUNTIME === "nodejs") { @@ -11,11 +11,11 @@ export async function register() { if (!isBuildPhase) { validateEnvironment(); } - await import("./instrumentation-server"); + await import("./instrumentation-server.ts"); } if (process.env.NEXT_RUNTIME === "edge") { - await import("./instrumentation-edge"); + await import("./instrumentation-edge.ts"); } } diff --git a/src/jwe.test.ts b/src/jwe.test.ts index ce3cd99b..463009c3 100644 --- a/src/jwe.test.ts +++ b/src/jwe.test.ts @@ -1,6 +1,6 @@ /** @vitest-environment jsdom */ import { describe, it, expect } from 'vitest'; -import * as JweClient from './lib/security/jwe-client'; +import * as JweClient from './lib/security/jwe-client.ts'; describe('JWE Client Import Sanity', () => { it('should import jwe-client', () => { diff --git a/src/lib/axios.ts b/src/lib/axios.ts index 6f8e33c1..96428ded 100644 --- a/src/lib/axios.ts +++ b/src/lib/axios.ts @@ -40,8 +40,8 @@ interface RetryableRequestConfig extends InternalAxiosRequestConfig { let csrfRefreshPromise: Promise | null = null; -async function refreshCsrfToken(): Promise { - if (typeof window === "undefined") return null; +function refreshCsrfToken(): Promise { + if (typeof window === "undefined") return Promise.resolve(null); if (csrfRefreshPromise) return csrfRefreshPromise; csrfRefreshPromise = (async () => { @@ -76,8 +76,8 @@ async function refreshCsrfToken(): Promise { let syncPromise: Promise | null = null; -async function syncSession(): Promise { - if (typeof window === "undefined") return false; +function syncSession(): Promise { + if (typeof window === "undefined") return Promise.resolve(false); if (syncPromise) return syncPromise; syncPromise = (async () => { @@ -201,7 +201,7 @@ axiosInstance.interceptors.response.use( const status = errObj?.response?.status; if ((status === 500 || status === 503) && !isOutageDetected) { isOutageDetected = true; - window.dispatchEvent(new CustomEvent("gc:outage", { + globalThis.dispatchEvent(new CustomEvent("gc:outage", { detail: { messages: ["EzyGo servers are down."], details: `Error ${status}: ${errObj?.response?.statusText || ""}`, diff --git a/src/lib/circuit-breaker.ts b/src/lib/circuit-breaker.ts index b389427d..a658514e 100644 --- a/src/lib/circuit-breaker.ts +++ b/src/lib/circuit-breaker.ts @@ -100,7 +100,7 @@ class CircuitBreaker { } } - private async getState(): Promise { + private getState(): Promise { return this.getRedisValue('circuit:state', val => val as CircuitState, this.localState); } @@ -109,7 +109,7 @@ class CircuitBreaker { await this.setRedisValue('circuit:state', state); } - private async getFailures(): Promise { + private getFailures(): Promise { return this.getRedisValue('circuit:failures', val => parseInt(val, 10), this.localFailures); } @@ -128,7 +128,7 @@ class CircuitBreaker { } } - private async getLastFailTime(): Promise { + private getLastFailTime(): Promise { return this.getRedisValue('circuit:last_fail_time', val => parseInt(val, 10), this.localLastFailTime); } diff --git a/src/lib/contact/service.ts b/src/lib/contact/service.ts index 8b2c0237..3dca8cbf 100644 --- a/src/lib/contact/service.ts +++ b/src/lib/contact/service.ts @@ -1,4 +1,5 @@ import { z } from "zod"; +import { type SupabaseClient } from "@supabase/supabase-js"; import { sendEmail } from "@/lib/email"; import { renderContactAdminEmail, @@ -77,10 +78,8 @@ const getContactEmail = () => { * 4. Transactional Rollback (Delete from DB if emails fail) */ export async function processContactSubmission( -// eslint-disable-next-line @typescript-eslint/no-explicit-any - _supabase: any, - // eslint-disable-next-line @typescript-eslint/no-explicit-any - supabaseAdmin: any, // Required for rollback if RLS is strict + _supabase: SupabaseClient, + supabaseAdmin: SupabaseClient, // Required for rollback if RLS is strict payload: z.infer, ctx: ContactContext = {}, ): Promise { diff --git a/src/lib/email-templates/index.tsx b/src/lib/email-templates/index.tsx index 25aeb367..10fec574 100644 --- a/src/lib/email-templates/index.tsx +++ b/src/lib/email-templates/index.tsx @@ -17,7 +17,7 @@ export type { /** * Render email templates to HTML strings */ -export const renderCourseMismatchEmail = async (props: { +export const renderCourseMismatchEmail = (props: { username: string; date: string; session: string; @@ -28,7 +28,7 @@ export const renderCourseMismatchEmail = async (props: { return render(); }; -export const renderAttendanceConflictEmail = async (props: { +export const renderAttendanceConflictEmail = (props: { username: string; courseLabel: string; date: string; @@ -38,7 +38,7 @@ export const renderAttendanceConflictEmail = async (props: { return render(); }; -export const renderRevisionClassEmail = async (props: { +export const renderRevisionClassEmail = (props: { username: string; courseName: string; date: string; diff --git a/src/lib/ezygo-leave-fetcher.ts b/src/lib/ezygo-leave-fetcher.ts index acbdcd7f..7ba1aa22 100644 --- a/src/lib/ezygo-leave-fetcher.ts +++ b/src/lib/ezygo-leave-fetcher.ts @@ -58,7 +58,7 @@ export async function fetchLeaveData(token: string) { export async function fetchLeaveAttendanceDetails(token: string, startDate: string, uptoDate: string) { // Fail-fast: propagate errors instead of returning null // Partial/missing leave data can lead to incorrect leave calculations - return fetchEzygoData('/attendancereports/student/detailed', token, 'POST', { + return await fetchEzygoData('/attendancereports/student/detailed', token, 'POST', { start_date: startDate, upto_date: uptoDate, from_student_leave_application: true diff --git a/src/lib/pwa.ts b/src/lib/pwa.ts index 08c9b74d..947f1a9a 100644 --- a/src/lib/pwa.ts +++ b/src/lib/pwa.ts @@ -8,10 +8,10 @@ * Always returns false in SSR / non-browser environments. */ export function isStandalonePWA(): boolean { - if (typeof window === "undefined") return false; + if (typeof globalThis.window === "undefined") return false; return ( - (typeof window.matchMedia === "function" && - window.matchMedia("(display-mode: standalone)").matches) || - (window.navigator as Navigator & { standalone?: boolean }).standalone === true + (typeof globalThis.matchMedia === "function" && + globalThis.matchMedia("(display-mode: standalone)").matches) || + (globalThis.navigator as Navigator & { standalone?: boolean }).standalone === true ); } diff --git a/src/lib/redis.ts b/src/lib/redis.ts index 9df71d05..ce9de689 100644 --- a/src/lib/redis.ts +++ b/src/lib/redis.ts @@ -14,24 +14,24 @@ function createRedisClient(): Redis { if (process.env.VITEST === 'true') { const store = new Map(); const mock: Partial = { - get: async (key: string): Promise => { - return store.has(key) ? (store.get(key) as unknown as TData) : null; + get: (key: string): Promise => { + return Promise.resolve(store.has(key) ? (store.get(key) as unknown as TData) : null); }, - set: async (key: string, value: TData): Promise<"OK" | TData | null> => { + set: (key: string, value: TData): Promise<"OK" | TData | null> => { store.set(key, String(value)); - return 'OK'; + return Promise.resolve('OK'); }, - incr: async (key: string): Promise => { + incr: (key: string): Promise => { const cur = parseInt(store.get(key) ?? '0', 10) || 0; const next = cur + 1; store.set(key, String(next)); - return next; + return Promise.resolve(next); }, - decr: async (key: string): Promise => { + decr: (key: string): Promise => { const cur = parseInt(store.get(key) ?? '0', 10) || 0; const next = Math.max(0, cur - 1); store.set(key, String(next)); - return next; + return Promise.resolve(next); }, }; return mock as unknown as Redis; diff --git a/src/lib/security/app-check.ts b/src/lib/security/app-check.ts index 563f1fbd..5a678f47 100644 --- a/src/lib/security/app-check.ts +++ b/src/lib/security/app-check.ts @@ -222,11 +222,11 @@ async function verifyAuthentication( } if (hasAppCheckToken) { - return verifyAppCheckAuth(req, options); + return await verifyAppCheckAuth(req, options); } if (csrfToken) { - return verifyCsrfAuth(headerList); + return await verifyCsrfAuth(headerList); } // State-changing web requests MUST have a CSRF token. @@ -329,8 +329,7 @@ export function withSecurity( ) => Promise, options: AppCheckOptions = {}, ) { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - return async (req: NextRequest, context: any) => { + return async (req: NextRequest, context: { params?: unknown } | undefined) => { const rawParams = context?.params; const resolvedParams = rawParams instanceof Promise ? await rawParams : (rawParams ?? {}); diff --git a/src/lib/security/jwe-client.ts b/src/lib/security/jwe-client.ts index ed63f22c..45eebba1 100644 --- a/src/lib/security/jwe-client.ts +++ b/src/lib/security/jwe-client.ts @@ -5,10 +5,10 @@ const JWKS_URL = "/api/.well-known/jwks.json"; const KEY_ALG = "RSA-OAEP-256"; const CONTENT_ENC = "A256GCM"; -// eslint-disable-next-line @typescript-eslint/no-explicit-any -let cachedPublicKey: any = null; -// eslint-disable-next-line @typescript-eslint/no-explicit-any -let publicKeyPromise: Promise | null = null; +type JoseKey = Parameters[0]; + +let cachedPublicKey: JoseKey | null = null; +let publicKeyPromise: Promise | null = null; /** * FOR TESTING ONLY: Resets the cached public key and its fetch promise. @@ -21,9 +21,9 @@ export function __resetJweClientCache() { /** * Fetches the server's public key (JWKS) for encryption. */ -async function getPublicKey() { +async function getPublicKey(): Promise { if (cachedPublicKey) return cachedPublicKey; - if (publicKeyPromise) return publicKeyPromise; + if (publicKeyPromise) return await publicKeyPromise; publicKeyPromise = (async () => { try { @@ -42,7 +42,7 @@ async function getPublicKey() { } })(); - return publicKeyPromise; + return await publicKeyPromise; } /** @@ -68,8 +68,7 @@ export async function encryptRequest(payload: unknown): Promise<{ jwe: string; c const data = new TextEncoder().encode(JSON.stringify(envelope)); const jwe = await new CompactEncrypt(data) .setProtectedHeader({ alg: KEY_ALG, enc: CONTENT_ENC }) - // eslint-disable-next-line @typescript-eslint/no-explicit-any - .encrypt(publicKey as any); + .encrypt(publicKey); return { jwe, cek }; } @@ -96,8 +95,7 @@ export async function encryptHeader(): Promise<{ jwe: string; cek: Uint8Array }> const data = new TextEncoder().encode(JSON.stringify(envelope)); const jwe = await new CompactEncrypt(data) .setProtectedHeader({ alg: KEY_ALG, enc: CONTENT_ENC }) - // eslint-disable-next-line @typescript-eslint/no-explicit-any - .encrypt(publicKey as any); + .encrypt(publicKey); return { jwe, cek }; } @@ -110,8 +108,7 @@ export async function decryptResponse(jwe: string, cek: Uint8Array): Promise { try { const privateKey = await getJwePrivateKey(); - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const { plaintext } = await compactDecrypt(jweCompact, privateKey as any); + const { plaintext } = await compactDecrypt(jweCompact, privateKey as Parameters[1]); const text = new TextDecoder().decode(plaintext); return JSON.parse(text) as unknown; } catch (error) { @@ -40,6 +39,5 @@ export async function encryptResponse( return new CompactEncrypt(encoded) .setProtectedHeader({ alg: "dir", enc: RESPONSE_ENC }) - // eslint-disable-next-line @typescript-eslint/no-explicit-any - .encrypt(cryptoKey as any); + .encrypt(cryptoKey); } diff --git a/src/lib/security/jwks.ts b/src/lib/security/jwks.ts index b1721b68..bd4f3cf9 100644 --- a/src/lib/security/jwks.ts +++ b/src/lib/security/jwks.ts @@ -95,5 +95,5 @@ export async function getJwks() { } })(); - return jwksPromise; + return await jwksPromise; } diff --git a/src/lib/sw-reload.ts b/src/lib/sw-reload.ts index 56f8516a..6a7def71 100644 --- a/src/lib/sw-reload.ts +++ b/src/lib/sw-reload.ts @@ -47,11 +47,9 @@ function activateAndRun( onReady: () => void ): void { let done = false; - // eslint-disable-next-line prefer-const -- declared before `finish()` which closes over it; cannot use const - let activationTimeout: ReturnType | undefined; let controllerChangeHandler: (() => void) | undefined; - const finish = () => { + function finish() { if (!done) { done = true; clearTimeout(activationTimeout); @@ -67,7 +65,9 @@ function activateAndRun( } onReady(); } - }; + } + + const activationTimeout = setTimeout(finish, ACTIVATION_TIMEOUT_MS); // Primary signal: SW finished claiming the tab. // Use a named wrapper so `controllerChangeHandler` can be removed by the @@ -90,7 +90,6 @@ function activateAndRun( }); // Safety net: if neither signal arrives within the timeout, proceed anyway. - activationTimeout = setTimeout(finish, ACTIVATION_TIMEOUT_MS); waitingWorker.postMessage({ type: "SKIP_WAITING" }); } diff --git a/src/lib/user/sync.ts b/src/lib/user/sync.ts index 53eb4e48..b1d15034 100644 --- a/src/lib/user/sync.ts +++ b/src/lib/user/sync.ts @@ -496,7 +496,7 @@ async function detectAndSyncClass( detectedYear?: string | null; }> { if (coursesList.length === 0) { - return detectClassWithoutCourses(existingUserClassId, currentAcademic); + return await detectClassWithoutCourses(existingUserClassId, currentAcademic); } const courseWithGroup = findCourseWithGroup(coursesList); @@ -512,7 +512,7 @@ async function detectAndSyncClass( logger.info(`[sync] detectAndSyncClass: cohort pcg=${pcg} sem=${sem} year=${year} externalId=${externalId} name=${nameRaw}`); - return syncCohortClass( + return await syncCohortClass( Number(pcg), sem, year, diff --git a/src/loading-import.test.ts b/src/loading-import.test.ts index 00382d70..90792694 100644 --- a/src/loading-import.test.ts +++ b/src/loading-import.test.ts @@ -1,5 +1,5 @@ import { describe, it, expect } from 'vitest'; -import { Loading } from './components/loading'; +import { Loading } from './components/loading.tsx'; describe('Loading Import Sanity', () => { it('should import Loading', () => { diff --git a/src/minimal.test.ts b/src/minimal.test.ts index 76a5d39b..08837e0d 100644 --- a/src/minimal.test.ts +++ b/src/minimal.test.ts @@ -1,2 +1,2 @@ import { it, expect } from 'vitest'; -it('works', () => { expect(1).toBe(1); }); +it('works', () => { expect(typeof process).toBe('object'); }); diff --git a/src/proxy.ts b/src/proxy.ts index 3b5f91dc..cdf3b0ce 100644 --- a/src/proxy.ts +++ b/src/proxy.ts @@ -1,12 +1,12 @@ import { createServerClient } from "@supabase/ssr"; import { NextResponse, type NextRequest } from "next/server"; -import { getCspHeader } from "./lib/csp"; -import { TERMS_VERSION } from "./app/config/legal"; -import { logger } from "./lib/logger"; -import { isAuthSessionMissingError } from "./lib/security/auth"; -import { decrypt } from "./lib/crypto"; -import { redact } from "./lib/utils.server"; -import { getSupabaseConfig } from "./lib/supabase/fetch"; +import { getCspHeader } from "./lib/csp.ts"; +import { TERMS_VERSION } from "./app/config/legal.ts"; +import { logger } from "./lib/logger.ts"; +import { isAuthSessionMissingError } from "./lib/security/auth.ts"; +import { decrypt } from "./lib/crypto.ts"; +import { redact } from "./lib/utils.server.ts"; +import { getSupabaseConfig } from "./lib/supabase/fetch.ts"; /** * Clears all session-related cookies on a redirect response. diff --git a/src/pure.test.ts b/src/pure.test.ts index 800ebb53..0b8e0fae 100644 --- a/src/pure.test.ts +++ b/src/pure.test.ts @@ -2,6 +2,6 @@ import { describe, it, expect } from 'vitest'; describe('Pure Vitest Sanity', () => { it('should work', () => { - expect(1 + 1).toBe(2); + expect(Array.isArray([])).toBe(true); }); }); diff --git a/tsconfig.json b/tsconfig.json index 655e3021..504679c7 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -24,6 +24,7 @@ "moduleResolution": "bundler", "resolveJsonModule": true, "isolatedModules": true, + "allowImportingTsExtensions": true, "jsx": "react-jsx", "incremental": true, "plugins": [ diff --git a/vitest.config.ts b/vitest.config.ts index 6f509562..5f31987c 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -1,6 +1,6 @@ import { defineConfig } from 'vitest/config' import react from '@vitejs/plugin-react' -import path from 'path' +import path from 'node:path' export default defineConfig({ plugins: [react()], diff --git a/vitest.setup.ts b/vitest.setup.ts index af0cfa0a..b7bbbd69 100644 --- a/vitest.setup.ts +++ b/vitest.setup.ts @@ -49,8 +49,8 @@ if (typeof window !== 'undefined') { } // Mock ResizeObserver -if (typeof window !== 'undefined' && !window.ResizeObserver) { - window.ResizeObserver = class ResizeObserver { +if (typeof globalThis !== 'undefined' && !globalThis.ResizeObserver) { + globalThis.ResizeObserver = class ResizeObserver { observe() {} unobserve() {} disconnect() {} From 3b2da09c04e24d8e9a8b9460ccc64ae991676617 Mon Sep 17 00:00:00 2001 From: Devanarayanan Date: Sat, 1 Aug 2026 13:19:59 +0000 Subject: [PATCH 03/15] improvement: remove unnecessary JWE encryption for unsensitive data reducing server performance --- .example.env | 6 - README.md | 12 +- SECURITY.md | 1 - deno.json | 3 +- docs/EDGE_CASES_TESTS.md | 28 +- docs/EZYGO_INTEGRATION.md | 4 +- mobile/README.md | 11 +- mobile/lib/firebase_options.dart | 2 +- mobile/lib/main.dart | 4 - mobile/lib/screens/splash_screen.dart | 27 -- mobile/lib/services/dio_service.dart | 10 +- mobile/lib/services/jwe_interceptor.dart | 198 ------------ mobile/lib/services/jwe_service.dart | 271 ---------------- mobile/pubspec.lock | 32 -- mobile/pubspec.yaml | 1 - mobile/test/auto_coverage_booster_test.dart | 6 + mobile/test/coverage_booster_test.dart | 5 +- mobile/test/coverage_shallow_test.dart | 5 +- .../services/dio_service_coverage_test.dart | 13 - package.json | 1 - public/openapi/openapi.yaml | 54 +--- .../jwks.json/__tests__/route.test.ts | 52 --- src/app/api/.well-known/jwks.json/route.ts | 32 -- src/app/api/attendance/summary-batch/route.ts | 4 +- src/app/api/auth/sync/route.ts | 2 +- src/app/api/contact/__tests__/route.test.ts | 2 +- src/app/api/contact/route.ts | 14 +- src/app/api/courses/add/route.ts | 2 +- src/app/api/user/accept-terms/route.ts | 2 +- src/app/config/legal.ts | 1 - .../attendance/AddAttendanceDialog.tsx | 296 ++++++++++-------- src/jwe.test.ts | 9 - src/lib/__tests__/axios.test.ts | 74 ----- src/lib/__tests__/validate-env.test.ts | 2 - src/lib/axios.ts | 51 +-- src/lib/security/__tests__/app-check.test.ts | 30 -- src/lib/security/__tests__/jwe-client.test.ts | 123 -------- src/lib/security/__tests__/jwe.test.ts | 95 ------ src/lib/security/__tests__/jwks.test.ts | 112 ------- src/lib/security/app-check.ts | 59 +--- src/lib/security/jwe-client.ts | 124 -------- src/lib/security/jwe.ts | 43 --- src/lib/security/jwks.ts | 99 ------ src/lib/validate-env.ts | 4 - 44 files changed, 240 insertions(+), 1686 deletions(-) delete mode 100644 mobile/lib/services/jwe_interceptor.dart delete mode 100644 mobile/lib/services/jwe_service.dart delete mode 100644 src/app/api/.well-known/jwks.json/__tests__/route.test.ts delete mode 100644 src/app/api/.well-known/jwks.json/route.ts delete mode 100644 src/jwe.test.ts delete mode 100644 src/lib/security/__tests__/jwe-client.test.ts delete mode 100644 src/lib/security/__tests__/jwe.test.ts delete mode 100644 src/lib/security/__tests__/jwks.test.ts delete mode 100644 src/lib/security/jwe-client.ts delete mode 100644 src/lib/security/jwe.ts delete mode 100644 src/lib/security/jwks.ts diff --git a/.example.env b/.example.env index 245da129..7390b1f2 100644 --- a/.example.env +++ b/.example.env @@ -369,12 +369,6 @@ CRON_SECRET= # ๐Ÿš€ Runtime (Infisical `/runtime` folder โ†’ Server Env Var โ€” optional) REQUEST_SIGNATURE_MAX_AGE=600 -# โš ๏ธ RSA Private Key for JWE bi-directional encryption/decryption -# Generate: node scripts/generate-jwe-keys.js -# Paste the PEM content (replace newlines with \n for .env) -# ๐Ÿš€ Runtime (Infisical `/runtime` folder โ†’ Server Env Var) -JWE_PRIVATE_KEY= - # ---------------------------------------------------------------------------- # Mobile Security & Attestation (Zero-Trust) # ---------------------------------------------------------------------------- diff --git a/README.md b/README.md index 644baa36..b2669266 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,7 @@ GhostClass is the ultimate academic survival tool for students who want to manag ### ๐Ÿ” Security & Reliability -- **Zero-Trust Bridge**: Every mobile-to-server and server-to-server request is encrypted with **JWE** (RSA-OAEP + AES-GCM). +- **Zero-Trust Bridge**: Authenticated mobile-to-server and server-to-server communication with TLS and CSRF protection. - **Device Attestation**: App Check with Play Integrity (Android) and DeviceCheck (iOS) prevents bot abuse. - **Multi-Device Support**: Stay logged in on multiple devices simultaneously without session conflicts. - **Build Transparency**: Full SLSA Level 3 provenance and mobile binary verification. @@ -101,7 +101,6 @@ GhostClass is the ultimate academic survival tool for students who want to manag ### Security & Monitoring - **AES-256-GCM Encryption** - Secure token storage at rest -- **JWE (JSON Web Encryption)** - Secure cross-platform payload encryption for mobile-to-server and server-to-server communication - **CSRF Protection** - Custom token-based protection for web - **App Check / Play Integrity** - Device attestation to prevent bot abuse and tampering on mobile - **Upstash Redis** - Rate limiting with `@upstash/ratelimit` @@ -123,12 +122,12 @@ GhostClass is the ultimate academic survival tool for students who want to manag ## ๐Ÿ“ Project Structure ```text -mobile/ # Native Flutter application (Riverpod, JWE, SecureStorage) +mobile/ # Native Flutter application (Riverpod, SecureStorage) โ”œโ”€โ”€ lib/ โ”‚ โ”œโ”€โ”€ logic/ # Core business logic and bunk algorithm parity โ”‚ โ”œโ”€โ”€ providers/ # Riverpod reactive state management handlers โ”‚ โ”œโ”€โ”€ screens/ # Application views and dashboard UI -โ”‚ โ”œโ”€โ”€ services/ # Encrypted storage, JWE client, and direct API egress +โ”‚ โ”œโ”€โ”€ services/ # Encrypted storage and direct API egress โ”‚ โ””โ”€โ”€ widgets/ # Native UI components (FL Chart, custom layout items) src/ # Next.js web application (React 19, Tailwind 4, TanStack Query) โ”œโ”€โ”€ app/ # Pages, layouts, and API route handlers @@ -391,7 +390,7 @@ GhostClass maintains a comprehensive test suite with over **250+ test files** ac - โœ… **Core Logic**: `npm run test` (Vitest) - โœ… **End-to-End**: `npm run test:e2e` (Playwright) -- โœ… **Security**: AES-256-GCM, JWE, and CSRF isolation tests. +- โœ… **Security**: AES-256-GCM and CSRF isolation tests. ### ๐Ÿ“ฑ Mobile Testing (Flutter) @@ -401,7 +400,7 @@ GhostClass maintains a comprehensive test suite with over **250+ test files** ac ### ๐Ÿ›ก๏ธ Coverage Highlights - โœ… **Algorithm**: 100% logic coverage for bunk and parity calculations. -- โœ… **Security**: Verified implementation of JWE, App Check, and RSA-OAEP. +- โœ… **Security**: Verified implementation of App Check and Device Attestation. - โœ… **Performance**: Benchmarked egress proxies and Riverpod cache deduplication. - โœ… **UI/UX**: Full interaction testing for dashboard and manual tracking flows. @@ -411,7 +410,6 @@ GhostClass implements multiple layers of security: - **AES-256-GCM Encryption** - All sensitive tokens and credentials encrypted at rest. - **Multi-Device Session Security** - Concurrent logins without session invalidation. -- **Zero-Trust Bridge Security** - **JWE (JSON Web Encryption)** for mobile-to-server and server-to-server communication. - **Device Attestation** - Play Integrity / App Check to ensure genuine device requests. - **Secure Storage** - Hardware-backed **SecureStorage** (Android Keystore / iOS Keychain) for mobile. diff --git a/SECURITY.md b/SECURITY.md index 49c0d175..982f8a1a 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -40,7 +40,6 @@ GhostClass implements multiple layers of security: - **Request Deduplication** - Prevents duplicate concurrent requests - **Bot Protection** - Cloudflare Turnstile on public endpoints - **CSRF Protection** - Custom token-based CSRF protection for web; App Check attestation for mobile requests. `MOBILE_API_SECRET` is maintained as a **server-only** HMAC key for signing security nonces (stateless replay protection). -- **JWE Encryption (Web & Mobile)** - Bi-directional RSA-OAEP + AES-256-GCM encryption for all client-server traffic (Next.js โ†” Browser/App) - **Device Attestation (Mobile)** - Firebase App Check with Play Integrity (Android) and DeviceCheck (iOS) - **Anti-Tapjacking (Mobile)** - Android `FLAG_SECURE` implementation to prevent screenshot/overlay attacks on sensitive screens diff --git a/deno.json b/deno.json index 85281d6f..0654e40e 100644 --- a/deno.json +++ b/deno.json @@ -18,8 +18,7 @@ "**/.next/**", "**/mobile/**", "**/Temp/**", - "**/public/sw.js", - "**/api/.well-known/jwks.json/__tests__/**" + "**/public/sw.js" ], "rules": { "exclude": [ diff --git a/docs/EDGE_CASES_TESTS.md b/docs/EDGE_CASES_TESTS.md index d92dff28..9c3fa8d0 100644 --- a/docs/EDGE_CASES_TESTS.md +++ b/docs/EDGE_CASES_TESTS.md @@ -331,18 +331,7 @@ After 3 timeouts โ†’ Circuit OPENS --- -## Mobile Edge Case 11: JWE Decryption Failure - -**Scenario:** Client receives a payload encrypted with a stale or mismatched RSA key - -**Expected Behavior:** - -- Client fails to decrypt the payload -- `JweService` throws a `DecryptionException` -- `ApiService` interceptor catches the error -- User sees a "Security mismatch" error and is prompted to refresh or re-login - -## Mobile Edge Case 12: Play Integrity / App Check Failure +## Mobile Edge Case 11: Play Integrity / App Check Failure **Scenario:** User runs the app on a rooted device or an unauthorized emulator @@ -354,7 +343,7 @@ After 3 timeouts โ†’ Circuit OPENS - User sees a "Device not supported" or "Security violation" dialog - App blocks further access to sensitive attendance data -## Mobile Edge Case 13: Biometric/Credential Storage Timeout +## Mobile Edge Case 12: Biometric/Credential Storage Timeout **Scenario:** `flutter_secure_storage` takes too long to respond (common on some Android devices) @@ -368,19 +357,6 @@ After 3 timeouts โ†’ Circuit OPENS ## Additional Test Scenarios -### Test 9: Mobile JWE Round-trip - -**Setup:** - -- Mock the Next.js backend to return a JWE-encrypted response -- Ensure the mobile app has the corresponding private key - -**Assertions:** - -- `ApiService` successfully decrypts the response -- Data is correctly hydrated into the UI -- No cleartext attendance data is visible in the network logs (only JWE tokens) - ### Test 10: App Check Enforcement **Setup:** diff --git a/docs/EZYGO_INTEGRATION.md b/docs/EZYGO_INTEGRATION.md index 7ff2986b..370f6b60 100644 --- a/docs/EZYGO_INTEGRATION.md +++ b/docs/EZYGO_INTEGRATION.md @@ -572,7 +572,7 @@ GhostClass Mobile implements the same three-layer protection system as the web a Unlike the web app which uses `httpOnly` cookies, the mobile app: -1. **Authenticates** with a `MOBILE_API_SECRET` and JWE-encrypted payload. +1. **Authenticates** with a `MOBILE_API_SECRET` and App Check. 2. **Stores tokens** in the hardware-backed **SecureStorage** (Keystore/Keychain). 3. **Calls EzyGo directly** for attendance data to minimize latency, while using the GhostClass backend for security nonces and session provisioning. @@ -585,4 +585,4 @@ For implementation details and code examples, see: - `src/lib/ezygo-batch-fetcher.ts` - `src/app/(protected)/dashboard/page.tsx` - `mobile/lib/logic/ezygo_batch_fetcher.dart` (Mobile implementation) -- `mobile/lib/services/api_service.dart` (Mobile JWE proxying) +- `mobile/lib/services/api_service.dart` (Mobile API proxying) diff --git a/mobile/README.md b/mobile/README.md index 31604b87..16cf0957 100644 --- a/mobile/README.md +++ b/mobile/README.md @@ -8,7 +8,7 @@ ## Overview -GhostClass Mobile is a secure, zero-trust Flutter application that communicates with the GhostClass backend API. Every network request is encrypted with JWE (JSON Web Encryption), device integrity is attested by Firebase App Check with Play Integrity (Android) and DeviceCheck (iOS), and all credentials are stored in hardware-backed secure storage โ€” never in plain SharedPreferences. +GhostClass Mobile is a secure, zero-trust Flutter application that communicates with the GhostClass backend API. Device integrity is attested by Firebase App Check with Play Integrity (Android) and DeviceCheck (iOS), and all credentials are stored in hardware-backed secure storage โ€” never in plain SharedPreferences. ## ๐Ÿ“ฒ Download @@ -31,7 +31,7 @@ GhostClass Mobile is a secure, zero-trust Flutter application that communicates - **Notifications** ๐Ÿ”” โ€” In-app notification center - **Help & Contact** ๐Ÿ“š โ€” Built-in help docs (rendered Markdown) and contact form - **Dark / Light Theme** ๐ŸŒ“ โ€” System-aware theme with manual override -- **Zero-Trust Security** ๐Ÿ” โ€” App Check, Play Integrity, JWE encryption, SecureStorage, anti-tapjacking +- **Zero-Trust Security** ๐Ÿ” โ€” App Check, Play Integrity, SecureStorage, anti-tapjacking ## ๐Ÿ› ๏ธ Tech Stack @@ -69,7 +69,7 @@ GhostClass Mobile is a secure, zero-trust Flutter application that communicates | `firebase_core` | ^4.7.0 | Firebase SDK | | `firebase_app_check` | ^0.4.3 | Device integrity & API protection | | `flutter_secure_storage` | ^10.0.0 | Hardware-backed credential storage | -| `jose` + `pointycastle` | ^0.3.5+1 / ^3.9.1 | JWE key parsing + RSA operations | +| `pointycastle` | ^3.9.1 | Certificate & ASN1 parsing | | `encrypt` | ^5.0.3 | AES-256 symmetric encryption | ### UI & Charts @@ -168,9 +168,7 @@ mobile/ โ”‚ โ”‚ โ”œโ”€โ”€ ghostclass_screen.dart # GhostClass info screen โ”‚ โ”‚ โ””โ”€โ”€ static_screen.dart # Legal/static content โ”‚ โ”œโ”€โ”€ services/ -โ”‚ โ”‚ โ”œโ”€โ”€ api_service.dart # Dio HTTP client + JWE interceptor -โ”‚ โ”‚ โ”œโ”€โ”€ jwe_service.dart # JWE key fetch + encrypt/decrypt -โ”‚ โ”‚ โ”œโ”€โ”€ jwe_interceptor.dart # Dio interceptor for JWE wrapping +โ”‚ โ”‚ โ”œโ”€โ”€ api_service.dart # Dio HTTP client & API egress โ”‚ โ”‚ โ”œโ”€โ”€ secure_storage.dart # flutter_secure_storage wrapper โ”‚ โ”‚ โ”œโ”€โ”€ security_guard.dart # App Check + Play Integrity check โ”‚ โ”‚ โ”œโ”€โ”€ stealth_headers_service.dart # Anti-fingerprinting header injection @@ -313,7 +311,6 @@ GhostClass Mobile implements a zero-trust security model: | Layer | Mechanism | | :--- | :--- | | **Device Attestation** | Firebase App Check โ†’ Play Integrity (Android) / DeviceCheck (iOS) | -| **Network Encryption** | Every API request/response wrapped in JWE (RSA-OAEP + AES-256-GCM) | | **Credential Storage** | `flutter_secure_storage` (Android Keystore / iOS Keychain) | | **Anti-Tapjacking** | `FLAG_SECURE` on Android `MainActivity` | | **Stealth Headers** | Custom header injection to reduce fingerprinting during upstream data fetches | diff --git a/mobile/lib/firebase_options.dart b/mobile/lib/firebase_options.dart index 9701b88a..e24bc74a 100644 --- a/mobile/lib/firebase_options.dart +++ b/mobile/lib/firebase_options.dart @@ -28,7 +28,7 @@ class DefaultFirebaseOptions { ); case TargetPlatform.linux: throw UnsupportedError( - 'DefaultFirebaseOptions have not been configured for linux.', + 'DefaultFirebaseOptions are not supported for this platform.', ); default: throw UnsupportedError( diff --git a/mobile/lib/main.dart b/mobile/lib/main.dart index fc93e93f..65746442 100644 --- a/mobile/lib/main.dart +++ b/mobile/lib/main.dart @@ -12,7 +12,6 @@ import 'package:ghostclass/logic/security_initializer.dart'; import 'package:ghostclass/providers/theme_provider.dart'; import 'package:ghostclass/router/app_router.dart'; import 'package:ghostclass/services/analytics_service.dart'; -import 'package:ghostclass/services/jwe_service.dart'; import 'package:ghostclass/services/logger.dart'; import 'package:ghostclass/theme/app_theme.dart'; import 'package:ghostclass/widgets/security_lockdown_listener.dart'; @@ -127,9 +126,6 @@ void main() async { await ThemeNotifier.preload(); - // Eagerly pre-warm cryptographic services concurrently while other SDKs/Fonts initialize - AppLogger.safeUnawait(JweService.instance.preWarm(), 'JWE pre-warm'); - // Defer font pre-warm so UI can render faster AppLogger.safeUnawait( GoogleFonts.pendingFonts([ diff --git a/mobile/lib/screens/splash_screen.dart b/mobile/lib/screens/splash_screen.dart index 10e0fb98..b1e1e835 100644 --- a/mobile/lib/screens/splash_screen.dart +++ b/mobile/lib/screens/splash_screen.dart @@ -21,7 +21,6 @@ import 'package:ghostclass/providers/notification_provider.dart'; import 'package:ghostclass/providers/score_provider.dart'; import 'package:ghostclass/providers/tracking_provider.dart'; import 'package:ghostclass/services/api_service.dart'; -import 'package:ghostclass/services/jwe_service.dart'; import 'package:ghostclass/services/logger.dart'; import 'package:ghostclass/services/push_notification_service.dart'; import 'package:ghostclass/services/secure_storage.dart'; @@ -139,26 +138,11 @@ class _SplashScreenState extends ConsumerState { authStack = st; }); - Object? jweError; - StackTrace? jweStack; - - final jweTask = JweService.instance - .preWarm() - .then((_) { - AppLogger.i('SplashScreen: jweTask completed'); - }) - .catchError((Object e, StackTrace st) { - AppLogger.e('SplashScreen: jweTask failed', e, st); - jweError = e; - jweStack = st; - }); - api.clearCaches(); AppLogger.i('SplashScreen: Awaiting Future.wait...'); await Future.wait([ integrityTask, authTask, - jweTask, ]); AppLogger.i('SplashScreen: Future.wait completed'); @@ -171,9 +155,6 @@ class _SplashScreenState extends ConsumerState { if (authError != null) { Error.throwWithStackTrace(authError!, authStack ?? StackTrace.current); } - if (jweError != null) { - Error.throwWithStackTrace(jweError!, jweStack ?? StackTrace.current); - } return _StartupSnapshot(user: user, versionResult: versionResult); }(); @@ -256,14 +237,6 @@ class _SplashScreenState extends ConsumerState { void _startPostNavigationPreloads({ required ApiService apiService, }) { - AppLogger.safeUnawait( - JweService.instance.preWarm().catchError( - (Object e, StackTrace st) => - AppLogger.e('SplashScreen: post-nav JWE pre-warm failed', e, st), - ), - 'SplashScreen: post-nav JWE pre-warm', - ); - AppLogger.safeUnawait( apiService.preWarm().catchError((Object e, StackTrace st) { AppLogger.e('SplashScreen: post-nav API pre-warm failed', e, st); diff --git a/mobile/lib/services/dio_service.dart b/mobile/lib/services/dio_service.dart index 91bc9ef5..dd831f88 100644 --- a/mobile/lib/services/dio_service.dart +++ b/mobile/lib/services/dio_service.dart @@ -4,7 +4,6 @@ import 'package:firebase_app_check/firebase_app_check.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:ghostclass/config/app_config.dart'; -import 'package:ghostclass/services/jwe_interceptor.dart'; import 'package:ghostclass/services/logger.dart'; import 'package:ghostclass/services/stealth_headers_service.dart'; import 'package:sentry_dio/sentry_dio.dart'; @@ -13,7 +12,7 @@ import 'package:sentry_dio/sentry_dio.dart'; /// ---------- /// Centralized network client for the application. /// -/// Configures interceptors for JWE, Sentry, and authentication headers. +/// Configures interceptors for Sentry and authentication headers. class DioService { DioService(this._ref) { const timeout = kDebugMode ? Duration(seconds: 45) : Duration(seconds: 30); @@ -29,9 +28,6 @@ class DioService { dio.addSentry(); - // Attach JWE Layer first - dio.interceptors.add(_ref.read(jweInterceptorProvider)); - // Auth & Security Interceptor dio.interceptors.add( InterceptorsWrapper( @@ -297,7 +293,3 @@ final dioServiceProvider = Provider(DioService.new); final appCheckProvider = Provider( (ref) => FirebaseAppCheck.instance, ); - -final jweInterceptorProvider = Provider( - (ref) => JweInterceptor(), -); diff --git a/mobile/lib/services/jwe_interceptor.dart b/mobile/lib/services/jwe_interceptor.dart deleted file mode 100644 index a9cda053..00000000 --- a/mobile/lib/services/jwe_interceptor.dart +++ /dev/null @@ -1,198 +0,0 @@ -import 'package:dio/dio.dart'; -import 'package:ghostclass/config/app_config.dart'; -import 'package:ghostclass/services/jwe_service.dart'; -import 'package:ghostclass/services/logger.dart'; -import 'package:uuid/uuid.dart'; - -/// Interceptor that handles JSON Web Encryption (JWE) for all GhostClass API requests. -/// -/// 1. [onRequest]: Encrypts outgoing POST/PUT request bodies and attaches the RCEK -/// (Response Content Encryption Key) to the headers for server-side use. -/// 2. [onResponse]: Decrypts incoming encrypted responses using the stored RCEK. -class JweInterceptor extends Interceptor { - JweInterceptor([this._serviceOverride]); - final JweService? _serviceOverride; - - JweService get _jweService => _serviceOverride ?? JweService.instance; - - // Use a map to store RCEKs for concurrent requests with self-pruning timestamps - final Map _rcekMap = {}; - - void _pruneExpiredRceks() { - final now = DateTime.now(); - // Prune entries older than 2 minutes (120 seconds) to prevent any unbounded leak - _rcekMap.removeWhere( - (key, entry) => now.difference(entry.timestamp).inSeconds > 120, - ); - // Defensive cap: if an attacker floods requests, prevent the map from - // growing without bound by removing the oldest entries when exceeding - // a reasonable limit. - const maxEntries = 256; - if (_rcekMap.length > maxEntries) { - final entries = _rcekMap.entries.toList() - ..sort((a, b) => a.value.timestamp.compareTo(b.value.timestamp)); - final toRemove = _rcekMap.length - maxEntries; - for (var i = 0; i < toRemove; i++) { - _rcekMap.remove(entries[i].key); - } - } - } - - @override - Future onRequest( - RequestOptions options, - RequestInterceptorHandler handler, - ) async { - final baseUrl = AppConfig.ghostclassApiUrl; - // Ensure we only encrypt requests targeting our own backend. - // Check both absolute paths and relative paths combined with baseUrl. - final fullUrl = options.path.startsWith('http') - ? options.path - : '${options.baseUrl}${options.path}'; - final isGhostClassApi = fullUrl.startsWith(baseUrl); - final isWrite = - options.method == 'POST' || - options.method == 'PUT' || - options.method == 'PATCH'; - - if (isGhostClassApi && isWrite && options.data is Map) { - try { - final jweService = _jweService; - final result = await jweService.encryptRequest( - options.data as Map, - ); - - // Store the RCEK for this request's response decryption using a unique request ID - final requestId = const Uuid().v4(); - _pruneExpiredRceks(); - _rcekMap[requestId] = _RcekEntry( - rcek: result.rcek, - timestamp: DateTime.now(), - ); - options.headers['X-GhostClass-Request-ID'] = requestId; - - options.data = result.jwe; - options.headers['x-jwe'] = 'true'; - options.headers['Content-Type'] = 'application/jose'; - // The server needs the RCEK to decrypt the request and to encrypt the response - // In the GhostClass protocol, we send the RCEK encrypted with the server's public key - final keyResult = await jweService.encryptHeaderKey(); - options.headers['x-jwe-key'] = keyResult.jwe; - - AppLogger.d('JweInterceptor: Request encrypted for ${options.path}'); - } on Object catch (e) { - AppLogger.e('JweInterceptor: Encryption failed', e); - // Fail the request if encryption for our backend fails to avoid sending - // sensitive payloads unencrypted. - return handler.reject( - DioException( - requestOptions: options, - error: 'JWE encryption failed', - ), - ); - } - } else if (isGhostClassApi && options.method == 'GET') { - // For GET requests, we still need to send a JWE key if we want the response to be encrypted - try { - final jweService = _jweService; - final keyResult = await jweService.encryptHeaderKey(); - - final requestId = const Uuid().v4(); - _pruneExpiredRceks(); - _rcekMap[requestId] = _RcekEntry( - rcek: keyResult.rcek, - timestamp: DateTime.now(), - ); - options.headers['X-GhostClass-Request-ID'] = requestId; - - options.headers['x-jwe-key'] = keyResult.jwe; - } on Object catch (e) { - AppLogger.e('JweInterceptor: GET Key setup failed', e); - // Fail GET if we cannot establish a header key for our backend. - return handler.reject( - DioException( - requestOptions: options, - error: 'JWE header key setup failed', - ), - ); - } - } - - return handler.next(options); - } - - @override - Future onResponse( - Response response, - ResponseInterceptorHandler handler, - ) async { - final contentType = response.headers.value('content-type') ?? ''; - final isEncrypted = - contentType.contains('application/jose') || - response.headers.value('x-jwe') == 'true'; - // Header casing can vary depending on platform/transport. Try common - // variants to robustly retrieve the request ID used to store the RCEK. - String? requestId; - final headers = response.requestOptions.headers; - if (headers.containsKey('X-GhostClass-Request-ID')) { - requestId = headers['X-GhostClass-Request-ID'] as String?; - } else if (headers.containsKey('x-ghostclass-request-id')) { - requestId = headers['x-ghostclass-request-id'] as String?; - } else if (headers.containsKey('X-Ghostclass-Request-Id')) { - requestId = headers['X-Ghostclass-Request-Id'] as String?; - } - final entry = requestId == null ? null : _rcekMap.remove(requestId); - final rcek = entry?.rcek; - - if (isEncrypted && rcek != null) { - String? jwe; - if (response.data is String) { - jwe = response.data as String; - } - - if (jwe != null) { - try { - final jweService = _jweService; - final decryptedData = await jweService.decryptResponse(jwe, rcek); - response.data = decryptedData; - AppLogger.d( - 'JweInterceptor: Response decrypted for ${response.requestOptions.path}', - ); - } on Object catch (e) { - AppLogger.e('JweInterceptor: Decryption failed', e); - // If decryption fails, reject the response so callers don't process - // potentially tampered or unreadable data. - return handler.reject( - DioException( - requestOptions: response.requestOptions, - error: 'JWE response decryption failed', - type: DioExceptionType.badResponse, - ), - ); - } - } - } - - return handler.next(response); - } - - @override - void onError(DioException err, ErrorInterceptorHandler handler) { - // Clean up RCEK on error to prevent memory leaks - final headers = err.requestOptions.headers; - String? requestId; - if (headers.containsKey('X-GhostClass-Request-ID')) { - requestId = headers['X-GhostClass-Request-ID'] as String?; - } else if (headers.containsKey('x-ghostclass-request-id')) { - requestId = headers['x-ghostclass-request-id'] as String?; - } - if (requestId != null) _rcekMap.remove(requestId); - return handler.next(err); - } -} - -class _RcekEntry { - _RcekEntry({required this.rcek, required this.timestamp}); - final String rcek; - final DateTime timestamp; -} diff --git a/mobile/lib/services/jwe_service.dart b/mobile/lib/services/jwe_service.dart deleted file mode 100644 index 752d6e05..00000000 --- a/mobile/lib/services/jwe_service.dart +++ /dev/null @@ -1,271 +0,0 @@ -import 'dart:async'; -import 'dart:convert'; -import 'dart:io'; -import 'dart:math'; -// Preserved for potential platform-specific overrides -// ignore: unnecessary_import -import 'dart:typed_data'; - -import 'package:dio/dio.dart'; -import 'package:dio/io.dart'; -import 'package:flutter/foundation.dart'; -import 'package:ghostclass/config/app_config.dart'; -import 'package:ghostclass/logic/network_utils.dart'; -import 'package:ghostclass/services/logger.dart'; -import 'package:jose/jose.dart'; -import 'package:shared_preferences/shared_preferences.dart'; - -/// JweService -/// ---------- -/// Handles Bi-directional End-to-End Encryption (E2EE) for GhostClass. -class JweService { - JweService._internal() { - const networkTimeout = kDebugMode - ? Duration(seconds: 45) - : Duration(seconds: 30); - - _dio = Dio( - BaseOptions( - connectTimeout: networkTimeout, - receiveTimeout: networkTimeout, - sendTimeout: networkTimeout, - ), - ); - - if (kDebugMode) { - (_dio.httpClientAdapter as IOHttpClientAdapter).createHttpClient = () { - return HttpClient() - ..badCertificateCallback = NetworkUtils.validateCertificateHostname; - }; - } - } - static final JweService _instance = JweService._internal(); - static JweService get instance => _instance; - - late final Dio _dio; - - JsonWebKeySet? _cachedJwks; - DateTime? _lastFetch; - - final String _ghostclassApiUrl = AppConfig.ghostclassApiUrl; - - /// No longer needed internally, delegated to NetworkUtils. - - Future? _inFlightFetch; - static const String _jwksCacheKey = 'ghostclass_jwks_cache'; - static const String _jwksTimeKey = 'ghostclass_jwks_time'; - - Future _fetchJwks() async { - // 1. In-memory cache check (1 hour) - if (_cachedJwks != null && - _lastFetch != null && - DateTime.now().difference(_lastFetch!).inHours < 1) { - return; - } - - // 2. Return in-flight fetch if exists to deduplicate concurrent calls - if (_inFlightFetch != null) { - return _inFlightFetch!; - } - - _inFlightFetch = _performFetch(); - try { - await _inFlightFetch; - } finally { - _inFlightFetch = null; - } - } - - Future _performFetch() async { - try { - final prefs = await SharedPreferences.getInstance(); - - // 3. Persistent cache check - final cachedJson = prefs.getString(_jwksCacheKey); - final cachedTimeStr = prefs.getString(_jwksTimeKey); - if (cachedJson != null && cachedTimeStr != null) { - try { - final cachedTime = DateTime.parse(cachedTimeStr); - _cachedJwks = JsonWebKeySet.fromJson( - json.decode(cachedJson) as Map, - ); - _lastFetch = cachedTime; - AppLogger.d('JweService: Loaded JWKS from persistent cache.'); - - // Stale-While-Revalidate: if cached keys are older than 24 hours, - // refresh from network in the background without blocking startup. - if (DateTime.now().difference(cachedTime).inHours >= 24) { - AppLogger.safeUnawait( - _refreshJwksFromNetwork(prefs).catchError( - (Object e, StackTrace st) => AppLogger.e( - 'JweService: Background JWKS refresh failed', - e, - st, - ), - ), - 'JweService: background JWKS refresh', - ); - } - return; - } on Object catch (e) { - AppLogger.e('JweService: Failed to parse cached JWKS time', e); - } - } - - // 4. Cache miss: Blocking network fetch - await _refreshJwksFromNetwork(prefs); - } on Object catch (e) { - AppLogger.e('JweService: JWKS Fetch Error', e); - rethrow; - } - } - - Future _refreshJwksFromNetwork(SharedPreferences prefs) async { - try { - final url = '$_ghostclassApiUrl/.well-known/jwks.json'; - final response = await _dio.get(url); - - if (response.statusCode == 200) { - final data = response.data; - _cachedJwks = JsonWebKeySet.fromJson(data as Map); - _lastFetch = DateTime.now(); - - // Update persistent cache - await prefs.setString(_jwksCacheKey, json.encode(data)); - await prefs.setString(_jwksTimeKey, _lastFetch!.toIso8601String()); - - AppLogger.i('JweService: Fetched server JWKS successfully.'); - } else { - throw Exception('Failed to fetch JWKS: ${response.statusCode}'); - } - } on Object catch (e) { - AppLogger.e('JweService: Failed to refresh JWKS from network', e); - // If we already have a cached copy, don't bubble up background errors - if (_cachedJwks == null) { - rethrow; - } - } - } - - Future preWarm() async { - try { - await _fetchJwks(); - } on Object catch (e) { - AppLogger.d('JweService: Pre-warm skipped.', e); - } - } - - /// Selects a usable server key from JWKS. - /// - /// Prefer a key with a kid so the resulting JWE preserves key-rotation hints. - JsonWebKey _getPreferredServerKey() { - final keys = _cachedJwks?.keys ?? const []; - if (keys.isEmpty) { - throw Exception('Server public key not available.'); - } - - return keys.firstWhere( - (key) => key.keyId != null && key.keyId!.isNotEmpty, - orElse: () => keys.first, - ); - } - - /// Forces the JsonWebKey to explicitly support wrapKey while preserving kid. - JsonWebKey _getSanitizedServerKey(JsonWebKey key) { - final rawJson = key.toJson(); - - // Ensure the server key has the required RSA parameters. If the server - // provides an unexpected key shape, fail fast instead of constructing a - // potentially invalid JWK which could cause subtle crypto errors later. - final n = rawJson['n'] as String?; - final e = rawJson['e'] as String?; - if (n == null || n.isEmpty || e == null || e.isEmpty) { - throw Exception('Server JWK missing RSA modulus or exponent.'); - } - - return JsonWebKey.fromJson({ - 'kty': 'RSA', - 'n': n, - 'e': e, - if (rawJson['kid'] != null) 'kid': rawJson['kid'], - // Notice: We deliberately omit 'alg', 'use', and 'key_ops' to avoid - // rejecting the key for operation mismatches while preserving the kid. - }); - } - - Future<({String jwe, String rcek})> encryptRequest( - Map data, - ) async { - await _fetchJwks(); - - if (_cachedJwks == null || _cachedJwks!.keys.isEmpty) { - throw Exception('Server public key not available.'); - } - - final random = Random.secure(); - final rcekBytes = Uint8List.fromList( - List.generate(32, (_) => random.nextInt(256)), - ); - final rcekBase64 = base64Url.encode(rcekBytes).replaceAll('=', ''); - - final enrichedData = {...data, 'rcek': rcekBase64}; - - // Use the sanitized key while preserving kid for rotation-aware servers - final serverKey = _getSanitizedServerKey(_getPreferredServerKey()); - - final builder = JsonWebEncryptionBuilder() - ..jsonContent = enrichedData - ..encryptionAlgorithm = 'A256GCM' - ..addRecipient(serverKey, algorithm: 'RSA-OAEP-256'); - - final jwe = builder.build().toCompactSerialization(); - - return (jwe: jwe, rcek: rcekBase64); - } - - Future<({String jwe, String rcek})> encryptHeaderKey() async { - await _fetchJwks(); - - if (_cachedJwks == null || _cachedJwks!.keys.isEmpty) { - throw Exception('Server public key not available.'); - } - - final random = Random.secure(); - final rcekBytes = Uint8List.fromList( - List.generate(32, (_) => random.nextInt(256)), - ); - final rcekBase64 = base64Url.encode(rcekBytes).replaceAll('=', ''); - - // Use the sanitized key while preserving kid for rotation-aware servers - final serverKey = _getSanitizedServerKey(_getPreferredServerKey()); - - final builder = JsonWebEncryptionBuilder() - ..jsonContent = {'rcek': rcekBase64} - ..encryptionAlgorithm = 'A256GCM' - ..addRecipient(serverKey, algorithm: 'RSA-OAEP-256'); - - return (jwe: builder.build().toCompactSerialization(), rcek: rcekBase64); - } - - Future decryptResponse(String jwe, String rcekBase64) async { - try { - final rcekBytes = base64Url.decode(base64.normalize(rcekBase64)); - - final jwk = JsonWebKey.fromJson({ - 'kty': 'oct', - 'k': base64Url.encode(rcekBytes).replaceAll('=', ''), - 'alg': 'A256GCM', - 'use': 'enc', - }); - - final jweObj = JsonWebEncryption.fromCompactSerialization(jwe); - final keyStore = JsonWebKeyStore()..addKey(jwk); - final payload = await jweObj.getPayload(keyStore); - - return json.decode(utf8.decode(payload.data)); - } on Object catch (e) { - AppLogger.e('JweService: Response Decryption Error', e); - throw Exception('Security sync failed: Response could not be verified.'); - } - } -} diff --git a/mobile/pubspec.lock b/mobile/pubspec.lock index 666cd573..991205a4 100644 --- a/mobile/pubspec.lock +++ b/mobile/pubspec.lock @@ -265,14 +265,6 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.7" - crypto_keys: - dependency: transitive - description: - name: crypto_keys - sha256: acc19abf34623d990a0e8aec69463d74a824c31f137128f42e2810befc509ad0 - url: "https://pub.dev" - source: hosted - version: "0.3.0+1" cupertino_icons: dependency: "direct main" description: @@ -864,14 +856,6 @@ packages: url: "https://pub.dev" source: hosted version: "0.14.2" - jose: - dependency: "direct main" - description: - name: jose - sha256: a0a339d0a0652dc1bd89f8b92d38479e07e16db83858fb55fa57212479f323f7 - url: "https://pub.dev" - source: hosted - version: "0.3.5+2" js: dependency: transitive description: @@ -1240,14 +1224,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.5.0" - quiver: - dependency: transitive - description: - name: quiver - sha256: ea0b925899e64ecdfbf9c7becb60d5b50e706ade44a85b2363be2a22d88117d2 - url: "https://pub.dev" - source: hosted - version: "3.2.2" realtime_client: dependency: transitive description: @@ -1749,14 +1725,6 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.3" - x509: - dependency: transitive - description: - name: x509 - sha256: cbd1a63846884afd273cda247b0365284c8d85a365ca98e110413f93d105b935 - url: "https://pub.dev" - source: hosted - version: "0.2.4+3" xdg_directories: dependency: transitive description: diff --git a/mobile/pubspec.yaml b/mobile/pubspec.yaml index bc349e53..dad78bfa 100644 --- a/mobile/pubspec.yaml +++ b/mobile/pubspec.yaml @@ -47,7 +47,6 @@ dependencies: google_fonts: ^8.0.2 image_picker: ^1.1.2 intl: ^0.20.2 - jose: ^0.3.5+1 lucide_icons_flutter: ^3.1.14+1 markdown: any package_info_plus: ^10.2.1 diff --git a/mobile/test/auto_coverage_booster_test.dart b/mobile/test/auto_coverage_booster_test.dart index f8e50311..598fe296 100644 --- a/mobile/test/auto_coverage_booster_test.dart +++ b/mobile/test/auto_coverage_booster_test.dart @@ -1,3 +1,4 @@ +import 'package:firebase_app_check/firebase_app_check.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -40,6 +41,7 @@ import 'package:ghostclass/screens/scores_screen.dart'; import 'package:ghostclass/screens/splash_screen.dart'; import 'package:ghostclass/screens/static_screen.dart'; import 'package:ghostclass/screens/tracking_screen.dart'; +import 'package:ghostclass/services/dio_service.dart'; import 'package:ghostclass/services/logger.dart'; import 'package:ghostclass/theme/app_theme.dart'; import 'package:ghostclass/widgets/about/about_widgets.dart'; @@ -79,11 +81,14 @@ import 'package:ghostclass/widgets/tracking/tracking_header_widgets.dart'; import 'package:ghostclass/widgets/tracking/tracking_record_card.dart'; import 'package:ghostclass/widgets/tracking/tracking_subject_picker.dart'; import 'package:ghostclass/widgets/transparency_badge.dart'; +import 'package:mocktail/mocktail.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:supabase_flutter/supabase_flutter.dart'; import 'coverage_helper.dart'; +class MockFirebaseAppCheck extends Mock implements FirebaseAppCheck {} + void main() { setUpAll(() async { SharedPreferences.setMockInitialValues({}); @@ -115,6 +120,7 @@ void main() { final mockLeave = createMockLeaveState(); final overrides = [ + appCheckProvider.overrideWithValue(MockFirebaseAppCheck()), dashboardProvider.overrideWith(() => MockDashboardNotifier(mockDashboard)), authProvider.overrideWith(() => MockAuthNotifier(mockUser)), trackingProvider.overrideWith(() => MockTrackingNotifier(mockTracking)), diff --git a/mobile/test/coverage_booster_test.dart b/mobile/test/coverage_booster_test.dart index 6f962c56..b8be5463 100644 --- a/mobile/test/coverage_booster_test.dart +++ b/mobile/test/coverage_booster_test.dart @@ -206,10 +206,7 @@ void main() { }); testWidgets('Coverage Booster: AppRouter & SplashScreen', (tester) async { - SharedPreferences.setMockInitialValues({ - 'ghostclass_jwks_cache': '{"keys": []}', - 'ghostclass_jwks_time': DateTime.now().toIso8601String(), - }); + SharedPreferences.setMockInitialValues({}); final mockSupabase = MockSupabaseClient(); final mockAuth = MockGoTrueClient(); diff --git a/mobile/test/coverage_shallow_test.dart b/mobile/test/coverage_shallow_test.dart index e2da4719..aebb2d6f 100644 --- a/mobile/test/coverage_shallow_test.dart +++ b/mobile/test/coverage_shallow_test.dart @@ -42,10 +42,7 @@ void main() { setUp(() { TestWidgetsFlutterBinding.ensureInitialized(); - SharedPreferences.setMockInitialValues({ - 'ghostclass_jwks_cache': '{"keys": []}', - 'ghostclass_jwks_time': DateTime.now().toIso8601String(), - }); + SharedPreferences.setMockInitialValues({}); }); testWidgets('Shallow render important widgets', (tester) async { diff --git a/mobile/test/services/dio_service_coverage_test.dart b/mobile/test/services/dio_service_coverage_test.dart index 5d14f272..ef32064b 100644 --- a/mobile/test/services/dio_service_coverage_test.dart +++ b/mobile/test/services/dio_service_coverage_test.dart @@ -5,19 +5,14 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:ghostclass/config/app_config.dart'; import 'package:ghostclass/services/dio_service.dart'; -import 'package:ghostclass/services/jwe_interceptor.dart'; -import 'package:ghostclass/services/jwe_service.dart'; import 'package:mocktail/mocktail.dart'; class MockFirebaseAppCheck extends Mock implements FirebaseAppCheck {} -class MockJweService extends Mock implements JweService {} - class MockHttpClientAdapter extends Mock implements HttpClientAdapter {} void main() { late MockFirebaseAppCheck mockAppCheck; - late MockJweService mockJweService; late MockHttpClientAdapter mockAdapter; late ProviderContainer container; late DioService dioService; @@ -28,19 +23,11 @@ void main() { setUp(() { mockAppCheck = MockFirebaseAppCheck(); - mockJweService = MockJweService(); mockAdapter = MockHttpClientAdapter(); - when( - () => mockJweService.encryptHeaderKey(), - ).thenAnswer((_) async => (jwe: 'mock-key', rcek: 'mock-rcek')); - container = ProviderContainer( overrides: [ appCheckProvider.overrideWithValue(mockAppCheck), - jweInterceptorProvider.overrideWithValue( - JweInterceptor(mockJweService), - ), ], ); dioService = container.read(dioServiceProvider); diff --git a/package.json b/package.json index d2bcac3c..8274cc1f 100644 --- a/package.json +++ b/package.json @@ -82,7 +82,6 @@ "firebase-admin": "^14.2.0", "framer-motion": "^12.43.0", "googleapis": "^173.0.0", - "jose": "^6.2.5", "ldrs": "^1.1.9", "lodash-es": "^4.18.1", "lru-cache": "^11.5.2", diff --git a/public/openapi/openapi.yaml b/public/openapi/openapi.yaml index bb657609..a2a8b695 100644 --- a/public/openapi/openapi.yaml +++ b/public/openapi/openapi.yaml @@ -66,23 +66,29 @@ tags: - name: Authentication description: Endpoints for managing EzyGo authentication tokens - name: Mobile - description: Mobile-first authenticated endpoints and JWE-secured bridge APIs + description: Mobile-first authenticated endpoints and bridge APIs - name: Security description: Security endpoints for CSRF protection - name: Sync - description: Endpoints for synchronizing attendance data with EzyGo - - name: Proxy - description: Secure backend proxy and pass-through endpoints for EzyGo APIs - - name: Health - description: System health and status endpoints + description: Synchronization endpoints for mobile and web + - name: Attendance + description: Attendance tracking and calculation endpoints + - name: Courses + description: Course management and search endpoints + - name: Scores + description: Student scores and academic performance endpoints + - name: Classes + description: Class list and instructor discovery endpoints - name: Analytics - description: Server-side analytics event forwarding + description: Application analytics and telemetry tracking + - name: Contact + description: Contact form submission and support endpoints + - name: Health + description: Health check and diagnostic endpoints - name: Reporting description: Browser-generated violation and telemetry reports - name: Profile description: User profile management - - name: Keys - description: Public key discovery endpoints for JWE/JWKS - name: Documentation description: OpenAPI and API reference endpoints - name: Provenance @@ -701,7 +707,7 @@ paths: Retrieves attendance summaries for multiple courses in a single request. Optimized for dashboard card views to avoid N+1 network requests. - Requires Firebase App Check and JWE encryption. + Requires Firebase App Check. tags: - Attendance security: @@ -1359,34 +1365,6 @@ paths: schema: type: string - /api/.well-known/jwks.json: - get: - tags: - - Keys - summary: Get JWKS public keys - security: [] - description: | - Returns the JSON Web Key Set (JWKS) used by clients to discover - active public keys for cryptographic operations. - operationId: getJwks - responses: - "200": - description: JSON Web Key Set - content: - application/jwk-set+json: - schema: - type: object - properties: - keys: - type: array - items: - type: object - "500": - description: Failed to fetch keys - content: - application/json: - schema: - $ref: "#/components/schemas/Error" /api/auth/sync: post: diff --git a/src/app/api/.well-known/jwks.json/__tests__/route.test.ts b/src/app/api/.well-known/jwks.json/__tests__/route.test.ts deleted file mode 100644 index 06594f6f..00000000 --- a/src/app/api/.well-known/jwks.json/__tests__/route.test.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { describe, it, expect, vi, beforeEach } from 'vitest'; -import { GET } from '../route'; -import { getJwks } from '@/lib/security/jwks'; -import { logger } from '@/lib/logger'; - -vi.mock('@/lib/security/jwks', () => ({ - getJwks: vi.fn(), -})); - -vi.mock('@/lib/logger', () => ({ - logger: { - error: vi.fn(), - }, -})); - -vi.mock('next/server', () => ({ - NextResponse: { - json: vi.fn((data, init) => ({ - data, - status: init?.status || 200, - headers: init?.headers || {}, - })), - }, -})); - -describe('GET /api/.well-known/jwks.json', () => { - beforeEach(() => { - vi.clearAllMocks(); - }); - - it('returns JWKS with correct headers', async () => { - const mockJwks = { keys: [{ kid: '1', kty: 'RSA' }] }; - vi.mocked(getJwks).mockResolvedValue(mockJwks as any); - - const response = await GET() as any; - - expect(response.status).toBe(200); - expect(response.data).toEqual(mockJwks); - expect(response.headers['Content-Type']).toBe('application/jwk-set+json'); - expect(response.headers['Cache-Control']).toContain('public'); - }); - - it('returns 500 if JWKS generation fails', async () => { - vi.mocked(getJwks).mockRejectedValue(new Error('JWKS Error')); - - const response = await GET() as any; - - expect(response.status).toBe(500); - expect(response.data.error).toBe('Internal Server Error'); - expect(logger.error).toHaveBeenCalled(); - }); -}); diff --git a/src/app/api/.well-known/jwks.json/route.ts b/src/app/api/.well-known/jwks.json/route.ts deleted file mode 100644 index 6c81e30f..00000000 --- a/src/app/api/.well-known/jwks.json/route.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { NextResponse } from "next/server"; -import { getJwks } from "@/lib/security/jwks"; -import { logger } from "@/lib/logger"; - -export const dynamic = "force-dynamic"; -export const revalidate = 3600; // Cache for 1 hour - -/** - * GET /api/.well-known/jwks.json - * - * Returns the JSON Web Key Set (JWKS) containing the public RSA keys - * used by clients (like the Flutter mobile app) to verify and wrap - * session keys for JWE encryption. - */ -export async function GET() { - try { - const jwks = await getJwks(); - - return NextResponse.json(jwks, { - headers: { - "Content-Type": "application/jwk-set+json", - "Cache-Control": "public, max-age=3600, s-maxage=3600, stale-while-revalidate=86400", - }, - }); - } catch (error) { - logger.error("JWKS endpoint failed:", error); - return NextResponse.json( - { error: "Internal Server Error" }, - { status: 500 } - ); - } -} diff --git a/src/app/api/attendance/summary-batch/route.ts b/src/app/api/attendance/summary-batch/route.ts index 09309cfa..686e47d0 100644 --- a/src/app/api/attendance/summary-batch/route.ts +++ b/src/app/api/attendance/summary-batch/route.ts @@ -62,7 +62,7 @@ const handler = async (req: NextRequest, { decryptedBody }: { decryptedBody?: Ba return NextResponse.json({ error: "EzyGo token missing" }, { status: 401 }); } - // 4. Parse request body (handle both JWE and plain JSON) + // 4. Parse request body (plain JSON) let body = decryptedBody; if (!body) { try { @@ -157,5 +157,5 @@ const handler = async (req: NextRequest, { decryptedBody }: { decryptedBody?: Ba return NextResponse.json(results); }; -// Wrap with security HOF to handle App Check and JWE decryption for mobile clients +// Wrap with security HOF to handle App Check for mobile clients export const POST = withSecurity(handler); diff --git a/src/app/api/auth/sync/route.ts b/src/app/api/auth/sync/route.ts index 9bf215aa..868b3609 100644 --- a/src/app/api/auth/sync/route.ts +++ b/src/app/api/auth/sync/route.ts @@ -83,7 +83,7 @@ export const dynamic = "force-dynamic"; /** * Universal Authentication Sync Route * - * Handles session healing for both web (cookies) and mobile (JWE/Bearer). + * Handles session healing for both web (cookies) and mobile (Bearer). * - Web: Refreshes Supabase session and heals ezygo_access_token cookie. * - Mobile: Returns an encrypted bundle containing the healed EzyGo token and terms status. */ diff --git a/src/app/api/contact/__tests__/route.test.ts b/src/app/api/contact/__tests__/route.test.ts index 2e44b3db..10edb021 100644 --- a/src/app/api/contact/__tests__/route.test.ts +++ b/src/app/api/contact/__tests__/route.test.ts @@ -155,7 +155,7 @@ describe("POST /api/contact", () => { }); it("uses decryptedBody if provided by withSecurity", async () => { - (processContactSubmission as any).mockResolvedValueOnce({ success: true, id: "msg-jwe" }); + (processContactSubmission as any).mockResolvedValueOnce({ success: true, id: "msg-contact" }); const { POST } = await import("../route"); const req = new NextRequest("http://localhost/api/contact", { method: "POST" }); // withSecurity passes decryptedBody as second argument diff --git a/src/app/api/contact/route.ts b/src/app/api/contact/route.ts index b159cbfc..deb4f253 100644 --- a/src/app/api/contact/route.ts +++ b/src/app/api/contact/route.ts @@ -15,13 +15,15 @@ export const dynamic = "force-dynamic"; /** * Unified API for contact form submissions. - * Optimized for Mobile App usage (Flutter) with Zero-Trust security (JWE + App Check). - * Now triggers the same email notification and confirmation flow as the web app. - * - * Security layers: + * Optimized for Mobile App usage (Flutter) with Zero-Trust security (App Check). + * + * Flow: + * - App Check for mobile callers (via withSecurity) + * - Rate limited via withSecurity + * - Turnstile CAPTCHA optional check for web callers + * - Server-side validation using Zod * - Rate limiting (per-IP via contactRateLimiter) * - CSRF validation for non-mobile (web) callers - * - App Check + JWE for mobile callers (via withSecurity) */ export const POST = withSecurity(async (req, { decryptedBody }) => { const request = req as NextRequest; @@ -55,7 +57,7 @@ export const POST = withSecurity(async (req, { decryptedBody }) => { ); } - // 2. Resolve Payload (JWE or JSON) + // 2. Resolve Payload (JSON) let body = decryptedBody; if (!body) { try { diff --git a/src/app/api/courses/add/route.ts b/src/app/api/courses/add/route.ts index 6ac29a89..8d9a6bd0 100644 --- a/src/app/api/courses/add/route.ts +++ b/src/app/api/courses/add/route.ts @@ -32,7 +32,7 @@ async function authenticateRequest(req: Request) { /** * API Route for adding a new course to a class lineup. * Primarily used by the mobile app which bypasses the Turnstile check - * but uses JWE/AppCheck/PlayIntegrity for security. + * but uses AppCheck/PlayIntegrity for security. */ async function handler(req: Request, { decryptedBody }: { decryptedBody?: unknown }) { try { diff --git a/src/app/api/user/accept-terms/route.ts b/src/app/api/user/accept-terms/route.ts index 292e8e86..52cd892a 100644 --- a/src/app/api/user/accept-terms/route.ts +++ b/src/app/api/user/accept-terms/route.ts @@ -17,7 +17,7 @@ export const dynamic = "force-dynamic"; const handler = async (req: NextRequest, { decryptedBody }: { decryptedBody?: { version?: unknown } }) => { const supabaseAdmin = getAdminClient(); - // withSecurity handles auth and JWE. We expect a Bearer token or cookie. + // withSecurity handles auth. We expect a Bearer token or cookie. const authHeader = req.headers.get("Authorization"); let authUser; diff --git a/src/app/config/legal.ts b/src/app/config/legal.ts index f9dd17ae..511295cd 100644 --- a/src/app/config/legal.ts +++ b/src/app/config/legal.ts @@ -37,7 +37,6 @@ To provide the GhostClass service, we collect and process specific categories of **2. Security & Encryption Standards** We employ industry-standard security measures to protect your data: * **AES-256 Encryption:** All sensitive tokens are encrypted using **AES-256** before being written to our database. -* **JWE (Mobile App):** Mobile API payloads and responses are wrapped using JSON Web Encryption. * **Secure Device Storage:** Sensitive mobile tokens are stored in OS-provided secure storage (Keychain/Keystore). * **In-Memory Processing:** Decryption of credentials occurs only in ephemeral server memory (RAM) for the duration of the API request and is never written to disk logs. * **HTTPS/TLS:** All data transmission occurs over secure, encrypted channels. diff --git a/src/components/attendance/AddAttendanceDialog.tsx b/src/components/attendance/AddAttendanceDialog.tsx index 0f2e521e..2a8c6054 100644 --- a/src/components/attendance/AddAttendanceDialog.tsx +++ b/src/components/attendance/AddAttendanceDialog.tsx @@ -1,8 +1,6 @@ "use client"; -import { useEffect, useMemo, useState } from "react"; -import * as Sentry from "@sentry/nextjs"; -import { logger } from "@/lib/logger"; +import { Button } from "@/components/ui/button"; import { Dialog, DialogContent, @@ -11,7 +9,14 @@ import { DialogHeader, DialogTitle, } from "@/components/ui/dialog"; -import { Button } from "@/components/ui/button"; +import { Input } from "@/components/ui/input"; +import { Label } from "@/components/ui/label"; +import { + Popover, + PopoverContent, + PopoverTrigger, +} from "@/components/ui/popover"; +import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"; import { Select, SelectContent, @@ -19,18 +24,28 @@ import { SelectTrigger, SelectValue, } from "@/components/ui/select"; -import { Label } from "@/components/ui/label"; -import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"; -import { Input } from "@/components/ui/input"; +import { useCourseLookup } from "@/hooks/courses/useCourseLookup"; +import { useDisabledCourses } from "@/hooks/courses/useDisabledCourses"; +import { useFetchClassCourses } from "@/hooks/courses/useFetchClassCourses"; +import { useProfile } from "@/hooks/users/profile"; import { - BookOpen, - Calendar as CalendarIcon, - ChevronLeft, - ChevronRight, - Loader2, -} from "lucide-react"; -import { toast } from "sonner"; + getDutyLeaveErrorMessage, + getHumanReadableError, + isDutyLeaveConstraintError, +} from "@/lib/error-handling"; +import { logger } from "@/lib/logger"; import { createClient } from "@/lib/supabase/client"; +import { + cn, + formatSessionName, + normalizeCourseCode, + normalizeDate, + normalizeSession, + toRoman, +} from "@/lib/utils"; +import { optionalReasonSchema } from "@/lib/validation/text"; +import { AttendanceReport, Course, TrackAttendance } from "@/types"; +import * as Sentry from "@sentry/nextjs"; import { addMonths, eachDayOfInterval, @@ -44,29 +59,15 @@ import { startOfMonth, subMonths, } from "date-fns"; -import { cn, normalizeCourseCode } from "@/lib/utils"; -import { optionalReasonSchema } from "@/lib/validation/text"; -import { - Popover, - PopoverContent, - PopoverTrigger, -} from "@/components/ui/popover"; import { - formatSessionName, - normalizeDate, - normalizeSession, - toRoman, -} from "@/lib/utils"; -import { - getHumanReadableError, - getDutyLeaveErrorMessage, - isDutyLeaveConstraintError, -} from "@/lib/error-handling"; -import { AttendanceReport, Course, TrackAttendance } from "@/types"; -import { useDisabledCourses } from "@/hooks/courses/useDisabledCourses"; -import { useFetchClassCourses } from "@/hooks/courses/useFetchClassCourses"; -import { useCourseLookup } from "@/hooks/courses/useCourseLookup"; -import { useProfile } from "@/hooks/users/profile"; + BookOpen, + Calendar as CalendarIcon, + ChevronLeft, + ChevronRight, + Loader2, +} from "lucide-react"; +import { useEffect, useMemo, useState } from "react"; +import { toast } from "sonner"; interface User { id: string | number; @@ -112,20 +113,20 @@ function computeSortedCourses( coursesData: { courses: Record } | undefined, classCourses: { course_code: string; course_name: string }[] | undefined, isDisabled: (code: string) => boolean, - getCourseCodeById: (id: string) => string + getCourseCodeById: (id: string) => string, ) { const courses: { key: string; name: string }[] = []; - + if (coursesData?.courses) { Object.entries(coursesData.courses).forEach(([key, c]) => { courses.push({ key, name: c.name }); }); } - + if (classCourses) { - classCourses.forEach(cc => { + classCourses.forEach((cc) => { const code = normalizeCourseCode(cc.course_code); - if (!courses.some(c => normalizeCourseCode(c.key) === code)) { + if (!courses.some((c) => normalizeCourseCode(c.key) === code)) { courses.push({ key: cc.course_code, name: cc.course_name }); } }); @@ -142,7 +143,10 @@ function computeSortedCourses( }); } -function computeSemesterBounds(selectedSemester?: "odd" | "even", selectedYear?: string) { +function computeSemesterBounds( + selectedSemester?: "odd" | "even", + selectedYear?: string, +) { if (!selectedYear || !selectedSemester) { return { min: undefined, max: undefined }; } @@ -170,7 +174,12 @@ function computeSemesterBounds(selectedSemester?: "odd" | "even", selectedYear?: } } -function computeAutoSession(open: boolean, attendanceData: AttendanceReport | undefined, trackingData: TrackAttendance[], date: Date) { +function computeAutoSession( + open: boolean, + attendanceData: AttendanceReport | undefined, + trackingData: TrackAttendance[], + date: Date, +) { if (!open || !attendanceData) return ""; const occupiedSessions = new Set(); const dateKey = normalizeDate(date); @@ -181,16 +190,20 @@ function computeAutoSession(open: boolean, attendanceData: AttendanceReport | un Object.entries(officialDay).forEach(([key, s], index) => { const slot = s as AttendanceSlot; if ( - slot.course == null || slot.course === "null" || - slot.course === 0 || slot.course === "0" - ) return; + slot.course == null || + slot.course === "null" || + slot.course === 0 || + slot.course === "0" + ) + return; // eslint-disable-next-line security/detect-object-injection let name = attendanceData.sessions?.[key]?.name; - if (!name && slot.session && slot.session !== "null") name = String(slot.session); + if (!name && slot.session && slot.session !== "null") + name = String(slot.session); if (!name) { const keyInt = parseInt(key); - name = (!isNaN(keyInt) && keyInt < 20) ? key : String(index + 1); + name = !isNaN(keyInt) && keyInt < 20 ? key : String(index + 1); } if (name) occupiedSessions.add(normalizeSession(name)); }); @@ -207,10 +220,10 @@ function computeAutoSession(open: boolean, attendanceData: AttendanceReport | un } function computeBestCourse( - session: string, - date: Date, - attendanceData: AttendanceReport | undefined, - getCourseCodeById: (id: string) => string + session: string, + date: Date, + attendanceData: AttendanceReport | undefined, + getCourseCodeById: (id: string) => string, ) { if (!session || !attendanceData?.studentAttendanceData) return ""; const dayOfWeek = date.getDay(); @@ -225,14 +238,21 @@ function computeBestCourse( if (new Date(y, m, d).getDay() === dayOfWeek) { Object.entries(sessions).forEach(([key, s], index) => { const slot = s as AttendanceSlot; - if (slot.course == null || slot.course === "null" || slot.course === 0 || slot.course === "0") return; + if ( + slot.course == null || + slot.course === "null" || + slot.course === 0 || + slot.course === "0" + ) + return; // eslint-disable-next-line security/detect-object-injection let name = attendanceData.sessions?.[key]?.name; - if (!name && slot.session && slot.session !== "null") name = String(slot.session); + if (!name && slot.session && slot.session !== "null") + name = String(slot.session); if (!name) { const keyInt = parseInt(key); - name = (!isNaN(keyInt) && keyInt < 20) ? key : String(index + 1); + name = !isNaN(keyInt) && keyInt < 20 ? key : String(index + 1); } if (name && normalizeSession(name) === target) { const cid = getCourseCodeById(String(slot.course)); @@ -247,16 +267,19 @@ function computeBestCourse( let best = ""; let max = 0; Object.entries(frequencyMap).forEach(([cid, count]) => { - if (count > max) { max = count; best = cid; } + if (count > max) { + max = count; + best = cid; + } }); return best; } function checkIfSessionBlocked( - session: string, - date: Date, - attendanceData: AttendanceReport | undefined, - trackingData: TrackAttendance[] + session: string, + date: Date, + attendanceData: AttendanceReport | undefined, + trackingData: TrackAttendance[], ) { if (!session) return false; @@ -271,7 +294,9 @@ function checkIfSessionBlocked( const slot = s as AttendanceSlot; if ( - slot.course == null || slot.course === "null" || slot.course === 0 || + slot.course == null || + slot.course === "null" || + slot.course === 0 || slot.course === "0" ) { return false; @@ -286,9 +311,7 @@ function checkIfSessionBlocked( if (!effectiveName) { const keyInt = parseInt(key); - effectiveName = (!isNaN(keyInt) && keyInt < 20) - ? key - : String(index + 1); + effectiveName = !isNaN(keyInt) && keyInt < 20 ? key : String(index + 1); } if (effectiveName && normalizeSession(effectiveName) === targetSession) { @@ -301,7 +324,8 @@ function checkIfSessionBlocked( if (!isBlocked && trackingData) { const targetDbDate = normalizeDate(date); isBlocked = trackingData.some((t) => { - const isMatch = normalizeDate(t.date) === targetDbDate && + const isMatch = + normalizeDate(t.date) === targetDbDate && normalizeSession(t.session) === targetSession; return isMatch; }); @@ -376,7 +400,12 @@ export function AddAttendanceDialog({ }); const sortedCourses = useMemo(() => { - return computeSortedCourses(coursesData, classCourses, isDisabled, getCourseCodeById); + return computeSortedCourses( + coursesData, + classCourses, + isDisabled, + getCourseCodeById, + ); }, [coursesData, classCourses, isDisabled, getCourseCodeById]); // 1. CALCULATE SEMESTER BOUNDS @@ -407,7 +436,7 @@ export function AddAttendanceDialog({ setStatusType("Present"); }); } - // eslint-disable-next-line react-hooks/exhaustive-deps + // eslint-disable-next-line react-hooks/exhaustive-deps }, [open, semesterBounds.min, semesterBounds.max]); // --- 3. SMART DEFAULTS (Occupancy Check) --- @@ -422,7 +451,7 @@ export function AddAttendanceDialog({ setSession(autoSession); }); } - // eslint-disable-next-line react-hooks/exhaustive-deps + // eslint-disable-next-line react-hooks/exhaustive-deps }, [open, getDateKey(date), attendanceData, autoSession]); // --- 4. PREFILL COURSE --- @@ -438,10 +467,9 @@ export function AddAttendanceDialog({ else if (sortedCourses.length > 0) setCourseId(sortedCourses[0].key); }); } - // eslint-disable-next-line react-hooks/exhaustive-deps + // eslint-disable-next-line react-hooks/exhaustive-deps }, [open, date.getDay(), session, bestCourse, sortedCourses]); - // --- 5. VALIDATION (Is Session Blocked?) --- const isSessionBlocked = useMemo(() => { return checkIfSessionBlocked(session, date, attendanceData, trackingData); @@ -464,7 +492,9 @@ export function AddAttendanceDialog({ if (statusType === "Duty Leave") attCode = 225; const supabase = createClient(); - const { data: { user: authUser } } = await supabase.auth.getUser(); + const { + data: { user: authUser }, + } = await supabase.auth.getUser(); if (!authUser) { toast.error("You must be logged in"); @@ -480,19 +510,17 @@ export function AddAttendanceDialog({ const finalRemarks = optionalReasonSchema.parse(remarks); - const { error } = await supabase - .from("tracker") - .insert({ - auth_user_id: authUser.id, - course: courseIdToSave, - date: format(date, "yyyy-MM-dd"), - session: toRoman(session), - semester: selectedSemester, - year: selectedYear, - status: "extra", - attendance: attCode, - remarks: finalRemarks, - }); + const { error } = await supabase.from("tracker").insert({ + auth_user_id: authUser.id, + course: courseIdToSave, + date: format(date, "yyyy-MM-dd"), + session: toRoman(session), + semester: selectedSemester, + year: selectedYear, + status: "extra", + attendance: attCode, + remarks: finalRemarks, + }); if (error) { if (isDutyLeaveConstraintError(error)) { @@ -564,9 +592,10 @@ export function AddAttendanceDialog({ className={cn( "w-full justify-start text-left font-normal bg-accent/20 border-border/50 hover:bg-accent/30", )} - aria-label={`Selected date: ${ - format(date, "MMMM d, yyyy") - }. Click to change date`} + aria-label={`Selected date: ${format( + date, + "MMMM d, yyyy", + )}. Click to change date`} >