diff --git a/.claude/settings.json b/.claude/settings.json new file mode 100644 index 00000000..bc28fb5f --- /dev/null +++ b/.claude/settings.json @@ -0,0 +1,47 @@ +{ + "permissions": { + "allow": [ + "Bash(pnpm run *)", + "Bash(git add *)", + "Bash(git commit *)", + "Bash(git branch *)", + "Bash(git log *)", + "Bash(git checkout *)", + "Bash(git status *)", + "Bash(ls *)", + "Bash(cat *)", + "Bash(grep *)", + "Bash(find *)", + "Bash(tree *)", + "WebSearch", + "WebFetch(domain:*.anthropic.com)", + "WebFetch(domain:docs.sentry.io)", + "WebFetch(domain:www.better-auth.com)", + "WebFetch(domain:hono.dev)", + "WebFetch(domain:tanstack.com)", + "WebFetch(domain:trpc.io)", + "WebFetch(domain:orm.drizzle.team)", + "mcp__sentry__*", + "mcp__better-auth__*", + "mcp__shadcn__*", + "Skill(*)" + ], + "deny": [ + "Read(.env*)", + "Read(**/.env*)", + "Read(**/secrets.*)", + "Read(**/*secret*)", + "Read(**/*credential*)", + "Read(**/wrangler.toml)", + "Write(.env*)", + "Write(**/.env*)", + "Bash(wrangler d1 execute * --remote *)", + "Bash(rm -rf *)", + "Bash(sudo *)" + ] + }, + "enableAllProjectMcpServers": true, + "git": { + "includeCoAuthoredBy": true + } +} diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..a5d79f97 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,54 @@ +# Dependencies +node_modules/ +**/node_modules/ + +# Build output +dist/ +**/dist/ +build/ +**/.output/ + +# Development +.git/ +.github/ +.vscode/ +.idea/ +*.md +docs/ + +# Testing +**/__tests__/ +**/*.test.ts +**/*.spec.ts +coverage/ +**/coverage/ +.nyc_output/ + +# Environment +.env +.env.* +!.env.example + +# Logs +*.log +logs/ + +# Cache +.cache/ +**/.cache/ +.parcel-cache/ +.wrangler/ +**/.wrangler/ + +# Temp files +tmp/ +temp/ +*.tmp +.DS_Store + +# Application specific +packages/app/dist/ +packages/api/dist/ +data/ +*.db +*.db-* diff --git a/.github/workflows/ci-reusable.yml b/.github/workflows/ci-reusable.yml index 6e8c5d53..9d927eca 100644 --- a/.github/workflows/ci-reusable.yml +++ b/.github/workflows/ci-reusable.yml @@ -111,7 +111,7 @@ jobs: - name: Upload API test coverage if: ${{ inputs.upload_coverage }} - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v5 with: name: ${{ inputs.pr_number && format('api-coverage-pr-{0}', inputs.pr_number) || 'api-coverage' }} path: packages/api/coverage @@ -145,7 +145,7 @@ jobs: - name: Upload App test coverage if: ${{ inputs.upload_coverage }} - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v5 with: name: ${{ inputs.pr_number && format('app-coverage-pr-{0}', inputs.pr_number) || 'app-coverage' }} path: packages/app/coverage @@ -185,7 +185,7 @@ jobs: - name: Upload build artifacts if: ${{ inputs.upload_artifacts }} - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v5 with: name: build-artifacts path: | diff --git a/.github/workflows/ci-tricorder.yml b/.github/workflows/ci-tricorder.yml index 900f5ad3..9a337511 100644 --- a/.github/workflows/ci-tricorder.yml +++ b/.github/workflows/ci-tricorder.yml @@ -46,7 +46,7 @@ jobs: version: ${{ env.PNPM_VERSION }} - name: Setup Node.js - uses: actions/setup-node@v5 + uses: actions/setup-node@v6 with: node-version: ${{ env.NODE_VERSION }} cache: 'pnpm' @@ -70,7 +70,7 @@ jobs: version: ${{ env.PNPM_VERSION }} - name: Setup Node.js - uses: actions/setup-node@v5 + uses: actions/setup-node@v6 with: node-version: ${{ env.NODE_VERSION }} cache: 'pnpm' @@ -94,7 +94,7 @@ jobs: version: ${{ env.PNPM_VERSION }} - name: Setup Node.js - uses: actions/setup-node@v5 + uses: actions/setup-node@v6 with: node-version: ${{ env.NODE_VERSION }} cache: 'pnpm' @@ -118,7 +118,7 @@ jobs: version: ${{ env.PNPM_VERSION }} - name: Setup Node.js - uses: actions/setup-node@v5 + uses: actions/setup-node@v6 with: node-version: ${{ env.NODE_VERSION }} cache: 'pnpm' @@ -130,7 +130,7 @@ jobs: run: pnpm --filter @tuvixrss/tricorder test:coverage - name: Upload coverage - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v5 with: name: tricorder-coverage path: packages/tricorder/coverage @@ -158,7 +158,7 @@ jobs: version: ${{ env.PNPM_VERSION }} - name: Setup Node.js - uses: actions/setup-node@v5 + uses: actions/setup-node@v6 with: node-version: ${{ env.NODE_VERSION }} cache: 'pnpm' @@ -178,7 +178,7 @@ jobs: echo "โœ… Package is ready for publishing" - name: Upload build artifacts - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v5 with: name: tricorder-dist path: packages/tricorder/dist diff --git a/.github/workflows/docker-test.yml b/.github/workflows/docker-test.yml new file mode 100644 index 00000000..15d4381f --- /dev/null +++ b/.github/workflows/docker-test.yml @@ -0,0 +1,306 @@ +name: Docker Build & Test + +on: + pull_request: + paths: + - 'packages/api/**' + - 'packages/app/**' + - 'packages/tricorder/**' + - 'docker-compose.yml' + - 'docker-compose.test.yml' + - '**/Dockerfile' + - '.dockerignore' + - 'package.json' + - 'pnpm-lock.yaml' + push: + branches: + - main + - dev + +env: + # CI-specific environment variables + BETTER_AUTH_SECRET: test-secret-for-ci-must-be-at-least-32-characters-long-xyz + CORS_ORIGIN: http://localhost:5173 + DATABASE_PATH: /app/data/test.db + +jobs: + docker-build-and-test: + runs-on: ubuntu-latest + timeout-minutes: 30 + + steps: + - name: Checkout code + uses: actions/checkout@v6 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Build Docker images + run: | + echo "๐Ÿ“ฆ Building Docker images..." + docker compose build + env: + COMPOSE_DOCKER_CLI_BUILD: 1 + DOCKER_BUILDKIT: 1 + + - name: Check image sizes + run: | + echo "๐Ÿ“ Checking image sizes..." + + # Get image sizes + API_SIZE_RAW=$(docker images --format "{{.Size}}" tuvixrss-api:latest) + APP_SIZE_RAW=$(docker images --format "{{.Size}}" tuvixrss-app:latest) + + echo "API Image: ${API_SIZE_RAW}" + echo "App Image: ${APP_SIZE_RAW}" + + # Extract numeric size (handle both MB and GB) + API_SIZE=$(echo "$API_SIZE_RAW" | sed 's/MB//' | sed 's/GB/*1024/' | bc 2>/dev/null || echo "$API_SIZE_RAW" | sed 's/[^0-9.]//g') + APP_SIZE=$(echo "$APP_SIZE_RAW" | sed 's/MB//' | sed 's/GB/*1024/' | bc 2>/dev/null || echo "$APP_SIZE_RAW" | sed 's/[^0-9.]//g') + + # Convert to integer for comparison + API_SIZE_INT=$(printf "%.0f" "$API_SIZE" 2>/dev/null || echo "0") + APP_SIZE_INT=$(printf "%.0f" "$APP_SIZE" 2>/dev/null || echo "0") + + # Check size limits (API: 400MB, App: 100MB) + if [ "$API_SIZE_INT" -gt 400 ]; then + echo "โŒ API image too large: ${API_SIZE_RAW} (limit: 400MB)" + exit 1 + fi + + if [ "$APP_SIZE_INT" -gt 100 ]; then + echo "โŒ App image too large: ${APP_SIZE_RAW} (limit: 100MB)" + exit 1 + fi + + echo "โœ… Image sizes within limits" + echo "api_size=${API_SIZE_RAW}" >> $GITHUB_OUTPUT + echo "app_size=${APP_SIZE_RAW}" >> $GITHUB_OUTPUT + + - name: Prepare data directory + run: | + echo "๐Ÿ“ Creating data directory with proper permissions..." + mkdir -p ./data + # Set permissions so container user (uid 1001) can write + chmod 777 ./data + ls -la ./data + + - name: Start API container + run: | + echo "๐Ÿš€ Starting API container..." + docker compose up -d api --wait=false + + echo "๐Ÿ“‹ Container status:" + docker ps -a + + echo "" + echo "๐Ÿ” Initial API logs:" + sleep 2 + docker logs tuvix-api 2>&1 | head -30 || echo "No logs yet" + + - name: Wait for API to be healthy + run: | + echo "โณ Waiting for API to be healthy (max 90s)..." + SECONDS=0 + MAX_WAIT=90 + + while [ $SECONDS -lt $MAX_WAIT ]; do + STATUS=$(docker inspect --format="{{.State.Health.Status}}" tuvix-api 2>/dev/null || echo "none") + echo "[$SECONDS s] API health status: $STATUS" + + if [ "$STATUS" = "healthy" ]; then + echo "โœ… API is healthy!" + break + fi + + # Show recent logs every 10 seconds + if [ $((SECONDS % 10)) -eq 0 ]; then + echo "๐Ÿ“œ Recent API logs:" + docker logs tuvix-api 2>&1 | tail -20 + fi + + sleep 2 + done + + if [ $SECONDS -ge $MAX_WAIT ]; then + echo "โŒ API failed to become healthy after ${MAX_WAIT}s" + echo "" + echo "๐Ÿ“‹ Container status:" + docker ps -a + echo "" + echo "๐Ÿ“œ Full API logs:" + docker logs tuvix-api 2>&1 + exit 1 + fi + + - name: Start App container + run: | + echo "๐Ÿš€ Starting App container..." + docker compose up -d app + + echo "๐Ÿ“‹ Container status:" + docker ps -a + + echo "" + echo "๐Ÿงช Testing health endpoint manually:" + sleep 2 + docker exec tuvix-app wget -O- http://127.0.0.1:8080/health || echo "Manual health check failed" + + - name: Wait for App to be healthy + run: | + echo "โณ Waiting for App to be healthy (max 120s)..." + SECONDS=0 + MAX_WAIT=120 + + while [ $SECONDS -lt $MAX_WAIT ]; do + STATUS=$(docker inspect --format="{{.State.Health.Status}}" tuvix-app 2>/dev/null || echo "none") + echo "[$SECONDS s] App health status: $STATUS" + + if [ "$STATUS" = "healthy" ]; then + echo "โœ… App is healthy!" + break + fi + + sleep 2 + done + + if [ $SECONDS -ge $MAX_WAIT ]; then + echo "โŒ App failed to become healthy after ${MAX_WAIT}s" + echo "" + echo "๐Ÿ“‹ Container status:" + docker ps -a + echo "" + echo "๐Ÿ“œ Full App logs:" + docker logs tuvix-app 2>&1 + exit 1 + fi + + - name: Test API health endpoint + run: | + echo "๐Ÿ” Testing API health endpoint..." + RESPONSE=$(curl -s http://localhost:3001/health) + echo "Response: $RESPONSE" + + if echo "$RESPONSE" | grep -q '"status":"ok"'; then + echo "โœ… API health check passed" + else + echo "โŒ API health check failed" + exit 1 + fi + + - name: Test App health endpoint + run: | + echo "๐Ÿ” Testing App health endpoint..." + RESPONSE=$(curl -s http://localhost:5173/health) + echo "Response: $RESPONSE" + + if echo "$RESPONSE" | grep -q 'ok'; then + echo "โœ… App health check passed" + else + echo "โŒ App health check failed" + exit 1 + fi + + - name: Verify containers run as non-root + run: | + echo "๐Ÿ”’ Verifying security (non-root users)..." + + API_USER=$(docker exec tuvix-api id -u) + APP_USER=$(docker exec tuvix-app id -u) + + echo "API running as uid: $API_USER" + echo "App running as uid: $APP_USER" + + if [ "$API_USER" = "0" ]; then + echo "โŒ API running as root" + exit 1 + fi + + if [ "$APP_USER" = "0" ]; then + echo "โŒ App running as root" + exit 1 + fi + + if [ "$API_USER" != "1001" ]; then + echo "โš ๏ธ Warning: API not running as expected user (expected: 1001, got: $API_USER)" + fi + + if [ "$APP_USER" != "1001" ]; then + echo "โš ๏ธ Warning: App not running as expected user (expected: 1001, got: $APP_USER)" + fi + + echo "โœ… All containers running as non-root" + + - name: Verify database migrations + run: | + echo "๐Ÿ—„๏ธ Verifying database migrations..." + + # Check if database exists + if docker exec tuvix-api test -f /app/data/test.db; then + echo "โœ… Database file created" + docker exec tuvix-api ls -lh /app/data/test.db + else + echo "โŒ Database file not found" + exit 1 + fi + + # Check migration logs + if docker logs tuvix-api 2>&1 | grep -q "Migrations complete\|โœ… Migrations completed"; then + echo "โœ… Migrations executed successfully" + else + echo "โŒ Migrations not found in logs" + docker logs tuvix-api 2>&1 | grep -i migration || echo "No migration logs found" + exit 1 + fi + + - name: Run smoke tests + run: | + echo "๐Ÿงช Running smoke tests..." + + # Test that API is responding + curl -f http://localhost:3001/health || exit 1 + + # Test that App is serving content + curl -f http://localhost:5173/ || exit 1 + + # Test that App serves static assets + curl -f http://localhost:5173/health || exit 1 + + echo "โœ… All smoke tests passed" + + - name: Show container stats + if: always() + run: | + echo "๐Ÿ“Š Container statistics:" + docker stats --no-stream + + echo "" + echo "๐Ÿ“‹ Container details:" + docker ps -a + + - name: Show logs on failure + if: failure() + run: | + echo "====================" + echo "=== API Logs ===" + echo "====================" + docker logs tuvix-api + + echo "" + echo "====================" + echo "=== App Logs ===" + echo "====================" + docker logs tuvix-app + + echo "" + echo "====================" + echo "=== Docker Compose Logs ===" + echo "====================" + docker compose logs + + - name: Cleanup + if: always() + run: | + echo "๐Ÿงน Cleaning up..." + docker compose down -v + docker system prune -af --volumes diff --git a/.github/workflows/publish-tricorder.yml b/.github/workflows/publish-tricorder.yml index d77005f5..80e8c347 100644 --- a/.github/workflows/publish-tricorder.yml +++ b/.github/workflows/publish-tricorder.yml @@ -71,7 +71,7 @@ jobs: version: ${{ env.PNPM_VERSION }} - name: Setup Node.js - uses: actions/setup-node@v5 + uses: actions/setup-node@v6 with: node-version: ${{ env.NODE_VERSION }} cache: 'pnpm' @@ -100,7 +100,7 @@ jobs: npm pack --dry-run - name: Upload build artifacts - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v5 with: name: tricorder-dist path: packages/tricorder/dist @@ -125,7 +125,7 @@ jobs: version: ${{ env.PNPM_VERSION }} - name: Setup Node.js with NPM registry - uses: actions/setup-node@v5 + uses: actions/setup-node@v6 with: node-version: ${{ env.NODE_VERSION }} cache: 'pnpm' @@ -206,7 +206,7 @@ jobs: - name: Create GitHub Release if: startsWith(github.ref, 'refs/tags/') && steps.check_version.outputs.already_published == 'false' - uses: actions/github-script@v7 + uses: actions/github-script@v8 with: script: | const tagRef = context.ref.replace('refs/tags/', ''); diff --git a/.gitignore b/.gitignore index 20c64422..a5235722 100644 --- a/.gitignore +++ b/.gitignore @@ -68,6 +68,7 @@ data/ # Claude AI .claude/ +!.claude/settings.json # Share team settings, keep local settings private # Cursor AI .cursor/ .cursorrules @@ -140,6 +141,8 @@ temp/ .dev.vars wrangler.toml.local wrangler.toml # Actual config (use wrangler.example.toml as template) +packages/api/wrangler.toml +packages/api/wrangler.toml.local packages/api/migrations/ # Generated folder for Wrangler (copied from drizzle/) # ============================================ @@ -181,6 +184,9 @@ pnpm-lock.yaml.bak package-lock.json yarn.lock +# Individual package lockfiles (use workspace root lockfile) +packages/*/pnpm-lock.yaml + # ============================================ # Misc # ============================================ diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 00000000..d719c478 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,85 @@ +# TuvixRSS - Claude Code Guidelines + +TuvixRSS is a modern RSS reader with AI features, built on Cloudflare Workers. + +## Tech Stack + +- **API**: Hono (Cloudflare Workers), tRPC, Drizzle ORM, Cloudflare D1 +- **Frontend**: React, TanStack Router, TanStack Query, Tailwind CSS +- **Auth**: Better Auth (email/password) +- **Observability**: Sentry (errors, performance, metrics) +- **Email**: Resend +- **Monorepo**: pnpm workspaces (`packages/api`, `packages/app`, `packages/tricorder`) + +## Project Structure + +``` +packages/ + api/ # Cloudflare Workers API (Hono + tRPC) + src/ + routers/ # tRPC route handlers + services/ # Business logic (RSS fetching, email, etc.) + auth/ # Better Auth configuration + db/ # Drizzle schema and migrations + app/ # React frontend (Vite + TanStack) + tricorder/ # RSS/Atom feed discovery library +``` + +## Critical Rules + +### Production Database Operations + +**โ›” NEVER run production database migrations or modifications without explicit user permission.** + +This includes but is not limited to: + +- `wrangler d1 execute --remote` +- Any SQL migrations against production databases +- Schema alterations on live systems +- Data modifications in production + +**Required Process:** + +1. Generate migrations locally +2. Show the user what will change +3. Explain impact and safety +4. **ASK FOR PERMISSION** +5. Only after explicit approval, proceed + +**Rationale:** Production database operations are irreversible and can cause data loss, service disruption, or schema conflicts. Always give the user control over these decisions. + +**Exception:** Local/dev database operations (`--local`, `db:migrate:local`) are safe to run without asking. + +### Production Deployments + +**โ›” NEVER deploy to production. Only local development is allowed.** + +Deployment is explicitly forbidden and handled by CI/CD pipelines. + +## Common Workflows + +### Database Changes + +1. Modify schema in `packages/api/src/db/schema.ts` +2. Generate migration: `pnpm db:generate` +3. Review generated SQL in `packages/api/drizzle/` +4. Apply locally: `pnpm db:migrate:local` + +### Running Tests + +- API: `pnpm --filter @tuvixrss/api test` +- App: `pnpm --filter @tuvixrss/app test` +- All: `pnpm test` + +### Type Checking & Linting + +- `pnpm type-check` - Check all packages +- `pnpm lint` - Lint all packages +- `pnpm format` - Format with Prettier + +## Key Architecture Decisions + +- **Fire-and-forget emails**: Email sending doesn't block API responses; uses Sentry spans for tracking +- **Admin dashboard**: User management at `packages/api/src/routers/admin.ts` +- **Security audit logging**: All auth events logged to `security_audit_log` table +- **Rate limiting**: Cloudflare Workers rate limit API per plan tier diff --git a/README.md b/README.md index 94a023a8..fdbdad01 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,10 @@ Head over to **[tuvix.app](https://tuvix.app)** to create your free account and Immediately begin subscribing to your favorite feeds. Remember, you can always export your data to OPML and migrate to your own self-hosted instance, or any other RSS reader. +### Browser Extension + +Install the **[Tuvix Tricorder Extension](https://github.com/TechSquidTV/Tuvix-Tricorder-Extension)** for Chrome and Firefox to easily discover and subscribe to RSS feeds on any website with one click. + --- ## ๐Ÿš€ Deployment diff --git a/docker-compose.test.yml b/docker-compose.test.yml new file mode 100644 index 00000000..c9f1e735 --- /dev/null +++ b/docker-compose.test.yml @@ -0,0 +1,26 @@ +# Docker Compose configuration for CI/CD testing +# This file extends docker-compose.yml with test-specific settings +# +# Usage: +# docker compose -f docker-compose.yml -f docker-compose.test.yml up + +services: + api: + environment: + # Override for testing + - NODE_ENV=test + - DATABASE_PATH=/app/data/test.db + # Faster health checks for CI + healthcheck: + interval: 5s + timeout: 3s + start_period: 10s + retries: 10 + + app: + # Faster health checks for CI + healthcheck: + interval: 5s + timeout: 3s + start_period: 5s + retries: 10 diff --git a/docker-compose.yml b/docker-compose.yml index a305fcae..81800ba4 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,8 +1,8 @@ services: api: build: - context: ./packages/api - dockerfile: Dockerfile + context: . + dockerfile: ./packages/api/Dockerfile pull_policy: build container_name: tuvix-api restart: unless-stopped @@ -11,7 +11,7 @@ services: volumes: - ./data:/app/data environment: - - DATABASE_PATH=/app/data/tuvix.db + - DATABASE_PATH=${DATABASE_PATH:-/app/data/tuvix.db} - PORT=3001 - NODE_ENV=production - BETTER_AUTH_SECRET=${BETTER_AUTH_SECRET:-change-me-in-production} @@ -21,29 +21,29 @@ services: - SENTRY_RELEASE=${SENTRY_RELEASE:-} healthcheck: test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3001/health"] - interval: 30s + interval: 5s timeout: 3s - start_period: 5s + start_period: 30s retries: 3 networks: - tuvix-network app: build: - context: ./packages/app - dockerfile: Dockerfile + context: . + dockerfile: ./packages/app/Dockerfile args: - VITE_API_URL=${VITE_API_URL:-http://localhost:3001/trpc} pull_policy: build container_name: tuvix-app restart: unless-stopped ports: - - "5173:80" + - "5173:8080" healthcheck: - test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost/health"] - interval: 30s + test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://127.0.0.1:8080/health"] + interval: 5s timeout: 3s - start_period: 5s + start_period: 10s retries: 3 depends_on: api: diff --git a/docs/deployment.md b/docs/deployment.md index c4012114..0e5508b2 100644 --- a/docs/deployment.md +++ b/docs/deployment.md @@ -293,15 +293,22 @@ docker compose up -d #### Dockerfile Structure +**Important:** Both Dockerfiles use the monorepo root as the build context and copy workspace files. This ensures the correct `pnpm-lock.yaml` from the workspace root is used. + **API Dockerfile** (`packages/api/Dockerfile`): - Multi-stage build (builder + production) +- Build context: monorepo root (not `packages/api`) +- Copies workspace files (`pnpm-workspace.yaml`, root `pnpm-lock.yaml`) - Installs pnpm 10.19.0 +- Installs dependencies for all needed packages (api + tricorder) - Runs migrations on startup - Exposes port 3001 - Health check on /health endpoint **App Dockerfile** (`packages/app/Dockerfile`): - Multi-stage build with nginx +- Build context: monorepo root (not `packages/app`) +- Copies workspace files (`pnpm-workspace.yaml`, root `pnpm-lock.yaml`) - Accepts VITE_API_URL build arg - SPA routing support - Static asset caching @@ -312,7 +319,9 @@ docker compose up -d ```yaml services: api: - build: ./packages/api + build: + context: . + dockerfile: ./packages/api/Dockerfile ports: - "3001:3001" volumes: @@ -329,7 +338,8 @@ services: app: build: - context: ./packages/app + context: . + dockerfile: ./packages/app/Dockerfile args: - VITE_API_URL=${VITE_API_URL:-http://localhost:3001/trpc} ports: diff --git a/docs/features/url-subscribe.md b/docs/features/url-subscribe.md index b6b190e0..7965d9f3 100644 --- a/docs/features/url-subscribe.md +++ b/docs/features/url-subscribe.md @@ -9,17 +9,17 @@ Tuvix supports multiple ways to subscribe to RSS feeds and import OPML files, in ### Basic URL Format ``` -https://feedsmith.dev/app/subscriptions?subscribe= +https://feed.tuvix.app/app/subscriptions?subscribe= ``` ### Examples ``` # Subscribe to a blog feed -https://feedsmith.dev/app/subscriptions?subscribe=https%3A%2F%2Fblog.example.com%2Ffeed.xml +https://feed.tuvix.app/app/subscriptions?subscribe=https%3A%2F%2Fblog.example.com%2Ffeed.xml # Subscribe from a website URL (auto-discovery) -https://feedsmith.dev/app/subscriptions?subscribe=https%3A%2F%2Fblog.example.com +https://feed.tuvix.app/app/subscriptions?subscribe=https%3A%2F%2Fblog.example.com ``` ## How It Works @@ -57,7 +57,7 @@ Create a browser bookmarklet for one-click subscriptions: ```javascript javascript:(function(){ - const tuvixUrl = 'https://feedsmith.dev/app/subscriptions'; + const tuvixUrl = 'https://feed.tuvix.app/app/subscriptions'; const currentUrl = encodeURIComponent(window.location.href); window.open(`${tuvixUrl}?subscribe=${currentUrl}`, '_blank'); })(); @@ -68,7 +68,7 @@ javascript:(function(){ Add "Subscribe in Tuvix" buttons to your blog: ```html - + Subscribe in Tuvix ``` @@ -81,12 +81,12 @@ Use the URL format in browser extensions to detect feeds on pages and provide qu ```html - + ๐Ÿ“ฐ Follow our blog in Tuvix - + ๐Ÿ”” Get changelog updates ``` diff --git a/package.json b/package.json index 0430fb67..1de15f7c 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,8 @@ "docker:down": "docker compose down", "docker:logs": "docker compose logs -f", "docker:up": "docker compose up -d", + "docker:test": "bash scripts/test-docker.sh", + "docker:test:ci": "docker compose -f docker-compose.yml -f docker-compose.test.yml up --abort-on-container-exit", "format": "pnpm run format:root && pnpm --filter @tuvixrss/tricorder format && pnpm --filter @tuvixrss/api format && pnpm --filter @tuvixrss/app format", "format:check": "pnpm run format:root:check && pnpm --filter @tuvixrss/tricorder format:check && pnpm --filter @tuvixrss/api format:check && pnpm --filter @tuvixrss/app format:check", "format:root": "prettier --write \"*.{js,json,md}\" \"scripts/*.js\"", @@ -86,7 +88,7 @@ "devDependencies": { "concurrently": "^9.2.1", "nyc": "^17.1.0", - "prettier": "^3.6.2", - "shadcn": "^3.5.0" + "prettier": "^3.7.4", + "shadcn": "^3.5.1" } } diff --git a/packages/api/.dockerignore b/packages/api/.dockerignore new file mode 100644 index 00000000..e701c28b --- /dev/null +++ b/packages/api/.dockerignore @@ -0,0 +1,9 @@ +node_modules/ +dist/ +coverage/ +*.test.ts +*.spec.ts +.env +.env.* +!.env.example +*.log diff --git a/packages/api/Dockerfile b/packages/api/Dockerfile index 9095095d..771da193 100644 --- a/packages/api/Dockerfile +++ b/packages/api/Dockerfile @@ -5,41 +5,61 @@ WORKDIR /app # Install pnpm RUN npm install -g pnpm@10.19.0 +# Copy workspace files +COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./ + # Copy package files -COPY package.json pnpm-lock.yaml* ./ +COPY packages/api/package.json ./packages/api/ +COPY packages/tricorder/package.json ./packages/tricorder/ + +# Install all dependencies (includes workspace deps) RUN pnpm install --frozen-lockfile --prod=false -# Copy source code -COPY . . +# Copy source code for all needed packages +COPY packages/api ./packages/api +COPY packages/tricorder ./packages/tricorder -# Build the application -RUN pnpm build +# Build tricorder first (dependency of api) +RUN pnpm --filter @tuvixrss/tricorder build + +# Build the application with tsup (bundles and resolves ESM) +RUN pnpm --filter @tuvixrss/api build # Production stage FROM node:20-alpine +# Create non-root user FIRST (before any files to avoid permission layer bloat) +RUN addgroup -g 1001 -S nodejs && \ + adduser -S nodejs -u 1001 + WORKDIR /app -# Install pnpm +# Install pnpm for production dependencies RUN npm install -g pnpm@10.19.0 -# Copy package files and install production dependencies only -COPY package.json pnpm-lock.yaml* ./ +# Copy package files with ownership +COPY --chown=nodejs:nodejs package.json pnpm-lock.yaml pnpm-workspace.yaml ./ +COPY --chown=nodejs:nodejs packages/api/package.json ./packages/api/ +COPY --chown=nodejs:nodejs packages/tricorder/package.json ./packages/tricorder/ + +# Install production dependencies only RUN pnpm install --frozen-lockfile --prod -# Copy built files from builder -COPY --from=builder /app/dist ./dist -COPY --from=builder /app/drizzle ./drizzle +# Copy built artifacts with correct ownership +COPY --from=builder --chown=nodejs:nodejs /app/packages/api/dist ./packages/api/dist +COPY --from=builder --chown=nodejs:nodejs /app/packages/api/drizzle ./packages/api/drizzle + +# Create data directory with ownership +RUN mkdir -p /app/data && chown nodejs:nodejs /app/data -# Create data directory for SQLite database -RUN mkdir -p /app/data +USER nodejs # Expose the API port EXPOSE 3001 # Health check -HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ +HEALTHCHECK --interval=30s --timeout=3s --start-period=30s --retries=3 \ CMD wget --no-verbose --tries=1 --spider http://localhost:3001/health || exit 1 -# Run migrations then start the server -CMD ["sh", "-c", "node dist/db/migrate-local.js && node dist/entries/node.js"] +# Start the server (migrations run automatically inside node.ts) +CMD ["node", "packages/api/dist/entries/node.js"] diff --git a/packages/api/drizzle/0006_fix_security_audit_log_default.sql b/packages/api/drizzle/0006_fix_security_audit_log_default.sql new file mode 100644 index 00000000..32481a51 --- /dev/null +++ b/packages/api/drizzle/0006_fix_security_audit_log_default.sql @@ -0,0 +1,29 @@ +PRAGMA foreign_keys=OFF; +--> statement-breakpoint +CREATE TABLE `__new_security_audit_log` ( + `id` integer PRIMARY KEY AUTOINCREMENT NOT NULL, + `user_id` integer, + `action` text NOT NULL, + `ip_address` text, + `user_agent` text, + `metadata` text, + `success` integer NOT NULL, + `created_at` integer DEFAULT (cast(unixepoch('subsecond') * 1000 as integer)) NOT NULL, + FOREIGN KEY (`user_id`) REFERENCES `user`(`id`) ON UPDATE no action ON DELETE set null +); +--> statement-breakpoint +INSERT INTO `__new_security_audit_log`("id", "user_id", "action", "ip_address", "user_agent", "metadata", "success", "created_at") +SELECT "id", "user_id", "action", "ip_address", "user_agent", "metadata", "success", "created_at" +FROM `security_audit_log`; +--> statement-breakpoint +DROP TABLE `security_audit_log`; +--> statement-breakpoint +ALTER TABLE `__new_security_audit_log` RENAME TO `security_audit_log`; +--> statement-breakpoint +CREATE INDEX `idx_security_audit_log_user_id` ON `security_audit_log` (`user_id`); +--> statement-breakpoint +CREATE INDEX `idx_security_audit_log_action` ON `security_audit_log` (`action`); +--> statement-breakpoint +CREATE INDEX `idx_security_audit_log_created_at` ON `security_audit_log` (`created_at`); +--> statement-breakpoint +PRAGMA foreign_keys=ON; diff --git a/packages/api/drizzle/meta/0006_snapshot.json b/packages/api/drizzle/meta/0006_snapshot.json new file mode 100644 index 00000000..15a5cdfb --- /dev/null +++ b/packages/api/drizzle/meta/0006_snapshot.json @@ -0,0 +1,2325 @@ +{ + "version": "6", + "dialect": "sqlite", + "id": "e8126989-6d66-49c1-95ad-3392316739fc", + "prevId": "c31c4ddf-ba6f-41a5-9052-d13da161a011", + "tables": { + "account": { + "name": "account", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "account_id": { + "name": "account_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "provider_id": { + "name": "provider_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "access_token": { + "name": "access_token", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "refresh_token": { + "name": "refresh_token", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "id_token": { + "name": "id_token", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "access_token_expires_at": { + "name": "access_token_expires_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "refresh_token_expires_at": { + "name": "refresh_token_expires_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "scope": { + "name": "scope", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "password": { + "name": "password", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(cast(unixepoch('subsecond') * 1000 as integer))" + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "account_user_id_user_id_fk": { + "name": "account_user_id_user_id_fk", + "tableFrom": "account", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "api_usage_log": { + "name": "api_usage_log", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "endpoint": { + "name": "endpoint", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "method": { + "name": "method", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "status_code": { + "name": "status_code", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "duration_ms": { + "name": "duration_ms", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "ip_address": { + "name": "ip_address", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "idx_api_usage_log_user_id": { + "name": "idx_api_usage_log_user_id", + "columns": [ + "user_id" + ], + "isUnique": false + }, + "idx_api_usage_log_created_at": { + "name": "idx_api_usage_log_created_at", + "columns": [ + "created_at" + ], + "isUnique": false + }, + "idx_api_usage_log_endpoint": { + "name": "idx_api_usage_log_endpoint", + "columns": [ + "endpoint" + ], + "isUnique": false + } + }, + "foreignKeys": { + "api_usage_log_user_id_user_id_fk": { + "name": "api_usage_log_user_id_user_id_fk", + "tableFrom": "api_usage_log", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "articles": { + "name": "articles", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "source_id": { + "name": "source_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "guid": { + "name": "guid", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "link": { + "name": "link", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "content": { + "name": "content", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "author": { + "name": "author", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "image_url": { + "name": "image_url", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "audio_url": { + "name": "audio_url", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "comment_link": { + "name": "comment_link", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "published_at": { + "name": "published_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "idx_articles_source_id": { + "name": "idx_articles_source_id", + "columns": [ + "source_id" + ], + "isUnique": false + }, + "idx_articles_published_at": { + "name": "idx_articles_published_at", + "columns": [ + "published_at" + ], + "isUnique": false + }, + "idx_articles_guid": { + "name": "idx_articles_guid", + "columns": [ + "guid" + ], + "isUnique": false + }, + "idx_articles_audio_url": { + "name": "idx_articles_audio_url", + "columns": [ + "audio_url" + ], + "isUnique": false + }, + "articles_source_id_guid_unique": { + "name": "articles_source_id_guid_unique", + "columns": [ + "source_id", + "guid" + ], + "isUnique": true + } + }, + "foreignKeys": { + "articles_source_id_sources_id_fk": { + "name": "articles_source_id_sources_id_fk", + "tableFrom": "articles", + "tableTo": "sources", + "columnsFrom": [ + "source_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "blocked_domains": { + "name": "blocked_domains", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "domain": { + "name": "domain", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "reason": { + "name": "reason", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_by": { + "name": "created_by", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "blocked_domains_domain_unique": { + "name": "blocked_domains_domain_unique", + "columns": [ + "domain" + ], + "isUnique": true + }, + "idx_blocked_domains_domain": { + "name": "idx_blocked_domains_domain", + "columns": [ + "domain" + ], + "isUnique": false + }, + "idx_blocked_domains_reason": { + "name": "idx_blocked_domains_reason", + "columns": [ + "reason" + ], + "isUnique": false + }, + "idx_blocked_domains_created_at": { + "name": "idx_blocked_domains_created_at", + "columns": [ + "created_at" + ], + "isUnique": false + } + }, + "foreignKeys": { + "blocked_domains_created_by_user_id_fk": { + "name": "blocked_domains_created_by_user_id_fk", + "tableFrom": "blocked_domains", + "tableTo": "user", + "columnsFrom": [ + "created_by" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "categories": { + "name": "categories", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "color": { + "name": "color", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "icon": { + "name": "icon", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "idx_categories_user_id": { + "name": "idx_categories_user_id", + "columns": [ + "user_id" + ], + "isUnique": false + }, + "idx_categories_user_id_name_normalized": { + "name": "idx_categories_user_id_name_normalized", + "columns": [ + "user_id", + "LOWER(\"name\")" + ], + "isUnique": true + } + }, + "foreignKeys": { + "categories_user_id_user_id_fk": { + "name": "categories_user_id_user_id_fk", + "tableFrom": "categories", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "feed_categories": { + "name": "feed_categories", + "columns": { + "feed_id": { + "name": "feed_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "category_id": { + "name": "category_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "idx_feed_categories_feed_id": { + "name": "idx_feed_categories_feed_id", + "columns": [ + "feed_id" + ], + "isUnique": false + }, + "idx_feed_categories_category_id": { + "name": "idx_feed_categories_category_id", + "columns": [ + "category_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "feed_categories_feed_id_feeds_id_fk": { + "name": "feed_categories_feed_id_feeds_id_fk", + "tableFrom": "feed_categories", + "tableTo": "feeds", + "columnsFrom": [ + "feed_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "feed_categories_category_id_categories_id_fk": { + "name": "feed_categories_category_id_categories_id_fk", + "tableFrom": "feed_categories", + "tableTo": "categories", + "columnsFrom": [ + "category_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "feed_categories_feed_id_category_id_pk": { + "columns": [ + "feed_id", + "category_id" + ], + "name": "feed_categories_feed_id_category_id_pk" + } + }, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "feeds": { + "name": "feeds", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "slug": { + "name": "slug", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "public": { + "name": "public", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": true + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "idx_feeds_user_id": { + "name": "idx_feeds_user_id", + "columns": [ + "user_id" + ], + "isUnique": false + }, + "idx_feeds_slug": { + "name": "idx_feeds_slug", + "columns": [ + "slug" + ], + "isUnique": false + }, + "feeds_user_id_slug_unique": { + "name": "feeds_user_id_slug_unique", + "columns": [ + "user_id", + "slug" + ], + "isUnique": true + } + }, + "foreignKeys": { + "feeds_user_id_user_id_fk": { + "name": "feeds_user_id_user_id_fk", + "tableFrom": "feeds", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "global_settings": { + "name": "global_settings", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "max_login_attempts": { + "name": "max_login_attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 5 + }, + "login_attempt_window_minutes": { + "name": "login_attempt_window_minutes", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 15 + }, + "lockout_duration_minutes": { + "name": "lockout_duration_minutes", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 30 + }, + "allow_registration": { + "name": "allow_registration", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": true + }, + "require_email_verification": { + "name": "require_email_verification", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "admin_bypass_email_verification": { + "name": "admin_bypass_email_verification", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": true + }, + "password_reset_token_expiry_hours": { + "name": "password_reset_token_expiry_hours", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 1 + }, + "fetch_interval_minutes": { + "name": "fetch_interval_minutes", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 60 + }, + "prune_days": { + "name": "prune_days", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 90 + }, + "last_rss_fetch_at": { + "name": "last_rss_fetch_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "last_prune_at": { + "name": "last_prune_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "updated_by": { + "name": "updated_by", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "global_settings_updated_by_user_id_fk": { + "name": "global_settings_updated_by_user_id_fk", + "tableFrom": "global_settings", + "tableTo": "user", + "columnsFrom": [ + "updated_by" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "password_reset_tokens": { + "name": "password_reset_tokens", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "expires_at": { + "name": "expires_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "used": { + "name": "used", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "password_reset_tokens_token_unique": { + "name": "password_reset_tokens_token_unique", + "columns": [ + "token" + ], + "isUnique": true + }, + "idx_password_reset_tokens_token": { + "name": "idx_password_reset_tokens_token", + "columns": [ + "token" + ], + "isUnique": false + }, + "idx_password_reset_tokens_user_id": { + "name": "idx_password_reset_tokens_user_id", + "columns": [ + "user_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "password_reset_tokens_user_id_user_id_fk": { + "name": "password_reset_tokens_user_id_user_id_fk", + "tableFrom": "password_reset_tokens", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "plans": { + "name": "plans", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "max_sources": { + "name": "max_sources", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "max_public_feeds": { + "name": "max_public_feeds", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "max_categories": { + "name": "max_categories", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "api_rate_limit_per_minute": { + "name": "api_rate_limit_per_minute", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "public_feed_rate_limit_per_minute": { + "name": "public_feed_rate_limit_per_minute", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "price_cents": { + "name": "price_cents", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "features": { + "name": "features", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "public_feed_access_log": { + "name": "public_feed_access_log", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "feed_id": { + "name": "feed_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "ip_address": { + "name": "ip_address", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "accessed_at": { + "name": "accessed_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "idx_public_feed_access_log_feed_id": { + "name": "idx_public_feed_access_log_feed_id", + "columns": [ + "feed_id" + ], + "isUnique": false + }, + "idx_public_feed_access_log_accessed_at": { + "name": "idx_public_feed_access_log_accessed_at", + "columns": [ + "accessed_at" + ], + "isUnique": false + } + }, + "foreignKeys": { + "public_feed_access_log_feed_id_feeds_id_fk": { + "name": "public_feed_access_log_feed_id_feeds_id_fk", + "tableFrom": "public_feed_access_log", + "tableTo": "feeds", + "columnsFrom": [ + "feed_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "security_audit_log": { + "name": "security_audit_log", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "action": { + "name": "action", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "ip_address": { + "name": "ip_address", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "metadata": { + "name": "metadata", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "success": { + "name": "success", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(cast(unixepoch('subsecond') * 1000 as integer))" + } + }, + "indexes": { + "idx_security_audit_log_user_id": { + "name": "idx_security_audit_log_user_id", + "columns": [ + "user_id" + ], + "isUnique": false + }, + "idx_security_audit_log_action": { + "name": "idx_security_audit_log_action", + "columns": [ + "action" + ], + "isUnique": false + }, + "idx_security_audit_log_created_at": { + "name": "idx_security_audit_log_created_at", + "columns": [ + "created_at" + ], + "isUnique": false + } + }, + "foreignKeys": { + "security_audit_log_user_id_user_id_fk": { + "name": "security_audit_log_user_id_user_id_fk", + "tableFrom": "security_audit_log", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "session": { + "name": "session", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "expires_at": { + "name": "expires_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(cast(unixepoch('subsecond') * 1000 as integer))" + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "ip_address": { + "name": "ip_address", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "impersonated_by": { + "name": "impersonated_by", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "session_token_unique": { + "name": "session_token_unique", + "columns": [ + "token" + ], + "isUnique": true + } + }, + "foreignKeys": { + "session_user_id_user_id_fk": { + "name": "session_user_id_user_id_fk", + "tableFrom": "session", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "sources": { + "name": "sources", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "url": { + "name": "url", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "site_url": { + "name": "site_url", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "icon_url": { + "name": "icon_url", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "icon_type": { + "name": "icon_type", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "'auto'" + }, + "icon_updated_at": { + "name": "icon_updated_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "last_fetched": { + "name": "last_fetched", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "sources_url_unique": { + "name": "sources_url_unique", + "columns": [ + "url" + ], + "isUnique": true + }, + "idx_sources_url": { + "name": "idx_sources_url", + "columns": [ + "url" + ], + "isUnique": false + }, + "idx_sources_icon_url": { + "name": "idx_sources_icon_url", + "columns": [ + "icon_url" + ], + "isUnique": false + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "subscription_categories": { + "name": "subscription_categories", + "columns": { + "subscription_id": { + "name": "subscription_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "category_id": { + "name": "category_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "idx_subscription_categories_subscription_id": { + "name": "idx_subscription_categories_subscription_id", + "columns": [ + "subscription_id" + ], + "isUnique": false + }, + "idx_subscription_categories_category_id": { + "name": "idx_subscription_categories_category_id", + "columns": [ + "category_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "subscription_categories_subscription_id_subscriptions_id_fk": { + "name": "subscription_categories_subscription_id_subscriptions_id_fk", + "tableFrom": "subscription_categories", + "tableTo": "subscriptions", + "columnsFrom": [ + "subscription_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "subscription_categories_category_id_categories_id_fk": { + "name": "subscription_categories_category_id_categories_id_fk", + "tableFrom": "subscription_categories", + "tableTo": "categories", + "columnsFrom": [ + "category_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "subscription_categories_subscription_id_category_id_pk": { + "columns": [ + "subscription_id", + "category_id" + ], + "name": "subscription_categories_subscription_id_category_id_pk" + } + }, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "subscription_filters": { + "name": "subscription_filters", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "subscription_id": { + "name": "subscription_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "field": { + "name": "field", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "match_type": { + "name": "match_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "pattern": { + "name": "pattern", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "case_sensitive": { + "name": "case_sensitive", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "idx_subscription_filters_subscription_id": { + "name": "idx_subscription_filters_subscription_id", + "columns": [ + "subscription_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "subscription_filters_subscription_id_subscriptions_id_fk": { + "name": "subscription_filters_subscription_id_subscriptions_id_fk", + "tableFrom": "subscription_filters", + "tableTo": "subscriptions", + "columnsFrom": [ + "subscription_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "subscriptions": { + "name": "subscriptions", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "source_id": { + "name": "source_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "custom_title": { + "name": "custom_title", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "filter_enabled": { + "name": "filter_enabled", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "filter_mode": { + "name": "filter_mode", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'include'" + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "idx_subscriptions_user_id": { + "name": "idx_subscriptions_user_id", + "columns": [ + "user_id" + ], + "isUnique": false + }, + "idx_subscriptions_source_id": { + "name": "idx_subscriptions_source_id", + "columns": [ + "source_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "subscriptions_user_id_user_id_fk": { + "name": "subscriptions_user_id_user_id_fk", + "tableFrom": "subscriptions", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "subscriptions_source_id_sources_id_fk": { + "name": "subscriptions_source_id_sources_id_fk", + "tableFrom": "subscriptions", + "tableTo": "sources", + "columnsFrom": [ + "source_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "usage_stats": { + "name": "usage_stats", + "columns": { + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "source_count": { + "name": "source_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 0 + }, + "public_feed_count": { + "name": "public_feed_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 0 + }, + "category_count": { + "name": "category_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 0 + }, + "article_count": { + "name": "article_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 0 + }, + "last_updated": { + "name": "last_updated", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "usage_stats_user_id_user_id_fk": { + "name": "usage_stats_user_id_user_id_fk", + "tableFrom": "usage_stats", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "user": { + "name": "user", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "email_verified": { + "name": "email_verified", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "image": { + "name": "image", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(cast(unixepoch('subsecond') * 1000 as integer))" + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(cast(unixepoch('subsecond') * 1000 as integer))" + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "display_username": { + "name": "display_username", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "role": { + "name": "role", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "plan": { + "name": "plan", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "'free'" + }, + "banned": { + "name": "banned", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": false + }, + "ban_reason": { + "name": "ban_reason", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "ban_expires": { + "name": "ban_expires", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "user_email_unique": { + "name": "user_email_unique", + "columns": [ + "email" + ], + "isUnique": true + }, + "user_username_unique": { + "name": "user_username_unique", + "columns": [ + "username" + ], + "isUnique": true + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "user_article_states": { + "name": "user_article_states", + "columns": { + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "article_id": { + "name": "article_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "read": { + "name": "read", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "saved": { + "name": "saved", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "audio_position": { + "name": "audio_position", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": 0 + }, + "audio_duration": { + "name": "audio_duration", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "audio_completed_at": { + "name": "audio_completed_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "audio_last_played_at": { + "name": "audio_last_played_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "idx_user_article_states_user_id": { + "name": "idx_user_article_states_user_id", + "columns": [ + "user_id" + ], + "isUnique": false + }, + "idx_user_article_states_read": { + "name": "idx_user_article_states_read", + "columns": [ + "read" + ], + "isUnique": false + }, + "idx_user_article_states_saved": { + "name": "idx_user_article_states_saved", + "columns": [ + "saved" + ], + "isUnique": false + }, + "idx_user_article_states_audio_position": { + "name": "idx_user_article_states_audio_position", + "columns": [ + "audio_position" + ], + "isUnique": false + } + }, + "foreignKeys": { + "user_article_states_user_id_user_id_fk": { + "name": "user_article_states_user_id_user_id_fk", + "tableFrom": "user_article_states", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "user_article_states_article_id_articles_id_fk": { + "name": "user_article_states_article_id_articles_id_fk", + "tableFrom": "user_article_states", + "tableTo": "articles", + "columnsFrom": [ + "article_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "user_article_states_user_id_article_id_pk": { + "columns": [ + "user_id", + "article_id" + ], + "name": "user_article_states_user_id_article_id_pk" + } + }, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "user_limits": { + "name": "user_limits", + "columns": { + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "max_sources": { + "name": "max_sources", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "max_public_feeds": { + "name": "max_public_feeds", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "max_categories": { + "name": "max_categories", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "api_rate_limit_per_minute": { + "name": "api_rate_limit_per_minute", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "public_feed_rate_limit_per_minute": { + "name": "public_feed_rate_limit_per_minute", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "user_limits_user_id_user_id_fk": { + "name": "user_limits_user_id_user_id_fk", + "tableFrom": "user_limits", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "user_settings": { + "name": "user_settings", + "columns": { + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "theme": { + "name": "theme", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'system'" + }, + "auto_age_days": { + "name": "auto_age_days", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 7 + }, + "default_filter": { + "name": "default_filter", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'all'" + }, + "share_email": { + "name": "share_email", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": true + }, + "share_hackernews": { + "name": "share_hackernews", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "share_reddit": { + "name": "share_reddit", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "share_twitter": { + "name": "share_twitter", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "share_bluesky": { + "name": "share_bluesky", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "share_mastodon": { + "name": "share_mastodon", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "idx_user_settings_user_id": { + "name": "idx_user_settings_user_id", + "columns": [ + "user_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "user_settings_user_id_user_id_fk": { + "name": "user_settings_user_id_user_id_fk", + "tableFrom": "user_settings", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "verification": { + "name": "verification", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "identifier": { + "name": "identifier", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "expires_at": { + "name": "expires_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(cast(unixepoch('subsecond') * 1000 as integer))" + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(cast(unixepoch('subsecond') * 1000 as integer))" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + } + }, + "views": {}, + "enums": {}, + "_meta": { + "schemas": {}, + "tables": {}, + "columns": {} + }, + "internal": { + "indexes": { + "idx_categories_user_id_name_normalized": { + "columns": { + "LOWER(\"name\")": { + "isExpression": true + } + } + } + } + } +} \ No newline at end of file diff --git a/packages/api/drizzle/meta/_journal.json b/packages/api/drizzle/meta/_journal.json index 6c19954a..e7730760 100644 --- a/packages/api/drizzle/meta/_journal.json +++ b/packages/api/drizzle/meta/_journal.json @@ -43,6 +43,13 @@ "when": 1764633557616, "tag": "0005_panoramic_magdalene", "breakpoints": true + }, + { + "idx": 6, + "version": "6", + "when": 1764822482306, + "tag": "0006_fix_security_audit_log_default", + "breakpoints": true } ] } \ No newline at end of file diff --git a/packages/api/package.json b/packages/api/package.json index eea29c71..fd8c4bad 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -14,7 +14,8 @@ "scripts": { "dev": "tsx watch --env-file=.env --env-file=../../.env src/entries/node.ts", "dev:workers": "wrangler dev --persist-to .wrangler/state", - "build": "tsc", + "build": "tsup", + "build:tsc": "tsc", "start": "node dist/entries/node.js", "type-check": "tsc --noEmit", "test": "vitest run", @@ -79,6 +80,7 @@ "knip": "^5.70.1", "prettier": "^3.6.2", "react": "^19.2.0", + "tsup": "^8.5.1", "tsx": "^4.20.6", "typescript": "^5.9.3", "vitest": "^4.0.13", diff --git a/packages/api/pnpm-lock.yaml b/packages/api/pnpm-lock.yaml deleted file mode 100644 index fdfad47c..00000000 --- a/packages/api/pnpm-lock.yaml +++ /dev/null @@ -1,3616 +0,0 @@ -lockfileVersion: '9.0' - -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false - -importers: - - .: - dependencies: - '@trpc/server': - specifier: ^11.7.1 - version: 11.7.1(typescript@5.9.3) - bcrypt: - specifier: ^6.0.0 - version: 6.0.0 - better-sqlite3: - specifier: ^12.4.1 - version: 12.4.1 - cors: - specifier: ^2.8.5 - version: 2.8.5 - drizzle-orm: - specifier: ^0.44.7 - version: 0.44.7(@cloudflare/workers-types@4.20251111.0)(@types/better-sqlite3@7.6.13)(better-sqlite3@12.4.1) - drizzle-zod: - specifier: ^0.8.3 - version: 0.8.3(drizzle-orm@0.44.7(@cloudflare/workers-types@4.20251111.0)(@types/better-sqlite3@7.6.13)(better-sqlite3@12.4.1))(zod@4.1.12) - eslint-plugin-drizzle: - specifier: ^0.2.3 - version: 0.2.3(eslint@9.39.1) - express: - specifier: ^5.1.0 - version: 5.1.0 - feedsmith: - specifier: ^2.4.0 - version: 2.4.0 - jose: - specifier: ^6.1.1 - version: 6.1.1 - node-cron: - specifier: ^4.2.1 - version: 4.2.1 - zod: - specifier: ^4.1.12 - version: 4.1.12 - devDependencies: - '@cloudflare/workers-types': - specifier: ^4.20251111.0 - version: 4.20251111.0 - '@types/bcrypt': - specifier: ^6.0.0 - version: 6.0.0 - '@types/better-sqlite3': - specifier: ^7.6.13 - version: 7.6.13 - '@types/cors': - specifier: ^2.8.19 - version: 2.8.19 - '@types/express': - specifier: ^5.0.5 - version: 5.0.5 - '@types/node': - specifier: ^24.10.0 - version: 24.10.0 - '@types/node-cron': - specifier: ^3.0.11 - version: 3.0.11 - '@typescript-eslint/eslint-plugin': - specifier: ^8.46.4 - version: 8.46.4(@typescript-eslint/parser@8.46.4(eslint@9.39.1)(typescript@5.9.3))(eslint@9.39.1)(typescript@5.9.3) - '@typescript-eslint/parser': - specifier: ^8.46.4 - version: 8.46.4(eslint@9.39.1)(typescript@5.9.3) - drizzle-kit: - specifier: ^0.31.6 - version: 0.31.6 - eslint: - specifier: ^9.39.1 - version: 9.39.1 - prettier: - specifier: ^3.6.2 - version: 3.6.2 - tsx: - specifier: ^4.20.6 - version: 4.20.6 - typescript: - specifier: ^5.9.3 - version: 5.9.3 - wrangler: - specifier: ^4.47.0 - version: 4.47.0(@cloudflare/workers-types@4.20251111.0) - -packages: - - '@cloudflare/kv-asset-handler@0.4.0': - resolution: {integrity: sha512-+tv3z+SPp+gqTIcImN9o0hqE9xyfQjI1XD9pL6NuKjua9B1y7mNYv0S9cP+QEbA4ppVgGZEmKOvHX5G5Ei1CVA==} - engines: {node: '>=18.0.0'} - - '@cloudflare/unenv-preset@2.7.10': - resolution: {integrity: sha512-mvsNAiJSduC/9yxv1ZpCxwgAXgcuoDvkl8yaHjxoLpFxXy2ugc6TZK20EKgv4yO0vZhAEKwqJm+eGOzf8Oc45w==} - peerDependencies: - unenv: 2.0.0-rc.24 - workerd: ^1.20251106.1 - peerDependenciesMeta: - workerd: - optional: true - - '@cloudflare/workerd-darwin-64@1.20251109.0': - resolution: {integrity: sha512-GAYXHOgPTJm6F+mOt0/Zf+rL+xPfMp8zAxGN4pqkzJ6QVQA/mNVMMuj22dI5x8+Ey+lCulKC3rNs4K3VE12hlA==} - engines: {node: '>=16'} - cpu: [x64] - os: [darwin] - - '@cloudflare/workerd-darwin-arm64@1.20251109.0': - resolution: {integrity: sha512-fpLJvZi3i+btgrXJcOtKYrbmdnHVTKpaZigoKIcpBX4mbwxUh/GVbrCmOqLebr57asQC+PmBfghUEYniqRgnhA==} - engines: {node: '>=16'} - cpu: [arm64] - os: [darwin] - - '@cloudflare/workerd-linux-64@1.20251109.0': - resolution: {integrity: sha512-5NjCnXQoaySFAGGn10w0rPfmEhTSKTP/k7f3aduvt1syt462+66X7luOME/k2x5EB/Z5L8xvwf3/LejSSZ4EVA==} - engines: {node: '>=16'} - cpu: [x64] - os: [linux] - - '@cloudflare/workerd-linux-arm64@1.20251109.0': - resolution: {integrity: sha512-f2AeJlpSwrEvEV57+JU+vRPL8c/Dv8nwY4XW+YwnzPo2TpbI/zzqloPXQ6PY79ftDfEsJJPzQuaDDPq3UOGJQA==} - engines: {node: '>=16'} - cpu: [arm64] - os: [linux] - - '@cloudflare/workerd-windows-64@1.20251109.0': - resolution: {integrity: sha512-IGo/lzbYoeJdfLkpaKLoeG6C7Rwcf5kXjzV0wO8fLUSmlfOLQvXTIehWc7EkbHFHjPapDqYqR0KsmbizBi68Lg==} - engines: {node: '>=16'} - cpu: [x64] - os: [win32] - - '@cloudflare/workers-types@4.20251111.0': - resolution: {integrity: sha512-C8BgQRJlnxcUGycNr8pSKs7WBDQwc43p3pnuGv+Lc0KR2y6raR/9Rs7/lPqQ086ECYSiNqU6IPcbeszKbg4LXA==} - - '@cspotcode/source-map-support@0.8.1': - resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} - engines: {node: '>=12'} - - '@drizzle-team/brocli@0.10.2': - resolution: {integrity: sha512-z33Il7l5dKjUgGULTqBsQBQwckHh5AbIuxhdsIxDDiZAzBOrZO6q9ogcWC65kU382AfynTfgNumVcNIjuIua6w==} - - '@emnapi/runtime@1.7.0': - resolution: {integrity: sha512-oAYoQnCYaQZKVS53Fq23ceWMRxq5EhQsE0x0RdQ55jT7wagMu5k+fS39v1fiSLrtrLQlXwVINenqhLMtTrV/1Q==} - - '@esbuild-kit/core-utils@3.3.2': - resolution: {integrity: sha512-sPRAnw9CdSsRmEtnsl2WXWdyquogVpB3yZ3dgwJfe8zrOzTsV7cJvmwrKVa+0ma5BoiGJ+BoqkMvawbayKUsqQ==} - deprecated: 'Merged into tsx: https://tsx.is' - - '@esbuild-kit/esm-loader@2.6.5': - resolution: {integrity: sha512-FxEMIkJKnodyA1OaCUoEvbYRkoZlLZ4d/eXFu9Fh8CbBBgP5EmZxrfTRyN0qpXZ4vOvqnE5YdRdcrmUUXuU+dA==} - deprecated: 'Merged into tsx: https://tsx.is' - - '@esbuild/aix-ppc64@0.25.12': - resolution: {integrity: sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [aix] - - '@esbuild/aix-ppc64@0.25.4': - resolution: {integrity: sha512-1VCICWypeQKhVbE9oW/sJaAmjLxhVqacdkvPLEjwlttjfwENRSClS8EjBz0KzRyFSCPDIkuXW34Je/vk7zdB7Q==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [aix] - - '@esbuild/android-arm64@0.18.20': - resolution: {integrity: sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==} - engines: {node: '>=12'} - cpu: [arm64] - os: [android] - - '@esbuild/android-arm64@0.25.12': - resolution: {integrity: sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [android] - - '@esbuild/android-arm64@0.25.4': - resolution: {integrity: sha512-bBy69pgfhMGtCnwpC/x5QhfxAz/cBgQ9enbtwjf6V9lnPI/hMyT9iWpR1arm0l3kttTr4L0KSLpKmLp/ilKS9A==} - engines: {node: '>=18'} - cpu: [arm64] - os: [android] - - '@esbuild/android-arm@0.18.20': - resolution: {integrity: sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==} - engines: {node: '>=12'} - cpu: [arm] - os: [android] - - '@esbuild/android-arm@0.25.12': - resolution: {integrity: sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==} - engines: {node: '>=18'} - cpu: [arm] - os: [android] - - '@esbuild/android-arm@0.25.4': - resolution: {integrity: sha512-QNdQEps7DfFwE3hXiU4BZeOV68HHzYwGd0Nthhd3uCkkEKK7/R6MTgM0P7H7FAs5pU/DIWsviMmEGxEoxIZ+ZQ==} - engines: {node: '>=18'} - cpu: [arm] - os: [android] - - '@esbuild/android-x64@0.18.20': - resolution: {integrity: sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==} - engines: {node: '>=12'} - cpu: [x64] - os: [android] - - '@esbuild/android-x64@0.25.12': - resolution: {integrity: sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==} - engines: {node: '>=18'} - cpu: [x64] - os: [android] - - '@esbuild/android-x64@0.25.4': - resolution: {integrity: sha512-TVhdVtQIFuVpIIR282btcGC2oGQoSfZfmBdTip2anCaVYcqWlZXGcdcKIUklfX2wj0JklNYgz39OBqh2cqXvcQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [android] - - '@esbuild/darwin-arm64@0.18.20': - resolution: {integrity: sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==} - engines: {node: '>=12'} - cpu: [arm64] - os: [darwin] - - '@esbuild/darwin-arm64@0.25.12': - resolution: {integrity: sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [darwin] - - '@esbuild/darwin-arm64@0.25.4': - resolution: {integrity: sha512-Y1giCfM4nlHDWEfSckMzeWNdQS31BQGs9/rouw6Ub91tkK79aIMTH3q9xHvzH8d0wDru5Ci0kWB8b3up/nl16g==} - engines: {node: '>=18'} - cpu: [arm64] - os: [darwin] - - '@esbuild/darwin-x64@0.18.20': - resolution: {integrity: sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [darwin] - - '@esbuild/darwin-x64@0.25.12': - resolution: {integrity: sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==} - engines: {node: '>=18'} - cpu: [x64] - os: [darwin] - - '@esbuild/darwin-x64@0.25.4': - resolution: {integrity: sha512-CJsry8ZGM5VFVeyUYB3cdKpd/H69PYez4eJh1W/t38vzutdjEjtP7hB6eLKBoOdxcAlCtEYHzQ/PJ/oU9I4u0A==} - engines: {node: '>=18'} - cpu: [x64] - os: [darwin] - - '@esbuild/freebsd-arm64@0.18.20': - resolution: {integrity: sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==} - engines: {node: '>=12'} - cpu: [arm64] - os: [freebsd] - - '@esbuild/freebsd-arm64@0.25.12': - resolution: {integrity: sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [freebsd] - - '@esbuild/freebsd-arm64@0.25.4': - resolution: {integrity: sha512-yYq+39NlTRzU2XmoPW4l5Ifpl9fqSk0nAJYM/V/WUGPEFfek1epLHJIkTQM6bBs1swApjO5nWgvr843g6TjxuQ==} - engines: {node: '>=18'} - cpu: [arm64] - os: [freebsd] - - '@esbuild/freebsd-x64@0.18.20': - resolution: {integrity: sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [freebsd] - - '@esbuild/freebsd-x64@0.25.12': - resolution: {integrity: sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [freebsd] - - '@esbuild/freebsd-x64@0.25.4': - resolution: {integrity: sha512-0FgvOJ6UUMflsHSPLzdfDnnBBVoCDtBTVyn/MrWloUNvq/5SFmh13l3dvgRPkDihRxb77Y17MbqbCAa2strMQQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [freebsd] - - '@esbuild/linux-arm64@0.18.20': - resolution: {integrity: sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==} - engines: {node: '>=12'} - cpu: [arm64] - os: [linux] - - '@esbuild/linux-arm64@0.25.12': - resolution: {integrity: sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==} - engines: {node: '>=18'} - cpu: [arm64] - os: [linux] - - '@esbuild/linux-arm64@0.25.4': - resolution: {integrity: sha512-+89UsQTfXdmjIvZS6nUnOOLoXnkUTB9hR5QAeLrQdzOSWZvNSAXAtcRDHWtqAUtAmv7ZM1WPOOeSxDzzzMogiQ==} - engines: {node: '>=18'} - cpu: [arm64] - os: [linux] - - '@esbuild/linux-arm@0.18.20': - resolution: {integrity: sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==} - engines: {node: '>=12'} - cpu: [arm] - os: [linux] - - '@esbuild/linux-arm@0.25.12': - resolution: {integrity: sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==} - engines: {node: '>=18'} - cpu: [arm] - os: [linux] - - '@esbuild/linux-arm@0.25.4': - resolution: {integrity: sha512-kro4c0P85GMfFYqW4TWOpvmF8rFShbWGnrLqlzp4X1TNWjRY3JMYUfDCtOxPKOIY8B0WC8HN51hGP4I4hz4AaQ==} - engines: {node: '>=18'} - cpu: [arm] - os: [linux] - - '@esbuild/linux-ia32@0.18.20': - resolution: {integrity: sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==} - engines: {node: '>=12'} - cpu: [ia32] - os: [linux] - - '@esbuild/linux-ia32@0.25.12': - resolution: {integrity: sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==} - engines: {node: '>=18'} - cpu: [ia32] - os: [linux] - - '@esbuild/linux-ia32@0.25.4': - resolution: {integrity: sha512-yTEjoapy8UP3rv8dB0ip3AfMpRbyhSN3+hY8mo/i4QXFeDxmiYbEKp3ZRjBKcOP862Ua4b1PDfwlvbuwY7hIGQ==} - engines: {node: '>=18'} - cpu: [ia32] - os: [linux] - - '@esbuild/linux-loong64@0.18.20': - resolution: {integrity: sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==} - engines: {node: '>=12'} - cpu: [loong64] - os: [linux] - - '@esbuild/linux-loong64@0.25.12': - resolution: {integrity: sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==} - engines: {node: '>=18'} - cpu: [loong64] - os: [linux] - - '@esbuild/linux-loong64@0.25.4': - resolution: {integrity: sha512-NeqqYkrcGzFwi6CGRGNMOjWGGSYOpqwCjS9fvaUlX5s3zwOtn1qwg1s2iE2svBe4Q/YOG1q6875lcAoQK/F4VA==} - engines: {node: '>=18'} - cpu: [loong64] - os: [linux] - - '@esbuild/linux-mips64el@0.18.20': - resolution: {integrity: sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==} - engines: {node: '>=12'} - cpu: [mips64el] - os: [linux] - - '@esbuild/linux-mips64el@0.25.12': - resolution: {integrity: sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==} - engines: {node: '>=18'} - cpu: [mips64el] - os: [linux] - - '@esbuild/linux-mips64el@0.25.4': - resolution: {integrity: sha512-IcvTlF9dtLrfL/M8WgNI/qJYBENP3ekgsHbYUIzEzq5XJzzVEV/fXY9WFPfEEXmu3ck2qJP8LG/p3Q8f7Zc2Xg==} - engines: {node: '>=18'} - cpu: [mips64el] - os: [linux] - - '@esbuild/linux-ppc64@0.18.20': - resolution: {integrity: sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [linux] - - '@esbuild/linux-ppc64@0.25.12': - resolution: {integrity: sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [linux] - - '@esbuild/linux-ppc64@0.25.4': - resolution: {integrity: sha512-HOy0aLTJTVtoTeGZh4HSXaO6M95qu4k5lJcH4gxv56iaycfz1S8GO/5Jh6X4Y1YiI0h7cRyLi+HixMR+88swag==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [linux] - - '@esbuild/linux-riscv64@0.18.20': - resolution: {integrity: sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==} - engines: {node: '>=12'} - cpu: [riscv64] - os: [linux] - - '@esbuild/linux-riscv64@0.25.12': - resolution: {integrity: sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==} - engines: {node: '>=18'} - cpu: [riscv64] - os: [linux] - - '@esbuild/linux-riscv64@0.25.4': - resolution: {integrity: sha512-i8JUDAufpz9jOzo4yIShCTcXzS07vEgWzyX3NH2G7LEFVgrLEhjwL3ajFE4fZI3I4ZgiM7JH3GQ7ReObROvSUA==} - engines: {node: '>=18'} - cpu: [riscv64] - os: [linux] - - '@esbuild/linux-s390x@0.18.20': - resolution: {integrity: sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==} - engines: {node: '>=12'} - cpu: [s390x] - os: [linux] - - '@esbuild/linux-s390x@0.25.12': - resolution: {integrity: sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==} - engines: {node: '>=18'} - cpu: [s390x] - os: [linux] - - '@esbuild/linux-s390x@0.25.4': - resolution: {integrity: sha512-jFnu+6UbLlzIjPQpWCNh5QtrcNfMLjgIavnwPQAfoGx4q17ocOU9MsQ2QVvFxwQoWpZT8DvTLooTvmOQXkO51g==} - engines: {node: '>=18'} - cpu: [s390x] - os: [linux] - - '@esbuild/linux-x64@0.18.20': - resolution: {integrity: sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==} - engines: {node: '>=12'} - cpu: [x64] - os: [linux] - - '@esbuild/linux-x64@0.25.12': - resolution: {integrity: sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==} - engines: {node: '>=18'} - cpu: [x64] - os: [linux] - - '@esbuild/linux-x64@0.25.4': - resolution: {integrity: sha512-6e0cvXwzOnVWJHq+mskP8DNSrKBr1bULBvnFLpc1KY+d+irZSgZ02TGse5FsafKS5jg2e4pbvK6TPXaF/A6+CA==} - engines: {node: '>=18'} - cpu: [x64] - os: [linux] - - '@esbuild/netbsd-arm64@0.25.12': - resolution: {integrity: sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [netbsd] - - '@esbuild/netbsd-arm64@0.25.4': - resolution: {integrity: sha512-vUnkBYxZW4hL/ie91hSqaSNjulOnYXE1VSLusnvHg2u3jewJBz3YzB9+oCw8DABeVqZGg94t9tyZFoHma8gWZQ==} - engines: {node: '>=18'} - cpu: [arm64] - os: [netbsd] - - '@esbuild/netbsd-x64@0.18.20': - resolution: {integrity: sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==} - engines: {node: '>=12'} - cpu: [x64] - os: [netbsd] - - '@esbuild/netbsd-x64@0.25.12': - resolution: {integrity: sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [netbsd] - - '@esbuild/netbsd-x64@0.25.4': - resolution: {integrity: sha512-XAg8pIQn5CzhOB8odIcAm42QsOfa98SBeKUdo4xa8OvX8LbMZqEtgeWE9P/Wxt7MlG2QqvjGths+nq48TrUiKw==} - engines: {node: '>=18'} - cpu: [x64] - os: [netbsd] - - '@esbuild/openbsd-arm64@0.25.12': - resolution: {integrity: sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openbsd] - - '@esbuild/openbsd-arm64@0.25.4': - resolution: {integrity: sha512-Ct2WcFEANlFDtp1nVAXSNBPDxyU+j7+tId//iHXU2f/lN5AmO4zLyhDcpR5Cz1r08mVxzt3Jpyt4PmXQ1O6+7A==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openbsd] - - '@esbuild/openbsd-x64@0.18.20': - resolution: {integrity: sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==} - engines: {node: '>=12'} - cpu: [x64] - os: [openbsd] - - '@esbuild/openbsd-x64@0.25.12': - resolution: {integrity: sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==} - engines: {node: '>=18'} - cpu: [x64] - os: [openbsd] - - '@esbuild/openbsd-x64@0.25.4': - resolution: {integrity: sha512-xAGGhyOQ9Otm1Xu8NT1ifGLnA6M3sJxZ6ixylb+vIUVzvvd6GOALpwQrYrtlPouMqd/vSbgehz6HaVk4+7Afhw==} - engines: {node: '>=18'} - cpu: [x64] - os: [openbsd] - - '@esbuild/openharmony-arm64@0.25.12': - resolution: {integrity: sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openharmony] - - '@esbuild/sunos-x64@0.18.20': - resolution: {integrity: sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [sunos] - - '@esbuild/sunos-x64@0.25.12': - resolution: {integrity: sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==} - engines: {node: '>=18'} - cpu: [x64] - os: [sunos] - - '@esbuild/sunos-x64@0.25.4': - resolution: {integrity: sha512-Mw+tzy4pp6wZEK0+Lwr76pWLjrtjmJyUB23tHKqEDP74R3q95luY/bXqXZeYl4NYlvwOqoRKlInQialgCKy67Q==} - engines: {node: '>=18'} - cpu: [x64] - os: [sunos] - - '@esbuild/win32-arm64@0.18.20': - resolution: {integrity: sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==} - engines: {node: '>=12'} - cpu: [arm64] - os: [win32] - - '@esbuild/win32-arm64@0.25.12': - resolution: {integrity: sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [win32] - - '@esbuild/win32-arm64@0.25.4': - resolution: {integrity: sha512-AVUP428VQTSddguz9dO9ngb+E5aScyg7nOeJDrF1HPYu555gmza3bDGMPhmVXL8svDSoqPCsCPjb265yG/kLKQ==} - engines: {node: '>=18'} - cpu: [arm64] - os: [win32] - - '@esbuild/win32-ia32@0.18.20': - resolution: {integrity: sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==} - engines: {node: '>=12'} - cpu: [ia32] - os: [win32] - - '@esbuild/win32-ia32@0.25.12': - resolution: {integrity: sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==} - engines: {node: '>=18'} - cpu: [ia32] - os: [win32] - - '@esbuild/win32-ia32@0.25.4': - resolution: {integrity: sha512-i1sW+1i+oWvQzSgfRcxxG2k4I9n3O9NRqy8U+uugaT2Dy7kLO9Y7wI72haOahxceMX8hZAzgGou1FhndRldxRg==} - engines: {node: '>=18'} - cpu: [ia32] - os: [win32] - - '@esbuild/win32-x64@0.18.20': - resolution: {integrity: sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [win32] - - '@esbuild/win32-x64@0.25.12': - resolution: {integrity: sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==} - engines: {node: '>=18'} - cpu: [x64] - os: [win32] - - '@esbuild/win32-x64@0.25.4': - resolution: {integrity: sha512-nOT2vZNw6hJ+z43oP1SPea/G/6AbN6X+bGNhNuq8NtRHy4wsMhw765IKLNmnjek7GvjWBYQ8Q5VBoYTFg9y1UQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [win32] - - '@eslint-community/eslint-utils@4.9.0': - resolution: {integrity: sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - - '@eslint-community/regexpp@4.12.2': - resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==} - engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - - '@eslint/config-array@0.21.1': - resolution: {integrity: sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/config-helpers@0.4.2': - resolution: {integrity: sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/core@0.17.0': - resolution: {integrity: sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/eslintrc@3.3.1': - resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/js@9.39.1': - resolution: {integrity: sha512-S26Stp4zCy88tH94QbBv3XCuzRQiZ9yXofEILmglYTh/Ug/a9/umqvgFtYBAo3Lp0nsI/5/qH1CCrbdK3AP1Tw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/object-schema@2.1.7': - resolution: {integrity: sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/plugin-kit@0.4.1': - resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@humanfs/core@0.19.1': - resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} - engines: {node: '>=18.18.0'} - - '@humanfs/node@0.16.7': - resolution: {integrity: sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==} - engines: {node: '>=18.18.0'} - - '@humanwhocodes/module-importer@1.0.1': - resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} - engines: {node: '>=12.22'} - - '@humanwhocodes/retry@0.4.3': - resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} - engines: {node: '>=18.18'} - - '@img/sharp-darwin-arm64@0.33.5': - resolution: {integrity: sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm64] - os: [darwin] - - '@img/sharp-darwin-x64@0.33.5': - resolution: {integrity: sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [x64] - os: [darwin] - - '@img/sharp-libvips-darwin-arm64@1.0.4': - resolution: {integrity: sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==} - cpu: [arm64] - os: [darwin] - - '@img/sharp-libvips-darwin-x64@1.0.4': - resolution: {integrity: sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==} - cpu: [x64] - os: [darwin] - - '@img/sharp-libvips-linux-arm64@1.0.4': - resolution: {integrity: sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==} - cpu: [arm64] - os: [linux] - - '@img/sharp-libvips-linux-arm@1.0.5': - resolution: {integrity: sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==} - cpu: [arm] - os: [linux] - - '@img/sharp-libvips-linux-s390x@1.0.4': - resolution: {integrity: sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==} - cpu: [s390x] - os: [linux] - - '@img/sharp-libvips-linux-x64@1.0.4': - resolution: {integrity: sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==} - cpu: [x64] - os: [linux] - - '@img/sharp-libvips-linuxmusl-arm64@1.0.4': - resolution: {integrity: sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==} - cpu: [arm64] - os: [linux] - - '@img/sharp-libvips-linuxmusl-x64@1.0.4': - resolution: {integrity: sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==} - cpu: [x64] - os: [linux] - - '@img/sharp-linux-arm64@0.33.5': - resolution: {integrity: sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm64] - os: [linux] - - '@img/sharp-linux-arm@0.33.5': - resolution: {integrity: sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm] - os: [linux] - - '@img/sharp-linux-s390x@0.33.5': - resolution: {integrity: sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [s390x] - os: [linux] - - '@img/sharp-linux-x64@0.33.5': - resolution: {integrity: sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [x64] - os: [linux] - - '@img/sharp-linuxmusl-arm64@0.33.5': - resolution: {integrity: sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm64] - os: [linux] - - '@img/sharp-linuxmusl-x64@0.33.5': - resolution: {integrity: sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [x64] - os: [linux] - - '@img/sharp-wasm32@0.33.5': - resolution: {integrity: sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [wasm32] - - '@img/sharp-win32-ia32@0.33.5': - resolution: {integrity: sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [ia32] - os: [win32] - - '@img/sharp-win32-x64@0.33.5': - resolution: {integrity: sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [x64] - os: [win32] - - '@jridgewell/resolve-uri@3.1.2': - resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} - engines: {node: '>=6.0.0'} - - '@jridgewell/sourcemap-codec@1.5.5': - resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} - - '@jridgewell/trace-mapping@0.3.9': - resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} - - '@nodelib/fs.scandir@2.1.5': - resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} - engines: {node: '>= 8'} - - '@nodelib/fs.stat@2.0.5': - resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} - engines: {node: '>= 8'} - - '@nodelib/fs.walk@1.2.8': - resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} - engines: {node: '>= 8'} - - '@poppinss/colors@4.1.5': - resolution: {integrity: sha512-FvdDqtcRCtz6hThExcFOgW0cWX+xwSMWcRuQe5ZEb2m7cVQOAVZOIMt+/v9RxGiD9/OY16qJBXK4CVKWAPalBw==} - - '@poppinss/dumper@0.6.5': - resolution: {integrity: sha512-NBdYIb90J7LfOI32dOewKI1r7wnkiH6m920puQ3qHUeZkxNkQiFnXVWoE6YtFSv6QOiPPf7ys6i+HWWecDz7sw==} - - '@poppinss/exception@1.2.2': - resolution: {integrity: sha512-m7bpKCD4QMlFCjA/nKTs23fuvoVFoA83brRKmObCUNmi/9tVu8Ve3w4YQAnJu4q3Tjf5fr685HYIC/IA2zHRSg==} - - '@sindresorhus/is@7.1.1': - resolution: {integrity: sha512-rO92VvpgMc3kfiTjGT52LEtJ8Yc5kCWhZjLQ3LwlA4pSgPpQO7bVpYXParOD8Jwf+cVQECJo3yP/4I8aZtUQTQ==} - engines: {node: '>=18'} - - '@speed-highlight/core@1.2.12': - resolution: {integrity: sha512-uilwrK0Ygyri5dToHYdZSjcvpS2ZwX0w5aSt3GCEN9hrjxWCoeV4Z2DTXuxjwbntaLQIEEAlCeNQss5SoHvAEA==} - - '@trpc/server@11.7.1': - resolution: {integrity: sha512-N3U8LNLIP4g9C7LJ/sLkjuPHwqlvE3bnspzC4DEFVdvx2+usbn70P80E3wj5cjOTLhmhRiwJCSXhlB+MHfGeCw==} - peerDependencies: - typescript: '>=5.7.2' - - '@types/bcrypt@6.0.0': - resolution: {integrity: sha512-/oJGukuH3D2+D+3H4JWLaAsJ/ji86dhRidzZ/Od7H/i8g+aCmvkeCc6Ni/f9uxGLSQVCRZkX2/lqEFG2BvWtlQ==} - - '@types/better-sqlite3@7.6.13': - resolution: {integrity: sha512-NMv9ASNARoKksWtsq/SHakpYAYnhBrQgGD8zkLYk/jaK8jUGn08CfEdTRgYhMypUQAfzSP8W6gNLe0q19/t4VA==} - - '@types/body-parser@1.19.6': - resolution: {integrity: sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==} - - '@types/connect@3.4.38': - resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} - - '@types/cors@2.8.19': - resolution: {integrity: sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg==} - - '@types/estree@1.0.8': - resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} - - '@types/express-serve-static-core@5.1.0': - resolution: {integrity: sha512-jnHMsrd0Mwa9Cf4IdOzbz543y4XJepXrbia2T4b6+spXC2We3t1y6K44D3mR8XMFSXMCf3/l7rCgddfx7UNVBA==} - - '@types/express@5.0.5': - resolution: {integrity: sha512-LuIQOcb6UmnF7C1PCFmEU1u2hmiHL43fgFQX67sN3H4Z+0Yk0Neo++mFsBjhOAuLzvlQeqAAkeDOZrJs9rzumQ==} - - '@types/http-errors@2.0.5': - resolution: {integrity: sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==} - - '@types/json-schema@7.0.15': - resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - - '@types/mime@1.3.5': - resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} - - '@types/node-cron@3.0.11': - resolution: {integrity: sha512-0ikrnug3/IyneSHqCBeslAhlK2aBfYek1fGo4bP4QnZPmiqSGRK+Oy7ZMisLWkesffJvQ1cqAcBnJC+8+nxIAg==} - - '@types/node@24.10.0': - resolution: {integrity: sha512-qzQZRBqkFsYyaSWXuEHc2WR9c0a0CXwiE5FWUvn7ZM+vdy1uZLfCunD38UzhuB7YN/J11ndbDBcTmOdxJo9Q7A==} - - '@types/qs@6.14.0': - resolution: {integrity: sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==} - - '@types/range-parser@1.2.7': - resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==} - - '@types/send@0.17.6': - resolution: {integrity: sha512-Uqt8rPBE8SY0RK8JB1EzVOIZ32uqy8HwdxCnoCOsYrvnswqmFZ/k+9Ikidlk/ImhsdvBsloHbAlewb2IEBV/Og==} - - '@types/send@1.2.1': - resolution: {integrity: sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ==} - - '@types/serve-static@1.15.10': - resolution: {integrity: sha512-tRs1dB+g8Itk72rlSI2ZrW6vZg0YrLI81iQSTkMmOqnqCaNr/8Ek4VwWcN5vZgCYWbg/JJSGBlUaYGAOP73qBw==} - - '@typescript-eslint/eslint-plugin@8.46.4': - resolution: {integrity: sha512-R48VhmTJqplNyDxCyqqVkFSZIx1qX6PzwqgcXn1olLrzxcSBDlOsbtcnQuQhNtnNiJ4Xe5gREI1foajYaYU2Vg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - '@typescript-eslint/parser': ^8.46.4 - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <6.0.0' - - '@typescript-eslint/parser@8.46.4': - resolution: {integrity: sha512-tK3GPFWbirvNgsNKto+UmB/cRtn6TZfyw0D6IKrW55n6Vbs7KJoZtI//kpTKzE/DUmmnAFD8/Ca46s7Obs92/w==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <6.0.0' - - '@typescript-eslint/project-service@8.46.4': - resolution: {integrity: sha512-nPiRSKuvtTN+no/2N1kt2tUh/HoFzeEgOm9fQ6XQk4/ApGqjx0zFIIaLJ6wooR1HIoozvj2j6vTi/1fgAz7UYQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '>=4.8.4 <6.0.0' - - '@typescript-eslint/scope-manager@8.46.4': - resolution: {integrity: sha512-tMDbLGXb1wC+McN1M6QeDx7P7c0UWO5z9CXqp7J8E+xGcJuUuevWKxuG8j41FoweS3+L41SkyKKkia16jpX7CA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@typescript-eslint/tsconfig-utils@8.46.4': - resolution: {integrity: sha512-+/XqaZPIAk6Cjg7NWgSGe27X4zMGqrFqZ8atJsX3CWxH/jACqWnrWI68h7nHQld0y+k9eTTjb9r+KU4twLoo9A==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '>=4.8.4 <6.0.0' - - '@typescript-eslint/type-utils@8.46.4': - resolution: {integrity: sha512-V4QC8h3fdT5Wro6vANk6eojqfbv5bpwHuMsBcJUJkqs2z5XnYhJzyz9Y02eUmF9u3PgXEUiOt4w4KHR3P+z0PQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <6.0.0' - - '@typescript-eslint/types@8.46.4': - resolution: {integrity: sha512-USjyxm3gQEePdUwJBFjjGNG18xY9A2grDVGuk7/9AkjIF1L+ZrVnwR5VAU5JXtUnBL/Nwt3H31KlRDaksnM7/w==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@typescript-eslint/typescript-estree@8.46.4': - resolution: {integrity: sha512-7oV2qEOr1d4NWNmpXLR35LvCfOkTNymY9oyW+lUHkmCno7aOmIf/hMaydnJBUTBMRCOGZh8YjkFOc8dadEoNGA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '>=4.8.4 <6.0.0' - - '@typescript-eslint/utils@8.46.4': - resolution: {integrity: sha512-AbSv11fklGXV6T28dp2Me04Uw90R2iJ30g2bgLz529Koehrmkbs1r7paFqr1vPCZi7hHwYxYtxfyQMRC8QaVSg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <6.0.0' - - '@typescript-eslint/visitor-keys@8.46.4': - resolution: {integrity: sha512-/++5CYLQqsO9HFGLI7APrxBJYo+5OCMpViuhV8q5/Qa3o5mMrF//eQHks+PXcsAVaLdn817fMuS7zqoXNNZGaw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - accepts@2.0.0: - resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==} - engines: {node: '>= 0.6'} - - acorn-jsx@5.3.2: - resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} - peerDependencies: - acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - - acorn-walk@8.3.2: - resolution: {integrity: sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==} - engines: {node: '>=0.4.0'} - - acorn@8.14.0: - resolution: {integrity: sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==} - engines: {node: '>=0.4.0'} - hasBin: true - - acorn@8.15.0: - resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} - engines: {node: '>=0.4.0'} - hasBin: true - - ajv@6.12.6: - resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} - - ansi-styles@4.3.0: - resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} - engines: {node: '>=8'} - - argparse@2.0.1: - resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - - balanced-match@1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - - base64-js@1.5.1: - resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - - bcrypt@6.0.0: - resolution: {integrity: sha512-cU8v/EGSrnH+HnxV2z0J7/blxH8gq7Xh2JFT6Aroax7UohdmiJJlxApMxtKfuI7z68NvvVcmR78k2LbT6efhRg==} - engines: {node: '>= 18'} - - better-sqlite3@12.4.1: - resolution: {integrity: sha512-3yVdyZhklTiNrtg+4WqHpJpFDd+WHTg2oM7UcR80GqL05AOV0xEJzc6qNvFYoEtE+hRp1n9MpN6/+4yhlGkDXQ==} - engines: {node: 20.x || 22.x || 23.x || 24.x} - - bindings@1.5.0: - resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} - - bl@4.1.0: - resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} - - blake3-wasm@2.1.5: - resolution: {integrity: sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==} - - body-parser@2.2.0: - resolution: {integrity: sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==} - engines: {node: '>=18'} - - brace-expansion@1.1.12: - resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} - - brace-expansion@2.0.2: - resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==} - - braces@3.0.3: - resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} - engines: {node: '>=8'} - - buffer-from@1.1.2: - resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} - - buffer@5.7.1: - resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} - - bytes@3.1.2: - resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} - engines: {node: '>= 0.8'} - - call-bind-apply-helpers@1.0.2: - resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} - engines: {node: '>= 0.4'} - - call-bound@1.0.4: - resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} - engines: {node: '>= 0.4'} - - callsites@3.1.0: - resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} - engines: {node: '>=6'} - - chalk@4.1.2: - resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} - engines: {node: '>=10'} - - chownr@1.1.4: - resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} - - color-convert@2.0.1: - resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} - engines: {node: '>=7.0.0'} - - color-name@1.1.4: - resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - - color-string@1.9.1: - resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} - - color@4.2.3: - resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} - engines: {node: '>=12.5.0'} - - concat-map@0.0.1: - resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - - content-disposition@1.0.0: - resolution: {integrity: sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==} - engines: {node: '>= 0.6'} - - content-type@1.0.5: - resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} - engines: {node: '>= 0.6'} - - cookie-signature@1.2.2: - resolution: {integrity: sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==} - engines: {node: '>=6.6.0'} - - cookie@0.7.2: - resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} - engines: {node: '>= 0.6'} - - cookie@1.0.2: - resolution: {integrity: sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==} - engines: {node: '>=18'} - - cors@2.8.5: - resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==} - engines: {node: '>= 0.10'} - - cross-spawn@7.0.6: - resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} - engines: {node: '>= 8'} - - debug@4.4.3: - resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - - decompress-response@6.0.0: - resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} - engines: {node: '>=10'} - - deep-extend@0.6.0: - resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} - engines: {node: '>=4.0.0'} - - deep-is@0.1.4: - resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} - - depd@2.0.0: - resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} - engines: {node: '>= 0.8'} - - detect-libc@2.1.2: - resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} - engines: {node: '>=8'} - - drizzle-kit@0.31.6: - resolution: {integrity: sha512-/B4e/4pwnx25QwD5xXgdpo1S+077a2VZdosXbItE/oNmUgQwZydGDz9qJYmnQl/b+5IX0rLfwRhrPnroGtrg8Q==} - hasBin: true - - drizzle-orm@0.44.7: - resolution: {integrity: sha512-quIpnYznjU9lHshEOAYLoZ9s3jweleHlZIAWR/jX9gAWNg/JhQ1wj0KGRf7/Zm+obRrYd9GjPVJg790QY9N5AQ==} - peerDependencies: - '@aws-sdk/client-rds-data': '>=3' - '@cloudflare/workers-types': '>=4' - '@electric-sql/pglite': '>=0.2.0' - '@libsql/client': '>=0.10.0' - '@libsql/client-wasm': '>=0.10.0' - '@neondatabase/serverless': '>=0.10.0' - '@op-engineering/op-sqlite': '>=2' - '@opentelemetry/api': ^1.4.1 - '@planetscale/database': '>=1.13' - '@prisma/client': '*' - '@tidbcloud/serverless': '*' - '@types/better-sqlite3': '*' - '@types/pg': '*' - '@types/sql.js': '*' - '@upstash/redis': '>=1.34.7' - '@vercel/postgres': '>=0.8.0' - '@xata.io/client': '*' - better-sqlite3: '>=7' - bun-types: '*' - expo-sqlite: '>=14.0.0' - gel: '>=2' - knex: '*' - kysely: '*' - mysql2: '>=2' - pg: '>=8' - postgres: '>=3' - prisma: '*' - sql.js: '>=1' - sqlite3: '>=5' - peerDependenciesMeta: - '@aws-sdk/client-rds-data': - optional: true - '@cloudflare/workers-types': - optional: true - '@electric-sql/pglite': - optional: true - '@libsql/client': - optional: true - '@libsql/client-wasm': - optional: true - '@neondatabase/serverless': - optional: true - '@op-engineering/op-sqlite': - optional: true - '@opentelemetry/api': - optional: true - '@planetscale/database': - optional: true - '@prisma/client': - optional: true - '@tidbcloud/serverless': - optional: true - '@types/better-sqlite3': - optional: true - '@types/pg': - optional: true - '@types/sql.js': - optional: true - '@upstash/redis': - optional: true - '@vercel/postgres': - optional: true - '@xata.io/client': - optional: true - better-sqlite3: - optional: true - bun-types: - optional: true - expo-sqlite: - optional: true - gel: - optional: true - knex: - optional: true - kysely: - optional: true - mysql2: - optional: true - pg: - optional: true - postgres: - optional: true - prisma: - optional: true - sql.js: - optional: true - sqlite3: - optional: true - - drizzle-zod@0.8.3: - resolution: {integrity: sha512-66yVOuvGhKJnTdiqj1/Xaaz9/qzOdRJADpDa68enqS6g3t0kpNkwNYjUuaeXgZfO/UWuIM9HIhSlJ6C5ZraMww==} - peerDependencies: - drizzle-orm: '>=0.36.0' - zod: ^3.25.0 || ^4.0.0 - - dunder-proto@1.0.1: - resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} - engines: {node: '>= 0.4'} - - ee-first@1.1.1: - resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} - - encodeurl@2.0.0: - resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} - engines: {node: '>= 0.8'} - - end-of-stream@1.4.5: - resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} - - entities@7.0.0: - resolution: {integrity: sha512-FDWG5cmEYf2Z00IkYRhbFrwIwvdFKH07uV8dvNy0omp/Qb1xcyCWp2UDtcwJF4QZZvk0sLudP6/hAu42TaqVhQ==} - engines: {node: '>=0.12'} - - error-stack-parser-es@1.0.5: - resolution: {integrity: sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA==} - - es-define-property@1.0.1: - resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} - engines: {node: '>= 0.4'} - - es-errors@1.3.0: - resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} - engines: {node: '>= 0.4'} - - es-object-atoms@1.1.1: - resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} - engines: {node: '>= 0.4'} - - esbuild-register@3.6.0: - resolution: {integrity: sha512-H2/S7Pm8a9CL1uhp9OvjwrBh5Pvx0H8qVOxNu8Wed9Y7qv56MPtq+GGM8RJpq6glYJn9Wspr8uw7l55uyinNeg==} - peerDependencies: - esbuild: '>=0.12 <1' - - esbuild@0.18.20: - resolution: {integrity: sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==} - engines: {node: '>=12'} - hasBin: true - - esbuild@0.25.12: - resolution: {integrity: sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==} - engines: {node: '>=18'} - hasBin: true - - esbuild@0.25.4: - resolution: {integrity: sha512-8pgjLUcUjcgDg+2Q4NYXnPbo/vncAY4UmyaCm0jZevERqCHZIaWwdJHkf8XQtu4AxSKCdvrUbT0XUr1IdZzI8Q==} - engines: {node: '>=18'} - hasBin: true - - escape-html@1.0.3: - resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} - - escape-string-regexp@4.0.0: - resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} - engines: {node: '>=10'} - - eslint-plugin-drizzle@0.2.3: - resolution: {integrity: sha512-BO+ymHo33IUNoJlC0rbd7HP9EwwpW4VIp49R/tWQF/d2E1K2kgTf0tCXT0v9MSiBr6gGR1LtPwMLapTKEWSg9A==} - peerDependencies: - eslint: '>=8.0.0' - - eslint-scope@8.4.0: - resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - eslint-visitor-keys@3.4.3: - resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - - eslint-visitor-keys@4.2.1: - resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - eslint@9.39.1: - resolution: {integrity: sha512-BhHmn2yNOFA9H9JmmIVKJmd288g9hrVRDkdoIgRCRuSySRUHH7r/DI6aAXW9T1WwUuY3DFgrcaqB+deURBLR5g==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - hasBin: true - peerDependencies: - jiti: '*' - peerDependenciesMeta: - jiti: - optional: true - - espree@10.4.0: - resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - esquery@1.6.0: - resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} - engines: {node: '>=0.10'} - - esrecurse@4.3.0: - resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} - engines: {node: '>=4.0'} - - estraverse@5.3.0: - resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} - engines: {node: '>=4.0'} - - esutils@2.0.3: - resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} - engines: {node: '>=0.10.0'} - - etag@1.8.1: - resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} - engines: {node: '>= 0.6'} - - exit-hook@2.2.1: - resolution: {integrity: sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw==} - engines: {node: '>=6'} - - expand-template@2.0.3: - resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==} - engines: {node: '>=6'} - - express@5.1.0: - resolution: {integrity: sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==} - engines: {node: '>= 18'} - - fast-deep-equal@3.1.3: - resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - - fast-glob@3.3.3: - resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} - engines: {node: '>=8.6.0'} - - fast-json-stable-stringify@2.1.0: - resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} - - fast-levenshtein@2.0.6: - resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} - - fast-xml-parser@5.3.1: - resolution: {integrity: sha512-jbNkWiv2Ec1A7wuuxk0br0d0aTMUtQ4IkL+l/i1r9PRf6pLXjDgsBsWwO+UyczmQlnehi4Tbc8/KIvxGQe+I/A==} - hasBin: true - - fastq@1.19.1: - resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} - - feedsmith@2.4.0: - resolution: {integrity: sha512-2yZSUERJ+ctCpb/ADrMlP/vfBXDKtN6hpVAvHLZaE17WAyXdI2UGq/NsKxBE+Wb3hRF6wTzBoJ4/yEginfIPZQ==} - - file-entry-cache@8.0.0: - resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} - engines: {node: '>=16.0.0'} - - file-uri-to-path@1.0.0: - resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} - - fill-range@7.1.1: - resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} - engines: {node: '>=8'} - - finalhandler@2.1.0: - resolution: {integrity: sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==} - engines: {node: '>= 0.8'} - - find-up@5.0.0: - resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} - engines: {node: '>=10'} - - flat-cache@4.0.1: - resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} - engines: {node: '>=16'} - - flatted@3.3.3: - resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} - - forwarded@0.2.0: - resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} - engines: {node: '>= 0.6'} - - fresh@2.0.0: - resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} - engines: {node: '>= 0.8'} - - fs-constants@1.0.0: - resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} - - fsevents@2.3.3: - resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] - - function-bind@1.1.2: - resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} - - get-intrinsic@1.3.0: - resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} - engines: {node: '>= 0.4'} - - get-proto@1.0.1: - resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} - engines: {node: '>= 0.4'} - - get-tsconfig@4.13.0: - resolution: {integrity: sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==} - - github-from-package@0.0.0: - resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==} - - glob-parent@5.1.2: - resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} - engines: {node: '>= 6'} - - glob-parent@6.0.2: - resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} - engines: {node: '>=10.13.0'} - - glob-to-regexp@0.4.1: - resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} - - globals@14.0.0: - resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} - engines: {node: '>=18'} - - gopd@1.2.0: - resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} - engines: {node: '>= 0.4'} - - graphemer@1.4.0: - resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} - - has-flag@4.0.0: - resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} - engines: {node: '>=8'} - - has-symbols@1.1.0: - resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} - engines: {node: '>= 0.4'} - - hasown@2.0.2: - resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} - engines: {node: '>= 0.4'} - - http-errors@2.0.0: - resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} - engines: {node: '>= 0.8'} - - iconv-lite@0.6.3: - resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} - engines: {node: '>=0.10.0'} - - iconv-lite@0.7.0: - resolution: {integrity: sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==} - engines: {node: '>=0.10.0'} - - ieee754@1.2.1: - resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} - - ignore@5.3.2: - resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} - engines: {node: '>= 4'} - - ignore@7.0.5: - resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} - engines: {node: '>= 4'} - - import-fresh@3.3.1: - resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} - engines: {node: '>=6'} - - imurmurhash@0.1.4: - resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} - engines: {node: '>=0.8.19'} - - inherits@2.0.4: - resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - - ini@1.3.8: - resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} - - ipaddr.js@1.9.1: - resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} - engines: {node: '>= 0.10'} - - is-arrayish@0.3.4: - resolution: {integrity: sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA==} - - is-extglob@2.1.1: - resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} - engines: {node: '>=0.10.0'} - - is-glob@4.0.3: - resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} - engines: {node: '>=0.10.0'} - - is-number@7.0.0: - resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} - engines: {node: '>=0.12.0'} - - is-promise@4.0.0: - resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==} - - isexe@2.0.0: - resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - - jose@6.1.1: - resolution: {integrity: sha512-GWSqjfOPf4cWOkBzw5THBjtGPhXKqYnfRBzh4Ni+ArTrQQ9unvmsA3oFLqaYKoKe5sjWmGu5wVKg9Ft1i+LQfg==} - - js-yaml@4.1.0: - resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} - hasBin: true - - json-buffer@3.0.1: - resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} - - json-schema-traverse@0.4.1: - resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} - - json-stable-stringify-without-jsonify@1.0.1: - resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} - - keyv@4.5.4: - resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} - - kleur@4.1.5: - resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} - engines: {node: '>=6'} - - levn@0.4.1: - resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} - engines: {node: '>= 0.8.0'} - - locate-path@6.0.0: - resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} - engines: {node: '>=10'} - - lodash.merge@4.6.2: - resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} - - math-intrinsics@1.1.0: - resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} - engines: {node: '>= 0.4'} - - media-typer@1.1.0: - resolution: {integrity: sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==} - engines: {node: '>= 0.8'} - - merge-descriptors@2.0.0: - resolution: {integrity: sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==} - engines: {node: '>=18'} - - merge2@1.4.1: - resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} - engines: {node: '>= 8'} - - micromatch@4.0.8: - resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} - engines: {node: '>=8.6'} - - mime-db@1.54.0: - resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} - engines: {node: '>= 0.6'} - - mime-types@3.0.1: - resolution: {integrity: sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==} - engines: {node: '>= 0.6'} - - mime@3.0.0: - resolution: {integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==} - engines: {node: '>=10.0.0'} - hasBin: true - - mimic-response@3.1.0: - resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} - engines: {node: '>=10'} - - miniflare@4.20251109.0: - resolution: {integrity: sha512-fm0J/IFrrx7RT1w3SIoDM5m7zPCa2wBtxBApy6G0QVjd2tx8w0WGlMFop6R49XyTfF1q3LRHCjFMfzJ8YS0RzQ==} - engines: {node: '>=18.0.0'} - hasBin: true - - minimatch@3.1.2: - resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} - - minimatch@9.0.5: - resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} - engines: {node: '>=16 || 14 >=14.17'} - - minimist@1.2.8: - resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - - mkdirp-classic@0.5.3: - resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} - - ms@2.1.3: - resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - - napi-build-utils@2.0.0: - resolution: {integrity: sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==} - - natural-compare@1.4.0: - resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} - - negotiator@1.0.0: - resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==} - engines: {node: '>= 0.6'} - - node-abi@3.80.0: - resolution: {integrity: sha512-LyPuZJcI9HVwzXK1GPxWNzrr+vr8Hp/3UqlmWxxh8p54U1ZbclOqbSog9lWHaCX+dBaiGi6n/hIX+mKu74GmPA==} - engines: {node: '>=10'} - - node-addon-api@8.5.0: - resolution: {integrity: sha512-/bRZty2mXUIFY/xU5HLvveNHlswNJej+RnxBjOMkidWfwZzgTbPG1E3K5TOxRLOR+5hX7bSofy8yf1hZevMS8A==} - engines: {node: ^18 || ^20 || >= 21} - - node-cron@4.2.1: - resolution: {integrity: sha512-lgimEHPE/QDgFlywTd8yTR61ptugX3Qer29efeyWw2rv259HtGBNn1vZVmp8lB9uo9wC0t/AT4iGqXxia+CJFg==} - engines: {node: '>=6.0.0'} - - node-gyp-build@4.8.4: - resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} - hasBin: true - - object-assign@4.1.1: - resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} - engines: {node: '>=0.10.0'} - - object-inspect@1.13.4: - resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} - engines: {node: '>= 0.4'} - - on-finished@2.4.1: - resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} - engines: {node: '>= 0.8'} - - once@1.4.0: - resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} - - optionator@0.9.4: - resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} - engines: {node: '>= 0.8.0'} - - p-limit@3.1.0: - resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} - engines: {node: '>=10'} - - p-locate@5.0.0: - resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} - engines: {node: '>=10'} - - parent-module@1.0.1: - resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} - engines: {node: '>=6'} - - parseurl@1.3.3: - resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} - engines: {node: '>= 0.8'} - - path-exists@4.0.0: - resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} - engines: {node: '>=8'} - - path-key@3.1.1: - resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} - engines: {node: '>=8'} - - path-to-regexp@6.3.0: - resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==} - - path-to-regexp@8.3.0: - resolution: {integrity: sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==} - - pathe@2.0.3: - resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} - - picomatch@2.3.1: - resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} - engines: {node: '>=8.6'} - - prebuild-install@7.1.3: - resolution: {integrity: sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==} - engines: {node: '>=10'} - hasBin: true - - prelude-ls@1.2.1: - resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} - engines: {node: '>= 0.8.0'} - - prettier@3.6.2: - resolution: {integrity: sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==} - engines: {node: '>=14'} - hasBin: true - - proxy-addr@2.0.7: - resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} - engines: {node: '>= 0.10'} - - pump@3.0.3: - resolution: {integrity: sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==} - - punycode@2.3.1: - resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} - engines: {node: '>=6'} - - qs@6.14.0: - resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==} - engines: {node: '>=0.6'} - - queue-microtask@1.2.3: - resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - - range-parser@1.2.1: - resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} - engines: {node: '>= 0.6'} - - raw-body@3.0.1: - resolution: {integrity: sha512-9G8cA+tuMS75+6G/TzW8OtLzmBDMo8p1JRxN5AZ+LAp8uxGA8V8GZm4GQ4/N5QNQEnLmg6SS7wyuSmbKepiKqA==} - engines: {node: '>= 0.10'} - - rc@1.2.8: - resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} - hasBin: true - - readable-stream@3.6.2: - resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} - engines: {node: '>= 6'} - - resolve-from@4.0.0: - resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} - engines: {node: '>=4'} - - resolve-pkg-maps@1.0.0: - resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} - - reusify@1.1.0: - resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} - engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - - router@2.2.0: - resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==} - engines: {node: '>= 18'} - - run-parallel@1.2.0: - resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} - - safe-buffer@5.2.1: - resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - - safer-buffer@2.1.2: - resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - - semver@7.7.3: - resolution: {integrity: sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==} - engines: {node: '>=10'} - hasBin: true - - send@1.2.0: - resolution: {integrity: sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==} - engines: {node: '>= 18'} - - serve-static@2.2.0: - resolution: {integrity: sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==} - engines: {node: '>= 18'} - - setprototypeof@1.2.0: - resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} - - sharp@0.33.5: - resolution: {integrity: sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - - shebang-command@2.0.0: - resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} - engines: {node: '>=8'} - - shebang-regex@3.0.0: - resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} - engines: {node: '>=8'} - - side-channel-list@1.0.0: - resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} - engines: {node: '>= 0.4'} - - side-channel-map@1.0.1: - resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} - engines: {node: '>= 0.4'} - - side-channel-weakmap@1.0.2: - resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} - engines: {node: '>= 0.4'} - - side-channel@1.1.0: - resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} - engines: {node: '>= 0.4'} - - simple-concat@1.0.1: - resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==} - - simple-get@4.0.1: - resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==} - - simple-swizzle@0.2.4: - resolution: {integrity: sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw==} - - source-map-support@0.5.21: - resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} - - source-map@0.6.1: - resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} - engines: {node: '>=0.10.0'} - - statuses@2.0.1: - resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} - engines: {node: '>= 0.8'} - - statuses@2.0.2: - resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} - engines: {node: '>= 0.8'} - - stoppable@1.1.0: - resolution: {integrity: sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==} - engines: {node: '>=4', npm: '>=6'} - - string_decoder@1.3.0: - resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} - - strip-json-comments@2.0.1: - resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} - engines: {node: '>=0.10.0'} - - strip-json-comments@3.1.1: - resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} - engines: {node: '>=8'} - - strnum@2.1.1: - resolution: {integrity: sha512-7ZvoFTiCnGxBtDqJ//Cu6fWtZtc7Y3x+QOirG15wztbdngGSkht27o2pyGWrVy0b4WAy3jbKmnoK6g5VlVNUUw==} - - supports-color@10.2.2: - resolution: {integrity: sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==} - engines: {node: '>=18'} - - supports-color@7.2.0: - resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} - engines: {node: '>=8'} - - tar-fs@2.1.4: - resolution: {integrity: sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==} - - tar-stream@2.2.0: - resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} - engines: {node: '>=6'} - - to-regex-range@5.0.1: - resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} - engines: {node: '>=8.0'} - - toidentifier@1.0.1: - resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} - engines: {node: '>=0.6'} - - ts-api-utils@2.1.0: - resolution: {integrity: sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==} - engines: {node: '>=18.12'} - peerDependencies: - typescript: '>=4.8.4' - - tslib@2.8.1: - resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} - - tsx@4.20.6: - resolution: {integrity: sha512-ytQKuwgmrrkDTFP4LjR0ToE2nqgy886GpvRSpU0JAnrdBYppuY5rLkRUYPU1yCryb24SsKBTL/hlDQAEFVwtZg==} - engines: {node: '>=18.0.0'} - hasBin: true - - tunnel-agent@0.6.0: - resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} - - type-check@0.4.0: - resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} - engines: {node: '>= 0.8.0'} - - type-is@2.0.1: - resolution: {integrity: sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==} - engines: {node: '>= 0.6'} - - typescript@5.9.3: - resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} - engines: {node: '>=14.17'} - hasBin: true - - undici-types@7.16.0: - resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} - - undici@7.14.0: - resolution: {integrity: sha512-Vqs8HTzjpQXZeXdpsfChQTlafcMQaaIwnGwLam1wudSSjlJeQ3bw1j+TLPePgrCnCpUXx7Ba5Pdpf5OBih62NQ==} - engines: {node: '>=20.18.1'} - - unenv@2.0.0-rc.24: - resolution: {integrity: sha512-i7qRCmY42zmCwnYlh9H2SvLEypEFGye5iRmEMKjcGi7zk9UquigRjFtTLz0TYqr0ZGLZhaMHl/foy1bZR+Cwlw==} - - unpipe@1.0.0: - resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} - engines: {node: '>= 0.8'} - - uri-js@4.4.1: - resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} - - util-deprecate@1.0.2: - resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - - vary@1.1.2: - resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} - engines: {node: '>= 0.8'} - - which@2.0.2: - resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} - engines: {node: '>= 8'} - hasBin: true - - word-wrap@1.2.5: - resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} - engines: {node: '>=0.10.0'} - - workerd@1.20251109.0: - resolution: {integrity: sha512-VfazMiymlzos0c1t9AhNi0w8gN9+ZbCVLdEE0VDOsI22WYa6yj+pYOhpZzI/mOzCGmk/o1eNjLMkfjWli6aRVg==} - engines: {node: '>=16'} - hasBin: true - - wrangler@4.47.0: - resolution: {integrity: sha512-JP0U8oqUETK9D+ZbrSjFFOxGdufYsS6HsT0vLU1IAQrban9a6woMHdBZlGNn/lt8QA70xv1uFiJK8DUMPzC73A==} - engines: {node: '>=18.0.0'} - hasBin: true - peerDependencies: - '@cloudflare/workers-types': ^4.20251109.0 - peerDependenciesMeta: - '@cloudflare/workers-types': - optional: true - - wrappy@1.0.2: - resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - - ws@8.18.0: - resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} - 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 - - yocto-queue@0.1.0: - resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} - engines: {node: '>=10'} - - youch-core@0.3.3: - resolution: {integrity: sha512-ho7XuGjLaJ2hWHoK8yFnsUGy2Y5uDpqSTq1FkHLK4/oqKtyUU1AFbOOxY4IpC9f0fTLjwYbslUz0Po5BpD1wrA==} - - youch@4.1.0-beta.10: - resolution: {integrity: sha512-rLfVLB4FgQneDr0dv1oddCVZmKjcJ6yX6mS4pU82Mq/Dt9a3cLZQ62pDBL4AUO+uVrCvtWz3ZFUL2HFAFJ/BXQ==} - - zod@3.22.3: - resolution: {integrity: sha512-EjIevzuJRiRPbVH4mGc8nApb/lVLKVpmUhAaR5R5doKGfAnGJ6Gr3CViAVjP+4FWSxCsybeWQdcgCtbX+7oZug==} - - zod@4.1.12: - resolution: {integrity: sha512-JInaHOamG8pt5+Ey8kGmdcAcg3OL9reK8ltczgHTAwNhMys/6ThXHityHxVV2p3fkw/c+MAvBHFVYHFZDmjMCQ==} - -snapshots: - - '@cloudflare/kv-asset-handler@0.4.0': - dependencies: - mime: 3.0.0 - - '@cloudflare/unenv-preset@2.7.10(unenv@2.0.0-rc.24)(workerd@1.20251109.0)': - dependencies: - unenv: 2.0.0-rc.24 - optionalDependencies: - workerd: 1.20251109.0 - - '@cloudflare/workerd-darwin-64@1.20251109.0': - optional: true - - '@cloudflare/workerd-darwin-arm64@1.20251109.0': - optional: true - - '@cloudflare/workerd-linux-64@1.20251109.0': - optional: true - - '@cloudflare/workerd-linux-arm64@1.20251109.0': - optional: true - - '@cloudflare/workerd-windows-64@1.20251109.0': - optional: true - - '@cloudflare/workers-types@4.20251111.0': {} - - '@cspotcode/source-map-support@0.8.1': - dependencies: - '@jridgewell/trace-mapping': 0.3.9 - - '@drizzle-team/brocli@0.10.2': {} - - '@emnapi/runtime@1.7.0': - dependencies: - tslib: 2.8.1 - optional: true - - '@esbuild-kit/core-utils@3.3.2': - dependencies: - esbuild: 0.18.20 - source-map-support: 0.5.21 - - '@esbuild-kit/esm-loader@2.6.5': - dependencies: - '@esbuild-kit/core-utils': 3.3.2 - get-tsconfig: 4.13.0 - - '@esbuild/aix-ppc64@0.25.12': - optional: true - - '@esbuild/aix-ppc64@0.25.4': - optional: true - - '@esbuild/android-arm64@0.18.20': - optional: true - - '@esbuild/android-arm64@0.25.12': - optional: true - - '@esbuild/android-arm64@0.25.4': - optional: true - - '@esbuild/android-arm@0.18.20': - optional: true - - '@esbuild/android-arm@0.25.12': - optional: true - - '@esbuild/android-arm@0.25.4': - optional: true - - '@esbuild/android-x64@0.18.20': - optional: true - - '@esbuild/android-x64@0.25.12': - optional: true - - '@esbuild/android-x64@0.25.4': - optional: true - - '@esbuild/darwin-arm64@0.18.20': - optional: true - - '@esbuild/darwin-arm64@0.25.12': - optional: true - - '@esbuild/darwin-arm64@0.25.4': - optional: true - - '@esbuild/darwin-x64@0.18.20': - optional: true - - '@esbuild/darwin-x64@0.25.12': - optional: true - - '@esbuild/darwin-x64@0.25.4': - optional: true - - '@esbuild/freebsd-arm64@0.18.20': - optional: true - - '@esbuild/freebsd-arm64@0.25.12': - optional: true - - '@esbuild/freebsd-arm64@0.25.4': - optional: true - - '@esbuild/freebsd-x64@0.18.20': - optional: true - - '@esbuild/freebsd-x64@0.25.12': - optional: true - - '@esbuild/freebsd-x64@0.25.4': - optional: true - - '@esbuild/linux-arm64@0.18.20': - optional: true - - '@esbuild/linux-arm64@0.25.12': - optional: true - - '@esbuild/linux-arm64@0.25.4': - optional: true - - '@esbuild/linux-arm@0.18.20': - optional: true - - '@esbuild/linux-arm@0.25.12': - optional: true - - '@esbuild/linux-arm@0.25.4': - optional: true - - '@esbuild/linux-ia32@0.18.20': - optional: true - - '@esbuild/linux-ia32@0.25.12': - optional: true - - '@esbuild/linux-ia32@0.25.4': - optional: true - - '@esbuild/linux-loong64@0.18.20': - optional: true - - '@esbuild/linux-loong64@0.25.12': - optional: true - - '@esbuild/linux-loong64@0.25.4': - optional: true - - '@esbuild/linux-mips64el@0.18.20': - optional: true - - '@esbuild/linux-mips64el@0.25.12': - optional: true - - '@esbuild/linux-mips64el@0.25.4': - optional: true - - '@esbuild/linux-ppc64@0.18.20': - optional: true - - '@esbuild/linux-ppc64@0.25.12': - optional: true - - '@esbuild/linux-ppc64@0.25.4': - optional: true - - '@esbuild/linux-riscv64@0.18.20': - optional: true - - '@esbuild/linux-riscv64@0.25.12': - optional: true - - '@esbuild/linux-riscv64@0.25.4': - optional: true - - '@esbuild/linux-s390x@0.18.20': - optional: true - - '@esbuild/linux-s390x@0.25.12': - optional: true - - '@esbuild/linux-s390x@0.25.4': - optional: true - - '@esbuild/linux-x64@0.18.20': - optional: true - - '@esbuild/linux-x64@0.25.12': - optional: true - - '@esbuild/linux-x64@0.25.4': - optional: true - - '@esbuild/netbsd-arm64@0.25.12': - optional: true - - '@esbuild/netbsd-arm64@0.25.4': - optional: true - - '@esbuild/netbsd-x64@0.18.20': - optional: true - - '@esbuild/netbsd-x64@0.25.12': - optional: true - - '@esbuild/netbsd-x64@0.25.4': - optional: true - - '@esbuild/openbsd-arm64@0.25.12': - optional: true - - '@esbuild/openbsd-arm64@0.25.4': - optional: true - - '@esbuild/openbsd-x64@0.18.20': - optional: true - - '@esbuild/openbsd-x64@0.25.12': - optional: true - - '@esbuild/openbsd-x64@0.25.4': - optional: true - - '@esbuild/openharmony-arm64@0.25.12': - optional: true - - '@esbuild/sunos-x64@0.18.20': - optional: true - - '@esbuild/sunos-x64@0.25.12': - optional: true - - '@esbuild/sunos-x64@0.25.4': - optional: true - - '@esbuild/win32-arm64@0.18.20': - optional: true - - '@esbuild/win32-arm64@0.25.12': - optional: true - - '@esbuild/win32-arm64@0.25.4': - optional: true - - '@esbuild/win32-ia32@0.18.20': - optional: true - - '@esbuild/win32-ia32@0.25.12': - optional: true - - '@esbuild/win32-ia32@0.25.4': - optional: true - - '@esbuild/win32-x64@0.18.20': - optional: true - - '@esbuild/win32-x64@0.25.12': - optional: true - - '@esbuild/win32-x64@0.25.4': - optional: true - - '@eslint-community/eslint-utils@4.9.0(eslint@9.39.1)': - dependencies: - eslint: 9.39.1 - eslint-visitor-keys: 3.4.3 - - '@eslint-community/regexpp@4.12.2': {} - - '@eslint/config-array@0.21.1': - dependencies: - '@eslint/object-schema': 2.1.7 - debug: 4.4.3 - minimatch: 3.1.2 - transitivePeerDependencies: - - supports-color - - '@eslint/config-helpers@0.4.2': - dependencies: - '@eslint/core': 0.17.0 - - '@eslint/core@0.17.0': - dependencies: - '@types/json-schema': 7.0.15 - - '@eslint/eslintrc@3.3.1': - dependencies: - ajv: 6.12.6 - debug: 4.4.3 - espree: 10.4.0 - globals: 14.0.0 - ignore: 5.3.2 - import-fresh: 3.3.1 - js-yaml: 4.1.0 - minimatch: 3.1.2 - strip-json-comments: 3.1.1 - transitivePeerDependencies: - - supports-color - - '@eslint/js@9.39.1': {} - - '@eslint/object-schema@2.1.7': {} - - '@eslint/plugin-kit@0.4.1': - dependencies: - '@eslint/core': 0.17.0 - levn: 0.4.1 - - '@humanfs/core@0.19.1': {} - - '@humanfs/node@0.16.7': - dependencies: - '@humanfs/core': 0.19.1 - '@humanwhocodes/retry': 0.4.3 - - '@humanwhocodes/module-importer@1.0.1': {} - - '@humanwhocodes/retry@0.4.3': {} - - '@img/sharp-darwin-arm64@0.33.5': - optionalDependencies: - '@img/sharp-libvips-darwin-arm64': 1.0.4 - optional: true - - '@img/sharp-darwin-x64@0.33.5': - optionalDependencies: - '@img/sharp-libvips-darwin-x64': 1.0.4 - optional: true - - '@img/sharp-libvips-darwin-arm64@1.0.4': - optional: true - - '@img/sharp-libvips-darwin-x64@1.0.4': - optional: true - - '@img/sharp-libvips-linux-arm64@1.0.4': - optional: true - - '@img/sharp-libvips-linux-arm@1.0.5': - optional: true - - '@img/sharp-libvips-linux-s390x@1.0.4': - optional: true - - '@img/sharp-libvips-linux-x64@1.0.4': - optional: true - - '@img/sharp-libvips-linuxmusl-arm64@1.0.4': - optional: true - - '@img/sharp-libvips-linuxmusl-x64@1.0.4': - optional: true - - '@img/sharp-linux-arm64@0.33.5': - optionalDependencies: - '@img/sharp-libvips-linux-arm64': 1.0.4 - optional: true - - '@img/sharp-linux-arm@0.33.5': - optionalDependencies: - '@img/sharp-libvips-linux-arm': 1.0.5 - optional: true - - '@img/sharp-linux-s390x@0.33.5': - optionalDependencies: - '@img/sharp-libvips-linux-s390x': 1.0.4 - optional: true - - '@img/sharp-linux-x64@0.33.5': - optionalDependencies: - '@img/sharp-libvips-linux-x64': 1.0.4 - optional: true - - '@img/sharp-linuxmusl-arm64@0.33.5': - optionalDependencies: - '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 - optional: true - - '@img/sharp-linuxmusl-x64@0.33.5': - optionalDependencies: - '@img/sharp-libvips-linuxmusl-x64': 1.0.4 - optional: true - - '@img/sharp-wasm32@0.33.5': - dependencies: - '@emnapi/runtime': 1.7.0 - optional: true - - '@img/sharp-win32-ia32@0.33.5': - optional: true - - '@img/sharp-win32-x64@0.33.5': - optional: true - - '@jridgewell/resolve-uri@3.1.2': {} - - '@jridgewell/sourcemap-codec@1.5.5': {} - - '@jridgewell/trace-mapping@0.3.9': - dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.5 - - '@nodelib/fs.scandir@2.1.5': - dependencies: - '@nodelib/fs.stat': 2.0.5 - run-parallel: 1.2.0 - - '@nodelib/fs.stat@2.0.5': {} - - '@nodelib/fs.walk@1.2.8': - dependencies: - '@nodelib/fs.scandir': 2.1.5 - fastq: 1.19.1 - - '@poppinss/colors@4.1.5': - dependencies: - kleur: 4.1.5 - - '@poppinss/dumper@0.6.5': - dependencies: - '@poppinss/colors': 4.1.5 - '@sindresorhus/is': 7.1.1 - supports-color: 10.2.2 - - '@poppinss/exception@1.2.2': {} - - '@sindresorhus/is@7.1.1': {} - - '@speed-highlight/core@1.2.12': {} - - '@trpc/server@11.7.1(typescript@5.9.3)': - dependencies: - typescript: 5.9.3 - - '@types/bcrypt@6.0.0': - dependencies: - '@types/node': 24.10.0 - - '@types/better-sqlite3@7.6.13': - dependencies: - '@types/node': 24.10.0 - - '@types/body-parser@1.19.6': - dependencies: - '@types/connect': 3.4.38 - '@types/node': 24.10.0 - - '@types/connect@3.4.38': - dependencies: - '@types/node': 24.10.0 - - '@types/cors@2.8.19': - dependencies: - '@types/node': 24.10.0 - - '@types/estree@1.0.8': {} - - '@types/express-serve-static-core@5.1.0': - dependencies: - '@types/node': 24.10.0 - '@types/qs': 6.14.0 - '@types/range-parser': 1.2.7 - '@types/send': 1.2.1 - - '@types/express@5.0.5': - dependencies: - '@types/body-parser': 1.19.6 - '@types/express-serve-static-core': 5.1.0 - '@types/serve-static': 1.15.10 - - '@types/http-errors@2.0.5': {} - - '@types/json-schema@7.0.15': {} - - '@types/mime@1.3.5': {} - - '@types/node-cron@3.0.11': {} - - '@types/node@24.10.0': - dependencies: - undici-types: 7.16.0 - - '@types/qs@6.14.0': {} - - '@types/range-parser@1.2.7': {} - - '@types/send@0.17.6': - dependencies: - '@types/mime': 1.3.5 - '@types/node': 24.10.0 - - '@types/send@1.2.1': - dependencies: - '@types/node': 24.10.0 - - '@types/serve-static@1.15.10': - dependencies: - '@types/http-errors': 2.0.5 - '@types/node': 24.10.0 - '@types/send': 0.17.6 - - '@typescript-eslint/eslint-plugin@8.46.4(@typescript-eslint/parser@8.46.4(eslint@9.39.1)(typescript@5.9.3))(eslint@9.39.1)(typescript@5.9.3)': - dependencies: - '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.46.4(eslint@9.39.1)(typescript@5.9.3) - '@typescript-eslint/scope-manager': 8.46.4 - '@typescript-eslint/type-utils': 8.46.4(eslint@9.39.1)(typescript@5.9.3) - '@typescript-eslint/utils': 8.46.4(eslint@9.39.1)(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.46.4 - eslint: 9.39.1 - graphemer: 1.4.0 - ignore: 7.0.5 - natural-compare: 1.4.0 - ts-api-utils: 2.1.0(typescript@5.9.3) - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/parser@8.46.4(eslint@9.39.1)(typescript@5.9.3)': - dependencies: - '@typescript-eslint/scope-manager': 8.46.4 - '@typescript-eslint/types': 8.46.4 - '@typescript-eslint/typescript-estree': 8.46.4(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.46.4 - debug: 4.4.3 - eslint: 9.39.1 - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/project-service@8.46.4(typescript@5.9.3)': - dependencies: - '@typescript-eslint/tsconfig-utils': 8.46.4(typescript@5.9.3) - '@typescript-eslint/types': 8.46.4 - debug: 4.4.3 - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/scope-manager@8.46.4': - dependencies: - '@typescript-eslint/types': 8.46.4 - '@typescript-eslint/visitor-keys': 8.46.4 - - '@typescript-eslint/tsconfig-utils@8.46.4(typescript@5.9.3)': - dependencies: - typescript: 5.9.3 - - '@typescript-eslint/type-utils@8.46.4(eslint@9.39.1)(typescript@5.9.3)': - dependencies: - '@typescript-eslint/types': 8.46.4 - '@typescript-eslint/typescript-estree': 8.46.4(typescript@5.9.3) - '@typescript-eslint/utils': 8.46.4(eslint@9.39.1)(typescript@5.9.3) - debug: 4.4.3 - eslint: 9.39.1 - ts-api-utils: 2.1.0(typescript@5.9.3) - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/types@8.46.4': {} - - '@typescript-eslint/typescript-estree@8.46.4(typescript@5.9.3)': - dependencies: - '@typescript-eslint/project-service': 8.46.4(typescript@5.9.3) - '@typescript-eslint/tsconfig-utils': 8.46.4(typescript@5.9.3) - '@typescript-eslint/types': 8.46.4 - '@typescript-eslint/visitor-keys': 8.46.4 - debug: 4.4.3 - fast-glob: 3.3.3 - is-glob: 4.0.3 - minimatch: 9.0.5 - semver: 7.7.3 - ts-api-utils: 2.1.0(typescript@5.9.3) - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/utils@8.46.4(eslint@9.39.1)(typescript@5.9.3)': - dependencies: - '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.1) - '@typescript-eslint/scope-manager': 8.46.4 - '@typescript-eslint/types': 8.46.4 - '@typescript-eslint/typescript-estree': 8.46.4(typescript@5.9.3) - eslint: 9.39.1 - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/visitor-keys@8.46.4': - dependencies: - '@typescript-eslint/types': 8.46.4 - eslint-visitor-keys: 4.2.1 - - accepts@2.0.0: - dependencies: - mime-types: 3.0.1 - negotiator: 1.0.0 - - acorn-jsx@5.3.2(acorn@8.15.0): - dependencies: - acorn: 8.15.0 - - acorn-walk@8.3.2: {} - - acorn@8.14.0: {} - - acorn@8.15.0: {} - - ajv@6.12.6: - dependencies: - fast-deep-equal: 3.1.3 - fast-json-stable-stringify: 2.1.0 - json-schema-traverse: 0.4.1 - uri-js: 4.4.1 - - ansi-styles@4.3.0: - dependencies: - color-convert: 2.0.1 - - argparse@2.0.1: {} - - balanced-match@1.0.2: {} - - base64-js@1.5.1: {} - - bcrypt@6.0.0: - dependencies: - node-addon-api: 8.5.0 - node-gyp-build: 4.8.4 - - better-sqlite3@12.4.1: - dependencies: - bindings: 1.5.0 - prebuild-install: 7.1.3 - - bindings@1.5.0: - dependencies: - file-uri-to-path: 1.0.0 - - bl@4.1.0: - dependencies: - buffer: 5.7.1 - inherits: 2.0.4 - readable-stream: 3.6.2 - - blake3-wasm@2.1.5: {} - - body-parser@2.2.0: - dependencies: - bytes: 3.1.2 - content-type: 1.0.5 - debug: 4.4.3 - http-errors: 2.0.0 - iconv-lite: 0.6.3 - on-finished: 2.4.1 - qs: 6.14.0 - raw-body: 3.0.1 - type-is: 2.0.1 - transitivePeerDependencies: - - supports-color - - brace-expansion@1.1.12: - dependencies: - balanced-match: 1.0.2 - concat-map: 0.0.1 - - brace-expansion@2.0.2: - dependencies: - balanced-match: 1.0.2 - - braces@3.0.3: - dependencies: - fill-range: 7.1.1 - - buffer-from@1.1.2: {} - - buffer@5.7.1: - dependencies: - base64-js: 1.5.1 - ieee754: 1.2.1 - - bytes@3.1.2: {} - - call-bind-apply-helpers@1.0.2: - dependencies: - es-errors: 1.3.0 - function-bind: 1.1.2 - - call-bound@1.0.4: - dependencies: - call-bind-apply-helpers: 1.0.2 - get-intrinsic: 1.3.0 - - callsites@3.1.0: {} - - chalk@4.1.2: - dependencies: - ansi-styles: 4.3.0 - supports-color: 7.2.0 - - chownr@1.1.4: {} - - color-convert@2.0.1: - dependencies: - color-name: 1.1.4 - - color-name@1.1.4: {} - - color-string@1.9.1: - dependencies: - color-name: 1.1.4 - simple-swizzle: 0.2.4 - - color@4.2.3: - dependencies: - color-convert: 2.0.1 - color-string: 1.9.1 - - concat-map@0.0.1: {} - - content-disposition@1.0.0: - dependencies: - safe-buffer: 5.2.1 - - content-type@1.0.5: {} - - cookie-signature@1.2.2: {} - - cookie@0.7.2: {} - - cookie@1.0.2: {} - - cors@2.8.5: - dependencies: - object-assign: 4.1.1 - vary: 1.1.2 - - cross-spawn@7.0.6: - dependencies: - path-key: 3.1.1 - shebang-command: 2.0.0 - which: 2.0.2 - - debug@4.4.3: - dependencies: - ms: 2.1.3 - - decompress-response@6.0.0: - dependencies: - mimic-response: 3.1.0 - - deep-extend@0.6.0: {} - - deep-is@0.1.4: {} - - depd@2.0.0: {} - - detect-libc@2.1.2: {} - - drizzle-kit@0.31.6: - dependencies: - '@drizzle-team/brocli': 0.10.2 - '@esbuild-kit/esm-loader': 2.6.5 - esbuild: 0.25.12 - esbuild-register: 3.6.0(esbuild@0.25.12) - transitivePeerDependencies: - - supports-color - - drizzle-orm@0.44.7(@cloudflare/workers-types@4.20251111.0)(@types/better-sqlite3@7.6.13)(better-sqlite3@12.4.1): - optionalDependencies: - '@cloudflare/workers-types': 4.20251111.0 - '@types/better-sqlite3': 7.6.13 - better-sqlite3: 12.4.1 - - drizzle-zod@0.8.3(drizzle-orm@0.44.7(@cloudflare/workers-types@4.20251111.0)(@types/better-sqlite3@7.6.13)(better-sqlite3@12.4.1))(zod@4.1.12): - dependencies: - drizzle-orm: 0.44.7(@cloudflare/workers-types@4.20251111.0)(@types/better-sqlite3@7.6.13)(better-sqlite3@12.4.1) - zod: 4.1.12 - - dunder-proto@1.0.1: - dependencies: - call-bind-apply-helpers: 1.0.2 - es-errors: 1.3.0 - gopd: 1.2.0 - - ee-first@1.1.1: {} - - encodeurl@2.0.0: {} - - end-of-stream@1.4.5: - dependencies: - once: 1.4.0 - - entities@7.0.0: {} - - error-stack-parser-es@1.0.5: {} - - es-define-property@1.0.1: {} - - es-errors@1.3.0: {} - - es-object-atoms@1.1.1: - dependencies: - es-errors: 1.3.0 - - esbuild-register@3.6.0(esbuild@0.25.12): - dependencies: - debug: 4.4.3 - esbuild: 0.25.12 - transitivePeerDependencies: - - supports-color - - esbuild@0.18.20: - optionalDependencies: - '@esbuild/android-arm': 0.18.20 - '@esbuild/android-arm64': 0.18.20 - '@esbuild/android-x64': 0.18.20 - '@esbuild/darwin-arm64': 0.18.20 - '@esbuild/darwin-x64': 0.18.20 - '@esbuild/freebsd-arm64': 0.18.20 - '@esbuild/freebsd-x64': 0.18.20 - '@esbuild/linux-arm': 0.18.20 - '@esbuild/linux-arm64': 0.18.20 - '@esbuild/linux-ia32': 0.18.20 - '@esbuild/linux-loong64': 0.18.20 - '@esbuild/linux-mips64el': 0.18.20 - '@esbuild/linux-ppc64': 0.18.20 - '@esbuild/linux-riscv64': 0.18.20 - '@esbuild/linux-s390x': 0.18.20 - '@esbuild/linux-x64': 0.18.20 - '@esbuild/netbsd-x64': 0.18.20 - '@esbuild/openbsd-x64': 0.18.20 - '@esbuild/sunos-x64': 0.18.20 - '@esbuild/win32-arm64': 0.18.20 - '@esbuild/win32-ia32': 0.18.20 - '@esbuild/win32-x64': 0.18.20 - - esbuild@0.25.12: - optionalDependencies: - '@esbuild/aix-ppc64': 0.25.12 - '@esbuild/android-arm': 0.25.12 - '@esbuild/android-arm64': 0.25.12 - '@esbuild/android-x64': 0.25.12 - '@esbuild/darwin-arm64': 0.25.12 - '@esbuild/darwin-x64': 0.25.12 - '@esbuild/freebsd-arm64': 0.25.12 - '@esbuild/freebsd-x64': 0.25.12 - '@esbuild/linux-arm': 0.25.12 - '@esbuild/linux-arm64': 0.25.12 - '@esbuild/linux-ia32': 0.25.12 - '@esbuild/linux-loong64': 0.25.12 - '@esbuild/linux-mips64el': 0.25.12 - '@esbuild/linux-ppc64': 0.25.12 - '@esbuild/linux-riscv64': 0.25.12 - '@esbuild/linux-s390x': 0.25.12 - '@esbuild/linux-x64': 0.25.12 - '@esbuild/netbsd-arm64': 0.25.12 - '@esbuild/netbsd-x64': 0.25.12 - '@esbuild/openbsd-arm64': 0.25.12 - '@esbuild/openbsd-x64': 0.25.12 - '@esbuild/openharmony-arm64': 0.25.12 - '@esbuild/sunos-x64': 0.25.12 - '@esbuild/win32-arm64': 0.25.12 - '@esbuild/win32-ia32': 0.25.12 - '@esbuild/win32-x64': 0.25.12 - - esbuild@0.25.4: - optionalDependencies: - '@esbuild/aix-ppc64': 0.25.4 - '@esbuild/android-arm': 0.25.4 - '@esbuild/android-arm64': 0.25.4 - '@esbuild/android-x64': 0.25.4 - '@esbuild/darwin-arm64': 0.25.4 - '@esbuild/darwin-x64': 0.25.4 - '@esbuild/freebsd-arm64': 0.25.4 - '@esbuild/freebsd-x64': 0.25.4 - '@esbuild/linux-arm': 0.25.4 - '@esbuild/linux-arm64': 0.25.4 - '@esbuild/linux-ia32': 0.25.4 - '@esbuild/linux-loong64': 0.25.4 - '@esbuild/linux-mips64el': 0.25.4 - '@esbuild/linux-ppc64': 0.25.4 - '@esbuild/linux-riscv64': 0.25.4 - '@esbuild/linux-s390x': 0.25.4 - '@esbuild/linux-x64': 0.25.4 - '@esbuild/netbsd-arm64': 0.25.4 - '@esbuild/netbsd-x64': 0.25.4 - '@esbuild/openbsd-arm64': 0.25.4 - '@esbuild/openbsd-x64': 0.25.4 - '@esbuild/sunos-x64': 0.25.4 - '@esbuild/win32-arm64': 0.25.4 - '@esbuild/win32-ia32': 0.25.4 - '@esbuild/win32-x64': 0.25.4 - - escape-html@1.0.3: {} - - escape-string-regexp@4.0.0: {} - - eslint-plugin-drizzle@0.2.3(eslint@9.39.1): - dependencies: - eslint: 9.39.1 - - eslint-scope@8.4.0: - dependencies: - esrecurse: 4.3.0 - estraverse: 5.3.0 - - eslint-visitor-keys@3.4.3: {} - - eslint-visitor-keys@4.2.1: {} - - eslint@9.39.1: - dependencies: - '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.1) - '@eslint-community/regexpp': 4.12.2 - '@eslint/config-array': 0.21.1 - '@eslint/config-helpers': 0.4.2 - '@eslint/core': 0.17.0 - '@eslint/eslintrc': 3.3.1 - '@eslint/js': 9.39.1 - '@eslint/plugin-kit': 0.4.1 - '@humanfs/node': 0.16.7 - '@humanwhocodes/module-importer': 1.0.1 - '@humanwhocodes/retry': 0.4.3 - '@types/estree': 1.0.8 - ajv: 6.12.6 - chalk: 4.1.2 - cross-spawn: 7.0.6 - debug: 4.4.3 - escape-string-regexp: 4.0.0 - eslint-scope: 8.4.0 - eslint-visitor-keys: 4.2.1 - espree: 10.4.0 - esquery: 1.6.0 - esutils: 2.0.3 - fast-deep-equal: 3.1.3 - file-entry-cache: 8.0.0 - find-up: 5.0.0 - glob-parent: 6.0.2 - ignore: 5.3.2 - imurmurhash: 0.1.4 - is-glob: 4.0.3 - json-stable-stringify-without-jsonify: 1.0.1 - lodash.merge: 4.6.2 - minimatch: 3.1.2 - natural-compare: 1.4.0 - optionator: 0.9.4 - transitivePeerDependencies: - - supports-color - - espree@10.4.0: - dependencies: - acorn: 8.15.0 - acorn-jsx: 5.3.2(acorn@8.15.0) - eslint-visitor-keys: 4.2.1 - - esquery@1.6.0: - dependencies: - estraverse: 5.3.0 - - esrecurse@4.3.0: - dependencies: - estraverse: 5.3.0 - - estraverse@5.3.0: {} - - esutils@2.0.3: {} - - etag@1.8.1: {} - - exit-hook@2.2.1: {} - - expand-template@2.0.3: {} - - express@5.1.0: - dependencies: - accepts: 2.0.0 - body-parser: 2.2.0 - content-disposition: 1.0.0 - content-type: 1.0.5 - cookie: 0.7.2 - cookie-signature: 1.2.2 - debug: 4.4.3 - encodeurl: 2.0.0 - escape-html: 1.0.3 - etag: 1.8.1 - finalhandler: 2.1.0 - fresh: 2.0.0 - http-errors: 2.0.0 - merge-descriptors: 2.0.0 - mime-types: 3.0.1 - on-finished: 2.4.1 - once: 1.4.0 - parseurl: 1.3.3 - proxy-addr: 2.0.7 - qs: 6.14.0 - range-parser: 1.2.1 - router: 2.2.0 - send: 1.2.0 - serve-static: 2.2.0 - statuses: 2.0.2 - type-is: 2.0.1 - vary: 1.1.2 - transitivePeerDependencies: - - supports-color - - fast-deep-equal@3.1.3: {} - - fast-glob@3.3.3: - dependencies: - '@nodelib/fs.stat': 2.0.5 - '@nodelib/fs.walk': 1.2.8 - glob-parent: 5.1.2 - merge2: 1.4.1 - micromatch: 4.0.8 - - fast-json-stable-stringify@2.1.0: {} - - fast-levenshtein@2.0.6: {} - - fast-xml-parser@5.3.1: - dependencies: - strnum: 2.1.1 - - fastq@1.19.1: - dependencies: - reusify: 1.1.0 - - feedsmith@2.4.0: - dependencies: - entities: 7.0.0 - fast-xml-parser: 5.3.1 - - file-entry-cache@8.0.0: - dependencies: - flat-cache: 4.0.1 - - file-uri-to-path@1.0.0: {} - - fill-range@7.1.1: - dependencies: - to-regex-range: 5.0.1 - - finalhandler@2.1.0: - dependencies: - debug: 4.4.3 - encodeurl: 2.0.0 - escape-html: 1.0.3 - on-finished: 2.4.1 - parseurl: 1.3.3 - statuses: 2.0.2 - transitivePeerDependencies: - - supports-color - - find-up@5.0.0: - dependencies: - locate-path: 6.0.0 - path-exists: 4.0.0 - - flat-cache@4.0.1: - dependencies: - flatted: 3.3.3 - keyv: 4.5.4 - - flatted@3.3.3: {} - - forwarded@0.2.0: {} - - fresh@2.0.0: {} - - fs-constants@1.0.0: {} - - fsevents@2.3.3: - optional: true - - function-bind@1.1.2: {} - - get-intrinsic@1.3.0: - dependencies: - call-bind-apply-helpers: 1.0.2 - es-define-property: 1.0.1 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - function-bind: 1.1.2 - get-proto: 1.0.1 - gopd: 1.2.0 - has-symbols: 1.1.0 - hasown: 2.0.2 - math-intrinsics: 1.1.0 - - get-proto@1.0.1: - dependencies: - dunder-proto: 1.0.1 - es-object-atoms: 1.1.1 - - get-tsconfig@4.13.0: - dependencies: - resolve-pkg-maps: 1.0.0 - - github-from-package@0.0.0: {} - - glob-parent@5.1.2: - dependencies: - is-glob: 4.0.3 - - glob-parent@6.0.2: - dependencies: - is-glob: 4.0.3 - - glob-to-regexp@0.4.1: {} - - globals@14.0.0: {} - - gopd@1.2.0: {} - - graphemer@1.4.0: {} - - has-flag@4.0.0: {} - - has-symbols@1.1.0: {} - - hasown@2.0.2: - dependencies: - function-bind: 1.1.2 - - http-errors@2.0.0: - dependencies: - depd: 2.0.0 - inherits: 2.0.4 - setprototypeof: 1.2.0 - statuses: 2.0.1 - toidentifier: 1.0.1 - - iconv-lite@0.6.3: - dependencies: - safer-buffer: 2.1.2 - - iconv-lite@0.7.0: - dependencies: - safer-buffer: 2.1.2 - - ieee754@1.2.1: {} - - ignore@5.3.2: {} - - ignore@7.0.5: {} - - import-fresh@3.3.1: - dependencies: - parent-module: 1.0.1 - resolve-from: 4.0.0 - - imurmurhash@0.1.4: {} - - inherits@2.0.4: {} - - ini@1.3.8: {} - - ipaddr.js@1.9.1: {} - - is-arrayish@0.3.4: {} - - is-extglob@2.1.1: {} - - is-glob@4.0.3: - dependencies: - is-extglob: 2.1.1 - - is-number@7.0.0: {} - - is-promise@4.0.0: {} - - isexe@2.0.0: {} - - jose@6.1.1: {} - - js-yaml@4.1.0: - dependencies: - argparse: 2.0.1 - - json-buffer@3.0.1: {} - - json-schema-traverse@0.4.1: {} - - json-stable-stringify-without-jsonify@1.0.1: {} - - keyv@4.5.4: - dependencies: - json-buffer: 3.0.1 - - kleur@4.1.5: {} - - levn@0.4.1: - dependencies: - prelude-ls: 1.2.1 - type-check: 0.4.0 - - locate-path@6.0.0: - dependencies: - p-locate: 5.0.0 - - lodash.merge@4.6.2: {} - - math-intrinsics@1.1.0: {} - - media-typer@1.1.0: {} - - merge-descriptors@2.0.0: {} - - merge2@1.4.1: {} - - micromatch@4.0.8: - dependencies: - braces: 3.0.3 - picomatch: 2.3.1 - - mime-db@1.54.0: {} - - mime-types@3.0.1: - dependencies: - mime-db: 1.54.0 - - mime@3.0.0: {} - - mimic-response@3.1.0: {} - - miniflare@4.20251109.0: - dependencies: - '@cspotcode/source-map-support': 0.8.1 - acorn: 8.14.0 - acorn-walk: 8.3.2 - exit-hook: 2.2.1 - glob-to-regexp: 0.4.1 - sharp: 0.33.5 - stoppable: 1.1.0 - undici: 7.14.0 - workerd: 1.20251109.0 - ws: 8.18.0 - youch: 4.1.0-beta.10 - zod: 3.22.3 - transitivePeerDependencies: - - bufferutil - - utf-8-validate - - minimatch@3.1.2: - dependencies: - brace-expansion: 1.1.12 - - minimatch@9.0.5: - dependencies: - brace-expansion: 2.0.2 - - minimist@1.2.8: {} - - mkdirp-classic@0.5.3: {} - - ms@2.1.3: {} - - napi-build-utils@2.0.0: {} - - natural-compare@1.4.0: {} - - negotiator@1.0.0: {} - - node-abi@3.80.0: - dependencies: - semver: 7.7.3 - - node-addon-api@8.5.0: {} - - node-cron@4.2.1: {} - - node-gyp-build@4.8.4: {} - - object-assign@4.1.1: {} - - object-inspect@1.13.4: {} - - on-finished@2.4.1: - dependencies: - ee-first: 1.1.1 - - once@1.4.0: - dependencies: - wrappy: 1.0.2 - - optionator@0.9.4: - dependencies: - deep-is: 0.1.4 - fast-levenshtein: 2.0.6 - levn: 0.4.1 - prelude-ls: 1.2.1 - type-check: 0.4.0 - word-wrap: 1.2.5 - - p-limit@3.1.0: - dependencies: - yocto-queue: 0.1.0 - - p-locate@5.0.0: - dependencies: - p-limit: 3.1.0 - - parent-module@1.0.1: - dependencies: - callsites: 3.1.0 - - parseurl@1.3.3: {} - - path-exists@4.0.0: {} - - path-key@3.1.1: {} - - path-to-regexp@6.3.0: {} - - path-to-regexp@8.3.0: {} - - pathe@2.0.3: {} - - picomatch@2.3.1: {} - - prebuild-install@7.1.3: - dependencies: - detect-libc: 2.1.2 - expand-template: 2.0.3 - github-from-package: 0.0.0 - minimist: 1.2.8 - mkdirp-classic: 0.5.3 - napi-build-utils: 2.0.0 - node-abi: 3.80.0 - pump: 3.0.3 - rc: 1.2.8 - simple-get: 4.0.1 - tar-fs: 2.1.4 - tunnel-agent: 0.6.0 - - prelude-ls@1.2.1: {} - - prettier@3.6.2: {} - - proxy-addr@2.0.7: - dependencies: - forwarded: 0.2.0 - ipaddr.js: 1.9.1 - - pump@3.0.3: - dependencies: - end-of-stream: 1.4.5 - once: 1.4.0 - - punycode@2.3.1: {} - - qs@6.14.0: - dependencies: - side-channel: 1.1.0 - - queue-microtask@1.2.3: {} - - range-parser@1.2.1: {} - - raw-body@3.0.1: - dependencies: - bytes: 3.1.2 - http-errors: 2.0.0 - iconv-lite: 0.7.0 - unpipe: 1.0.0 - - rc@1.2.8: - dependencies: - deep-extend: 0.6.0 - ini: 1.3.8 - minimist: 1.2.8 - strip-json-comments: 2.0.1 - - readable-stream@3.6.2: - dependencies: - inherits: 2.0.4 - string_decoder: 1.3.0 - util-deprecate: 1.0.2 - - resolve-from@4.0.0: {} - - resolve-pkg-maps@1.0.0: {} - - reusify@1.1.0: {} - - router@2.2.0: - dependencies: - debug: 4.4.3 - depd: 2.0.0 - is-promise: 4.0.0 - parseurl: 1.3.3 - path-to-regexp: 8.3.0 - transitivePeerDependencies: - - supports-color - - run-parallel@1.2.0: - dependencies: - queue-microtask: 1.2.3 - - safe-buffer@5.2.1: {} - - safer-buffer@2.1.2: {} - - semver@7.7.3: {} - - send@1.2.0: - dependencies: - debug: 4.4.3 - encodeurl: 2.0.0 - escape-html: 1.0.3 - etag: 1.8.1 - fresh: 2.0.0 - http-errors: 2.0.0 - mime-types: 3.0.1 - ms: 2.1.3 - on-finished: 2.4.1 - range-parser: 1.2.1 - statuses: 2.0.2 - transitivePeerDependencies: - - supports-color - - serve-static@2.2.0: - dependencies: - encodeurl: 2.0.0 - escape-html: 1.0.3 - parseurl: 1.3.3 - send: 1.2.0 - transitivePeerDependencies: - - supports-color - - setprototypeof@1.2.0: {} - - sharp@0.33.5: - dependencies: - color: 4.2.3 - detect-libc: 2.1.2 - semver: 7.7.3 - optionalDependencies: - '@img/sharp-darwin-arm64': 0.33.5 - '@img/sharp-darwin-x64': 0.33.5 - '@img/sharp-libvips-darwin-arm64': 1.0.4 - '@img/sharp-libvips-darwin-x64': 1.0.4 - '@img/sharp-libvips-linux-arm': 1.0.5 - '@img/sharp-libvips-linux-arm64': 1.0.4 - '@img/sharp-libvips-linux-s390x': 1.0.4 - '@img/sharp-libvips-linux-x64': 1.0.4 - '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 - '@img/sharp-libvips-linuxmusl-x64': 1.0.4 - '@img/sharp-linux-arm': 0.33.5 - '@img/sharp-linux-arm64': 0.33.5 - '@img/sharp-linux-s390x': 0.33.5 - '@img/sharp-linux-x64': 0.33.5 - '@img/sharp-linuxmusl-arm64': 0.33.5 - '@img/sharp-linuxmusl-x64': 0.33.5 - '@img/sharp-wasm32': 0.33.5 - '@img/sharp-win32-ia32': 0.33.5 - '@img/sharp-win32-x64': 0.33.5 - - shebang-command@2.0.0: - dependencies: - shebang-regex: 3.0.0 - - shebang-regex@3.0.0: {} - - side-channel-list@1.0.0: - dependencies: - es-errors: 1.3.0 - object-inspect: 1.13.4 - - side-channel-map@1.0.1: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - get-intrinsic: 1.3.0 - object-inspect: 1.13.4 - - side-channel-weakmap@1.0.2: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - get-intrinsic: 1.3.0 - object-inspect: 1.13.4 - side-channel-map: 1.0.1 - - side-channel@1.1.0: - dependencies: - es-errors: 1.3.0 - object-inspect: 1.13.4 - side-channel-list: 1.0.0 - side-channel-map: 1.0.1 - side-channel-weakmap: 1.0.2 - - simple-concat@1.0.1: {} - - simple-get@4.0.1: - dependencies: - decompress-response: 6.0.0 - once: 1.4.0 - simple-concat: 1.0.1 - - simple-swizzle@0.2.4: - dependencies: - is-arrayish: 0.3.4 - - source-map-support@0.5.21: - dependencies: - buffer-from: 1.1.2 - source-map: 0.6.1 - - source-map@0.6.1: {} - - statuses@2.0.1: {} - - statuses@2.0.2: {} - - stoppable@1.1.0: {} - - string_decoder@1.3.0: - dependencies: - safe-buffer: 5.2.1 - - strip-json-comments@2.0.1: {} - - strip-json-comments@3.1.1: {} - - strnum@2.1.1: {} - - supports-color@10.2.2: {} - - supports-color@7.2.0: - dependencies: - has-flag: 4.0.0 - - tar-fs@2.1.4: - dependencies: - chownr: 1.1.4 - mkdirp-classic: 0.5.3 - pump: 3.0.3 - tar-stream: 2.2.0 - - tar-stream@2.2.0: - dependencies: - bl: 4.1.0 - end-of-stream: 1.4.5 - fs-constants: 1.0.0 - inherits: 2.0.4 - readable-stream: 3.6.2 - - to-regex-range@5.0.1: - dependencies: - is-number: 7.0.0 - - toidentifier@1.0.1: {} - - ts-api-utils@2.1.0(typescript@5.9.3): - dependencies: - typescript: 5.9.3 - - tslib@2.8.1: - optional: true - - tsx@4.20.6: - dependencies: - esbuild: 0.25.12 - get-tsconfig: 4.13.0 - optionalDependencies: - fsevents: 2.3.3 - - tunnel-agent@0.6.0: - dependencies: - safe-buffer: 5.2.1 - - type-check@0.4.0: - dependencies: - prelude-ls: 1.2.1 - - type-is@2.0.1: - dependencies: - content-type: 1.0.5 - media-typer: 1.1.0 - mime-types: 3.0.1 - - typescript@5.9.3: {} - - undici-types@7.16.0: {} - - undici@7.14.0: {} - - unenv@2.0.0-rc.24: - dependencies: - pathe: 2.0.3 - - unpipe@1.0.0: {} - - uri-js@4.4.1: - dependencies: - punycode: 2.3.1 - - util-deprecate@1.0.2: {} - - vary@1.1.2: {} - - which@2.0.2: - dependencies: - isexe: 2.0.0 - - word-wrap@1.2.5: {} - - workerd@1.20251109.0: - optionalDependencies: - '@cloudflare/workerd-darwin-64': 1.20251109.0 - '@cloudflare/workerd-darwin-arm64': 1.20251109.0 - '@cloudflare/workerd-linux-64': 1.20251109.0 - '@cloudflare/workerd-linux-arm64': 1.20251109.0 - '@cloudflare/workerd-windows-64': 1.20251109.0 - - wrangler@4.47.0(@cloudflare/workers-types@4.20251111.0): - dependencies: - '@cloudflare/kv-asset-handler': 0.4.0 - '@cloudflare/unenv-preset': 2.7.10(unenv@2.0.0-rc.24)(workerd@1.20251109.0) - blake3-wasm: 2.1.5 - esbuild: 0.25.4 - miniflare: 4.20251109.0 - path-to-regexp: 6.3.0 - unenv: 2.0.0-rc.24 - workerd: 1.20251109.0 - optionalDependencies: - '@cloudflare/workers-types': 4.20251111.0 - fsevents: 2.3.3 - transitivePeerDependencies: - - bufferutil - - utf-8-validate - - wrappy@1.0.2: {} - - ws@8.18.0: {} - - yocto-queue@0.1.0: {} - - youch-core@0.3.3: - dependencies: - '@poppinss/exception': 1.2.2 - error-stack-parser-es: 1.0.5 - - youch@4.1.0-beta.10: - dependencies: - '@poppinss/colors': 4.1.5 - '@poppinss/dumper': 0.6.5 - '@speed-highlight/core': 1.2.12 - cookie: 1.0.2 - youch-core: 0.3.3 - - zod@3.22.3: {} - - zod@4.1.12: {} diff --git a/packages/api/src/auth/better-auth.ts b/packages/api/src/auth/better-auth.ts index d0227bce..4cf80a7e 100644 --- a/packages/api/src/auth/better-auth.ts +++ b/packages/api/src/auth/better-auth.ts @@ -19,7 +19,7 @@ import { } from "@/services/email"; import { logSecurityEvent } from "@/auth/security"; import { getGlobalSettings } from "@/services/global-settings"; -import { getClientIp, getUserAgent } from "@/auth/security"; +import { getClientIp, getUserAgent, extractHeaders } from "@/auth/security"; import { eq } from "drizzle-orm"; import * as schema from "@/db/schema"; import type { Env } from "@/types"; @@ -151,6 +151,18 @@ export function createAuth(env: Env, db?: ReturnType) { }, }, async (span) => { + // Add breadcrumb for email sending attempt + await Sentry.addBreadcrumb({ + category: "email", + message: "Sending password reset email", + level: "info", + data: { + userEmail: user.email, + userId: user.id, + emailType: "password_reset", + }, + }); + const userWithPlugins = user as BetterAuthUser; const emailResult = await sendPasswordResetEmail(env, { to: user.email, @@ -170,6 +182,31 @@ export function createAuth(env: Env, db?: ReturnType) { "email.error", emailResult.error || "Unknown error" ); + + // Add breadcrumb for failure + await Sentry.addBreadcrumb({ + category: "email", + message: "Password reset email failed", + level: "error", + data: { + userEmail: user.email, + userId: user.id, + error: emailResult.error, + emailType: "password_reset", + }, + }); + } else { + // Add breadcrumb for success + await Sentry.addBreadcrumb({ + category: "email", + message: "Password reset email sent successfully", + level: "info", + data: { + userEmail: user.email, + userId: user.id, + emailType: "password_reset", + }, + }); } // Log email result to security audit log @@ -311,42 +348,175 @@ export function createAuth(env: Env, db?: ReturnType) { // This ensures proper logo loading and post-verification redirect const frontendVerificationUrl = `${frontendUrl}/verify-email?token=${token}`; - // Send verification email (fire-and-forget) - sendVerificationEmail(env, { - to: user.email, - username: - (userWithPlugins.username as string | undefined) || - user.name || - "User", - verificationToken: token, - verificationUrl: frontendVerificationUrl, // Frontend URL instead of backend URL - }).catch((error) => { - // Log critical email failures to Sentry - Sentry.captureException(error, { - tags: { - component: "better-auth", - operation: "email-verification", - email_type: "verification", + // Send verification email (fire-and-forget with Sentry tracking) + // Wrap in Sentry span for monitoring even though we don't await + Sentry.startSpan( + { + op: "email.verification", + name: "Send Verification Email (Fire-and-Forget)", + attributes: { + user_id: user.id, + user_email: user.email, + fire_and_forget: true, }, - extra: { - userEmail: user.email, - userId: user.id, - }, - level: "error", - }); + }, + async (span) => { + // Add breadcrumb for email sending attempt + await Sentry.addBreadcrumb({ + category: "email", + message: "Sending verification email", + level: "info", + data: { + userEmail: user.email, + userId: user.id, + emailType: "verification", + }, + }); - console.error("Failed to send verification email:", { - userEmail: user.email, - userId: user.id, - error: error instanceof Error ? error.message : String(error), - }); - }); + sendVerificationEmail(env, { + to: user.email, + username: + (userWithPlugins.username as string | undefined) || + user.name || + "User", + verificationToken: token, + verificationUrl: frontendVerificationUrl, // Frontend URL instead of backend URL + }) + .then(async (emailResult) => { + // Track result in span + span?.setAttribute("email.success", emailResult.success); + + // Check if email sending failed + if (!emailResult.success) { + span?.setAttribute( + "email.error", + emailResult.error || "Unknown error" + ); + span?.setStatus({ code: 2, message: "email failed" }); + + // Add breadcrumb for failure + await Sentry.addBreadcrumb({ + category: "email", + message: "Verification email failed", + level: "error", + data: { + userEmail: user.email, + userId: user.id, + error: emailResult.error, + emailType: "verification", + }, + }); + + // Log critical email failures to Sentry + await Sentry.captureException( + new Error( + emailResult.error || + "Failed to send verification email" + ), + { + tags: { + component: "better-auth", + operation: "email-verification", + email_type: "verification", + }, + extra: { + userEmail: user.email, + userId: user.id, + errorMessage: emailResult.error, + }, + level: "error", + } + ); + + console.error("Failed to send verification email:", { + userEmail: user.email, + userId: user.id, + error: emailResult.error, + }); + } else { + span?.setStatus({ code: 1, message: "ok" }); + + // Add breadcrumb for success + await Sentry.addBreadcrumb({ + category: "email", + message: "Verification email sent successfully", + level: "info", + data: { + userEmail: user.email, + userId: user.id, + emailType: "verification", + }, + }); + } + }) + .catch(async (error) => { + span?.setAttribute( + "email.exception", + error instanceof Error ? error.message : String(error) + ); + span?.setStatus({ code: 2, message: "exception" }); + + // Add breadcrumb for unexpected error + await Sentry.addBreadcrumb({ + category: "email", + message: "Unexpected error sending verification email", + level: "error", + data: { + userEmail: user.email, + userId: user.id, + error: + error instanceof Error + ? error.message + : String(error), + emailType: "verification", + }, + }); + + // Log unexpected exceptions (e.g., network errors, timeouts) + await Sentry.captureException(error, { + tags: { + component: "better-auth", + operation: "email-verification", + email_type: "verification", + }, + extra: { + userEmail: user.email, + userId: user.id, + }, + level: "error", + }); + + console.error( + "Unexpected error sending verification email:", + { + userEmail: user.email, + userId: user.id, + error: + error instanceof Error + ? error.message + : String(error), + } + ); + }); + } + ); }) - .catch((error) => { + .catch(async (error) => { console.error( "Failed to check email verification settings:", error ); + await Sentry.captureException(error, { + tags: { + component: "better-auth", + operation: "check-verification-settings", + }, + extra: { + userId: user.id, + userEmail: user.email, + }, + level: "warning", + }); }); // Return immediately without awaiting @@ -391,20 +561,6 @@ export function createAuth(env: Env, db?: ReturnType) { if (newSession?.user) { const user = newSession.user; - // Get IP and user agent from headers - const headers: Record = {}; - if (ctx.headers) { - if (ctx.headers instanceof Headers) { - ctx.headers.forEach((value, key) => { - headers[key.toLowerCase()] = value; - }); - } else { - Object.entries(ctx.headers).forEach(([key, value]) => { - headers[key.toLowerCase()] = String(value); - }); - } - } - // Note: Registration event logging is handled in the register endpoint // after the user is created in the user table, to avoid foreign key constraint issues @@ -424,142 +580,223 @@ export function createAuth(env: Env, db?: ReturnType) { const appUrl = frontendUrl; const userWithPlugins = user as BetterAuthUser; - // Send welcome email (fire-and-forget) - sendWelcomeEmail(env, { - to: user.email, - username: - (userWithPlugins.username as string | undefined) || - user.name || - "User", - appUrl, - }).catch((error) => { - // Log email failures to Sentry - Sentry.captureException(error, { - tags: { - component: "better-auth", - operation: "welcome-email", - email_type: "welcome", + // Send welcome email (fire-and-forget with Sentry tracking) + Sentry.startSpan( + { + op: "email.welcome", + name: "Send Welcome Email (Fire-and-Forget)", + attributes: { + user_id: user.id, + user_email: user.email, + fire_and_forget: true, }, - extra: { - userEmail: user.email, - userId: user.id, - }, - level: "error", - }); - - console.error( - `Failed to send welcome email to ${user.email}:`, - { - error: - error instanceof Error - ? error.message - : String(error), - } - ); - }); + }, + async (span) => { + // Add breadcrumb for email sending attempt + await Sentry.addBreadcrumb({ + category: "email", + message: "Sending welcome email", + level: "info", + data: { + userEmail: user.email, + userId: user.id, + emailType: "welcome", + }, + }); + + sendWelcomeEmail(env, { + to: user.email, + username: + (userWithPlugins.username as string | undefined) || + user.name || + "User", + appUrl, + }) + .then(async (emailResult) => { + // Track result in span + span?.setAttribute( + "email.success", + emailResult.success + ); + + // Check if email sending failed + if (!emailResult.success) { + span?.setAttribute( + "email.error", + emailResult.error || "Unknown error" + ); + span?.setStatus({ + code: 2, + message: "email failed", + }); + + // Add breadcrumb for failure + await Sentry.addBreadcrumb({ + category: "email", + message: "Welcome email failed", + level: "error", + data: { + userEmail: user.email, + userId: user.id, + error: emailResult.error, + emailType: "welcome", + }, + }); + + // Log email failures to Sentry + await Sentry.captureException( + new Error( + emailResult.error || + "Failed to send welcome email" + ), + { + tags: { + component: "better-auth", + operation: "welcome-email", + email_type: "welcome", + }, + extra: { + userEmail: user.email, + userId: user.id, + errorMessage: emailResult.error, + }, + level: "error", + } + ); + + console.error( + `Failed to send welcome email to ${user.email}:`, + { + error: emailResult.error, + } + ); + } else { + span?.setStatus({ code: 1, message: "ok" }); + + // Add breadcrumb for success + await Sentry.addBreadcrumb({ + category: "email", + message: "Welcome email sent successfully", + level: "info", + data: { + userEmail: user.email, + userId: user.id, + emailType: "welcome", + }, + }); + } + }) + .catch(async (error) => { + span?.setAttribute( + "email.exception", + error instanceof Error + ? error.message + : String(error) + ); + span?.setStatus({ code: 2, message: "exception" }); + + // Add breadcrumb for unexpected error + await Sentry.addBreadcrumb({ + category: "email", + message: "Unexpected error sending welcome email", + level: "error", + data: { + userEmail: user.email, + userId: user.id, + error: + error instanceof Error + ? error.message + : String(error), + emailType: "welcome", + }, + }); + + // Log unexpected exceptions (e.g., network errors, timeouts) + await Sentry.captureException(error, { + tags: { + component: "better-auth", + operation: "welcome-email", + email_type: "welcome", + }, + extra: { + userEmail: user.email, + userId: user.id, + }, + level: "error", + }); + + console.error( + `Unexpected error sending welcome email to ${user.email}:`, + { + error: + error instanceof Error + ? error.message + : String(error), + } + ); + }); + } + ); } }) - .catch((error) => { + .catch(async (error) => { console.error( `Error checking welcome email requirements:`, error ); + await Sentry.captureException(error, { + tags: { + component: "better-auth", + operation: "check-welcome-settings", + }, + extra: { + userId: user.id, + userEmail: user.email, + }, + level: "warning", + }); }); } } // Handle sign-in events - if (ctx.path.startsWith("/sign-in")) { + // Note: Login audit logging is handled in auth.ts router for consistency with signup flow + // and to have access to more request context + + // Handle sign-out events + if (ctx.path.startsWith("/sign-out")) { const session = ctx.context.session; if (session?.user) { const user = session.user; // Get IP and user agent from headers - const headers: Record = {}; - if (ctx.headers) { - if (ctx.headers instanceof Headers) { - ctx.headers.forEach((value, key) => { - headers[key.toLowerCase()] = value; - }); - } else { - Object.entries(ctx.headers).forEach(([key, value]) => { - headers[key.toLowerCase()] = String(value); - }); - } - } - + const headers = extractHeaders(ctx.headers); const ipAddress = getClientIp(headers); const userAgent = getUserAgent(headers); - // Log successful login (non-blocking - don't fail login if logging fails) + // Log logout event (non-blocking - don't fail logout if logging fails) try { await logSecurityEvent(database, { userId: Number(user.id), - action: "login_success", + action: "logout", ipAddress, userAgent, success: true, }); } catch (error) { console.error( - `Failed to log login event for user ${user.id}:`, + `Failed to log logout event for user ${user.id}:`, error instanceof Error ? error.message : "Unknown error" ); - // Don't throw - logging failures shouldn't prevent login - } - } - } - - // Handle sign-out events - if (ctx.path.startsWith("/sign-out")) { - const session = ctx.context.session; - if (session?.user) { - const user = session.user; - - // Get IP and user agent from headers - const headers: Record = {}; - if (ctx.headers) { - if (ctx.headers instanceof Headers) { - ctx.headers.forEach((value, key) => { - headers[key.toLowerCase()] = value; - }); - } else { - Object.entries(ctx.headers).forEach(([key, value]) => { - headers[key.toLowerCase()] = String(value); - }); - } + // Don't throw - logging failures shouldn't prevent logout } - - const ipAddress = getClientIp(headers); - const userAgent = getUserAgent(headers); - - // Log logout event - await logSecurityEvent(database, { - userId: Number(user.id), - action: "logout", - ipAddress, - userAgent, - success: true, - }); } } // Handle password reset request events if (ctx.path.startsWith("/request-password-reset")) { // Get IP and user agent from headers - const headers: Record = {}; - if (ctx.headers) { - if (ctx.headers instanceof Headers) { - ctx.headers.forEach((value, key) => { - headers[key.toLowerCase()] = value; - }); - } else { - Object.entries(ctx.headers).forEach(([key, value]) => { - headers[key.toLowerCase()] = String(value); - }); - } - } - + const headers = extractHeaders(ctx.headers); const ipAddress = getClientIp(headers); const userAgent = getUserAgent(headers); @@ -576,6 +813,7 @@ export function createAuth(env: Env, db?: ReturnType) { if (userRecord) { // Log password reset request + // Note: Email sent status is logged in sendResetPassword callback with actual result await logSecurityEvent(database, { userId: Number(userRecord.id), action: "password_reset_request", @@ -583,17 +821,6 @@ export function createAuth(env: Env, db?: ReturnType) { userAgent, success: true, }); - - // Log password reset email sent (if email was sent successfully) - // Note: We can't determine email success here, so we'll log it as success - // The actual email result is handled in sendResetPassword callback - await logSecurityEvent(database, { - userId: Number(userRecord.id), - action: "password_reset_email_sent", - ipAddress, - userAgent, - success: true, - }); } } } catch (error) { diff --git a/packages/api/src/auth/security.ts b/packages/api/src/auth/security.ts index 01d9eb64..9f17b175 100644 --- a/packages/api/src/auth/security.ts +++ b/packages/api/src/auth/security.ts @@ -19,6 +19,7 @@ export type SecurityAction = | "password_reset_request" | "password_reset_email_sent" | "password_reset_success" + | "password_reset_failed" | "account_locked" | "account_unlocked" | "token_expired" @@ -49,6 +50,7 @@ export async function logSecurityEvent( userAgent: params.userAgent, metadata: params.metadata ? JSON.stringify(params.metadata) : undefined, success: params.success, + // createdAt uses SQL DEFAULT from schema }); } catch (error) { // Log but don't throw - audit logging shouldn't break the app @@ -88,3 +90,58 @@ export function getUserAgent( ): string | undefined { return headers["user-agent"]; } + +/** + * Extract request metadata for security audit logging + * Convenience function that combines header extraction, IP, and user agent + */ +export function getRequestMetadata( + reqHeaders: + | Headers + | Record + | undefined +): { + headers: Record; + ipAddress: string | undefined; + userAgent: string | undefined; +} { + const headers = extractHeaders(reqHeaders); + const ipAddress = getClientIp(headers); + const userAgent = getUserAgent(headers); + + return { headers, ipAddress, userAgent }; +} + +/** + * Extract headers from request into a normalized Record + * Handles both Headers object and plain object formats + */ +export function extractHeaders( + reqHeaders: + | Headers + | Record + | undefined +): Record { + const headers: Record = {}; + + if (!reqHeaders) { + return headers; + } + + if (reqHeaders instanceof Headers) { + reqHeaders.forEach((value, key) => { + headers[key.toLowerCase()] = value; + }); + } else { + Object.entries(reqHeaders).forEach(([key, value]) => { + headers[key.toLowerCase()] = + value === undefined + ? undefined + : Array.isArray(value) + ? value[0] + : String(value); + }); + } + + return headers; +} diff --git a/packages/api/src/db/migrate-local.ts b/packages/api/src/db/migrate-local.ts index 1bb5ee47..7c44d15d 100644 --- a/packages/api/src/db/migrate-local.ts +++ b/packages/api/src/db/migrate-local.ts @@ -87,7 +87,14 @@ export async function runMigrationsIfNeeded( } // CLI entry point - run migrations if this file is executed directly -if (import.meta.url === `file://${process.argv[1]}`) { +// Note: This check is disabled when bundled to prevent double-execution +const isMainModule = + typeof process !== "undefined" && + import.meta.url === `file://${process.argv[1]}` && + // Additional check: only run if not bundled (dist/entries would indicate bundled) + !process.argv[1]?.includes("dist/entries"); + +if (isMainModule) { runMigrationsIfNeeded() .then(() => { process.exit(0); diff --git a/packages/api/src/db/schema.ts b/packages/api/src/db/schema.ts index 24d3dbf1..3c28273a 100644 --- a/packages/api/src/db/schema.ts +++ b/packages/api/src/db/schema.ts @@ -458,7 +458,7 @@ export const securityAuditLog = sqliteTable( success: integer("success", { mode: "boolean" }).notNull(), createdAt: integer("created_at", { mode: "timestamp" }) .notNull() - .$defaultFn(() => new Date()), + .default(sql`(cast(unixepoch('subsecond') * 1000 as integer))`), }, (table) => [ index("idx_security_audit_log_user_id").on(table.userId), diff --git a/packages/api/src/routers/admin.ts b/packages/api/src/routers/admin.ts index 101efb68..4aede417 100644 --- a/packages/api/src/routers/admin.ts +++ b/packages/api/src/routers/admin.ts @@ -46,6 +46,7 @@ const AdminUserSchema = z.object({ id: z.number(), username: z.string(), email: z.string(), + emailVerified: z.boolean(), role: z.enum(["user", "admin"]), plan: z.string(), // Plan ID - validated against plans table banned: z.boolean(), @@ -88,6 +89,7 @@ export const adminRouter = router({ role: z.enum(["user", "admin"]).optional(), plan: z.string().optional(), // Plan ID filter - validated at runtime banned: z.boolean().optional(), + emailVerified: z.boolean().optional(), // Filter by email verification status search: z.string().optional(), // Search by username or email }) ) @@ -104,6 +106,9 @@ export const adminRouter = router({ if (input.banned !== undefined) { conditions.push(eq(schema.user.banned, input.banned)); } + if (input.emailVerified !== undefined) { + conditions.push(eq(schema.user.emailVerified, input.emailVerified)); + } if (input.search) { conditions.push( sql`(LOWER(COALESCE(${schema.user.username}, ${schema.user.name})) LIKE LOWER(${`%${input.search}%`}) OR LOWER(${schema.user.email}) LIKE LOWER(${`%${input.search}%`}))` @@ -127,6 +132,7 @@ export const adminRouter = router({ "db.has_role_filter": input.role !== undefined, "db.has_plan_filter": input.plan !== undefined, "db.has_banned_filter": input.banned !== undefined, + "db.has_email_verified_filter": input.emailVerified !== undefined, "db.has_search": !!input.search, } ); @@ -169,6 +175,7 @@ export const adminRouter = router({ id: user.id, username: user.username || user.name, email: user.email, + emailVerified: user.emailVerified || false, role: (user.role as "user" | "admin") || "user", plan: user.plan || "free", banned: user.banned || false, @@ -263,6 +270,7 @@ export const adminRouter = router({ id: user.id, username: user.username || user.name, email: user.email, + emailVerified: user.emailVerified || false, role: (user.role as "user" | "admin") || "user", plan: user.plan || "free", banned: user.banned || false, diff --git a/packages/api/src/routers/articles.ts b/packages/api/src/routers/articles.ts index f9e7598e..6cf9278c 100644 --- a/packages/api/src/routers/articles.ts +++ b/packages/api/src/routers/articles.ts @@ -18,11 +18,11 @@ import { applyCategoryFilter, buildArticlesWhereConditions, } from "./articles-helpers"; -import { D1_MAX_PARAMETERS, chunkArray } from "@/db/utils"; import * as schema from "@/db/schema"; -import { executeBatch } from "@/db/utils"; -import { withQueryMetrics } from "@/utils/db-metrics"; +import { D1_MAX_PARAMETERS, chunkArray, executeBatch } from "@/db/utils"; import { upsertArticleState } from "@/db/helpers"; +import { withQueryMetrics } from "@/utils/db-metrics"; +import * as Sentry from "@/utils/sentry"; /** * Helper function to transform database row to article output @@ -812,7 +812,38 @@ export const articlesRouter = router({ }) ); - await executeBatch(ctx.db, statements); + // Wrap batch execution in Sentry span for monitoring + await Sentry.startSpan( + { + op: "db.batch", + name: "Mark Articles Read/Unread", + attributes: { + "db.batch_size": statements.length, + "db.operation": input.read ? "mark_read" : "mark_unread", + "db.user_id": userId, + }, + }, + async (span) => { + try { + await executeBatch(ctx.db, statements); + span.setStatus({ code: 1, message: "ok" }); + } catch (error) { + span.setStatus({ code: 2, message: "batch failed" }); + await Sentry.captureException(error, { + tags: { + operation: "mark_articles_read", + batch_size: statements.length.toString(), + }, + extra: { + userId, + articleCount: input.articleIds.length, + read: input.read, + }, + }); + throw error; + } + } + ); return { updated: input.articleIds.length }; }), @@ -914,7 +945,39 @@ export const articlesRouter = router({ }) ); - await executeBatch(ctx.db, statements); + // Wrap batch execution in Sentry span for monitoring + await Sentry.startSpan( + { + op: "db.batch", + name: "Mark All Articles Read", + attributes: { + "db.batch_size": statements.length, + "db.operation": "mark_all_read", + "db.user_id": userId, + "filter.older_than_days": input.olderThanDays ?? "none", + }, + }, + async (span) => { + try { + await executeBatch(ctx.db, statements); + span.setStatus({ code: 1, message: "ok" }); + } catch (error) { + span.setStatus({ code: 2, message: "batch failed" }); + await Sentry.captureException(error, { + tags: { + operation: "mark_all_read", + batch_size: statements.length.toString(), + }, + extra: { + userId, + articleCount: articleIds.length, + olderThanDays: input.olderThanDays, + }, + }); + throw error; + } + } + ); return { updated: articleIds.length }; }), diff --git a/packages/api/src/routers/auth.ts b/packages/api/src/routers/auth.ts index 2e246378..2729cb4c 100644 --- a/packages/api/src/routers/auth.ts +++ b/packages/api/src/routers/auth.ts @@ -32,6 +32,12 @@ import { import { getBaseUrl } from "@/utils/base-url"; import * as Sentry from "@/utils/sentry"; import { emitCounter, emitMetrics } from "@/utils/metrics"; +import { + logSecurityEvent, + getClientIp, + getUserAgent, + getRequestMetadata, +} from "@/auth/security"; import type { BetterAuthUser, SignUpEmailResult, @@ -267,9 +273,6 @@ export const authRouter = router({ op: "db.insert", }, async (span) => { - const { logSecurityEvent, getClientIp, getUserAgent } = - await import("@/auth/security"); - // Extract IP and user agent from request headers const headers: Record = {}; if (ctx.req.headers) { @@ -421,78 +424,247 @@ export const authRouter = router({ }) ) .mutation(async ({ ctx, input }) => { - const auth = createAuth(ctx.env, ctx.db); - - // Convert headers for Better Auth - const authHeaders = - ctx.req.headers instanceof Headers - ? ctx.req.headers - : fromNodeHeaders( - Object.fromEntries( - Object.entries(ctx.req.headers || {}).map(([k, v]) => [ - k, - Array.isArray(v) ? v[0] : v, - ]) - ) as Record - ); - - try { - // Use Better Auth's signIn with username plugin - // Note: Username plugin adds signInUsername method - const result: SignInUsernameResult = await auth.api.signInUsername({ - body: { - username: input.username, - password: input.password, + // Wrap entire login in Sentry span + return Sentry.startSpan( + { + name: "auth.login", + op: "auth.signin", + attributes: { + "auth.method": "username_password", + "auth.username": input.username, }, - headers: authHeaders, - }); + }, + async (parentSpan) => { + const startTime = Date.now(); + let userId: number | undefined; - if (!result || !result.user) { - throw new TRPCError({ - code: "UNAUTHORIZED", - message: "Invalid credentials", + // Add breadcrumb for login attempt + await Sentry.addBreadcrumb({ + category: "auth", + message: "Login attempt", + level: "info", + data: { + username: input.username, + method: "username_password", + }, }); - } - const resultUser = result.user as Partial; + const auth = createAuth(ctx.env, ctx.db); + + // Convert headers for Better Auth + const authHeaders = + ctx.req.headers instanceof Headers + ? ctx.req.headers + : fromNodeHeaders( + Object.fromEntries( + Object.entries(ctx.req.headers || {}).map(([k, v]) => [ + k, + Array.isArray(v) ? v[0] : v, + ]) + ) as Record + ); - // Get user from Better Auth user table for role/plan info - const [dbUser] = await ctx.db - .select() - .from(schema.user) - .where(eq(schema.user.id, Number(result.user.id))) - .limit(1); + try { + // Use Better Auth's signIn with username plugin + // Note: Username plugin adds signInUsername method + const result: SignInUsernameResult = await auth.api.signInUsername({ + body: { + username: input.username, + password: input.password, + }, + headers: authHeaders, + }); - if (!dbUser) { - throw new TRPCError({ - code: "UNAUTHORIZED", - message: "User not found", - }); - } + if (!result || !result.user) { + throw new TRPCError({ + code: "UNAUTHORIZED", + message: "Invalid credentials", + }); + } - // Return user info (session is handled by Better Auth via cookies) - return { - user: { - id: Number(result.user.id), - username: - (resultUser.username as string | undefined) || - result.user.name || - "", - email: result.user.email, - role: (dbUser.role as "user" | "admin") || "user", - plan: dbUser.plan || DEFAULT_USER_PLAN, - banned: dbUser.banned || false, - }, - }; - } catch (error) { - // Better Auth errors are already logged - const authError = error as { status?: number; message?: string }; - throw new TRPCError({ - code: - authError.status === 401 ? "UNAUTHORIZED" : "INTERNAL_SERVER_ERROR", - message: authError.message || "Login failed", - }); - } + userId = Number(result.user.id); + const resultUser = result.user as Partial; + + // Get user from Better Auth user table for role/plan info + const [dbUser] = await ctx.db + .select() + .from(schema.user) + .where(eq(schema.user.id, userId)) + .limit(1); + + if (!dbUser) { + throw new TRPCError({ + code: "UNAUTHORIZED", + message: "User not found", + }); + } + + // Log successful login to security audit + const { + ipAddress, + userAgent, + }: { + ipAddress: string | undefined; + userAgent: string | undefined; + } = getRequestMetadata(ctx.req.headers); + + try { + await logSecurityEvent(ctx.db, { + userId, + action: "login_success", + ipAddress, + userAgent, + success: true, + }); + } catch (auditError) { + // Don't fail login if audit logging fails + console.error("Failed to log login event:", auditError); + await Sentry.captureException(auditError, { + tags: { + flow: "login", + step: "audit_log", + }, + level: "warning", + }); + } + + // Add success breadcrumb + await Sentry.addBreadcrumb({ + category: "auth", + message: "Login successful", + level: "info", + data: { + userId: userId.toString(), + username: input.username, + role: dbUser.role, + }, + }); + + const totalDuration = Date.now() - startTime; + + // Set success attributes on span + parentSpan?.setAttributes({ + "auth.login_success": true, + "auth.user_id": userId.toString(), + "auth.role": dbUser.role || "user", + "auth.duration_ms": totalDuration, + }); + + // Emit metrics + emitMetrics([ + { + type: "counter", + name: "auth.login_success", + value: 1, + attributes: { + role: dbUser.role || "user", + }, + }, + { + type: "distribution", + name: "auth.login_duration", + value: totalDuration, + unit: "millisecond", + }, + ]); + + // Return user info (session is handled by Better Auth via cookies) + return { + user: { + id: userId, + username: + (resultUser.username as string | undefined) || + result.user.name || + "", + email: result.user.email, + role: (dbUser.role as "user" | "admin") || "user", + plan: dbUser.plan || DEFAULT_USER_PLAN, + banned: dbUser.banned || false, + }, + }; + } catch (error) { + const totalDuration = Date.now() - startTime; + + // Add failure breadcrumb + await Sentry.addBreadcrumb({ + category: "auth", + message: "Login failed", + level: "error", + data: { + username: input.username, + error: (error as Error).message, + errorType: (error as Error).constructor.name, + }, + }); + + // Log failed login attempt to security audit (if not a generic auth error) + const { + ipAddress, + userAgent, + }: { + ipAddress: string | undefined; + userAgent: string | undefined; + } = getRequestMetadata(ctx.req.headers); + + try { + await logSecurityEvent(ctx.db, { + userId, + action: "login_failed", + ipAddress, + userAgent, + success: false, + metadata: { + username: input.username, + error: (error as Error).message, + }, + }); + } catch (auditError) { + // Don't fail login if audit logging fails + console.error("Failed to log failed login event:", auditError); + } + + // Set error attributes on span + parentSpan?.setAttributes({ + "auth.login_success": false, + "auth.error": (error as Error).message, + "auth.error_code": (error as TRPCError).code || "unknown", + "auth.duration_ms": totalDuration, + }); + + // Capture in Sentry + await Sentry.captureException(error, { + tags: { + flow: "login", + step: "overall", + }, + contexts: { + login: { + username: input.username, + user_id: userId?.toString(), + duration_ms: totalDuration, + }, + }, + user: userId ? { id: userId.toString() } : undefined, + }); + + // Emit failure metrics + emitCounter("auth.login_failed", 1, { + error_code: (error as TRPCError).code || "unknown", + error_type: (error as Error).constructor.name, + }); + + // Better Auth errors are already logged + const authError = error as { status?: number; message?: string }; + throw new TRPCError({ + code: + authError.status === 401 + ? "UNAUTHORIZED" + : "INTERNAL_SERVER_ERROR", + message: authError.message || "Login failed", + }); + } + } + ); }), /** @@ -703,6 +875,15 @@ export const authRouter = router({ ) as Record ); + // Extract IP and user agent for audit logging + const { + ipAddress, + userAgent, + }: { + ipAddress: string | undefined; + userAgent: string | undefined; + } = getRequestMetadata(ctx.req.headers); + try { await auth.api.changePassword({ body: { @@ -712,8 +893,48 @@ export const authRouter = router({ headers: authHeaders, }); + // Log successful password change + try { + await logSecurityEvent(ctx.db, { + userId: ctx.user.userId, + action: "password_change", + ipAddress, + userAgent, + success: true, + }); + } catch (auditError) { + // Don't fail password change if audit logging fails + console.error("Failed to log password change event:", auditError); + await Sentry.captureException(auditError, { + tags: { + flow: "password_change", + step: "audit_log", + }, + level: "warning", + }); + } + return { success: true }; } catch (error) { + // Log failed password change attempt + try { + await logSecurityEvent(ctx.db, { + userId: ctx.user.userId, + action: "password_change", + ipAddress, + userAgent, + success: false, + metadata: { + error: (error as Error).message, + }, + }); + } catch (auditError) { + console.error( + "Failed to log failed password change event:", + auditError + ); + } + const authError = error as { status?: number; message?: string }; throw new TRPCError({ code: @@ -742,9 +963,6 @@ export const authRouter = router({ ) .mutation(async ({ ctx, input }) => { const auth = createAuth(ctx.env, ctx.db); - const { logSecurityEvent, getClientIp, getUserAgent } = await import( - "@/auth/security" - ); // Convert headers for Better Auth const authHeaders = @@ -850,6 +1068,41 @@ export const authRouter = router({ ) as Record ); + // Extract IP and user agent for audit logging + const { + ipAddress, + userAgent, + }: { + ipAddress: string | undefined; + userAgent: string | undefined; + } = getRequestMetadata(ctx.req.headers); + + // Find user by verification token BEFORE resetting (token is deleted after use) + let userId: number | undefined; + try { + const [verification] = await ctx.db + .select() + .from(schema.verification) + .where(eq(schema.verification.value, input.token)) + .limit(1); + + if (verification) { + // identifier is the user's email + const [userRecord] = await ctx.db + .select() + .from(schema.user) + .where(eq(schema.user.email, verification.identifier)) + .limit(1); + + if (userRecord) { + userId = Number(userRecord.id); + } + } + } catch (error) { + // Continue even if we can't find the user + console.error("Failed to find user for password reset logging:", error); + } + try { await auth.api.resetPassword({ body: { @@ -859,8 +1112,49 @@ export const authRouter = router({ headers: authHeaders, }); + // Log successful password reset with actual user ID + try { + await logSecurityEvent(ctx.db, { + userId, + action: "password_reset_success", + ipAddress, + userAgent, + success: true, + }); + } catch (auditError) { + // Don't fail password reset if audit logging fails + console.error("Failed to log password reset event:", auditError); + await Sentry.captureException(auditError, { + tags: { + flow: "password_reset", + step: "audit_log", + }, + level: "warning", + }); + } + return { success: true }; } catch (error) { + // Log failed password reset attempt + try { + await logSecurityEvent(ctx.db, { + userId, + action: "password_reset_failed", + ipAddress, + userAgent, + success: false, + metadata: { + error: (error as Error).message, + note: "Invalid or expired token", + }, + }); + } catch (auditError) { + console.error( + "Failed to log failed password reset event:", + auditError + ); + } + const authError = error as { status?: number; message?: string }; throw new TRPCError({ code: diff --git a/packages/api/src/routers/subscriptions.ts b/packages/api/src/routers/subscriptions.ts index eebff322..1f43c574 100644 --- a/packages/api/src/routers/subscriptions.ts +++ b/packages/api/src/routers/subscriptions.ts @@ -5,6 +5,11 @@ */ import * as Sentry from "@/utils/sentry"; + +// Retry configuration for transient HTTP failures +const MAX_RETRIES = 2; +const RETRY_DELAY_MS = 1000; +const TRANSIENT_STATUS_CODES = [502, 503, 504, 429]; import { z } from "zod"; import { TRPCError } from "@trpc/server"; import { eq, and } from "drizzle-orm"; @@ -301,62 +306,182 @@ export const subscriptionsRouter = router({ let feedUrl = input.url; let feedData; let feedContent: string | undefined; + let lastError: Error | undefined; + let lastStatusCode: number | undefined; - try { - await Sentry.addBreadcrumb({ - category: "subscription", - message: `Fetching feed from ${feedUrl}`, - level: "info", - }); + for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) { + try { + if (attempt > 0) { + // Add delay between retries with exponential backoff + const delay = RETRY_DELAY_MS * Math.pow(2, attempt - 1); + await new Promise((resolve) => setTimeout(resolve, delay)); - const response = await fetch(feedUrl, { - headers: { - "User-Agent": "TuvixRSS/1.0", - Accept: - "application/rss+xml, application/atom+xml, application/xml, text/xml, */*", - }, - signal: AbortSignal.timeout(30000), - }); + await Sentry.addBreadcrumb({ + category: "subscription", + message: `Retrying feed fetch (attempt ${attempt + 1}/${MAX_RETRIES + 1})`, + level: "info", + data: { + attempt: attempt + 1, + delay_ms: delay, + }, + }); + } else { + await Sentry.addBreadcrumb({ + category: "subscription", + message: `Fetching feed from ${feedUrl}`, + level: "info", + }); + } - if (!response.ok) { - const errorMessage = `HTTP ${response.status}: ${response.statusText}`; - // Don't capture here - let the catch block handle it to avoid duplicates - throw new Error(errorMessage); - } + const response = await fetch(feedUrl, { + headers: { + "User-Agent": "TuvixRSS/1.0", + Accept: + "application/rss+xml, application/atom+xml, application/xml, text/xml, */*", + }, + signal: AbortSignal.timeout(30000), + }); - feedContent = await response.text(); - const result = parseFeed(feedContent); - feedData = result.feed; + lastStatusCode = response.status; - await Sentry.addBreadcrumb({ - category: "subscription", - message: `Successfully parsed feed as ${result.format}`, - level: "info", - data: { feed_format: result.format }, - }); - } catch (error) { - // Extract HTTP status if this is an HTTP error - const errorMessage = error instanceof Error ? error.message : "Unknown"; - const httpStatusMatch = errorMessage.match(/HTTP (\d+):/); - const httpStatus = httpStatusMatch ? httpStatusMatch[1] : undefined; + if (!response.ok) { + const errorMessage = `HTTP ${response.status}: ${response.statusText}`; + + // Check if this is a transient error that should be retried + if ( + TRANSIENT_STATUS_CODES.includes(response.status) && + attempt < MAX_RETRIES + ) { + continue; // Retry + } - await Sentry.captureException(error, { - level: "error", - tags: { - operation: "subscription_feed_parse", - domain: domain || "unknown", - ...(httpStatus && { http_status: httpStatus }), - }, - extra: { - url: input.url, - user_id: userId, - error_message: errorMessage, - }, - }); + // Non-transient error or max retries reached + throw new Error(errorMessage); + } + + feedContent = await response.text(); + + // Parse feed - parsing errors should NOT be retried + try { + const result = parseFeed(feedContent); + feedData = result.feed; + + await Sentry.addBreadcrumb({ + category: "subscription", + message: `Successfully parsed feed as ${result.format}`, + level: "info", + data: { + feed_format: result.format, + attempts: attempt + 1, + }, + }); + + // Success - break out of retry loop + break; + } catch (parseError) { + // Parse error - capture and throw immediately (don't retry) + const errorMessage = + parseError instanceof Error + ? parseError.message + : "Failed to parse feed"; + + await Sentry.captureException(parseError, { + level: "error", + tags: { + operation: "subscription_feed_parse", + domain: domain || "unknown", + error_type: "parse_error", + attempts: (attempt + 1).toString(), + }, + extra: { + url: input.url, + user_id: userId, + error_message: errorMessage, + fetch_status: lastStatusCode, + }, + }); + throw new TRPCError({ + code: "BAD_REQUEST", + message: `Failed to parse feed: ${errorMessage}`, + }); + } + } catch (error) { + // This catch block is only for FETCH errors now + // If it's a TRPCError (from parse error), rethrow immediately + if (error instanceof TRPCError) { + throw error; + } + + lastError = error instanceof Error ? error : new Error(String(error)); + + // If this is the last attempt or not a transient error, throw + if (attempt === MAX_RETRIES) { + // Extract HTTP status if this is an HTTP error + const errorMessage = lastError.message; + const httpStatusMatch = errorMessage.match(/HTTP (\d+):/); + const httpStatus = httpStatusMatch + ? httpStatusMatch[1] + : lastStatusCode?.toString(); + + await Sentry.captureException(lastError, { + level: "error", + tags: { + operation: "subscription_feed_parse", + domain: domain || "unknown", + ...(httpStatus && { http_status: httpStatus }), + attempts: (attempt + 1).toString(), + }, + extra: { + url: input.url, + user_id: userId, + error_message: errorMessage, + final_attempt: attempt + 1, + last_status_code: lastStatusCode, + }, + }); + + throw new TRPCError({ + code: "BAD_REQUEST", + message: `Failed to fetch or parse feed: ${errorMessage}`, + }); + } + + // Check if we should retry this error + const errorMessage = lastError.message; + const httpStatusMatch = errorMessage.match(/HTTP (\d+):/); + const httpStatus = httpStatusMatch ? parseInt(httpStatusMatch[1]) : 0; + + if (!TRANSIENT_STATUS_CODES.includes(httpStatus)) { + // Non-transient error - don't retry + await Sentry.captureException(lastError, { + level: "error", + tags: { + operation: "subscription_feed_parse", + domain: domain || "unknown", + http_status: httpStatus.toString(), + attempts: (attempt + 1).toString(), + }, + extra: { + url: input.url, + user_id: userId, + error_message: errorMessage, + }, + }); + + throw new TRPCError({ + code: "BAD_REQUEST", + message: `Failed to fetch or parse feed: ${errorMessage}`, + }); + } + } + } + + // If we get here, feedData should be defined from successful parse + if (!feedData) { throw new TRPCError({ - code: "BAD_REQUEST", - message: `Failed to fetch or parse feed: ${errorMessage}`, + code: "INTERNAL_SERVER_ERROR", + message: "Feed parsing failed unexpectedly", }); } @@ -869,55 +994,175 @@ export const subscriptionsRouter = router({ let feedData; let feedUrl = input.url; let feedContent: string | undefined; + let lastError: Error | undefined; + let lastStatusCode: number | undefined; - try { - const response = await fetch(feedUrl, { - headers: { - "User-Agent": "TuvixRSS/1.0", - Accept: - "application/rss+xml, application/atom+xml, application/xml, text/xml, */*", - }, - signal: AbortSignal.timeout(30000), - }); + for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) { + try { + if (attempt > 0) { + // Add delay between retries with exponential backoff + const delay = RETRY_DELAY_MS * Math.pow(2, attempt - 1); + await new Promise((resolve) => setTimeout(resolve, delay)); - if (!response.ok) { - const errorMessage = `HTTP ${response.status}: ${response.statusText}`; - // Don't capture here - let the catch block handle it to avoid duplicates - throw new Error(errorMessage); - } + await Sentry.addBreadcrumb({ + category: "subscription", + message: `Retrying feed preview (attempt ${attempt + 1}/${MAX_RETRIES + 1})`, + level: "info", + data: { + attempt: attempt + 1, + delay_ms: delay, + }, + }); + } - feedContent = await response.text(); - const result = parseFeed(feedContent); - feedData = result.feed; + const response = await fetch(feedUrl, { + headers: { + "User-Agent": "TuvixRSS/1.0", + Accept: + "application/rss+xml, application/atom+xml, application/xml, text/xml, */*", + }, + signal: AbortSignal.timeout(30000), + }); - await Sentry.addBreadcrumb({ - category: "subscription", - message: `Preview parsed feed as ${result.format}`, - level: "info", - data: { feed_format: result.format }, - }); - } catch (error) { - // Extract HTTP status if this is an HTTP error - const errorMessage = error instanceof Error ? error.message : "Unknown"; - const httpStatusMatch = errorMessage.match(/HTTP (\d+):/); - const httpStatus = httpStatusMatch ? httpStatusMatch[1] : undefined; + lastStatusCode = response.status; - await Sentry.captureException(error, { - level: "error", - tags: { - operation: "subscription_preview_parse", - domain: domain || "unknown", - ...(httpStatus && { http_status: httpStatus }), - }, - extra: { - url: input.url, - error_message: errorMessage, - }, - }); + if (!response.ok) { + const errorMessage = `HTTP ${response.status}: ${response.statusText}`; + + // Check if this is a transient error that should be retried + if ( + TRANSIENT_STATUS_CODES.includes(response.status) && + attempt < MAX_RETRIES + ) { + continue; // Retry + } + + // Non-transient error or max retries reached + throw new Error(errorMessage); + } + + feedContent = await response.text(); + + // Parse feed - parsing errors should NOT be retried + try { + const result = parseFeed(feedContent); + feedData = result.feed; + + await Sentry.addBreadcrumb({ + category: "subscription", + message: `Preview parsed feed as ${result.format}`, + level: "info", + data: { + feed_format: result.format, + attempts: attempt + 1, + }, + }); + + // Success - break out of retry loop + break; + } catch (parseError) { + // Parse error - capture and throw immediately (don't retry) + const errorMessage = + parseError instanceof Error + ? parseError.message + : "Failed to parse feed"; + + await Sentry.captureException(parseError, { + level: "error", + tags: { + operation: "subscription_preview_parse", + domain: domain || "unknown", + error_type: "parse_error", + attempts: (attempt + 1).toString(), + }, + extra: { + url: input.url, + error_message: errorMessage, + fetch_status: lastStatusCode, + }, + }); + + throw new TRPCError({ + code: "BAD_REQUEST", + message: `Failed to parse feed: ${errorMessage}`, + }); + } + } catch (error) { + // This catch block is only for FETCH errors now + // If it's a TRPCError (from parse error), rethrow immediately + if (error instanceof TRPCError) { + throw error; + } + + lastError = error instanceof Error ? error : new Error(String(error)); + + // If this is the last attempt, throw with full context + if (attempt === MAX_RETRIES) { + // Extract HTTP status if this is an HTTP error + const errorMessage = lastError.message; + const httpStatusMatch = errorMessage.match(/HTTP (\d+):/); + const httpStatus = httpStatusMatch + ? httpStatusMatch[1] + : lastStatusCode?.toString(); + + await Sentry.captureException(lastError, { + level: "error", + tags: { + operation: "subscription_preview_fetch", + domain: domain || "unknown", + ...(httpStatus && { http_status: httpStatus }), + attempts: (attempt + 1).toString(), + error_type: "fetch_error", + }, + extra: { + url: input.url, + error_message: errorMessage, + final_attempt: attempt + 1, + last_status_code: lastStatusCode, + }, + }); + + throw new TRPCError({ + code: "BAD_REQUEST", + message: `Failed to fetch feed: ${errorMessage}`, + }); + } + + // Check if we should retry this error + const errorMessage = lastError.message; + const httpStatusMatch = errorMessage.match(/HTTP (\d+):/); + const httpStatus = httpStatusMatch ? parseInt(httpStatusMatch[1]) : 0; + + if (!TRANSIENT_STATUS_CODES.includes(httpStatus)) { + // Non-transient error - don't retry + await Sentry.captureException(lastError, { + level: "error", + tags: { + operation: "subscription_preview_fetch", + domain: domain || "unknown", + http_status: httpStatus.toString(), + attempts: (attempt + 1).toString(), + error_type: "fetch_error", + }, + extra: { + url: input.url, + error_message: errorMessage, + }, + }); + + throw new TRPCError({ + code: "BAD_REQUEST", + message: `Failed to fetch feed: ${errorMessage}`, + }); + } + } + } + // If we get here, feedData should be defined from successful parse + if (!feedData) { throw new TRPCError({ - code: "BAD_REQUEST", - message: `Failed to fetch or parse feed: ${errorMessage}`, + code: "INTERNAL_SERVER_ERROR", + message: "Feed parsing failed unexpectedly", }); } @@ -1580,210 +1825,309 @@ export const subscriptionsRouter = router({ let errorCount = 0; const errors: { url: string; error: string }[] = []; - // Process each feed - for (const feedInfo of feedsToProcess) { - try { - // Fetch and validate feed - const response = await fetch(feedInfo.url, { - headers: { - "User-Agent": "TuvixRSS/1.0", - Accept: - "application/rss+xml, application/atom+xml, application/xml, text/xml, */*", - }, - signal: AbortSignal.timeout(15000), - }); - - if (!response.ok) { - throw new Error(`HTTP ${response.status}`); - } - - const feedContent = await response.text(); - const feedResult = parseFeed(feedContent); - const feedData = feedResult.feed; - - // Extract metadata - const feedTitle = - "title" in feedData && feedData.title - ? feedData.title - : feedInfo.title; - const feedDescription = - "description" in feedData && feedData.description - ? stripHtml(feedData.description) - : "subtitle" in feedData && feedData.subtitle - ? stripHtml(feedData.subtitle) - : undefined; - const siteUrl = - "link" in feedData && feedData.link - ? feedData.link - : "links" in feedData && - Array.isArray(feedData.links) && - feedData.links[0]?.href - ? feedData.links[0].href - : undefined; - - // Check if source exists - // Normalize Reddit URLs to prevent duplicates across different domains - const normalizedFeedUrl = normalizeRedditUrl(feedInfo.url); - - const existingSources = await ctx.db - .select() - .from(schema.sources) - .where(eq(schema.sources.url, normalizedFeedUrl)) - .limit(1); - - let sourceId: number; - - if (existingSources.length > 0) { - sourceId = existingSources[0].id; - await ctx.db - .update(schema.sources) - .set({ - title: feedTitle, - description: feedDescription, - siteUrl, - lastFetched: new Date(), - }) - .where(eq(schema.sources.id, sourceId)); - } else { - const newSource = await ctx.db - .insert(schema.sources) - .values({ - url: normalizedFeedUrl, - title: feedTitle, - description: feedDescription, - siteUrl, - iconType: "auto", - lastFetched: new Date(), - }) - .returning(); - sourceId = newSource[0].id; - } - - // Check if already subscribed - const existingSubscription = await ctx.db - .select() - .from(schema.subscriptions) - .where( - and( - eq(schema.subscriptions.userId, userId), - eq(schema.subscriptions.sourceId, sourceId) - ) - ) - .limit(1); + // Wrap entire OPML import in Sentry transaction for monitoring + await Sentry.startSpan( + { + op: "opml.import", + name: "OPML Import", + attributes: { + "opml.total_feeds": feedsToProcess.length, + "opml.user_id": userId, + }, + }, + async (importSpan) => { + // Process each feed + let shouldStopImporting = false; + for (const feedInfo of feedsToProcess) { + if (shouldStopImporting) { + break; // Stop processing remaining feeds if limit reached + } - if (existingSubscription.length > 0) { - // Already subscribed, skip - successCount++; - continue; - } + // Create a span for each feed import + await Sentry.startSpan( + { + op: "opml.import_feed", + name: `Import Feed: ${feedInfo.title}`, + attributes: { + "feed.url": feedInfo.url, + "feed.title": feedInfo.title, + "feed.domain": extractDomain(feedInfo.url) || "unknown", + "feed.has_filters": feedInfo.filters + ? feedInfo.filters.length > 0 + : false, + "feed.categories_count": feedInfo.categories.length, + }, + }, + async (feedSpan) => { + try { + // Fetch and validate feed + const response = await fetch(feedInfo.url, { + headers: { + "User-Agent": "TuvixRSS/1.0", + Accept: + "application/rss+xml, application/atom+xml, application/xml, text/xml, */*", + }, + signal: AbortSignal.timeout(15000), + }); + + if (!response.ok) { + throw new Error(`HTTP ${response.status}`); + } - // Check source limit before creating subscription - const limitCheck = await checkSourceLimit(ctx.db, userId); - if (!limitCheck.allowed) { - // Limit reached, stop importing - errorCount++; - errors.push({ - url: feedInfo.url, - error: `Source limit reached (${limitCheck.limit}/${limitCheck.limit}). Remaining feeds not imported.`, - }); - break; // Stop processing remaining feeds - } + const feedContent = await response.text(); + const feedResult = parseFeed(feedContent); + const feedData = feedResult.feed; + + // Extract metadata + const feedTitle = + "title" in feedData && feedData.title + ? feedData.title + : feedInfo.title; + const feedDescription = + "description" in feedData && feedData.description + ? stripHtml(feedData.description) + : "subtitle" in feedData && feedData.subtitle + ? stripHtml(feedData.subtitle) + : undefined; + const siteUrl = + "link" in feedData && feedData.link + ? feedData.link + : "links" in feedData && + Array.isArray(feedData.links) && + feedData.links[0]?.href + ? feedData.links[0].href + : undefined; + + // Check if source exists + // Normalize Reddit URLs to prevent duplicates across different domains + const normalizedFeedUrl = normalizeRedditUrl(feedInfo.url); + + const existingSources = await ctx.db + .select() + .from(schema.sources) + .where(eq(schema.sources.url, normalizedFeedUrl)) + .limit(1); + + let sourceId: number; + + if (existingSources.length > 0) { + sourceId = existingSources[0].id; + await ctx.db + .update(schema.sources) + .set({ + title: feedTitle, + description: feedDescription, + siteUrl, + lastFetched: new Date(), + }) + .where(eq(schema.sources.id, sourceId)); + } else { + const newSource = await ctx.db + .insert(schema.sources) + .values({ + url: normalizedFeedUrl, + title: feedTitle, + description: feedDescription, + siteUrl, + iconType: "auto", + lastFetched: new Date(), + }) + .returning(); + sourceId = newSource[0].id; + } - // Determine filter settings from OPML data - const filterEnabled = - feedInfo.filterEnabled !== undefined - ? feedInfo.filterEnabled - : feedInfo.filters && feedInfo.filters.length > 0 - ? true - : false; - const filterMode = feedInfo.filterMode || "include"; - - // Create subscription - const newSubscription = await ctx.db - .insert(schema.subscriptions) - .values({ - userId, - sourceId, - customTitle: null, - filterEnabled, - filterMode, - }) - .returning(); - - const subscriptionId = newSubscription[0].id; - - // Create/link categories (using normalization helper to prevent duplicates) - if (feedInfo.categories.length > 0) { - // Track category IDs to prevent duplicate links - const linkedCategoryIds = new Set(); - - for (const categoryName of feedInfo.categories) { - // Use findOrCreateCategory for case-insensitive normalization - const categoryId = await findOrCreateCategory( - ctx.db, - schema.categories, - userId, - categoryName, - generateColorFromString - ); - - // Only link if we haven't already linked this category - if (!linkedCategoryIds.has(categoryId)) { - linkedCategoryIds.add(categoryId); - await ctx.db.insert(schema.subscriptionCategories).values({ - subscriptionId, - categoryId, - }); - } - } - } + // Check if already subscribed + const existingSubscription = await ctx.db + .select() + .from(schema.subscriptions) + .where( + and( + eq(schema.subscriptions.userId, userId), + eq(schema.subscriptions.sourceId, sourceId) + ) + ) + .limit(1); + + if (existingSubscription.length > 0) { + // Already subscribed, skip + successCount++; + + // Mark span as successful (already exists) + feedSpan.setAttribute("feed.status", "already_exists"); + feedSpan.setStatus({ + code: 1, + message: "already subscribed", + }); + return; // Return from span callback (equivalent to continue) + } - // Create filters if provided - if (feedInfo.filters && feedInfo.filters.length > 0) { - for (const filter of feedInfo.filters) { - try { - // Validate regex pattern if matchType is 'regex' - if (filter.matchType === "regex") { - try { - new RegExp(filter.pattern); - } catch (regexError) { - // Invalid regex - skip this filter but continue + // Check source limit before creating subscription + const limitCheck = await checkSourceLimit(ctx.db, userId); + if (!limitCheck.allowed) { + // Limit reached, stop importing + errorCount++; errors.push({ url: feedInfo.url, - error: `Invalid regex pattern in filter: ${regexError instanceof Error ? regexError.message : "Unknown error"}`, + error: `Source limit reached (${limitCheck.limit}/${limitCheck.limit}). Remaining feeds not imported.`, + }); + + // Mark span as failed due to limit + feedSpan.setAttribute("feed.status", "limit_reached"); + feedSpan.setStatus({ + code: 2, + message: "source limit reached", }); - continue; + + shouldStopImporting = true; // Signal to stop processing remaining feeds + return; // Return from span callback + } + + // Determine filter settings from OPML data + const filterEnabled = + feedInfo.filterEnabled !== undefined + ? feedInfo.filterEnabled + : feedInfo.filters && feedInfo.filters.length > 0 + ? true + : false; + const filterMode = feedInfo.filterMode || "include"; + + // Create subscription + const newSubscription = await ctx.db + .insert(schema.subscriptions) + .values({ + userId, + sourceId, + customTitle: null, + filterEnabled, + filterMode, + }) + .returning(); + + const subscriptionId = newSubscription[0].id; + + // Create/link categories (using normalization helper to prevent duplicates) + if (feedInfo.categories.length > 0) { + // Track category IDs to prevent duplicate links + const linkedCategoryIds = new Set(); + + for (const categoryName of feedInfo.categories) { + // Use findOrCreateCategory for case-insensitive normalization + const categoryId = await findOrCreateCategory( + ctx.db, + schema.categories, + userId, + categoryName, + generateColorFromString + ); + + // Only link if we haven't already linked this category + if (!linkedCategoryIds.has(categoryId)) { + linkedCategoryIds.add(categoryId); + await ctx.db + .insert(schema.subscriptionCategories) + .values({ + subscriptionId, + categoryId, + }); + } + } + } + + // Create filters if provided + if (feedInfo.filters && feedInfo.filters.length > 0) { + for (const filter of feedInfo.filters) { + try { + // Validate regex pattern if matchType is 'regex' + if (filter.matchType === "regex") { + try { + new RegExp(filter.pattern); + } catch (regexError) { + // Invalid regex - skip this filter but continue + errors.push({ + url: feedInfo.url, + error: `Invalid regex pattern in filter: ${regexError instanceof Error ? regexError.message : "Unknown error"}`, + }); + continue; + } + } + + // Insert filter directly (more efficient than API call) + await ctx.db.insert(schema.subscriptionFilters).values({ + subscriptionId, + field: filter.field, + matchType: filter.matchType, + pattern: filter.pattern, + caseSensitive: filter.caseSensitive, + }); + } catch (filterError) { + // Filter creation failed - log error but continue + errors.push({ + url: feedInfo.url, + error: `Failed to create filter: ${filterError instanceof Error ? filterError.message : "Unknown error"}`, + }); + // Continue with next filter + } + } } - } - // Insert filter directly (more efficient than API call) - await ctx.db.insert(schema.subscriptionFilters).values({ - subscriptionId, - field: filter.field, - matchType: filter.matchType, - pattern: filter.pattern, - caseSensitive: filter.caseSensitive, - }); - } catch (filterError) { - // Filter creation failed - log error but continue - errors.push({ - url: feedInfo.url, - error: `Failed to create filter: ${filterError instanceof Error ? filterError.message : "Unknown error"}`, - }); - // Continue with next filter + successCount++; + + // Mark span as successful + feedSpan.setAttribute("feed.status", "success"); + feedSpan.setStatus({ code: 1, message: "ok" }); + } catch (error) { + errorCount++; + const errorMessage = + error instanceof Error ? error.message : "Unknown error"; + + errors.push({ + url: feedInfo.url, + error: errorMessage, + }); + + // Mark span as failed + feedSpan.setAttribute("feed.status", "error"); + feedSpan.setAttribute("feed.error", errorMessage); + feedSpan.setStatus({ + code: 2, + message: "feed import failed", + }); + + // Capture exception for this specific feed + await Sentry.captureException(error, { + level: "warning", + tags: { + operation: "opml_import_feed", + domain: extractDomain(feedInfo.url) || "unknown", + }, + extra: { + feed_url: feedInfo.url, + feed_title: feedInfo.title, + user_id: userId, + }, + }); + } } - } + ); } - successCount++; - } catch (error) { - errorCount++; - errors.push({ - url: feedInfo.url, - error: error instanceof Error ? error.message : "Unknown error", - }); + // Set final status on import span + importSpan.setAttribute("opml.success_count", successCount); + importSpan.setAttribute("opml.error_count", errorCount); + importSpan.setAttribute( + "opml.success_rate", + feedsToProcess.length > 0 ? successCount / feedsToProcess.length : 0 + ); + + if (errorCount === 0) { + importSpan.setStatus({ code: 1, message: "ok" }); + } else if (successCount === 0) { + importSpan.setStatus({ code: 2, message: "all feeds failed" }); + } else { + importSpan.setStatus({ code: 1, message: "partial success" }); + } } - } + ); // Recalculate usage stats to ensure accuracy after bulk import await recalculateUsage(ctx.db, userId); diff --git a/packages/api/src/services/email.ts b/packages/api/src/services/email.ts index a2427cdf..39d8909c 100644 --- a/packages/api/src/services/email.ts +++ b/packages/api/src/services/email.ts @@ -106,6 +106,19 @@ async function sendEmail(options: SendEmailOptions): Promise { return { success: true }; // Return success in dev mode } + // Add breadcrumb at service level for debugging + await Sentry.addBreadcrumb({ + category: "email.service", + message: `Attempting to send ${type} email`, + level: "info", + data: { + emailType: type, + recipient: to, + subject, + configured: isEmailConfigured(env), + }, + }); + // Wrap email sending in Sentry span for observability and timing const sendEmailWithSentry = async (): Promise => { return await withTiming( @@ -115,6 +128,17 @@ async function sendEmail(options: SendEmailOptions): Promise { // Initialize Resend client const resend = new Resend(env.RESEND_API_KEY); + // Add breadcrumb before API call + await Sentry.addBreadcrumb({ + category: "email.service", + message: "Calling Resend API", + level: "info", + data: { + emailType: type, + recipient: to, + }, + }); + // Send email via Resend (using React Email component directly) const { data, error } = await resend.emails.send({ from: env.EMAIL_FROM!, @@ -125,6 +149,21 @@ async function sendEmail(options: SendEmailOptions): Promise { if (error) { const errorMessage = `Failed to send ${type} email: ${error.message || "Unknown error"}`; + + // Add breadcrumb for Resend API error + await Sentry.addBreadcrumb({ + category: "email.service", + message: "Resend API returned error", + level: "error", + data: { + emailType: type, + recipient: to, + errorMessage: error.message, + errorCode: (error as { code?: string })?.code, + errorStatus: (error as { status?: number })?.status, + }, + }); + console.error(errorMessage, { type, to, @@ -161,6 +200,18 @@ async function sendEmail(options: SendEmailOptions): Promise { }; } + // Add breadcrumb for successful send + await Sentry.addBreadcrumb({ + category: "email.service", + message: `${type} email sent successfully`, + level: "info", + data: { + emailType: type, + recipient: to, + emailId: data?.id, + }, + }); + // Log success (in development) if (process.env.NODE_ENV !== "production") { console.log(`โœ… ${type} email sent to ${to} (ID: ${data?.id})`); @@ -178,6 +229,19 @@ async function sendEmail(options: SendEmailOptions): Promise { error instanceof Error ? error.message : "Unknown error"; const errorStack = error instanceof Error ? error.stack : undefined; + // Add breadcrumb for exception + await Sentry.addBreadcrumb({ + category: "email.service", + message: "Exception thrown while sending email", + level: "error", + data: { + emailType: type, + recipient: to, + errorMessage, + errorType: error instanceof Error ? error.name : "Unknown", + }, + }); + console.error(`Error sending ${type} email:`, { errorMessage, errorStack, diff --git a/packages/api/src/services/rss-fetcher.ts b/packages/api/src/services/rss-fetcher.ts index b78690e5..ecf5145a 100644 --- a/packages/api/src/services/rss-fetcher.ts +++ b/packages/api/src/services/rss-fetcher.ts @@ -870,14 +870,42 @@ async function extractArticleData( // Final fallback: OpenGraph image from article URL if (!imageUrl && link) { - try { - const ogImage = await extractOgImage(link); - if (ogImage) { - imageUrl = ogImage; + await Sentry.startSpan( + { + op: "http.client", + name: "Fetch OpenGraph Image", + attributes: { + "http.url": link, + "og.domain": extractDomain(link) ?? "unknown", + }, + }, + async (span) => { + try { + const ogImage = await extractOgImage(link); + if (ogImage) { + imageUrl = ogImage; + span.setAttribute("og.found", true); + span.setStatus({ code: 1, message: "ok" }); + } else { + span.setAttribute("og.found", false); + span.setStatus({ code: 1, message: "no image found" }); + } + } catch (error) { + // Track OG fetch failures for pattern analysis + span.setAttribute( + "og.error", + error instanceof Error ? error.message : String(error) + ); + span.setStatus({ code: 2, message: "fetch failed" }); + + // Don't spam Sentry with every OG failure, but track metrics + emitCounter("og_image.fetch_error", 1, { + domain: extractDomain(link) ?? "unknown", + error_type: error instanceof Error ? error.name : "unknown", + }); + } } - } catch (error) { - // Silently ignore OG fetch errors - } + ); } // Audio URL from enclosures (for podcasts) diff --git a/packages/api/tsup.config.ts b/packages/api/tsup.config.ts new file mode 100644 index 00000000..5727c6ba --- /dev/null +++ b/packages/api/tsup.config.ts @@ -0,0 +1,27 @@ +import { defineConfig } from "tsup"; + +export default defineConfig({ + entry: { + "entries/node": "src/entries/node.ts", + "db/migrate-local": "src/db/migrate-local.ts", + }, + format: ["esm"], + target: "node20", + platform: "node", + outDir: "dist", + clean: true, + sourcemap: false, + minify: false, + bundle: true, + external: [ + // External packages that shouldn't be bundled + "better-sqlite3", + "bcrypt", + ], + noExternal: [ + // Bundle everything else including workspace packages + "@tuvixrss/tricorder", + ], + splitting: false, + treeshake: true, +}); diff --git a/packages/app/Dockerfile b/packages/app/Dockerfile index fe845c61..094110ce 100644 --- a/packages/app/Dockerfile +++ b/packages/app/Dockerfile @@ -5,29 +5,46 @@ WORKDIR /app # Install pnpm RUN npm install -g pnpm@10.19.0 +# Copy workspace files +COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./ + # Copy package files -COPY package.json pnpm-lock.yaml* ./ +COPY packages/app/package.json ./packages/app/ +COPY packages/api/package.json ./packages/api/ +COPY packages/tricorder/package.json ./packages/tricorder/ + +# Install dependencies RUN pnpm install --frozen-lockfile # Copy source code -COPY . . +COPY packages/app ./packages/app # Build argument for API URL ARG VITE_API_URL=http://localhost:3001/trpc ENV VITE_API_URL=${VITE_API_URL} # Build the application -RUN pnpm build +RUN pnpm --filter @tuvixrss/app build # Production stage with nginx FROM nginx:alpine # Copy built files from builder -COPY --from=builder /app/dist /usr/share/nginx/html +COPY --from=builder /app/packages/app/dist /usr/share/nginx/html + +# Create non-root user for nginx +RUN addgroup -g 1001 -S nginx-app && \ + adduser -S nginx-app -u 1001 && \ + chown -R nginx-app:nginx-app /usr/share/nginx/html && \ + chown -R nginx-app:nginx-app /var/cache/nginx && \ + chown -R nginx-app:nginx-app /var/log/nginx && \ + touch /var/run/nginx.pid && \ + chown -R nginx-app:nginx-app /var/run/nginx.pid # Create nginx configuration for SPA routing and health check +# Listen on port 8080 (non-privileged) since we run as non-root user RUN echo 'server { \ - listen 80; \ + listen 8080; \ server_name _; \ root /usr/share/nginx/html; \ index index.html; \ @@ -50,6 +67,12 @@ RUN echo 'server { \ } \ }' > /etc/nginx/conf.d/default.conf -EXPOSE 80 +USER nginx-app + +EXPOSE 8080 + +# Health check +HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ + CMD wget --no-verbose --tries=1 --spider http://127.0.0.1:8080/health || exit 1 CMD ["nginx", "-g", "daemon off;"] diff --git a/packages/app/pnpm-lock.yaml b/packages/app/pnpm-lock.yaml deleted file mode 100644 index 094ac454..00000000 --- a/packages/app/pnpm-lock.yaml +++ /dev/null @@ -1,6804 +0,0 @@ -lockfileVersion: "9.0" - -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false - -importers: - .: - dependencies: - "@hookform/resolvers": - specifier: ^5.2.2 - version: 5.2.2(react-hook-form@7.66.0(react@19.2.0)) - "@radix-ui/react-alert-dialog": - specifier: ^1.1.15 - version: 1.1.15(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-avatar": - specifier: ^1.1.10 - version: 1.1.10(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-checkbox": - specifier: ^1.3.3 - version: 1.3.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-collapsible": - specifier: ^1.1.12 - version: 1.1.12(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-dialog": - specifier: ^1.1.15 - version: 1.1.15(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-dropdown-menu": - specifier: ^2.1.16 - version: 2.1.16(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-label": - specifier: ^2.1.7 - version: 2.1.7(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-scroll-area": - specifier: ^1.2.10 - version: 1.2.10(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-select": - specifier: ^2.2.6 - version: 2.2.6(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-separator": - specifier: ^1.1.7 - version: 1.1.7(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-slot": - specifier: ^1.2.3 - version: 1.2.3(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-switch": - specifier: ^1.2.6 - version: 1.2.6(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-tabs": - specifier: ^1.1.13 - version: 1.1.13(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-tooltip": - specifier: ^1.2.8 - version: 1.2.8(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@tailwindcss/vite": - specifier: ^4.1.16 - version: 4.1.16(rolldown-vite@7.1.14(@types/node@24.9.2)(esbuild@0.25.12)(jiti@2.6.1)(tsx@4.20.6)) - "@tanstack/react-query": - specifier: ^5.90.6 - version: 5.90.6(react@19.2.0) - "@tanstack/react-router": - specifier: ^1.134.9 - version: 1.134.9(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@trpc/client": - specifier: ^11.7.1 - version: 11.7.1(@trpc/server@11.7.1(typescript@5.9.3))(typescript@5.9.3) - "@trpc/react-query": - specifier: ^11.7.1 - version: 11.7.1(@tanstack/react-query@5.90.6(react@19.2.0))(@trpc/client@11.7.1(@trpc/server@11.7.1(typescript@5.9.3))(typescript@5.9.3))(@trpc/server@11.7.1(typescript@5.9.3))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.9.3) - "@trpc/server": - specifier: ^11.7.1 - version: 11.7.1(typescript@5.9.3) - class-variance-authority: - specifier: ^0.7.1 - version: 0.7.1 - clsx: - specifier: ^2.1.1 - version: 2.1.1 - lucide-react: - specifier: ^0.552.0 - version: 0.552.0(react@19.2.0) - motion: - specifier: ^12.23.24 - version: 12.23.24(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - radix-ui: - specifier: ^1.4.3 - version: 1.4.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - react: - specifier: ^19.1.1 - version: 19.2.0 - react-dom: - specifier: ^19.1.1 - version: 19.2.0(react@19.2.0) - react-hook-form: - specifier: ^7.66.0 - version: 7.66.0(react@19.2.0) - react-intersection-observer: - specifier: ^10.0.0 - version: 10.0.0(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - sonner: - specifier: ^2.0.7 - version: 2.0.7(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - tailwind-merge: - specifier: ^3.3.1 - version: 3.3.1 - tailwindcss: - specifier: ^4.1.16 - version: 4.1.16 - zod: - specifier: ^4.1.12 - version: 4.1.12 - devDependencies: - "@eslint/js": - specifier: ^9.36.0 - version: 9.39.0 - "@tanstack/router-cli": - specifier: ^1.134.9 - version: 1.134.9 - "@tanstack/router-plugin": - specifier: ^1.134.9 - version: 1.134.9(@tanstack/react-router@1.134.9(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(rolldown-vite@7.1.14(@types/node@24.9.2)(esbuild@0.25.12)(jiti@2.6.1)(tsx@4.20.6)) - "@types/node": - specifier: ^24.6.0 - version: 24.9.2 - "@types/react": - specifier: ^19.1.16 - version: 19.2.2 - "@types/react-dom": - specifier: ^19.1.9 - version: 19.2.2(@types/react@19.2.2) - "@vitejs/plugin-react": - specifier: ^5.1.0 - version: 5.1.0(rolldown-vite@7.1.14(@types/node@24.9.2)(esbuild@0.25.12)(jiti@2.6.1)(tsx@4.20.6)) - "@vitejs/plugin-react-swc": - specifier: ^4.1.0 - version: 4.2.0(rolldown-vite@7.1.14(@types/node@24.9.2)(esbuild@0.25.12)(jiti@2.6.1)(tsx@4.20.6)) - eslint: - specifier: ^9.36.0 - version: 9.39.0(jiti@2.6.1) - eslint-plugin-react-hooks: - specifier: ^5.2.0 - version: 5.2.0(eslint@9.39.0(jiti@2.6.1)) - eslint-plugin-react-refresh: - specifier: ^0.4.22 - version: 0.4.24(eslint@9.39.0(jiti@2.6.1)) - globals: - specifier: ^16.4.0 - version: 16.5.0 - knip: - specifier: ^5.67.1 - version: 5.67.1(@types/node@24.9.2)(typescript@5.9.3) - prettier: - specifier: ^3.6.2 - version: 3.6.2 - tw-animate-css: - specifier: ^1.4.0 - version: 1.4.0 - typescript: - specifier: ~5.9.3 - version: 5.9.3 - typescript-eslint: - specifier: ^8.45.0 - version: 8.46.2(eslint@9.39.0(jiti@2.6.1))(typescript@5.9.3) - vite: - specifier: npm:rolldown-vite@7.1.14 - version: rolldown-vite@7.1.14(@types/node@24.9.2)(esbuild@0.25.12)(jiti@2.6.1)(tsx@4.20.6) - -packages: - "@babel/code-frame@7.27.1": - resolution: - { - integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==, - } - engines: { node: ">=6.9.0" } - - "@babel/compat-data@7.28.5": - resolution: - { - integrity: sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==, - } - engines: { node: ">=6.9.0" } - - "@babel/core@7.28.5": - resolution: - { - integrity: sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==, - } - engines: { node: ">=6.9.0" } - - "@babel/generator@7.28.5": - resolution: - { - integrity: sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==, - } - engines: { node: ">=6.9.0" } - - "@babel/helper-annotate-as-pure@7.27.3": - resolution: - { - integrity: sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==, - } - engines: { node: ">=6.9.0" } - - "@babel/helper-compilation-targets@7.27.2": - resolution: - { - integrity: sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==, - } - engines: { node: ">=6.9.0" } - - "@babel/helper-create-class-features-plugin@7.28.5": - resolution: - { - integrity: sha512-q3WC4JfdODypvxArsJQROfupPBq9+lMwjKq7C33GhbFYJsufD0yd/ziwD+hJucLeWsnFPWZjsU2DNFqBPE7jwQ==, - } - engines: { node: ">=6.9.0" } - peerDependencies: - "@babel/core": ^7.0.0 - - "@babel/helper-globals@7.28.0": - resolution: - { - integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==, - } - engines: { node: ">=6.9.0" } - - "@babel/helper-member-expression-to-functions@7.28.5": - resolution: - { - integrity: sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==, - } - engines: { node: ">=6.9.0" } - - "@babel/helper-module-imports@7.27.1": - resolution: - { - integrity: sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==, - } - engines: { node: ">=6.9.0" } - - "@babel/helper-module-transforms@7.28.3": - resolution: - { - integrity: sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==, - } - engines: { node: ">=6.9.0" } - peerDependencies: - "@babel/core": ^7.0.0 - - "@babel/helper-optimise-call-expression@7.27.1": - resolution: - { - integrity: sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==, - } - engines: { node: ">=6.9.0" } - - "@babel/helper-plugin-utils@7.27.1": - resolution: - { - integrity: sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==, - } - engines: { node: ">=6.9.0" } - - "@babel/helper-replace-supers@7.27.1": - resolution: - { - integrity: sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA==, - } - engines: { node: ">=6.9.0" } - peerDependencies: - "@babel/core": ^7.0.0 - - "@babel/helper-skip-transparent-expression-wrappers@7.27.1": - resolution: - { - integrity: sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==, - } - engines: { node: ">=6.9.0" } - - "@babel/helper-string-parser@7.27.1": - resolution: - { - integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==, - } - engines: { node: ">=6.9.0" } - - "@babel/helper-validator-identifier@7.28.5": - resolution: - { - integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==, - } - engines: { node: ">=6.9.0" } - - "@babel/helper-validator-option@7.27.1": - resolution: - { - integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==, - } - engines: { node: ">=6.9.0" } - - "@babel/helpers@7.28.4": - resolution: - { - integrity: sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==, - } - engines: { node: ">=6.9.0" } - - "@babel/parser@7.28.5": - resolution: - { - integrity: sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==, - } - engines: { node: ">=6.0.0" } - hasBin: true - - "@babel/plugin-syntax-jsx@7.27.1": - resolution: - { - integrity: sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==, - } - engines: { node: ">=6.9.0" } - peerDependencies: - "@babel/core": ^7.0.0-0 - - "@babel/plugin-syntax-typescript@7.27.1": - resolution: - { - integrity: sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==, - } - engines: { node: ">=6.9.0" } - peerDependencies: - "@babel/core": ^7.0.0-0 - - "@babel/plugin-transform-modules-commonjs@7.27.1": - resolution: - { - integrity: sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw==, - } - engines: { node: ">=6.9.0" } - peerDependencies: - "@babel/core": ^7.0.0-0 - - "@babel/plugin-transform-react-jsx-self@7.27.1": - resolution: - { - integrity: sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==, - } - engines: { node: ">=6.9.0" } - peerDependencies: - "@babel/core": ^7.0.0-0 - - "@babel/plugin-transform-react-jsx-source@7.27.1": - resolution: - { - integrity: sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==, - } - engines: { node: ">=6.9.0" } - peerDependencies: - "@babel/core": ^7.0.0-0 - - "@babel/plugin-transform-typescript@7.28.5": - resolution: - { - integrity: sha512-x2Qa+v/CuEoX7Dr31iAfr0IhInrVOWZU/2vJMJ00FOR/2nM0BcBEclpaf9sWCDc+v5e9dMrhSH8/atq/kX7+bA==, - } - engines: { node: ">=6.9.0" } - peerDependencies: - "@babel/core": ^7.0.0-0 - - "@babel/preset-typescript@7.28.5": - resolution: - { - integrity: sha512-+bQy5WOI2V6LJZpPVxY+yp66XdZ2yifu0Mc1aP5CQKgjn4QM5IN2i5fAZ4xKop47pr8rpVhiAeu+nDQa12C8+g==, - } - engines: { node: ">=6.9.0" } - peerDependencies: - "@babel/core": ^7.0.0-0 - - "@babel/template@7.27.2": - resolution: - { - integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==, - } - engines: { node: ">=6.9.0" } - - "@babel/traverse@7.28.5": - resolution: - { - integrity: sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==, - } - engines: { node: ">=6.9.0" } - - "@babel/types@7.28.5": - resolution: - { - integrity: sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==, - } - engines: { node: ">=6.9.0" } - - "@emnapi/core@1.6.0": - resolution: - { - integrity: sha512-zq/ay+9fNIJJtJiZxdTnXS20PllcYMX3OE23ESc4HK/bdYu3cOWYVhsOhVnXALfU/uqJIxn5NBPd9z4v+SfoSg==, - } - - "@emnapi/runtime@1.6.0": - resolution: - { - integrity: sha512-obtUmAHTMjll499P+D9A3axeJFlhdjOWdKUNs/U6QIGT7V5RjcUW1xToAzjvmgTSQhDbYn/NwfTRoJcQ2rNBxA==, - } - - "@emnapi/wasi-threads@1.1.0": - resolution: - { - integrity: sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==, - } - - "@esbuild/aix-ppc64@0.25.12": - resolution: - { - integrity: sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==, - } - engines: { node: ">=18" } - cpu: [ppc64] - os: [aix] - - "@esbuild/android-arm64@0.25.12": - resolution: - { - integrity: sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==, - } - engines: { node: ">=18" } - cpu: [arm64] - os: [android] - - "@esbuild/android-arm@0.25.12": - resolution: - { - integrity: sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==, - } - engines: { node: ">=18" } - cpu: [arm] - os: [android] - - "@esbuild/android-x64@0.25.12": - resolution: - { - integrity: sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==, - } - engines: { node: ">=18" } - cpu: [x64] - os: [android] - - "@esbuild/darwin-arm64@0.25.12": - resolution: - { - integrity: sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==, - } - engines: { node: ">=18" } - cpu: [arm64] - os: [darwin] - - "@esbuild/darwin-x64@0.25.12": - resolution: - { - integrity: sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==, - } - engines: { node: ">=18" } - cpu: [x64] - os: [darwin] - - "@esbuild/freebsd-arm64@0.25.12": - resolution: - { - integrity: sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==, - } - engines: { node: ">=18" } - cpu: [arm64] - os: [freebsd] - - "@esbuild/freebsd-x64@0.25.12": - resolution: - { - integrity: sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==, - } - engines: { node: ">=18" } - cpu: [x64] - os: [freebsd] - - "@esbuild/linux-arm64@0.25.12": - resolution: - { - integrity: sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==, - } - engines: { node: ">=18" } - cpu: [arm64] - os: [linux] - - "@esbuild/linux-arm@0.25.12": - resolution: - { - integrity: sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==, - } - engines: { node: ">=18" } - cpu: [arm] - os: [linux] - - "@esbuild/linux-ia32@0.25.12": - resolution: - { - integrity: sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==, - } - engines: { node: ">=18" } - cpu: [ia32] - os: [linux] - - "@esbuild/linux-loong64@0.25.12": - resolution: - { - integrity: sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==, - } - engines: { node: ">=18" } - cpu: [loong64] - os: [linux] - - "@esbuild/linux-mips64el@0.25.12": - resolution: - { - integrity: sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==, - } - engines: { node: ">=18" } - cpu: [mips64el] - os: [linux] - - "@esbuild/linux-ppc64@0.25.12": - resolution: - { - integrity: sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==, - } - engines: { node: ">=18" } - cpu: [ppc64] - os: [linux] - - "@esbuild/linux-riscv64@0.25.12": - resolution: - { - integrity: sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==, - } - engines: { node: ">=18" } - cpu: [riscv64] - os: [linux] - - "@esbuild/linux-s390x@0.25.12": - resolution: - { - integrity: sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==, - } - engines: { node: ">=18" } - cpu: [s390x] - os: [linux] - - "@esbuild/linux-x64@0.25.12": - resolution: - { - integrity: sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==, - } - engines: { node: ">=18" } - cpu: [x64] - os: [linux] - - "@esbuild/netbsd-arm64@0.25.12": - resolution: - { - integrity: sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==, - } - engines: { node: ">=18" } - cpu: [arm64] - os: [netbsd] - - "@esbuild/netbsd-x64@0.25.12": - resolution: - { - integrity: sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==, - } - engines: { node: ">=18" } - cpu: [x64] - os: [netbsd] - - "@esbuild/openbsd-arm64@0.25.12": - resolution: - { - integrity: sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==, - } - engines: { node: ">=18" } - cpu: [arm64] - os: [openbsd] - - "@esbuild/openbsd-x64@0.25.12": - resolution: - { - integrity: sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==, - } - engines: { node: ">=18" } - cpu: [x64] - os: [openbsd] - - "@esbuild/openharmony-arm64@0.25.12": - resolution: - { - integrity: sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==, - } - engines: { node: ">=18" } - cpu: [arm64] - os: [openharmony] - - "@esbuild/sunos-x64@0.25.12": - resolution: - { - integrity: sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==, - } - engines: { node: ">=18" } - cpu: [x64] - os: [sunos] - - "@esbuild/win32-arm64@0.25.12": - resolution: - { - integrity: sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==, - } - engines: { node: ">=18" } - cpu: [arm64] - os: [win32] - - "@esbuild/win32-ia32@0.25.12": - resolution: - { - integrity: sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==, - } - engines: { node: ">=18" } - cpu: [ia32] - os: [win32] - - "@esbuild/win32-x64@0.25.12": - resolution: - { - integrity: sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==, - } - engines: { node: ">=18" } - cpu: [x64] - os: [win32] - - "@eslint-community/eslint-utils@4.9.0": - resolution: - { - integrity: sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==, - } - engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 } - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - - "@eslint-community/regexpp@4.12.2": - resolution: - { - integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==, - } - engines: { node: ^12.0.0 || ^14.0.0 || >=16.0.0 } - - "@eslint/config-array@0.21.1": - resolution: - { - integrity: sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==, - } - engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } - - "@eslint/config-helpers@0.4.2": - resolution: - { - integrity: sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==, - } - engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } - - "@eslint/core@0.17.0": - resolution: - { - integrity: sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==, - } - engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } - - "@eslint/eslintrc@3.3.1": - resolution: - { - integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==, - } - engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } - - "@eslint/js@9.39.0": - resolution: - { - integrity: sha512-BIhe0sW91JGPiaF1mOuPy5v8NflqfjIcDNpC+LbW9f609WVRX1rArrhi6Z2ymvrAry9jw+5POTj4t2t62o8Bmw==, - } - engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } - - "@eslint/object-schema@2.1.7": - resolution: - { - integrity: sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==, - } - engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } - - "@eslint/plugin-kit@0.4.1": - resolution: - { - integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==, - } - engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } - - "@floating-ui/core@1.7.3": - resolution: - { - integrity: sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==, - } - - "@floating-ui/dom@1.7.4": - resolution: - { - integrity: sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA==, - } - - "@floating-ui/react-dom@2.1.6": - resolution: - { - integrity: sha512-4JX6rEatQEvlmgU80wZyq9RT96HZJa88q8hp0pBd+LrczeDI4o6uA2M+uvxngVHo4Ihr8uibXxH6+70zhAFrVw==, - } - peerDependencies: - react: ">=16.8.0" - react-dom: ">=16.8.0" - - "@floating-ui/utils@0.2.10": - resolution: - { - integrity: sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==, - } - - "@hookform/resolvers@5.2.2": - resolution: - { - integrity: sha512-A/IxlMLShx3KjV/HeTcTfaMxdwy690+L/ZADoeaTltLx+CVuzkeVIPuybK3jrRfw7YZnmdKsVVHAlEPIAEUNlA==, - } - peerDependencies: - react-hook-form: ^7.55.0 - - "@humanfs/core@0.19.1": - resolution: - { - integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==, - } - engines: { node: ">=18.18.0" } - - "@humanfs/node@0.16.7": - resolution: - { - integrity: sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==, - } - engines: { node: ">=18.18.0" } - - "@humanwhocodes/module-importer@1.0.1": - resolution: - { - integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==, - } - engines: { node: ">=12.22" } - - "@humanwhocodes/retry@0.4.3": - resolution: - { - integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==, - } - engines: { node: ">=18.18" } - - "@jridgewell/gen-mapping@0.3.13": - resolution: - { - integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==, - } - - "@jridgewell/remapping@2.3.5": - resolution: - { - integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==, - } - - "@jridgewell/resolve-uri@3.1.2": - resolution: - { - integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==, - } - engines: { node: ">=6.0.0" } - - "@jridgewell/sourcemap-codec@1.5.5": - resolution: - { - integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==, - } - - "@jridgewell/trace-mapping@0.3.31": - resolution: - { - integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==, - } - - "@napi-rs/wasm-runtime@1.0.7": - resolution: - { - integrity: sha512-SeDnOO0Tk7Okiq6DbXmmBODgOAb9dp9gjlphokTUxmt8U3liIP1ZsozBahH69j/RJv+Rfs6IwUKHTgQYJ/HBAw==, - } - - "@nodelib/fs.scandir@2.1.5": - resolution: - { - integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==, - } - engines: { node: ">= 8" } - - "@nodelib/fs.stat@2.0.5": - resolution: - { - integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==, - } - engines: { node: ">= 8" } - - "@nodelib/fs.walk@1.2.8": - resolution: - { - integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==, - } - engines: { node: ">= 8" } - - "@oxc-project/runtime@0.92.0": - resolution: - { - integrity: sha512-Z7x2dZOmznihvdvCvLKMl+nswtOSVxS2H2ocar+U9xx6iMfTp0VGIrX6a4xB1v80IwOPC7dT1LXIJrY70Xu3Jw==, - } - engines: { node: ^20.19.0 || >=22.12.0 } - - "@oxc-project/types@0.93.0": - resolution: - { - integrity: sha512-yNtwmWZIBtJsMr5TEfoZFDxIWV6OdScOpza/f5YxbqUMJk+j6QX3Cf3jgZShGEFYWQJ5j9mJ6jM0tZHu2J9Yrg==, - } - - "@oxc-resolver/binding-android-arm-eabi@11.13.1": - resolution: - { - integrity: sha512-YijiebZnGbKtwhLJXmUkOTS2iFF5Mh7TZb3SpVGrbgH6t2flJn7K+k78FJN7tc2lfixdlI1amkcCbTCgV+2WwQ==, - } - cpu: [arm] - os: [android] - - "@oxc-resolver/binding-android-arm64@11.13.1": - resolution: - { - integrity: sha512-cURsasEvObw/KCi8eRuZhHiT4agR4cui6uWX8ss2z/Ok23f8W+P8fvEZD0iUMIAmHwyAxA93RxNTIKh48zK39A==, - } - cpu: [arm64] - os: [android] - - "@oxc-resolver/binding-darwin-arm64@11.13.1": - resolution: - { - integrity: sha512-IKsn9oeVrbWpbE+PanGr5C4tRPVhVuBh/ZY8I7bbqaxBjemlgKKNGNSq73VDzQjRApJgjjzsVDgkTwTrKivLGg==, - } - cpu: [arm64] - os: [darwin] - - "@oxc-resolver/binding-darwin-x64@11.13.1": - resolution: - { - integrity: sha512-FW9toaDOXSLmP3lYXsXPalQKLs8eXwZCNUOPeng84MExl+ALe0Ik+sif/U6P/nqJgVdVm4MEiZcnnNtQ+Bn29Q==, - } - cpu: [x64] - os: [darwin] - - "@oxc-resolver/binding-freebsd-x64@11.13.1": - resolution: - { - integrity: sha512-9EODydJ8P/DhEmVIdcjLnlDXAw9hot2NLuwY1/6gp3fKNXsqz3s9ch/vlDpq0CMtvjQ3Z4a2P+4IsH5A73Eh/A==, - } - cpu: [x64] - os: [freebsd] - - "@oxc-resolver/binding-linux-arm-gnueabihf@11.13.1": - resolution: - { - integrity: sha512-Ud/q31NNEFXVy9mwO1jbXXsuqYd8ftoweL4z9MZ5wahlncnzPYKcEGSdBfSi7TKct4KU8EdvAxi+F9wdO1dCGw==, - } - cpu: [arm] - os: [linux] - - "@oxc-resolver/binding-linux-arm-musleabihf@11.13.1": - resolution: - { - integrity: sha512-4x/eNAoQ7Ec2n81S2akaBeDbM4ceuy8R4sd41p1ETnM5PBhvBzWSuf75vQp4K1dLyKKPe+fw+uG4eIpgzqvj8A==, - } - cpu: [arm] - os: [linux] - - "@oxc-resolver/binding-linux-arm64-gnu@11.13.1": - resolution: - { - integrity: sha512-435Sf0a1KKjU7jgB5gcisTq6WMxQQVfsmKWAcQ3VhbXU/NpaUUZaezKmZJXNiAO1sUY6/zRJnTaPtsBq9msYlQ==, - } - cpu: [arm64] - os: [linux] - - "@oxc-resolver/binding-linux-arm64-musl@11.13.1": - resolution: - { - integrity: sha512-Okb7KgPJvA/Db0QwdVziuYs5MZQEq9PC5MEDrBK7jmcqQL2RO+mk7oztqSegcNJ7kMyNM7Zi2cN9G69g4Cs3zg==, - } - cpu: [arm64] - os: [linux] - - "@oxc-resolver/binding-linux-ppc64-gnu@11.13.1": - resolution: - { - integrity: sha512-HyM9+MlH7bWQtjtGzhxVMVhIuy2C1+MqavBfSMyY2d9SSdxcKvboMhl/0vTTMH/R94z8n/gP5XSJ1M6/BC30Pw==, - } - cpu: [ppc64] - os: [linux] - - "@oxc-resolver/binding-linux-riscv64-gnu@11.13.1": - resolution: - { - integrity: sha512-ukJFu+798IzODSIupFAbouehJOLqQwhz56VlzRXi+42xtsmtZ+NLla2CXlaw1V9nMB7HLEQU1+XklkeFsIxz4g==, - } - cpu: [riscv64] - os: [linux] - - "@oxc-resolver/binding-linux-riscv64-musl@11.13.1": - resolution: - { - integrity: sha512-gCr05/1CbuKQ/E39pzVjBLE/amtdvFpHeEd6lUOshnoInZ48g33b+1/CNyeO+B1CoiIydYGrkbyIoIeSMWzSsw==, - } - cpu: [riscv64] - os: [linux] - - "@oxc-resolver/binding-linux-s390x-gnu@11.13.1": - resolution: - { - integrity: sha512-ojQVasxjsZGCxt+ygyipCSp74P22WdUToBLM8D9qVm/yehOtxIT8nv0FyQrc4DOpqzGPxQS2OcgvLag+9AhsFg==, - } - cpu: [s390x] - os: [linux] - - "@oxc-resolver/binding-linux-x64-gnu@11.13.1": - resolution: - { - integrity: sha512-Vr28gTydAegrq+qmQu4IvR+LEq3A8amuHdOPSOwMM44cwpIvEDd4MmhimfEqoWjcfVZy9vpd5mPZZY6C/lHq9g==, - } - cpu: [x64] - os: [linux] - - "@oxc-resolver/binding-linux-x64-musl@11.13.1": - resolution: - { - integrity: sha512-a2g2nv3IulLb9lHd8ZDGEnWIpNXcZviLiEKt+PHP3k3d86U1adlL5rNmImjF+eNGReTyttlX/hYNT4UIPo7IjA==, - } - cpu: [x64] - os: [linux] - - "@oxc-resolver/binding-wasm32-wasi@11.13.1": - resolution: - { - integrity: sha512-PhvfJQG6IyI9uN1c5NAZqfl1N9lLF1XdenX+H3aHYHlADPiOgwtpQgBETSD2L3ySeR7jLzJRVFUrWEu4uDz7Lg==, - } - engines: { node: ">=14.0.0" } - cpu: [wasm32] - - "@oxc-resolver/binding-win32-arm64-msvc@11.13.1": - resolution: - { - integrity: sha512-hyKUC0JQbTKoaPw3r9XHWHtj+B/win36VjTyKDd0OjG71UeyAhZiJBjoNJwfmnTIPcQS4YNesjNkqqDe4qN44w==, - } - cpu: [arm64] - os: [win32] - - "@oxc-resolver/binding-win32-ia32-msvc@11.13.1": - resolution: - { - integrity: sha512-0/y+YMQJEd8kltqPTAUi1PHsYTUi/7UL8Jkhh6BODn3VBQIMMfHhyS8MH4geYJLEJUxuRxGKtya57GOTAN2WSw==, - } - cpu: [ia32] - os: [win32] - - "@oxc-resolver/binding-win32-x64-msvc@11.13.1": - resolution: - { - integrity: sha512-0r1P/PDUD936rZShGdfnqNFdozRVgFYrcdajm1ZZ8wMoN594YkjKmlM3z3DB6arS+Bz7RhA9uLXcP74GqZ/lAw==, - } - cpu: [x64] - os: [win32] - - "@radix-ui/number@1.1.1": - resolution: - { - integrity: sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==, - } - - "@radix-ui/primitive@1.1.3": - resolution: - { - integrity: sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==, - } - - "@radix-ui/react-accessible-icon@1.1.7": - resolution: - { - integrity: sha512-XM+E4WXl0OqUJFovy6GjmxxFyx9opfCAIUku4dlKRd5YEPqt4kALOkQOp0Of6reHuUkJuiPBEc5k0o4z4lTC8A==, - } - 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 - - "@radix-ui/react-accordion@1.2.12": - resolution: - { - integrity: sha512-T4nygeh9YE9dLRPhAHSeOZi7HBXo+0kYIPJXayZfvWOWA0+n3dESrZbjfDPUABkUNym6Hd+f2IR113To8D2GPA==, - } - 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 - - "@radix-ui/react-alert-dialog@1.1.15": - resolution: - { - integrity: sha512-oTVLkEw5GpdRe29BqJ0LSDFWI3qu0vR1M0mUkOQWDIUnY/QIkLpgDMWuKxP94c2NAC2LGcgVhG1ImF3jkZ5wXw==, - } - 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 - - "@radix-ui/react-arrow@1.1.7": - resolution: - { - integrity: sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==, - } - 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 - - "@radix-ui/react-aspect-ratio@1.1.7": - resolution: - { - integrity: sha512-Yq6lvO9HQyPwev1onK1daHCHqXVLzPhSVjmsNjCa2Zcxy2f7uJD2itDtxknv6FzAKCwD1qQkeVDmX/cev13n/g==, - } - 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 - - "@radix-ui/react-avatar@1.1.10": - resolution: - { - integrity: sha512-V8piFfWapM5OmNCXTzVQY+E1rDa53zY+MQ4Y7356v4fFz6vqCyUtIz2rUD44ZEdwg78/jKmMJHj07+C/Z/rcog==, - } - 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 - - "@radix-ui/react-checkbox@1.3.3": - resolution: - { - integrity: sha512-wBbpv+NQftHDdG86Qc0pIyXk5IR3tM8Vd0nWLKDcX8nNn4nXFOFwsKuqw2okA/1D/mpaAkmuyndrPJTYDNZtFw==, - } - 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 - - "@radix-ui/react-collapsible@1.1.12": - resolution: - { - integrity: sha512-Uu+mSh4agx2ib1uIGPP4/CKNULyajb3p92LsVXmH2EHVMTfZWpll88XJ0j4W0z3f8NK1eYl1+Mf/szHPmcHzyA==, - } - 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 - - "@radix-ui/react-collection@1.1.7": - resolution: - { - integrity: sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==, - } - 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 - - "@radix-ui/react-compose-refs@1.1.2": - resolution: - { - integrity: sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==, - } - peerDependencies: - "@types/react": "*" - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - "@types/react": - optional: true - - "@radix-ui/react-context-menu@2.2.16": - resolution: - { - integrity: sha512-O8morBEW+HsVG28gYDZPTrT9UUovQUlJue5YO836tiTJhuIWBm/zQHc7j388sHWtdH/xUZurK9olD2+pcqx5ww==, - } - 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 - - "@radix-ui/react-context@1.1.2": - resolution: - { - integrity: sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==, - } - peerDependencies: - "@types/react": "*" - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - "@types/react": - optional: true - - "@radix-ui/react-dialog@1.1.15": - resolution: - { - integrity: sha512-TCglVRtzlffRNxRMEyR36DGBLJpeusFcgMVD9PZEzAKnUs1lKCgX5u9BmC2Yg+LL9MgZDugFFs1Vl+Jp4t/PGw==, - } - 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 - - "@radix-ui/react-direction@1.1.1": - resolution: - { - integrity: sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==, - } - peerDependencies: - "@types/react": "*" - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - "@types/react": - optional: true - - "@radix-ui/react-dismissable-layer@1.1.11": - resolution: - { - integrity: sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg==, - } - 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 - - "@radix-ui/react-dropdown-menu@2.1.16": - resolution: - { - integrity: sha512-1PLGQEynI/3OX/ftV54COn+3Sud/Mn8vALg2rWnBLnRaGtJDduNW/22XjlGgPdpcIbiQxjKtb7BkcjP00nqfJw==, - } - 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 - - "@radix-ui/react-focus-guards@1.1.3": - resolution: - { - integrity: sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw==, - } - peerDependencies: - "@types/react": "*" - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - "@types/react": - optional: true - - "@radix-ui/react-focus-scope@1.1.7": - resolution: - { - integrity: sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==, - } - 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 - - "@radix-ui/react-form@0.1.8": - resolution: - { - integrity: sha512-QM70k4Zwjttifr5a4sZFts9fn8FzHYvQ5PiB19O2HsYibaHSVt9fH9rzB0XZo/YcM+b7t/p7lYCT/F5eOeF5yQ==, - } - 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 - - "@radix-ui/react-hover-card@1.1.15": - resolution: - { - integrity: sha512-qgTkjNT1CfKMoP0rcasmlH2r1DAiYicWsDsufxl940sT2wHNEWWv6FMWIQXWhVdmC1d/HYfbhQx60KYyAtKxjg==, - } - 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 - - "@radix-ui/react-id@1.1.1": - resolution: - { - integrity: sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==, - } - peerDependencies: - "@types/react": "*" - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - "@types/react": - optional: true - - "@radix-ui/react-label@2.1.7": - resolution: - { - integrity: sha512-YT1GqPSL8kJn20djelMX7/cTRp/Y9w5IZHvfxQTVHrOqa2yMl7i/UfMqKRU5V7mEyKTrUVgJXhNQPVCG8PBLoQ==, - } - 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 - - "@radix-ui/react-menu@2.1.16": - resolution: - { - integrity: sha512-72F2T+PLlphrqLcAotYPp0uJMr5SjP5SL01wfEspJbru5Zs5vQaSHb4VB3ZMJPimgHHCHG7gMOeOB9H3Hdmtxg==, - } - 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 - - "@radix-ui/react-menubar@1.1.16": - resolution: - { - integrity: sha512-EB1FktTz5xRRi2Er974AUQZWg2yVBb1yjip38/lgwtCVRd3a+maUoGHN/xs9Yv8SY8QwbSEb+YrxGadVWbEutA==, - } - 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 - - "@radix-ui/react-navigation-menu@1.2.14": - resolution: - { - integrity: sha512-YB9mTFQvCOAQMHU+C/jVl96WmuWeltyUEpRJJky51huhds5W2FQr1J8D/16sQlf0ozxkPK8uF3niQMdUwZPv5w==, - } - 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 - - "@radix-ui/react-one-time-password-field@0.1.8": - resolution: - { - integrity: sha512-ycS4rbwURavDPVjCb5iS3aG4lURFDILi6sKI/WITUMZ13gMmn/xGjpLoqBAalhJaDk8I3UbCM5GzKHrnzwHbvg==, - } - 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 - - "@radix-ui/react-password-toggle-field@0.1.3": - resolution: - { - integrity: sha512-/UuCrDBWravcaMix4TdT+qlNdVwOM1Nck9kWx/vafXsdfj1ChfhOdfi3cy9SGBpWgTXwYCuboT/oYpJy3clqfw==, - } - 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 - - "@radix-ui/react-popover@1.1.15": - resolution: - { - integrity: sha512-kr0X2+6Yy/vJzLYJUPCZEc8SfQcf+1COFoAqauJm74umQhta9M7lNJHP7QQS3vkvcGLQUbWpMzwrXYwrYztHKA==, - } - 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 - - "@radix-ui/react-popper@1.2.8": - resolution: - { - integrity: sha512-0NJQ4LFFUuWkE7Oxf0htBKS6zLkkjBH+hM1uk7Ng705ReR8m/uelduy1DBo0PyBXPKVnBA6YBlU94MBGXrSBCw==, - } - 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 - - "@radix-ui/react-portal@1.1.9": - resolution: - { - integrity: sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==, - } - 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 - - "@radix-ui/react-presence@1.1.5": - resolution: - { - integrity: sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==, - } - 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 - - "@radix-ui/react-primitive@2.1.3": - resolution: - { - integrity: sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==, - } - 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 - - "@radix-ui/react-progress@1.1.7": - resolution: - { - integrity: sha512-vPdg/tF6YC/ynuBIJlk1mm7Le0VgW6ub6J2UWnTQ7/D23KXcPI1qy+0vBkgKgd38RCMJavBXpB83HPNFMTb0Fg==, - } - 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 - - "@radix-ui/react-radio-group@1.3.8": - resolution: - { - integrity: sha512-VBKYIYImA5zsxACdisNQ3BjCBfmbGH3kQlnFVqlWU4tXwjy7cGX8ta80BcrO+WJXIn5iBylEH3K6ZTlee//lgQ==, - } - 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 - - "@radix-ui/react-roving-focus@1.1.11": - resolution: - { - integrity: sha512-7A6S9jSgm/S+7MdtNDSb+IU859vQqJ/QAtcYQcfFC6W8RS4IxIZDldLR0xqCFZ6DCyrQLjLPsxtTNch5jVA4lA==, - } - 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 - - "@radix-ui/react-scroll-area@1.2.10": - resolution: - { - integrity: sha512-tAXIa1g3sM5CGpVT0uIbUx/U3Gs5N8T52IICuCtObaos1S8fzsrPXG5WObkQN3S6NVl6wKgPhAIiBGbWnvc97A==, - } - 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 - - "@radix-ui/react-select@2.2.6": - resolution: - { - integrity: sha512-I30RydO+bnn2PQztvo25tswPH+wFBjehVGtmagkU78yMdwTwVf12wnAOF+AeP8S2N8xD+5UPbGhkUfPyvT+mwQ==, - } - 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 - - "@radix-ui/react-separator@1.1.7": - resolution: - { - integrity: sha512-0HEb8R9E8A+jZjvmFCy/J4xhbXy3TV+9XSnGJ3KvTtjlIUy/YQ/p6UYZvi7YbeoeXdyU9+Y3scizK6hkY37baA==, - } - 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 - - "@radix-ui/react-slider@1.3.6": - resolution: - { - integrity: sha512-JPYb1GuM1bxfjMRlNLE+BcmBC8onfCi60Blk7OBqi2MLTFdS+8401U4uFjnwkOr49BLmXxLC6JHkvAsx5OJvHw==, - } - 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 - - "@radix-ui/react-slot@1.2.3": - resolution: - { - integrity: sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==, - } - peerDependencies: - "@types/react": "*" - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - "@types/react": - optional: true - - "@radix-ui/react-switch@1.2.6": - resolution: - { - integrity: sha512-bByzr1+ep1zk4VubeEVViV592vu2lHE2BZY5OnzehZqOOgogN80+mNtCqPkhn2gklJqOpxWgPoYTSnhBCqpOXQ==, - } - 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 - - "@radix-ui/react-tabs@1.1.13": - resolution: - { - integrity: sha512-7xdcatg7/U+7+Udyoj2zodtI9H/IIopqo+YOIcZOq1nJwXWBZ9p8xiu5llXlekDbZkca79a/fozEYQXIA4sW6A==, - } - 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 - - "@radix-ui/react-toast@1.2.15": - resolution: - { - integrity: sha512-3OSz3TacUWy4WtOXV38DggwxoqJK4+eDkNMl5Z/MJZaoUPaP4/9lf81xXMe1I2ReTAptverZUpbPY4wWwWyL5g==, - } - 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 - - "@radix-ui/react-toggle-group@1.1.11": - resolution: - { - integrity: sha512-5umnS0T8JQzQT6HbPyO7Hh9dgd82NmS36DQr+X/YJ9ctFNCiiQd6IJAYYZ33LUwm8M+taCz5t2ui29fHZc4Y6Q==, - } - 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 - - "@radix-ui/react-toggle@1.1.10": - resolution: - { - integrity: sha512-lS1odchhFTeZv3xwHH31YPObmJn8gOg7Lq12inrr0+BH/l3Tsq32VfjqH1oh80ARM3mlkfMic15n0kg4sD1poQ==, - } - 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 - - "@radix-ui/react-toolbar@1.1.11": - resolution: - { - integrity: sha512-4ol06/1bLoFu1nwUqzdD4Y5RZ9oDdKeiHIsntug54Hcr1pgaHiPqHFEaXI1IFP/EsOfROQZ8Mig9VTIRza6Tjg==, - } - 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 - - "@radix-ui/react-tooltip@1.2.8": - resolution: - { - integrity: sha512-tY7sVt1yL9ozIxvmbtN5qtmH2krXcBCfjEiCgKGLqunJHvgvZG2Pcl2oQ3kbcZARb1BGEHdkLzcYGO8ynVlieg==, - } - 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 - - "@radix-ui/react-use-callback-ref@1.1.1": - resolution: - { - integrity: sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==, - } - peerDependencies: - "@types/react": "*" - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - "@types/react": - optional: true - - "@radix-ui/react-use-controllable-state@1.2.2": - resolution: - { - integrity: sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==, - } - peerDependencies: - "@types/react": "*" - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - "@types/react": - optional: true - - "@radix-ui/react-use-effect-event@0.0.2": - resolution: - { - integrity: sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==, - } - peerDependencies: - "@types/react": "*" - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - "@types/react": - optional: true - - "@radix-ui/react-use-escape-keydown@1.1.1": - resolution: - { - integrity: sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==, - } - peerDependencies: - "@types/react": "*" - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - "@types/react": - optional: true - - "@radix-ui/react-use-is-hydrated@0.1.0": - resolution: - { - integrity: sha512-U+UORVEq+cTnRIaostJv9AGdV3G6Y+zbVd+12e18jQ5A3c0xL03IhnHuiU4UV69wolOQp5GfR58NW/EgdQhwOA==, - } - peerDependencies: - "@types/react": "*" - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - "@types/react": - optional: true - - "@radix-ui/react-use-layout-effect@1.1.1": - resolution: - { - integrity: sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==, - } - peerDependencies: - "@types/react": "*" - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - "@types/react": - optional: true - - "@radix-ui/react-use-previous@1.1.1": - resolution: - { - integrity: sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ==, - } - peerDependencies: - "@types/react": "*" - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - "@types/react": - optional: true - - "@radix-ui/react-use-rect@1.1.1": - resolution: - { - integrity: sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w==, - } - peerDependencies: - "@types/react": "*" - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - "@types/react": - optional: true - - "@radix-ui/react-use-size@1.1.1": - resolution: - { - integrity: sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ==, - } - peerDependencies: - "@types/react": "*" - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - "@types/react": - optional: true - - "@radix-ui/react-visually-hidden@1.2.3": - resolution: - { - integrity: sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug==, - } - 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 - - "@radix-ui/rect@1.1.1": - resolution: - { - integrity: sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==, - } - - "@rolldown/binding-android-arm64@1.0.0-beta.41": - resolution: - { - integrity: sha512-Edflndd9lU7JVhVIvJlZhdCj5DkhYDJPIRn4Dx0RUdfc8asP9xHOI5gMd8MesDDx+BJpdIT/uAmVTearteU/mQ==, - } - engines: { node: ^20.19.0 || >=22.12.0 } - cpu: [arm64] - os: [android] - - "@rolldown/binding-darwin-arm64@1.0.0-beta.41": - resolution: - { - integrity: sha512-XGCzqfjdk7550PlyZRTBKbypXrB7ATtXhw/+bjtxnklLQs0mKP/XkQVOKyn9qGKSlvH8I56JLYryVxl0PCvSNw==, - } - engines: { node: ^20.19.0 || >=22.12.0 } - cpu: [arm64] - os: [darwin] - - "@rolldown/binding-darwin-x64@1.0.0-beta.41": - resolution: - { - integrity: sha512-Ho6lIwGJed98zub7n0xcRKuEtnZgbxevAmO4x3zn3C3N4GVXZD5xvCvTVxSMoeBJwTcIYzkVDRTIhylQNsTgLQ==, - } - engines: { node: ^20.19.0 || >=22.12.0 } - cpu: [x64] - os: [darwin] - - "@rolldown/binding-freebsd-x64@1.0.0-beta.41": - resolution: - { - integrity: sha512-ijAZETywvL+gACjbT4zBnCp5ez1JhTRs6OxRN4J+D6AzDRbU2zb01Esl51RP5/8ZOlvB37xxsRQ3X4YRVyYb3g==, - } - engines: { node: ^20.19.0 || >=22.12.0 } - cpu: [x64] - os: [freebsd] - - "@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.41": - resolution: - { - integrity: sha512-EgIOZt7UildXKFEFvaiLNBXm+4ggQyGe3E5Z1QP9uRcJJs9omihOnm897FwOBQdCuMvI49iBgjFrkhH+wMJ2MA==, - } - engines: { node: ^20.19.0 || >=22.12.0 } - cpu: [arm] - os: [linux] - - "@rolldown/binding-linux-arm64-gnu@1.0.0-beta.41": - resolution: - { - integrity: sha512-F8bUwJq8v/JAU8HSwgF4dztoqJ+FjdyjuvX4//3+Fbe2we9UktFeZ27U4lRMXF1vxWtdV4ey6oCSqI7yUrSEeg==, - } - engines: { node: ^20.19.0 || >=22.12.0 } - cpu: [arm64] - os: [linux] - - "@rolldown/binding-linux-arm64-musl@1.0.0-beta.41": - resolution: - { - integrity: sha512-MioXcCIX/wB1pBnBoJx8q4OGucUAfC1+/X1ilKFsjDK05VwbLZGRgOVD5OJJpUQPK86DhQciNBrfOKDiatxNmg==, - } - engines: { node: ^20.19.0 || >=22.12.0 } - cpu: [arm64] - os: [linux] - - "@rolldown/binding-linux-x64-gnu@1.0.0-beta.41": - resolution: - { - integrity: sha512-m66M61fizvRCwt5pOEiZQMiwBL9/y0bwU/+Kc4Ce/Pef6YfoEkR28y+DzN9rMdjo8Z28NXjsDPq9nH4mXnAP0g==, - } - engines: { node: ^20.19.0 || >=22.12.0 } - cpu: [x64] - os: [linux] - - "@rolldown/binding-linux-x64-musl@1.0.0-beta.41": - resolution: - { - integrity: sha512-yRxlSfBvWnnfrdtJfvi9lg8xfG5mPuyoSHm0X01oiE8ArmLRvoJGHUTJydCYz+wbK2esbq5J4B4Tq9WAsOlP1Q==, - } - engines: { node: ^20.19.0 || >=22.12.0 } - cpu: [x64] - os: [linux] - - "@rolldown/binding-openharmony-arm64@1.0.0-beta.41": - resolution: - { - integrity: sha512-PHVxYhBpi8UViS3/hcvQQb9RFqCtvFmFU1PvUoTRiUdBtgHA6fONNHU4x796lgzNlVSD3DO/MZNk1s5/ozSMQg==, - } - engines: { node: ^20.19.0 || >=22.12.0 } - cpu: [arm64] - os: [openharmony] - - "@rolldown/binding-wasm32-wasi@1.0.0-beta.41": - resolution: - { - integrity: sha512-OAfcO37ME6GGWmj9qTaDT7jY4rM0T2z0/8ujdQIJQ2x2nl+ztO32EIwURfmXOK0U1tzkyuaKYvE34Pug/ucXlQ==, - } - engines: { node: ">=14.0.0" } - cpu: [wasm32] - - "@rolldown/binding-win32-arm64-msvc@1.0.0-beta.41": - resolution: - { - integrity: sha512-NIYGuCcuXaq5BC4Q3upbiMBvmZsTsEPG9k/8QKQdmrch+ocSy5Jv9tdpdmXJyighKqm182nh/zBt+tSJkYoNlg==, - } - engines: { node: ^20.19.0 || >=22.12.0 } - cpu: [arm64] - os: [win32] - - "@rolldown/binding-win32-ia32-msvc@1.0.0-beta.41": - resolution: - { - integrity: sha512-kANdsDbE5FkEOb5NrCGBJBCaZ2Sabp3D7d4PRqMYJqyLljwh9mDyYyYSv5+QNvdAmifj+f3lviNEUUuUZPEFPw==, - } - engines: { node: ^20.19.0 || >=22.12.0 } - cpu: [ia32] - os: [win32] - - "@rolldown/binding-win32-x64-msvc@1.0.0-beta.41": - resolution: - { - integrity: sha512-UlpxKmFdik0Y2VjZrgUCgoYArZJiZllXgIipdBRV1hw6uK45UbQabSTW6Kp6enuOu7vouYWftwhuxfpE8J2JAg==, - } - engines: { node: ^20.19.0 || >=22.12.0 } - cpu: [x64] - os: [win32] - - "@rolldown/pluginutils@1.0.0-beta.41": - resolution: - { - integrity: sha512-ycMEPrS3StOIeb87BT3/+bu+blEtyvwQ4zmo2IcJQy0Rd1DAAhKksA0iUZ3MYSpJtjlPhg0Eo6mvVS6ggPhRbw==, - } - - "@rolldown/pluginutils@1.0.0-beta.43": - resolution: - { - integrity: sha512-5Uxg7fQUCmfhax7FJke2+8B6cqgeUJUD9o2uXIKXhD+mG0mL6NObmVoi9wXEU1tY89mZKgAYA6fTbftx3q2ZPQ==, - } - - "@standard-schema/utils@0.3.0": - resolution: - { - integrity: sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==, - } - - "@swc/core-darwin-arm64@1.14.0": - resolution: - { - integrity: sha512-uHPC8rlCt04nvYNczWzKVdgnRhxCa3ndKTBBbBpResOZsRmiwRAvByIGh599j+Oo6Z5eyTPrgY+XfJzVmXnN7Q==, - } - engines: { node: ">=10" } - cpu: [arm64] - os: [darwin] - - "@swc/core-darwin-x64@1.14.0": - resolution: - { - integrity: sha512-2SHrlpl68vtePRknv9shvM9YKKg7B9T13tcTg9aFCwR318QTYo+FzsKGmQSv9ox/Ua0Q2/5y2BNjieffJoo4nA==, - } - engines: { node: ">=10" } - cpu: [x64] - os: [darwin] - - "@swc/core-linux-arm-gnueabihf@1.14.0": - resolution: - { - integrity: sha512-SMH8zn01dxt809svetnxpeg/jWdpi6dqHKO3Eb11u4OzU2PK7I5uKS6gf2hx5LlTbcJMFKULZiVwjlQLe8eqtg==, - } - engines: { node: ">=10" } - cpu: [arm] - os: [linux] - - "@swc/core-linux-arm64-gnu@1.14.0": - resolution: - { - integrity: sha512-q2JRu2D8LVqGeHkmpVCljVNltG0tB4o4eYg+dElFwCS8l2Mnt9qurMCxIeo9mgoqz0ax+k7jWtIRHktnVCbjvQ==, - } - engines: { node: ">=10" } - cpu: [arm64] - os: [linux] - - "@swc/core-linux-arm64-musl@1.14.0": - resolution: - { - integrity: sha512-uofpVoPCEUjYIv454ZEZ3sLgMD17nIwlz2z7bsn7rl301Kt/01umFA7MscUovFfAK2IRGck6XB+uulMu6aFhKQ==, - } - engines: { node: ">=10" } - cpu: [arm64] - os: [linux] - - "@swc/core-linux-x64-gnu@1.14.0": - resolution: - { - integrity: sha512-quTTx1Olm05fBfv66DEBuOsOgqdypnZ/1Bh3yGXWY7ANLFeeRpCDZpljD9BSjdsNdPOlwJmEUZXMHtGm3v1TZQ==, - } - engines: { node: ">=10" } - cpu: [x64] - os: [linux] - - "@swc/core-linux-x64-musl@1.14.0": - resolution: - { - integrity: sha512-caaNAu+aIqT8seLtCf08i8C3/UC5ttQujUjejhMcuS1/LoCKtNiUs4VekJd2UGt+pyuuSrQ6dKl8CbCfWvWeXw==, - } - engines: { node: ">=10" } - cpu: [x64] - os: [linux] - - "@swc/core-win32-arm64-msvc@1.14.0": - resolution: - { - integrity: sha512-EeW3jFlT3YNckJ6V/JnTfGcX7UHGyh6/AiCPopZ1HNaGiXVCKHPpVQZicmtyr/UpqxCXLrTgjHOvyMke7YN26A==, - } - engines: { node: ">=10" } - cpu: [arm64] - os: [win32] - - "@swc/core-win32-ia32-msvc@1.14.0": - resolution: - { - integrity: sha512-dPai3KUIcihV5hfoO4QNQF5HAaw8+2bT7dvi8E5zLtecW2SfL3mUZipzampXq5FHll0RSCLzlrXnSx+dBRZIIQ==, - } - engines: { node: ">=10" } - cpu: [ia32] - os: [win32] - - "@swc/core-win32-x64-msvc@1.14.0": - resolution: - { - integrity: sha512-nm+JajGrTqUA6sEHdghDlHMNfH1WKSiuvljhdmBACW4ta4LC3gKurX2qZuiBARvPkephW9V/i5S8QPY1PzFEqg==, - } - engines: { node: ">=10" } - cpu: [x64] - os: [win32] - - "@swc/core@1.14.0": - resolution: - { - integrity: sha512-oExhY90bes5pDTVrei0xlMVosTxwd/NMafIpqsC4dMbRYZ5KB981l/CX8tMnGsagTplj/RcG9BeRYmV6/J5m3w==, - } - engines: { node: ">=10" } - peerDependencies: - "@swc/helpers": ">=0.5.17" - peerDependenciesMeta: - "@swc/helpers": - optional: true - - "@swc/counter@0.1.3": - resolution: - { - integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==, - } - - "@swc/types@0.1.25": - resolution: - { - integrity: sha512-iAoY/qRhNH8a/hBvm3zKj9qQ4oc2+3w1unPJa2XvTK3XjeLXtzcCingVPw/9e5mn1+0yPqxcBGp9Jf0pkfMb1g==, - } - - "@tailwindcss/node@4.1.16": - resolution: - { - integrity: sha512-BX5iaSsloNuvKNHRN3k2RcCuTEgASTo77mofW0vmeHkfrDWaoFAFvNHpEgtu0eqyypcyiBkDWzSMxJhp3AUVcw==, - } - - "@tailwindcss/oxide-android-arm64@4.1.16": - resolution: - { - integrity: sha512-8+ctzkjHgwDJ5caq9IqRSgsP70xhdhJvm+oueS/yhD5ixLhqTw9fSL1OurzMUhBwE5zK26FXLCz2f/RtkISqHA==, - } - engines: { node: ">= 10" } - cpu: [arm64] - os: [android] - - "@tailwindcss/oxide-darwin-arm64@4.1.16": - resolution: - { - integrity: sha512-C3oZy5042v2FOALBZtY0JTDnGNdS6w7DxL/odvSny17ORUnaRKhyTse8xYi3yKGyfnTUOdavRCdmc8QqJYwFKA==, - } - engines: { node: ">= 10" } - cpu: [arm64] - os: [darwin] - - "@tailwindcss/oxide-darwin-x64@4.1.16": - resolution: - { - integrity: sha512-vjrl/1Ub9+JwU6BP0emgipGjowzYZMjbWCDqwA2Z4vCa+HBSpP4v6U2ddejcHsolsYxwL5r4bPNoamlV0xDdLg==, - } - engines: { node: ">= 10" } - cpu: [x64] - os: [darwin] - - "@tailwindcss/oxide-freebsd-x64@4.1.16": - resolution: - { - integrity: sha512-TSMpPYpQLm+aR1wW5rKuUuEruc/oOX3C7H0BTnPDn7W/eMw8W+MRMpiypKMkXZfwH8wqPIRKppuZoedTtNj2tg==, - } - engines: { node: ">= 10" } - cpu: [x64] - os: [freebsd] - - "@tailwindcss/oxide-linux-arm-gnueabihf@4.1.16": - resolution: - { - integrity: sha512-p0GGfRg/w0sdsFKBjMYvvKIiKy/LNWLWgV/plR4lUgrsxFAoQBFrXkZ4C0w8IOXfslB9vHK/JGASWD2IefIpvw==, - } - engines: { node: ">= 10" } - cpu: [arm] - os: [linux] - - "@tailwindcss/oxide-linux-arm64-gnu@4.1.16": - resolution: - { - integrity: sha512-DoixyMmTNO19rwRPdqviTrG1rYzpxgyYJl8RgQvdAQUzxC1ToLRqtNJpU/ATURSKgIg6uerPw2feW0aS8SNr/w==, - } - engines: { node: ">= 10" } - cpu: [arm64] - os: [linux] - - "@tailwindcss/oxide-linux-arm64-musl@4.1.16": - resolution: - { - integrity: sha512-H81UXMa9hJhWhaAUca6bU2wm5RRFpuHImrwXBUvPbYb+3jo32I9VIwpOX6hms0fPmA6f2pGVlybO6qU8pF4fzQ==, - } - engines: { node: ">= 10" } - cpu: [arm64] - os: [linux] - - "@tailwindcss/oxide-linux-x64-gnu@4.1.16": - resolution: - { - integrity: sha512-ZGHQxDtFC2/ruo7t99Qo2TTIvOERULPl5l0K1g0oK6b5PGqjYMga+FcY1wIUnrUxY56h28FxybtDEla+ICOyew==, - } - engines: { node: ">= 10" } - cpu: [x64] - os: [linux] - - "@tailwindcss/oxide-linux-x64-musl@4.1.16": - resolution: - { - integrity: sha512-Oi1tAaa0rcKf1Og9MzKeINZzMLPbhxvm7rno5/zuP1WYmpiG0bEHq4AcRUiG2165/WUzvxkW4XDYCscZWbTLZw==, - } - engines: { node: ">= 10" } - cpu: [x64] - os: [linux] - - "@tailwindcss/oxide-wasm32-wasi@4.1.16": - resolution: - { - integrity: sha512-B01u/b8LteGRwucIBmCQ07FVXLzImWESAIMcUU6nvFt/tYsQ6IHz8DmZ5KtvmwxD+iTYBtM1xwoGXswnlu9v0Q==, - } - engines: { node: ">=14.0.0" } - cpu: [wasm32] - bundledDependencies: - - "@napi-rs/wasm-runtime" - - "@emnapi/core" - - "@emnapi/runtime" - - "@tybys/wasm-util" - - "@emnapi/wasi-threads" - - tslib - - "@tailwindcss/oxide-win32-arm64-msvc@4.1.16": - resolution: - { - integrity: sha512-zX+Q8sSkGj6HKRTMJXuPvOcP8XfYON24zJBRPlszcH1Np7xuHXhWn8qfFjIujVzvH3BHU+16jBXwgpl20i+v9A==, - } - engines: { node: ">= 10" } - cpu: [arm64] - os: [win32] - - "@tailwindcss/oxide-win32-x64-msvc@4.1.16": - resolution: - { - integrity: sha512-m5dDFJUEejbFqP+UXVstd4W/wnxA4F61q8SoL+mqTypId2T2ZpuxosNSgowiCnLp2+Z+rivdU0AqpfgiD7yCBg==, - } - engines: { node: ">= 10" } - cpu: [x64] - os: [win32] - - "@tailwindcss/oxide@4.1.16": - resolution: - { - integrity: sha512-2OSv52FRuhdlgyOQqgtQHuCgXnS8nFSYRp2tJ+4WZXKgTxqPy7SMSls8c3mPT5pkZ17SBToGM5LHEJBO7miEdg==, - } - engines: { node: ">= 10" } - - "@tailwindcss/vite@4.1.16": - resolution: - { - integrity: sha512-bbguNBcDxsRmi9nnlWJxhfDWamY3lmcyACHcdO1crxfzuLpOhHLLtEIN/nCbbAtj5rchUgQD17QVAKi1f7IsKg==, - } - peerDependencies: - vite: ^5.2.0 || ^6 || ^7 - - "@tanstack/history@1.133.28": - resolution: - { - integrity: sha512-B7+x7eP2FFvi3fgd3rNH9o/Eixt+pp0zCIdGhnQbAJjFrlwIKGjGnwyJjhWJ5fMQlGks/E2LdDTqEV4W9Plx7g==, - } - engines: { node: ">=12" } - - "@tanstack/query-core@5.90.6": - resolution: - { - integrity: sha512-AnZSLF26R8uX+tqb/ivdrwbVdGemdEDm1Q19qM6pry6eOZ6bEYiY7mWhzXT1YDIPTNEVcZ5kYP9nWjoxDLiIVw==, - } - - "@tanstack/react-query@5.90.6": - resolution: - { - integrity: sha512-gB1sljYjcobZKxjPbKSa31FUTyr+ROaBdoH+wSSs9Dk+yDCmMs+TkTV3PybRRVLC7ax7q0erJ9LvRWnMktnRAw==, - } - peerDependencies: - react: ^18 || ^19 - - "@tanstack/react-router@1.134.9": - resolution: - { - integrity: sha512-JIxFamShs3gRIkOxpgz/3bglbSKZHMrzKASwNFg+sQPVXVPOLtN35D5PuEDAFTPPht9Wv48WWUNYE03ZytnNug==, - } - engines: { node: ">=12" } - peerDependencies: - react: ">=18.0.0 || >=19.0.0" - react-dom: ">=18.0.0 || >=19.0.0" - - "@tanstack/react-store@0.8.0": - resolution: - { - integrity: sha512-1vG9beLIuB7q69skxK9r5xiLN3ztzIPfSQSs0GfeqWGO2tGIyInZx0x1COhpx97RKaONSoAb8C3dxacWksm1ow==, - } - peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - - "@tanstack/router-cli@1.134.9": - resolution: - { - integrity: sha512-5aE55UaaJcP9Pi1UArlpOQzyGK4JKAfES/toNrc+HDVpNqyhFegZWCumxgdauHFU13YjQXZJAi2dn0ITfD7lFw==, - } - engines: { node: ">=12" } - hasBin: true - - "@tanstack/router-core@1.134.9": - resolution: - { - integrity: sha512-9Vr8tYC59I70DYGVRknRf4vjQMjSfHvmc+iTM8vcpwERBh3Vgkv90f8ol85KHKqjorSsCqMeYFhFt8AM4A4CSw==, - } - engines: { node: ">=12" } - - "@tanstack/router-generator@1.134.9": - resolution: - { - integrity: sha512-yBPX/xCWE/sdEEtCKOtPBl4cQo+G5Tt7UTB0li49CW8qhmD2eFKTQY1enRb68SwFNH5uwToBXFmJkSG1zPaA5Q==, - } - engines: { node: ">=12" } - - "@tanstack/router-plugin@1.134.9": - resolution: - { - integrity: sha512-iD85GvRADpVhRXkVGRwJqprhIXPLNH+O210UjFDQ8RC2Vn92IwKY6sx8fCgwjHtcYgnTdu3p8eIYJ8CfrLazxA==, - } - engines: { node: ">=12" } - peerDependencies: - "@rsbuild/core": ">=1.0.2" - "@tanstack/react-router": ^1.134.9 - vite: ">=5.0.0 || >=6.0.0 || >=7.0.0" - vite-plugin-solid: ^2.11.10 - webpack: ">=5.92.0" - peerDependenciesMeta: - "@rsbuild/core": - optional: true - "@tanstack/react-router": - optional: true - vite: - optional: true - vite-plugin-solid: - optional: true - webpack: - optional: true - - "@tanstack/router-utils@1.133.19": - resolution: - { - integrity: sha512-WEp5D2gPxvlLDRXwD/fV7RXjYtqaqJNXKB/L6OyZEbT+9BG/Ib2d7oG9GSUZNNMGPGYAlhBUOi3xutySsk6rxA==, - } - engines: { node: ">=12" } - - "@tanstack/store@0.8.0": - resolution: - { - integrity: sha512-Om+BO0YfMZe//X2z0uLF2j+75nQga6TpTJgLJQBiq85aOyZNIhkCgleNcud2KQg4k4v9Y9l+Uhru3qWMPGTOzQ==, - } - - "@tanstack/virtual-file-routes@1.133.19": - resolution: - { - integrity: sha512-IKwZENsK7owmW1Lm5FhuHegY/SyQ8KqtL/7mTSnzoKJgfzhrrf9qwKB1rmkKkt+svUuy/Zw3uVEpZtUzQruWtA==, - } - engines: { node: ">=12" } - - "@trpc/client@11.7.1": - resolution: - { - integrity: sha512-uOnAjElKI892/U6aQMcBHYs3x7mme3Cvv1F87ytBL56rBvs7+DyK7r43zgaXKf13+GtPEI6ex5xjVUfyDW8XcQ==, - } - peerDependencies: - "@trpc/server": 11.7.1 - typescript: ">=5.7.2" - - "@trpc/react-query@11.7.1": - resolution: - { - integrity: sha512-dEHDjIqSTzO8nLlCbtiFBMBwhbSkK1QP7aYVo3nP3sYBna0b+iCtrPXdxVPCSopr9/aIqDTEh+dMRZa7yBgjfQ==, - } - peerDependencies: - "@tanstack/react-query": ^5.80.3 - "@trpc/client": 11.7.1 - "@trpc/server": 11.7.1 - react: ">=18.2.0" - react-dom: ">=18.2.0" - typescript: ">=5.7.2" - - "@trpc/server@11.7.1": - resolution: - { - integrity: sha512-N3U8LNLIP4g9C7LJ/sLkjuPHwqlvE3bnspzC4DEFVdvx2+usbn70P80E3wj5cjOTLhmhRiwJCSXhlB+MHfGeCw==, - } - peerDependencies: - typescript: ">=5.7.2" - - "@tybys/wasm-util@0.10.1": - resolution: - { - integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==, - } - - "@types/babel__core@7.20.5": - resolution: - { - integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==, - } - - "@types/babel__generator@7.27.0": - resolution: - { - integrity: sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==, - } - - "@types/babel__template@7.4.4": - resolution: - { - integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==, - } - - "@types/babel__traverse@7.28.0": - resolution: - { - integrity: sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==, - } - - "@types/estree@1.0.8": - resolution: - { - integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==, - } - - "@types/json-schema@7.0.15": - resolution: - { - integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==, - } - - "@types/node@24.9.2": - resolution: - { - integrity: sha512-uWN8YqxXxqFMX2RqGOrumsKeti4LlmIMIyV0lgut4jx7KQBcBiW6vkDtIBvHnHIquwNfJhk8v2OtmO8zXWHfPA==, - } - - "@types/react-dom@19.2.2": - resolution: - { - integrity: sha512-9KQPoO6mZCi7jcIStSnlOWn2nEF3mNmyr3rIAsGnAbQKYbRLyqmeSc39EVgtxXVia+LMT8j3knZLAZAh+xLmrw==, - } - peerDependencies: - "@types/react": ^19.2.0 - - "@types/react@19.2.2": - resolution: - { - integrity: sha512-6mDvHUFSjyT2B2yeNx2nUgMxh9LtOWvkhIU3uePn2I2oyNymUAX1NIsdgviM4CH+JSrp2D2hsMvJOkxY+0wNRA==, - } - - "@typescript-eslint/eslint-plugin@8.46.2": - resolution: - { - integrity: sha512-ZGBMToy857/NIPaaCucIUQgqueOiq7HeAKkhlvqVV4lm089zUFW6ikRySx2v+cAhKeUCPuWVHeimyk6Dw1iY3w==, - } - engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } - peerDependencies: - "@typescript-eslint/parser": ^8.46.2 - eslint: ^8.57.0 || ^9.0.0 - typescript: ">=4.8.4 <6.0.0" - - "@typescript-eslint/parser@8.46.2": - resolution: - { - integrity: sha512-BnOroVl1SgrPLywqxyqdJ4l3S2MsKVLDVxZvjI1Eoe8ev2r3kGDo+PcMihNmDE+6/KjkTubSJnmqGZZjQSBq/g==, - } - engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: ">=4.8.4 <6.0.0" - - "@typescript-eslint/project-service@8.46.2": - resolution: - { - integrity: sha512-PULOLZ9iqwI7hXcmL4fVfIsBi6AN9YxRc0frbvmg8f+4hQAjQ5GYNKK0DIArNo+rOKmR/iBYwkpBmnIwin4wBg==, - } - engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } - peerDependencies: - typescript: ">=4.8.4 <6.0.0" - - "@typescript-eslint/scope-manager@8.46.2": - resolution: - { - integrity: sha512-LF4b/NmGvdWEHD2H4MsHD8ny6JpiVNDzrSZr3CsckEgCbAGZbYM4Cqxvi9L+WqDMT+51Ozy7lt2M+d0JLEuBqA==, - } - engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } - - "@typescript-eslint/tsconfig-utils@8.46.2": - resolution: - { - integrity: sha512-a7QH6fw4S57+F5y2FIxxSDyi5M4UfGF+Jl1bCGd7+L4KsaUY80GsiF/t0UoRFDHAguKlBaACWJRmdrc6Xfkkag==, - } - engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } - peerDependencies: - typescript: ">=4.8.4 <6.0.0" - - "@typescript-eslint/type-utils@8.46.2": - resolution: - { - integrity: sha512-HbPM4LbaAAt/DjxXaG9yiS9brOOz6fabal4uvUmaUYe6l3K1phQDMQKBRUrr06BQkxkvIZVVHttqiybM9nJsLA==, - } - engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: ">=4.8.4 <6.0.0" - - "@typescript-eslint/types@8.46.2": - resolution: - { - integrity: sha512-lNCWCbq7rpg7qDsQrd3D6NyWYu+gkTENkG5IKYhUIcxSb59SQC/hEQ+MrG4sTgBVghTonNWq42bA/d4yYumldQ==, - } - engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } - - "@typescript-eslint/typescript-estree@8.46.2": - resolution: - { - integrity: sha512-f7rW7LJ2b7Uh2EiQ+7sza6RDZnajbNbemn54Ob6fRwQbgcIn+GWfyuHDHRYgRoZu1P4AayVScrRW+YfbTvPQoQ==, - } - engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } - peerDependencies: - typescript: ">=4.8.4 <6.0.0" - - "@typescript-eslint/utils@8.46.2": - resolution: - { - integrity: sha512-sExxzucx0Tud5tE0XqR0lT0psBQvEpnpiul9XbGUB1QwpWJJAps1O/Z7hJxLGiZLBKMCutjTzDgmd1muEhBnVg==, - } - engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: ">=4.8.4 <6.0.0" - - "@typescript-eslint/visitor-keys@8.46.2": - resolution: - { - integrity: sha512-tUFMXI4gxzzMXt4xpGJEsBsTox0XbNQ1y94EwlD/CuZwFcQP79xfQqMhau9HsRc/J0cAPA/HZt1dZPtGn9V/7w==, - } - engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } - - "@vitejs/plugin-react-swc@4.2.0": - resolution: - { - integrity: sha512-/tesahXD1qpkGC6FzMoFOJj0RyZdw9xLELOL+6jbElwmWfwOnIVy+IfpY+o9JfD9PKaR/Eyb6DNrvbXpuvA+8Q==, - } - engines: { node: ^20.19.0 || >=22.12.0 } - peerDependencies: - vite: ^4 || ^5 || ^6 || ^7 - - "@vitejs/plugin-react@5.1.0": - resolution: - { - integrity: sha512-4LuWrg7EKWgQaMJfnN+wcmbAW+VSsCmqGohftWjuct47bv8uE4n/nPpq4XjJPsxgq00GGG5J8dvBczp8uxScew==, - } - engines: { node: ^20.19.0 || >=22.12.0 } - peerDependencies: - vite: ^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 - - acorn-jsx@5.3.2: - resolution: - { - integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==, - } - peerDependencies: - acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - - acorn@8.15.0: - resolution: - { - integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==, - } - engines: { node: ">=0.4.0" } - hasBin: true - - ajv@6.12.6: - resolution: - { - integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==, - } - - ansi-regex@5.0.1: - resolution: - { - integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==, - } - engines: { node: ">=8" } - - ansi-styles@4.3.0: - resolution: - { - integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==, - } - engines: { node: ">=8" } - - ansis@4.2.0: - resolution: - { - integrity: sha512-HqZ5rWlFjGiV0tDm3UxxgNRqsOTniqoKZu0pIAfh7TZQMGuZK+hH0drySty0si0QXj1ieop4+SkSfPZBPPkHig==, - } - engines: { node: ">=14" } - - anymatch@3.1.3: - resolution: - { - integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==, - } - engines: { node: ">= 8" } - - argparse@2.0.1: - resolution: - { - integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==, - } - - aria-hidden@1.2.6: - resolution: - { - integrity: sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==, - } - engines: { node: ">=10" } - - ast-types@0.16.1: - resolution: - { - integrity: sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==, - } - engines: { node: ">=4" } - - babel-dead-code-elimination@1.0.10: - resolution: - { - integrity: sha512-DV5bdJZTzZ0zn0DC24v3jD7Mnidh6xhKa4GfKCbq3sfW8kaWhDdZjP3i81geA8T33tdYqWKw4D3fVv0CwEgKVA==, - } - - balanced-match@1.0.2: - resolution: - { - integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==, - } - - baseline-browser-mapping@2.8.23: - resolution: - { - integrity: sha512-616V5YX4bepJFzNyOfce5Fa8fDJMfoxzOIzDCZwaGL8MKVpFrXqfNUoIpRn9YMI5pXf/VKgzjB4htFMsFKKdiQ==, - } - hasBin: true - - binary-extensions@2.3.0: - resolution: - { - integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==, - } - engines: { node: ">=8" } - - brace-expansion@1.1.12: - resolution: - { - integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==, - } - - brace-expansion@2.0.2: - resolution: - { - integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==, - } - - braces@3.0.3: - resolution: - { - integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==, - } - engines: { node: ">=8" } - - browserslist@4.27.0: - resolution: - { - integrity: sha512-AXVQwdhot1eqLihwasPElhX2tAZiBjWdJ9i/Zcj2S6QYIjkx62OKSfnobkriB81C3l4w0rVy3Nt4jaTBltYEpw==, - } - engines: { node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7 } - hasBin: true - - callsites@3.1.0: - resolution: - { - integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==, - } - engines: { node: ">=6" } - - caniuse-lite@1.0.30001753: - resolution: - { - integrity: sha512-Bj5H35MD/ebaOV4iDLqPEtiliTN29qkGtEHCwawWn4cYm+bPJM2NsaP30vtZcnERClMzp52J4+aw2UNbK4o+zw==, - } - - chalk@4.1.2: - resolution: - { - integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==, - } - engines: { node: ">=10" } - - chokidar@3.6.0: - resolution: - { - integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==, - } - engines: { node: ">= 8.10.0" } - - class-variance-authority@0.7.1: - resolution: - { - integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==, - } - - cliui@8.0.1: - resolution: - { - integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==, - } - engines: { node: ">=12" } - - clsx@2.1.1: - resolution: - { - integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==, - } - engines: { node: ">=6" } - - color-convert@2.0.1: - resolution: - { - integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==, - } - engines: { node: ">=7.0.0" } - - color-name@1.1.4: - resolution: - { - integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==, - } - - concat-map@0.0.1: - resolution: - { - integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==, - } - - convert-source-map@2.0.0: - resolution: - { - integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==, - } - - cookie-es@2.0.0: - resolution: - { - integrity: sha512-RAj4E421UYRgqokKUmotqAwuplYw15qtdXfY+hGzgCJ/MBjCVZcSoHK/kH9kocfjRjcDME7IiDWR/1WX1TM2Pg==, - } - - cross-spawn@7.0.6: - resolution: - { - integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==, - } - engines: { node: ">= 8" } - - csstype@3.1.3: - resolution: - { - integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==, - } - - debug@4.4.3: - resolution: - { - integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==, - } - engines: { node: ">=6.0" } - peerDependencies: - supports-color: "*" - peerDependenciesMeta: - supports-color: - optional: true - - deep-is@0.1.4: - resolution: - { - integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==, - } - - detect-libc@2.1.2: - resolution: - { - integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==, - } - engines: { node: ">=8" } - - detect-node-es@1.1.0: - resolution: - { - integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==, - } - - diff@8.0.2: - resolution: - { - integrity: sha512-sSuxWU5j5SR9QQji/o2qMvqRNYRDOcBTgsJ/DeCf4iSN4gW+gNMXM7wFIP+fdXZxoNiAnHUTGjCr+TSWXdRDKg==, - } - engines: { node: ">=0.3.1" } - - electron-to-chromium@1.5.244: - resolution: - { - integrity: sha512-OszpBN7xZX4vWMPJwB9illkN/znA8M36GQqQxi6MNy9axWxhOfJyZZJtSLQCpEFLHP2xK33BiWx9aIuIEXVCcw==, - } - - emoji-regex@8.0.0: - resolution: - { - integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==, - } - - enhanced-resolve@5.18.3: - resolution: - { - integrity: sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==, - } - engines: { node: ">=10.13.0" } - - esbuild@0.25.12: - resolution: - { - integrity: sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==, - } - engines: { node: ">=18" } - hasBin: true - - escalade@3.2.0: - resolution: - { - integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==, - } - engines: { node: ">=6" } - - escape-string-regexp@4.0.0: - resolution: - { - integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==, - } - engines: { node: ">=10" } - - eslint-plugin-react-hooks@5.2.0: - resolution: - { - integrity: sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==, - } - engines: { node: ">=10" } - peerDependencies: - eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 - - eslint-plugin-react-refresh@0.4.24: - resolution: - { - integrity: sha512-nLHIW7TEq3aLrEYWpVaJ1dRgFR+wLDPN8e8FpYAql/bMV2oBEfC37K0gLEGgv9fy66juNShSMV8OkTqzltcG/w==, - } - peerDependencies: - eslint: ">=8.40" - - eslint-scope@8.4.0: - resolution: - { - integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==, - } - engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } - - eslint-visitor-keys@3.4.3: - resolution: - { - integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==, - } - engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 } - - eslint-visitor-keys@4.2.1: - resolution: - { - integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==, - } - engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } - - eslint@9.39.0: - resolution: - { - integrity: sha512-iy2GE3MHrYTL5lrCtMZ0X1KLEKKUjmK0kzwcnefhR66txcEmXZD2YWgR5GNdcEwkNx3a0siYkSvl0vIC+Svjmg==, - } - engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } - hasBin: true - peerDependencies: - jiti: "*" - peerDependenciesMeta: - jiti: - optional: true - - espree@10.4.0: - resolution: - { - integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==, - } - engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } - - esprima@4.0.1: - resolution: - { - integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==, - } - engines: { node: ">=4" } - hasBin: true - - esquery@1.6.0: - resolution: - { - integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==, - } - engines: { node: ">=0.10" } - - esrecurse@4.3.0: - resolution: - { - integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==, - } - engines: { node: ">=4.0" } - - estraverse@5.3.0: - resolution: - { - integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==, - } - engines: { node: ">=4.0" } - - esutils@2.0.3: - resolution: - { - integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==, - } - engines: { node: ">=0.10.0" } - - fast-deep-equal@3.1.3: - resolution: - { - integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==, - } - - fast-glob@3.3.3: - resolution: - { - integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==, - } - engines: { node: ">=8.6.0" } - - fast-json-stable-stringify@2.1.0: - resolution: - { - integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==, - } - - fast-levenshtein@2.0.6: - resolution: - { - integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==, - } - - fastq@1.19.1: - resolution: - { - integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==, - } - - fd-package-json@2.0.0: - resolution: - { - integrity: sha512-jKmm9YtsNXN789RS/0mSzOC1NUq9mkVd65vbSSVsKdjGvYXBuE4oWe2QOEoFeRmJg+lPuZxpmrfFclNhoRMneQ==, - } - - fdir@6.5.0: - resolution: - { - integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==, - } - engines: { node: ">=12.0.0" } - peerDependencies: - picomatch: ^3 || ^4 - peerDependenciesMeta: - picomatch: - optional: true - - file-entry-cache@8.0.0: - resolution: - { - integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==, - } - engines: { node: ">=16.0.0" } - - fill-range@7.1.1: - resolution: - { - integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==, - } - engines: { node: ">=8" } - - find-up@5.0.0: - resolution: - { - integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==, - } - engines: { node: ">=10" } - - flat-cache@4.0.1: - resolution: - { - integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==, - } - engines: { node: ">=16" } - - flatted@3.3.3: - resolution: - { - integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==, - } - - formatly@0.3.0: - resolution: - { - integrity: sha512-9XNj/o4wrRFyhSMJOvsuyMwy8aUfBaZ1VrqHVfohyXf0Sw0e+yfKG+xZaY3arGCOMdwFsqObtzVOc1gU9KiT9w==, - } - engines: { node: ">=18.3.0" } - hasBin: true - - framer-motion@12.23.24: - resolution: - { - integrity: sha512-HMi5HRoRCTou+3fb3h9oTLyJGBxHfW+HnNE25tAXOvVx/IvwMHK0cx7IR4a2ZU6sh3IX1Z+4ts32PcYBOqka8w==, - } - peerDependencies: - "@emotion/is-prop-valid": "*" - react: ^18.0.0 || ^19.0.0 - react-dom: ^18.0.0 || ^19.0.0 - peerDependenciesMeta: - "@emotion/is-prop-valid": - optional: true - react: - optional: true - react-dom: - optional: true - - fsevents@2.3.3: - resolution: - { - integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==, - } - engines: { node: ^8.16.0 || ^10.6.0 || >=11.0.0 } - os: [darwin] - - gensync@1.0.0-beta.2: - resolution: - { - integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==, - } - engines: { node: ">=6.9.0" } - - get-caller-file@2.0.5: - resolution: - { - integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==, - } - engines: { node: 6.* || 8.* || >= 10.* } - - get-nonce@1.0.1: - resolution: - { - integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==, - } - engines: { node: ">=6" } - - get-tsconfig@4.13.0: - resolution: - { - integrity: sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==, - } - - glob-parent@5.1.2: - resolution: - { - integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==, - } - engines: { node: ">= 6" } - - glob-parent@6.0.2: - resolution: - { - integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==, - } - engines: { node: ">=10.13.0" } - - globals@14.0.0: - resolution: - { - integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==, - } - engines: { node: ">=18" } - - globals@16.5.0: - resolution: - { - integrity: sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ==, - } - engines: { node: ">=18" } - - graceful-fs@4.2.11: - resolution: - { - integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==, - } - - graphemer@1.4.0: - resolution: - { - integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==, - } - - has-flag@4.0.0: - resolution: - { - integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==, - } - engines: { node: ">=8" } - - ignore@5.3.2: - resolution: - { - integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==, - } - engines: { node: ">= 4" } - - ignore@7.0.5: - resolution: - { - integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==, - } - engines: { node: ">= 4" } - - import-fresh@3.3.1: - resolution: - { - integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==, - } - engines: { node: ">=6" } - - imurmurhash@0.1.4: - resolution: - { - integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==, - } - engines: { node: ">=0.8.19" } - - is-binary-path@2.1.0: - resolution: - { - integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==, - } - engines: { node: ">=8" } - - is-extglob@2.1.1: - resolution: - { - integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==, - } - engines: { node: ">=0.10.0" } - - is-fullwidth-code-point@3.0.0: - resolution: - { - integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==, - } - engines: { node: ">=8" } - - is-glob@4.0.3: - resolution: - { - integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==, - } - engines: { node: ">=0.10.0" } - - is-number@7.0.0: - resolution: - { - integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==, - } - engines: { node: ">=0.12.0" } - - isbot@5.1.31: - resolution: - { - integrity: sha512-DPgQshehErHAqSCKDb3rNW03pa2wS/v5evvUqtxt6TTnHRqAG8FdzcSSJs9656pK6Y+NT7K9R4acEYXLHYfpUQ==, - } - engines: { node: ">=18" } - - isexe@2.0.0: - resolution: - { - integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==, - } - - jiti@2.6.1: - resolution: - { - integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==, - } - hasBin: true - - js-tokens@4.0.0: - resolution: - { - integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==, - } - - js-yaml@4.1.0: - resolution: - { - integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==, - } - hasBin: true - - jsesc@3.1.0: - resolution: - { - integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==, - } - engines: { node: ">=6" } - hasBin: true - - json-buffer@3.0.1: - resolution: - { - integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==, - } - - json-schema-traverse@0.4.1: - resolution: - { - integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==, - } - - json-stable-stringify-without-jsonify@1.0.1: - resolution: - { - integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==, - } - - json5@2.2.3: - resolution: - { - integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==, - } - engines: { node: ">=6" } - hasBin: true - - keyv@4.5.4: - resolution: - { - integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==, - } - - knip@5.67.1: - resolution: - { - integrity: sha512-U5AtiqnZAbWIxihs5wxFFEZlpKhzRLWlXSGwA79na7wvlX+MsE0rSuU6If+kl/A4o3TDzTtKGZ4SjeLyWkNR/A==, - } - engines: { node: ">=18.18.0" } - hasBin: true - peerDependencies: - "@types/node": ">=18" - typescript: ">=5.0.4 <7" - - levn@0.4.1: - resolution: - { - integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==, - } - engines: { node: ">= 0.8.0" } - - lightningcss-android-arm64@1.30.2: - resolution: - { - integrity: sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A==, - } - engines: { node: ">= 12.0.0" } - cpu: [arm64] - os: [android] - - lightningcss-darwin-arm64@1.30.2: - resolution: - { - integrity: sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA==, - } - engines: { node: ">= 12.0.0" } - cpu: [arm64] - os: [darwin] - - lightningcss-darwin-x64@1.30.2: - resolution: - { - integrity: sha512-oBZgKchomuDYxr7ilwLcyms6BCyLn0z8J0+ZZmfpjwg9fRVZIR5/GMXd7r9RH94iDhld3UmSjBM6nXWM2TfZTQ==, - } - engines: { node: ">= 12.0.0" } - cpu: [x64] - os: [darwin] - - lightningcss-freebsd-x64@1.30.2: - resolution: - { - integrity: sha512-c2bH6xTrf4BDpK8MoGG4Bd6zAMZDAXS569UxCAGcA7IKbHNMlhGQ89eRmvpIUGfKWNVdbhSbkQaWhEoMGmGslA==, - } - engines: { node: ">= 12.0.0" } - cpu: [x64] - os: [freebsd] - - lightningcss-linux-arm-gnueabihf@1.30.2: - resolution: - { - integrity: sha512-eVdpxh4wYcm0PofJIZVuYuLiqBIakQ9uFZmipf6LF/HRj5Bgm0eb3qL/mr1smyXIS1twwOxNWndd8z0E374hiA==, - } - engines: { node: ">= 12.0.0" } - cpu: [arm] - os: [linux] - - lightningcss-linux-arm64-gnu@1.30.2: - resolution: - { - integrity: sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A==, - } - engines: { node: ">= 12.0.0" } - cpu: [arm64] - os: [linux] - - lightningcss-linux-arm64-musl@1.30.2: - resolution: - { - integrity: sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==, - } - engines: { node: ">= 12.0.0" } - cpu: [arm64] - os: [linux] - - lightningcss-linux-x64-gnu@1.30.2: - resolution: - { - integrity: sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==, - } - engines: { node: ">= 12.0.0" } - cpu: [x64] - os: [linux] - - lightningcss-linux-x64-musl@1.30.2: - resolution: - { - integrity: sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==, - } - engines: { node: ">= 12.0.0" } - cpu: [x64] - os: [linux] - - lightningcss-win32-arm64-msvc@1.30.2: - resolution: - { - integrity: sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ==, - } - engines: { node: ">= 12.0.0" } - cpu: [arm64] - os: [win32] - - lightningcss-win32-x64-msvc@1.30.2: - resolution: - { - integrity: sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw==, - } - engines: { node: ">= 12.0.0" } - cpu: [x64] - os: [win32] - - lightningcss@1.30.2: - resolution: - { - integrity: sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ==, - } - engines: { node: ">= 12.0.0" } - - locate-path@6.0.0: - resolution: - { - integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==, - } - engines: { node: ">=10" } - - lodash.merge@4.6.2: - resolution: - { - integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==, - } - - lru-cache@5.1.1: - resolution: - { - integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==, - } - - lucide-react@0.552.0: - resolution: - { - integrity: sha512-g9WCjmfwqbexSnZE+2cl21PCfXOcqnGeWeMTNAOGEfpPbm/ZF4YIq77Z8qWrxbu660EKuLB4nSLggoKnCb+isw==, - } - peerDependencies: - react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 - - magic-string@0.30.21: - resolution: - { - integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==, - } - - merge2@1.4.1: - resolution: - { - integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==, - } - engines: { node: ">= 8" } - - micromatch@4.0.8: - resolution: - { - integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==, - } - engines: { node: ">=8.6" } - - minimatch@3.1.2: - resolution: - { - integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==, - } - - minimatch@9.0.5: - resolution: - { - integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==, - } - engines: { node: ">=16 || 14 >=14.17" } - - minimist@1.2.8: - resolution: - { - integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==, - } - - motion-dom@12.23.23: - resolution: - { - integrity: sha512-n5yolOs0TQQBRUFImrRfs/+6X4p3Q4n1dUEqt/H58Vx7OW6RF+foWEgmTVDhIWJIMXOuNNL0apKH2S16en9eiA==, - } - - motion-utils@12.23.6: - resolution: - { - integrity: sha512-eAWoPgr4eFEOFfg2WjIsMoqJTW6Z8MTUCgn/GZ3VRpClWBdnbjryiA3ZSNLyxCTmCQx4RmYX6jX1iWHbenUPNQ==, - } - - motion@12.23.24: - resolution: - { - integrity: sha512-Rc5E7oe2YZ72N//S3QXGzbnXgqNrTESv8KKxABR20q2FLch9gHLo0JLyYo2hZ238bZ9Gx6cWhj9VO0IgwbMjCw==, - } - peerDependencies: - "@emotion/is-prop-valid": "*" - react: ^18.0.0 || ^19.0.0 - react-dom: ^18.0.0 || ^19.0.0 - peerDependenciesMeta: - "@emotion/is-prop-valid": - optional: true - react: - optional: true - react-dom: - optional: true - - ms@2.1.3: - resolution: - { - integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==, - } - - nanoid@3.3.11: - resolution: - { - integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==, - } - engines: { node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1 } - hasBin: true - - natural-compare@1.4.0: - resolution: - { - integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==, - } - - node-releases@2.0.27: - resolution: - { - integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==, - } - - normalize-path@3.0.0: - resolution: - { - integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==, - } - engines: { node: ">=0.10.0" } - - optionator@0.9.4: - resolution: - { - integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==, - } - engines: { node: ">= 0.8.0" } - - oxc-resolver@11.13.1: - resolution: - { - integrity: sha512-/MS37pbsjfdujmuiM/qONFToT8zjDh78xOhVOPStG7fiZlE0b8od8XOfLhqovL0NnMR0ojumTUWF4LK/U15qDQ==, - } - - p-limit@3.1.0: - resolution: - { - integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==, - } - engines: { node: ">=10" } - - p-locate@5.0.0: - resolution: - { - integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==, - } - engines: { node: ">=10" } - - parent-module@1.0.1: - resolution: - { - integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==, - } - engines: { node: ">=6" } - - path-exists@4.0.0: - resolution: - { - integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==, - } - engines: { node: ">=8" } - - path-key@3.1.1: - resolution: - { - integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==, - } - engines: { node: ">=8" } - - pathe@2.0.3: - resolution: - { - integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==, - } - - picocolors@1.1.1: - resolution: - { - integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==, - } - - picomatch@2.3.1: - resolution: - { - integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==, - } - engines: { node: ">=8.6" } - - picomatch@4.0.3: - resolution: - { - integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==, - } - engines: { node: ">=12" } - - postcss@8.5.6: - resolution: - { - integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==, - } - engines: { node: ^10 || ^12 || >=14 } - - prelude-ls@1.2.1: - resolution: - { - integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==, - } - engines: { node: ">= 0.8.0" } - - prettier@3.6.2: - resolution: - { - integrity: sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==, - } - engines: { node: ">=14" } - hasBin: true - - punycode@2.3.1: - resolution: - { - integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==, - } - engines: { node: ">=6" } - - queue-microtask@1.2.3: - resolution: - { - integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==, - } - - radix-ui@1.4.3: - resolution: - { - integrity: sha512-aWizCQiyeAenIdUbqEpXgRA1ya65P13NKn/W8rWkcN0OPkRDxdBVLWnIEDsS2RpwCK2nobI7oMUSmexzTDyAmA==, - } - 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 - - react-dom@19.2.0: - resolution: - { - integrity: sha512-UlbRu4cAiGaIewkPyiRGJk0imDN2T3JjieT6spoL2UeSf5od4n5LB/mQ4ejmxhCFT1tYe8IvaFulzynWovsEFQ==, - } - peerDependencies: - react: ^19.2.0 - - react-hook-form@7.66.0: - resolution: - { - integrity: sha512-xXBqsWGKrY46ZqaHDo+ZUYiMUgi8suYu5kdrS20EG8KiL7VRQitEbNjm+UcrDYrNi1YLyfpmAeGjCZYXLT9YBw==, - } - engines: { node: ">=18.0.0" } - peerDependencies: - react: ^16.8.0 || ^17 || ^18 || ^19 - - react-intersection-observer@10.0.0: - resolution: - { - integrity: sha512-JJRgcnFQoVXmbE5+GXr1OS1NDD1gHk0HyfpLcRf0575IbJz+io8yzs4mWVlfaqOQq1FiVjLvuYAdEEcrrCfveg==, - } - peerDependencies: - react: ^17.0.0 || ^18.0.0 || ^19.0.0 - react-dom: ^17.0.0 || ^18.0.0 || ^19.0.0 - peerDependenciesMeta: - react-dom: - optional: true - - react-refresh@0.18.0: - resolution: - { - integrity: sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==, - } - engines: { node: ">=0.10.0" } - - react-remove-scroll-bar@2.3.8: - resolution: - { - integrity: sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==, - } - engines: { node: ">=10" } - peerDependencies: - "@types/react": "*" - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - peerDependenciesMeta: - "@types/react": - optional: true - - react-remove-scroll@2.7.1: - resolution: - { - integrity: sha512-HpMh8+oahmIdOuS5aFKKY6Pyog+FNaZV/XyJOq7b4YFwsFHe5yYfdbIalI4k3vU2nSDql7YskmUseHsRrJqIPA==, - } - engines: { node: ">=10" } - peerDependencies: - "@types/react": "*" - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc - peerDependenciesMeta: - "@types/react": - optional: true - - react-style-singleton@2.2.3: - resolution: - { - integrity: sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==, - } - engines: { node: ">=10" } - peerDependencies: - "@types/react": "*" - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc - peerDependenciesMeta: - "@types/react": - optional: true - - react@19.2.0: - resolution: - { - integrity: sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ==, - } - engines: { node: ">=0.10.0" } - - readdirp@3.6.0: - resolution: - { - integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==, - } - engines: { node: ">=8.10.0" } - - recast@0.23.11: - resolution: - { - integrity: sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA==, - } - engines: { node: ">= 4" } - - require-directory@2.1.1: - resolution: - { - integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==, - } - engines: { node: ">=0.10.0" } - - resolve-from@4.0.0: - resolution: - { - integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==, - } - engines: { node: ">=4" } - - resolve-pkg-maps@1.0.0: - resolution: - { - integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==, - } - - reusify@1.1.0: - resolution: - { - integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==, - } - engines: { iojs: ">=1.0.0", node: ">=0.10.0" } - - rolldown-vite@7.1.14: - resolution: - { - integrity: sha512-eSiiRJmovt8qDJkGyZuLnbxAOAdie6NCmmd0NkTC0RJI9duiSBTfr8X2mBYJOUFzxQa2USaHmL99J9uMxkjCyw==, - } - engines: { node: ^20.19.0 || >=22.12.0 } - hasBin: true - peerDependencies: - "@types/node": ^20.19.0 || >=22.12.0 - esbuild: ^0.25.0 - jiti: ">=1.21.0" - less: ^4.0.0 - sass: ^1.70.0 - sass-embedded: ^1.70.0 - stylus: ">=0.54.8" - sugarss: ^5.0.0 - terser: ^5.16.0 - tsx: ^4.8.1 - yaml: ^2.4.2 - peerDependenciesMeta: - "@types/node": - optional: true - esbuild: - optional: true - jiti: - optional: true - less: - optional: true - sass: - optional: true - sass-embedded: - optional: true - stylus: - optional: true - sugarss: - optional: true - terser: - optional: true - tsx: - optional: true - yaml: - optional: true - - rolldown@1.0.0-beta.41: - resolution: - { - integrity: sha512-U+NPR0Bkg3wm61dteD2L4nAM1U9dtaqVrpDXwC36IKRHpEO/Ubpid4Nijpa2imPchcVNHfxVFwSSMJdwdGFUbg==, - } - engines: { node: ^20.19.0 || >=22.12.0 } - hasBin: true - - run-parallel@1.2.0: - resolution: - { - integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==, - } - - scheduler@0.27.0: - resolution: - { - integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==, - } - - semver@6.3.1: - resolution: - { - integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==, - } - hasBin: true - - semver@7.7.3: - resolution: - { - integrity: sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==, - } - engines: { node: ">=10" } - hasBin: true - - seroval-plugins@1.3.3: - resolution: - { - integrity: sha512-16OL3NnUBw8JG1jBLUoZJsLnQq0n5Ua6aHalhJK4fMQkz1lqR7Osz1sA30trBtd9VUDc2NgkuRCn8+/pBwqZ+w==, - } - engines: { node: ">=10" } - peerDependencies: - seroval: ^1.0 - - seroval@1.3.2: - resolution: - { - integrity: sha512-RbcPH1n5cfwKrru7v7+zrZvjLurgHhGyso3HTyGtRivGWgYjbOmGuivCQaORNELjNONoK35nj28EoWul9sb1zQ==, - } - engines: { node: ">=10" } - - shebang-command@2.0.0: - resolution: - { - integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==, - } - engines: { node: ">=8" } - - shebang-regex@3.0.0: - resolution: - { - integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==, - } - engines: { node: ">=8" } - - smol-toml@1.4.2: - resolution: - { - integrity: sha512-rInDH6lCNiEyn3+hH8KVGFdbjc099j47+OSgbMrfDYX1CmXLfdKd7qi6IfcWj2wFxvSVkuI46M+wPGYfEOEj6g==, - } - engines: { node: ">= 18" } - - sonner@2.0.7: - resolution: - { - integrity: sha512-W6ZN4p58k8aDKA4XPcx2hpIQXBRAgyiWVkYhT7CvK6D3iAu7xjvVyhQHg2/iaKJZ1XVJ4r7XuwGL+WGEK37i9w==, - } - peerDependencies: - react: ^18.0.0 || ^19.0.0 || ^19.0.0-rc - react-dom: ^18.0.0 || ^19.0.0 || ^19.0.0-rc - - source-map-js@1.2.1: - resolution: - { - integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==, - } - engines: { node: ">=0.10.0" } - - source-map@0.6.1: - resolution: - { - integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==, - } - engines: { node: ">=0.10.0" } - - source-map@0.7.6: - resolution: - { - integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==, - } - engines: { node: ">= 12" } - - string-width@4.2.3: - resolution: - { - integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==, - } - engines: { node: ">=8" } - - strip-ansi@6.0.1: - resolution: - { - integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==, - } - engines: { node: ">=8" } - - strip-json-comments@3.1.1: - resolution: - { - integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==, - } - engines: { node: ">=8" } - - strip-json-comments@5.0.2: - resolution: - { - integrity: sha512-4X2FR3UwhNUE9G49aIsJW5hRRR3GXGTBTZRMfv568O60ojM8HcWjV/VxAxCDW3SUND33O6ZY66ZuRcdkj73q2g==, - } - engines: { node: ">=14.16" } - - supports-color@7.2.0: - resolution: - { - integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==, - } - engines: { node: ">=8" } - - tailwind-merge@3.3.1: - resolution: - { - integrity: sha512-gBXpgUm/3rp1lMZZrM/w7D8GKqshif0zAymAhbCyIt8KMe+0v9DQ7cdYLR4FHH/cKpdTXb+A/tKKU3eolfsI+g==, - } - - tailwindcss@4.1.16: - resolution: - { - integrity: sha512-pONL5awpaQX4LN5eiv7moSiSPd/DLDzKVRJz8Q9PgzmAdd1R4307GQS2ZpfiN7ZmekdQrfhZZiSE5jkLR4WNaA==, - } - - tapable@2.3.0: - resolution: - { - integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==, - } - engines: { node: ">=6" } - - tiny-invariant@1.3.3: - resolution: - { - integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==, - } - - tiny-warning@1.0.3: - resolution: - { - integrity: sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==, - } - - tinyglobby@0.2.15: - resolution: - { - integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==, - } - engines: { node: ">=12.0.0" } - - to-regex-range@5.0.1: - resolution: - { - integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==, - } - engines: { node: ">=8.0" } - - ts-api-utils@2.1.0: - resolution: - { - integrity: sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==, - } - engines: { node: ">=18.12" } - peerDependencies: - typescript: ">=4.8.4" - - tslib@2.8.1: - resolution: - { - integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==, - } - - tsx@4.20.6: - resolution: - { - integrity: sha512-ytQKuwgmrrkDTFP4LjR0ToE2nqgy886GpvRSpU0JAnrdBYppuY5rLkRUYPU1yCryb24SsKBTL/hlDQAEFVwtZg==, - } - engines: { node: ">=18.0.0" } - hasBin: true - - tw-animate-css@1.4.0: - resolution: - { - integrity: sha512-7bziOlRqH0hJx80h/3mbicLW7o8qLsH5+RaLR2t+OHM3D0JlWGODQKQ4cxbK7WlvmUxpcj6Kgu6EKqjrGFe3QQ==, - } - - type-check@0.4.0: - resolution: - { - integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==, - } - engines: { node: ">= 0.8.0" } - - typescript-eslint@8.46.2: - resolution: - { - integrity: sha512-vbw8bOmiuYNdzzV3lsiWv6sRwjyuKJMQqWulBOU7M0RrxedXledX8G8kBbQeiOYDnTfiXz0Y4081E1QMNB6iQg==, - } - engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: ">=4.8.4 <6.0.0" - - typescript@5.9.3: - resolution: - { - integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==, - } - engines: { node: ">=14.17" } - hasBin: true - - undici-types@7.16.0: - resolution: - { - integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==, - } - - unplugin@2.3.10: - resolution: - { - integrity: sha512-6NCPkv1ClwH+/BGE9QeoTIl09nuiAt0gS28nn1PvYXsGKRwM2TCbFA2QiilmehPDTXIe684k4rZI1yl3A1PCUw==, - } - engines: { node: ">=18.12.0" } - - update-browserslist-db@1.1.4: - resolution: - { - integrity: sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A==, - } - hasBin: true - peerDependencies: - browserslist: ">= 4.21.0" - - uri-js@4.4.1: - resolution: - { - integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==, - } - - use-callback-ref@1.3.3: - resolution: - { - integrity: sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==, - } - engines: { node: ">=10" } - peerDependencies: - "@types/react": "*" - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc - peerDependenciesMeta: - "@types/react": - optional: true - - use-sidecar@1.1.3: - resolution: - { - integrity: sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==, - } - engines: { node: ">=10" } - peerDependencies: - "@types/react": "*" - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc - peerDependenciesMeta: - "@types/react": - optional: true - - use-sync-external-store@1.6.0: - resolution: - { - integrity: sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==, - } - peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - - walk-up-path@4.0.0: - resolution: - { - integrity: sha512-3hu+tD8YzSLGuFYtPRb48vdhKMi0KQV5sn+uWr8+7dMEq/2G/dtLrdDinkLjqq5TIbIBjYJ4Ax/n3YiaW7QM8A==, - } - engines: { node: 20 || >=22 } - - webpack-virtual-modules@0.6.2: - resolution: - { - integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==, - } - - which@2.0.2: - resolution: - { - integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==, - } - engines: { node: ">= 8" } - hasBin: true - - word-wrap@1.2.5: - resolution: - { - integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==, - } - engines: { node: ">=0.10.0" } - - wrap-ansi@7.0.0: - resolution: - { - integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==, - } - engines: { node: ">=10" } - - y18n@5.0.8: - resolution: - { - integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==, - } - engines: { node: ">=10" } - - yallist@3.1.1: - resolution: - { - integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==, - } - - yargs-parser@21.1.1: - resolution: - { - integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==, - } - engines: { node: ">=12" } - - yargs@17.7.2: - resolution: - { - integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==, - } - engines: { node: ">=12" } - - yocto-queue@0.1.0: - resolution: - { - integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==, - } - engines: { node: ">=10" } - - zod@3.25.76: - resolution: - { - integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==, - } - - zod@4.1.12: - resolution: - { - integrity: sha512-JInaHOamG8pt5+Ey8kGmdcAcg3OL9reK8ltczgHTAwNhMys/6ThXHityHxVV2p3fkw/c+MAvBHFVYHFZDmjMCQ==, - } - -snapshots: - "@babel/code-frame@7.27.1": - dependencies: - "@babel/helper-validator-identifier": 7.28.5 - js-tokens: 4.0.0 - picocolors: 1.1.1 - - "@babel/compat-data@7.28.5": {} - - "@babel/core@7.28.5": - dependencies: - "@babel/code-frame": 7.27.1 - "@babel/generator": 7.28.5 - "@babel/helper-compilation-targets": 7.27.2 - "@babel/helper-module-transforms": 7.28.3(@babel/core@7.28.5) - "@babel/helpers": 7.28.4 - "@babel/parser": 7.28.5 - "@babel/template": 7.27.2 - "@babel/traverse": 7.28.5 - "@babel/types": 7.28.5 - "@jridgewell/remapping": 2.3.5 - convert-source-map: 2.0.0 - debug: 4.4.3 - gensync: 1.0.0-beta.2 - json5: 2.2.3 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - - "@babel/generator@7.28.5": - dependencies: - "@babel/parser": 7.28.5 - "@babel/types": 7.28.5 - "@jridgewell/gen-mapping": 0.3.13 - "@jridgewell/trace-mapping": 0.3.31 - jsesc: 3.1.0 - - "@babel/helper-annotate-as-pure@7.27.3": - dependencies: - "@babel/types": 7.28.5 - - "@babel/helper-compilation-targets@7.27.2": - dependencies: - "@babel/compat-data": 7.28.5 - "@babel/helper-validator-option": 7.27.1 - browserslist: 4.27.0 - lru-cache: 5.1.1 - semver: 6.3.1 - - "@babel/helper-create-class-features-plugin@7.28.5(@babel/core@7.28.5)": - dependencies: - "@babel/core": 7.28.5 - "@babel/helper-annotate-as-pure": 7.27.3 - "@babel/helper-member-expression-to-functions": 7.28.5 - "@babel/helper-optimise-call-expression": 7.27.1 - "@babel/helper-replace-supers": 7.27.1(@babel/core@7.28.5) - "@babel/helper-skip-transparent-expression-wrappers": 7.27.1 - "@babel/traverse": 7.28.5 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - - "@babel/helper-globals@7.28.0": {} - - "@babel/helper-member-expression-to-functions@7.28.5": - dependencies: - "@babel/traverse": 7.28.5 - "@babel/types": 7.28.5 - transitivePeerDependencies: - - supports-color - - "@babel/helper-module-imports@7.27.1": - dependencies: - "@babel/traverse": 7.28.5 - "@babel/types": 7.28.5 - transitivePeerDependencies: - - supports-color - - "@babel/helper-module-transforms@7.28.3(@babel/core@7.28.5)": - dependencies: - "@babel/core": 7.28.5 - "@babel/helper-module-imports": 7.27.1 - "@babel/helper-validator-identifier": 7.28.5 - "@babel/traverse": 7.28.5 - transitivePeerDependencies: - - supports-color - - "@babel/helper-optimise-call-expression@7.27.1": - dependencies: - "@babel/types": 7.28.5 - - "@babel/helper-plugin-utils@7.27.1": {} - - "@babel/helper-replace-supers@7.27.1(@babel/core@7.28.5)": - dependencies: - "@babel/core": 7.28.5 - "@babel/helper-member-expression-to-functions": 7.28.5 - "@babel/helper-optimise-call-expression": 7.27.1 - "@babel/traverse": 7.28.5 - transitivePeerDependencies: - - supports-color - - "@babel/helper-skip-transparent-expression-wrappers@7.27.1": - dependencies: - "@babel/traverse": 7.28.5 - "@babel/types": 7.28.5 - transitivePeerDependencies: - - supports-color - - "@babel/helper-string-parser@7.27.1": {} - - "@babel/helper-validator-identifier@7.28.5": {} - - "@babel/helper-validator-option@7.27.1": {} - - "@babel/helpers@7.28.4": - dependencies: - "@babel/template": 7.27.2 - "@babel/types": 7.28.5 - - "@babel/parser@7.28.5": - dependencies: - "@babel/types": 7.28.5 - - "@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.28.5)": - dependencies: - "@babel/core": 7.28.5 - "@babel/helper-plugin-utils": 7.27.1 - - "@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.28.5)": - dependencies: - "@babel/core": 7.28.5 - "@babel/helper-plugin-utils": 7.27.1 - - "@babel/plugin-transform-modules-commonjs@7.27.1(@babel/core@7.28.5)": - dependencies: - "@babel/core": 7.28.5 - "@babel/helper-module-transforms": 7.28.3(@babel/core@7.28.5) - "@babel/helper-plugin-utils": 7.27.1 - transitivePeerDependencies: - - supports-color - - "@babel/plugin-transform-react-jsx-self@7.27.1(@babel/core@7.28.5)": - dependencies: - "@babel/core": 7.28.5 - "@babel/helper-plugin-utils": 7.27.1 - - "@babel/plugin-transform-react-jsx-source@7.27.1(@babel/core@7.28.5)": - dependencies: - "@babel/core": 7.28.5 - "@babel/helper-plugin-utils": 7.27.1 - - "@babel/plugin-transform-typescript@7.28.5(@babel/core@7.28.5)": - dependencies: - "@babel/core": 7.28.5 - "@babel/helper-annotate-as-pure": 7.27.3 - "@babel/helper-create-class-features-plugin": 7.28.5(@babel/core@7.28.5) - "@babel/helper-plugin-utils": 7.27.1 - "@babel/helper-skip-transparent-expression-wrappers": 7.27.1 - "@babel/plugin-syntax-typescript": 7.27.1(@babel/core@7.28.5) - transitivePeerDependencies: - - supports-color - - "@babel/preset-typescript@7.28.5(@babel/core@7.28.5)": - dependencies: - "@babel/core": 7.28.5 - "@babel/helper-plugin-utils": 7.27.1 - "@babel/helper-validator-option": 7.27.1 - "@babel/plugin-syntax-jsx": 7.27.1(@babel/core@7.28.5) - "@babel/plugin-transform-modules-commonjs": 7.27.1(@babel/core@7.28.5) - "@babel/plugin-transform-typescript": 7.28.5(@babel/core@7.28.5) - transitivePeerDependencies: - - supports-color - - "@babel/template@7.27.2": - dependencies: - "@babel/code-frame": 7.27.1 - "@babel/parser": 7.28.5 - "@babel/types": 7.28.5 - - "@babel/traverse@7.28.5": - dependencies: - "@babel/code-frame": 7.27.1 - "@babel/generator": 7.28.5 - "@babel/helper-globals": 7.28.0 - "@babel/parser": 7.28.5 - "@babel/template": 7.27.2 - "@babel/types": 7.28.5 - debug: 4.4.3 - transitivePeerDependencies: - - supports-color - - "@babel/types@7.28.5": - dependencies: - "@babel/helper-string-parser": 7.27.1 - "@babel/helper-validator-identifier": 7.28.5 - - "@emnapi/core@1.6.0": - dependencies: - "@emnapi/wasi-threads": 1.1.0 - tslib: 2.8.1 - optional: true - - "@emnapi/runtime@1.6.0": - dependencies: - tslib: 2.8.1 - optional: true - - "@emnapi/wasi-threads@1.1.0": - dependencies: - tslib: 2.8.1 - optional: true - - "@esbuild/aix-ppc64@0.25.12": - optional: true - - "@esbuild/android-arm64@0.25.12": - optional: true - - "@esbuild/android-arm@0.25.12": - optional: true - - "@esbuild/android-x64@0.25.12": - optional: true - - "@esbuild/darwin-arm64@0.25.12": - optional: true - - "@esbuild/darwin-x64@0.25.12": - optional: true - - "@esbuild/freebsd-arm64@0.25.12": - optional: true - - "@esbuild/freebsd-x64@0.25.12": - optional: true - - "@esbuild/linux-arm64@0.25.12": - optional: true - - "@esbuild/linux-arm@0.25.12": - optional: true - - "@esbuild/linux-ia32@0.25.12": - optional: true - - "@esbuild/linux-loong64@0.25.12": - optional: true - - "@esbuild/linux-mips64el@0.25.12": - optional: true - - "@esbuild/linux-ppc64@0.25.12": - optional: true - - "@esbuild/linux-riscv64@0.25.12": - optional: true - - "@esbuild/linux-s390x@0.25.12": - optional: true - - "@esbuild/linux-x64@0.25.12": - optional: true - - "@esbuild/netbsd-arm64@0.25.12": - optional: true - - "@esbuild/netbsd-x64@0.25.12": - optional: true - - "@esbuild/openbsd-arm64@0.25.12": - optional: true - - "@esbuild/openbsd-x64@0.25.12": - optional: true - - "@esbuild/openharmony-arm64@0.25.12": - optional: true - - "@esbuild/sunos-x64@0.25.12": - optional: true - - "@esbuild/win32-arm64@0.25.12": - optional: true - - "@esbuild/win32-ia32@0.25.12": - optional: true - - "@esbuild/win32-x64@0.25.12": - optional: true - - "@eslint-community/eslint-utils@4.9.0(eslint@9.39.0(jiti@2.6.1))": - dependencies: - eslint: 9.39.0(jiti@2.6.1) - eslint-visitor-keys: 3.4.3 - - "@eslint-community/regexpp@4.12.2": {} - - "@eslint/config-array@0.21.1": - dependencies: - "@eslint/object-schema": 2.1.7 - debug: 4.4.3 - minimatch: 3.1.2 - transitivePeerDependencies: - - supports-color - - "@eslint/config-helpers@0.4.2": - dependencies: - "@eslint/core": 0.17.0 - - "@eslint/core@0.17.0": - dependencies: - "@types/json-schema": 7.0.15 - - "@eslint/eslintrc@3.3.1": - dependencies: - ajv: 6.12.6 - debug: 4.4.3 - espree: 10.4.0 - globals: 14.0.0 - ignore: 5.3.2 - import-fresh: 3.3.1 - js-yaml: 4.1.0 - minimatch: 3.1.2 - strip-json-comments: 3.1.1 - transitivePeerDependencies: - - supports-color - - "@eslint/js@9.39.0": {} - - "@eslint/object-schema@2.1.7": {} - - "@eslint/plugin-kit@0.4.1": - dependencies: - "@eslint/core": 0.17.0 - levn: 0.4.1 - - "@floating-ui/core@1.7.3": - dependencies: - "@floating-ui/utils": 0.2.10 - - "@floating-ui/dom@1.7.4": - dependencies: - "@floating-ui/core": 1.7.3 - "@floating-ui/utils": 0.2.10 - - "@floating-ui/react-dom@2.1.6(react-dom@19.2.0(react@19.2.0))(react@19.2.0)": - dependencies: - "@floating-ui/dom": 1.7.4 - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - - "@floating-ui/utils@0.2.10": {} - - "@hookform/resolvers@5.2.2(react-hook-form@7.66.0(react@19.2.0))": - dependencies: - "@standard-schema/utils": 0.3.0 - react-hook-form: 7.66.0(react@19.2.0) - - "@humanfs/core@0.19.1": {} - - "@humanfs/node@0.16.7": - dependencies: - "@humanfs/core": 0.19.1 - "@humanwhocodes/retry": 0.4.3 - - "@humanwhocodes/module-importer@1.0.1": {} - - "@humanwhocodes/retry@0.4.3": {} - - "@jridgewell/gen-mapping@0.3.13": - dependencies: - "@jridgewell/sourcemap-codec": 1.5.5 - "@jridgewell/trace-mapping": 0.3.31 - - "@jridgewell/remapping@2.3.5": - dependencies: - "@jridgewell/gen-mapping": 0.3.13 - "@jridgewell/trace-mapping": 0.3.31 - - "@jridgewell/resolve-uri@3.1.2": {} - - "@jridgewell/sourcemap-codec@1.5.5": {} - - "@jridgewell/trace-mapping@0.3.31": - dependencies: - "@jridgewell/resolve-uri": 3.1.2 - "@jridgewell/sourcemap-codec": 1.5.5 - - "@napi-rs/wasm-runtime@1.0.7": - dependencies: - "@emnapi/core": 1.6.0 - "@emnapi/runtime": 1.6.0 - "@tybys/wasm-util": 0.10.1 - optional: true - - "@nodelib/fs.scandir@2.1.5": - dependencies: - "@nodelib/fs.stat": 2.0.5 - run-parallel: 1.2.0 - - "@nodelib/fs.stat@2.0.5": {} - - "@nodelib/fs.walk@1.2.8": - dependencies: - "@nodelib/fs.scandir": 2.1.5 - fastq: 1.19.1 - - "@oxc-project/runtime@0.92.0": {} - - "@oxc-project/types@0.93.0": {} - - "@oxc-resolver/binding-android-arm-eabi@11.13.1": - optional: true - - "@oxc-resolver/binding-android-arm64@11.13.1": - optional: true - - "@oxc-resolver/binding-darwin-arm64@11.13.1": - optional: true - - "@oxc-resolver/binding-darwin-x64@11.13.1": - optional: true - - "@oxc-resolver/binding-freebsd-x64@11.13.1": - optional: true - - "@oxc-resolver/binding-linux-arm-gnueabihf@11.13.1": - optional: true - - "@oxc-resolver/binding-linux-arm-musleabihf@11.13.1": - optional: true - - "@oxc-resolver/binding-linux-arm64-gnu@11.13.1": - optional: true - - "@oxc-resolver/binding-linux-arm64-musl@11.13.1": - optional: true - - "@oxc-resolver/binding-linux-ppc64-gnu@11.13.1": - optional: true - - "@oxc-resolver/binding-linux-riscv64-gnu@11.13.1": - optional: true - - "@oxc-resolver/binding-linux-riscv64-musl@11.13.1": - optional: true - - "@oxc-resolver/binding-linux-s390x-gnu@11.13.1": - optional: true - - "@oxc-resolver/binding-linux-x64-gnu@11.13.1": - optional: true - - "@oxc-resolver/binding-linux-x64-musl@11.13.1": - optional: true - - "@oxc-resolver/binding-wasm32-wasi@11.13.1": - dependencies: - "@napi-rs/wasm-runtime": 1.0.7 - optional: true - - "@oxc-resolver/binding-win32-arm64-msvc@11.13.1": - optional: true - - "@oxc-resolver/binding-win32-ia32-msvc@11.13.1": - optional: true - - "@oxc-resolver/binding-win32-x64-msvc@11.13.1": - optional: true - - "@radix-ui/number@1.1.1": {} - - "@radix-ui/primitive@1.1.3": {} - - "@radix-ui/react-accessible-icon@1.1.7(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)": - dependencies: - "@radix-ui/react-visually-hidden": 1.2.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - optionalDependencies: - "@types/react": 19.2.2 - "@types/react-dom": 19.2.2(@types/react@19.2.2) - - "@radix-ui/react-accordion@1.2.12(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)": - dependencies: - "@radix-ui/primitive": 1.1.3 - "@radix-ui/react-collapsible": 1.1.12(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-collection": 1.1.7(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-compose-refs": 1.1.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-context": 1.1.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-direction": 1.1.1(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-id": 1.1.1(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-primitive": 2.1.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-use-controllable-state": 1.2.2(@types/react@19.2.2)(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - optionalDependencies: - "@types/react": 19.2.2 - "@types/react-dom": 19.2.2(@types/react@19.2.2) - - "@radix-ui/react-alert-dialog@1.1.15(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)": - dependencies: - "@radix-ui/primitive": 1.1.3 - "@radix-ui/react-compose-refs": 1.1.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-context": 1.1.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-dialog": 1.1.15(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-primitive": 2.1.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-slot": 1.2.3(@types/react@19.2.2)(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - optionalDependencies: - "@types/react": 19.2.2 - "@types/react-dom": 19.2.2(@types/react@19.2.2) - - "@radix-ui/react-arrow@1.1.7(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)": - dependencies: - "@radix-ui/react-primitive": 2.1.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - optionalDependencies: - "@types/react": 19.2.2 - "@types/react-dom": 19.2.2(@types/react@19.2.2) - - "@radix-ui/react-aspect-ratio@1.1.7(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)": - dependencies: - "@radix-ui/react-primitive": 2.1.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - optionalDependencies: - "@types/react": 19.2.2 - "@types/react-dom": 19.2.2(@types/react@19.2.2) - - "@radix-ui/react-avatar@1.1.10(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)": - dependencies: - "@radix-ui/react-context": 1.1.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-primitive": 2.1.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-use-callback-ref": 1.1.1(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-use-is-hydrated": 0.1.0(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-use-layout-effect": 1.1.1(@types/react@19.2.2)(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - optionalDependencies: - "@types/react": 19.2.2 - "@types/react-dom": 19.2.2(@types/react@19.2.2) - - "@radix-ui/react-checkbox@1.3.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)": - dependencies: - "@radix-ui/primitive": 1.1.3 - "@radix-ui/react-compose-refs": 1.1.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-context": 1.1.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-presence": 1.1.5(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-primitive": 2.1.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-use-controllable-state": 1.2.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-use-previous": 1.1.1(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-use-size": 1.1.1(@types/react@19.2.2)(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - optionalDependencies: - "@types/react": 19.2.2 - "@types/react-dom": 19.2.2(@types/react@19.2.2) - - "@radix-ui/react-collapsible@1.1.12(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)": - dependencies: - "@radix-ui/primitive": 1.1.3 - "@radix-ui/react-compose-refs": 1.1.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-context": 1.1.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-id": 1.1.1(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-presence": 1.1.5(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-primitive": 2.1.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-use-controllable-state": 1.2.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-use-layout-effect": 1.1.1(@types/react@19.2.2)(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - optionalDependencies: - "@types/react": 19.2.2 - "@types/react-dom": 19.2.2(@types/react@19.2.2) - - "@radix-ui/react-collection@1.1.7(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)": - dependencies: - "@radix-ui/react-compose-refs": 1.1.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-context": 1.1.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-primitive": 2.1.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-slot": 1.2.3(@types/react@19.2.2)(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - optionalDependencies: - "@types/react": 19.2.2 - "@types/react-dom": 19.2.2(@types/react@19.2.2) - - "@radix-ui/react-compose-refs@1.1.2(@types/react@19.2.2)(react@19.2.0)": - dependencies: - react: 19.2.0 - optionalDependencies: - "@types/react": 19.2.2 - - "@radix-ui/react-context-menu@2.2.16(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)": - dependencies: - "@radix-ui/primitive": 1.1.3 - "@radix-ui/react-context": 1.1.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-menu": 2.1.16(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-primitive": 2.1.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-use-callback-ref": 1.1.1(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-use-controllable-state": 1.2.2(@types/react@19.2.2)(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - optionalDependencies: - "@types/react": 19.2.2 - "@types/react-dom": 19.2.2(@types/react@19.2.2) - - "@radix-ui/react-context@1.1.2(@types/react@19.2.2)(react@19.2.0)": - dependencies: - react: 19.2.0 - optionalDependencies: - "@types/react": 19.2.2 - - "@radix-ui/react-dialog@1.1.15(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)": - dependencies: - "@radix-ui/primitive": 1.1.3 - "@radix-ui/react-compose-refs": 1.1.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-context": 1.1.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-dismissable-layer": 1.1.11(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-focus-guards": 1.1.3(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-focus-scope": 1.1.7(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-id": 1.1.1(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-portal": 1.1.9(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-presence": 1.1.5(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-primitive": 2.1.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-slot": 1.2.3(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-use-controllable-state": 1.2.2(@types/react@19.2.2)(react@19.2.0) - aria-hidden: 1.2.6 - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - react-remove-scroll: 2.7.1(@types/react@19.2.2)(react@19.2.0) - optionalDependencies: - "@types/react": 19.2.2 - "@types/react-dom": 19.2.2(@types/react@19.2.2) - - "@radix-ui/react-direction@1.1.1(@types/react@19.2.2)(react@19.2.0)": - dependencies: - react: 19.2.0 - optionalDependencies: - "@types/react": 19.2.2 - - "@radix-ui/react-dismissable-layer@1.1.11(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)": - dependencies: - "@radix-ui/primitive": 1.1.3 - "@radix-ui/react-compose-refs": 1.1.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-primitive": 2.1.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-use-callback-ref": 1.1.1(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-use-escape-keydown": 1.1.1(@types/react@19.2.2)(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - optionalDependencies: - "@types/react": 19.2.2 - "@types/react-dom": 19.2.2(@types/react@19.2.2) - - "@radix-ui/react-dropdown-menu@2.1.16(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)": - dependencies: - "@radix-ui/primitive": 1.1.3 - "@radix-ui/react-compose-refs": 1.1.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-context": 1.1.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-id": 1.1.1(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-menu": 2.1.16(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-primitive": 2.1.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-use-controllable-state": 1.2.2(@types/react@19.2.2)(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - optionalDependencies: - "@types/react": 19.2.2 - "@types/react-dom": 19.2.2(@types/react@19.2.2) - - "@radix-ui/react-focus-guards@1.1.3(@types/react@19.2.2)(react@19.2.0)": - dependencies: - react: 19.2.0 - optionalDependencies: - "@types/react": 19.2.2 - - "@radix-ui/react-focus-scope@1.1.7(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)": - dependencies: - "@radix-ui/react-compose-refs": 1.1.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-primitive": 2.1.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-use-callback-ref": 1.1.1(@types/react@19.2.2)(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - optionalDependencies: - "@types/react": 19.2.2 - "@types/react-dom": 19.2.2(@types/react@19.2.2) - - "@radix-ui/react-form@0.1.8(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)": - dependencies: - "@radix-ui/primitive": 1.1.3 - "@radix-ui/react-compose-refs": 1.1.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-context": 1.1.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-id": 1.1.1(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-label": 2.1.7(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-primitive": 2.1.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - optionalDependencies: - "@types/react": 19.2.2 - "@types/react-dom": 19.2.2(@types/react@19.2.2) - - "@radix-ui/react-hover-card@1.1.15(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)": - dependencies: - "@radix-ui/primitive": 1.1.3 - "@radix-ui/react-compose-refs": 1.1.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-context": 1.1.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-dismissable-layer": 1.1.11(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-popper": 1.2.8(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-portal": 1.1.9(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-presence": 1.1.5(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-primitive": 2.1.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-use-controllable-state": 1.2.2(@types/react@19.2.2)(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - optionalDependencies: - "@types/react": 19.2.2 - "@types/react-dom": 19.2.2(@types/react@19.2.2) - - "@radix-ui/react-id@1.1.1(@types/react@19.2.2)(react@19.2.0)": - dependencies: - "@radix-ui/react-use-layout-effect": 1.1.1(@types/react@19.2.2)(react@19.2.0) - react: 19.2.0 - optionalDependencies: - "@types/react": 19.2.2 - - "@radix-ui/react-label@2.1.7(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)": - dependencies: - "@radix-ui/react-primitive": 2.1.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - optionalDependencies: - "@types/react": 19.2.2 - "@types/react-dom": 19.2.2(@types/react@19.2.2) - - "@radix-ui/react-menu@2.1.16(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)": - dependencies: - "@radix-ui/primitive": 1.1.3 - "@radix-ui/react-collection": 1.1.7(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-compose-refs": 1.1.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-context": 1.1.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-direction": 1.1.1(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-dismissable-layer": 1.1.11(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-focus-guards": 1.1.3(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-focus-scope": 1.1.7(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-id": 1.1.1(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-popper": 1.2.8(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-portal": 1.1.9(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-presence": 1.1.5(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-primitive": 2.1.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-roving-focus": 1.1.11(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-slot": 1.2.3(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-use-callback-ref": 1.1.1(@types/react@19.2.2)(react@19.2.0) - aria-hidden: 1.2.6 - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - react-remove-scroll: 2.7.1(@types/react@19.2.2)(react@19.2.0) - optionalDependencies: - "@types/react": 19.2.2 - "@types/react-dom": 19.2.2(@types/react@19.2.2) - - "@radix-ui/react-menubar@1.1.16(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)": - dependencies: - "@radix-ui/primitive": 1.1.3 - "@radix-ui/react-collection": 1.1.7(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-compose-refs": 1.1.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-context": 1.1.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-direction": 1.1.1(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-id": 1.1.1(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-menu": 2.1.16(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-primitive": 2.1.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-roving-focus": 1.1.11(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-use-controllable-state": 1.2.2(@types/react@19.2.2)(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - optionalDependencies: - "@types/react": 19.2.2 - "@types/react-dom": 19.2.2(@types/react@19.2.2) - - "@radix-ui/react-navigation-menu@1.2.14(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)": - dependencies: - "@radix-ui/primitive": 1.1.3 - "@radix-ui/react-collection": 1.1.7(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-compose-refs": 1.1.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-context": 1.1.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-direction": 1.1.1(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-dismissable-layer": 1.1.11(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-id": 1.1.1(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-presence": 1.1.5(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-primitive": 2.1.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-use-callback-ref": 1.1.1(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-use-controllable-state": 1.2.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-use-layout-effect": 1.1.1(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-use-previous": 1.1.1(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-visually-hidden": 1.2.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - optionalDependencies: - "@types/react": 19.2.2 - "@types/react-dom": 19.2.2(@types/react@19.2.2) - - "@radix-ui/react-one-time-password-field@0.1.8(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)": - dependencies: - "@radix-ui/number": 1.1.1 - "@radix-ui/primitive": 1.1.3 - "@radix-ui/react-collection": 1.1.7(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-compose-refs": 1.1.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-context": 1.1.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-direction": 1.1.1(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-primitive": 2.1.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-roving-focus": 1.1.11(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-use-controllable-state": 1.2.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-use-effect-event": 0.0.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-use-is-hydrated": 0.1.0(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-use-layout-effect": 1.1.1(@types/react@19.2.2)(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - optionalDependencies: - "@types/react": 19.2.2 - "@types/react-dom": 19.2.2(@types/react@19.2.2) - - "@radix-ui/react-password-toggle-field@0.1.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)": - dependencies: - "@radix-ui/primitive": 1.1.3 - "@radix-ui/react-compose-refs": 1.1.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-context": 1.1.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-id": 1.1.1(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-primitive": 2.1.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-use-controllable-state": 1.2.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-use-effect-event": 0.0.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-use-is-hydrated": 0.1.0(@types/react@19.2.2)(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - optionalDependencies: - "@types/react": 19.2.2 - "@types/react-dom": 19.2.2(@types/react@19.2.2) - - "@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)": - dependencies: - "@radix-ui/primitive": 1.1.3 - "@radix-ui/react-compose-refs": 1.1.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-context": 1.1.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-dismissable-layer": 1.1.11(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-focus-guards": 1.1.3(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-focus-scope": 1.1.7(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-id": 1.1.1(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-popper": 1.2.8(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-portal": 1.1.9(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-presence": 1.1.5(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-primitive": 2.1.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-slot": 1.2.3(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-use-controllable-state": 1.2.2(@types/react@19.2.2)(react@19.2.0) - aria-hidden: 1.2.6 - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - react-remove-scroll: 2.7.1(@types/react@19.2.2)(react@19.2.0) - optionalDependencies: - "@types/react": 19.2.2 - "@types/react-dom": 19.2.2(@types/react@19.2.2) - - "@radix-ui/react-popper@1.2.8(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)": - dependencies: - "@floating-ui/react-dom": 2.1.6(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-arrow": 1.1.7(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-compose-refs": 1.1.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-context": 1.1.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-primitive": 2.1.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-use-callback-ref": 1.1.1(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-use-layout-effect": 1.1.1(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-use-rect": 1.1.1(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-use-size": 1.1.1(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/rect": 1.1.1 - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - optionalDependencies: - "@types/react": 19.2.2 - "@types/react-dom": 19.2.2(@types/react@19.2.2) - - "@radix-ui/react-portal@1.1.9(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)": - dependencies: - "@radix-ui/react-primitive": 2.1.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-use-layout-effect": 1.1.1(@types/react@19.2.2)(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - optionalDependencies: - "@types/react": 19.2.2 - "@types/react-dom": 19.2.2(@types/react@19.2.2) - - "@radix-ui/react-presence@1.1.5(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)": - dependencies: - "@radix-ui/react-compose-refs": 1.1.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-use-layout-effect": 1.1.1(@types/react@19.2.2)(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - optionalDependencies: - "@types/react": 19.2.2 - "@types/react-dom": 19.2.2(@types/react@19.2.2) - - "@radix-ui/react-primitive@2.1.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)": - dependencies: - "@radix-ui/react-slot": 1.2.3(@types/react@19.2.2)(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - optionalDependencies: - "@types/react": 19.2.2 - "@types/react-dom": 19.2.2(@types/react@19.2.2) - - "@radix-ui/react-progress@1.1.7(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)": - dependencies: - "@radix-ui/react-context": 1.1.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-primitive": 2.1.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - optionalDependencies: - "@types/react": 19.2.2 - "@types/react-dom": 19.2.2(@types/react@19.2.2) - - "@radix-ui/react-radio-group@1.3.8(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)": - dependencies: - "@radix-ui/primitive": 1.1.3 - "@radix-ui/react-compose-refs": 1.1.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-context": 1.1.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-direction": 1.1.1(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-presence": 1.1.5(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-primitive": 2.1.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-roving-focus": 1.1.11(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-use-controllable-state": 1.2.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-use-previous": 1.1.1(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-use-size": 1.1.1(@types/react@19.2.2)(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - optionalDependencies: - "@types/react": 19.2.2 - "@types/react-dom": 19.2.2(@types/react@19.2.2) - - "@radix-ui/react-roving-focus@1.1.11(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)": - dependencies: - "@radix-ui/primitive": 1.1.3 - "@radix-ui/react-collection": 1.1.7(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-compose-refs": 1.1.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-context": 1.1.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-direction": 1.1.1(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-id": 1.1.1(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-primitive": 2.1.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-use-callback-ref": 1.1.1(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-use-controllable-state": 1.2.2(@types/react@19.2.2)(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - optionalDependencies: - "@types/react": 19.2.2 - "@types/react-dom": 19.2.2(@types/react@19.2.2) - - "@radix-ui/react-scroll-area@1.2.10(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)": - dependencies: - "@radix-ui/number": 1.1.1 - "@radix-ui/primitive": 1.1.3 - "@radix-ui/react-compose-refs": 1.1.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-context": 1.1.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-direction": 1.1.1(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-presence": 1.1.5(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-primitive": 2.1.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-use-callback-ref": 1.1.1(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-use-layout-effect": 1.1.1(@types/react@19.2.2)(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - optionalDependencies: - "@types/react": 19.2.2 - "@types/react-dom": 19.2.2(@types/react@19.2.2) - - "@radix-ui/react-select@2.2.6(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)": - dependencies: - "@radix-ui/number": 1.1.1 - "@radix-ui/primitive": 1.1.3 - "@radix-ui/react-collection": 1.1.7(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-compose-refs": 1.1.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-context": 1.1.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-direction": 1.1.1(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-dismissable-layer": 1.1.11(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-focus-guards": 1.1.3(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-focus-scope": 1.1.7(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-id": 1.1.1(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-popper": 1.2.8(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-portal": 1.1.9(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-primitive": 2.1.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-slot": 1.2.3(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-use-callback-ref": 1.1.1(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-use-controllable-state": 1.2.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-use-layout-effect": 1.1.1(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-use-previous": 1.1.1(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-visually-hidden": 1.2.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - aria-hidden: 1.2.6 - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - react-remove-scroll: 2.7.1(@types/react@19.2.2)(react@19.2.0) - optionalDependencies: - "@types/react": 19.2.2 - "@types/react-dom": 19.2.2(@types/react@19.2.2) - - "@radix-ui/react-separator@1.1.7(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)": - dependencies: - "@radix-ui/react-primitive": 2.1.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - optionalDependencies: - "@types/react": 19.2.2 - "@types/react-dom": 19.2.2(@types/react@19.2.2) - - "@radix-ui/react-slider@1.3.6(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)": - dependencies: - "@radix-ui/number": 1.1.1 - "@radix-ui/primitive": 1.1.3 - "@radix-ui/react-collection": 1.1.7(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-compose-refs": 1.1.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-context": 1.1.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-direction": 1.1.1(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-primitive": 2.1.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-use-controllable-state": 1.2.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-use-layout-effect": 1.1.1(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-use-previous": 1.1.1(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-use-size": 1.1.1(@types/react@19.2.2)(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - optionalDependencies: - "@types/react": 19.2.2 - "@types/react-dom": 19.2.2(@types/react@19.2.2) - - "@radix-ui/react-slot@1.2.3(@types/react@19.2.2)(react@19.2.0)": - dependencies: - "@radix-ui/react-compose-refs": 1.1.2(@types/react@19.2.2)(react@19.2.0) - react: 19.2.0 - optionalDependencies: - "@types/react": 19.2.2 - - "@radix-ui/react-switch@1.2.6(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)": - dependencies: - "@radix-ui/primitive": 1.1.3 - "@radix-ui/react-compose-refs": 1.1.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-context": 1.1.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-primitive": 2.1.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-use-controllable-state": 1.2.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-use-previous": 1.1.1(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-use-size": 1.1.1(@types/react@19.2.2)(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - optionalDependencies: - "@types/react": 19.2.2 - "@types/react-dom": 19.2.2(@types/react@19.2.2) - - "@radix-ui/react-tabs@1.1.13(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)": - dependencies: - "@radix-ui/primitive": 1.1.3 - "@radix-ui/react-context": 1.1.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-direction": 1.1.1(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-id": 1.1.1(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-presence": 1.1.5(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-primitive": 2.1.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-roving-focus": 1.1.11(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-use-controllable-state": 1.2.2(@types/react@19.2.2)(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - optionalDependencies: - "@types/react": 19.2.2 - "@types/react-dom": 19.2.2(@types/react@19.2.2) - - "@radix-ui/react-toast@1.2.15(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)": - dependencies: - "@radix-ui/primitive": 1.1.3 - "@radix-ui/react-collection": 1.1.7(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-compose-refs": 1.1.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-context": 1.1.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-dismissable-layer": 1.1.11(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-portal": 1.1.9(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-presence": 1.1.5(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-primitive": 2.1.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-use-callback-ref": 1.1.1(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-use-controllable-state": 1.2.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-use-layout-effect": 1.1.1(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-visually-hidden": 1.2.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - optionalDependencies: - "@types/react": 19.2.2 - "@types/react-dom": 19.2.2(@types/react@19.2.2) - - "@radix-ui/react-toggle-group@1.1.11(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)": - dependencies: - "@radix-ui/primitive": 1.1.3 - "@radix-ui/react-context": 1.1.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-direction": 1.1.1(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-primitive": 2.1.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-roving-focus": 1.1.11(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-toggle": 1.1.10(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-use-controllable-state": 1.2.2(@types/react@19.2.2)(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - optionalDependencies: - "@types/react": 19.2.2 - "@types/react-dom": 19.2.2(@types/react@19.2.2) - - "@radix-ui/react-toggle@1.1.10(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)": - dependencies: - "@radix-ui/primitive": 1.1.3 - "@radix-ui/react-primitive": 2.1.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-use-controllable-state": 1.2.2(@types/react@19.2.2)(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - optionalDependencies: - "@types/react": 19.2.2 - "@types/react-dom": 19.2.2(@types/react@19.2.2) - - "@radix-ui/react-toolbar@1.1.11(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)": - dependencies: - "@radix-ui/primitive": 1.1.3 - "@radix-ui/react-context": 1.1.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-direction": 1.1.1(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-primitive": 2.1.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-roving-focus": 1.1.11(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-separator": 1.1.7(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-toggle-group": 1.1.11(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - optionalDependencies: - "@types/react": 19.2.2 - "@types/react-dom": 19.2.2(@types/react@19.2.2) - - "@radix-ui/react-tooltip@1.2.8(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)": - dependencies: - "@radix-ui/primitive": 1.1.3 - "@radix-ui/react-compose-refs": 1.1.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-context": 1.1.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-dismissable-layer": 1.1.11(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-id": 1.1.1(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-popper": 1.2.8(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-portal": 1.1.9(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-presence": 1.1.5(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-primitive": 2.1.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-slot": 1.2.3(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-use-controllable-state": 1.2.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-visually-hidden": 1.2.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - optionalDependencies: - "@types/react": 19.2.2 - "@types/react-dom": 19.2.2(@types/react@19.2.2) - - "@radix-ui/react-use-callback-ref@1.1.1(@types/react@19.2.2)(react@19.2.0)": - dependencies: - react: 19.2.0 - optionalDependencies: - "@types/react": 19.2.2 - - "@radix-ui/react-use-controllable-state@1.2.2(@types/react@19.2.2)(react@19.2.0)": - dependencies: - "@radix-ui/react-use-effect-event": 0.0.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-use-layout-effect": 1.1.1(@types/react@19.2.2)(react@19.2.0) - react: 19.2.0 - optionalDependencies: - "@types/react": 19.2.2 - - "@radix-ui/react-use-effect-event@0.0.2(@types/react@19.2.2)(react@19.2.0)": - dependencies: - "@radix-ui/react-use-layout-effect": 1.1.1(@types/react@19.2.2)(react@19.2.0) - react: 19.2.0 - optionalDependencies: - "@types/react": 19.2.2 - - "@radix-ui/react-use-escape-keydown@1.1.1(@types/react@19.2.2)(react@19.2.0)": - dependencies: - "@radix-ui/react-use-callback-ref": 1.1.1(@types/react@19.2.2)(react@19.2.0) - react: 19.2.0 - optionalDependencies: - "@types/react": 19.2.2 - - "@radix-ui/react-use-is-hydrated@0.1.0(@types/react@19.2.2)(react@19.2.0)": - dependencies: - react: 19.2.0 - use-sync-external-store: 1.6.0(react@19.2.0) - optionalDependencies: - "@types/react": 19.2.2 - - "@radix-ui/react-use-layout-effect@1.1.1(@types/react@19.2.2)(react@19.2.0)": - dependencies: - react: 19.2.0 - optionalDependencies: - "@types/react": 19.2.2 - - "@radix-ui/react-use-previous@1.1.1(@types/react@19.2.2)(react@19.2.0)": - dependencies: - react: 19.2.0 - optionalDependencies: - "@types/react": 19.2.2 - - "@radix-ui/react-use-rect@1.1.1(@types/react@19.2.2)(react@19.2.0)": - dependencies: - "@radix-ui/rect": 1.1.1 - react: 19.2.0 - optionalDependencies: - "@types/react": 19.2.2 - - "@radix-ui/react-use-size@1.1.1(@types/react@19.2.2)(react@19.2.0)": - dependencies: - "@radix-ui/react-use-layout-effect": 1.1.1(@types/react@19.2.2)(react@19.2.0) - react: 19.2.0 - optionalDependencies: - "@types/react": 19.2.2 - - "@radix-ui/react-visually-hidden@1.2.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)": - dependencies: - "@radix-ui/react-primitive": 2.1.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - optionalDependencies: - "@types/react": 19.2.2 - "@types/react-dom": 19.2.2(@types/react@19.2.2) - - "@radix-ui/rect@1.1.1": {} - - "@rolldown/binding-android-arm64@1.0.0-beta.41": - optional: true - - "@rolldown/binding-darwin-arm64@1.0.0-beta.41": - optional: true - - "@rolldown/binding-darwin-x64@1.0.0-beta.41": - optional: true - - "@rolldown/binding-freebsd-x64@1.0.0-beta.41": - optional: true - - "@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.41": - optional: true - - "@rolldown/binding-linux-arm64-gnu@1.0.0-beta.41": - optional: true - - "@rolldown/binding-linux-arm64-musl@1.0.0-beta.41": - optional: true - - "@rolldown/binding-linux-x64-gnu@1.0.0-beta.41": - optional: true - - "@rolldown/binding-linux-x64-musl@1.0.0-beta.41": - optional: true - - "@rolldown/binding-openharmony-arm64@1.0.0-beta.41": - optional: true - - "@rolldown/binding-wasm32-wasi@1.0.0-beta.41": - dependencies: - "@napi-rs/wasm-runtime": 1.0.7 - optional: true - - "@rolldown/binding-win32-arm64-msvc@1.0.0-beta.41": - optional: true - - "@rolldown/binding-win32-ia32-msvc@1.0.0-beta.41": - optional: true - - "@rolldown/binding-win32-x64-msvc@1.0.0-beta.41": - optional: true - - "@rolldown/pluginutils@1.0.0-beta.41": {} - - "@rolldown/pluginutils@1.0.0-beta.43": {} - - "@standard-schema/utils@0.3.0": {} - - "@swc/core-darwin-arm64@1.14.0": - optional: true - - "@swc/core-darwin-x64@1.14.0": - optional: true - - "@swc/core-linux-arm-gnueabihf@1.14.0": - optional: true - - "@swc/core-linux-arm64-gnu@1.14.0": - optional: true - - "@swc/core-linux-arm64-musl@1.14.0": - optional: true - - "@swc/core-linux-x64-gnu@1.14.0": - optional: true - - "@swc/core-linux-x64-musl@1.14.0": - optional: true - - "@swc/core-win32-arm64-msvc@1.14.0": - optional: true - - "@swc/core-win32-ia32-msvc@1.14.0": - optional: true - - "@swc/core-win32-x64-msvc@1.14.0": - optional: true - - "@swc/core@1.14.0": - dependencies: - "@swc/counter": 0.1.3 - "@swc/types": 0.1.25 - optionalDependencies: - "@swc/core-darwin-arm64": 1.14.0 - "@swc/core-darwin-x64": 1.14.0 - "@swc/core-linux-arm-gnueabihf": 1.14.0 - "@swc/core-linux-arm64-gnu": 1.14.0 - "@swc/core-linux-arm64-musl": 1.14.0 - "@swc/core-linux-x64-gnu": 1.14.0 - "@swc/core-linux-x64-musl": 1.14.0 - "@swc/core-win32-arm64-msvc": 1.14.0 - "@swc/core-win32-ia32-msvc": 1.14.0 - "@swc/core-win32-x64-msvc": 1.14.0 - - "@swc/counter@0.1.3": {} - - "@swc/types@0.1.25": - dependencies: - "@swc/counter": 0.1.3 - - "@tailwindcss/node@4.1.16": - dependencies: - "@jridgewell/remapping": 2.3.5 - enhanced-resolve: 5.18.3 - jiti: 2.6.1 - lightningcss: 1.30.2 - magic-string: 0.30.21 - source-map-js: 1.2.1 - tailwindcss: 4.1.16 - - "@tailwindcss/oxide-android-arm64@4.1.16": - optional: true - - "@tailwindcss/oxide-darwin-arm64@4.1.16": - optional: true - - "@tailwindcss/oxide-darwin-x64@4.1.16": - optional: true - - "@tailwindcss/oxide-freebsd-x64@4.1.16": - optional: true - - "@tailwindcss/oxide-linux-arm-gnueabihf@4.1.16": - optional: true - - "@tailwindcss/oxide-linux-arm64-gnu@4.1.16": - optional: true - - "@tailwindcss/oxide-linux-arm64-musl@4.1.16": - optional: true - - "@tailwindcss/oxide-linux-x64-gnu@4.1.16": - optional: true - - "@tailwindcss/oxide-linux-x64-musl@4.1.16": - optional: true - - "@tailwindcss/oxide-wasm32-wasi@4.1.16": - optional: true - - "@tailwindcss/oxide-win32-arm64-msvc@4.1.16": - optional: true - - "@tailwindcss/oxide-win32-x64-msvc@4.1.16": - optional: true - - "@tailwindcss/oxide@4.1.16": - optionalDependencies: - "@tailwindcss/oxide-android-arm64": 4.1.16 - "@tailwindcss/oxide-darwin-arm64": 4.1.16 - "@tailwindcss/oxide-darwin-x64": 4.1.16 - "@tailwindcss/oxide-freebsd-x64": 4.1.16 - "@tailwindcss/oxide-linux-arm-gnueabihf": 4.1.16 - "@tailwindcss/oxide-linux-arm64-gnu": 4.1.16 - "@tailwindcss/oxide-linux-arm64-musl": 4.1.16 - "@tailwindcss/oxide-linux-x64-gnu": 4.1.16 - "@tailwindcss/oxide-linux-x64-musl": 4.1.16 - "@tailwindcss/oxide-wasm32-wasi": 4.1.16 - "@tailwindcss/oxide-win32-arm64-msvc": 4.1.16 - "@tailwindcss/oxide-win32-x64-msvc": 4.1.16 - - "@tailwindcss/vite@4.1.16(rolldown-vite@7.1.14(@types/node@24.9.2)(esbuild@0.25.12)(jiti@2.6.1)(tsx@4.20.6))": - dependencies: - "@tailwindcss/node": 4.1.16 - "@tailwindcss/oxide": 4.1.16 - tailwindcss: 4.1.16 - vite: rolldown-vite@7.1.14(@types/node@24.9.2)(esbuild@0.25.12)(jiti@2.6.1)(tsx@4.20.6) - - "@tanstack/history@1.133.28": {} - - "@tanstack/query-core@5.90.6": {} - - "@tanstack/react-query@5.90.6(react@19.2.0)": - dependencies: - "@tanstack/query-core": 5.90.6 - react: 19.2.0 - - "@tanstack/react-router@1.134.9(react-dom@19.2.0(react@19.2.0))(react@19.2.0)": - dependencies: - "@tanstack/history": 1.133.28 - "@tanstack/react-store": 0.8.0(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@tanstack/router-core": 1.134.9 - isbot: 5.1.31 - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - tiny-invariant: 1.3.3 - tiny-warning: 1.0.3 - - "@tanstack/react-store@0.8.0(react-dom@19.2.0(react@19.2.0))(react@19.2.0)": - dependencies: - "@tanstack/store": 0.8.0 - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - use-sync-external-store: 1.6.0(react@19.2.0) - - "@tanstack/router-cli@1.134.9": - dependencies: - "@tanstack/router-generator": 1.134.9 - chokidar: 3.6.0 - yargs: 17.7.2 - transitivePeerDependencies: - - supports-color - - "@tanstack/router-core@1.134.9": - dependencies: - "@tanstack/history": 1.133.28 - "@tanstack/store": 0.8.0 - cookie-es: 2.0.0 - seroval: 1.3.2 - seroval-plugins: 1.3.3(seroval@1.3.2) - tiny-invariant: 1.3.3 - tiny-warning: 1.0.3 - - "@tanstack/router-generator@1.134.9": - dependencies: - "@tanstack/router-core": 1.134.9 - "@tanstack/router-utils": 1.133.19 - "@tanstack/virtual-file-routes": 1.133.19 - prettier: 3.6.2 - recast: 0.23.11 - source-map: 0.7.6 - tsx: 4.20.6 - zod: 3.25.76 - transitivePeerDependencies: - - supports-color - - "@tanstack/router-plugin@1.134.9(@tanstack/react-router@1.134.9(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(rolldown-vite@7.1.14(@types/node@24.9.2)(esbuild@0.25.12)(jiti@2.6.1)(tsx@4.20.6))": - dependencies: - "@babel/core": 7.28.5 - "@babel/plugin-syntax-jsx": 7.27.1(@babel/core@7.28.5) - "@babel/plugin-syntax-typescript": 7.27.1(@babel/core@7.28.5) - "@babel/template": 7.27.2 - "@babel/traverse": 7.28.5 - "@babel/types": 7.28.5 - "@tanstack/router-core": 1.134.9 - "@tanstack/router-generator": 1.134.9 - "@tanstack/router-utils": 1.133.19 - "@tanstack/virtual-file-routes": 1.133.19 - babel-dead-code-elimination: 1.0.10 - chokidar: 3.6.0 - unplugin: 2.3.10 - zod: 3.25.76 - optionalDependencies: - "@tanstack/react-router": 1.134.9(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - vite: rolldown-vite@7.1.14(@types/node@24.9.2)(esbuild@0.25.12)(jiti@2.6.1)(tsx@4.20.6) - transitivePeerDependencies: - - supports-color - - "@tanstack/router-utils@1.133.19": - dependencies: - "@babel/core": 7.28.5 - "@babel/generator": 7.28.5 - "@babel/parser": 7.28.5 - "@babel/preset-typescript": 7.28.5(@babel/core@7.28.5) - ansis: 4.2.0 - diff: 8.0.2 - pathe: 2.0.3 - tinyglobby: 0.2.15 - transitivePeerDependencies: - - supports-color - - "@tanstack/store@0.8.0": {} - - "@tanstack/virtual-file-routes@1.133.19": {} - - "@trpc/client@11.7.1(@trpc/server@11.7.1(typescript@5.9.3))(typescript@5.9.3)": - dependencies: - "@trpc/server": 11.7.1(typescript@5.9.3) - typescript: 5.9.3 - - "@trpc/react-query@11.7.1(@tanstack/react-query@5.90.6(react@19.2.0))(@trpc/client@11.7.1(@trpc/server@11.7.1(typescript@5.9.3))(typescript@5.9.3))(@trpc/server@11.7.1(typescript@5.9.3))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.9.3)": - dependencies: - "@tanstack/react-query": 5.90.6(react@19.2.0) - "@trpc/client": 11.7.1(@trpc/server@11.7.1(typescript@5.9.3))(typescript@5.9.3) - "@trpc/server": 11.7.1(typescript@5.9.3) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - typescript: 5.9.3 - - "@trpc/server@11.7.1(typescript@5.9.3)": - dependencies: - typescript: 5.9.3 - - "@tybys/wasm-util@0.10.1": - dependencies: - tslib: 2.8.1 - optional: true - - "@types/babel__core@7.20.5": - dependencies: - "@babel/parser": 7.28.5 - "@babel/types": 7.28.5 - "@types/babel__generator": 7.27.0 - "@types/babel__template": 7.4.4 - "@types/babel__traverse": 7.28.0 - - "@types/babel__generator@7.27.0": - dependencies: - "@babel/types": 7.28.5 - - "@types/babel__template@7.4.4": - dependencies: - "@babel/parser": 7.28.5 - "@babel/types": 7.28.5 - - "@types/babel__traverse@7.28.0": - dependencies: - "@babel/types": 7.28.5 - - "@types/estree@1.0.8": {} - - "@types/json-schema@7.0.15": {} - - "@types/node@24.9.2": - dependencies: - undici-types: 7.16.0 - - "@types/react-dom@19.2.2(@types/react@19.2.2)": - dependencies: - "@types/react": 19.2.2 - - "@types/react@19.2.2": - dependencies: - csstype: 3.1.3 - - "@typescript-eslint/eslint-plugin@8.46.2(@typescript-eslint/parser@8.46.2(eslint@9.39.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.0(jiti@2.6.1))(typescript@5.9.3)": - dependencies: - "@eslint-community/regexpp": 4.12.2 - "@typescript-eslint/parser": 8.46.2(eslint@9.39.0(jiti@2.6.1))(typescript@5.9.3) - "@typescript-eslint/scope-manager": 8.46.2 - "@typescript-eslint/type-utils": 8.46.2(eslint@9.39.0(jiti@2.6.1))(typescript@5.9.3) - "@typescript-eslint/utils": 8.46.2(eslint@9.39.0(jiti@2.6.1))(typescript@5.9.3) - "@typescript-eslint/visitor-keys": 8.46.2 - eslint: 9.39.0(jiti@2.6.1) - graphemer: 1.4.0 - ignore: 7.0.5 - natural-compare: 1.4.0 - ts-api-utils: 2.1.0(typescript@5.9.3) - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - - "@typescript-eslint/parser@8.46.2(eslint@9.39.0(jiti@2.6.1))(typescript@5.9.3)": - dependencies: - "@typescript-eslint/scope-manager": 8.46.2 - "@typescript-eslint/types": 8.46.2 - "@typescript-eslint/typescript-estree": 8.46.2(typescript@5.9.3) - "@typescript-eslint/visitor-keys": 8.46.2 - debug: 4.4.3 - eslint: 9.39.0(jiti@2.6.1) - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - - "@typescript-eslint/project-service@8.46.2(typescript@5.9.3)": - dependencies: - "@typescript-eslint/tsconfig-utils": 8.46.2(typescript@5.9.3) - "@typescript-eslint/types": 8.46.2 - debug: 4.4.3 - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - - "@typescript-eslint/scope-manager@8.46.2": - dependencies: - "@typescript-eslint/types": 8.46.2 - "@typescript-eslint/visitor-keys": 8.46.2 - - "@typescript-eslint/tsconfig-utils@8.46.2(typescript@5.9.3)": - dependencies: - typescript: 5.9.3 - - "@typescript-eslint/type-utils@8.46.2(eslint@9.39.0(jiti@2.6.1))(typescript@5.9.3)": - dependencies: - "@typescript-eslint/types": 8.46.2 - "@typescript-eslint/typescript-estree": 8.46.2(typescript@5.9.3) - "@typescript-eslint/utils": 8.46.2(eslint@9.39.0(jiti@2.6.1))(typescript@5.9.3) - debug: 4.4.3 - eslint: 9.39.0(jiti@2.6.1) - ts-api-utils: 2.1.0(typescript@5.9.3) - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - - "@typescript-eslint/types@8.46.2": {} - - "@typescript-eslint/typescript-estree@8.46.2(typescript@5.9.3)": - dependencies: - "@typescript-eslint/project-service": 8.46.2(typescript@5.9.3) - "@typescript-eslint/tsconfig-utils": 8.46.2(typescript@5.9.3) - "@typescript-eslint/types": 8.46.2 - "@typescript-eslint/visitor-keys": 8.46.2 - debug: 4.4.3 - fast-glob: 3.3.3 - is-glob: 4.0.3 - minimatch: 9.0.5 - semver: 7.7.3 - ts-api-utils: 2.1.0(typescript@5.9.3) - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - - "@typescript-eslint/utils@8.46.2(eslint@9.39.0(jiti@2.6.1))(typescript@5.9.3)": - dependencies: - "@eslint-community/eslint-utils": 4.9.0(eslint@9.39.0(jiti@2.6.1)) - "@typescript-eslint/scope-manager": 8.46.2 - "@typescript-eslint/types": 8.46.2 - "@typescript-eslint/typescript-estree": 8.46.2(typescript@5.9.3) - eslint: 9.39.0(jiti@2.6.1) - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - - "@typescript-eslint/visitor-keys@8.46.2": - dependencies: - "@typescript-eslint/types": 8.46.2 - eslint-visitor-keys: 4.2.1 - - "@vitejs/plugin-react-swc@4.2.0(rolldown-vite@7.1.14(@types/node@24.9.2)(esbuild@0.25.12)(jiti@2.6.1)(tsx@4.20.6))": - dependencies: - "@rolldown/pluginutils": 1.0.0-beta.43 - "@swc/core": 1.14.0 - vite: rolldown-vite@7.1.14(@types/node@24.9.2)(esbuild@0.25.12)(jiti@2.6.1)(tsx@4.20.6) - transitivePeerDependencies: - - "@swc/helpers" - - "@vitejs/plugin-react@5.1.0(rolldown-vite@7.1.14(@types/node@24.9.2)(esbuild@0.25.12)(jiti@2.6.1)(tsx@4.20.6))": - dependencies: - "@babel/core": 7.28.5 - "@babel/plugin-transform-react-jsx-self": 7.27.1(@babel/core@7.28.5) - "@babel/plugin-transform-react-jsx-source": 7.27.1(@babel/core@7.28.5) - "@rolldown/pluginutils": 1.0.0-beta.43 - "@types/babel__core": 7.20.5 - react-refresh: 0.18.0 - vite: rolldown-vite@7.1.14(@types/node@24.9.2)(esbuild@0.25.12)(jiti@2.6.1)(tsx@4.20.6) - transitivePeerDependencies: - - supports-color - - acorn-jsx@5.3.2(acorn@8.15.0): - dependencies: - acorn: 8.15.0 - - acorn@8.15.0: {} - - ajv@6.12.6: - dependencies: - fast-deep-equal: 3.1.3 - fast-json-stable-stringify: 2.1.0 - json-schema-traverse: 0.4.1 - uri-js: 4.4.1 - - ansi-regex@5.0.1: {} - - ansi-styles@4.3.0: - dependencies: - color-convert: 2.0.1 - - ansis@4.2.0: {} - - anymatch@3.1.3: - dependencies: - normalize-path: 3.0.0 - picomatch: 2.3.1 - - argparse@2.0.1: {} - - aria-hidden@1.2.6: - dependencies: - tslib: 2.8.1 - - ast-types@0.16.1: - dependencies: - tslib: 2.8.1 - - babel-dead-code-elimination@1.0.10: - dependencies: - "@babel/core": 7.28.5 - "@babel/parser": 7.28.5 - "@babel/traverse": 7.28.5 - "@babel/types": 7.28.5 - transitivePeerDependencies: - - supports-color - - balanced-match@1.0.2: {} - - baseline-browser-mapping@2.8.23: {} - - binary-extensions@2.3.0: {} - - brace-expansion@1.1.12: - dependencies: - balanced-match: 1.0.2 - concat-map: 0.0.1 - - brace-expansion@2.0.2: - dependencies: - balanced-match: 1.0.2 - - braces@3.0.3: - dependencies: - fill-range: 7.1.1 - - browserslist@4.27.0: - dependencies: - baseline-browser-mapping: 2.8.23 - caniuse-lite: 1.0.30001753 - electron-to-chromium: 1.5.244 - node-releases: 2.0.27 - update-browserslist-db: 1.1.4(browserslist@4.27.0) - - callsites@3.1.0: {} - - caniuse-lite@1.0.30001753: {} - - chalk@4.1.2: - dependencies: - ansi-styles: 4.3.0 - supports-color: 7.2.0 - - chokidar@3.6.0: - dependencies: - anymatch: 3.1.3 - braces: 3.0.3 - glob-parent: 5.1.2 - is-binary-path: 2.1.0 - is-glob: 4.0.3 - normalize-path: 3.0.0 - readdirp: 3.6.0 - optionalDependencies: - fsevents: 2.3.3 - - class-variance-authority@0.7.1: - dependencies: - clsx: 2.1.1 - - cliui@8.0.1: - dependencies: - string-width: 4.2.3 - strip-ansi: 6.0.1 - wrap-ansi: 7.0.0 - - clsx@2.1.1: {} - - color-convert@2.0.1: - dependencies: - color-name: 1.1.4 - - color-name@1.1.4: {} - - concat-map@0.0.1: {} - - convert-source-map@2.0.0: {} - - cookie-es@2.0.0: {} - - cross-spawn@7.0.6: - dependencies: - path-key: 3.1.1 - shebang-command: 2.0.0 - which: 2.0.2 - - csstype@3.1.3: {} - - debug@4.4.3: - dependencies: - ms: 2.1.3 - - deep-is@0.1.4: {} - - detect-libc@2.1.2: {} - - detect-node-es@1.1.0: {} - - diff@8.0.2: {} - - electron-to-chromium@1.5.244: {} - - emoji-regex@8.0.0: {} - - enhanced-resolve@5.18.3: - dependencies: - graceful-fs: 4.2.11 - tapable: 2.3.0 - - esbuild@0.25.12: - optionalDependencies: - "@esbuild/aix-ppc64": 0.25.12 - "@esbuild/android-arm": 0.25.12 - "@esbuild/android-arm64": 0.25.12 - "@esbuild/android-x64": 0.25.12 - "@esbuild/darwin-arm64": 0.25.12 - "@esbuild/darwin-x64": 0.25.12 - "@esbuild/freebsd-arm64": 0.25.12 - "@esbuild/freebsd-x64": 0.25.12 - "@esbuild/linux-arm": 0.25.12 - "@esbuild/linux-arm64": 0.25.12 - "@esbuild/linux-ia32": 0.25.12 - "@esbuild/linux-loong64": 0.25.12 - "@esbuild/linux-mips64el": 0.25.12 - "@esbuild/linux-ppc64": 0.25.12 - "@esbuild/linux-riscv64": 0.25.12 - "@esbuild/linux-s390x": 0.25.12 - "@esbuild/linux-x64": 0.25.12 - "@esbuild/netbsd-arm64": 0.25.12 - "@esbuild/netbsd-x64": 0.25.12 - "@esbuild/openbsd-arm64": 0.25.12 - "@esbuild/openbsd-x64": 0.25.12 - "@esbuild/openharmony-arm64": 0.25.12 - "@esbuild/sunos-x64": 0.25.12 - "@esbuild/win32-arm64": 0.25.12 - "@esbuild/win32-ia32": 0.25.12 - "@esbuild/win32-x64": 0.25.12 - - escalade@3.2.0: {} - - escape-string-regexp@4.0.0: {} - - eslint-plugin-react-hooks@5.2.0(eslint@9.39.0(jiti@2.6.1)): - dependencies: - eslint: 9.39.0(jiti@2.6.1) - - eslint-plugin-react-refresh@0.4.24(eslint@9.39.0(jiti@2.6.1)): - dependencies: - eslint: 9.39.0(jiti@2.6.1) - - eslint-scope@8.4.0: - dependencies: - esrecurse: 4.3.0 - estraverse: 5.3.0 - - eslint-visitor-keys@3.4.3: {} - - eslint-visitor-keys@4.2.1: {} - - eslint@9.39.0(jiti@2.6.1): - dependencies: - "@eslint-community/eslint-utils": 4.9.0(eslint@9.39.0(jiti@2.6.1)) - "@eslint-community/regexpp": 4.12.2 - "@eslint/config-array": 0.21.1 - "@eslint/config-helpers": 0.4.2 - "@eslint/core": 0.17.0 - "@eslint/eslintrc": 3.3.1 - "@eslint/js": 9.39.0 - "@eslint/plugin-kit": 0.4.1 - "@humanfs/node": 0.16.7 - "@humanwhocodes/module-importer": 1.0.1 - "@humanwhocodes/retry": 0.4.3 - "@types/estree": 1.0.8 - ajv: 6.12.6 - chalk: 4.1.2 - cross-spawn: 7.0.6 - debug: 4.4.3 - escape-string-regexp: 4.0.0 - eslint-scope: 8.4.0 - eslint-visitor-keys: 4.2.1 - espree: 10.4.0 - esquery: 1.6.0 - esutils: 2.0.3 - fast-deep-equal: 3.1.3 - file-entry-cache: 8.0.0 - find-up: 5.0.0 - glob-parent: 6.0.2 - ignore: 5.3.2 - imurmurhash: 0.1.4 - is-glob: 4.0.3 - json-stable-stringify-without-jsonify: 1.0.1 - lodash.merge: 4.6.2 - minimatch: 3.1.2 - natural-compare: 1.4.0 - optionator: 0.9.4 - optionalDependencies: - jiti: 2.6.1 - transitivePeerDependencies: - - supports-color - - espree@10.4.0: - dependencies: - acorn: 8.15.0 - acorn-jsx: 5.3.2(acorn@8.15.0) - eslint-visitor-keys: 4.2.1 - - esprima@4.0.1: {} - - esquery@1.6.0: - dependencies: - estraverse: 5.3.0 - - esrecurse@4.3.0: - dependencies: - estraverse: 5.3.0 - - estraverse@5.3.0: {} - - esutils@2.0.3: {} - - fast-deep-equal@3.1.3: {} - - fast-glob@3.3.3: - dependencies: - "@nodelib/fs.stat": 2.0.5 - "@nodelib/fs.walk": 1.2.8 - glob-parent: 5.1.2 - merge2: 1.4.1 - micromatch: 4.0.8 - - fast-json-stable-stringify@2.1.0: {} - - fast-levenshtein@2.0.6: {} - - fastq@1.19.1: - dependencies: - reusify: 1.1.0 - - fd-package-json@2.0.0: - dependencies: - walk-up-path: 4.0.0 - - fdir@6.5.0(picomatch@4.0.3): - optionalDependencies: - picomatch: 4.0.3 - - file-entry-cache@8.0.0: - dependencies: - flat-cache: 4.0.1 - - fill-range@7.1.1: - dependencies: - to-regex-range: 5.0.1 - - find-up@5.0.0: - dependencies: - locate-path: 6.0.0 - path-exists: 4.0.0 - - flat-cache@4.0.1: - dependencies: - flatted: 3.3.3 - keyv: 4.5.4 - - flatted@3.3.3: {} - - formatly@0.3.0: - dependencies: - fd-package-json: 2.0.0 - - framer-motion@12.23.24(react-dom@19.2.0(react@19.2.0))(react@19.2.0): - dependencies: - motion-dom: 12.23.23 - motion-utils: 12.23.6 - tslib: 2.8.1 - optionalDependencies: - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - - fsevents@2.3.3: - optional: true - - gensync@1.0.0-beta.2: {} - - get-caller-file@2.0.5: {} - - get-nonce@1.0.1: {} - - get-tsconfig@4.13.0: - dependencies: - resolve-pkg-maps: 1.0.0 - - glob-parent@5.1.2: - dependencies: - is-glob: 4.0.3 - - glob-parent@6.0.2: - dependencies: - is-glob: 4.0.3 - - globals@14.0.0: {} - - globals@16.5.0: {} - - graceful-fs@4.2.11: {} - - graphemer@1.4.0: {} - - has-flag@4.0.0: {} - - ignore@5.3.2: {} - - ignore@7.0.5: {} - - import-fresh@3.3.1: - dependencies: - parent-module: 1.0.1 - resolve-from: 4.0.0 - - imurmurhash@0.1.4: {} - - is-binary-path@2.1.0: - dependencies: - binary-extensions: 2.3.0 - - is-extglob@2.1.1: {} - - is-fullwidth-code-point@3.0.0: {} - - is-glob@4.0.3: - dependencies: - is-extglob: 2.1.1 - - is-number@7.0.0: {} - - isbot@5.1.31: {} - - isexe@2.0.0: {} - - jiti@2.6.1: {} - - js-tokens@4.0.0: {} - - js-yaml@4.1.0: - dependencies: - argparse: 2.0.1 - - jsesc@3.1.0: {} - - json-buffer@3.0.1: {} - - json-schema-traverse@0.4.1: {} - - json-stable-stringify-without-jsonify@1.0.1: {} - - json5@2.2.3: {} - - keyv@4.5.4: - dependencies: - json-buffer: 3.0.1 - - knip@5.67.1(@types/node@24.9.2)(typescript@5.9.3): - dependencies: - "@nodelib/fs.walk": 1.2.8 - "@types/node": 24.9.2 - fast-glob: 3.3.3 - formatly: 0.3.0 - jiti: 2.6.1 - js-yaml: 4.1.0 - minimist: 1.2.8 - oxc-resolver: 11.13.1 - picocolors: 1.1.1 - picomatch: 4.0.3 - smol-toml: 1.4.2 - strip-json-comments: 5.0.2 - typescript: 5.9.3 - zod: 4.1.12 - - levn@0.4.1: - dependencies: - prelude-ls: 1.2.1 - type-check: 0.4.0 - - lightningcss-android-arm64@1.30.2: - optional: true - - lightningcss-darwin-arm64@1.30.2: - optional: true - - lightningcss-darwin-x64@1.30.2: - optional: true - - lightningcss-freebsd-x64@1.30.2: - optional: true - - lightningcss-linux-arm-gnueabihf@1.30.2: - optional: true - - lightningcss-linux-arm64-gnu@1.30.2: - optional: true - - lightningcss-linux-arm64-musl@1.30.2: - optional: true - - lightningcss-linux-x64-gnu@1.30.2: - optional: true - - lightningcss-linux-x64-musl@1.30.2: - optional: true - - lightningcss-win32-arm64-msvc@1.30.2: - optional: true - - lightningcss-win32-x64-msvc@1.30.2: - optional: true - - lightningcss@1.30.2: - dependencies: - detect-libc: 2.1.2 - optionalDependencies: - lightningcss-android-arm64: 1.30.2 - lightningcss-darwin-arm64: 1.30.2 - lightningcss-darwin-x64: 1.30.2 - lightningcss-freebsd-x64: 1.30.2 - lightningcss-linux-arm-gnueabihf: 1.30.2 - lightningcss-linux-arm64-gnu: 1.30.2 - lightningcss-linux-arm64-musl: 1.30.2 - lightningcss-linux-x64-gnu: 1.30.2 - lightningcss-linux-x64-musl: 1.30.2 - lightningcss-win32-arm64-msvc: 1.30.2 - lightningcss-win32-x64-msvc: 1.30.2 - - locate-path@6.0.0: - dependencies: - p-locate: 5.0.0 - - lodash.merge@4.6.2: {} - - lru-cache@5.1.1: - dependencies: - yallist: 3.1.1 - - lucide-react@0.552.0(react@19.2.0): - dependencies: - react: 19.2.0 - - magic-string@0.30.21: - dependencies: - "@jridgewell/sourcemap-codec": 1.5.5 - - merge2@1.4.1: {} - - micromatch@4.0.8: - dependencies: - braces: 3.0.3 - picomatch: 2.3.1 - - minimatch@3.1.2: - dependencies: - brace-expansion: 1.1.12 - - minimatch@9.0.5: - dependencies: - brace-expansion: 2.0.2 - - minimist@1.2.8: {} - - motion-dom@12.23.23: - dependencies: - motion-utils: 12.23.6 - - motion-utils@12.23.6: {} - - motion@12.23.24(react-dom@19.2.0(react@19.2.0))(react@19.2.0): - dependencies: - framer-motion: 12.23.24(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - tslib: 2.8.1 - optionalDependencies: - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - - ms@2.1.3: {} - - nanoid@3.3.11: {} - - natural-compare@1.4.0: {} - - node-releases@2.0.27: {} - - normalize-path@3.0.0: {} - - optionator@0.9.4: - dependencies: - deep-is: 0.1.4 - fast-levenshtein: 2.0.6 - levn: 0.4.1 - prelude-ls: 1.2.1 - type-check: 0.4.0 - word-wrap: 1.2.5 - - oxc-resolver@11.13.1: - optionalDependencies: - "@oxc-resolver/binding-android-arm-eabi": 11.13.1 - "@oxc-resolver/binding-android-arm64": 11.13.1 - "@oxc-resolver/binding-darwin-arm64": 11.13.1 - "@oxc-resolver/binding-darwin-x64": 11.13.1 - "@oxc-resolver/binding-freebsd-x64": 11.13.1 - "@oxc-resolver/binding-linux-arm-gnueabihf": 11.13.1 - "@oxc-resolver/binding-linux-arm-musleabihf": 11.13.1 - "@oxc-resolver/binding-linux-arm64-gnu": 11.13.1 - "@oxc-resolver/binding-linux-arm64-musl": 11.13.1 - "@oxc-resolver/binding-linux-ppc64-gnu": 11.13.1 - "@oxc-resolver/binding-linux-riscv64-gnu": 11.13.1 - "@oxc-resolver/binding-linux-riscv64-musl": 11.13.1 - "@oxc-resolver/binding-linux-s390x-gnu": 11.13.1 - "@oxc-resolver/binding-linux-x64-gnu": 11.13.1 - "@oxc-resolver/binding-linux-x64-musl": 11.13.1 - "@oxc-resolver/binding-wasm32-wasi": 11.13.1 - "@oxc-resolver/binding-win32-arm64-msvc": 11.13.1 - "@oxc-resolver/binding-win32-ia32-msvc": 11.13.1 - "@oxc-resolver/binding-win32-x64-msvc": 11.13.1 - - p-limit@3.1.0: - dependencies: - yocto-queue: 0.1.0 - - p-locate@5.0.0: - dependencies: - p-limit: 3.1.0 - - parent-module@1.0.1: - dependencies: - callsites: 3.1.0 - - path-exists@4.0.0: {} - - path-key@3.1.1: {} - - pathe@2.0.3: {} - - picocolors@1.1.1: {} - - picomatch@2.3.1: {} - - picomatch@4.0.3: {} - - postcss@8.5.6: - dependencies: - nanoid: 3.3.11 - picocolors: 1.1.1 - source-map-js: 1.2.1 - - prelude-ls@1.2.1: {} - - prettier@3.6.2: {} - - punycode@2.3.1: {} - - queue-microtask@1.2.3: {} - - radix-ui@1.4.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0): - dependencies: - "@radix-ui/primitive": 1.1.3 - "@radix-ui/react-accessible-icon": 1.1.7(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-accordion": 1.2.12(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-alert-dialog": 1.1.15(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-arrow": 1.1.7(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-aspect-ratio": 1.1.7(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-avatar": 1.1.10(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-checkbox": 1.3.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-collapsible": 1.1.12(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-collection": 1.1.7(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-compose-refs": 1.1.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-context": 1.1.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-context-menu": 2.2.16(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-dialog": 1.1.15(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-direction": 1.1.1(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-dismissable-layer": 1.1.11(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-dropdown-menu": 2.1.16(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-focus-guards": 1.1.3(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-focus-scope": 1.1.7(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-form": 0.1.8(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-hover-card": 1.1.15(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-label": 2.1.7(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-menu": 2.1.16(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-menubar": 1.1.16(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-navigation-menu": 1.2.14(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-one-time-password-field": 0.1.8(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-password-toggle-field": 0.1.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-popover": 1.1.15(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-popper": 1.2.8(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-portal": 1.1.9(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-presence": 1.1.5(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-primitive": 2.1.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-progress": 1.1.7(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-radio-group": 1.3.8(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-roving-focus": 1.1.11(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-scroll-area": 1.2.10(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-select": 2.2.6(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-separator": 1.1.7(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-slider": 1.3.6(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-slot": 1.2.3(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-switch": 1.2.6(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-tabs": 1.1.13(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-toast": 1.2.15(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-toggle": 1.1.10(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-toggle-group": 1.1.11(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-toolbar": 1.1.11(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-tooltip": 1.2.8(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - "@radix-ui/react-use-callback-ref": 1.1.1(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-use-controllable-state": 1.2.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-use-effect-event": 0.0.2(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-use-escape-keydown": 1.1.1(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-use-is-hydrated": 0.1.0(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-use-layout-effect": 1.1.1(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-use-size": 1.1.1(@types/react@19.2.2)(react@19.2.0) - "@radix-ui/react-visually-hidden": 1.2.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - optionalDependencies: - "@types/react": 19.2.2 - "@types/react-dom": 19.2.2(@types/react@19.2.2) - - react-dom@19.2.0(react@19.2.0): - dependencies: - react: 19.2.0 - scheduler: 0.27.0 - - react-hook-form@7.66.0(react@19.2.0): - dependencies: - react: 19.2.0 - - react-intersection-observer@10.0.0(react-dom@19.2.0(react@19.2.0))(react@19.2.0): - dependencies: - react: 19.2.0 - optionalDependencies: - react-dom: 19.2.0(react@19.2.0) - - react-refresh@0.18.0: {} - - react-remove-scroll-bar@2.3.8(@types/react@19.2.2)(react@19.2.0): - dependencies: - react: 19.2.0 - react-style-singleton: 2.2.3(@types/react@19.2.2)(react@19.2.0) - tslib: 2.8.1 - optionalDependencies: - "@types/react": 19.2.2 - - react-remove-scroll@2.7.1(@types/react@19.2.2)(react@19.2.0): - dependencies: - react: 19.2.0 - react-remove-scroll-bar: 2.3.8(@types/react@19.2.2)(react@19.2.0) - react-style-singleton: 2.2.3(@types/react@19.2.2)(react@19.2.0) - tslib: 2.8.1 - use-callback-ref: 1.3.3(@types/react@19.2.2)(react@19.2.0) - use-sidecar: 1.1.3(@types/react@19.2.2)(react@19.2.0) - optionalDependencies: - "@types/react": 19.2.2 - - react-style-singleton@2.2.3(@types/react@19.2.2)(react@19.2.0): - dependencies: - get-nonce: 1.0.1 - react: 19.2.0 - tslib: 2.8.1 - optionalDependencies: - "@types/react": 19.2.2 - - react@19.2.0: {} - - readdirp@3.6.0: - dependencies: - picomatch: 2.3.1 - - recast@0.23.11: - dependencies: - ast-types: 0.16.1 - esprima: 4.0.1 - source-map: 0.6.1 - tiny-invariant: 1.3.3 - tslib: 2.8.1 - - require-directory@2.1.1: {} - - resolve-from@4.0.0: {} - - resolve-pkg-maps@1.0.0: {} - - reusify@1.1.0: {} - - rolldown-vite@7.1.14(@types/node@24.9.2)(esbuild@0.25.12)(jiti@2.6.1)(tsx@4.20.6): - dependencies: - "@oxc-project/runtime": 0.92.0 - fdir: 6.5.0(picomatch@4.0.3) - lightningcss: 1.30.2 - picomatch: 4.0.3 - postcss: 8.5.6 - rolldown: 1.0.0-beta.41 - tinyglobby: 0.2.15 - optionalDependencies: - "@types/node": 24.9.2 - esbuild: 0.25.12 - fsevents: 2.3.3 - jiti: 2.6.1 - tsx: 4.20.6 - - rolldown@1.0.0-beta.41: - dependencies: - "@oxc-project/types": 0.93.0 - "@rolldown/pluginutils": 1.0.0-beta.41 - ansis: 4.2.0 - optionalDependencies: - "@rolldown/binding-android-arm64": 1.0.0-beta.41 - "@rolldown/binding-darwin-arm64": 1.0.0-beta.41 - "@rolldown/binding-darwin-x64": 1.0.0-beta.41 - "@rolldown/binding-freebsd-x64": 1.0.0-beta.41 - "@rolldown/binding-linux-arm-gnueabihf": 1.0.0-beta.41 - "@rolldown/binding-linux-arm64-gnu": 1.0.0-beta.41 - "@rolldown/binding-linux-arm64-musl": 1.0.0-beta.41 - "@rolldown/binding-linux-x64-gnu": 1.0.0-beta.41 - "@rolldown/binding-linux-x64-musl": 1.0.0-beta.41 - "@rolldown/binding-openharmony-arm64": 1.0.0-beta.41 - "@rolldown/binding-wasm32-wasi": 1.0.0-beta.41 - "@rolldown/binding-win32-arm64-msvc": 1.0.0-beta.41 - "@rolldown/binding-win32-ia32-msvc": 1.0.0-beta.41 - "@rolldown/binding-win32-x64-msvc": 1.0.0-beta.41 - - run-parallel@1.2.0: - dependencies: - queue-microtask: 1.2.3 - - scheduler@0.27.0: {} - - semver@6.3.1: {} - - semver@7.7.3: {} - - seroval-plugins@1.3.3(seroval@1.3.2): - dependencies: - seroval: 1.3.2 - - seroval@1.3.2: {} - - shebang-command@2.0.0: - dependencies: - shebang-regex: 3.0.0 - - shebang-regex@3.0.0: {} - - smol-toml@1.4.2: {} - - sonner@2.0.7(react-dom@19.2.0(react@19.2.0))(react@19.2.0): - dependencies: - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - - source-map-js@1.2.1: {} - - source-map@0.6.1: {} - - source-map@0.7.6: {} - - string-width@4.2.3: - dependencies: - emoji-regex: 8.0.0 - is-fullwidth-code-point: 3.0.0 - strip-ansi: 6.0.1 - - strip-ansi@6.0.1: - dependencies: - ansi-regex: 5.0.1 - - strip-json-comments@3.1.1: {} - - strip-json-comments@5.0.2: {} - - supports-color@7.2.0: - dependencies: - has-flag: 4.0.0 - - tailwind-merge@3.3.1: {} - - tailwindcss@4.1.16: {} - - tapable@2.3.0: {} - - tiny-invariant@1.3.3: {} - - tiny-warning@1.0.3: {} - - tinyglobby@0.2.15: - dependencies: - fdir: 6.5.0(picomatch@4.0.3) - picomatch: 4.0.3 - - to-regex-range@5.0.1: - dependencies: - is-number: 7.0.0 - - ts-api-utils@2.1.0(typescript@5.9.3): - dependencies: - typescript: 5.9.3 - - tslib@2.8.1: {} - - tsx@4.20.6: - dependencies: - esbuild: 0.25.12 - get-tsconfig: 4.13.0 - optionalDependencies: - fsevents: 2.3.3 - - tw-animate-css@1.4.0: {} - - type-check@0.4.0: - dependencies: - prelude-ls: 1.2.1 - - typescript-eslint@8.46.2(eslint@9.39.0(jiti@2.6.1))(typescript@5.9.3): - dependencies: - "@typescript-eslint/eslint-plugin": 8.46.2(@typescript-eslint/parser@8.46.2(eslint@9.39.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.0(jiti@2.6.1))(typescript@5.9.3) - "@typescript-eslint/parser": 8.46.2(eslint@9.39.0(jiti@2.6.1))(typescript@5.9.3) - "@typescript-eslint/typescript-estree": 8.46.2(typescript@5.9.3) - "@typescript-eslint/utils": 8.46.2(eslint@9.39.0(jiti@2.6.1))(typescript@5.9.3) - eslint: 9.39.0(jiti@2.6.1) - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - - typescript@5.9.3: {} - - undici-types@7.16.0: {} - - unplugin@2.3.10: - dependencies: - "@jridgewell/remapping": 2.3.5 - acorn: 8.15.0 - picomatch: 4.0.3 - webpack-virtual-modules: 0.6.2 - - update-browserslist-db@1.1.4(browserslist@4.27.0): - dependencies: - browserslist: 4.27.0 - escalade: 3.2.0 - picocolors: 1.1.1 - - uri-js@4.4.1: - dependencies: - punycode: 2.3.1 - - use-callback-ref@1.3.3(@types/react@19.2.2)(react@19.2.0): - dependencies: - react: 19.2.0 - tslib: 2.8.1 - optionalDependencies: - "@types/react": 19.2.2 - - use-sidecar@1.1.3(@types/react@19.2.2)(react@19.2.0): - dependencies: - detect-node-es: 1.1.0 - react: 19.2.0 - tslib: 2.8.1 - optionalDependencies: - "@types/react": 19.2.2 - - use-sync-external-store@1.6.0(react@19.2.0): - dependencies: - react: 19.2.0 - - walk-up-path@4.0.0: {} - - webpack-virtual-modules@0.6.2: {} - - which@2.0.2: - dependencies: - isexe: 2.0.0 - - word-wrap@1.2.5: {} - - wrap-ansi@7.0.0: - dependencies: - ansi-styles: 4.3.0 - string-width: 4.2.3 - strip-ansi: 6.0.1 - - y18n@5.0.8: {} - - yallist@3.1.1: {} - - yargs-parser@21.1.1: {} - - yargs@17.7.2: - dependencies: - cliui: 8.0.1 - escalade: 3.2.0 - get-caller-file: 2.0.5 - require-directory: 2.1.1 - string-width: 4.2.3 - y18n: 5.0.8 - yargs-parser: 21.1.1 - - yocto-queue@0.1.0: {} - - zod@3.25.76: {} - - zod@4.1.12: {} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 688fc626..6abcadae 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -19,11 +19,11 @@ importers: specifier: ^17.1.0 version: 17.1.0 prettier: - specifier: ^3.6.2 - version: 3.6.2 + specifier: ^3.7.4 + version: 3.7.4 shadcn: - specifier: ^3.5.0 - version: 3.5.0(@types/node@24.10.1)(typescript@5.9.3) + specifier: ^3.5.1 + version: 3.5.1(@types/node@24.10.1)(typescript@5.9.3) packages/api: dependencies: @@ -136,6 +136,9 @@ importers: react: specifier: ^19.2.0 version: 19.2.0 + tsup: + specifier: ^8.5.1 + version: 8.5.1(jiti@2.6.1)(postcss@8.5.6)(tsx@4.20.6)(typescript@5.9.3) tsx: specifier: ^4.20.6 version: 4.20.6 @@ -144,7 +147,7 @@ importers: version: 5.9.3 vitest: specifier: ^4.0.13 - version: 4.0.13(@opentelemetry/api@1.9.0)(@types/node@24.10.1)(@vitest/ui@4.0.13)(esbuild@0.27.0)(jiti@2.6.1)(jsdom@27.2.0)(msw@2.12.3(@types/node@24.10.1)(typescript@5.9.3))(terser@5.44.1)(tsx@4.20.6) + version: 4.0.13(@opentelemetry/api@1.9.0)(@types/node@24.10.1)(@vitest/ui@4.0.13)(esbuild@0.27.0)(jiti@2.6.1)(jsdom@27.2.0)(msw@2.12.4(@types/node@24.10.1)(typescript@5.9.3))(terser@5.44.1)(tsx@4.20.6) wrangler: specifier: ^4.50.0 version: 4.50.0(@cloudflare/workers-types@4.20251121.0) @@ -337,7 +340,7 @@ importers: version: 1.1.0(rolldown-vite@7.2.7(@types/node@24.10.1)(esbuild@0.27.0)(jiti@2.6.1)(terser@5.44.1)(tsx@4.20.6))(workbox-build@7.3.0(@types/babel__core@7.20.5))(workbox-window@7.4.0) vitest: specifier: ^4.0.13 - version: 4.0.13(@opentelemetry/api@1.9.0)(@types/node@24.10.1)(@vitest/ui@4.0.13)(esbuild@0.27.0)(jiti@2.6.1)(jsdom@27.2.0)(msw@2.12.3(@types/node@24.10.1)(typescript@5.9.3))(terser@5.44.1)(tsx@4.20.6) + version: 4.0.13(@opentelemetry/api@1.9.0)(@types/node@24.10.1)(@vitest/ui@4.0.13)(esbuild@0.27.0)(jiti@2.6.1)(jsdom@27.2.0)(msw@2.12.4(@types/node@24.10.1)(typescript@5.9.3))(terser@5.44.1)(tsx@4.20.6) workbox-window: specifier: ^7.4.0 version: 7.4.0 @@ -374,7 +377,7 @@ importers: version: 5.9.3 vitest: specifier: ^4.0.13 - version: 4.0.13(@opentelemetry/api@1.9.0)(@types/node@24.10.1)(@vitest/ui@4.0.13)(esbuild@0.27.0)(jiti@2.6.1)(jsdom@27.2.0)(msw@2.12.3(@types/node@24.10.1)(typescript@5.9.3))(terser@5.44.1)(tsx@4.20.6) + version: 4.0.13(@opentelemetry/api@1.9.0)(@types/node@24.10.1)(@vitest/ui@4.0.13)(esbuild@0.27.0)(jiti@2.6.1)(jsdom@27.2.0)(msw@2.12.4(@types/node@24.10.1)(typescript@5.9.3))(terser@5.44.1)(tsx@4.20.6) packages: @@ -1645,11 +1648,12 @@ packages: '@jridgewell/trace-mapping@0.3.9': resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} - '@modelcontextprotocol/sdk@1.22.0': - resolution: {integrity: sha512-VUpl106XVTCpDmTBil2ehgJZjhyLY2QZikzF8NvTXtLRF1CvO5iEE2UNZdVIUer35vFOwMKYeUGbjJtvPWan3g==} + '@modelcontextprotocol/sdk@1.24.3': + resolution: {integrity: sha512-YgSHW29fuzKKAHTGe9zjNoo+yF8KaQPzDC2W9Pv41E7/57IfY+AMGJ/aDFlgTLcVVELoggKE4syABCE75u3NCw==} engines: {node: '>=18'} peerDependencies: '@cfworker/json-schema': ^4.1.1 + zod: ^3.25 || ^4.0 peerDependenciesMeta: '@cfworker/json-schema': optional: true @@ -3234,6 +3238,116 @@ packages: rollup: optional: true + '@rollup/rollup-android-arm-eabi@4.53.3': + resolution: {integrity: sha512-mRSi+4cBjrRLoaal2PnqH82Wqyb+d3HsPUN/W+WslCXsZsyHa9ZeQQX/pQsZaVIWDkPcpV6jJ+3KLbTbgnwv8w==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.53.3': + resolution: {integrity: sha512-CbDGaMpdE9sh7sCmTrTUyllhrg65t6SwhjlMJsLr+J8YjFuPmCEjbBSx4Z/e4SmDyH3aB5hGaJUP2ltV/vcs4w==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.53.3': + resolution: {integrity: sha512-Nr7SlQeqIBpOV6BHHGZgYBuSdanCXuw09hon14MGOLGmXAFYjx1wNvquVPmpZnl0tLjg25dEdr4IQ6GgyToCUA==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.53.3': + resolution: {integrity: sha512-DZ8N4CSNfl965CmPktJ8oBnfYr3F8dTTNBQkRlffnUarJ2ohudQD17sZBa097J8xhQ26AwhHJ5mvUyQW8ddTsQ==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.53.3': + resolution: {integrity: sha512-yMTrCrK92aGyi7GuDNtGn2sNW+Gdb4vErx4t3Gv/Tr+1zRb8ax4z8GWVRfr3Jw8zJWvpGHNpss3vVlbF58DZ4w==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.53.3': + resolution: {integrity: sha512-lMfF8X7QhdQzseM6XaX0vbno2m3hlyZFhwcndRMw8fbAGUGL3WFMBdK0hbUBIUYcEcMhVLr1SIamDeuLBnXS+Q==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.53.3': + resolution: {integrity: sha512-k9oD15soC/Ln6d2Wv/JOFPzZXIAIFLp6B+i14KhxAfnq76ajt0EhYc5YPeX6W1xJkAdItcVT+JhKl1QZh44/qw==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm-musleabihf@4.53.3': + resolution: {integrity: sha512-vTNlKq+N6CK/8UktsrFuc+/7NlEYVxgaEgRXVUVK258Z5ymho29skzW1sutgYjqNnquGwVUObAaxae8rZ6YMhg==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm64-gnu@4.53.3': + resolution: {integrity: sha512-RGrFLWgMhSxRs/EWJMIFM1O5Mzuz3Xy3/mnxJp/5cVhZ2XoCAxJnmNsEyeMJtpK+wu0FJFWz+QF4mjCA7AUQ3w==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-musl@4.53.3': + resolution: {integrity: sha512-kASyvfBEWYPEwe0Qv4nfu6pNkITLTb32p4yTgzFCocHnJLAHs+9LjUu9ONIhvfT/5lv4YS5muBHyuV84epBo/A==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-loong64-gnu@4.53.3': + resolution: {integrity: sha512-JiuKcp2teLJwQ7vkJ95EwESWkNRFJD7TQgYmCnrPtlu50b4XvT5MOmurWNrCj3IFdyjBQ5p9vnrX4JM6I8OE7g==} + cpu: [loong64] + os: [linux] + + '@rollup/rollup-linux-ppc64-gnu@4.53.3': + resolution: {integrity: sha512-EoGSa8nd6d3T7zLuqdojxC20oBfNT8nexBbB/rkxgKj5T5vhpAQKKnD+h3UkoMuTyXkP5jTjK/ccNRmQrPNDuw==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.53.3': + resolution: {integrity: sha512-4s+Wped2IHXHPnAEbIB0YWBv7SDohqxobiiPA1FIWZpX+w9o2i4LezzH/NkFUl8LRci/8udci6cLq+jJQlh+0g==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-riscv64-musl@4.53.3': + resolution: {integrity: sha512-68k2g7+0vs2u9CxDt5ktXTngsxOQkSEV/xBbwlqYcUrAVh6P9EgMZvFsnHy4SEiUl46Xf0IObWVbMvPrr2gw8A==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-s390x-gnu@4.53.3': + resolution: {integrity: sha512-VYsFMpULAz87ZW6BVYw3I6sWesGpsP9OPcyKe8ofdg9LHxSbRMd7zrVrr5xi/3kMZtpWL/wC+UIJWJYVX5uTKg==} + cpu: [s390x] + os: [linux] + + '@rollup/rollup-linux-x64-gnu@4.53.3': + resolution: {integrity: sha512-3EhFi1FU6YL8HTUJZ51imGJWEX//ajQPfqWLI3BQq4TlvHy4X0MOr5q3D2Zof/ka0d5FNdPwZXm3Yyib/UEd+w==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-musl@4.53.3': + resolution: {integrity: sha512-eoROhjcc6HbZCJr+tvVT8X4fW3/5g/WkGvvmwz/88sDtSJzO7r/blvoBDgISDiCjDRZmHpwud7h+6Q9JxFwq1Q==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-openharmony-arm64@4.53.3': + resolution: {integrity: sha512-OueLAWgrNSPGAdUdIjSWXw+u/02BRTcnfw9PN41D2vq/JSEPnJnVuBgw18VkN8wcd4fjUs+jFHVM4t9+kBSNLw==} + cpu: [arm64] + os: [openharmony] + + '@rollup/rollup-win32-arm64-msvc@4.53.3': + resolution: {integrity: sha512-GOFuKpsxR/whszbF/bzydebLiXIHSgsEUp6M0JI8dWvi+fFa1TD6YQa4aSZHtpmh2/uAlj/Dy+nmby3TJ3pkTw==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.53.3': + resolution: {integrity: sha512-iah+THLcBJdpfZ1TstDFbKNznlzoxa8fmnFYK4V67HvmuNYkVdAywJSoteUszvBQ9/HqN2+9AZghbajMsFT+oA==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-gnu@4.53.3': + resolution: {integrity: sha512-J9QDiOIZlZLdcot5NXEepDkstocktoVjkaKUtqzgzpt2yWjGlbYiKyp05rWwk4nypbYUNoFAztEgixoLaSETkg==} + cpu: [x64] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.53.3': + resolution: {integrity: sha512-UhTd8u31dXadv0MopwGgNOBpUVROFKWVQgAg5N1ESyCz8AuBcMqm4AuTjrwgQKGDfoFuz02EuMRHQIw/frmYKQ==} + cpu: [x64] + os: [win32] + '@sec-ant/readable-stream@0.4.1': resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==} @@ -3857,6 +3971,9 @@ packages: resolution: {integrity: sha512-HqZ5rWlFjGiV0tDm3UxxgNRqsOTniqoKZu0pIAfh7TZQMGuZK+hH0drySty0si0QXj1ieop4+SkSfPZBPPkHig==} engines: {node: '>=14'} + any-promise@1.3.0: + resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} + anymatch@3.1.3: resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} engines: {node: '>= 8'} @@ -3950,8 +4067,8 @@ packages: resolution: {integrity: sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==} engines: {node: ^4.5.0 || >= 5.9} - baseline-browser-mapping@2.8.31: - resolution: {integrity: sha512-a28v2eWrrRWPpJSzxc+mKwm0ZtVx/G8SepdQZDArnXYU/XS+IF6mp8aB/4E+hH1tyGCoDo3KlUCdlSxGDsRkAw==} + baseline-browser-mapping@2.9.2: + resolution: {integrity: sha512-PxSsosKQjI38iXkmb3d0Y32efqyA0uW4s41u4IVBsLlWLhCiYNpH/AfNOVWRqCQBlD8TFJTz6OUWNd4DFJCnmw==} hasBin: true bcrypt@6.0.0: @@ -4010,8 +4127,8 @@ packages: blake3-wasm@2.1.5: resolution: {integrity: sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==} - body-parser@2.2.0: - resolution: {integrity: sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==} + body-parser@2.2.1: + resolution: {integrity: sha512-nfDwkulwiZYQIGwxdy0RUmowMhKcFVcYXUU7m4QlKYim1rUtg83xm2yjZ40QjDuc291AJjjeSc9b++AWHSgSHw==} engines: {node: '>=18'} brace-expansion@1.1.12: @@ -4024,8 +4141,8 @@ packages: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} - browserslist@4.28.0: - resolution: {integrity: sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ==} + browserslist@4.28.1: + resolution: {integrity: sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true @@ -4035,10 +4152,20 @@ packages: buffer@5.7.1: resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + bundle-require@5.1.0: + resolution: {integrity: sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + peerDependencies: + esbuild: '>=0.25.0' + bytes@3.1.2: resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} engines: {node: '>= 0.8'} + cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} + engines: {node: '>=8'} + caching-transform@4.0.0: resolution: {integrity: sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==} engines: {node: '>=8'} @@ -4066,6 +4193,9 @@ packages: caniuse-lite@1.0.30001756: resolution: {integrity: sha512-4HnCNKbMLkLdhJz3TToeVWHSnfJvPaq6vu/eRP0Ahub/07n484XHhBF5AJoSGHdVrS8tKFauUQz8Bp9P7LVx7A==} + caniuse-lite@1.0.30001759: + resolution: {integrity: sha512-Pzfx9fOKoKvevQf8oCXoyNRQ5QyxJj+3O0Rqx2V5oxT61KGx8+n6hV/IUyJeifUci2clnmmKVpvtiqRzgiWjSw==} + chai@6.2.1: resolution: {integrity: sha512-p4Z49OGG5W/WBCPSS/dH3jQ73kD6tiMmUM+bckNK6Jr5JHMG3k9bg/BvKR8lKmtVBKmOiuVaV2ws8s9oSbwysg==} engines: {node: '>=18'} @@ -4160,6 +4290,10 @@ packages: commander@2.20.3: resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + commander@4.1.1: + resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} + engines: {node: '>= 6'} + common-tags@1.8.2: resolution: {integrity: sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==} engines: {node: '>=4.0.0'} @@ -4179,6 +4313,9 @@ packages: resolution: {integrity: sha512-JBSrutapCafTrddF9dH3lc7+T2tBycGF4uPkI4Js+g4vLLEhG6RZcFi3aJd5zntdf5tQxAejJt8dihkoQ/eSJw==} engines: {node: '>=20'} + confbox@0.1.8: + resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} + confbox@0.2.2: resolution: {integrity: sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ==} @@ -4215,6 +4352,10 @@ packages: resolution: {integrity: sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==} engines: {node: '>=18'} + cookie@1.1.1: + resolution: {integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==} + engines: {node: '>=18'} + core-js-compat@3.47.0: resolution: {integrity: sha512-IGfuznZ/n7Kp9+nypamBhvwdwLsW6KC8IOaURw2doAK5e98AG3acVLdh0woOnEqCfUtS+Vu882JE4k/DAm3ItQ==} @@ -4563,8 +4704,8 @@ packages: engines: {node: '>=0.10.0'} hasBin: true - electron-to-chromium@1.5.259: - resolution: {integrity: sha512-I+oLXgpEJzD6Cwuwt1gYjxsDmu/S/Kd41mmLA3O+/uH2pFRO/DvOjUyGozL8j3KeLV6WyZ7ssPwELMsXCcsJAQ==} + electron-to-chromium@1.5.264: + resolution: {integrity: sha512-1tEf0nLgltC3iy9wtlYDlQDc5Rg9lEKVjEmIHJ21rI9OcqkvD45K1oyNIRA4rR1z3LgJ7KeGzEBojVcV6m4qjA==} emoji-regex@10.6.0: resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==} @@ -4774,8 +4915,8 @@ packages: resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} engines: {node: '>=10'} - execa@9.6.0: - resolution: {integrity: sha512-jpWzZ1ZhwUmeWRhS7Qv3mhpOhLfwI+uAX4e5fOcXqwMR7EcJ0pj2kV1CVzHVMX/LphnKWD3LObjZCoJ71lKpHw==} + execa@9.6.1: + resolution: {integrity: sha512-9Be3ZoN4LmYR90tUoVu2te2BsbzHfhJyfEiAVfz7N5/zv+jduIfLrV2xdQXOHbaD6KgpGdO9PRPM1Y4Q9QkPkA==} engines: {node: ^18.19.0 || >=20.5.0} exit-hook@2.2.1: @@ -4796,8 +4937,8 @@ packages: peerDependencies: express: '>= 4.11' - express@5.1.0: - resolution: {integrity: sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==} + express@5.2.1: + resolution: {integrity: sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==} engines: {node: '>= 18'} exsolve@1.0.8: @@ -4869,9 +5010,9 @@ packages: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} - finalhandler@2.1.0: - resolution: {integrity: sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==} - engines: {node: '>= 0.8'} + finalhandler@2.1.1: + resolution: {integrity: sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==} + engines: {node: '>= 18.0.0'} find-cache-dir@3.3.2: resolution: {integrity: sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==} @@ -4885,6 +5026,9 @@ packages: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} engines: {node: '>=10'} + fix-dts-default-cjs-exports@1.0.1: + resolution: {integrity: sha512-pVIECanWFC61Hzl2+oOCtoJ3F17kglZC/6N94eRWycFgBH35hHx0Li604ZIzhseh97mf2p0cv7vVrOZGoqhlEg==} + flat-cache@4.0.1: resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} engines: {node: '>=16'} @@ -5465,6 +5609,13 @@ packages: jose@6.1.2: resolution: {integrity: sha512-MpcPtHLE5EmztuFIqB0vzHAWJPpmN1E6L4oo+kze56LIs3MyXIj9ZHMDxqOvkP38gBR7K1v3jqd4WU2+nrfONQ==} + jose@6.1.3: + resolution: {integrity: sha512-0TpaTfihd4QMNwrz/ob2Bp7X04yuxJkjRGi4aKmOqwhov54i6u79oCv7T+C7lo70MKH6BesI3vscD1yb/yzKXQ==} + + joycon@3.1.1: + resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} + engines: {node: '>=10'} + js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} @@ -5630,9 +5781,17 @@ packages: resolution: {integrity: sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ==} engines: {node: '>= 12.0.0'} + lilconfig@3.1.3: + resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} + engines: {node: '>=14'} + lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + load-tsconfig@0.2.5: + resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + locate-path@5.0.0: resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} engines: {node: '>=8'} @@ -5795,6 +5954,9 @@ packages: mkdirp-classic@0.5.3: resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} + mlly@1.8.0: + resolution: {integrity: sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==} + module-details-from-path@1.0.4: resolution: {integrity: sha512-EGWKgxALGMgzvxYF1UyGTy0HXX/2vHLkw6+NvDKW2jypWbHpjQuj4UMcqQWXHERJhVGKikolT06G3bcKe4fi7w==} @@ -5825,8 +5987,8 @@ packages: ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - msw@2.12.3: - resolution: {integrity: sha512-/5rpGC0eK8LlFqsHaBmL19/PVKxu/CCt8pO1vzp9X6SDLsRDh/Ccudkf3Ur5lyaKxJz9ndAx+LaThdv0ySqB6A==} + msw@2.12.4: + resolution: {integrity: sha512-rHNiVfTyKhzc0EjoXUBVGteNKBevdjOlVC6GlIRXpy+/3LHEIGRovnB5WPjcvmNODVQ1TNFnoa7wsGbd0V3epg==} engines: {node: '>=18'} hasBin: true peerDependencies: @@ -5839,6 +6001,9 @@ packages: resolution: {integrity: sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==} engines: {node: ^18.17.0 || >=20.5.0} + mz@2.7.0: + resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + nanoid@3.3.11: resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} @@ -6021,8 +6186,8 @@ packages: package-json-from-dist@1.0.1: resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} - package-manager-detector@1.5.0: - resolution: {integrity: sha512-uBj69dVlYe/+wxj8JOpr97XfsxH/eumMt6HqjNTmJDf/6NO9s+0uxeOneIz3AsPt2m6y9PqzDzd3ATcU17MNfw==} + package-manager-detector@1.6.0: + resolution: {integrity: sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==} parent-module@1.0.1: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} @@ -6109,6 +6274,10 @@ packages: resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} engines: {node: '>=12'} + pirates@4.0.7: + resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} + engines: {node: '>= 6'} + pkce-challenge@5.0.1: resolution: {integrity: sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==} engines: {node: '>=16.20.0'} @@ -6117,6 +6286,9 @@ packages: resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} engines: {node: '>=8'} + pkg-types@1.3.1: + resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} + pkg-types@2.3.0: resolution: {integrity: sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==} @@ -6124,6 +6296,24 @@ packages: resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} engines: {node: '>= 0.4'} + postcss-load-config@6.0.1: + resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==} + engines: {node: '>= 18'} + peerDependencies: + jiti: '>=1.21.0' + postcss: '>=8.0.9' + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + jiti: + optional: true + postcss: + optional: true + tsx: + optional: true + yaml: + optional: true + postcss-selector-parser@6.0.10: resolution: {integrity: sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==} engines: {node: '>=4'} @@ -6166,6 +6356,11 @@ packages: engines: {node: '>=14'} hasBin: true + prettier@3.7.4: + resolution: {integrity: sha512-v6UNi1+3hSlVvv8fSaoUbggEM5VErKmmpGA7Pl3HF8V6uKY7rvClBOJlH6yNwQtfTueNkGVpOv/mtWL9L4bgRA==} + engines: {node: '>=14'} + hasBin: true + pretty-bytes@5.6.0: resolution: {integrity: sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==} engines: {node: '>=6'} @@ -6550,6 +6745,11 @@ packages: engines: {node: '>=10.0.0'} hasBin: true + rollup@4.53.3: + resolution: {integrity: sha512-w8GmOxZfBmKknvdXU1sdM9NHcoQejwF/4mNgj2JuEEdRaHwwF12K7e9eXn1nLZ07ad+du76mkVsyeb2rKGllsA==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + rou3@0.5.1: resolution: {integrity: sha512-OXMmJ3zRk2xeXFGfA3K+EOPHC5u7RDFG7lIOx0X1pdnhUkI8MdVrbV+sNsD80ElpUZ+MRHdyxPnFthq9VHs8uQ==} @@ -6645,8 +6845,8 @@ packages: setprototypeof@1.2.0: resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} - shadcn@3.5.0: - resolution: {integrity: sha512-5f9tn7gHOiI8CqJ8LGrUEmX6dOivGgSbHkMCeOMCzxHZy9cPwyuRXt7ZyjwukO8QH9kGqi6oiKOpfvTXNGBP4g==} + shadcn@3.5.1: + resolution: {integrity: sha512-yLbIDouYv8Xz25BxV/GAGC/46R7/oNwoXIs/IFIYXK47+fKcFIYzThtBqJwFEZTzkkvqJCo+MBg0K9QLTmhFmQ==} hasBin: true sharp@0.33.5: @@ -6899,6 +7099,11 @@ packages: babel-plugin-macros: optional: true + sucrase@3.35.1: + resolution: {integrity: sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==} + engines: {node: '>=16 || 14 >=14.17'} + hasBin: true + supports-color@10.2.2: resolution: {integrity: sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==} engines: {node: '>=18'} @@ -6962,6 +7167,13 @@ packages: resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} engines: {node: '>=8'} + thenify-all@1.6.0: + resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} + engines: {node: '>=0.8'} + + thenify@3.3.1: + resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + tiny-invariant@1.3.3: resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} @@ -7026,6 +7238,9 @@ packages: peerDependencies: typescript: '>=4.8.4' + ts-interface-checker@0.1.13: + resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + ts-morph@26.0.0: resolution: {integrity: sha512-ztMO++owQnz8c/gIENcM9XfCEzgoGphTv+nKpYNM1bgsdOVC/jRZuEBf6N+mLLDNg68Kl+GgUZfOySaRiG1/Ug==} @@ -7036,6 +7251,25 @@ packages: tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + tsup@8.5.1: + resolution: {integrity: sha512-xtgkqwdhpKWr3tKPmCkvYmS9xnQK3m3XgxZHwSUjvfTjp7YfXe5tT3GgWi0F2N+ZSMsOeWeZFh7ZZFg5iPhing==} + engines: {node: '>=18'} + hasBin: true + peerDependencies: + '@microsoft/api-extractor': ^7.36.0 + '@swc/core': ^1 + postcss: ^8.4.12 + typescript: '>=4.5.0' + peerDependenciesMeta: + '@microsoft/api-extractor': + optional: true + '@swc/core': + optional: true + postcss: + optional: true + typescript: + optional: true + tsx@4.20.6: resolution: {integrity: sha512-ytQKuwgmrrkDTFP4LjR0ToE2nqgy886GpvRSpU0JAnrdBYppuY5rLkRUYPU1yCryb24SsKBTL/hlDQAEFVwtZg==} engines: {node: '>=18.0.0'} @@ -7063,6 +7297,10 @@ packages: resolution: {integrity: sha512-xxCJm+Bckc6kQBknN7i9fnP/xobQRsRQxR01CztFkp/h++yfVxUUcmMgfR2HttJx/dpWjS9ubVuyspJv24Q9DA==} engines: {node: '>=20'} + type-fest@5.3.0: + resolution: {integrity: sha512-d9CwU93nN0IA1QL+GSNDdwLAu1Ew5ZjTwupvedwg3WdfoH6pIDvYQ2hV0Uc2nKBLPq7NB5apCx57MLS5qlmO5g==} + engines: {node: '>=20'} + type-is@2.0.1: resolution: {integrity: sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==} engines: {node: '>= 0.6'} @@ -7098,6 +7336,9 @@ packages: engines: {node: '>=14.17'} hasBin: true + ufo@1.6.1: + resolution: {integrity: sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==} + uint8array-extras@1.5.0: resolution: {integrity: sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A==} engines: {node: '>=18'} @@ -7162,8 +7403,8 @@ packages: resolution: {integrity: sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==} engines: {node: '>=4'} - update-browserslist-db@1.1.4: - resolution: {integrity: sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A==} + update-browserslist-db@1.2.2: + resolution: {integrity: sha512-E85pfNzMQ9jpKkA7+TJAi4TJN+tBCuWh5rUcS/sv6cFi+1q9LYDwDI5dpUL0u/73EElyQ8d3TEaeW4sPedBqYA==} hasBin: true peerDependencies: browserslist: '>= 4.21.0' @@ -7559,7 +7800,7 @@ snapshots: dependencies: ansis: 4.2.0 fzf: 0.5.2 - package-manager-detector: 1.5.0 + package-manager-detector: 1.6.0 tinyexec: 1.0.2 '@apideck/better-ajv-errors@0.3.6(ajv@8.17.1)': @@ -7641,7 +7882,7 @@ snapshots: dependencies: '@babel/compat-data': 7.28.5 '@babel/helper-validator-option': 7.27.1 - browserslist: 4.28.0 + browserslist: 4.28.1 lru-cache: 5.1.1 semver: 6.3.1 @@ -8840,7 +9081,7 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 - '@modelcontextprotocol/sdk@1.22.0': + '@modelcontextprotocol/sdk@1.24.3(zod@3.25.76)': dependencies: ajv: 8.17.1 ajv-formats: 3.0.1(ajv@8.17.1) @@ -8849,8 +9090,9 @@ snapshots: cross-spawn: 7.0.6 eventsource: 3.0.7 eventsource-parser: 3.0.6 - express: 5.1.0 - express-rate-limit: 7.5.1(express@5.1.0) + express: 5.2.1 + express-rate-limit: 7.5.1(express@5.2.1) + jose: 6.1.3 pkce-challenge: 5.0.1 raw-body: 3.0.2 zod: 3.25.76 @@ -10371,6 +10613,72 @@ snapshots: optionalDependencies: rollup: 2.79.2 + '@rollup/rollup-android-arm-eabi@4.53.3': + optional: true + + '@rollup/rollup-android-arm64@4.53.3': + optional: true + + '@rollup/rollup-darwin-arm64@4.53.3': + optional: true + + '@rollup/rollup-darwin-x64@4.53.3': + optional: true + + '@rollup/rollup-freebsd-arm64@4.53.3': + optional: true + + '@rollup/rollup-freebsd-x64@4.53.3': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.53.3': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.53.3': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.53.3': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.53.3': + optional: true + + '@rollup/rollup-linux-loong64-gnu@4.53.3': + optional: true + + '@rollup/rollup-linux-ppc64-gnu@4.53.3': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.53.3': + optional: true + + '@rollup/rollup-linux-riscv64-musl@4.53.3': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.53.3': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.53.3': + optional: true + + '@rollup/rollup-linux-x64-musl@4.53.3': + optional: true + + '@rollup/rollup-openharmony-arm64@4.53.3': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.53.3': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.53.3': + optional: true + + '@rollup/rollup-win32-x64-gnu@4.53.3': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.53.3': + optional: true + '@sec-ant/readable-stream@0.4.1': {} '@selderee/plugin-htmlparser2@0.11.0': @@ -10987,7 +11295,7 @@ snapshots: magicast: 0.5.1 std-env: 3.10.0 tinyrainbow: 3.0.3 - vitest: 4.0.13(@opentelemetry/api@1.9.0)(@types/node@24.10.1)(@vitest/ui@4.0.13)(esbuild@0.27.0)(jiti@2.6.1)(jsdom@27.2.0)(msw@2.12.3(@types/node@24.10.1)(typescript@5.9.3))(terser@5.44.1)(tsx@4.20.6) + vitest: 4.0.13(@opentelemetry/api@1.9.0)(@types/node@24.10.1)(@vitest/ui@4.0.13)(esbuild@0.27.0)(jiti@2.6.1)(jsdom@27.2.0)(msw@2.12.4(@types/node@24.10.1)(typescript@5.9.3))(terser@5.44.1)(tsx@4.20.6) transitivePeerDependencies: - supports-color @@ -11000,13 +11308,13 @@ snapshots: chai: 6.2.1 tinyrainbow: 3.0.3 - '@vitest/mocker@4.0.13(msw@2.12.3(@types/node@24.10.1)(typescript@5.9.3))(rolldown-vite@7.1.14(@types/node@24.10.1)(esbuild@0.27.0)(jiti@2.6.1)(terser@5.44.1)(tsx@4.20.6))': + '@vitest/mocker@4.0.13(msw@2.12.4(@types/node@24.10.1)(typescript@5.9.3))(rolldown-vite@7.1.14(@types/node@24.10.1)(esbuild@0.27.0)(jiti@2.6.1)(terser@5.44.1)(tsx@4.20.6))': dependencies: '@vitest/spy': 4.0.13 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - msw: 2.12.3(@types/node@24.10.1)(typescript@5.9.3) + msw: 2.12.4(@types/node@24.10.1)(typescript@5.9.3) vite: rolldown-vite@7.1.14(@types/node@24.10.1)(esbuild@0.27.0)(jiti@2.6.1)(terser@5.44.1)(tsx@4.20.6) '@vitest/pretty-format@4.0.13': @@ -11035,7 +11343,7 @@ snapshots: sirv: 3.0.2 tinyglobby: 0.2.15 tinyrainbow: 3.0.3 - vitest: 4.0.13(@opentelemetry/api@1.9.0)(@types/node@24.10.1)(@vitest/ui@4.0.13)(esbuild@0.27.0)(jiti@2.6.1)(jsdom@27.2.0)(msw@2.12.3(@types/node@24.10.1)(typescript@5.9.3))(terser@5.44.1)(tsx@4.20.6) + vitest: 4.0.13(@opentelemetry/api@1.9.0)(@types/node@24.10.1)(@vitest/ui@4.0.13)(esbuild@0.27.0)(jiti@2.6.1)(jsdom@27.2.0)(msw@2.12.4(@types/node@24.10.1)(typescript@5.9.3))(terser@5.44.1)(tsx@4.20.6) '@vitest/utils@4.0.13': dependencies: @@ -11105,6 +11413,8 @@ snapshots: ansis@4.2.0: {} + any-promise@1.3.0: {} + anymatch@3.1.3: dependencies: normalize-path: 3.0.0 @@ -11213,7 +11523,7 @@ snapshots: base64id@2.0.0: {} - baseline-browser-mapping@2.8.31: {} + baseline-browser-mapping@2.9.2: {} bcrypt@6.0.0: dependencies: @@ -11269,13 +11579,13 @@ snapshots: blake3-wasm@2.1.5: {} - body-parser@2.2.0: + body-parser@2.2.1: dependencies: bytes: 3.1.2 content-type: 1.0.5 debug: 4.4.3 http-errors: 2.0.1 - iconv-lite: 0.6.3 + iconv-lite: 0.7.0 on-finished: 2.4.1 qs: 6.14.0 raw-body: 3.0.2 @@ -11296,13 +11606,13 @@ snapshots: dependencies: fill-range: 7.1.1 - browserslist@4.28.0: + browserslist@4.28.1: dependencies: - baseline-browser-mapping: 2.8.31 - caniuse-lite: 1.0.30001756 - electron-to-chromium: 1.5.259 + baseline-browser-mapping: 2.9.2 + caniuse-lite: 1.0.30001759 + electron-to-chromium: 1.5.264 node-releases: 2.0.27 - update-browserslist-db: 1.1.4(browserslist@4.28.0) + update-browserslist-db: 1.2.2(browserslist@4.28.1) buffer-from@1.1.2: {} @@ -11311,8 +11621,15 @@ snapshots: base64-js: 1.5.1 ieee754: 1.2.1 + bundle-require@5.1.0(esbuild@0.27.0): + dependencies: + esbuild: 0.27.0 + load-tsconfig: 0.2.5 + bytes@3.1.2: {} + cac@6.7.14: {} + caching-transform@4.0.0: dependencies: hasha: 5.2.2 @@ -11343,6 +11660,8 @@ snapshots: caniuse-lite@1.0.30001756: {} + caniuse-lite@1.0.30001759: {} + chai@6.2.1: {} chalk@4.1.2: @@ -11432,6 +11751,8 @@ snapshots: commander@2.20.3: {} + commander@4.1.1: {} + common-tags@1.8.2: {} commondir@1.0.1: {} @@ -11459,6 +11780,8 @@ snapshots: semver: 7.7.3 uint8array-extras: 1.5.0 + confbox@0.1.8: {} + confbox@0.2.2: {} consola@3.4.2: {} @@ -11479,9 +11802,11 @@ snapshots: cookie@1.0.2: {} + cookie@1.1.1: {} + core-js-compat@3.47.0: dependencies: - browserslist: 4.28.0 + browserslist: 4.28.1 cors@2.8.5: dependencies: @@ -11717,7 +12042,7 @@ snapshots: dependencies: jake: 10.9.4 - electron-to-chromium@1.5.259: {} + electron-to-chromium@1.5.264: {} emoji-regex@10.6.0: {} @@ -12021,7 +12346,7 @@ snapshots: signal-exit: 3.0.7 strip-final-newline: 2.0.0 - execa@9.6.0: + execa@9.6.1: dependencies: '@sindresorhus/merge-streams': 4.0.0 cross-spawn: 7.0.6 @@ -12042,23 +12367,24 @@ snapshots: expect-type@1.2.2: {} - express-rate-limit@7.5.1(express@5.1.0): + express-rate-limit@7.5.1(express@5.2.1): dependencies: - express: 5.1.0 + express: 5.2.1 - express@5.1.0: + express@5.2.1: dependencies: accepts: 2.0.0 - body-parser: 2.2.0 + body-parser: 2.2.1 content-disposition: 1.0.1 content-type: 1.0.5 cookie: 0.7.2 cookie-signature: 1.2.2 debug: 4.4.3 + depd: 2.0.0 encodeurl: 2.0.0 escape-html: 1.0.3 etag: 1.8.1 - finalhandler: 2.1.0 + finalhandler: 2.1.1 fresh: 2.0.0 http-errors: 2.0.1 merge-descriptors: 2.0.0 @@ -12144,7 +12470,7 @@ snapshots: dependencies: to-regex-range: 5.0.1 - finalhandler@2.1.0: + finalhandler@2.1.1: dependencies: debug: 4.4.3 encodeurl: 2.0.0 @@ -12171,6 +12497,12 @@ snapshots: locate-path: 6.0.0 path-exists: 4.0.0 + fix-dts-default-cjs-exports@1.0.1: + dependencies: + magic-string: 0.30.21 + mlly: 1.8.0 + rollup: 4.53.3 + flat-cache@4.0.1: dependencies: flatted: 3.3.3 @@ -12721,6 +13053,10 @@ snapshots: jose@6.1.2: {} + jose@6.1.3: {} + + joycon@3.1.1: {} + js-tokens@4.0.0: {} js-tokens@9.0.1: {} @@ -12872,8 +13208,12 @@ snapshots: lightningcss-win32-arm64-msvc: 1.30.2 lightningcss-win32-x64-msvc: 1.30.2 + lilconfig@3.1.3: {} + lines-and-columns@1.2.4: {} + load-tsconfig@0.2.5: {} + locate-path@5.0.0: dependencies: p-locate: 4.1.0 @@ -13017,6 +13357,13 @@ snapshots: mkdirp-classic@0.5.3: {} + mlly@1.8.0: + dependencies: + acorn: 8.15.0 + pathe: 2.0.3 + pkg-types: 1.3.1 + ufo: 1.6.1 + module-details-from-path@1.0.4: {} motion-dom@12.23.23: @@ -13037,13 +13384,13 @@ snapshots: ms@2.1.3: {} - msw@2.12.3(@types/node@24.10.1)(typescript@5.9.3): + msw@2.12.4(@types/node@24.10.1)(typescript@5.9.3): dependencies: '@inquirer/confirm': 5.1.21(@types/node@24.10.1) '@mswjs/interceptors': 0.40.0 '@open-draft/deferred-promise': 2.2.0 '@types/statuses': 2.0.6 - cookie: 1.0.2 + cookie: 1.1.1 graphql: 16.12.0 headers-polyfill: 4.0.3 is-node-process: 1.2.0 @@ -13054,7 +13401,7 @@ snapshots: statuses: 2.0.2 strict-event-emitter: 0.5.1 tough-cookie: 6.0.0 - type-fest: 5.2.0 + type-fest: 5.3.0 until-async: 3.0.2 yargs: 17.7.2 optionalDependencies: @@ -13064,6 +13411,12 @@ snapshots: mute-stream@2.0.0: {} + mz@2.7.0: + dependencies: + any-promise: 1.3.0 + object-assign: 4.1.1 + thenify-all: 1.6.0 + nanoid@3.3.11: {} nanostores@1.1.0: {} @@ -13290,7 +13643,7 @@ snapshots: package-json-from-dist@1.0.1: {} - package-manager-detector@1.5.0: {} + package-manager-detector@1.6.0: {} parent-module@1.0.1: dependencies: @@ -13361,12 +13714,20 @@ snapshots: picomatch@4.0.3: {} + pirates@4.0.7: {} + pkce-challenge@5.0.1: {} pkg-dir@4.2.0: dependencies: find-up: 4.1.0 + pkg-types@1.3.1: + dependencies: + confbox: 0.1.8 + mlly: 1.8.0 + pathe: 2.0.3 + pkg-types@2.3.0: dependencies: confbox: 0.2.2 @@ -13375,6 +13736,14 @@ snapshots: possible-typed-array-names@1.1.0: {} + postcss-load-config@6.0.1(jiti@2.6.1)(postcss@8.5.6)(tsx@4.20.6): + dependencies: + lilconfig: 3.1.3 + optionalDependencies: + jiti: 2.6.1 + postcss: 8.5.6 + tsx: 4.20.6 + postcss-selector-parser@6.0.10: dependencies: cssesc: 3.0.0 @@ -13421,6 +13790,8 @@ snapshots: prettier@3.6.2: {} + prettier@3.7.4: {} + pretty-bytes@5.6.0: {} pretty-bytes@6.1.1: {} @@ -13860,6 +14231,34 @@ snapshots: optionalDependencies: fsevents: 2.3.3 + rollup@4.53.3: + dependencies: + '@types/estree': 1.0.8 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.53.3 + '@rollup/rollup-android-arm64': 4.53.3 + '@rollup/rollup-darwin-arm64': 4.53.3 + '@rollup/rollup-darwin-x64': 4.53.3 + '@rollup/rollup-freebsd-arm64': 4.53.3 + '@rollup/rollup-freebsd-x64': 4.53.3 + '@rollup/rollup-linux-arm-gnueabihf': 4.53.3 + '@rollup/rollup-linux-arm-musleabihf': 4.53.3 + '@rollup/rollup-linux-arm64-gnu': 4.53.3 + '@rollup/rollup-linux-arm64-musl': 4.53.3 + '@rollup/rollup-linux-loong64-gnu': 4.53.3 + '@rollup/rollup-linux-ppc64-gnu': 4.53.3 + '@rollup/rollup-linux-riscv64-gnu': 4.53.3 + '@rollup/rollup-linux-riscv64-musl': 4.53.3 + '@rollup/rollup-linux-s390x-gnu': 4.53.3 + '@rollup/rollup-linux-x64-gnu': 4.53.3 + '@rollup/rollup-linux-x64-musl': 4.53.3 + '@rollup/rollup-openharmony-arm64': 4.53.3 + '@rollup/rollup-win32-arm64-msvc': 4.53.3 + '@rollup/rollup-win32-ia32-msvc': 4.53.3 + '@rollup/rollup-win32-x64-gnu': 4.53.3 + '@rollup/rollup-win32-x64-msvc': 4.53.3 + fsevents: 2.3.3 + rou3@0.5.1: {} router@2.2.0: @@ -13989,7 +14388,7 @@ snapshots: setprototypeof@1.2.0: {} - shadcn@3.5.0(@types/node@24.10.1)(typescript@5.9.3): + shadcn@3.5.1(@types/node@24.10.1)(typescript@5.9.3): dependencies: '@antfu/ni': 25.0.0 '@babel/core': 7.28.5 @@ -13997,20 +14396,20 @@ snapshots: '@babel/plugin-transform-typescript': 7.28.5(@babel/core@7.28.5) '@babel/preset-typescript': 7.28.5(@babel/core@7.28.5) '@dotenvx/dotenvx': 1.51.1 - '@modelcontextprotocol/sdk': 1.22.0 - browserslist: 4.28.0 + '@modelcontextprotocol/sdk': 1.24.3(zod@3.25.76) + browserslist: 4.28.1 commander: 14.0.2 cosmiconfig: 9.0.0(typescript@5.9.3) dedent: 1.7.0 deepmerge: 4.3.1 diff: 8.0.2 - execa: 9.6.0 + execa: 9.6.1 fast-glob: 3.3.3 fs-extra: 11.3.2 fuzzysort: 3.1.0 https-proxy-agent: 7.0.6 kleur: 4.1.5 - msw: 2.12.3(@types/node@24.10.1)(typescript@5.9.3) + msw: 2.12.4(@types/node@24.10.1)(typescript@5.9.3) node-fetch: 3.3.2 ora: 8.2.0 postcss: 8.5.6 @@ -14349,6 +14748,16 @@ snapshots: optionalDependencies: '@babel/core': 7.28.5 + sucrase@3.35.1: + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + commander: 4.1.1 + lines-and-columns: 1.2.4 + mz: 2.7.0 + pirates: 4.0.7 + tinyglobby: 0.2.15 + ts-interface-checker: 0.1.13 + supports-color@10.2.2: {} supports-color@7.2.0: @@ -14419,6 +14828,14 @@ snapshots: glob: 7.2.3 minimatch: 3.1.2 + thenify-all@1.6.0: + dependencies: + thenify: 3.3.1 + + thenify@3.3.1: + dependencies: + any-promise: 1.3.0 + tiny-invariant@1.3.3: {} tiny-warning@1.0.3: {} @@ -14468,6 +14885,8 @@ snapshots: dependencies: typescript: 5.9.3 + ts-interface-checker@0.1.13: {} + ts-morph@26.0.0: dependencies: '@ts-morph/common': 0.27.0 @@ -14481,6 +14900,34 @@ snapshots: tslib@2.8.1: {} + tsup@8.5.1(jiti@2.6.1)(postcss@8.5.6)(tsx@4.20.6)(typescript@5.9.3): + dependencies: + bundle-require: 5.1.0(esbuild@0.27.0) + cac: 6.7.14 + chokidar: 4.0.3 + consola: 3.4.2 + debug: 4.4.3 + esbuild: 0.27.0 + fix-dts-default-cjs-exports: 1.0.1 + joycon: 3.1.1 + picocolors: 1.1.1 + postcss-load-config: 6.0.1(jiti@2.6.1)(postcss@8.5.6)(tsx@4.20.6) + resolve-from: 5.0.0 + rollup: 4.53.3 + source-map: 0.7.6 + sucrase: 3.35.1 + tinyexec: 0.3.2 + tinyglobby: 0.2.15 + tree-kill: 1.2.2 + optionalDependencies: + postcss: 8.5.6 + typescript: 5.9.3 + transitivePeerDependencies: + - jiti + - supports-color + - tsx + - yaml + tsx@4.20.6: dependencies: esbuild: 0.27.0 @@ -14506,6 +14953,10 @@ snapshots: dependencies: tagged-tag: 1.0.0 + type-fest@5.3.0: + dependencies: + tagged-tag: 1.0.0 + type-is@2.0.1: dependencies: content-type: 1.0.5 @@ -14562,6 +15013,8 @@ snapshots: typescript@5.9.3: {} + ufo@1.6.1: {} + uint8array-extras@1.5.0: {} unbox-primitive@1.1.0: @@ -14613,9 +15066,9 @@ snapshots: upath@1.2.0: {} - update-browserslist-db@1.1.4(browserslist@4.28.0): + update-browserslist-db@1.2.2(browserslist@4.28.1): dependencies: - browserslist: 4.28.0 + browserslist: 4.28.1 escalade: 3.2.0 picocolors: 1.1.1 @@ -14692,10 +15145,10 @@ snapshots: transitivePeerDependencies: - supports-color - vitest@4.0.13(@opentelemetry/api@1.9.0)(@types/node@24.10.1)(@vitest/ui@4.0.13)(esbuild@0.27.0)(jiti@2.6.1)(jsdom@27.2.0)(msw@2.12.3(@types/node@24.10.1)(typescript@5.9.3))(terser@5.44.1)(tsx@4.20.6): + vitest@4.0.13(@opentelemetry/api@1.9.0)(@types/node@24.10.1)(@vitest/ui@4.0.13)(esbuild@0.27.0)(jiti@2.6.1)(jsdom@27.2.0)(msw@2.12.4(@types/node@24.10.1)(typescript@5.9.3))(terser@5.44.1)(tsx@4.20.6): dependencies: '@vitest/expect': 4.0.13 - '@vitest/mocker': 4.0.13(msw@2.12.3(@types/node@24.10.1)(typescript@5.9.3))(rolldown-vite@7.1.14(@types/node@24.10.1)(esbuild@0.27.0)(jiti@2.6.1)(terser@5.44.1)(tsx@4.20.6)) + '@vitest/mocker': 4.0.13(msw@2.12.4(@types/node@24.10.1)(typescript@5.9.3))(rolldown-vite@7.1.14(@types/node@24.10.1)(esbuild@0.27.0)(jiti@2.6.1)(terser@5.44.1)(tsx@4.20.6)) '@vitest/pretty-format': 4.0.13 '@vitest/runner': 4.0.13 '@vitest/snapshot': 4.0.13 diff --git a/scripts/check-gha-versions.sh b/scripts/check-gha-versions.sh new file mode 100755 index 00000000..07407402 --- /dev/null +++ b/scripts/check-gha-versions.sh @@ -0,0 +1,34 @@ +#!/bin/bash +# Check GitHub Actions for updates +# Usage: ./scripts/check-gha-versions.sh + +set -e + +echo "Checking GitHub Actions versions..." +echo "" + +# Extract all action versions from workflows +grep -r "uses: " .github/workflows/ | grep -v "^#" | sed 's/.*uses: //' | sort -u | while read -r action; do + # Split action@version + action_name=$(echo "$action" | cut -d'@' -f1) + current_version=$(echo "$action" | cut -d'@' -f2) + + # Get owner and repo + owner=$(echo "$action_name" | cut -d'/' -f1) + repo=$(echo "$action_name" | cut -d'/' -f2) + + # Fetch latest version from GitHub API + latest=$(curl -s "https://api.github.com/repos/$owner/$repo/releases/latest" | grep '"tag_name"' | cut -d'"' -f4) + + if [ -z "$latest" ]; then + echo "โš ๏ธ $action_name@$current_version (no releases found)" + elif [ "$current_version" = "$latest" ]; then + echo "โœ… $action_name@$current_version (up to date)" + else + echo "โฌ†๏ธ $action_name@$current_version โ†’ $latest (update available)" + fi +done + +echo "" +echo "To update manually, edit .github/workflows/*.yml" +echo "Or wait for Dependabot's monthly check" diff --git a/scripts/test-docker.sh b/scripts/test-docker.sh new file mode 100755 index 00000000..61deac8a --- /dev/null +++ b/scripts/test-docker.sh @@ -0,0 +1,188 @@ +#!/bin/bash +# Docker testing script for local development +# Tests Docker Compose setup with health checks and validation +# +# Usage: +# ./scripts/test-docker.sh +# pnpm docker:test + +set -e # Exit on error + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +# Functions +log_info() { + echo -e "${BLUE}โ„น๏ธ $1${NC}" +} + +log_success() { + echo -e "${GREEN}โœ… $1${NC}" +} + +log_warning() { + echo -e "${YELLOW}โš ๏ธ $1${NC}" +} + +log_error() { + echo -e "${RED}โŒ $1${NC}" +} + +# Cleanup function +cleanup() { + log_info "Cleaning up..." + docker compose down -v 2>/dev/null || true +} + +# Set trap to cleanup on exit +trap cleanup EXIT INT TERM + +# Main script +main() { + echo "=========================================" + echo "๐Ÿณ Docker Compose Test Suite" + echo "=========================================" + echo "" + + # Check if Docker is running + if ! docker info > /dev/null 2>&1; then + log_error "Docker is not running. Please start Docker and try again." + exit 1 + fi + log_success "Docker is running" + + # Build images + log_info "Building Docker images..." + if docker compose build; then + log_success "Images built successfully" + else + log_error "Failed to build images" + exit 1 + fi + + # Check image sizes + log_info "Checking image sizes..." + API_SIZE=$(docker images --format "{{.Size}}" tuvixrss-api:latest) + APP_SIZE=$(docker images --format "{{.Size}}" tuvixrss-app:latest) + + echo " API: ${API_SIZE}" + echo " App: ${APP_SIZE}" + log_success "Image sizes checked" + + # Start services + log_info "Starting Docker Compose services..." + export BETTER_AUTH_SECRET="test-secret-for-local-testing-minimum-32-chars-required" + export DATABASE_PATH="/app/data/test.db" + + if docker compose up -d; then + log_success "Services started" + else + log_error "Failed to start services" + exit 1 + fi + + # Wait for API health + log_info "Waiting for API to be healthy (max 60s)..." + SECONDS=0 + until docker inspect --format="{{.State.Health.Status}}" tuvix-api 2>/dev/null | grep -q "healthy"; do + if [ $SECONDS -gt 60 ]; then + log_error "API failed to become healthy after 60s" + docker logs tuvix-api + exit 1 + fi + sleep 2 + done + log_success "API is healthy" + + # Wait for App health + log_info "Waiting for App to be healthy (max 60s)..." + SECONDS=0 + until docker inspect --format="{{.State.Health.Status}}" tuvix-app 2>/dev/null | grep -q "healthy"; do + if [ $SECONDS -gt 60 ]; then + log_error "App failed to become healthy after 60s" + docker logs tuvix-app + exit 1 + fi + sleep 2 + done + log_success "App is healthy" + + # Test API endpoint + log_info "Testing API health endpoint..." + RESPONSE=$(curl -s http://localhost:3001/health) + if echo "$RESPONSE" | grep -q '"status":"ok"'; then + log_success "API health check passed" + echo " Response: $RESPONSE" + else + log_error "API health check failed" + echo " Response: $RESPONSE" + exit 1 + fi + + # Test App endpoint + log_info "Testing App health endpoint..." + RESPONSE=$(curl -s http://localhost:5173/health) + if echo "$RESPONSE" | grep -q 'ok'; then + log_success "App health check passed" + echo " Response: $RESPONSE" + else + log_error "App health check failed" + echo " Response: $RESPONSE" + exit 1 + fi + + # Verify non-root users + log_info "Verifying security (non-root users)..." + API_USER=$(docker exec tuvix-api id -u) + APP_USER=$(docker exec tuvix-app id -u) + + if [ "$API_USER" = "0" ] || [ "$APP_USER" = "0" ]; then + log_error "Containers running as root!" + echo " API: uid $API_USER" + echo " App: uid $APP_USER" + exit 1 + else + log_success "All containers running as non-root" + echo " API: uid $API_USER (nodejs)" + echo " App: uid $APP_USER (nginx-app)" + fi + + # Verify database + log_info "Verifying database migrations..." + if docker exec tuvix-api test -f /app/data/test.db; then + log_success "Database file exists" + docker exec tuvix-api ls -lh /app/data/test.db + else + log_warning "Database file not found (may not have created yet)" + fi + + if docker logs tuvix-api 2>&1 | grep -q "Migrations complete\|โœ… Migrations completed"; then + log_success "Migrations executed" + else + log_warning "Migration logs not found (check manually if needed)" + fi + + # Show container stats + log_info "Container statistics:" + docker stats --no-stream --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}" + + echo "" + echo "=========================================" + log_success "All tests passed!" + echo "=========================================" + echo "" + echo "Services are running at:" + echo " API: http://localhost:3001" + echo " App: http://localhost:5173" + echo "" + echo "To stop services, run:" + echo " docker compose down" + echo "" +} + +# Run main function +main "$@"