diff --git a/.changeset/ai-chat-view-activity-toggle.md b/.changeset/ai-chat-view-activity-toggle.md new file mode 100644 index 000000000..afe0e3344 --- /dev/null +++ b/.changeset/ai-chat-view-activity-toggle.md @@ -0,0 +1,5 @@ +--- +"gitbook": patch +--- + +Fix "View activity" disclosure in AI Chat not opening after the Base UI migration. diff --git a/.changeset/breadcrumbs-clear-page-actions.md b/.changeset/breadcrumbs-clear-page-actions.md new file mode 100644 index 000000000..5578d0473 --- /dev/null +++ b/.changeset/breadcrumbs-clear-page-actions.md @@ -0,0 +1,5 @@ +--- +"gitbook": patch +--- + +Keep the breadcrumbs from covering the page actions' hit area. diff --git a/.changeset/embed-search-tab-navigation.md b/.changeset/embed-search-tab-navigation.md new file mode 100644 index 000000000..4dd9395b5 --- /dev/null +++ b/.changeset/embed-search-tab-navigation.md @@ -0,0 +1,5 @@ +--- +"gitbook": patch +--- + +Fix switching from the Search tab to the Docs or Assistant tab in the embed doing nothing. diff --git a/.changeset/migrate-headless-primitives-to-base-ui.md b/.changeset/migrate-headless-primitives-to-base-ui.md new file mode 100644 index 000000000..c25622f16 --- /dev/null +++ b/.changeset/migrate-headless-primitives-to-base-ui.md @@ -0,0 +1,5 @@ +--- +"gitbook": patch +--- + +Migrate the headless UI primitives from Radix and react-aria to Base UI. diff --git a/.changeset/search-input-spacebar.md b/.changeset/search-input-spacebar.md new file mode 100644 index 000000000..52e8784c1 --- /dev/null +++ b/.changeset/search-input-spacebar.md @@ -0,0 +1,5 @@ +--- +"gitbook": patch +--- + +Fix the spacebar being ignored in the search bar, which made multi-word queries impossible. diff --git a/.changeset/tired-mails-fall.md b/.changeset/tired-mails-fall.md new file mode 100644 index 000000000..e0867d728 --- /dev/null +++ b/.changeset/tired-mails-fall.md @@ -0,0 +1,5 @@ +--- +"gitbook": patch +--- + +Support localized custom AI Assistant greeting subtitles. diff --git a/.changeset/tooltip-disclosure-open-state-conflict.md b/.changeset/tooltip-disclosure-open-state-conflict.md new file mode 100644 index 000000000..0878b3e23 --- /dev/null +++ b/.changeset/tooltip-disclosure-open-state-conflict.md @@ -0,0 +1,5 @@ +--- +"gitbook": patch +--- + +Fix chevrons and open-state styling incorrectly reacting to a tooltip opening on the same trigger, by switching from the shared Base UI `data-popup-open` attribute to `aria-expanded`. diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 000000000..ac3fb0063 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,10 @@ +# Stop editors from looking for .editorconfig files in parent directories. +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_style = space +indent_size = 4 +insert_final_newline = true +max_line_length = 100 diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index d5c6f5a21..182cb6f2e 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -76,7 +76,10 @@ bun dev ``` Additional development commands: -- `bun format`: Format the code using Biome +- `bun lint`: Lint the code using Oxlint +- `bun lint:fix`: Automatically fix lint issues using Oxlint +- `bun format`: Format the code using Oxfmt +- `bun format:check`: Check formatting without changing files - `bun typecheck`: Run TypeScript type checking - `bun unit`: Run unit tests - `bun e2e`: Run end-to-end tests diff --git a/.github/actions/gradual-deploy-cloudflare/action.yaml b/.github/actions/gradual-deploy-cloudflare/action.yaml index 48b078f96..4f4317047 100644 --- a/.github/actions/gradual-deploy-cloudflare/action.yaml +++ b/.github/actions/gradual-deploy-cloudflare/action.yaml @@ -1,83 +1,83 @@ name: Gradual Deploy to Cloudflare description: Use gradual deployment to deploy to Cloudflare. This action will upload the middleware and server versions to Cloudflare and kept them bound together inputs: - apiToken: - description: 'Cloudflare API token' - required: true - accountId: - description: 'Cloudflare account ID' - required: true - environment: - description: 'Cloudflare environment to deploy to (staging, production, preview)' - required: true - middlewareVersionId: - description: 'Middleware version ID to deploy' - required: true - serverVersionId: - description: 'Server version ID to deploy' - required: true + apiToken: + description: 'Cloudflare API token' + required: true + accountId: + description: 'Cloudflare account ID' + required: true + environment: + description: 'Cloudflare environment to deploy to (staging, production, preview)' + required: true + middlewareVersionId: + description: 'Middleware version ID to deploy' + required: true + serverVersionId: + description: 'Server version ID to deploy' + required: true outputs: - deployment-url: - description: "Deployment URL" - value: ${{ steps.deploy_middleware.outputs.deployment-url }} + deployment-url: + description: 'Deployment URL' + value: ${{ steps.deploy_middleware.outputs.deployment-url }} runs: - using: 'composite' - steps: - - id: wrangler_status - name: Check wrangler deployment status - uses: cloudflare/wrangler-action@v3.14.0 - with: - apiToken: ${{ inputs.apiToken }} - accountId: ${{ inputs.accountId }} - workingDirectory: ./ - wranglerVersion: '4.43.0' - environment: ${{ inputs.environment }} - command: deployments status --config ./packages/gitbook/openNext/customWorkers/defaultWrangler.jsonc + using: 'composite' + steps: + - id: wrangler_status + name: Check wrangler deployment status + uses: cloudflare/wrangler-action@v3.14.0 + with: + apiToken: ${{ inputs.apiToken }} + accountId: ${{ inputs.accountId }} + workingDirectory: ./ + wranglerVersion: '4.43.0' + environment: ${{ inputs.environment }} + command: deployments status --config ./packages/gitbook/openNext/customWorkers/defaultWrangler.jsonc - # This step is used to get the version ID that is currently deployed to Cloudflare. - - id: extract_current_version - name: Extract current version - shell: bash - run: | - version_id=$(echo "${{ steps.wrangler_status.outputs.command-output }}" | grep -A 3 "(100%)" | grep -oP '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}') - echo "version_id=$version_id" >> $GITHUB_OUTPUT + # This step is used to get the version ID that is currently deployed to Cloudflare. + - id: extract_current_version + name: Extract current version + shell: bash + run: | + version_id=$(echo "${{ steps.wrangler_status.outputs.command-output }}" | grep -A 3 "(100%)" | grep -oP '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}') + echo "version_id=$version_id" >> $GITHUB_OUTPUT - - id: deploy_server - name: Deploy server to Cloudflare at 0% - uses: cloudflare/wrangler-action@v3.14.0 - with: - apiToken: ${{ inputs.apiToken }} - accountId: ${{ inputs.accountId }} - workingDirectory: ./ - wranglerVersion: '4.43.0' - environment: ${{ inputs.environment }} - command: versions deploy ${{ steps.extract_current_version.outputs.version_id }}@100% ${{ inputs.serverVersionId }}@0% -y --config ./packages/gitbook/openNext/customWorkers/defaultWrangler.jsonc + - id: deploy_server + name: Deploy server to Cloudflare at 0% + uses: cloudflare/wrangler-action@v3.14.0 + with: + apiToken: ${{ inputs.apiToken }} + accountId: ${{ inputs.accountId }} + workingDirectory: ./ + wranglerVersion: '4.43.0' + environment: ${{ inputs.environment }} + command: versions deploy ${{ steps.extract_current_version.outputs.version_id }}@100% ${{ inputs.serverVersionId }}@0% -y --config ./packages/gitbook/openNext/customWorkers/defaultWrangler.jsonc - # Since we use version overrides headers, we can directly deploy the middleware to 100%. - - id: deploy_middleware - name: Deploy middleware to Cloudflare at 100% - uses: cloudflare/wrangler-action@v3.14.0 - with: - apiToken: ${{ inputs.apiToken }} - accountId: ${{ inputs.accountId }} - workingDirectory: ./ - wranglerVersion: '4.43.0' - environment: ${{ inputs.environment }} - command: versions deploy ${{ inputs.middlewareVersionId }}@100% -y --config ./packages/gitbook/openNext/customWorkers/middlewareWrangler.jsonc + # Since we use version overrides headers, we can directly deploy the middleware to 100%. + - id: deploy_middleware + name: Deploy middleware to Cloudflare at 100% + uses: cloudflare/wrangler-action@v3.14.0 + with: + apiToken: ${{ inputs.apiToken }} + accountId: ${{ inputs.accountId }} + workingDirectory: ./ + wranglerVersion: '4.43.0' + environment: ${{ inputs.environment }} + command: versions deploy ${{ inputs.middlewareVersionId }}@100% -y --config ./packages/gitbook/openNext/customWorkers/middlewareWrangler.jsonc - - name: Deploy server to Cloudflare at 100% - uses: cloudflare/wrangler-action@v3.14.0 - with: - apiToken: ${{ inputs.apiToken }} - accountId: ${{ inputs.accountId }} - workingDirectory: ./ - wranglerVersion: '4.43.0' - environment: ${{ inputs.environment }} - command: versions deploy ${{ inputs.serverVersionId }}@100% -y --config ./packages/gitbook/openNext/customWorkers/defaultWrangler.jsonc + - name: Deploy server to Cloudflare at 100% + uses: cloudflare/wrangler-action@v3.14.0 + with: + apiToken: ${{ inputs.apiToken }} + accountId: ${{ inputs.accountId }} + workingDirectory: ./ + wranglerVersion: '4.43.0' + environment: ${{ inputs.environment }} + command: versions deploy ${{ inputs.serverVersionId }}@100% -y --config ./packages/gitbook/openNext/customWorkers/defaultWrangler.jsonc - - name: Outputs - shell: bash - env: - DEPLOYMENT_URL: ${{ steps.deploy_middleware.outputs.deployment-url }} - run: | - echo "URL: ${{ steps.deploy_middleware.outputs.deployment-url }}" \ No newline at end of file + - name: Outputs + shell: bash + env: + DEPLOYMENT_URL: ${{ steps.deploy_middleware.outputs.deployment-url }} + run: | + echo "URL: ${{ steps.deploy_middleware.outputs.deployment-url }}" diff --git a/.github/composite/deploy-cloudflare/action.yaml b/.github/composite/deploy-cloudflare/action.yaml index 28055170d..77bc5689d 100644 --- a/.github/composite/deploy-cloudflare/action.yaml +++ b/.github/composite/deploy-cloudflare/action.yaml @@ -1,34 +1,34 @@ name: 'Deploy cloudflare' description: 'Deploy GitBook to Cloudflare' inputs: - opItem: - description: '1Password item to load secrets from' - required: true - opServiceAccount: - description: '1Password service account token' - required: true - apiToken: - description: 'Cloudflare API token' - required: true - accountId: - description: 'Cloudflare account ID' - required: true - environment: - description: 'Cloudflare environment to deploy to (staging, production, preview)' - required: true - deploy: - description: 'Deploy as main version for all traffic instead of uploading versions' - required: true - commitTag: - description: 'Commit branch to associate with the deployment' - required: true - commitMessage: - description: 'Commit message to associate with the deployment' - required: true + opItem: + description: '1Password item to load secrets from' + required: true + opServiceAccount: + description: '1Password service account token' + required: true + apiToken: + description: 'Cloudflare API token' + required: true + accountId: + description: 'Cloudflare account ID' + required: true + environment: + description: 'Cloudflare environment to deploy to (staging, production, preview)' + required: true + deploy: + description: 'Deploy as main version for all traffic instead of uploading versions' + required: true + commitTag: + description: 'Commit branch to associate with the deployment' + required: true + commitMessage: + description: 'Commit message to associate with the deployment' + required: true outputs: deployment-url: - description: "Deployment URL" - value: ${{ steps.upload_middleware.outputs.deployment-url }} + description: 'Deployment URL' + value: ${{ steps.upload_middleware.outputs.deployment-url }} runs: using: 'composite' steps: @@ -42,33 +42,33 @@ runs: - name: Load secret uses: 1password/load-secrets-action@v2 env: - OP_SERVICE_ACCOUNT_TOKEN: ${{ inputs.opServiceAccount }} - GITBOOK_URL: ${{ inputs.opItem }}/GITBOOK_URL - GITBOOK_ICONS_URL: ${{ inputs.opItem }}/GITBOOK_ICONS_URL - GITBOOK_ICONS_TOKEN: ${{ inputs.opItem }}/GITBOOK_ICONS_TOKEN - NEXT_SERVER_ACTIONS_ENCRYPTION_KEY: ${{ inputs.opItem }}/NEXT_SERVER_ACTIONS_ENCRYPTION_KEY - GITBOOK_SECRET: ${{ inputs.opItem }}/GITBOOK_SECRET - GITBOOK_APP_URL: ${{ inputs.opItem }}/GITBOOK_APP_URL - GITBOOK_API_URL: ${{ inputs.opItem }}/GITBOOK_API_URL - GITBOOK_API_PUBLIC_URL: ${{ inputs.opItem }}/GITBOOK_API_PUBLIC_URL - GITBOOK_API_TOKEN: ${{ inputs.opItem }}/GITBOOK_API_TOKEN - GITBOOK_OAUTH_SERVER_URL: ${{ inputs.opItem }}/GITBOOK_OAUTH_SERVER_URL - GITBOOK_SITE_OAUTH_SIGNING_SECRET: ${{ inputs.opItem }}/GITBOOK_SITE_OAUTH_SIGNING_SECRET - GITBOOK_PREVIEW_BASE_URL: ${{ inputs.opItem }}/GITBOOK_PREVIEW_BASE_URL - GITBOOK_INTEGRATIONS_HOST: ${{ inputs.opItem }}/GITBOOK_INTEGRATIONS_HOST - GITBOOK_INTEGRATIONS_CONTENT_HOST: ${{ inputs.opItem }}/GITBOOK_INTEGRATIONS_CONTENT_HOST - GITBOOK_IMAGE_RESIZE_SIGNING_KEY: ${{ inputs.opItem }}/GITBOOK_IMAGE_RESIZE_SIGNING_KEY - GITBOOK_IMAGE_RESIZE_URL: ${{ inputs.opItem }}/GITBOOK_IMAGE_RESIZE_URL_2 - GITBOOK_IMAGE_RESIZE_SALT: ${{ inputs.opItem }}/GITBOOK_IMAGE_RESIZE_SALT - GITBOOK_IMAGE_RESIZE_MODE: ${{ inputs.opItem }}/GITBOOK_IMAGE_RESIZE_MODE - GITBOOK_ASSETS_PREFIX: ${{ inputs.opItem }}/GITBOOK_ASSETS_PREFIX - GITBOOK_FONTS_URL: ${{ inputs.opItem }}/GITBOOK_FONTS_URL + OP_SERVICE_ACCOUNT_TOKEN: ${{ inputs.opServiceAccount }} + GITBOOK_URL: ${{ inputs.opItem }}/GITBOOK_URL + GITBOOK_ICONS_URL: ${{ inputs.opItem }}/GITBOOK_ICONS_URL + GITBOOK_ICONS_TOKEN: ${{ inputs.opItem }}/GITBOOK_ICONS_TOKEN + NEXT_SERVER_ACTIONS_ENCRYPTION_KEY: ${{ inputs.opItem }}/NEXT_SERVER_ACTIONS_ENCRYPTION_KEY + GITBOOK_SECRET: ${{ inputs.opItem }}/GITBOOK_SECRET + GITBOOK_APP_URL: ${{ inputs.opItem }}/GITBOOK_APP_URL + GITBOOK_API_URL: ${{ inputs.opItem }}/GITBOOK_API_URL + GITBOOK_API_PUBLIC_URL: ${{ inputs.opItem }}/GITBOOK_API_PUBLIC_URL + GITBOOK_API_TOKEN: ${{ inputs.opItem }}/GITBOOK_API_TOKEN + GITBOOK_OAUTH_SERVER_URL: ${{ inputs.opItem }}/GITBOOK_OAUTH_SERVER_URL + GITBOOK_SITE_OAUTH_SIGNING_SECRET: ${{ inputs.opItem }}/GITBOOK_SITE_OAUTH_SIGNING_SECRET + GITBOOK_PREVIEW_BASE_URL: ${{ inputs.opItem }}/GITBOOK_PREVIEW_BASE_URL + GITBOOK_INTEGRATIONS_HOST: ${{ inputs.opItem }}/GITBOOK_INTEGRATIONS_HOST + GITBOOK_INTEGRATIONS_CONTENT_HOST: ${{ inputs.opItem }}/GITBOOK_INTEGRATIONS_CONTENT_HOST + GITBOOK_IMAGE_RESIZE_SIGNING_KEY: ${{ inputs.opItem }}/GITBOOK_IMAGE_RESIZE_SIGNING_KEY + GITBOOK_IMAGE_RESIZE_URL: ${{ inputs.opItem }}/GITBOOK_IMAGE_RESIZE_URL_2 + GITBOOK_IMAGE_RESIZE_SALT: ${{ inputs.opItem }}/GITBOOK_IMAGE_RESIZE_SALT + GITBOOK_IMAGE_RESIZE_MODE: ${{ inputs.opItem }}/GITBOOK_IMAGE_RESIZE_MODE + GITBOOK_ASSETS_PREFIX: ${{ inputs.opItem }}/GITBOOK_ASSETS_PREFIX + GITBOOK_FONTS_URL: ${{ inputs.opItem }}/GITBOOK_FONTS_URL - name: Build worker run: bun run turbo build:cloudflare env: - GITBOOK_RUNTIME: cloudflare - GITBOOK_BLOCK_SEARCH_INDEXATION: ${{ inputs.environment == 'preview' && 'true' || '' }} - GITBOOK_ALLOW_CUSTOMIZATION_OVERRIDE: ${{ inputs.environment == 'preview' && 'true' || '' }} + GITBOOK_RUNTIME: cloudflare + GITBOOK_BLOCK_SEARCH_INDEXATION: ${{ inputs.environment == 'preview' && 'true' || '' }} + GITBOOK_ALLOW_CUSTOMIZATION_OVERRIDE: ${{ inputs.environment == 'preview' && 'true' || '' }} shell: bash - name: Upload the DO worker @@ -135,11 +135,10 @@ runs: middlewareVersionId: ${{ steps.extract_middleware_version_id.outputs.version_id }} deploy: ${{ inputs.deploy }} - - name: Outputs shell: bash env: - DEPLOYMENT_URL: ${{ steps.upload_middleware.outputs.deployment-url }} + DEPLOYMENT_URL: ${{ steps.upload_middleware.outputs.deployment-url }} run: | echo "URL: ${{ steps.upload_middleware.outputs.deployment-url }}" - echo "Output server: ${{ steps.upload_server.outputs.command-output }}" \ No newline at end of file + echo "Output server: ${{ steps.upload_server.outputs.command-output }}" diff --git a/.github/composite/deploy-vercel/action.yaml b/.github/composite/deploy-vercel/action.yaml index 974e9c980..4aa9fbbfe 100644 --- a/.github/composite/deploy-vercel/action.yaml +++ b/.github/composite/deploy-vercel/action.yaml @@ -1,31 +1,31 @@ name: 'Deploy vercel' description: 'Deploy GitBook to Vercel' inputs: - vercelOrg: - description: 'Vercel organization' - required: true - vercelProject: - description: 'Vercel project' - required: true - vercelToken: - description: 'Vercel token' - required: true - opItem: - description: '1Password item to load secrets from' - required: true - opServiceAccount: - description: '1Password service account token' - required: true - environment: - description: 'Environment to deploy to' - required: true - headSha: - description: 'Git ref to deploy, used for the deploymentId' - required: false + vercelOrg: + description: 'Vercel organization' + required: true + vercelProject: + description: 'Vercel project' + required: true + vercelToken: + description: 'Vercel token' + required: true + opItem: + description: '1Password item to load secrets from' + required: true + opServiceAccount: + description: '1Password service account token' + required: true + environment: + description: 'Environment to deploy to' + required: true + headSha: + description: 'Git ref to deploy, used for the deploymentId' + required: false outputs: deployment-url: - description: "Deployment URL" - value: ${{ steps.deploy.outputs.deployment-url }} + description: 'Deployment URL' + value: ${{ steps.deploy.outputs.deployment-url }} runs: using: 'composite' steps: @@ -40,51 +40,51 @@ runs: run: bun run vercel pull --yes --environment=${{ inputs.environment }} --token=${{ inputs.vercelToken }} shell: bash env: - VERCEL_ORG_ID: ${{ inputs.vercelOrg }} - VERCEL_PROJECT_ID: ${{ inputs.vercelProject }} + VERCEL_ORG_ID: ${{ inputs.vercelOrg }} + VERCEL_PROJECT_ID: ${{ inputs.vercelProject }} - name: Load secret uses: 1password/load-secrets-action@v2 env: - OP_SERVICE_ACCOUNT_TOKEN: ${{ inputs.opServiceAccount }} - GITBOOK_URL: ${{ inputs.opItem }}/GITBOOK_URL - GITBOOK_ICONS_URL: ${{ inputs.opItem }}/GITBOOK_ICONS_URL - GITBOOK_ICONS_TOKEN: ${{ inputs.opItem }}/GITBOOK_ICONS_TOKEN - GITBOOK_SECRET: ${{ inputs.opItem }}/GITBOOK_SECRET - GITBOOK_APP_URL: ${{ inputs.opItem }}/GITBOOK_APP_URL - GITBOOK_API_URL: ${{ inputs.opItem }}/GITBOOK_API_URL - GITBOOK_API_PUBLIC_URL: ${{ inputs.opItem }}/GITBOOK_API_PUBLIC_URL - GITBOOK_API_TOKEN: ${{ inputs.opItem }}/GITBOOK_API_TOKEN - GITBOOK_OAUTH_SERVER_URL: ${{ inputs.opItem }}/GITBOOK_OAUTH_SERVER_URL - GITBOOK_SITE_OAUTH_SIGNING_SECRET: ${{ inputs.opItem }}/GITBOOK_SITE_OAUTH_SIGNING_SECRET - GITBOOK_PREVIEW_BASE_URL: ${{ inputs.opItem }}/GITBOOK_PREVIEW_BASE_URL - GITBOOK_INTEGRATIONS_HOST: ${{ inputs.opItem }}/GITBOOK_INTEGRATIONS_HOST - GITBOOK_INTEGRATIONS_CONTENT_HOST: ${{ inputs.opItem }}/GITBOOK_INTEGRATIONS_CONTENT_HOST - GITBOOK_IMAGE_RESIZE_SIGNING_KEY: ${{ inputs.opItem }}/GITBOOK_IMAGE_RESIZE_SIGNING_KEY - GITBOOK_IMAGE_RESIZE_URL: ${{ inputs.opItem }}/GITBOOK_IMAGE_RESIZE_URL_2 - GITBOOK_IMAGE_RESIZE_SALT: ${{ inputs.opItem }}/GITBOOK_IMAGE_RESIZE_SALT - GITBOOK_IMAGE_RESIZE_MODE: ${{ inputs.opItem }}/GITBOOK_IMAGE_RESIZE_MODE - GITBOOK_ASSETS_PREFIX: ${{ inputs.opItem }}/GITBOOK_ASSETS_PREFIX - GITBOOK_FONTS_URL: ${{ inputs.opItem }}/GITBOOK_FONTS_URL + OP_SERVICE_ACCOUNT_TOKEN: ${{ inputs.opServiceAccount }} + GITBOOK_URL: ${{ inputs.opItem }}/GITBOOK_URL + GITBOOK_ICONS_URL: ${{ inputs.opItem }}/GITBOOK_ICONS_URL + GITBOOK_ICONS_TOKEN: ${{ inputs.opItem }}/GITBOOK_ICONS_TOKEN + GITBOOK_SECRET: ${{ inputs.opItem }}/GITBOOK_SECRET + GITBOOK_APP_URL: ${{ inputs.opItem }}/GITBOOK_APP_URL + GITBOOK_API_URL: ${{ inputs.opItem }}/GITBOOK_API_URL + GITBOOK_API_PUBLIC_URL: ${{ inputs.opItem }}/GITBOOK_API_PUBLIC_URL + GITBOOK_API_TOKEN: ${{ inputs.opItem }}/GITBOOK_API_TOKEN + GITBOOK_OAUTH_SERVER_URL: ${{ inputs.opItem }}/GITBOOK_OAUTH_SERVER_URL + GITBOOK_SITE_OAUTH_SIGNING_SECRET: ${{ inputs.opItem }}/GITBOOK_SITE_OAUTH_SIGNING_SECRET + GITBOOK_PREVIEW_BASE_URL: ${{ inputs.opItem }}/GITBOOK_PREVIEW_BASE_URL + GITBOOK_INTEGRATIONS_HOST: ${{ inputs.opItem }}/GITBOOK_INTEGRATIONS_HOST + GITBOOK_INTEGRATIONS_CONTENT_HOST: ${{ inputs.opItem }}/GITBOOK_INTEGRATIONS_CONTENT_HOST + GITBOOK_IMAGE_RESIZE_SIGNING_KEY: ${{ inputs.opItem }}/GITBOOK_IMAGE_RESIZE_SIGNING_KEY + GITBOOK_IMAGE_RESIZE_URL: ${{ inputs.opItem }}/GITBOOK_IMAGE_RESIZE_URL_2 + GITBOOK_IMAGE_RESIZE_SALT: ${{ inputs.opItem }}/GITBOOK_IMAGE_RESIZE_SALT + GITBOOK_IMAGE_RESIZE_MODE: ${{ inputs.opItem }}/GITBOOK_IMAGE_RESIZE_MODE + GITBOOK_ASSETS_PREFIX: ${{ inputs.opItem }}/GITBOOK_ASSETS_PREFIX + GITBOOK_FONTS_URL: ${{ inputs.opItem }}/GITBOOK_FONTS_URL - name: Inject build env vars if: ${{ inputs.environment == 'preview' }} shell: bash run: | - HEAD_SHA=$(git rev-parse HEAD) - echo "resolved HEAD_SHA: $HEAD_SHA" - echo "GITBOOK_HEAD_SHA=$HEAD_SHA" >> .vercel/.env.${{ inputs.environment }}.local - echo "GITBOOK_RUNTIME=vercel" >> .vercel/.env.${{ inputs.environment }}.local - echo "GITBOOK_BLOCK_SEARCH_INDEXATION=true" >> .vercel/.env.${{ inputs.environment }}.local - echo "GITBOOK_ALLOW_CUSTOMIZATION_OVERRIDE=true" >> .vercel/.env.${{ inputs.environment }}.local - echo "--- .vercel/.env.${{ inputs.environment }}.local after inject ---" - cat .vercel/.env.${{ inputs.environment }}.local + HEAD_SHA=$(git rev-parse HEAD) + echo "resolved HEAD_SHA: $HEAD_SHA" + echo "GITBOOK_HEAD_SHA=$HEAD_SHA" >> .vercel/.env.${{ inputs.environment }}.local + echo "GITBOOK_RUNTIME=vercel" >> .vercel/.env.${{ inputs.environment }}.local + echo "GITBOOK_BLOCK_SEARCH_INDEXATION=true" >> .vercel/.env.${{ inputs.environment }}.local + echo "GITBOOK_ALLOW_CUSTOMIZATION_OVERRIDE=true" >> .vercel/.env.${{ inputs.environment }}.local + echo "--- .vercel/.env.${{ inputs.environment }}.local after inject ---" + cat .vercel/.env.${{ inputs.environment }}.local - name: Build Project Artifacts run: bun run vercel build --target=${{ inputs.environment }} --token=${{ inputs.vercelToken }} shell: bash env: - VERCEL_ORG_ID: ${{ inputs.vercelOrg }} - VERCEL_PROJECT_ID: ${{ inputs.vercelProject }} - GITBOOK_RUNTIME: vercel - GITBOOK_HEAD_SHA: ${{ inputs.headSha }} + VERCEL_ORG_ID: ${{ inputs.vercelOrg }} + VERCEL_PROJECT_ID: ${{ inputs.vercelProject }} + GITBOOK_RUNTIME: vercel + GITBOOK_HEAD_SHA: ${{ inputs.headSha }} - name: Deploy Project Artifacts to Vercel id: deploy shell: bash @@ -92,10 +92,9 @@ runs: DEPLOYMENT_URL=$(bun run vercel deploy --prebuilt --target=${{ inputs.environment }} --token=${{ inputs.vercelToken }}) echo "deployment-url=$DEPLOYMENT_URL" >> "$GITHUB_OUTPUT" env: - VERCEL_ORG_ID: ${{ inputs.vercelOrg }} - VERCEL_PROJECT_ID: ${{ inputs.vercelProject }} + VERCEL_ORG_ID: ${{ inputs.vercelOrg }} + VERCEL_PROJECT_ID: ${{ inputs.vercelProject }} - name: Outputs shell: bash run: | echo "URL: ${{ steps.deploy.outputs.deployment-url }}" - diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index b92d860ca..a627b4546 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -20,6 +20,20 @@ jobs: env: PUPPETEER_SKIP_DOWNLOAD: 1 - run: bun format:check + lint: + runs-on: ubuntu-latest + name: Lint + timeout-minutes: 6 + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Setup Bun + uses: ./.github/composite/setup-bun + - name: Install dependencies + run: bun install --frozen-lockfile + env: + PUPPETEER_SKIP_DOWNLOAD: 1 + - run: bun lint test: runs-on: ubuntu-latest name: Test diff --git a/.github/workflows/css-browser-compatibility.yaml b/.github/workflows/css-browser-compatibility.yaml index 76be1dba0..ade3ee0ee 100644 --- a/.github/workflows/css-browser-compatibility.yaml +++ b/.github/workflows/css-browser-compatibility.yaml @@ -6,7 +6,6 @@ on: permissions: contents: read - issues: write pull-requests: read concurrency: diff --git a/.github/workflows/deploy-preview.yaml b/.github/workflows/deploy-preview.yaml index 44269f1d1..4b0cae96c 100644 --- a/.github/workflows/deploy-preview.yaml +++ b/.github/workflows/deploy-preview.yaml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest if: ${{ github.event_name == 'pull_request_target' && github.event.pull_request.head.repo.fork }} environment: - name: preview-approval + name: preview-approval steps: - name: Approval gate run: echo "Preview deployment approved." @@ -21,8 +21,8 @@ jobs: needs: approval if: ${{ always() && (needs.approval.result == 'success' || needs.approval.result == 'skipped') }} environment: - name: 2v-preview - url: ${{ steps.deploy.outputs.deployment-url }} + name: 2v-preview + url: ${{ steps.deploy.outputs.deployment-url }} outputs: deployment-url: ${{ steps.deploy.outputs.deployment-url }} steps: @@ -47,8 +47,8 @@ jobs: needs: approval if: ${{ always() && (needs.approval.result == 'success' || needs.approval.result == 'skipped') }} environment: - name: 2c-preview - url: ${{ steps.deploy.outputs.deployment-url }} + name: 2c-preview + url: ${{ steps.deploy.outputs.deployment-url }} outputs: deployment-url: ${{ steps.deploy.outputs.deployment-url || steps.extract-worker-id.outputs.worker-url }} steps: @@ -72,10 +72,10 @@ jobs: id: extract-worker-id if: ${{ !steps.deploy.outputs.deployment-url }} run: | - if [[ "${{ steps.deploy.outputs.command-output }}" =~ Worker\ Version\ ID:\ ([0-9a-f]{8})-([0-9a-f-]+) ]]; then - WORKER_ID_FIRST_PART="${BASH_REMATCH[1]}" - echo "worker-url=https://${WORKER_ID_FIRST_PART}-gitbook-open-v2-preview.gitbook.workers.dev/" >> $GITHUB_OUTPUT - fi + if [[ "${{ steps.deploy.outputs.command-output }}" =~ Worker\ Version\ ID:\ ([0-9a-f]{8})-([0-9a-f-]+) ]]; then + WORKER_ID_FIRST_PART="${BASH_REMATCH[1]}" + echo "worker-url=https://${WORKER_ID_FIRST_PART}-gitbook-open-v2-preview.gitbook.workers.dev/" >> $GITHUB_OUTPUT + fi - name: Outputs run: | echo "URL: ${{ steps.deploy.outputs.deployment-url || steps.extract-worker-id.outputs.worker-url }}" @@ -187,6 +187,54 @@ jobs: SITE_BASE_URL: ${{ needs.deploy-v2-vercel.outputs.deployment-url }}/url/ ARGOS_TOKEN: ${{ secrets.ARGOS_TOKEN }} ARGOS_BUILD_NAME: customers-v2-vercel + + # Style recalc depends on the client bundle, not the host, so this runs here only and + # not in the Cloudflare job. Kept out of `e2e-customers`, which is a visual suite. + - name: Run style invalidation tests + if: always() + working-directory: packages/gitbook + run: bun run e2e-style-perf + env: + BASE_URL: ${{ needs.deploy-v2-vercel.outputs.deployment-url }} + SITE_BASE_URL: ${{ needs.deploy-v2-vercel.outputs.deployment-url }}/url/ + + # Runs on failure too: a blown style budget is exactly when the numbers are worth seeing. + - name: Build style invalidation report + if: always() && github.event_name != 'push' + id: style-perf + working-directory: packages/gitbook + run: | + rows=$(cat test-results/style-perf.md 2>/dev/null || true) + if [ -z "$rows" ]; then exit 0; fi + { + echo 'body<> "$GITHUB_OUTPUT" + + - name: Find style invalidation comment + if: always() && github.event_name != 'push' && steps.style-perf.outputs.body != '' + uses: peter-evans/find-comment@v3 + id: fc-style-perf + with: + issue-number: ${{ github.event.pull_request.number }} + comment-author: 'github-actions[bot]' + body-includes: 'Style invalidation on a large API reference' + + - name: Create or update style invalidation comment + if: always() && github.event_name != 'push' && steps.style-perf.outputs.body != '' + uses: peter-evans/create-or-update-comment@v4 + with: + comment-id: ${{ steps.fc-style-perf.outputs.comment-id }} + issue-number: ${{ github.event.pull_request.number }} + body: ${{ steps.style-perf.outputs.body }} + edit-mode: replace visual-testing-customers-v2-cloudflare: runs-on: ubuntu-latest name: Visual Testing Customers v2 (Cloudflare) diff --git a/.github/workflows/deploy-production.yaml b/.github/workflows/deploy-production.yaml index fee8519ab..dcf465a76 100644 --- a/.github/workflows/deploy-production.yaml +++ b/.github/workflows/deploy-production.yaml @@ -7,7 +7,7 @@ jobs: deploy-v2-vercel: name: Deploy v2 to Vercel (production) runs-on: ubuntu-latest - environment: + environment: name: 2v-production url: ${{ steps.deploy.outputs.deployment-url }} outputs: @@ -19,16 +19,16 @@ jobs: id: deploy uses: ./.github/composite/deploy-vercel with: - environment: production - vercelOrg: ${{ secrets.VERCEL_ORG_ID }} - vercelProject: ${{ secrets.VERCEL_PROJECT_ID }} - vercelToken: ${{ secrets.VERCEL_TOKEN }} - opItem: op://gitbook-open/2v-production - opServiceAccount: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }} + environment: production + vercelOrg: ${{ secrets.VERCEL_ORG_ID }} + vercelProject: ${{ secrets.VERCEL_PROJECT_ID }} + vercelToken: ${{ secrets.VERCEL_TOKEN }} + opItem: op://gitbook-open/2v-production + opServiceAccount: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }} deploy-v2-cloudflare: name: Deploy v2 to Cloudflare Worker (production) runs-on: ubuntu-latest - environment: + environment: name: 2c-production url: ${{ steps.deploy.outputs.deployment-url }} outputs: @@ -50,4 +50,4 @@ jobs: commitMessage: ${{ github.sha }} - name: Outputs run: | - echo "URL: ${{ steps.deploy.outputs.deployment-url }}" \ No newline at end of file + echo "URL: ${{ steps.deploy.outputs.deployment-url }}" diff --git a/.github/workflows/deploy-staging.yaml b/.github/workflows/deploy-staging.yaml index c7766a903..394ede813 100644 --- a/.github/workflows/deploy-staging.yaml +++ b/.github/workflows/deploy-staging.yaml @@ -7,7 +7,7 @@ jobs: deploy-v2-vercel: name: Deploy v2 to Vercel (staging) runs-on: ubuntu-latest - environment: + environment: name: 2v-staging url: ${{ steps.deploy.outputs.deployment-url }} outputs: @@ -19,16 +19,16 @@ jobs: id: deploy uses: ./.github/composite/deploy-vercel with: - environment: staging - vercelOrg: ${{ secrets.VERCEL_ORG_ID }} - vercelProject: ${{ secrets.VERCEL_PROJECT_ID }} - vercelToken: ${{ secrets.VERCEL_TOKEN }} - opItem: op://gitbook-open/2v-staging - opServiceAccount: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }} + environment: staging + vercelOrg: ${{ secrets.VERCEL_ORG_ID }} + vercelProject: ${{ secrets.VERCEL_PROJECT_ID }} + vercelToken: ${{ secrets.VERCEL_TOKEN }} + opItem: op://gitbook-open/2v-staging + opServiceAccount: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }} deploy-v2-cloudflare: name: Deploy v2 to Cloudflare Worker (staging) runs-on: ubuntu-latest - environment: + environment: name: 2c-staging url: ${{ steps.deploy.outputs.deployment-url }} outputs: @@ -50,4 +50,4 @@ jobs: commitMessage: ${{ github.sha }} - name: Outputs run: | - echo "URL: ${{ steps.deploy.outputs.deployment-url }}" \ No newline at end of file + echo "URL: ${{ steps.deploy.outputs.deployment-url }}" diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml index 68bbbdc0b..3316674b6 100644 --- a/.github/workflows/publish.yaml +++ b/.github/workflows/publish.yaml @@ -4,7 +4,7 @@ on: push: branches: - main - + concurrency: ${{ github.workflow }}-${{ github.ref }} jobs: diff --git a/.oxfmtrc.json b/.oxfmtrc.json new file mode 100644 index 000000000..094382322 --- /dev/null +++ b/.oxfmtrc.json @@ -0,0 +1,70 @@ +{ + "$schema": "./node_modules/oxfmt/configuration_schema.json", + "printWidth": 100, + "tabWidth": 4, + "useTabs": false, + "semi": true, + "singleQuote": true, + "jsxSingleQuote": false, + "quoteProps": "as-needed", + "trailingComma": "es5", + "bracketSpacing": true, + "bracketSameLine": false, + "arrowParens": "always", + "endOfLine": "lf", + "sortImports": { + "customGroups": [ + { + "groupName": "workspace", + "elementNamePattern": ["@gitbook/**"] + } + ], + "groups": [ + ["value-builtin", "value-external", "type-builtin", "type-external"], + { "newlinesBetween": true }, + "workspace", + { "newlinesBetween": true }, + [ + "value-internal", + "type-internal", + "value-parent", + "type-parent", + "value-sibling", + "type-sibling", + "value-index", + "type-index" + ], + "type-import", + "unknown" + ] + }, + "sortPackageJson": false, + "sortTailwindcss": { + "config": "./packages/gitbook/tailwind.config.ts", + "attributes": ["class", "className", "style"], + "functions": ["clsx", "tw"] + }, + "ignorePatterns": [ + "**/node_modules/**", + "**/dist/**", + "**/build/**", + "**/public/**", + "**/.next/**", + "**/.open-next/**", + "**/.turbo/**", + "**/.vercel/**", + "**/.cache/**", + "**/.wrangler/**", + "**/*.log", + "**/*.MD", + "**/*.md", + "**/*.mdx", + "**/*.html", + "**/*.css", + "packages/embed/standalone/**", + "packages/openapi-parser/src/fixtures/**", + "packages/emoji-codepoints/index.ts", + "packages/icons/src/data/*.json", + "packages/gitbook/worker-configuration.d.ts" + ] +} diff --git a/.oxlintrc.json b/.oxlintrc.json new file mode 100644 index 000000000..f77105a94 --- /dev/null +++ b/.oxlintrc.json @@ -0,0 +1,87 @@ +{ + "$schema": "./node_modules/oxlint/configuration_schema.json", + "categories": { + "correctness": "warn", + "suspicious": "warn", + "perf": "warn" + }, + "plugins": ["eslint", "typescript", "unicorn", "oxc", "react", "jsx-a11y", "vitest"], + "env": { + "builtin": true, + "browser": true, + "node": true, + "shared-node-browser": true, + "worker": true + }, + "globals": { + "Bun": "readonly", + "GitBookIntegrationEvent": "readonly", + "React": "readonly" + }, + "rules": { + "eslint/no-console": [ + "warn", + { + "allow": ["assert", "error", "warn"] + } + ], + "eslint/no-control-regex": "warn", + "eslint/no-prototype-builtins": "warn", + "eslint/no-cond-assign": "warn", + "eslint/no-undef": "error", + "eslint/no-unused-vars": [ + "error", + { + "argsIgnorePattern": "^_", + "caughtErrorsIgnorePattern": "^_", + "ignoreRestSiblings": true, + "varsIgnorePattern": "^_" + } + ], + "react/button-has-type": "warn", + "react/exhaustive-deps": "warn", + "react/jsx-key": "warn", + "react/jsx-no-useless-fragment": "warn", + "react/no-array-index-key": "warn", + "react/void-dom-elements-no-children": "warn", + "react/rules-of-hooks": "error", + "jsx-a11y/alt-text": "warn", + "jsx-a11y/anchor-is-valid": "warn", + "jsx-a11y/click-events-have-key-events": "warn", + "jsx-a11y/iframe-has-title": "warn", + "jsx-a11y/interactive-supports-focus": "warn", + "jsx-a11y/label-has-associated-control": "warn", + "jsx-a11y/no-noninteractive-tabindex": "warn", + "jsx-a11y/role-has-required-aria-props": "warn", + "jsx-a11y/tabindex-no-positive": "warn", + "typescript/array-type": "error", + "typescript/no-explicit-any": "warn", + "typescript/no-non-null-assertion": "warn", + "typescript/no-confusing-void-expression": "warn", + "typescript/only-throw-error": "error", + "vitest/no-focused-tests": "error", + "no-delete-var": "warn", + "no-debugger": "error", + "no-throw-literal": "error", + "use-isnan": "error", + "valid-typeof": "error" + }, + "ignorePatterns": [ + "**/node_modules/**", + "**/dist/**", + "**/build/**", + "**/public/**", + "**/.next/**", + "**/.open-next/**", + "**/.turbo/**", + "**/.vercel/**", + "**/.cache/**", + "**/.wrangler/**", + "packages/embed/standalone/**", + "packages/openapi-parser/src/fixtures/**", + "packages/emoji-codepoints/index.ts", + "packages/icons/src/data/*.json", + "packages/gitbook/worker-configuration.d.ts", + "**/*.css" + ] +} diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 5f44864b4..9d5eb3d7f 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,3 +1,3 @@ { - "recommendations": ["biomejs.biome"] + "recommendations": ["oxc.oxc-vscode"] } diff --git a/.vscode/settings.json b/.vscode/settings.json index 8a86e5d5d..b0966a99e 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -8,14 +8,12 @@ ["style \\=([^;]*);", "\\`([^\\`]*)\\`"] ], "tailwindCSS.classAttributes": ["class", "className", "style", ".*Style"], - "prettier.enable": false, "editor.formatOnSave": true, - "editor.defaultFormatter": "biomejs.biome", + "editor.defaultFormatter": "oxc.oxc-vscode", "editor.codeActionsOnSave": { - "source.organizeImports.biome": "explicit", - "source.fixAll.biome": "explicit" + "source.fixAll.oxc": "always" }, "[typescript]": { - "editor.defaultFormatter": "biomejs.biome" + "editor.defaultFormatter": "oxc.oxc-vscode" } } diff --git a/AGENTS.md b/AGENTS.md index 0dd765268..f88860b3f 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -6,7 +6,8 @@ bun install # Install dependencies bun dev # Start dev server (all packages) bun run build # Build all packages -bun run format # Format with Biome (run after every change) +bun run lint # Lint with Oxlint +bun run format # Format with Oxfmt (run after every change) bun run typecheck # Type-check all packages bun run unit # Run unit tests ``` @@ -74,7 +75,7 @@ Save as `.changeset/.md`, then commit it separately with message: `changes ## Formatting -Uses Biome (not ESLint/Prettier). Always run `bun run format` before committing. +Linting uses Oxlint and formatting uses Oxfmt. Always run `bun run format` before committing. ## Comments diff --git a/biome.json b/biome.json deleted file mode 100644 index fc877aa01..000000000 --- a/biome.json +++ /dev/null @@ -1,178 +0,0 @@ -{ - "$schema": "https://biomejs.dev/schemas/1.9.4/schema.json", - "vcs": { - "enabled": false, - "clientKind": "git", - "useIgnoreFile": false - }, - "files": { - "ignoreUnknown": false, - "ignore": [ - "**/node_modules/**/*", - "**/dist/**/*", - "**/build/**/*", - "**/public/**/*", - "**/.next/**/*", - "**/.open-next/**/*", - "**/.turbo/**/*", - "**/.vercel/**/*", - "**/.cache/**/*", - "**/.wrangler/**/*", - "packages/embed/standalone/**/*", - "packages/openapi-parser/src/fixtures/**/*", - "packages/emoji-codepoints/index.ts", - "packages/icons/src/data/*.json", - "packages/gitbook/worker-configuration.d.ts", - "gitbook/tsconfig.json", - "**/*.css" - ] - }, - "formatter": { - "enabled": true, - "useEditorconfig": true, - "formatWithErrors": false, - "indentStyle": "space", - "indentWidth": 4, - "lineEnding": "lf", - "lineWidth": 100, - "attributePosition": "auto", - "bracketSpacing": true - }, - "organizeImports": { - "enabled": true - }, - "linter": { - "enabled": true, - "rules": { - "recommended": true, - "performance": { - "noDelete": "warn" - }, - "security": { - "noDangerouslySetInnerHtml": "off" - }, - "complexity": { - "noForEach": "off", - "noUselessFragments": "warn", - "noBannedTypes": "warn" - }, - "correctness": { - "noUndeclaredVariables": "error", - "noUnusedVariables": "error", - "useArrayLiterals": "error", - "useHookAtTopLevel": "error", - "noUnusedImports": "error", - "noVoidElementsWithChildren": "warn", - "useJsxKeyInIterable": "warn", - "useExhaustiveDependencies": "warn", - "noUnknownFunction": "warn" - }, - "style": { - "noNonNullAssertion": "warn", - "noParameterAssign": "off", - "useThrowOnlyError": "error" - }, - "suspicious": { - "noConsole": { - "level": "warn", - "options": { - "allow": ["assert", "error", "warn"] - } - }, - "noExplicitAny": "warn", - "noImplicitAnyLet": "warn", - "noConfusingVoidType": "warn", - "noControlCharactersInRegex": "warn", - "noPrototypeBuiltins": "warn", - "noAssignInExpressions": "warn", - "noArrayIndexKey": "warn" - }, - "a11y": { - "useSemanticElements": "warn", - "useKeyWithClickEvents": "warn", - "noSvgWithoutTitle": "warn", - "useButtonType": "warn", - "useIframeTitle": "warn", - "useAltText": "warn", - "noPositiveTabindex": "warn", - "useFocusableInteractive": "warn", - "useAriaPropsForRole": "warn", - "useValidAnchor": "warn", - "noLabelWithoutControl": "warn", - "noNoninteractiveTabindex": "warn" - }, - "nursery": { - "useSortedClasses": { - "level": "error", - "fix": "safe", - "options": { - "attributes": ["class", "className", "style"], - "functions": ["clsx", "tw"] - } - } - } - } - }, - "javascript": { - "formatter": { - "jsxQuoteStyle": "double", - "quoteProperties": "asNeeded", - "trailingCommas": "es5", - "semicolons": "always", - "arrowParentheses": "always", - "bracketSameLine": false, - "quoteStyle": "single", - "attributePosition": "auto", - "bracketSpacing": true - } - }, - "overrides": [ - { - "include": [ - "packages/gitbook/**/*", - "packages/react-openapi/**/*", - "packages/react-math/**/*", - "packages/react-contentkit/**/*", - "packages/icons/**/*" - ], - "javascript": { - "globals": ["React"] - } - }, - { - "include": ["packages/gitbook/**/*"], - "javascript": { - "globals": ["React", "GitBookIntegrationEvent"] - } - }, - { - "include": ["*.css"], - "javascript": { - "globals": ["theme"] - } - }, - { - "include": ["*.test.ts", "packages/gitbook/tests/**/*"], - "javascript": { - "globals": ["Bun"] - } - }, - { - "include": [ - "packages/cache-do/**/*", - "packages/gitbook/cf-env.d.ts", - "packages/gitbook/src/cloudflare-entrypoint.ts" - ], - "javascript": { - "globals": [ - "DurableObjectLocationHint", - "DurableObjectNamespace", - "DurableObjectStub", - "ContinentCode", - "Fetcher", - "ExportedHandler" - ] - } - } - ] -} diff --git a/bun.lock b/bun.lock index ca5f7f67f..e6a344803 100644 --- a/bun.lock +++ b/bun.lock @@ -5,8 +5,9 @@ "": { "name": "gitbook", "devDependencies": { - "@biomejs/biome": "^1.9.4", "@changesets/cli": "^2.31.0", + "oxfmt": "^0.62.0", + "oxlint": "^1.77.0", "turbo": "^2.10.3", "vercel": "50.37.3", }, @@ -111,6 +112,7 @@ "name": "gitbook", "version": "0.27.2", "dependencies": { + "@base-ui/react": "catalog:", "@cloudflare/workers-types": "^4.20251011.0", "@gitbook/api": "catalog:", "@gitbook/browser-types": "workspace:*", @@ -130,13 +132,6 @@ "@opennextjs/aws": "4.1.0", "@opennextjs/cloudflare": "1.20.2", "@panzoom/panzoom": "^4.6.1", - "@radix-ui/react-checkbox": "^1.0.4", - "@radix-ui/react-collapsible": "^1.1.12", - "@radix-ui/react-dropdown-menu": "^2.1.12", - "@radix-ui/react-hover-card": "^1.1.15", - "@radix-ui/react-navigation-menu": "^1.2.3", - "@radix-ui/react-popover": "^1.0.7", - "@radix-ui/react-tooltip": "^1.1.8", "@sindresorhus/fnv1a": "^3.1.0", "@tailwindcss/container-queries": "^0.1.1", "@tusbar/cache-control": "^1.0.2", @@ -175,7 +170,6 @@ "p-retry": "^8.0.0", "quick-lru": "^7.0.1", "react": "19.2.4", - "react-aria": "^3.44.0", "react-dom": "19.2.4", "react-hotkeys-hook": "^4.4.1", "rehype-raw": "^7.0.0", @@ -316,7 +310,7 @@ "name": "@gitbook/react-openapi", "version": "1.5.15", "dependencies": { - "@base-ui/react": "^1.7.0", + "@base-ui/react": "catalog:", "@gitbook/expr": "workspace:*", "@gitbook/openapi-parser": "workspace:*", "@scalar/api-client-react": "catalog:", @@ -351,7 +345,6 @@ }, "overrides": { "@codemirror/state": "6.4.1", - "@radix-ui/react-slot": "1.2.4", "@types/react": "catalog:", "@types/react-dom": "catalog:", "axios": "1.8.4", @@ -360,7 +353,8 @@ "react-dom": "catalog:", }, "catalog": { - "@gitbook/api": "0.192.0", + "@base-ui/react": "^1.7.0", + "@gitbook/api": "0.195.0", "@scalar/api-client-react": "^1.3.46", "@tsconfig/node20": "^20.1.6", "@tsconfig/strictest": "^2.0.6", @@ -538,24 +532,6 @@ "@base-ui/utils": ["@base-ui/utils@0.3.2", "", { "dependencies": { "@babel/runtime": "^7.29.2", "@floating-ui/utils": "^0.2.12", "reselect": "^5.2.0", "use-sync-external-store": "^1.6.0" }, "peerDependencies": { "@types/react": "^17 || ^18 || ^19", "react": "^17 || ^18 || ^19", "react-dom": "^17 || ^18 || ^19" }, "optionalPeers": ["@types/react"] }, "sha512-oWy1aq/I2GmYjpl4PhEAhzflF8VPGKgZeq0xAWTbfD5KBWyxcN0ZP2+WHSUm/5Z6lVMBDLReLcoXwSYoRc/zNQ=="], - "@biomejs/biome": ["@biomejs/biome@1.9.4", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "1.9.4", "@biomejs/cli-darwin-x64": "1.9.4", "@biomejs/cli-linux-arm64": "1.9.4", "@biomejs/cli-linux-arm64-musl": "1.9.4", "@biomejs/cli-linux-x64": "1.9.4", "@biomejs/cli-linux-x64-musl": "1.9.4", "@biomejs/cli-win32-arm64": "1.9.4", "@biomejs/cli-win32-x64": "1.9.4" }, "bin": { "biome": "bin/biome" } }, "sha512-1rkd7G70+o9KkTn5KLmDYXihGoTaIGO9PIIN2ZB7UJxFrWw04CZHPYiMRjYsaDvVV7hP1dYNRLxSANLaBFGpog=="], - - "@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@1.9.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-bFBsPWrNvkdKrNCYeAp+xo2HecOGPAy9WyNyB/jKnnedgzl4W4Hb9ZMzYNbf8dMCGmUdSavlYHiR01QaYR58cw=="], - - "@biomejs/cli-darwin-x64": ["@biomejs/cli-darwin-x64@1.9.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-ngYBh/+bEedqkSevPVhLP4QfVPCpb+4BBe2p7Xs32dBgs7rh9nY2AIYUL6BgLw1JVXV8GlpKmb/hNiuIxfPfZg=="], - - "@biomejs/cli-linux-arm64": ["@biomejs/cli-linux-arm64@1.9.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-fJIW0+LYujdjUgJJuwesP4EjIBl/N/TcOX3IvIHJQNsAqvV2CHIogsmA94BPG6jZATS4Hi+xv4SkBBQSt1N4/g=="], - - "@biomejs/cli-linux-arm64-musl": ["@biomejs/cli-linux-arm64-musl@1.9.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-v665Ct9WCRjGa8+kTr0CzApU0+XXtRgwmzIf1SeKSGAv+2scAlW6JR5PMFo6FzqqZ64Po79cKODKf3/AAmECqA=="], - - "@biomejs/cli-linux-x64": ["@biomejs/cli-linux-x64@1.9.4", "", { "os": "linux", "cpu": "x64" }, "sha512-lRCJv/Vi3Vlwmbd6K+oQ0KhLHMAysN8lXoCI7XeHlxaajk06u7G+UsFSO01NAs5iYuWKmVZjmiOzJ0OJmGsMwg=="], - - "@biomejs/cli-linux-x64-musl": ["@biomejs/cli-linux-x64-musl@1.9.4", "", { "os": "linux", "cpu": "x64" }, "sha512-gEhi/jSBhZ2m6wjV530Yy8+fNqG8PAinM3oV7CyO+6c3CEh16Eizm21uHVsyVBEB6RIM8JHIl6AGYCv6Q6Q9Tg=="], - - "@biomejs/cli-win32-arm64": ["@biomejs/cli-win32-arm64@1.9.4", "", { "os": "win32", "cpu": "arm64" }, "sha512-tlbhLk+WXZmgwoIKwHIHEBZUwxml7bRJgk0X2sPyNR3S93cdRq6XulAZRQJ17FYGGzWne0fgrXBKpl7l4M87Hg=="], - - "@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@1.9.4", "", { "os": "win32", "cpu": "x64" }, "sha512-8Y5wMhVIPaWe6jw2H+KlEm4wP/f7EW3810ZLmDlrEEy5KvBsb9ECEfu/kMWD484ijfQ8+nIi0giMgu9g1UAuuA=="], - "@braintree/sanitize-url": ["@braintree/sanitize-url@7.1.2", "", {}, "sha512-jigsZK+sMF/cuiB7sERuo9V7N9jx+dhmHHnQyDSVdpZwVutaBu7WvNYqMDLSgFgfB30n452TP3vjDAvFC973mA=="], "@bytecodealliance/preview2-shim": ["@bytecodealliance/preview2-shim@0.17.6", "", {}, "sha512-n3cM88gTen5980UOBAD6xDcNNL3ocTK8keab21bpx1ONdA+ARj7uD1qoFxOWCyKlkpSi195FH+GeAut7Oc6zZw=="], @@ -746,21 +722,11 @@ "@floating-ui/vue": ["@floating-ui/vue@1.1.9", "", { "dependencies": { "@floating-ui/dom": "^1.7.4", "@floating-ui/utils": "^0.2.10", "vue-demi": ">=0.13.0" } }, "sha512-BfNqNW6KA83Nexspgb9DZuz578R7HT8MZw1CfK9I6Ah4QReNWEJsXWHN+SdmOVLNGmTPDi+fDT535Df5PzMLbQ=="], - "@formatjs/ecma402-abstract": ["@formatjs/ecma402-abstract@2.3.2", "", { "dependencies": { "@formatjs/fast-memoize": "2.2.6", "@formatjs/intl-localematcher": "0.5.10", "decimal.js": "10", "tslib": "2" } }, "sha512-6sE5nyvDloULiyOMbOTJEEgWL32w+VHkZQs8S02Lnn8Y/O5aQhjOEXwWzvR7SsBE/exxlSpY2EsWZgqHbtLatg=="], - - "@formatjs/fast-memoize": ["@formatjs/fast-memoize@2.2.6", "", { "dependencies": { "tslib": "2" } }, "sha512-luIXeE2LJbQnnzotY1f2U2m7xuQNj2DA8Vq4ce1BY9ebRZaoPB1+8eZ6nXpLzsxuW5spQxr7LdCg+CApZwkqkw=="], - - "@formatjs/icu-messageformat-parser": ["@formatjs/icu-messageformat-parser@2.11.0", "", { "dependencies": { "@formatjs/ecma402-abstract": "2.3.2", "@formatjs/icu-skeleton-parser": "1.8.12", "tslib": "2" } }, "sha512-Hp81uTjjdTk3FLh/dggU5NK7EIsVWc5/ZDWrIldmf2rBuPejuZ13CZ/wpVE2SToyi4EiroPTQ1XJcJuZFIxTtw=="], - - "@formatjs/icu-skeleton-parser": ["@formatjs/icu-skeleton-parser@1.8.12", "", { "dependencies": { "@formatjs/ecma402-abstract": "2.3.2", "tslib": "2" } }, "sha512-QRAY2jC1BomFQHYDMcZtClqHR55EEnB96V7Xbk/UiBodsuFc5kujybzt87+qj1KqmJozFhk6n4KiT1HKwAkcfg=="], - - "@formatjs/intl-localematcher": ["@formatjs/intl-localematcher@0.5.10", "", { "dependencies": { "tslib": "2" } }, "sha512-af3qATX+m4Rnd9+wHcjJ4w2ijq+rAVP3CCinJQvFv1kgSu1W6jypUmvleJxcewdxmutM8dmIRZFxO/IQBZmP2Q=="], - "@fortawesome/fontawesome-common-types": ["@fortawesome/fontawesome-common-types@7.2.0", "", {}, "sha512-IpR0bER9FY25p+e7BmFH25MZKEwFHTfRAfhOyJubgiDnoJNsSvJ7nigLraHtp4VOG/cy8D7uiV0dLkHOne5Fhw=="], "@fortawesome/fontawesome-svg-core": ["@fortawesome/fontawesome-svg-core@7.2.0", "", { "dependencies": { "@fortawesome/fontawesome-common-types": "7.2.0" } }, "sha512-6639htZMjEkwskf3J+e6/iar+4cTNM9qhoWuRfj9F3eJD6r7iCzV1SWnQr2Mdv0QT0suuqU8BoJCZUyCtP9R4Q=="], - "@gitbook/api": ["@gitbook/api@0.192.0", "", { "dependencies": { "event-iterator": "^2.0.0", "eventsource-parser": "^3.0.0" } }, "sha512-S9ceF3XspgSqXb7JH5feSHSytVkq1jRDwOKeEK4nnZs9pSiKFxHZMj/LnHi8k8anaue/FeLwWYo+Vk08Pdl0+g=="], + "@gitbook/api": ["@gitbook/api@0.195.0", "", { "dependencies": { "event-iterator": "^2.0.0", "eventsource-parser": "^3.0.0" } }, "sha512-66OGIiiKUfHB7dF8fb9Ai8PkhQldD4SSQXHZ+X+SSEki2WXpgn6ze+PEXRQvDsJj2JKEvD9A7FfaGzUYiYn9hA=="], "@gitbook/browser-types": ["@gitbook/browser-types@workspace:packages/browser-types"], @@ -866,13 +832,9 @@ "@inquirer/external-editor": ["@inquirer/external-editor@1.0.2", "", { "dependencies": { "chardet": "^2.1.0", "iconv-lite": "^0.7.0" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-yy9cOoBnx58TlsPrIxauKIFQTiyH+0MK4e97y4sV9ERbI+zDxw7i2hxHLCIEGIE/8PPvDxGhgzIOTSOWcs6/MQ=="], - "@internationalized/date": ["@internationalized/date@3.10.0", "", { "dependencies": { "@swc/helpers": "^0.5.0" } }, "sha512-oxDR/NTEJ1k+UFVQElaNIk65E/Z83HK1z1WI3lQyhTtnNg4R5oVXaPzK3jcpKG8UHKDVuDQHzn+wsxSz8RP3aw=="], + "@internationalized/date": ["@internationalized/date@3.5.6", "", { "dependencies": { "@swc/helpers": "^0.5.0" } }, "sha512-jLxQjefH9VI5P9UQuqB6qNKnvFt1Ky1TPIzHGsIlCi7sZZoMR8SdYbBGRvM0y+Jtb+ez4ieBzmiAUcpmPYpyOw=="], - "@internationalized/message": ["@internationalized/message@3.1.8", "", { "dependencies": { "@swc/helpers": "^0.5.0", "intl-messageformat": "^10.1.0" } }, "sha512-Rwk3j/TlYZhn3HQ6PyXUV0XP9Uv42jqZGNegt0BXlxjE6G3+LwHjbQZAGHhCnCPdaA6Tvd3ma/7QzLlLkJxAWA=="], - - "@internationalized/number": ["@internationalized/number@3.6.5", "", { "dependencies": { "@swc/helpers": "^0.5.0" } }, "sha512-6hY4Kl4HPBvtfS62asS/R22JzNNy8vi/Ssev7x6EobfCp+9QIB2hKvI2EtbdJ0VSQacxVNtqhE/NmF/NZ0gm6g=="], - - "@internationalized/string": ["@internationalized/string@3.2.7", "", { "dependencies": { "@swc/helpers": "^0.5.0" } }, "sha512-D4OHBjrinH+PFZPvfCXvG28n2LSykWcJ7GIioQL+ok0LON15SdfoUssoHzzOUmVZLbRoREsQXVzA6r8JKsbP6A=="], + "@internationalized/number": ["@internationalized/number@3.5.4", "", { "dependencies": { "@swc/helpers": "^0.5.0" } }, "sha512-h9huwWjNqYyE2FXZZewWqmCdkw1HeFds5q4Siuoms3hUQC5iPJK3aBmkFZoDSLN4UD0Bl8G22L/NdHpeOr+/7A=="], "@isaacs/balanced-match": ["@isaacs/balanced-match@4.0.1", "", {}, "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ=="], @@ -1028,6 +990,82 @@ "@oxc-transform/binding-win32-x64-msvc": ["@oxc-transform/binding-win32-x64-msvc@0.111.0", "", { "os": "win32", "cpu": "x64" }, "sha512-QddKW4kBH0Wof6Y65eYCNHM4iOGmCTWLLcNYY1FGswhzmTYOUVXajNROR+iCXAOFnOF0ldtsR79SyqgyHH1Bgg=="], + "@oxfmt/binding-android-arm-eabi": ["@oxfmt/binding-android-arm-eabi@0.62.0", "", { "os": "android", "cpu": "arm" }, "sha512-pdsv0C4gPjJ8H1+sd8u0BDx+yLACTL+rgeMIOL1ln4ihSnhw8CWXtYWgvcSkyTfgGBIzFKab+d8rx9Xl4en/Kw=="], + + "@oxfmt/binding-android-arm64": ["@oxfmt/binding-android-arm64@0.62.0", "", { "os": "android", "cpu": "arm64" }, "sha512-WC3YQ7uS/KtDrjmqwBviwFKe9qeoi+eXx8aX1z/ffG23Md75myjrJaQqTuJvdOLPoa4EYTjDWH0dHXfwulCVog=="], + + "@oxfmt/binding-darwin-arm64": ["@oxfmt/binding-darwin-arm64@0.62.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-GM8Yf3LjjaR1I8PD0SfeoIlwhsh9GvSF+cQ8sf624Yxnjsyumn95aFzYfKJVefblfDIiOAnZ7QVm2sa21Er/0Q=="], + + "@oxfmt/binding-darwin-x64": ["@oxfmt/binding-darwin-x64@0.62.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-d5THp7F8bCxLqNogEXDORRsQD6dosf3EyFtnXfBer6v+8tGdcWIjoDX9WaXrrF/26zOmL8qHpPTKCEvpBDmZkQ=="], + + "@oxfmt/binding-freebsd-x64": ["@oxfmt/binding-freebsd-x64@0.62.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-1DnrtXGZooOZ0fHgAXZUaDQzBVh1CM2MNW4oBXyQ2aWKvCHjyljvT9fgBkOM0fEOb96X5eqtcfJ0YUVt9jj66g=="], + + "@oxfmt/binding-linux-arm-gnueabihf": ["@oxfmt/binding-linux-arm-gnueabihf@0.62.0", "", { "os": "linux", "cpu": "arm" }, "sha512-4pQDHOYRH+Huqe0StIaWyvk2CVl/aTaqSrbZpA3/pLS2xH24ME7lBgYprhQF2fRkHBzhGGGKliwxFsDdHwx59g=="], + + "@oxfmt/binding-linux-arm-musleabihf": ["@oxfmt/binding-linux-arm-musleabihf@0.62.0", "", { "os": "linux", "cpu": "arm" }, "sha512-X0jAaZJFMCVKhB6YyWVTQ/wN2DLsBcZKSMqTS76bF6riT+XZdtg2FPEdjDvdVbunO9cG+tWiVaEs4Zs38lxYog=="], + + "@oxfmt/binding-linux-arm64-gnu": ["@oxfmt/binding-linux-arm64-gnu@0.62.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-682Z8T5s8T5ATArYtsejKvbIfd8LEAXyyDkKkoZVq8HND7Vx8TYLlrDjDSeYfodMeVwHOgkj13lJYR8cj6vUSg=="], + + "@oxfmt/binding-linux-arm64-musl": ["@oxfmt/binding-linux-arm64-musl@0.62.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-lk25fAl7KWaLWVJcW0CHEXB7QlQZtx5eDkjpaGMK0hzXTjUe0Wmlu8IKuFHoviSOcEJedRTs4VE/506VqGxGew=="], + + "@oxfmt/binding-linux-ppc64-gnu": ["@oxfmt/binding-linux-ppc64-gnu@0.62.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-SFyNqHQLwySceWNLhiSldx7wPXRAzP0L0WcW9GegP3uWrpZGJiZlQO85NbHAFPEfxR9PhZ9qSnZryEh7+v+4Gw=="], + + "@oxfmt/binding-linux-riscv64-gnu": ["@oxfmt/binding-linux-riscv64-gnu@0.62.0", "", { "os": "linux", "cpu": "none" }, "sha512-KYj55C1ywJfHo6+aKDuEmUtVEdJALsC5GwayDGsI6FGz2GxFqNr/mA8nxVsNbJzm7sE5MRqTQ9ziImSzhYXysA=="], + + "@oxfmt/binding-linux-riscv64-musl": ["@oxfmt/binding-linux-riscv64-musl@0.62.0", "", { "os": "linux", "cpu": "none" }, "sha512-BhZDNo5GOU5nC378RhD0/XpvaEBHsH3HLgJp8YZX3A0InC7oivzA63HsRmiXFLtLSHAstEVrDf6fbC7Rs8Jh/A=="], + + "@oxfmt/binding-linux-s390x-gnu": ["@oxfmt/binding-linux-s390x-gnu@0.62.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-UyAFmyHkgSgUJ/wOM4p3U8AC2yAFvRH5PNBs7TnK0fObTT/XSWcdr/lAzPSWaekHaZFaMeFZyk9n93Joq3J93A=="], + + "@oxfmt/binding-linux-x64-gnu": ["@oxfmt/binding-linux-x64-gnu@0.62.0", "", { "os": "linux", "cpu": "x64" }, "sha512-1iYMP0leytWazFubD/WnINJuIrzRPuoL1aWEJdlGezEzDbTxcd29R4r8IUzP2oWeKst5V02uMJgR2NILlPlG6w=="], + + "@oxfmt/binding-linux-x64-musl": ["@oxfmt/binding-linux-x64-musl@0.62.0", "", { "os": "linux", "cpu": "x64" }, "sha512-4rA/URtJSTVNVAQz6Q8wf7SaRvOXVy+TizriT9hs/Y1XhLR/R+92uWKRQG8yFWRAIEBbFHJ6WevQcl/G9SXEfw=="], + + "@oxfmt/binding-openharmony-arm64": ["@oxfmt/binding-openharmony-arm64@0.62.0", "", { "os": "none", "cpu": "arm64" }, "sha512-mSZuFHU2ar1KLUjXpI2QBQcJ1VsOB3mOCgQXuXCpKs19dgh4u+OaovNfrWDfiJb+ihJ2+f7YFcaO9bS2dlTCXA=="], + + "@oxfmt/binding-win32-arm64-msvc": ["@oxfmt/binding-win32-arm64-msvc@0.62.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-OfwuhkcjDlqC4EgDojtiV9mzpLqeB9KqTOWPOjLEYBVdDCVSxqW3qzp/xcIxsbtI0UgGCnKvAqYKyY25kf5JZw=="], + + "@oxfmt/binding-win32-ia32-msvc": ["@oxfmt/binding-win32-ia32-msvc@0.62.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-P9uDDNFRzghO3X8QAzhkjKhK7JvtABsVn8UYtFX7uor12IAnwNt8nNIctvfWj1JkQU/kE+fmLRPiw7XlrIHsZw=="], + + "@oxfmt/binding-win32-x64-msvc": ["@oxfmt/binding-win32-x64-msvc@0.62.0", "", { "os": "win32", "cpu": "x64" }, "sha512-dlI5SY7XYQCiCBafntWagCR6HcAJB/NpsLtdlPx8x08+Osz8Ok1HHz1GZuusegCe/VoJ6pAnF5a4pd5OZAq7qQ=="], + + "@oxlint/binding-android-arm-eabi": ["@oxlint/binding-android-arm-eabi@1.78.0", "", { "os": "android", "cpu": "arm" }, "sha512-Bu819lmAfZMUHErrpe0cEWj3iaefuUODHSU8+UbXy67V/r7/7f4K3FL0NmbD85E+wiFLDYuhP8Zlv0XnVeXshw=="], + + "@oxlint/binding-android-arm64": ["@oxlint/binding-android-arm64@1.78.0", "", { "os": "android", "cpu": "arm64" }, "sha512-CDfxZgB61B7buRdY2FJoAYYPPXCZ1EoC1LKscnC5dg3kjobdxiconvAvvN1BmHyW4PyFT3jRLDag/BY/roSNBQ=="], + + "@oxlint/binding-darwin-arm64": ["@oxlint/binding-darwin-arm64@1.78.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-2Y2U9Ahrz+OO0Ej88f9SJYq51/jUBp1Mc7iZu0ukrbeeZ3gpRGfzIFnoqfHDY96xr0GEfNrPUBFEy0nN5aD7HA=="], + + "@oxlint/binding-darwin-x64": ["@oxlint/binding-darwin-x64@1.78.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-rpych6eJq6m9jDRypTEaPD1xysaEW5h9+xuxhGK/QhOg+/xaqPZrCrTNoIl/f3nEjuJeCEmstNDlrE9rJi/3/g=="], + + "@oxlint/binding-freebsd-x64": ["@oxlint/binding-freebsd-x64@1.78.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-IcMGrQT3QizkOESUJd5et+rOhVqSkNDfNik1cvrKDqIbzqx9KMtRswpFgkCuNTSwylCFLKhGUu8KmqY1ZnC0Dg=="], + + "@oxlint/binding-linux-arm-gnueabihf": ["@oxlint/binding-linux-arm-gnueabihf@1.78.0", "", { "os": "linux", "cpu": "arm" }, "sha512-/uLdoJ0IXE6vo/0f0LKjinQAp+re+VMaCWaNT8ENIv2EOCkSsc8SGaflXAuW0Jua2dq5+GLVWm1NQK7P3UFSNQ=="], + + "@oxlint/binding-linux-arm-musleabihf": ["@oxlint/binding-linux-arm-musleabihf@1.78.0", "", { "os": "linux", "cpu": "arm" }, "sha512-7xi4Wb/O8NRJhLoUXmDJMUVpNYvB5kefdhFU1Jb8rtae4QoXlTiLwI14X4YvAXVZLNZChP8m5qO9SQAlWQTbkQ=="], + + "@oxlint/binding-linux-arm64-gnu": ["@oxlint/binding-linux-arm64-gnu@1.78.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-4hFW0+fVXa3OIh1Y4A5SPkmvI4wuuBSrCVKzOyE7PTjhc7yEqZ1pmvEEeS5Lj/MaqvegFxXyF33N+6jkehxdyg=="], + + "@oxlint/binding-linux-arm64-musl": ["@oxlint/binding-linux-arm64-musl@1.78.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-oC0mvsgBJjlMijSDEhx9KuvR9zYeHXceA9MjbuXB1F8NSR78Yj2unOBrstEvTVaq+pko+kuue6DajC00eqvTdg=="], + + "@oxlint/binding-linux-ppc64-gnu": ["@oxlint/binding-linux-ppc64-gnu@1.78.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-XAllT5SUZS+ohjuZ3/5S0cwe0r7eboiuigeStCZ5DXRYx/2KVM2UvQXvAfyzXEimtQjAB7cDQ2YxDe2Zl2WNQQ=="], + + "@oxlint/binding-linux-riscv64-gnu": ["@oxlint/binding-linux-riscv64-gnu@1.78.0", "", { "os": "linux", "cpu": "none" }, "sha512-trucMER/0QtecoXvc1y/UVqE3kwJipDwrx4oHfj+nNm3dq2zjP44WT0CfHNDPM3G1DXIkx/gY6lAD21NSCZVhA=="], + + "@oxlint/binding-linux-riscv64-musl": ["@oxlint/binding-linux-riscv64-musl@1.78.0", "", { "os": "linux", "cpu": "none" }, "sha512-cm3O4F/HQbdzOUX5mKHqG5KDL6E5w0pnlZ+fbBy2rmLryPOowkuLagFHTopQsEIpjcaZoPOrL+BmmAytAG9HFg=="], + + "@oxlint/binding-linux-s390x-gnu": ["@oxlint/binding-linux-s390x-gnu@1.78.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-33wRf6HqGNsybJ3qX4cGaQN2ODPxNmc1rMa0mrTmx3eFq1VzOnvQooi9bIGVYakW8a/wmqVx1mgsUm8R2xfTiw=="], + + "@oxlint/binding-linux-x64-gnu": ["@oxlint/binding-linux-x64-gnu@1.78.0", "", { "os": "linux", "cpu": "x64" }, "sha512-rRdISSYegj6VganMZ9tjRjijowfHJ09IZU01i0toBAqr6n5LEtwHq2IeS4FjW2RoskOHlb6efB26H5izYb3GEQ=="], + + "@oxlint/binding-linux-x64-musl": ["@oxlint/binding-linux-x64-musl@1.78.0", "", { "os": "linux", "cpu": "x64" }, "sha512-GmsP4rW0xTL6u5CVdcDsaN5Fbc7hBc382Wmar1kttbnwSEviM+rSINKOMQ+UQ6iH+AGwC+8gaAiwu134Tgh6Lg=="], + + "@oxlint/binding-openharmony-arm64": ["@oxlint/binding-openharmony-arm64@1.78.0", "", { "os": "none", "cpu": "arm64" }, "sha512-sy9yeYuADc8a+n4TLBayzMCZiHPW78DcIFVpOXTmdKHWQeM9xe5uzkqIIZmi326D5hY9XVwacipEB1p7tQjPAg=="], + + "@oxlint/binding-win32-arm64-msvc": ["@oxlint/binding-win32-arm64-msvc@1.78.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-rjc2hF1KfMi8fZj1X/m3AmnHbdsF3rL0v6KQg0Uc880Yb2khjz+3U14sfdZ7jWTpRnN1m1NQa/TT7uU9lJWPrA=="], + + "@oxlint/binding-win32-ia32-msvc": ["@oxlint/binding-win32-ia32-msvc@1.78.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-zcuXFVrEFHIafRfkCQT8w/Xe41o07ozl/vwHq7p94vB29xVzsB0sZGYORU1jhcYKv3Lr0J3HbJ2T4fHH5rWmvA=="], + + "@oxlint/binding-win32-x64-msvc": ["@oxlint/binding-win32-x64-msvc@1.78.0", "", { "os": "win32", "cpu": "x64" }, "sha512-Sb5ocmLSuYeOuXd+CFOToGKp/gjXUEWDnvIGwhnh8aq8wY4TMmEnKnvbogSW7RdMZv77JSARduS7/gv+khYEjA=="], + "@panzoom/panzoom": ["@panzoom/panzoom@4.6.1", "", {}, "sha512-ogf/KhHHjj+DYAvHfaf3TXMQ8OE36pJtKpabLlx1OmpjcgtpCvkUoCiNONA8kuVRPGJdLiqMf0n8LRFXj1OyuA=="], "@phosphor-icons/core": ["@phosphor-icons/core@2.1.1", "", {}, "sha512-v4ARvrip4qBCImOE5rmPUylOEK4iiED9ZyKjcvzuezqMaiRASCHKcRIuvvxL/twvLpkfnEODCOJp5dM4eZilxQ=="], @@ -1044,272 +1082,20 @@ "@quansync/fs": ["@quansync/fs@0.1.5", "", { "dependencies": { "quansync": "^0.2.11" } }, "sha512-lNS9hL2aS2NZgNW7BBj+6EBl4rOf8l+tQ0eRY6JWCI8jI2kc53gSoqbjojU0OnAWhzoXiOjFyGsHcDGePB3lhA=="], - "@radix-ui/primitive": ["@radix-ui/primitive@1.1.0", "", {}, "sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA=="], - - "@radix-ui/react-arrow": ["@radix-ui/react-arrow@1.1.7", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.3" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w=="], - - "@radix-ui/react-checkbox": ["@radix-ui/react-checkbox@1.1.2", "", { "dependencies": { "@radix-ui/primitive": "1.1.0", "@radix-ui/react-compose-refs": "1.1.0", "@radix-ui/react-context": "1.1.1", "@radix-ui/react-presence": "1.1.1", "@radix-ui/react-primitive": "2.0.0", "@radix-ui/react-use-controllable-state": "1.1.0", "@radix-ui/react-use-previous": "1.1.0", "@radix-ui/react-use-size": "1.1.0" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-/i0fl686zaJbDQLNKrkCbMyDm6FQMt4jg323k7HuqitoANm9sE23Ql8yOK3Wusk34HSLKDChhMux05FnP6KUkw=="], - - "@radix-ui/react-collapsible": ["@radix-ui/react-collapsible@1.1.12", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-Uu+mSh4agx2ib1uIGPP4/CKNULyajb3p92LsVXmH2EHVMTfZWpll88XJ0j4W0z3f8NK1eYl1+Mf/szHPmcHzyA=="], - - "@radix-ui/react-collection": ["@radix-ui/react-collection@1.1.1", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.1", "@radix-ui/react-context": "1.1.1", "@radix-ui/react-primitive": "2.0.1", "@radix-ui/react-slot": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-LwT3pSho9Dljg+wY2KN2mrrh6y3qELfftINERIzBUO9e0N+t0oMTyn3k9iv+ZqgrwGkRnLpNJrsMv9BZlt2yuA=="], - - "@radix-ui/react-compose-refs": ["@radix-ui/react-compose-refs@1.1.0", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw=="], - - "@radix-ui/react-context": ["@radix-ui/react-context@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q=="], - - "@radix-ui/react-direction": ["@radix-ui/react-direction@1.1.0", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-BUuBvgThEiAXh2DWu93XsT+a3aWrGqolGlqqw5VU1kG7p/ZH2cuDlM1sRLNnY3QcBS69UIz2mcKhMxDsdewhjg=="], - - "@radix-ui/react-dismissable-layer": ["@radix-ui/react-dismissable-layer@1.1.11", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-escape-keydown": "1.1.1" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg=="], - - "@radix-ui/react-dropdown-menu": ["@radix-ui/react-dropdown-menu@2.1.12", "", { "dependencies": { "@radix-ui/primitive": "1.1.2", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-menu": "2.1.12", "@radix-ui/react-primitive": "2.1.0", "@radix-ui/react-use-controllable-state": "1.2.2" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-VJoMs+BWWE7YhzEQyVwvF9n22Eiyr83HotCVrMQzla/OwRovXCgah7AcaEr4hMNj4gJxSdtIbcHGvmJXOoJVHA=="], - - "@radix-ui/react-focus-guards": ["@radix-ui/react-focus-guards@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-pSIwfrT1a6sIoDASCSpFwOasEwKTZWDw/iBdtnqKO7v6FeOzYJ7U53cPzYFVR3geGGXgVHaH+CdngrrAzqUGxg=="], - - "@radix-ui/react-focus-scope": ["@radix-ui/react-focus-scope@1.1.0", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.0", "@radix-ui/react-primitive": "2.0.0", "@radix-ui/react-use-callback-ref": "1.1.0" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-200UD8zylvEyL8Bx+z76RJnASR2gRMuxlgFCPAe/Q/679a/r0eK3MBVYMb7vZODZcffZBdob1EGnky78xmVvcA=="], - - "@radix-ui/react-hover-card": ["@radix-ui/react-hover-card@1.1.15", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-popper": "1.2.8", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-controllable-state": "1.2.2" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-qgTkjNT1CfKMoP0rcasmlH2r1DAiYicWsDsufxl940sT2wHNEWWv6FMWIQXWhVdmC1d/HYfbhQx60KYyAtKxjg=="], - - "@radix-ui/react-id": ["@radix-ui/react-id@1.1.1", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg=="], - - "@radix-ui/react-menu": ["@radix-ui/react-menu@2.1.12", "", { "dependencies": { "@radix-ui/primitive": "1.1.2", "@radix-ui/react-collection": "1.1.4", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-dismissable-layer": "1.1.7", "@radix-ui/react-focus-guards": "1.1.2", "@radix-ui/react-focus-scope": "1.1.4", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-popper": "1.2.4", "@radix-ui/react-portal": "1.1.6", "@radix-ui/react-presence": "1.1.4", "@radix-ui/react-primitive": "2.1.0", "@radix-ui/react-roving-focus": "1.1.7", "@radix-ui/react-slot": "1.2.0", "@radix-ui/react-use-callback-ref": "1.1.1", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.6.3" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-+qYq6LfbiGo97Zz9fioX83HCiIYYFNs8zAsVCMQrIakoNYylIzWuoD/anAD3UzvvR6cnswmfRFJFq/zYYq/k7Q=="], - - "@radix-ui/react-navigation-menu": ["@radix-ui/react-navigation-menu@1.2.4", "", { "dependencies": { "@radix-ui/primitive": "1.1.1", "@radix-ui/react-collection": "1.1.1", "@radix-ui/react-compose-refs": "1.1.1", "@radix-ui/react-context": "1.1.1", "@radix-ui/react-direction": "1.1.0", "@radix-ui/react-dismissable-layer": "1.1.4", "@radix-ui/react-id": "1.1.0", "@radix-ui/react-presence": "1.1.2", "@radix-ui/react-primitive": "2.0.1", "@radix-ui/react-use-callback-ref": "1.1.0", "@radix-ui/react-use-controllable-state": "1.1.0", "@radix-ui/react-use-layout-effect": "1.1.0", "@radix-ui/react-use-previous": "1.1.0", "@radix-ui/react-visually-hidden": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-wUi01RrTDTOoGtjEPHsxlzPtVzVc3R/AZ5wfh0dyqMAqolhHAHvG5iQjBCTi2AjQqa77FWWbA3kE3RkD+bDMgQ=="], - - "@radix-ui/react-popover": ["@radix-ui/react-popover@1.1.2", "", { "dependencies": { "@radix-ui/primitive": "1.1.0", "@radix-ui/react-compose-refs": "1.1.0", "@radix-ui/react-context": "1.1.1", "@radix-ui/react-dismissable-layer": "1.1.1", "@radix-ui/react-focus-guards": "1.1.1", "@radix-ui/react-focus-scope": "1.1.0", "@radix-ui/react-id": "1.1.0", "@radix-ui/react-popper": "1.2.0", "@radix-ui/react-portal": "1.1.2", "@radix-ui/react-presence": "1.1.1", "@radix-ui/react-primitive": "2.0.0", "@radix-ui/react-slot": "1.1.0", "@radix-ui/react-use-controllable-state": "1.1.0", "aria-hidden": "^1.1.1", "react-remove-scroll": "2.6.0" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-u2HRUyWW+lOiA2g0Le0tMmT55FGOEWHwPFt1EPfbLly7uXQExFo5duNKqG2DzmFXIdqOeNd+TpE8baHWJCyP9w=="], - - "@radix-ui/react-popper": ["@radix-ui/react-popper@1.2.8", "", { "dependencies": { "@floating-ui/react-dom": "^2.0.0", "@radix-ui/react-arrow": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-layout-effect": "1.1.1", "@radix-ui/react-use-rect": "1.1.1", "@radix-ui/react-use-size": "1.1.1", "@radix-ui/rect": "1.1.1" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-0NJQ4LFFUuWkE7Oxf0htBKS6zLkkjBH+hM1uk7Ng705ReR8m/uelduy1DBo0PyBXPKVnBA6YBlU94MBGXrSBCw=="], - - "@radix-ui/react-portal": ["@radix-ui/react-portal@1.1.9", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ=="], - - "@radix-ui/react-presence": ["@radix-ui/react-presence@1.1.1", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.0", "@radix-ui/react-use-layout-effect": "1.1.0" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-IeFXVi4YS1K0wVZzXNrbaaUvIJ3qdY+/Ih4eHFhWA9SwGR9UDX7Ck8abvL57C4cv3wwMvUE0OG69Qc3NCcTe/A=="], - - "@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.0.0", "", { "dependencies": { "@radix-ui/react-slot": "1.1.0" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-ZSpFm0/uHa8zTvKBDjLFWLo8dkr4MBsiDLz0g3gMUwqgLHz9rTaRRGYDgvZPtBJgYCBKXkS9fzmoySgr8CO6Cw=="], - - "@radix-ui/react-roving-focus": ["@radix-ui/react-roving-focus@1.1.7", "", { "dependencies": { "@radix-ui/primitive": "1.1.2", "@radix-ui/react-collection": "1.1.4", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-primitive": "2.1.0", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-controllable-state": "1.2.2" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-C6oAg451/fQT3EGbWHbCQjYTtbyjNO1uzQgMzwyivcHT3GKNEmu1q3UuREhN+HzHAVtv3ivMVK08QlC+PkYw9Q=="], - - "@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.4", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-Jl+bCv8HxKnlTLVrcDE8zTMJ09R9/ukw4qBs/oZClOfoQk/cOTbDn+NceXfV7j09YPVQUryJPHurafcSg6EVKA=="], - - "@radix-ui/react-tooltip": ["@radix-ui/react-tooltip@1.1.8", "", { "dependencies": { "@radix-ui/primitive": "1.1.1", "@radix-ui/react-compose-refs": "1.1.1", "@radix-ui/react-context": "1.1.1", "@radix-ui/react-dismissable-layer": "1.1.5", "@radix-ui/react-id": "1.1.0", "@radix-ui/react-popper": "1.2.2", "@radix-ui/react-portal": "1.1.4", "@radix-ui/react-presence": "1.1.2", "@radix-ui/react-primitive": "2.0.2", "@radix-ui/react-slot": "1.1.2", "@radix-ui/react-use-controllable-state": "1.1.0", "@radix-ui/react-visually-hidden": "1.1.2" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-YAA2cu48EkJZdAMHC0dqo9kialOcRStbtiY4nJPaht7Ptrhcvpo+eDChaM6BIs8kL6a8Z5l5poiqLnXcNduOkA=="], - - "@radix-ui/react-use-callback-ref": ["@radix-ui/react-use-callback-ref@1.1.0", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw=="], - - "@radix-ui/react-use-controllable-state": ["@radix-ui/react-use-controllable-state@1.1.0", "", { "dependencies": { "@radix-ui/react-use-callback-ref": "1.1.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw=="], - - "@radix-ui/react-use-effect-event": ["@radix-ui/react-use-effect-event@0.0.2", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA=="], - - "@radix-ui/react-use-escape-keydown": ["@radix-ui/react-use-escape-keydown@1.1.1", "", { "dependencies": { "@radix-ui/react-use-callback-ref": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g=="], - - "@radix-ui/react-use-layout-effect": ["@radix-ui/react-use-layout-effect@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ=="], - - "@radix-ui/react-use-previous": ["@radix-ui/react-use-previous@1.1.0", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-Z/e78qg2YFnnXcW88A4JmTtm4ADckLno6F7OXotmkQfeuCVaKuYzqAATPhVzl3delXE7CxIV8shofPn3jPc5Og=="], - - "@radix-ui/react-use-rect": ["@radix-ui/react-use-rect@1.1.1", "", { "dependencies": { "@radix-ui/rect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w=="], - - "@radix-ui/react-use-size": ["@radix-ui/react-use-size@1.1.0", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-XW3/vWuIXHa+2Uwcc2ABSfcCledmXhhQPlGbfcRXbiUQI5Icjcg19BGCZVKKInYbvUCut/ufbbLLPFC5cbb1hw=="], - - "@radix-ui/react-visually-hidden": ["@radix-ui/react-visually-hidden@1.1.1", "", { "dependencies": { "@radix-ui/react-primitive": "2.0.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-vVfA2IZ9q/J+gEamvj761Oq1FpWgCDaNOOIfbPVp2MVPLEomUr5+Vf7kJGwQ24YxZSlQVar7Bes8kyTo5Dshpg=="], - - "@radix-ui/rect": ["@radix-ui/rect@1.1.1", "", {}, "sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw=="], - - "@react-aria/breadcrumbs": ["@react-aria/breadcrumbs@3.5.29", "", { "dependencies": { "@react-aria/i18n": "^3.12.13", "@react-aria/link": "^3.8.6", "@react-aria/utils": "^3.31.0", "@react-types/breadcrumbs": "^3.7.17", "@react-types/shared": "^3.32.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-rKS0dryllaZJqrr3f/EAf2liz8CBEfmL5XACj+Z1TAig6GIYe1QuA3BtkX0cV9OkMugXdX8e3cbA7nD10ORRqg=="], - - "@react-aria/button": ["@react-aria/button@3.14.2", "", { "dependencies": { "@react-aria/interactions": "^3.25.6", "@react-aria/toolbar": "3.0.0-beta.21", "@react-aria/utils": "^3.31.0", "@react-stately/toggle": "^3.9.2", "@react-types/button": "^3.14.1", "@react-types/shared": "^3.32.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-VbLIA+Kd6f/MDjd+TJBUg2+vNDw66pnvsj2E4RLomjI9dfBuN7d+Yo2UnsqKVyhePjCUZ6xxa2yDuD63IOSIYA=="], - - "@react-aria/calendar": ["@react-aria/calendar@3.9.2", "", { "dependencies": { "@internationalized/date": "^3.10.0", "@react-aria/i18n": "^3.12.13", "@react-aria/interactions": "^3.25.6", "@react-aria/live-announcer": "^3.4.4", "@react-aria/utils": "^3.31.0", "@react-stately/calendar": "^3.9.0", "@react-types/button": "^3.14.1", "@react-types/calendar": "^3.8.0", "@react-types/shared": "^3.32.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-uSLxLgOPRnEU4Jg59lAhUVA+uDx/55NBg4lpfsP2ynazyiJ5LCXmYceJi+VuOqMml7d9W0dB87OldOeLdIxYVA=="], - - "@react-aria/checkbox": ["@react-aria/checkbox@3.16.2", "", { "dependencies": { "@react-aria/form": "^3.1.2", "@react-aria/interactions": "^3.25.6", "@react-aria/label": "^3.7.22", "@react-aria/toggle": "^3.12.2", "@react-aria/utils": "^3.31.0", "@react-stately/checkbox": "^3.7.2", "@react-stately/form": "^3.2.2", "@react-stately/toggle": "^3.9.2", "@react-types/checkbox": "^3.10.2", "@react-types/shared": "^3.32.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-29Mj9ZqXioJ0bcMnNGooHztnTau5pikZqX3qCRj5bYR3by/ZFFavYoMroh9F7s/MbFm/tsKX+Sf02lYFEdXRjA=="], - - "@react-aria/color": ["@react-aria/color@3.1.2", "", { "dependencies": { "@react-aria/i18n": "^3.12.13", "@react-aria/interactions": "^3.25.6", "@react-aria/numberfield": "^3.12.2", "@react-aria/slider": "^3.8.2", "@react-aria/spinbutton": "^3.6.19", "@react-aria/textfield": "^3.18.2", "@react-aria/utils": "^3.31.0", "@react-aria/visually-hidden": "^3.8.28", "@react-stately/color": "^3.9.2", "@react-stately/form": "^3.2.2", "@react-types/color": "^3.1.2", "@react-types/shared": "^3.32.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-jCC+Q7rAQGLQBkHjkPAeDuGYuMbc4neifjlNRiyZ9as1z4gg63H8MteoWYYk6K4vCKKxSixgt8MfI29XWMOWPQ=="], - - "@react-aria/combobox": ["@react-aria/combobox@3.14.0", "", { "dependencies": { "@react-aria/focus": "^3.21.2", "@react-aria/i18n": "^3.12.13", "@react-aria/listbox": "^3.15.0", "@react-aria/live-announcer": "^3.4.4", "@react-aria/menu": "^3.19.3", "@react-aria/overlays": "^3.30.0", "@react-aria/selection": "^3.26.0", "@react-aria/textfield": "^3.18.2", "@react-aria/utils": "^3.31.0", "@react-stately/collections": "^3.12.8", "@react-stately/combobox": "^3.12.0", "@react-stately/form": "^3.2.2", "@react-types/button": "^3.14.1", "@react-types/combobox": "^3.13.9", "@react-types/shared": "^3.32.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-z4ro0Hma//p4nL2IJx5iUa7NwxeXbzSoZ0se5uTYjG1rUUMszg+wqQh/AQoL+eiULn7rs18JY9wwNbVIkRNKWA=="], - - "@react-aria/datepicker": ["@react-aria/datepicker@3.15.2", "", { "dependencies": { "@internationalized/date": "^3.10.0", "@internationalized/number": "^3.6.5", "@internationalized/string": "^3.2.7", "@react-aria/focus": "^3.21.2", "@react-aria/form": "^3.1.2", "@react-aria/i18n": "^3.12.13", "@react-aria/interactions": "^3.25.6", "@react-aria/label": "^3.7.22", "@react-aria/spinbutton": "^3.6.19", "@react-aria/utils": "^3.31.0", "@react-stately/datepicker": "^3.15.2", "@react-stately/form": "^3.2.2", "@react-types/button": "^3.14.1", "@react-types/calendar": "^3.8.0", "@react-types/datepicker": "^3.13.2", "@react-types/dialog": "^3.5.22", "@react-types/shared": "^3.32.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-th078hyNqPf4P2K10su/y32zPDjs3lOYVdHvsL9/+5K1dnTvLHCK5vgUyLuyn8FchhF7cmHV49D+LZVv65PEpQ=="], - - "@react-aria/dialog": ["@react-aria/dialog@3.5.31", "", { "dependencies": { "@react-aria/interactions": "^3.25.6", "@react-aria/overlays": "^3.30.0", "@react-aria/utils": "^3.31.0", "@react-types/dialog": "^3.5.22", "@react-types/shared": "^3.32.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-inxQMyrzX0UBW9Mhraq0nZ4HjHdygQvllzloT1E/RlDd61lr3RbmJR6pLsrbKOTtSvDIBJpCso1xEdHCFNmA0Q=="], - - "@react-aria/disclosure": ["@react-aria/disclosure@3.1.0", "", { "dependencies": { "@react-aria/ssr": "^3.9.10", "@react-aria/utils": "^3.31.0", "@react-stately/disclosure": "^3.0.8", "@react-types/button": "^3.14.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-5996BeBpnj+yKXYysz+UuhFQxGFPvaZZ3zNBd052wz/i+TVFVGSqqYJ6cwZyO1AfBR8zOT0ZIiK4EC3ETwSvtQ=="], - - "@react-aria/dnd": ["@react-aria/dnd@3.11.3", "", { "dependencies": { "@internationalized/string": "^3.2.7", "@react-aria/i18n": "^3.12.13", "@react-aria/interactions": "^3.25.6", "@react-aria/live-announcer": "^3.4.4", "@react-aria/overlays": "^3.30.0", "@react-aria/utils": "^3.31.0", "@react-stately/collections": "^3.12.8", "@react-stately/dnd": "^3.7.1", "@react-types/button": "^3.14.1", "@react-types/shared": "^3.32.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-MyTziciik1Owz3rqDghu0K3ZtTFvmj/R2ZsLDwbU9N4hKqGX/BKnrI8SytTn8RDqVv5LmA/GhApLngiupTAsXw=="], - "@react-aria/focus": ["@react-aria/focus@3.21.2", "", { "dependencies": { "@react-aria/interactions": "^3.25.6", "@react-aria/utils": "^3.31.0", "@react-types/shared": "^3.32.1", "@swc/helpers": "^0.5.0", "clsx": "^2.0.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-JWaCR7wJVggj+ldmM/cb/DXFg47CXR55lznJhZBh4XVqJjMKwaOOqpT5vNN7kpC1wUpXicGNuDnJDN1S/+6dhQ=="], - "@react-aria/form": ["@react-aria/form@3.1.2", "", { "dependencies": { "@react-aria/interactions": "^3.25.6", "@react-aria/utils": "^3.31.0", "@react-stately/form": "^3.2.2", "@react-types/shared": "^3.32.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-R3i7L7Ci61PqZQvOrnL9xJeWEbh28UkTVgkj72EvBBn39y4h7ReH++0stv7rRs8p5ozETSKezBbGfu4UsBewWw=="], - - "@react-aria/grid": ["@react-aria/grid@3.14.5", "", { "dependencies": { "@react-aria/focus": "^3.21.2", "@react-aria/i18n": "^3.12.13", "@react-aria/interactions": "^3.25.6", "@react-aria/live-announcer": "^3.4.4", "@react-aria/selection": "^3.26.0", "@react-aria/utils": "^3.31.0", "@react-stately/collections": "^3.12.8", "@react-stately/grid": "^3.11.6", "@react-stately/selection": "^3.20.6", "@react-types/checkbox": "^3.10.2", "@react-types/grid": "^3.3.6", "@react-types/shared": "^3.32.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-XHw6rgjlTqc85e3zjsWo3U0EVwjN5MOYtrolCKc/lc2ItNdcY3OlMhpsU9+6jHwg/U3VCSWkGvwAz9hg7krd8Q=="], - - "@react-aria/gridlist": ["@react-aria/gridlist@3.14.1", "", { "dependencies": { "@react-aria/focus": "^3.21.2", "@react-aria/grid": "^3.14.5", "@react-aria/i18n": "^3.12.13", "@react-aria/interactions": "^3.25.6", "@react-aria/selection": "^3.26.0", "@react-aria/utils": "^3.31.0", "@react-stately/list": "^3.13.1", "@react-stately/tree": "^3.9.3", "@react-types/shared": "^3.32.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-keS03Am07aOn7RuNaRsMOyh0jscyhDn95asCVy4lxhl9A9TFk1Jw0o2L6q6cWRj1gFiKeacj/otG5H8ZKQQ2Wg=="], - - "@react-aria/i18n": ["@react-aria/i18n@3.12.13", "", { "dependencies": { "@internationalized/date": "^3.10.0", "@internationalized/message": "^3.1.8", "@internationalized/number": "^3.6.5", "@internationalized/string": "^3.2.7", "@react-aria/ssr": "^3.9.10", "@react-aria/utils": "^3.31.0", "@react-types/shared": "^3.32.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-YTM2BPg0v1RvmP8keHenJBmlx8FXUKsdYIEX7x6QWRd1hKlcDwphfjzvt0InX9wiLiPHsT5EoBTpuUk8SXc0Mg=="], - "@react-aria/interactions": ["@react-aria/interactions@3.25.6", "", { "dependencies": { "@react-aria/ssr": "^3.9.10", "@react-aria/utils": "^3.31.0", "@react-stately/flags": "^3.1.2", "@react-types/shared": "^3.32.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-5UgwZmohpixwNMVkMvn9K1ceJe6TzlRlAfuYoQDUuOkk62/JVJNDLAPKIf5YMRc7d2B0rmfgaZLMtbREb0Zvkw=="], - "@react-aria/label": ["@react-aria/label@3.7.22", "", { "dependencies": { "@react-aria/utils": "^3.31.0", "@react-types/shared": "^3.32.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-jLquJeA5ZNqDT64UpTc9XJ7kQYltUlNcgxZ37/v4mHe0UZ7QohCKdKQhXHONb0h2jjNUpp2HOZI8J9++jOpzxA=="], - - "@react-aria/landmark": ["@react-aria/landmark@3.0.7", "", { "dependencies": { "@react-aria/utils": "^3.31.0", "@react-types/shared": "^3.32.1", "@swc/helpers": "^0.5.0", "use-sync-external-store": "^1.4.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-t8c610b8hPLS6Vwv+rbuSyljZosI1s5+Tosfa0Fk4q7d+Ex6Yj7hLfUFy59GxZAufhUYfGX396fT0gPqAbU1tg=="], - - "@react-aria/link": ["@react-aria/link@3.8.6", "", { "dependencies": { "@react-aria/interactions": "^3.25.6", "@react-aria/utils": "^3.31.0", "@react-types/link": "^3.6.5", "@react-types/shared": "^3.32.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-7F7UDJnwbU9IjfoAdl6f3Hho5/WB7rwcydUOjUux0p7YVWh/fTjIFjfAGyIir7MJhPapun1D0t97QQ3+8jXVcg=="], - - "@react-aria/listbox": ["@react-aria/listbox@3.15.0", "", { "dependencies": { "@react-aria/interactions": "^3.25.6", "@react-aria/label": "^3.7.22", "@react-aria/selection": "^3.26.0", "@react-aria/utils": "^3.31.0", "@react-stately/collections": "^3.12.8", "@react-stately/list": "^3.13.1", "@react-types/listbox": "^3.7.4", "@react-types/shared": "^3.32.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-Ub1Wu79R9sgxM7h4HeEdjOgOKDHwduvYcnDqsSddGXgpkL8ADjsy2YUQ0hHY5VnzA4BxK36bLp4mzSna8Qvj1w=="], - - "@react-aria/live-announcer": ["@react-aria/live-announcer@3.4.4", "", { "dependencies": { "@swc/helpers": "^0.5.0" } }, "sha512-PTTBIjNRnrdJOIRTDGNifY2d//kA7GUAwRFJNOEwSNG4FW+Bq9awqLiflw0JkpyB0VNIwou6lqKPHZVLsGWOXA=="], - - "@react-aria/menu": ["@react-aria/menu@3.19.3", "", { "dependencies": { "@react-aria/focus": "^3.21.2", "@react-aria/i18n": "^3.12.13", "@react-aria/interactions": "^3.25.6", "@react-aria/overlays": "^3.30.0", "@react-aria/selection": "^3.26.0", "@react-aria/utils": "^3.31.0", "@react-stately/collections": "^3.12.8", "@react-stately/menu": "^3.9.8", "@react-stately/selection": "^3.20.6", "@react-stately/tree": "^3.9.3", "@react-types/button": "^3.14.1", "@react-types/menu": "^3.10.5", "@react-types/shared": "^3.32.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-52fh8y8b2776R2VrfZPpUBJYC9oTP7XDy+zZuZTxPEd7Ywk0JNUl5F92y6ru22yPkS13sdhrNM/Op+V/KulmAg=="], - - "@react-aria/meter": ["@react-aria/meter@3.4.27", "", { "dependencies": { "@react-aria/progress": "^3.4.27", "@react-types/meter": "^3.4.13", "@react-types/shared": "^3.32.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-andOOdJkgRJF9vBi5VWRmFodK+GT+5X1lLeNUmb4qOX8/MVfX/RbK72LDeIhd7xC7rSCFHj3WvZ198rK4q0k3w=="], - - "@react-aria/numberfield": ["@react-aria/numberfield@3.12.2", "", { "dependencies": { "@react-aria/i18n": "^3.12.13", "@react-aria/interactions": "^3.25.6", "@react-aria/spinbutton": "^3.6.19", "@react-aria/textfield": "^3.18.2", "@react-aria/utils": "^3.31.0", "@react-stately/form": "^3.2.2", "@react-stately/numberfield": "^3.10.2", "@react-types/button": "^3.14.1", "@react-types/numberfield": "^3.8.15", "@react-types/shared": "^3.32.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-M2b+z0HIXiXpGAWOQkO2kpIjaLNUXJ5Q3/GMa3Fkr+B1piFX0VuOynYrtddKVrmXCe+r5t+XcGb0KS29uqv7nQ=="], - - "@react-aria/overlays": ["@react-aria/overlays@3.30.0", "", { "dependencies": { "@react-aria/focus": "^3.21.2", "@react-aria/i18n": "^3.12.13", "@react-aria/interactions": "^3.25.6", "@react-aria/ssr": "^3.9.10", "@react-aria/utils": "^3.31.0", "@react-aria/visually-hidden": "^3.8.28", "@react-stately/overlays": "^3.6.20", "@react-types/button": "^3.14.1", "@react-types/overlays": "^3.9.2", "@react-types/shared": "^3.32.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-UpjqSjYZx5FAhceWCRVsW6fX1sEwya1fQ/TKkL53FAlLFR8QKuoKqFlmiL43YUFTcGK3UdEOy3cWTleLQwdSmQ=="], - - "@react-aria/progress": ["@react-aria/progress@3.4.27", "", { "dependencies": { "@react-aria/i18n": "^3.12.13", "@react-aria/label": "^3.7.22", "@react-aria/utils": "^3.31.0", "@react-types/progress": "^3.5.16", "@react-types/shared": "^3.32.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-0OA1shs1575g1zmO8+rWozdbTnxThFFhOfuoL1m7UV5Dley6FHpueoKB1ECv7B+Qm4dQt6DoEqLg7wsbbQDhmg=="], - - "@react-aria/radio": ["@react-aria/radio@3.12.2", "", { "dependencies": { "@react-aria/focus": "^3.21.2", "@react-aria/form": "^3.1.2", "@react-aria/i18n": "^3.12.13", "@react-aria/interactions": "^3.25.6", "@react-aria/label": "^3.7.22", "@react-aria/utils": "^3.31.0", "@react-stately/radio": "^3.11.2", "@react-types/radio": "^3.9.2", "@react-types/shared": "^3.32.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-I11f6I90neCh56rT/6ieAs3XyDKvEfbj/QmbU5cX3p+SJpRRPN0vxQi5D1hkh0uxDpeClxygSr31NmZsd4sqfg=="], - - "@react-aria/searchfield": ["@react-aria/searchfield@3.8.9", "", { "dependencies": { "@react-aria/i18n": "^3.12.13", "@react-aria/textfield": "^3.18.2", "@react-aria/utils": "^3.31.0", "@react-stately/searchfield": "^3.5.16", "@react-types/button": "^3.14.1", "@react-types/searchfield": "^3.6.6", "@react-types/shared": "^3.32.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-Yt2pj8Wb5/XsUr2T0DQqFv+DlFpzzWIWnNr9cJATUcWV/xw6ok7YFEg9+7EHtBmsCQxFFJtock1QfZzBw6qLtQ=="], - - "@react-aria/select": ["@react-aria/select@3.17.0", "", { "dependencies": { "@react-aria/form": "^3.1.2", "@react-aria/i18n": "^3.12.13", "@react-aria/interactions": "^3.25.6", "@react-aria/label": "^3.7.22", "@react-aria/listbox": "^3.15.0", "@react-aria/menu": "^3.19.3", "@react-aria/selection": "^3.26.0", "@react-aria/utils": "^3.31.0", "@react-aria/visually-hidden": "^3.8.28", "@react-stately/select": "^3.8.0", "@react-types/button": "^3.14.1", "@react-types/select": "^3.11.0", "@react-types/shared": "^3.32.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-q5ZuyAn5jSOeI0Ys99951TaGcF4O7u1SSBVxPMwVVXOU8ZhToCNx+WG3n/JDYHEjqdo7sbsVRaPA7LkBzBGf5w=="], - - "@react-aria/selection": ["@react-aria/selection@3.26.0", "", { "dependencies": { "@react-aria/focus": "^3.21.2", "@react-aria/i18n": "^3.12.13", "@react-aria/interactions": "^3.25.6", "@react-aria/utils": "^3.31.0", "@react-stately/selection": "^3.20.6", "@react-types/shared": "^3.32.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-ZBH3EfWZ+RfhTj01dH8L17uT7iNbXWS8u77/fUpHgtrm0pwNVhx0TYVnLU1YpazQ/3WVpvWhmBB8sWwD1FlD/g=="], - - "@react-aria/separator": ["@react-aria/separator@3.4.13", "", { "dependencies": { "@react-aria/utils": "^3.31.0", "@react-types/shared": "^3.32.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-0NlcrdBfQbcjWEXdHl3+uSY1272n2ljT1gWL2RIf6aQsQWTZ0gz0rTgRHy0MTXN+y+tICItUERJT4vmTLtIzVg=="], - - "@react-aria/slider": ["@react-aria/slider@3.8.2", "", { "dependencies": { "@react-aria/i18n": "^3.12.13", "@react-aria/interactions": "^3.25.6", "@react-aria/label": "^3.7.22", "@react-aria/utils": "^3.31.0", "@react-stately/slider": "^3.7.2", "@react-types/shared": "^3.32.1", "@react-types/slider": "^3.8.2", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-6KyUGaVzRE4xAz1LKHbNh1q5wzxe58pdTHFSnxNe6nk1SCoHw7NfI4h2s2m6LgJ0megFxsT0Ir8aHaFyyxmbgg=="], - - "@react-aria/spinbutton": ["@react-aria/spinbutton@3.6.19", "", { "dependencies": { "@react-aria/i18n": "^3.12.13", "@react-aria/live-announcer": "^3.4.4", "@react-aria/utils": "^3.31.0", "@react-types/button": "^3.14.1", "@react-types/shared": "^3.32.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-xOIXegDpts9t3RSHdIN0iYQpdts0FZ3LbpYJIYVvdEHo9OpDS+ElnDzCGtwZLguvZlwc5s1LAKuKopDUsAEMkw=="], - "@react-aria/ssr": ["@react-aria/ssr@3.9.10", "", { "dependencies": { "@swc/helpers": "^0.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-hvTm77Pf+pMBhuBm760Li0BVIO38jv1IBws1xFm1NoL26PU+fe+FMW5+VZWyANR6nYL65joaJKZqOdTQMkO9IQ=="], - "@react-aria/switch": ["@react-aria/switch@3.7.8", "", { "dependencies": { "@react-aria/toggle": "^3.12.2", "@react-stately/toggle": "^3.9.2", "@react-types/shared": "^3.32.1", "@react-types/switch": "^3.5.15", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-AfsUq1/YiuoprhcBUD9vDPyWaigAwctQNW1fMb8dROL+i/12B+Zekj8Ml+jbU69/kIVtfL0Jl7/0Bo9KK3X0xQ=="], - - "@react-aria/table": ["@react-aria/table@3.17.8", "", { "dependencies": { "@react-aria/focus": "^3.21.2", "@react-aria/grid": "^3.14.5", "@react-aria/i18n": "^3.12.13", "@react-aria/interactions": "^3.25.6", "@react-aria/live-announcer": "^3.4.4", "@react-aria/utils": "^3.31.0", "@react-aria/visually-hidden": "^3.8.28", "@react-stately/collections": "^3.12.8", "@react-stately/flags": "^3.1.2", "@react-stately/table": "^3.15.1", "@react-types/checkbox": "^3.10.2", "@react-types/grid": "^3.3.6", "@react-types/shared": "^3.32.1", "@react-types/table": "^3.13.4", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-bXiZoxTMbsqUJsYDhHPzKc3jw0HFJ/xMsJ49a0f7mp5r9zACxNLeIU0wJ4Uvx37dnYOHKzGliG+rj5l4sph7MA=="], - - "@react-aria/tabs": ["@react-aria/tabs@3.10.8", "", { "dependencies": { "@react-aria/focus": "^3.21.2", "@react-aria/i18n": "^3.12.13", "@react-aria/selection": "^3.26.0", "@react-aria/utils": "^3.31.0", "@react-stately/tabs": "^3.8.6", "@react-types/shared": "^3.32.1", "@react-types/tabs": "^3.3.19", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-sPPJyTyoAqsBh76JinBAxStOcbjZvyWFYKpJ9Uqw+XT0ObshAPPFSGeh8DiQemPs02RwJdrfARPMhyqiX8t59A=="], - - "@react-aria/tag": ["@react-aria/tag@3.7.2", "", { "dependencies": { "@react-aria/gridlist": "^3.14.1", "@react-aria/i18n": "^3.12.13", "@react-aria/interactions": "^3.25.6", "@react-aria/label": "^3.7.22", "@react-aria/selection": "^3.26.0", "@react-aria/utils": "^3.31.0", "@react-stately/list": "^3.13.1", "@react-types/button": "^3.14.1", "@react-types/shared": "^3.32.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-JV679P5r4DftbqyNBRt7Nw9mP7dxaKPfikjyQuvUoEOa06wBLbM/hU9RJUPRvqK+Un6lgBDAmXD9NNf4N2xpdw=="], - - "@react-aria/textfield": ["@react-aria/textfield@3.18.2", "", { "dependencies": { "@react-aria/form": "^3.1.2", "@react-aria/interactions": "^3.25.6", "@react-aria/label": "^3.7.22", "@react-aria/utils": "^3.31.0", "@react-stately/form": "^3.2.2", "@react-stately/utils": "^3.10.8", "@react-types/shared": "^3.32.1", "@react-types/textfield": "^3.12.6", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-G+lM8VYSor6g9Yptc6hLZ6BF+0cq0pYol1z6wdQUQgJN8tg4HPtzq75lsZtlCSIznL3amgRAxJtd0dUrsAnvaQ=="], - - "@react-aria/toast": ["@react-aria/toast@3.0.8", "", { "dependencies": { "@react-aria/i18n": "^3.12.13", "@react-aria/interactions": "^3.25.6", "@react-aria/landmark": "^3.0.7", "@react-aria/utils": "^3.31.0", "@react-stately/toast": "^3.1.2", "@react-types/button": "^3.14.1", "@react-types/shared": "^3.32.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-rfJIms6AkMyQ7ZgKrMZgGfPwGcB/t1JoEwbc1PAmXcAvFI/hzF6YF7ZFDXiq38ucFsP9PnHmbXIzM9w4ccl18A=="], - - "@react-aria/toggle": ["@react-aria/toggle@3.12.2", "", { "dependencies": { "@react-aria/interactions": "^3.25.6", "@react-aria/utils": "^3.31.0", "@react-stately/toggle": "^3.9.2", "@react-types/checkbox": "^3.10.2", "@react-types/shared": "^3.32.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-g25XLYqJuJpt0/YoYz2Rab8ax+hBfbssllcEFh0v0jiwfk2gwTWfRU9KAZUvxIqbV8Nm8EBmrYychDpDcvW1kw=="], - - "@react-aria/toolbar": ["@react-aria/toolbar@3.0.0-beta.21", "", { "dependencies": { "@react-aria/focus": "^3.21.2", "@react-aria/i18n": "^3.12.13", "@react-aria/utils": "^3.31.0", "@react-types/shared": "^3.32.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-yRCk/GD8g+BhdDgxd3I0a0c8Ni4Wyo6ERzfSoBkPkwQ4X2E2nkopmraM9D0fXw4UcIr4bnmvADzkHXtBN0XrBg=="], - - "@react-aria/tooltip": ["@react-aria/tooltip@3.8.8", "", { "dependencies": { "@react-aria/interactions": "^3.25.6", "@react-aria/utils": "^3.31.0", "@react-stately/tooltip": "^3.5.8", "@react-types/shared": "^3.32.1", "@react-types/tooltip": "^3.4.21", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-CmHUqtXtFWmG4AHMEr9hIVex+oscK6xcM2V47gq9ijNInxe3M6UBu/dBdkgGP/jYv9N7tzCAjTR8nNIHQXwvWw=="], - - "@react-aria/tree": ["@react-aria/tree@3.1.4", "", { "dependencies": { "@react-aria/gridlist": "^3.14.1", "@react-aria/i18n": "^3.12.13", "@react-aria/selection": "^3.26.0", "@react-aria/utils": "^3.31.0", "@react-stately/tree": "^3.9.3", "@react-types/button": "^3.14.1", "@react-types/shared": "^3.32.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-6pbFeN0dAsCOrFGUKU39CNjft20zCAjLfMqfkRWisL+JkUHI2nq6odUJF5jJTsU1C+1951+3oFOmVxPX+K+akQ=="], - "@react-aria/utils": ["@react-aria/utils@3.31.0", "", { "dependencies": { "@react-aria/ssr": "^3.9.10", "@react-stately/flags": "^3.1.2", "@react-stately/utils": "^3.10.8", "@react-types/shared": "^3.32.1", "@swc/helpers": "^0.5.0", "clsx": "^2.0.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-ABOzCsZrWzf78ysswmguJbx3McQUja7yeGj6/vZo4JVsZNlxAN+E9rs381ExBRI0KzVo6iBTeX5De8eMZPJXig=="], - "@react-aria/visually-hidden": ["@react-aria/visually-hidden@3.8.28", "", { "dependencies": { "@react-aria/interactions": "^3.25.6", "@react-aria/utils": "^3.31.0", "@react-types/shared": "^3.32.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-KRRjbVVob2CeBidF24dzufMxBveEUtUu7IM+hpdZKB+gxVROoh4XRLPv9SFmaH89Z7D9To3QoykVZoWD0lan6Q=="], - - "@react-stately/calendar": ["@react-stately/calendar@3.9.0", "", { "dependencies": { "@internationalized/date": "^3.10.0", "@react-stately/utils": "^3.10.8", "@react-types/calendar": "^3.8.0", "@react-types/shared": "^3.32.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-U5Nf2kx9gDhJRxdDUm5gjfyUlt/uUfOvM1vDW2UA62cA6+2k2cavMLc2wNlXOb/twFtl6p0joYKHG7T4xnEFkg=="], - - "@react-stately/checkbox": ["@react-stately/checkbox@3.7.2", "", { "dependencies": { "@react-stately/form": "^3.2.2", "@react-stately/utils": "^3.10.8", "@react-types/checkbox": "^3.10.2", "@react-types/shared": "^3.32.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-j1ycUVz5JmqhaL6mDZgDNZqBilOB8PBW096sDPFaTtuYreDx2HOd1igxiIvwlvPESZwsJP7FVM3mYnaoXtpKPA=="], - - "@react-stately/collections": ["@react-stately/collections@3.12.8", "", { "dependencies": { "@react-types/shared": "^3.32.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-AceJYLLXt1Y2XIcOPi6LEJSs4G/ubeYW3LqOCQbhfIgMaNqKfQMIfagDnPeJX9FVmPFSlgoCBxb1pTJW2vjCAQ=="], - - "@react-stately/color": ["@react-stately/color@3.9.2", "", { "dependencies": { "@internationalized/number": "^3.6.5", "@internationalized/string": "^3.2.7", "@react-stately/form": "^3.2.2", "@react-stately/numberfield": "^3.10.2", "@react-stately/slider": "^3.7.2", "@react-stately/utils": "^3.10.8", "@react-types/color": "^3.1.2", "@react-types/shared": "^3.32.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-F+6Do8W3yu/4n7MpzZtbXwVukcLTFYYDIUtpoR+Jl52UmAr9Hf1CQgkyTI2azv1ZMzj1mVrTBhpBL0q27kFZig=="], - - "@react-stately/combobox": ["@react-stately/combobox@3.12.0", "", { "dependencies": { "@react-stately/collections": "^3.12.8", "@react-stately/form": "^3.2.2", "@react-stately/list": "^3.13.1", "@react-stately/overlays": "^3.6.20", "@react-stately/utils": "^3.10.8", "@react-types/combobox": "^3.13.9", "@react-types/shared": "^3.32.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-A6q9R/7cEa/qoQsBkdslXWvD7ztNLLQ9AhBhVN9QvzrmrH5B4ymUwcTU8lWl22ykH7RRwfonLeLXJL4C+/L2oQ=="], - - "@react-stately/datepicker": ["@react-stately/datepicker@3.15.2", "", { "dependencies": { "@internationalized/date": "^3.10.0", "@internationalized/string": "^3.2.7", "@react-stately/form": "^3.2.2", "@react-stately/overlays": "^3.6.20", "@react-stately/utils": "^3.10.8", "@react-types/datepicker": "^3.13.2", "@react-types/shared": "^3.32.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-S5GL+W37chvV8knv9v0JRv0L6hKo732qqabCCHXzOpYxkLIkV4f/y3cHdEzFWzpZ0O0Gkg7WgeYo160xOdBKYg=="], - - "@react-stately/disclosure": ["@react-stately/disclosure@3.0.8", "", { "dependencies": { "@react-stately/utils": "^3.10.8", "@react-types/shared": "^3.32.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-/Ce/Z76y85eSBZiemfU/uEyXkBBa1RdfLRaKD13rnfUV7/nS3ae1VtNlsXgmwQjWv2pmAiSuEKYMbZfVL7q/lQ=="], - - "@react-stately/dnd": ["@react-stately/dnd@3.7.1", "", { "dependencies": { "@react-stately/selection": "^3.20.6", "@react-types/shared": "^3.32.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-O1JBJ4HI1rVNKuoa5NXiC5FCrCEkr9KVBoKNlTZU8/cnQselhbEsUfMglAakO2EuwIaM1tIXoNF5J/N5P+6lTA=="], - "@react-stately/flags": ["@react-stately/flags@3.1.2", "", { "dependencies": { "@swc/helpers": "^0.5.0" } }, "sha512-2HjFcZx1MyQXoPqcBGALwWWmgFVUk2TuKVIQxCbRq7fPyWXIl6VHcakCLurdtYC2Iks7zizvz0Idv48MQ38DWg=="], - "@react-stately/form": ["@react-stately/form@3.2.2", "", { "dependencies": { "@react-types/shared": "^3.32.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-soAheOd7oaTO6eNs6LXnfn0tTqvOoe3zN9FvtIhhrErKz9XPc5sUmh3QWwR45+zKbitOi1HOjfA/gifKhZcfWw=="], - - "@react-stately/grid": ["@react-stately/grid@3.11.6", "", { "dependencies": { "@react-stately/collections": "^3.12.8", "@react-stately/selection": "^3.20.6", "@react-types/grid": "^3.3.6", "@react-types/shared": "^3.32.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-vWPAkzpeTIsrurHfMubzMuqEw7vKzFhIJeEK5sEcLunyr1rlADwTzeWrHNbPMl66NAIAi70Dr1yNq+kahQyvMA=="], - - "@react-stately/list": ["@react-stately/list@3.13.1", "", { "dependencies": { "@react-stately/collections": "^3.12.8", "@react-stately/selection": "^3.20.6", "@react-stately/utils": "^3.10.8", "@react-types/shared": "^3.32.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-eHaoauh21twbcl0kkwULhVJ+CzYcy1jUjMikNVMHOQdhr4WIBdExf7PmSgKHKqsSPhpGg6IpTCY2dUX3RycjDg=="], - - "@react-stately/menu": ["@react-stately/menu@3.9.8", "", { "dependencies": { "@react-stately/overlays": "^3.6.20", "@react-types/menu": "^3.10.5", "@react-types/shared": "^3.32.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-bo0NOhofnTHLESiYfsSSw6gyXiPVJJ0UlN2igUXtJk5PmyhWjFzUzTzcnd7B028OB0si9w3LIWM3stqz5271Eg=="], - - "@react-stately/numberfield": ["@react-stately/numberfield@3.10.2", "", { "dependencies": { "@internationalized/number": "^3.6.5", "@react-stately/form": "^3.2.2", "@react-stately/utils": "^3.10.8", "@react-types/numberfield": "^3.8.15", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-jlKVFYaH3RX5KvQ7a+SAMQuPccZCzxLkeYkBE64u1Zvi7YhJ8hkTMHG/fmZMbk1rHlseE2wfBdk0Rlya3MvoNQ=="], - - "@react-stately/overlays": ["@react-stately/overlays@3.6.20", "", { "dependencies": { "@react-stately/utils": "^3.10.8", "@react-types/overlays": "^3.9.2", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-YAIe+uI8GUXX8F/0Pzr53YeC5c/bjqbzDFlV8NKfdlCPa6+Jp4B/IlYVjIooBj9+94QvbQdjylegvYWK/iPwlg=="], - - "@react-stately/radio": ["@react-stately/radio@3.11.2", "", { "dependencies": { "@react-stately/form": "^3.2.2", "@react-stately/utils": "^3.10.8", "@react-types/radio": "^3.9.2", "@react-types/shared": "^3.32.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-UM7L6AW+k8edhSBUEPZAqiWNRNadfOKK7BrCXyBiG79zTz0zPcXRR+N+gzkDn7EMSawDeyK1SHYUuoSltTactg=="], - - "@react-stately/searchfield": ["@react-stately/searchfield@3.5.16", "", { "dependencies": { "@react-stately/utils": "^3.10.8", "@react-types/searchfield": "^3.6.6", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-MRfqT1lZ24r94GuFNcGJXsfijZoWjSMySCT60T6NXtbOzVPuAF3K+pL70Rayq/EWLJjS2NPHND11VTs0VdcE0Q=="], - - "@react-stately/select": ["@react-stately/select@3.8.0", "", { "dependencies": { "@react-stately/form": "^3.2.2", "@react-stately/list": "^3.13.1", "@react-stately/overlays": "^3.6.20", "@react-stately/utils": "^3.10.8", "@react-types/select": "^3.11.0", "@react-types/shared": "^3.32.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-A721nlt0DSCDit0wKvhcrXFTG5Vv1qkEVkeKvobmETZy6piKvwh0aaN8iQno5AFuZaj1iOZeNjZ/20TsDJR/4A=="], - - "@react-stately/selection": ["@react-stately/selection@3.20.6", "", { "dependencies": { "@react-stately/collections": "^3.12.8", "@react-stately/utils": "^3.10.8", "@react-types/shared": "^3.32.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-a0bjuP2pJYPKEiedz2Us1W1aSz0iHRuyeQEdBOyL6Z6VUa6hIMq9H60kvseir2T85cOa4QggizuRV7mcO6bU5w=="], - - "@react-stately/slider": ["@react-stately/slider@3.7.2", "", { "dependencies": { "@react-stately/utils": "^3.10.8", "@react-types/shared": "^3.32.1", "@react-types/slider": "^3.8.2", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-EVBHUdUYwj++XqAEiQg2fGi8Reccznba0uyQ3gPejF0pAc390Q/J5aqiTEDfiCM7uJ6WHxTM6lcCqHQBISk2dQ=="], - - "@react-stately/table": ["@react-stately/table@3.15.1", "", { "dependencies": { "@react-stately/collections": "^3.12.8", "@react-stately/flags": "^3.1.2", "@react-stately/grid": "^3.11.6", "@react-stately/selection": "^3.20.6", "@react-stately/utils": "^3.10.8", "@react-types/grid": "^3.3.6", "@react-types/shared": "^3.32.1", "@react-types/table": "^3.13.4", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-MhMAgE/LgAzHcAn1P3p/nQErzJ6DiixSJ1AOt2JlnAKEb5YJg4ATKWCb2IjBLwywt9ZCzfm3KMUzkctZqAoxwA=="], - - "@react-stately/tabs": ["@react-stately/tabs@3.8.6", "", { "dependencies": { "@react-stately/list": "^3.13.1", "@react-types/shared": "^3.32.1", "@react-types/tabs": "^3.3.19", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-9RYxmgjVIxUpIsGKPIF7uRoHWOEz8muwaYiStCVeyiYBPmarvZoIYtTXcwSMN/vEs7heVN5uGCL6/bfdY4+WiA=="], - - "@react-stately/toast": ["@react-stately/toast@3.1.2", "", { "dependencies": { "@swc/helpers": "^0.5.0", "use-sync-external-store": "^1.4.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-HiInm7bck32khFBHZThTQaAF6e6/qm57F4mYRWdTq8IVeGDzpkbUYibnLxRhk0UZ5ybc6me+nqqPkG/lVmM42Q=="], - - "@react-stately/toggle": ["@react-stately/toggle@3.9.2", "", { "dependencies": { "@react-stately/utils": "^3.10.8", "@react-types/checkbox": "^3.10.2", "@react-types/shared": "^3.32.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-dOxs9wrVXHUmA7lc8l+N9NbTJMAaXcYsnNGsMwfXIXQ3rdq+IjWGNYJ52UmNQyRYFcg0jrzRrU16TyGbNjOdNQ=="], - - "@react-stately/tooltip": ["@react-stately/tooltip@3.5.8", "", { "dependencies": { "@react-stately/overlays": "^3.6.20", "@react-types/tooltip": "^3.4.21", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-gkcUx2ROhCiGNAYd2BaTejakXUUNLPnnoJ5+V/mN480pN+OrO8/2V9pqb/IQmpqxLsso93zkM3A4wFHHLBBmPQ=="], - - "@react-stately/tree": ["@react-stately/tree@3.9.3", "", { "dependencies": { "@react-stately/collections": "^3.12.8", "@react-stately/selection": "^3.20.6", "@react-stately/utils": "^3.10.8", "@react-types/shared": "^3.32.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-ZngG79nLFxE/GYmpwX6E/Rma2MMkzdoJPRI3iWk3dgqnGMMzpPnUp/cvjDsU3UHF7xDVusC5BT6pjWN0uxCIFQ=="], - "@react-stately/utils": ["@react-stately/utils@3.10.8", "", { "dependencies": { "@swc/helpers": "^0.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-SN3/h7SzRsusVQjQ4v10LaVsDc81jyyR0DD5HnsQitm/I5WDpaSr2nRHtyloPFU48jlql1XX/S04T2DLQM7Y3g=="], - "@react-types/breadcrumbs": ["@react-types/breadcrumbs@3.7.17", "", { "dependencies": { "@react-types/link": "^3.6.5", "@react-types/shared": "^3.32.1" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-IhvVTcfli5o/UDlGACXxjlor2afGlMQA8pNR3faH0bBUay1Fmm3IWktVw9Xwmk+KraV2RTAg9e+E6p8DOQZfiw=="], - - "@react-types/button": ["@react-types/button@3.14.1", "", { "dependencies": { "@react-types/shared": "^3.32.1" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-D8C4IEwKB7zEtiWYVJ3WE/5HDcWlze9mLWQ5hfsBfpePyWCgO3bT/+wjb/7pJvcAocrkXo90QrMm85LcpBtrpg=="], - - "@react-types/calendar": ["@react-types/calendar@3.8.0", "", { "dependencies": { "@internationalized/date": "^3.10.0", "@react-types/shared": "^3.32.1" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-ZDZgfZgbz1ydWOFs1mH7QFfX3ioJrmb3Y/lkoubQE0HWXLZzyYNvhhKyFJRS1QJ40IofLSBHriwbQb/tsUnGlw=="], - - "@react-types/checkbox": ["@react-types/checkbox@3.10.2", "", { "dependencies": { "@react-types/shared": "^3.32.1" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-ktPkl6ZfIdGS1tIaGSU/2S5Agf2NvXI9qAgtdMDNva0oLyAZ4RLQb6WecPvofw1J7YKXu0VA5Mu7nlX+FM2weQ=="], - - "@react-types/color": ["@react-types/color@3.1.2", "", { "dependencies": { "@react-types/shared": "^3.32.1", "@react-types/slider": "^3.8.2" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-NP0TAY3j4tlMztOp/bBfMlPwC9AQKTjSiTFmc2oQNkx5M4sl3QpPqFPosdt7jZ8M4nItvfCWZrlZGjST4SB83A=="], - - "@react-types/combobox": ["@react-types/combobox@3.13.9", "", { "dependencies": { "@react-types/shared": "^3.32.1" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-G6GmLbzVkLW6VScxPAr/RtliEyPhBClfYaIllK1IZv+Z42SVnOpKzhnoe79BpmiFqy1AaC3+LjZX783mrsHCwA=="], - - "@react-types/datepicker": ["@react-types/datepicker@3.13.2", "", { "dependencies": { "@internationalized/date": "^3.10.0", "@react-types/calendar": "^3.8.0", "@react-types/overlays": "^3.9.2", "@react-types/shared": "^3.32.1" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-+M6UZxJnejYY8kz0spbY/hP08QJ5rsZ3aNarRQQHc48xV2oelFLX5MhAqizfLEsvyfb0JYrhWoh4z1xZtAmYCg=="], - - "@react-types/dialog": ["@react-types/dialog@3.5.22", "", { "dependencies": { "@react-types/overlays": "^3.9.2", "@react-types/shared": "^3.32.1" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-smSvzOcqKE196rWk0oqJDnz+ox5JM5+OT0PmmJXiUD4q7P5g32O6W5Bg7hMIFUI9clBtngo8kLaX2iMg+GqAzg=="], - - "@react-types/grid": ["@react-types/grid@3.3.6", "", { "dependencies": { "@react-types/shared": "^3.32.1" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-vIZJlYTii2n1We9nAugXwM2wpcpsC6JigJFBd6vGhStRdRWRoU4yv1Gc98Usbx0FQ/J7GLVIgeG8+1VMTKBdxw=="], - - "@react-types/link": ["@react-types/link@3.6.5", "", { "dependencies": { "@react-types/shared": "^3.32.1" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-+I2s3XWBEvLrzts0GnNeA84mUkwo+a7kLUWoaJkW0TOBDG7my95HFYxF9WnqKye7NgpOkCqz4s3oW96xPdIniQ=="], - - "@react-types/listbox": ["@react-types/listbox@3.7.4", "", { "dependencies": { "@react-types/shared": "^3.32.1" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-p4YEpTl/VQGrqVE8GIfqTS5LkT5jtjDTbVeZgrkPnX/fiPhsfbTPiZ6g0FNap4+aOGJFGEEZUv2q4vx+rCORww=="], - - "@react-types/menu": ["@react-types/menu@3.10.5", "", { "dependencies": { "@react-types/overlays": "^3.9.2", "@react-types/shared": "^3.32.1" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-HBTrKll2hm0VKJNM4ubIv1L9MNo8JuOnm2G3M+wXvb6EYIyDNxxJkhjsqsGpUXJdAOSkacHBDcNh2HsZABNX4A=="], - - "@react-types/meter": ["@react-types/meter@3.4.13", "", { "dependencies": { "@react-types/progress": "^3.5.16" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-EiarfbpHcvmeyXvXcr6XLaHkNHuGc4g7fBVEiDPwssFJKKfbUzqnnknDxPjyspqUVRcXC08CokS98J1jYobqDg=="], - - "@react-types/numberfield": ["@react-types/numberfield@3.8.15", "", { "dependencies": { "@react-types/shared": "^3.32.1" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-97r92D23GKCOjGIGMeW9nt+/KlfM3GeWH39Czcmd2/D5y3k6z4j0avbsfx2OttCtJszrnENjw3GraYGYI2KosQ=="], - - "@react-types/overlays": ["@react-types/overlays@3.9.2", "", { "dependencies": { "@react-types/shared": "^3.32.1" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-Q0cRPcBGzNGmC8dBuHyoPR7N3057KTS5g+vZfQ53k8WwmilXBtemFJPLsogJbspuewQ/QJ3o2HYsp2pne7/iNw=="], - - "@react-types/progress": ["@react-types/progress@3.5.16", "", { "dependencies": { "@react-types/shared": "^3.32.1" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-I9tSdCFfvQ7gHJtm90VAKgwdTWXQgVNvLRStEc0z9h+bXBxdvZb+QuiRPERChwFQ9VkK4p4rDqaFo69nDqWkpw=="], - - "@react-types/radio": ["@react-types/radio@3.9.2", "", { "dependencies": { "@react-types/shared": "^3.32.1" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-3UcJXu37JrTkRyP4GJPDBU7NmDTInrEdOe+bVzA1j4EegzdkJmLBkLg5cLDAbpiEHB+xIsvbJdx6dxeMuc+H3g=="], - - "@react-types/searchfield": ["@react-types/searchfield@3.6.6", "", { "dependencies": { "@react-types/shared": "^3.32.1", "@react-types/textfield": "^3.12.6" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-cl3itr/fk7wbIQc2Gz5Ie8aVeUmPjVX/mRGS5/EXlmzycAKNYTvqf2mlxwObLndtLISmt7IgNjRRhbUUDI8Ang=="], - - "@react-types/select": ["@react-types/select@3.11.0", "", { "dependencies": { "@react-types/shared": "^3.32.1" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-SzIsMFVPCbXE1Z1TLfpdfiwJ1xnIkcL1/CjGilmUKkNk5uT7rYX1xCJqWCjXI0vAU1xM4Qn+T3n8de4fw6HRBg=="], - "@react-types/shared": ["@react-types/shared@3.32.1", "", { "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-famxyD5emrGGpFuUlgOP6fVW2h/ZaF405G5KDi3zPHzyjAWys/8W6NAVJtNbkCkhedmvL0xOhvt8feGXyXaw5w=="], - "@react-types/slider": ["@react-types/slider@3.8.2", "", { "dependencies": { "@react-types/shared": "^3.32.1" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-MQYZP76OEOYe7/yA2To+Dl0LNb0cKKnvh5JtvNvDnAvEprn1RuLiay8Oi/rTtXmc2KmBa4VdTcsXsmkbbkeN2Q=="], - - "@react-types/switch": ["@react-types/switch@3.5.15", "", { "dependencies": { "@react-types/shared": "^3.32.1" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-r/ouGWQmIeHyYSP1e5luET+oiR7N7cLrAlWsrAfYRWHxqXOSNQloQnZJ3PLHrKFT02fsrQhx2rHaK2LfKeyN3A=="], - - "@react-types/table": ["@react-types/table@3.13.4", "", { "dependencies": { "@react-types/grid": "^3.3.6", "@react-types/shared": "^3.32.1" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-I/DYiZQl6aNbMmjk90J9SOhkzVDZvyA3Vn3wMWCiajkMNjvubFhTfda5DDf2SgFP5l0Yh6TGGH5XumRv9LqL5Q=="], - - "@react-types/tabs": ["@react-types/tabs@3.3.19", "", { "dependencies": { "@react-types/shared": "^3.32.1" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-fE+qI43yR5pAMpeqPxGqQq9jDHXEPqXskuxNHERMW0PYMdPyem2Cw6goc5F4qeZO3Hf6uPZgHkvJz2OAq7TbBw=="], - - "@react-types/textfield": ["@react-types/textfield@3.12.6", "", { "dependencies": { "@react-types/shared": "^3.32.1" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-hpEVKE+M3uUkTjw2WrX1NrH/B3rqDJFUa+ViNK2eVranLY4ZwFqbqaYXSzHupOF3ecSjJJv2C103JrwFvx6TPQ=="], - - "@react-types/tooltip": ["@react-types/tooltip@3.4.21", "", { "dependencies": { "@react-types/overlays": "^3.9.2", "@react-types/shared": "^3.32.1" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-ugGHOZU6WbOdeTdbjnaEc+Ms7/WhsUCg+T3PCOIeOT9FG02Ce189yJ/+hd7oqL/tVwIhEMYJIqSCgSELFox+QA=="], - "@redis/bloom": ["@redis/bloom@1.2.0", "", { "peerDependencies": { "@redis/client": "^1.0.0" } }, "sha512-HG2DFjYKbpNmVXsa0keLHp/3leGJz1mjh09f2RLGGLQZzSHpkmZWuwJbAvo3QcRY8p80m5+ZdXZdYOSBLlp7Cg=="], "@redis/client": ["@redis/client@1.6.1", "", { "dependencies": { "cluster-key-slot": "1.1.2", "generic-pool": "3.9.0", "yallist": "4.0.0" } }, "sha512-/KCsg3xSlR+nCK8/8ZYSknYxvXHwubJrU82F3Lm1Fp6789VQ0/3RJKfsmRXjqfaTA++23CvC3hqmqe/2GEt6Kw=="], @@ -2140,8 +1926,6 @@ "debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="], - "decimal.js": ["decimal.js@10.5.0", "", {}, "sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw=="], - "decode-named-character-reference": ["decode-named-character-reference@1.0.2", "", { "dependencies": { "character-entities": "^2.0.0" } }, "sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg=="], "deepmerge": ["deepmerge@4.3.1", "", {}, "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A=="], @@ -2166,8 +1950,6 @@ "detect-libc": ["detect-libc@2.0.4", "", {}, "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA=="], - "detect-node-es": ["detect-node-es@1.1.0", "", {}, "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ=="], - "devlop": ["devlop@1.1.0", "", { "dependencies": { "dequal": "^2.0.0" } }, "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA=="], "didyoumean": ["didyoumean@1.2.2", "", {}, "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw=="], @@ -2386,8 +2168,6 @@ "get-intrinsic": ["get-intrinsic@1.2.4", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2", "has-proto": "^1.0.1", "has-symbols": "^1.0.3", "hasown": "^2.0.0" } }, "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ=="], - "get-nonce": ["get-nonce@1.0.1", "", {}, "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q=="], - "get-own-enumerable-keys": ["get-own-enumerable-keys@1.0.0", "", {}, "sha512-PKsK2FSrQCyxcGHsGrLDcK0lx+0Ke+6e8KFFozA9/fIQLhQzPaRvJFdcz7+Axg3jUH/Mq+NI4xa5u/UT2tQskA=="], "get-proto": ["get-proto@1.0.1", "", { "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" } }, "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g=="], @@ -2522,10 +2302,6 @@ "internmap": ["internmap@1.0.1", "", {}, "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw=="], - "intl-messageformat": ["intl-messageformat@10.7.14", "", { "dependencies": { "@formatjs/ecma402-abstract": "2.3.2", "@formatjs/fast-memoize": "2.2.6", "@formatjs/icu-messageformat-parser": "2.11.0", "tslib": "2" } }, "sha512-mMGnE4E1otdEutV5vLUdCxRJygHB5ozUBxsPB5qhitewssrS/qGruq9bmvIRkkGsNeK5ZWLfYRld18UHGTIifQ=="], - - "invariant": ["invariant@2.2.4", "", { "dependencies": { "loose-envify": "^1.0.0" } }, "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA=="], - "ip-address": ["ip-address@10.1.0", "", {}, "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q=="], "ipaddr.js": ["ipaddr.js@1.9.1", "", {}, "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="], @@ -2700,8 +2476,6 @@ "longest-streak": ["longest-streak@3.1.0", "", {}, "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g=="], - "loose-envify": ["loose-envify@1.4.0", "", { "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" }, "bin": { "loose-envify": "cli.js" } }, "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q=="], - "lowlight": ["lowlight@3.1.0", "", { "dependencies": { "@types/hast": "^3.0.0", "devlop": "^1.0.0", "highlight.js": "~11.9.0" } }, "sha512-CEbNVoSikAxwDMDPjXlqlFYiZLkDJHwyGu/MfOsJnF3d7f3tds5J3z8s/l9TMXhzfsJCCJEAsD78842mwmg0PQ=="], "lru-cache": ["lru-cache@7.18.3", "", {}, "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA=="], @@ -2934,6 +2708,10 @@ "oxc-transform": ["oxc-transform@0.111.0", "", { "optionalDependencies": { "@oxc-transform/binding-android-arm-eabi": "0.111.0", "@oxc-transform/binding-android-arm64": "0.111.0", "@oxc-transform/binding-darwin-arm64": "0.111.0", "@oxc-transform/binding-darwin-x64": "0.111.0", "@oxc-transform/binding-freebsd-x64": "0.111.0", "@oxc-transform/binding-linux-arm-gnueabihf": "0.111.0", "@oxc-transform/binding-linux-arm-musleabihf": "0.111.0", "@oxc-transform/binding-linux-arm64-gnu": "0.111.0", "@oxc-transform/binding-linux-arm64-musl": "0.111.0", "@oxc-transform/binding-linux-ppc64-gnu": "0.111.0", "@oxc-transform/binding-linux-riscv64-gnu": "0.111.0", "@oxc-transform/binding-linux-riscv64-musl": "0.111.0", "@oxc-transform/binding-linux-s390x-gnu": "0.111.0", "@oxc-transform/binding-linux-x64-gnu": "0.111.0", "@oxc-transform/binding-linux-x64-musl": "0.111.0", "@oxc-transform/binding-openharmony-arm64": "0.111.0", "@oxc-transform/binding-wasm32-wasi": "0.111.0", "@oxc-transform/binding-win32-arm64-msvc": "0.111.0", "@oxc-transform/binding-win32-ia32-msvc": "0.111.0", "@oxc-transform/binding-win32-x64-msvc": "0.111.0" } }, "sha512-oa5KKSDNLHZGaiqIGAbCWXeN9IJUAz9MElWcQX90epDxdKc9Hrt/BsLj3K4gDqfAYa5dwdH+ZCFJG9hR74fiGg=="], + "oxfmt": ["oxfmt@0.62.0", "", { "dependencies": { "tinypool": "2.1.0" }, "optionalDependencies": { "@oxfmt/binding-android-arm-eabi": "0.62.0", "@oxfmt/binding-android-arm64": "0.62.0", "@oxfmt/binding-darwin-arm64": "0.62.0", "@oxfmt/binding-darwin-x64": "0.62.0", "@oxfmt/binding-freebsd-x64": "0.62.0", "@oxfmt/binding-linux-arm-gnueabihf": "0.62.0", "@oxfmt/binding-linux-arm-musleabihf": "0.62.0", "@oxfmt/binding-linux-arm64-gnu": "0.62.0", "@oxfmt/binding-linux-arm64-musl": "0.62.0", "@oxfmt/binding-linux-ppc64-gnu": "0.62.0", "@oxfmt/binding-linux-riscv64-gnu": "0.62.0", "@oxfmt/binding-linux-riscv64-musl": "0.62.0", "@oxfmt/binding-linux-s390x-gnu": "0.62.0", "@oxfmt/binding-linux-x64-gnu": "0.62.0", "@oxfmt/binding-linux-x64-musl": "0.62.0", "@oxfmt/binding-openharmony-arm64": "0.62.0", "@oxfmt/binding-win32-arm64-msvc": "0.62.0", "@oxfmt/binding-win32-ia32-msvc": "0.62.0", "@oxfmt/binding-win32-x64-msvc": "0.62.0" }, "peerDependencies": { "svelte": "^5.0.0", "vite-plus": "*" }, "optionalPeers": ["svelte", "vite-plus"], "bin": { "oxfmt": "bin/oxfmt" } }, "sha512-vxgGHTmnDU9j4CX7dDBLzxgmHxfda/yPcgJkGCMUSCwRmz+euo/V08xXLNgXTeqAB9Fhf3Pe2nO1RNKLCVgphQ=="], + + "oxlint": ["oxlint@1.78.0", "", { "optionalDependencies": { "@oxlint/binding-android-arm-eabi": "1.78.0", "@oxlint/binding-android-arm64": "1.78.0", "@oxlint/binding-darwin-arm64": "1.78.0", "@oxlint/binding-darwin-x64": "1.78.0", "@oxlint/binding-freebsd-x64": "1.78.0", "@oxlint/binding-linux-arm-gnueabihf": "1.78.0", "@oxlint/binding-linux-arm-musleabihf": "1.78.0", "@oxlint/binding-linux-arm64-gnu": "1.78.0", "@oxlint/binding-linux-arm64-musl": "1.78.0", "@oxlint/binding-linux-ppc64-gnu": "1.78.0", "@oxlint/binding-linux-riscv64-gnu": "1.78.0", "@oxlint/binding-linux-riscv64-musl": "1.78.0", "@oxlint/binding-linux-s390x-gnu": "1.78.0", "@oxlint/binding-linux-x64-gnu": "1.78.0", "@oxlint/binding-linux-x64-musl": "1.78.0", "@oxlint/binding-openharmony-arm64": "1.78.0", "@oxlint/binding-win32-arm64-msvc": "1.78.0", "@oxlint/binding-win32-ia32-msvc": "1.78.0", "@oxlint/binding-win32-x64-msvc": "1.78.0" }, "peerDependencies": { "oxlint-tsgolint": ">=7.0.2001", "vite-plus": "*" }, "optionalPeers": ["oxlint-tsgolint", "vite-plus"], "bin": { "oxlint": "bin/oxlint" } }, "sha512-QgQePuxIqKOzo1KSjG2EnITEeWvWnKAm77eq8nrMtf6AGoA+zyGc4PFYtDNJSD25g/ibOwfQ851hZ4/SPkMVoA=="], + "p-filter": ["p-filter@2.1.0", "", { "dependencies": { "p-map": "^2.0.0" } }, "sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw=="], "p-finally": ["p-finally@2.0.1", "", {}, "sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw=="], @@ -3082,18 +2860,10 @@ "react": ["react@19.1.0", "", {}, "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg=="], - "react-aria": ["react-aria@3.44.0", "", { "dependencies": { "@internationalized/string": "^3.2.7", "@react-aria/breadcrumbs": "^3.5.29", "@react-aria/button": "^3.14.2", "@react-aria/calendar": "^3.9.2", "@react-aria/checkbox": "^3.16.2", "@react-aria/color": "^3.1.2", "@react-aria/combobox": "^3.14.0", "@react-aria/datepicker": "^3.15.2", "@react-aria/dialog": "^3.5.31", "@react-aria/disclosure": "^3.1.0", "@react-aria/dnd": "^3.11.3", "@react-aria/focus": "^3.21.2", "@react-aria/gridlist": "^3.14.1", "@react-aria/i18n": "^3.12.13", "@react-aria/interactions": "^3.25.6", "@react-aria/label": "^3.7.22", "@react-aria/landmark": "^3.0.7", "@react-aria/link": "^3.8.6", "@react-aria/listbox": "^3.15.0", "@react-aria/menu": "^3.19.3", "@react-aria/meter": "^3.4.27", "@react-aria/numberfield": "^3.12.2", "@react-aria/overlays": "^3.30.0", "@react-aria/progress": "^3.4.27", "@react-aria/radio": "^3.12.2", "@react-aria/searchfield": "^3.8.9", "@react-aria/select": "^3.17.0", "@react-aria/selection": "^3.26.0", "@react-aria/separator": "^3.4.13", "@react-aria/slider": "^3.8.2", "@react-aria/ssr": "^3.9.10", "@react-aria/switch": "^3.7.8", "@react-aria/table": "^3.17.8", "@react-aria/tabs": "^3.10.8", "@react-aria/tag": "^3.7.2", "@react-aria/textfield": "^3.18.2", "@react-aria/toast": "^3.0.8", "@react-aria/tooltip": "^3.8.8", "@react-aria/tree": "^3.1.4", "@react-aria/utils": "^3.31.0", "@react-aria/visually-hidden": "^3.8.28", "@react-types/shared": "^3.32.1" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "sha512-2Pq3GQxBgM4/2BlpKYXeaZ47a3tdIcYSW/AYvKgypE3XipxOdQMDG5Sr/NBn7zuJq+thzmtfRb0lB9bTbsmaRw=="], - "react-dom": ["react-dom@19.1.0", "", { "dependencies": { "scheduler": "^0.26.0" }, "peerDependencies": { "react": "^19.1.0" } }, "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g=="], "react-hotkeys-hook": ["react-hotkeys-hook@4.5.1", "", { "peerDependencies": { "react": ">=16.8.1", "react-dom": ">=16.8.1" } }, "sha512-scAEJOh3Irm0g95NIn6+tQVf/OICCjsQsC9NBHfQws/Vxw4sfq1tDQut5fhTEvPraXhu/sHxRd9lOtxzyYuNAg=="], - "react-remove-scroll": ["react-remove-scroll@2.6.0", "", { "dependencies": { "react-remove-scroll-bar": "^2.3.6", "react-style-singleton": "^2.2.1", "tslib": "^2.1.0", "use-callback-ref": "^1.3.0", "use-sidecar": "^1.1.2" }, "peerDependencies": { "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", "react": "^16.8.0 || ^17.0.0 || ^18.0.0" }, "optionalPeers": ["@types/react"] }, "sha512-I2U4JVEsQenxDAKaVa3VZ/JeJZe0/2DxPWL8Tj8yLKctQJQiZM52pn/GWFpSp8dftjM3pSAHVJZscAnC/y+ySQ=="], - - "react-remove-scroll-bar": ["react-remove-scroll-bar@2.3.6", "", { "dependencies": { "react-style-singleton": "^2.2.1", "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", "react": "^16.8.0 || ^17.0.0 || ^18.0.0" }, "optionalPeers": ["@types/react"] }, "sha512-DtSYaao4mBmX+HDo5YWYdBWQwYIQQshUV/dVxFxK+KM26Wjwp1gZ6rv6OC3oujI6Bfu6Xyg3TwK533AQutsn/g=="], - - "react-style-singleton": ["react-style-singleton@2.2.1", "", { "dependencies": { "get-nonce": "^1.0.0", "invariant": "^2.2.4", "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", "react": "^16.8.0 || ^17.0.0 || ^18.0.0" }, "optionalPeers": ["@types/react"] }, "sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g=="], - "read-cache": ["read-cache@1.0.0", "", { "dependencies": { "pify": "^2.3.0" } }, "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA=="], "read-yaml-file": ["read-yaml-file@1.1.0", "", { "dependencies": { "graceful-fs": "^4.1.5", "js-yaml": "^3.6.1", "pify": "^4.0.1", "strip-bom": "^3.0.0" } }, "sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA=="], @@ -3336,6 +3106,8 @@ "tinyglobby": ["tinyglobby@0.2.15", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.3" } }, "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ=="], + "tinypool": ["tinypool@2.1.0", "", {}, "sha512-Pugqs6M0m7Lv1I7FtxN4aoyToKg1C4tu+/381vH35y8oENM/Ai7f7C4StcoK4/+BSw9ebcS8jRiVrORFKCALLw=="], + "tldts": ["tldts@7.0.30", "", { "dependencies": { "tldts-core": "^7.0.30" }, "bin": { "tldts": "bin/cli.js" } }, "sha512-ELrFxuqsDdHUwoh0XxDbxuLD3Wnz49Z57IFvTtvWy1hJdcMZjXLIuonjilCiWHlT2GbE4Wlv1wKVTzDFnXH1aw=="], "tldts-core": ["tldts-core@7.0.30", "", {}, "sha512-uiHN8PIB1VmWyS98eZYja4xzlYqeFZVjb4OuYlJQnZAuJhMw4PbKQOKgHKhBdJR3FE/t5mUQ1Kd80++B+qhD1Q=="], @@ -3428,10 +3200,6 @@ "urlpattern-polyfill": ["urlpattern-polyfill@10.1.0", "", {}, "sha512-IGjKp/o0NL3Bso1PymYURCJxMPNAf/ILOpendP9f5B6e1rTJgdgiOvgfoT8VxCAdY+Wisb9uhGaJJf3yZ2V9nw=="], - "use-callback-ref": ["use-callback-ref@1.3.2", "", { "dependencies": { "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", "react": "^16.8.0 || ^17.0.0 || ^18.0.0" }, "optionalPeers": ["@types/react"] }, "sha512-elOQwe6Q8gqZgDA8mrh44qRTQqpIHDcZ3hXTLjBe1i4ph8XpNJnO+aQf3NaG+lriLopI4HMx9VjQLfPQ6vhnoA=="], - - "use-sidecar": ["use-sidecar@1.1.2", "", { "dependencies": { "detect-node-es": "^1.1.0", "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "^16.9.0 || ^17.0.0 || ^18.0.0", "react": "^16.8.0 || ^17.0.0 || ^18.0.0" }, "optionalPeers": ["@types/react"] }, "sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw=="], - "use-sync-external-store": ["use-sync-external-store@1.6.0", "", { "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w=="], "usehooks-ts": ["usehooks-ts@3.1.1", "", { "dependencies": { "lodash.debounce": "^4.0.8" }, "peerDependencies": { "react": "^16.8.0 || ^17 || ^18 || ^19 || ^19.0.0-rc" } }, "sha512-I4diPp9Cq6ieSUH2wu+fDAVQO43xwtulo+fKEidHUwZPnYImbtkTjzIJYcDcJqxgmX31GVqNFURodvcgHcW0pA=="], @@ -3714,166 +3482,6 @@ "@poppinss/dumper/supports-color": ["supports-color@10.2.2", "", {}, "sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g=="], - "@radix-ui/react-arrow/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="], - - "@radix-ui/react-collapsible/@radix-ui/primitive": ["@radix-ui/primitive@1.1.3", "", {}, "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg=="], - - "@radix-ui/react-collapsible/@radix-ui/react-compose-refs": ["@radix-ui/react-compose-refs@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg=="], - - "@radix-ui/react-collapsible/@radix-ui/react-context": ["@radix-ui/react-context@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA=="], - - "@radix-ui/react-collapsible/@radix-ui/react-presence": ["@radix-ui/react-presence@1.1.5", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ=="], - - "@radix-ui/react-collapsible/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="], - - "@radix-ui/react-collapsible/@radix-ui/react-use-controllable-state": ["@radix-ui/react-use-controllable-state@1.2.2", "", { "dependencies": { "@radix-ui/react-use-effect-event": "0.0.2", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg=="], - - "@radix-ui/react-collection/@radix-ui/react-compose-refs": ["@radix-ui/react-compose-refs@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-Y9VzoRDSJtgFMUCoiZBDVo084VQ5hfpXxVE+NgkdNsjiDBByiImMZKKhxMwCbdHvhlENG6a833CbFkOQvTricw=="], - - "@radix-ui/react-collection/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.0.1", "", { "dependencies": { "@radix-ui/react-slot": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-sHCWTtxwNn3L3fH8qAfnF3WbUZycW93SM1j3NFDzXBiz8D6F5UTTy8G1+WFEaiCdvCVRJWj6N2R4Xq6HdiHmDg=="], - - "@radix-ui/react-dismissable-layer/@radix-ui/primitive": ["@radix-ui/primitive@1.1.3", "", {}, "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg=="], - - "@radix-ui/react-dismissable-layer/@radix-ui/react-compose-refs": ["@radix-ui/react-compose-refs@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg=="], - - "@radix-ui/react-dismissable-layer/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="], - - "@radix-ui/react-dismissable-layer/@radix-ui/react-use-callback-ref": ["@radix-ui/react-use-callback-ref@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg=="], - - "@radix-ui/react-dropdown-menu/@radix-ui/primitive": ["@radix-ui/primitive@1.1.2", "", {}, "sha512-XnbHrrprsNqZKQhStrSwgRUQzoCI1glLzdw79xiZPoofhGICeZRSQ3dIxAKH1gb3OHfNf4d6f+vAv3kil2eggA=="], - - "@radix-ui/react-dropdown-menu/@radix-ui/react-compose-refs": ["@radix-ui/react-compose-refs@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg=="], - - "@radix-ui/react-dropdown-menu/@radix-ui/react-context": ["@radix-ui/react-context@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA=="], - - "@radix-ui/react-dropdown-menu/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.0", "", { "dependencies": { "@radix-ui/react-slot": "1.2.0" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-/J/FhLdK0zVcILOwt5g+dH4KnkonCtkVJsa2G6JmvbbtZfBEI1gMsO3QMjseL4F/SwfAMt1Vc/0XKYKq+xJ1sw=="], - - "@radix-ui/react-dropdown-menu/@radix-ui/react-use-controllable-state": ["@radix-ui/react-use-controllable-state@1.2.2", "", { "dependencies": { "@radix-ui/react-use-effect-event": "0.0.2", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg=="], - - "@radix-ui/react-hover-card/@radix-ui/primitive": ["@radix-ui/primitive@1.1.3", "", {}, "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg=="], - - "@radix-ui/react-hover-card/@radix-ui/react-compose-refs": ["@radix-ui/react-compose-refs@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg=="], - - "@radix-ui/react-hover-card/@radix-ui/react-context": ["@radix-ui/react-context@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA=="], - - "@radix-ui/react-hover-card/@radix-ui/react-presence": ["@radix-ui/react-presence@1.1.5", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ=="], - - "@radix-ui/react-hover-card/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="], - - "@radix-ui/react-hover-card/@radix-ui/react-use-controllable-state": ["@radix-ui/react-use-controllable-state@1.2.2", "", { "dependencies": { "@radix-ui/react-use-effect-event": "0.0.2", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg=="], - - "@radix-ui/react-menu/@radix-ui/primitive": ["@radix-ui/primitive@1.1.2", "", {}, "sha512-XnbHrrprsNqZKQhStrSwgRUQzoCI1glLzdw79xiZPoofhGICeZRSQ3dIxAKH1gb3OHfNf4d6f+vAv3kil2eggA=="], - - "@radix-ui/react-menu/@radix-ui/react-collection": ["@radix-ui/react-collection@1.1.4", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-primitive": "2.1.0", "@radix-ui/react-slot": "1.2.0" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-cv4vSf7HttqXilDnAnvINd53OTl1/bjUYVZrkFnA7nwmY9Ob2POUy0WY0sfqBAe1s5FyKsyceQlqiEGPYNTadg=="], - - "@radix-ui/react-menu/@radix-ui/react-compose-refs": ["@radix-ui/react-compose-refs@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg=="], - - "@radix-ui/react-menu/@radix-ui/react-context": ["@radix-ui/react-context@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA=="], - - "@radix-ui/react-menu/@radix-ui/react-direction": ["@radix-ui/react-direction@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw=="], - - "@radix-ui/react-menu/@radix-ui/react-dismissable-layer": ["@radix-ui/react-dismissable-layer@1.1.7", "", { "dependencies": { "@radix-ui/primitive": "1.1.2", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-primitive": "2.1.0", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-escape-keydown": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-j5+WBUdhccJsmH5/H0K6RncjDtoALSEr6jbkaZu+bjw6hOPOhHycr6vEUujl+HBK8kjUfWcoCJXxP6e4lUlMZw=="], - - "@radix-ui/react-menu/@radix-ui/react-focus-guards": ["@radix-ui/react-focus-guards@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-fyjAACV62oPV925xFCrH8DR5xWhg9KYtJT4s3u54jxp+L/hbpTY2kIeEFFbFe+a/HCE94zGQMZLIpVTPVZDhaA=="], - - "@radix-ui/react-menu/@radix-ui/react-focus-scope": ["@radix-ui/react-focus-scope@1.1.4", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-primitive": "2.1.0", "@radix-ui/react-use-callback-ref": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-r2annK27lIW5w9Ho5NyQgqs0MmgZSTIKXWpVCJaLC1q2kZrZkcqnmHkCHMEmv8XLvsLlurKMPT+kbKkRkm/xVA=="], - - "@radix-ui/react-menu/@radix-ui/react-popper": ["@radix-ui/react-popper@1.2.4", "", { "dependencies": { "@floating-ui/react-dom": "^2.0.0", "@radix-ui/react-arrow": "1.1.4", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-primitive": "2.1.0", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-layout-effect": "1.1.1", "@radix-ui/react-use-rect": "1.1.1", "@radix-ui/react-use-size": "1.1.1", "@radix-ui/rect": "1.1.1" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-3p2Rgm/a1cK0r/UVkx5F/K9v/EplfjAeIFCGOPYPO4lZ0jtg4iSQXt/YGTSLWaf4x7NG6Z4+uKFcylcTZjeqDA=="], - - "@radix-ui/react-menu/@radix-ui/react-portal": ["@radix-ui/react-portal@1.1.6", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.0", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-XmsIl2z1n/TsYFLIdYam2rmFwf9OC/Sh2avkbmVMDuBZIe7hSpM0cYnWPAo7nHOVx8zTuwDZGByfcqLdnzp3Vw=="], - - "@radix-ui/react-menu/@radix-ui/react-presence": ["@radix-ui/react-presence@1.1.4", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-ueDqRbdc4/bkaQT3GIpLQssRlFgWaL/U2z/S31qRwwLWoxHLgry3SIfCwhxeQNbirEUXFa+lq3RL3oBYXtcmIA=="], - - "@radix-ui/react-menu/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.0", "", { "dependencies": { "@radix-ui/react-slot": "1.2.0" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-/J/FhLdK0zVcILOwt5g+dH4KnkonCtkVJsa2G6JmvbbtZfBEI1gMsO3QMjseL4F/SwfAMt1Vc/0XKYKq+xJ1sw=="], - - "@radix-ui/react-menu/@radix-ui/react-use-callback-ref": ["@radix-ui/react-use-callback-ref@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg=="], - - "@radix-ui/react-menu/react-remove-scroll": ["react-remove-scroll@2.6.3", "", { "dependencies": { "react-remove-scroll-bar": "^2.3.7", "react-style-singleton": "^2.2.3", "tslib": "^2.1.0", "use-callback-ref": "^1.3.3", "use-sidecar": "^1.1.3" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-pnAi91oOk8g8ABQKGF5/M9qxmmOPxaAnopyTHYfqYEwJhyFrbbBtHuSgtKEoH0jpcxx5o3hXqH1mNd9/Oi+8iQ=="], - - "@radix-ui/react-navigation-menu/@radix-ui/primitive": ["@radix-ui/primitive@1.1.1", "", {}, "sha512-SJ31y+Q/zAyShtXJc8x83i9TYdbAfHZ++tUZnvjJJqFjzsdUnKsxPL6IEtBlxKkU7yzer//GQtZSV4GbldL3YA=="], - - "@radix-ui/react-navigation-menu/@radix-ui/react-compose-refs": ["@radix-ui/react-compose-refs@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-Y9VzoRDSJtgFMUCoiZBDVo084VQ5hfpXxVE+NgkdNsjiDBByiImMZKKhxMwCbdHvhlENG6a833CbFkOQvTricw=="], - - "@radix-ui/react-navigation-menu/@radix-ui/react-dismissable-layer": ["@radix-ui/react-dismissable-layer@1.1.4", "", { "dependencies": { "@radix-ui/primitive": "1.1.1", "@radix-ui/react-compose-refs": "1.1.1", "@radix-ui/react-primitive": "2.0.1", "@radix-ui/react-use-callback-ref": "1.1.0", "@radix-ui/react-use-escape-keydown": "1.1.0" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-XDUI0IVYVSwjMXxM6P4Dfti7AH+Y4oS/TB+sglZ/EXc7cqLwGAmp1NlMrcUjj7ks6R5WTZuWKv44FBbLpwU3sA=="], - - "@radix-ui/react-navigation-menu/@radix-ui/react-id": ["@radix-ui/react-id@1.1.0", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA=="], - - "@radix-ui/react-navigation-menu/@radix-ui/react-presence": ["@radix-ui/react-presence@1.1.2", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.1", "@radix-ui/react-use-layout-effect": "1.1.0" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-18TFr80t5EVgL9x1SwF/YGtfG+l0BS0PRAlCWBDoBEiDQjeKgnNZRVJp/oVBl24sr3Gbfwc/Qpj4OcWTQMsAEg=="], - - "@radix-ui/react-navigation-menu/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.0.1", "", { "dependencies": { "@radix-ui/react-slot": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-sHCWTtxwNn3L3fH8qAfnF3WbUZycW93SM1j3NFDzXBiz8D6F5UTTy8G1+WFEaiCdvCVRJWj6N2R4Xq6HdiHmDg=="], - - "@radix-ui/react-navigation-menu/@radix-ui/react-use-layout-effect": ["@radix-ui/react-use-layout-effect@1.1.0", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w=="], - - "@radix-ui/react-popover/@radix-ui/react-dismissable-layer": ["@radix-ui/react-dismissable-layer@1.1.1", "", { "dependencies": { "@radix-ui/primitive": "1.1.0", "@radix-ui/react-compose-refs": "1.1.0", "@radix-ui/react-primitive": "2.0.0", "@radix-ui/react-use-callback-ref": "1.1.0", "@radix-ui/react-use-escape-keydown": "1.1.0" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-QSxg29lfr/xcev6kSz7MAlmDnzbP1eI/Dwn3Tp1ip0KT5CUELsxkekFEMVBEoykI3oV39hKT4TKZzBNMbcTZYQ=="], - - "@radix-ui/react-popover/@radix-ui/react-id": ["@radix-ui/react-id@1.1.0", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA=="], - - "@radix-ui/react-popover/@radix-ui/react-popper": ["@radix-ui/react-popper@1.2.0", "", { "dependencies": { "@floating-ui/react-dom": "^2.0.0", "@radix-ui/react-arrow": "1.1.0", "@radix-ui/react-compose-refs": "1.1.0", "@radix-ui/react-context": "1.1.0", "@radix-ui/react-primitive": "2.0.0", "@radix-ui/react-use-callback-ref": "1.1.0", "@radix-ui/react-use-layout-effect": "1.1.0", "@radix-ui/react-use-rect": "1.1.0", "@radix-ui/react-use-size": "1.1.0", "@radix-ui/rect": "1.1.0" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-ZnRMshKF43aBxVWPWvbj21+7TQCvhuULWJ4gNIKYpRlQt5xGRhLx66tMp8pya2UkGHTSlhpXwmjqltDYHhw7Vg=="], - - "@radix-ui/react-popover/@radix-ui/react-portal": ["@radix-ui/react-portal@1.1.2", "", { "dependencies": { "@radix-ui/react-primitive": "2.0.0", "@radix-ui/react-use-layout-effect": "1.1.0" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-WeDYLGPxJb/5EGBoedyJbT0MpoULmwnIPMJMSldkuiMsBAv7N1cRdsTWZWht9vpPOiN3qyiGAtbK2is47/uMFg=="], - - "@radix-ui/react-popper/@floating-ui/react-dom": ["@floating-ui/react-dom@2.1.2", "", { "dependencies": { "@floating-ui/dom": "^1.0.0" }, "peerDependencies": { "react": ">=16.8.0", "react-dom": ">=16.8.0" } }, "sha512-06okr5cgPzMNBy+Ycse2A6udMi4bqwW/zgBF/rwjcNqWkyr82Mcg8b0vjX8OJpZFy/FKjJmw6wV7t44kK6kW7A=="], - - "@radix-ui/react-popper/@radix-ui/react-compose-refs": ["@radix-ui/react-compose-refs@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg=="], - - "@radix-ui/react-popper/@radix-ui/react-context": ["@radix-ui/react-context@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA=="], - - "@radix-ui/react-popper/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="], - - "@radix-ui/react-popper/@radix-ui/react-use-callback-ref": ["@radix-ui/react-use-callback-ref@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg=="], - - "@radix-ui/react-popper/@radix-ui/react-use-size": ["@radix-ui/react-use-size@1.1.1", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ=="], - - "@radix-ui/react-portal/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="], - - "@radix-ui/react-presence/@radix-ui/react-use-layout-effect": ["@radix-ui/react-use-layout-effect@1.1.0", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w=="], - - "@radix-ui/react-roving-focus/@radix-ui/primitive": ["@radix-ui/primitive@1.1.2", "", {}, "sha512-XnbHrrprsNqZKQhStrSwgRUQzoCI1glLzdw79xiZPoofhGICeZRSQ3dIxAKH1gb3OHfNf4d6f+vAv3kil2eggA=="], - - "@radix-ui/react-roving-focus/@radix-ui/react-collection": ["@radix-ui/react-collection@1.1.4", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-primitive": "2.1.0", "@radix-ui/react-slot": "1.2.0" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-cv4vSf7HttqXilDnAnvINd53OTl1/bjUYVZrkFnA7nwmY9Ob2POUy0WY0sfqBAe1s5FyKsyceQlqiEGPYNTadg=="], - - "@radix-ui/react-roving-focus/@radix-ui/react-compose-refs": ["@radix-ui/react-compose-refs@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg=="], - - "@radix-ui/react-roving-focus/@radix-ui/react-context": ["@radix-ui/react-context@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA=="], - - "@radix-ui/react-roving-focus/@radix-ui/react-direction": ["@radix-ui/react-direction@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw=="], - - "@radix-ui/react-roving-focus/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.0", "", { "dependencies": { "@radix-ui/react-slot": "1.2.0" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-/J/FhLdK0zVcILOwt5g+dH4KnkonCtkVJsa2G6JmvbbtZfBEI1gMsO3QMjseL4F/SwfAMt1Vc/0XKYKq+xJ1sw=="], - - "@radix-ui/react-roving-focus/@radix-ui/react-use-callback-ref": ["@radix-ui/react-use-callback-ref@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg=="], - - "@radix-ui/react-roving-focus/@radix-ui/react-use-controllable-state": ["@radix-ui/react-use-controllable-state@1.2.2", "", { "dependencies": { "@radix-ui/react-use-effect-event": "0.0.2", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg=="], - - "@radix-ui/react-slot/@radix-ui/react-compose-refs": ["@radix-ui/react-compose-refs@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg=="], - - "@radix-ui/react-tooltip/@radix-ui/primitive": ["@radix-ui/primitive@1.1.1", "", {}, "sha512-SJ31y+Q/zAyShtXJc8x83i9TYdbAfHZ++tUZnvjJJqFjzsdUnKsxPL6IEtBlxKkU7yzer//GQtZSV4GbldL3YA=="], - - "@radix-ui/react-tooltip/@radix-ui/react-compose-refs": ["@radix-ui/react-compose-refs@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-Y9VzoRDSJtgFMUCoiZBDVo084VQ5hfpXxVE+NgkdNsjiDBByiImMZKKhxMwCbdHvhlENG6a833CbFkOQvTricw=="], - - "@radix-ui/react-tooltip/@radix-ui/react-dismissable-layer": ["@radix-ui/react-dismissable-layer@1.1.5", "", { "dependencies": { "@radix-ui/primitive": "1.1.1", "@radix-ui/react-compose-refs": "1.1.1", "@radix-ui/react-primitive": "2.0.2", "@radix-ui/react-use-callback-ref": "1.1.0", "@radix-ui/react-use-escape-keydown": "1.1.0" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-E4TywXY6UsXNRhFrECa5HAvE5/4BFcGyfTyK36gP+pAW1ed7UTK4vKwdr53gAJYwqbfCWC6ATvJa3J3R/9+Qrg=="], - - "@radix-ui/react-tooltip/@radix-ui/react-id": ["@radix-ui/react-id@1.1.0", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA=="], - - "@radix-ui/react-tooltip/@radix-ui/react-popper": ["@radix-ui/react-popper@1.2.2", "", { "dependencies": { "@floating-ui/react-dom": "^2.0.0", "@radix-ui/react-arrow": "1.1.2", "@radix-ui/react-compose-refs": "1.1.1", "@radix-ui/react-context": "1.1.1", "@radix-ui/react-primitive": "2.0.2", "@radix-ui/react-use-callback-ref": "1.1.0", "@radix-ui/react-use-layout-effect": "1.1.0", "@radix-ui/react-use-rect": "1.1.0", "@radix-ui/react-use-size": "1.1.0", "@radix-ui/rect": "1.1.0" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-Rvqc3nOpwseCyj/rgjlJDYAgyfw7OC1tTkKn2ivhaMGcYt8FSBlahHOZak2i3QwkRXUXgGgzeEe2RuqeEHuHgA=="], - - "@radix-ui/react-tooltip/@radix-ui/react-portal": ["@radix-ui/react-portal@1.1.4", "", { "dependencies": { "@radix-ui/react-primitive": "2.0.2", "@radix-ui/react-use-layout-effect": "1.1.0" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-sn2O9k1rPFYVyKd5LAJfo96JlSGVFpa1fS6UuBJfrZadudiw5tAmru+n1x7aMRQ84qDM71Zh1+SzK5QwU0tJfA=="], - - "@radix-ui/react-tooltip/@radix-ui/react-presence": ["@radix-ui/react-presence@1.1.2", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.1", "@radix-ui/react-use-layout-effect": "1.1.0" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-18TFr80t5EVgL9x1SwF/YGtfG+l0BS0PRAlCWBDoBEiDQjeKgnNZRVJp/oVBl24sr3Gbfwc/Qpj4OcWTQMsAEg=="], - - "@radix-ui/react-tooltip/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.0.2", "", { "dependencies": { "@radix-ui/react-slot": "1.1.2" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-Ec/0d38EIuvDF+GZjcMU/Ze6MxntVJYO/fRlCPhCaVUyPY9WTalHJw54tp9sXeJo3tlShWpy41vQRgLRGOuz+w=="], - - "@radix-ui/react-tooltip/@radix-ui/react-visually-hidden": ["@radix-ui/react-visually-hidden@1.1.2", "", { "dependencies": { "@radix-ui/react-primitive": "2.0.2" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-1SzA4ns2M1aRlvxErqhLHsBHoS5eI5UUcI2awAMgGUp4LoaoWOKYmvqDY2s/tltuPkh3Yk77YF/r3IRj+Amx4Q=="], - - "@radix-ui/react-use-escape-keydown/@radix-ui/react-use-callback-ref": ["@radix-ui/react-use-callback-ref@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg=="], - - "@radix-ui/react-use-size/@radix-ui/react-use-layout-effect": ["@radix-ui/react-use-layout-effect@1.1.0", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w=="], - - "@radix-ui/react-visually-hidden/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.0.1", "", { "dependencies": { "@radix-ui/react-slot": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-sHCWTtxwNn3L3fH8qAfnF3WbUZycW93SM1j3NFDzXBiz8D6F5UTTy8G1+WFEaiCdvCVRJWj6N2R4Xq6HdiHmDg=="], - - "@react-aria/landmark/use-sync-external-store": ["use-sync-external-store@1.4.0", "", { "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-9WXSPC5fMv61vaupRkCKCxsPxBocVnwakBEkMIHHpkTTg6icbJtg6jzgtLDm4bl3cSHAca52rYWih0k4K3PfHw=="], - - "@react-stately/toast/use-sync-external-store": ["use-sync-external-store@1.4.0", "", { "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-9WXSPC5fMv61vaupRkCKCxsPxBocVnwakBEkMIHHpkTTg6icbJtg6jzgtLDm4bl3cSHAca52rYWih0k4K3PfHw=="], - "@redis/client/generic-pool": ["generic-pool@3.9.0", "", {}, "sha512-hymDOu5B53XvN4QT9dBmZxPX4CWhBPPLguTZ9MMFeFa/Kg0xWVfylOVNlJji/E7yTZWFd/q9GO5TxDLq156D7g=="], "@redis/client/yallist": ["yallist@4.0.0", "", {}, "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="], @@ -4252,10 +3860,6 @@ "radix-vue/@floating-ui/vue": ["@floating-ui/vue@1.1.5", "", { "dependencies": { "@floating-ui/dom": "^1.0.0", "@floating-ui/utils": "^0.2.8", "vue-demi": ">=0.13.0" } }, "sha512-ynL1p5Z+woPVSwgMGqeDrx6HrJfGIDzFyESFkyqJKilGW1+h/8yVY29Khn0LaU6wHBRwZ13ntG6reiHWK6jyzw=="], - "radix-vue/@internationalized/date": ["@internationalized/date@3.5.6", "", { "dependencies": { "@swc/helpers": "^0.5.0" } }, "sha512-jLxQjefH9VI5P9UQuqB6qNKnvFt1Ky1TPIzHGsIlCi7sZZoMR8SdYbBGRvM0y+Jtb+ez4ieBzmiAUcpmPYpyOw=="], - - "radix-vue/@internationalized/number": ["@internationalized/number@3.5.4", "", { "dependencies": { "@swc/helpers": "^0.5.0" } }, "sha512-h9huwWjNqYyE2FXZZewWqmCdkw1HeFds5q4Siuoms3hUQC5iPJK3aBmkFZoDSLN4UD0Bl8G22L/NdHpeOr+/7A=="], - "radix-vue/@vueuse/core": ["@vueuse/core@10.11.1", "", { "dependencies": { "@types/web-bluetooth": "^0.0.20", "@vueuse/metadata": "10.11.1", "@vueuse/shared": "10.11.1", "vue-demi": ">=0.14.8" } }, "sha512-guoy26JQktXPcz+0n3GukWIy/JDNKti9v6VEMu6kV2sYBsWuGiTU8OWdg+ADfUbHg3/3DlqySDe7JmdHrktiww=="], "radix-vue/@vueuse/shared": ["@vueuse/shared@10.11.1", "", { "dependencies": { "vue-demi": ">=0.14.8" } }, "sha512-LHpC8711VFZlDaYUXEBbFBCQ7GS3dVU9mjOhhMhXP6txTV4EhYQg/KGnQuvt/sPAtoUKq7VVUnL6mVtFoL42sA=="], @@ -4264,12 +3868,6 @@ "raw-body/iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="], - "react-remove-scroll/tslib": ["tslib@2.7.0", "", {}, "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA=="], - - "react-remove-scroll-bar/tslib": ["tslib@2.7.0", "", {}, "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA=="], - - "react-style-singleton/tslib": ["tslib@2.7.0", "", {}, "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA=="], - "read-cache/pify": ["pify@2.3.0", "", {}, "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog=="], "read-yaml-file/js-yaml": ["js-yaml@3.14.1", "", { "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g=="], @@ -4326,10 +3924,6 @@ "unenv/pathe": ["pathe@2.0.3", "", {}, "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w=="], - "use-callback-ref/tslib": ["tslib@2.7.0", "", {}, "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA=="], - - "use-sidecar/tslib": ["tslib@2.7.0", "", {}, "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA=="], - "wrap-ansi/ansi-styles": ["ansi-styles@6.2.1", "", {}, "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug=="], "wrap-ansi/string-width": ["string-width@7.2.0", "", { "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="], @@ -4488,84 +4082,6 @@ "@playwright/test/playwright/playwright-core": ["playwright-core@1.61.1", "", { "bin": { "playwright-core": "cli.js" } }, "sha512-h7Qlt6m4REp25qvIdvbDtVmD4LqVXfpRxhORv9L0jzETM05p4fuPJ3dKyuSXQxDSbXnmS79HAgi9589lGSpLkg=="], - "@radix-ui/react-arrow/@radix-ui/react-primitive/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="], - - "@radix-ui/react-collapsible/@radix-ui/react-primitive/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="], - - "@radix-ui/react-collection/@radix-ui/react-primitive/@radix-ui/react-slot": ["@radix-ui/react-slot@1.1.1", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-RApLLOcINYJA+dMVbOju7MYv1Mb2EBp2nH4HdDzXTSyaR5optlm6Otrz1euW3HbdOR8UmmFK06TD+A9frYWv+g=="], - - "@radix-ui/react-dismissable-layer/@radix-ui/react-primitive/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="], - - "@radix-ui/react-dropdown-menu/@radix-ui/react-primitive/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.0", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-ujc+V6r0HNDviYqIK3rW4ffgYiZ8g5DEHrGJVk4x7kTlLXRDILnKX9vAUYeIsLOoDpDJ0ujpqMkjH4w2ofuo6w=="], - - "@radix-ui/react-hover-card/@radix-ui/react-primitive/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="], - - "@radix-ui/react-menu/@radix-ui/react-collection/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.0", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-ujc+V6r0HNDviYqIK3rW4ffgYiZ8g5DEHrGJVk4x7kTlLXRDILnKX9vAUYeIsLOoDpDJ0ujpqMkjH4w2ofuo6w=="], - - "@radix-ui/react-menu/@radix-ui/react-popper/@floating-ui/react-dom": ["@floating-ui/react-dom@2.1.2", "", { "dependencies": { "@floating-ui/dom": "^1.0.0" }, "peerDependencies": { "react": ">=16.8.0", "react-dom": ">=16.8.0" } }, "sha512-06okr5cgPzMNBy+Ycse2A6udMi4bqwW/zgBF/rwjcNqWkyr82Mcg8b0vjX8OJpZFy/FKjJmw6wV7t44kK6kW7A=="], - - "@radix-ui/react-menu/@radix-ui/react-popper/@radix-ui/react-arrow": ["@radix-ui/react-arrow@1.1.4", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.0" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-qz+fxrqgNxG0dYew5l7qR3c7wdgRu1XVUHGnGYX7rg5HM4p9SWaRmJwfgR3J0SgyUKayLmzQIun+N6rWRgiRKw=="], - - "@radix-ui/react-menu/@radix-ui/react-popper/@radix-ui/react-use-size": ["@radix-ui/react-use-size@1.1.1", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ=="], - - "@radix-ui/react-menu/@radix-ui/react-primitive/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.0", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-ujc+V6r0HNDviYqIK3rW4ffgYiZ8g5DEHrGJVk4x7kTlLXRDILnKX9vAUYeIsLOoDpDJ0ujpqMkjH4w2ofuo6w=="], - - "@radix-ui/react-menu/react-remove-scroll/react-remove-scroll-bar": ["react-remove-scroll-bar@2.3.8", "", { "dependencies": { "react-style-singleton": "^2.2.2", "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" }, "optionalPeers": ["@types/react"] }, "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q=="], - - "@radix-ui/react-menu/react-remove-scroll/react-style-singleton": ["react-style-singleton@2.2.3", "", { "dependencies": { "get-nonce": "^1.0.0", "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ=="], - - "@radix-ui/react-menu/react-remove-scroll/use-callback-ref": ["use-callback-ref@1.3.3", "", { "dependencies": { "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg=="], - - "@radix-ui/react-menu/react-remove-scroll/use-sidecar": ["use-sidecar@1.1.3", "", { "dependencies": { "detect-node-es": "^1.1.0", "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ=="], - - "@radix-ui/react-navigation-menu/@radix-ui/react-dismissable-layer/@radix-ui/react-use-escape-keydown": ["@radix-ui/react-use-escape-keydown@1.1.0", "", { "dependencies": { "@radix-ui/react-use-callback-ref": "1.1.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-L7vwWlR1kTTQ3oh7g1O0CBF3YCyyTj8NmhLR+phShpyA50HCfBFKVJTpshm9PzLiKmehsrQzTYTpX9HvmC9rhw=="], - - "@radix-ui/react-navigation-menu/@radix-ui/react-presence/@radix-ui/react-use-layout-effect": ["@radix-ui/react-use-layout-effect@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ=="], - - "@radix-ui/react-navigation-menu/@radix-ui/react-primitive/@radix-ui/react-slot": ["@radix-ui/react-slot@1.1.1", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-RApLLOcINYJA+dMVbOju7MYv1Mb2EBp2nH4HdDzXTSyaR5optlm6Otrz1euW3HbdOR8UmmFK06TD+A9frYWv+g=="], - - "@radix-ui/react-popover/@radix-ui/react-dismissable-layer/@radix-ui/react-use-escape-keydown": ["@radix-ui/react-use-escape-keydown@1.1.0", "", { "dependencies": { "@radix-ui/react-use-callback-ref": "1.1.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-L7vwWlR1kTTQ3oh7g1O0CBF3YCyyTj8NmhLR+phShpyA50HCfBFKVJTpshm9PzLiKmehsrQzTYTpX9HvmC9rhw=="], - - "@radix-ui/react-popover/@radix-ui/react-id/@radix-ui/react-use-layout-effect": ["@radix-ui/react-use-layout-effect@1.1.0", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w=="], - - "@radix-ui/react-popover/@radix-ui/react-popper/@floating-ui/react-dom": ["@floating-ui/react-dom@2.1.2", "", { "dependencies": { "@floating-ui/dom": "^1.0.0" }, "peerDependencies": { "react": ">=16.8.0", "react-dom": ">=16.8.0" } }, "sha512-06okr5cgPzMNBy+Ycse2A6udMi4bqwW/zgBF/rwjcNqWkyr82Mcg8b0vjX8OJpZFy/FKjJmw6wV7t44kK6kW7A=="], - - "@radix-ui/react-popover/@radix-ui/react-popper/@radix-ui/react-arrow": ["@radix-ui/react-arrow@1.1.0", "", { "dependencies": { "@radix-ui/react-primitive": "2.0.0" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-FmlW1rCg7hBpEBwFbjHwCW6AmWLQM6g/v0Sn8XbP9NvmSZ2San1FpQeyPtufzOMSIx7Y4dzjlHoifhp+7NkZhw=="], - - "@radix-ui/react-popover/@radix-ui/react-popper/@radix-ui/react-context": ["@radix-ui/react-context@1.1.0", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A=="], - - "@radix-ui/react-popover/@radix-ui/react-popper/@radix-ui/react-use-layout-effect": ["@radix-ui/react-use-layout-effect@1.1.0", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w=="], - - "@radix-ui/react-popover/@radix-ui/react-popper/@radix-ui/react-use-rect": ["@radix-ui/react-use-rect@1.1.0", "", { "dependencies": { "@radix-ui/rect": "1.1.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-0Fmkebhr6PiseyZlYAOtLS+nb7jLmpqTrJyv61Pe68MKYW6OWdRE2kI70TaYY27u7H0lajqM3hSMMLFq18Z7nQ=="], - - "@radix-ui/react-popover/@radix-ui/react-popper/@radix-ui/rect": ["@radix-ui/rect@1.1.0", "", {}, "sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg=="], - - "@radix-ui/react-popper/@floating-ui/react-dom/@floating-ui/dom": ["@floating-ui/dom@1.6.11", "", { "dependencies": { "@floating-ui/core": "^1.6.0", "@floating-ui/utils": "^0.2.8" } }, "sha512-qkMCxSR24v2vGkhYDo/UzxfJN3D4syqSjyuTFz6C7XcpU1pASPRieNI0Kj5VP3/503mOfYiGY891ugBX1GlABQ=="], - - "@radix-ui/react-popper/@radix-ui/react-primitive/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="], - - "@radix-ui/react-portal/@radix-ui/react-primitive/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="], - - "@radix-ui/react-roving-focus/@radix-ui/react-collection/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.0", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-ujc+V6r0HNDviYqIK3rW4ffgYiZ8g5DEHrGJVk4x7kTlLXRDILnKX9vAUYeIsLOoDpDJ0ujpqMkjH4w2ofuo6w=="], - - "@radix-ui/react-roving-focus/@radix-ui/react-primitive/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.0", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-ujc+V6r0HNDviYqIK3rW4ffgYiZ8g5DEHrGJVk4x7kTlLXRDILnKX9vAUYeIsLOoDpDJ0ujpqMkjH4w2ofuo6w=="], - - "@radix-ui/react-tooltip/@radix-ui/react-dismissable-layer/@radix-ui/react-use-escape-keydown": ["@radix-ui/react-use-escape-keydown@1.1.0", "", { "dependencies": { "@radix-ui/react-use-callback-ref": "1.1.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-L7vwWlR1kTTQ3oh7g1O0CBF3YCyyTj8NmhLR+phShpyA50HCfBFKVJTpshm9PzLiKmehsrQzTYTpX9HvmC9rhw=="], - - "@radix-ui/react-tooltip/@radix-ui/react-id/@radix-ui/react-use-layout-effect": ["@radix-ui/react-use-layout-effect@1.1.0", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w=="], - - "@radix-ui/react-tooltip/@radix-ui/react-popper/@floating-ui/react-dom": ["@floating-ui/react-dom@2.1.2", "", { "dependencies": { "@floating-ui/dom": "^1.0.0" }, "peerDependencies": { "react": ">=16.8.0", "react-dom": ">=16.8.0" } }, "sha512-06okr5cgPzMNBy+Ycse2A6udMi4bqwW/zgBF/rwjcNqWkyr82Mcg8b0vjX8OJpZFy/FKjJmw6wV7t44kK6kW7A=="], - - "@radix-ui/react-tooltip/@radix-ui/react-popper/@radix-ui/react-arrow": ["@radix-ui/react-arrow@1.1.2", "", { "dependencies": { "@radix-ui/react-primitive": "2.0.2" }, "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-G+KcpzXHq24iH0uGG/pF8LyzpFJYGD4RfLjCIBfGdSLXvjLHST31RUiRVrupIBMvIppMgSzQ6l66iAxl03tdlg=="], - - "@radix-ui/react-tooltip/@radix-ui/react-popper/@radix-ui/react-use-layout-effect": ["@radix-ui/react-use-layout-effect@1.1.0", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w=="], - - "@radix-ui/react-tooltip/@radix-ui/react-popper/@radix-ui/react-use-rect": ["@radix-ui/react-use-rect@1.1.0", "", { "dependencies": { "@radix-ui/rect": "1.1.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-0Fmkebhr6PiseyZlYAOtLS+nb7jLmpqTrJyv61Pe68MKYW6OWdRE2kI70TaYY27u7H0lajqM3hSMMLFq18Z7nQ=="], - - "@radix-ui/react-tooltip/@radix-ui/react-popper/@radix-ui/rect": ["@radix-ui/rect@1.1.0", "", {}, "sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg=="], - - "@radix-ui/react-visually-hidden/@radix-ui/react-primitive/@radix-ui/react-slot": ["@radix-ui/react-slot@1.1.1", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-RApLLOcINYJA+dMVbOju7MYv1Mb2EBp2nH4HdDzXTSyaR5optlm6Otrz1euW3HbdOR8UmmFK06TD+A9frYWv+g=="], - "@scalar/api-client-react/@scalar/types/@scalar/openapi-types": ["@scalar/openapi-types@0.5.0", "", { "dependencies": { "zod": "4.1.11" } }, "sha512-HJBcLa+/mPP+3TCcQngj/iW5UqynRosOQdEETXjmdy6Ngw8wBjwIcT6C86J5jufJ6sI8++HYnt+e7pAvp5FO6A=="], "@scalar/api-client-react/@scalar/types/zod": ["zod@4.1.11", "", {}, "sha512-WPsqwxITS2tzx1bzhIKsEs19ABD5vmCVa4xBo2tq/SrV4RNZtfws1EnCWQXM6yh8bD08a1idvkB5MZSBiZsjwg=="], @@ -4878,28 +4394,6 @@ "@opennextjs/aws/express/serve-static/send": ["send@1.2.0", "", { "dependencies": { "debug": "^4.3.5", "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.1" } }, "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw=="], - "@radix-ui/react-collapsible/@radix-ui/react-primitive/@radix-ui/react-slot/@radix-ui/react-compose-refs": ["@radix-ui/react-compose-refs@1.1.0", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw=="], - - "@radix-ui/react-collection/@radix-ui/react-primitive/@radix-ui/react-slot/@radix-ui/react-compose-refs": ["@radix-ui/react-compose-refs@1.1.0", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw=="], - - "@radix-ui/react-dismissable-layer/@radix-ui/react-primitive/@radix-ui/react-slot/@radix-ui/react-compose-refs": ["@radix-ui/react-compose-refs@1.1.0", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw=="], - - "@radix-ui/react-hover-card/@radix-ui/react-primitive/@radix-ui/react-slot/@radix-ui/react-compose-refs": ["@radix-ui/react-compose-refs@1.1.0", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw=="], - - "@radix-ui/react-menu/@radix-ui/react-popper/@floating-ui/react-dom/@floating-ui/dom": ["@floating-ui/dom@1.6.11", "", { "dependencies": { "@floating-ui/core": "^1.6.0", "@floating-ui/utils": "^0.2.8" } }, "sha512-qkMCxSR24v2vGkhYDo/UzxfJN3D4syqSjyuTFz6C7XcpU1pASPRieNI0Kj5VP3/503mOfYiGY891ugBX1GlABQ=="], - - "@radix-ui/react-navigation-menu/@radix-ui/react-primitive/@radix-ui/react-slot/@radix-ui/react-compose-refs": ["@radix-ui/react-compose-refs@1.1.0", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw=="], - - "@radix-ui/react-popover/@radix-ui/react-popper/@floating-ui/react-dom/@floating-ui/dom": ["@floating-ui/dom@1.6.11", "", { "dependencies": { "@floating-ui/core": "^1.6.0", "@floating-ui/utils": "^0.2.8" } }, "sha512-qkMCxSR24v2vGkhYDo/UzxfJN3D4syqSjyuTFz6C7XcpU1pASPRieNI0Kj5VP3/503mOfYiGY891ugBX1GlABQ=="], - - "@radix-ui/react-popper/@floating-ui/react-dom/@floating-ui/dom/@floating-ui/core": ["@floating-ui/core@1.6.8", "", { "dependencies": { "@floating-ui/utils": "^0.2.8" } }, "sha512-7XJ9cPU+yI2QeLS+FCSlqNFZJq8arvswefkZrYI1yQBbftw6FyrZOxYSh+9S7z7TpeWlRt9zJ5IhM1WIL334jA=="], - - "@radix-ui/react-popper/@floating-ui/react-dom/@floating-ui/dom/@floating-ui/utils": ["@floating-ui/utils@0.2.8", "", {}, "sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig=="], - - "@radix-ui/react-popper/@radix-ui/react-primitive/@radix-ui/react-slot/@radix-ui/react-compose-refs": ["@radix-ui/react-compose-refs@1.1.0", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw=="], - - "@radix-ui/react-tooltip/@radix-ui/react-popper/@floating-ui/react-dom/@floating-ui/dom": ["@floating-ui/dom@1.6.11", "", { "dependencies": { "@floating-ui/core": "^1.6.0", "@floating-ui/utils": "^0.2.8" } }, "sha512-qkMCxSR24v2vGkhYDo/UzxfJN3D4syqSjyuTFz6C7XcpU1pASPRieNI0Kj5VP3/503mOfYiGY891ugBX1GlABQ=="], - "@scalar/components/@scalar/oas-utils/@scalar/workspace-store/@scalar/openapi-upgrader": ["@scalar/openapi-upgrader@0.1.3", "", { "dependencies": { "@scalar/openapi-types": "0.5.0" } }, "sha512-iROhcgy3vge6zsviPtoTLHale0nYt1PLhuMmJweQwJ0U23ZYyYhV5xgHtAd0OBEXuqT6rjYbJFvKOJZmJOwpNQ=="], "@scalar/components/@scalar/themes/@scalar/types/@scalar/openapi-types": ["@scalar/openapi-types@0.5.0", "", { "dependencies": { "zod": "4.1.11" } }, "sha512-HJBcLa+/mPP+3TCcQngj/iW5UqynRosOQdEETXjmdy6Ngw8wBjwIcT6C86J5jufJ6sI8++HYnt+e7pAvp5FO6A=="], @@ -4964,18 +4458,6 @@ "@opennextjs/aws/express/serve-static/send/mime-types": ["mime-types@3.0.2", "", { "dependencies": { "mime-db": "^1.54.0" } }, "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A=="], - "@radix-ui/react-menu/@radix-ui/react-popper/@floating-ui/react-dom/@floating-ui/dom/@floating-ui/core": ["@floating-ui/core@1.6.8", "", { "dependencies": { "@floating-ui/utils": "^0.2.8" } }, "sha512-7XJ9cPU+yI2QeLS+FCSlqNFZJq8arvswefkZrYI1yQBbftw6FyrZOxYSh+9S7z7TpeWlRt9zJ5IhM1WIL334jA=="], - - "@radix-ui/react-menu/@radix-ui/react-popper/@floating-ui/react-dom/@floating-ui/dom/@floating-ui/utils": ["@floating-ui/utils@0.2.8", "", {}, "sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig=="], - - "@radix-ui/react-popover/@radix-ui/react-popper/@floating-ui/react-dom/@floating-ui/dom/@floating-ui/core": ["@floating-ui/core@1.6.8", "", { "dependencies": { "@floating-ui/utils": "^0.2.8" } }, "sha512-7XJ9cPU+yI2QeLS+FCSlqNFZJq8arvswefkZrYI1yQBbftw6FyrZOxYSh+9S7z7TpeWlRt9zJ5IhM1WIL334jA=="], - - "@radix-ui/react-popover/@radix-ui/react-popper/@floating-ui/react-dom/@floating-ui/dom/@floating-ui/utils": ["@floating-ui/utils@0.2.8", "", {}, "sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig=="], - - "@radix-ui/react-tooltip/@radix-ui/react-popper/@floating-ui/react-dom/@floating-ui/dom/@floating-ui/core": ["@floating-ui/core@1.6.8", "", { "dependencies": { "@floating-ui/utils": "^0.2.8" } }, "sha512-7XJ9cPU+yI2QeLS+FCSlqNFZJq8arvswefkZrYI1yQBbftw6FyrZOxYSh+9S7z7TpeWlRt9zJ5IhM1WIL334jA=="], - - "@radix-ui/react-tooltip/@radix-ui/react-popper/@floating-ui/react-dom/@floating-ui/dom/@floating-ui/utils": ["@floating-ui/utils@0.2.8", "", {}, "sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig=="], - "@scalar/draggable/vue/@vue/compiler-sfc/@babel/parser/@babel/types": ["@babel/types@7.28.2", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1" } }, "sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ=="], "@scalar/draggable/vue/@vue/compiler-sfc/magic-string/@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.0", "", {}, "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ=="], diff --git a/package.json b/package.json index c69a18743..7917ffa56 100644 --- a/package.json +++ b/package.json @@ -5,8 +5,9 @@ "node": "^22.3.0" }, "devDependencies": { - "@biomejs/biome": "^1.9.4", "@changesets/cli": "^2.31.0", + "oxfmt": "^0.62.0", + "oxlint": "^1.77.0", "turbo": "^2.10.3", "vercel": "50.37.3" }, @@ -18,8 +19,7 @@ "react": "catalog:", "react-dom": "catalog:", "esbuild": "0.27.3", - "axios": "1.8.4", - "@radix-ui/react-slot": "1.2.4" + "axios": "1.8.4" }, "private": true, "scripts": { @@ -27,8 +27,10 @@ "build": "turbo run build", "clean-deps": "rm -rf node_modules && rm -rf packages/*/node_modules", "typecheck": "turbo run typecheck", - "format": "biome check --write ./", - "format:check": "biome check --diagnostic-level=error ./", + "lint": "oxlint --quiet", + "lint:fix": "oxlint --fix --quiet", + "format": "oxfmt", + "format:check": "oxfmt --check", "unit": "turbo run unit", "e2e": "turbo run e2e", "e2e-customers": "turbo run e2e-customers", @@ -39,11 +41,14 @@ "clean": "turbo run clean" }, "workspaces": { - "packages": ["packages/*"], + "packages": [ + "packages/*" + ], "catalog": { "@tsconfig/strictest": "^2.0.6", "@tsconfig/node20": "^20.1.6", - "@gitbook/api": "0.192.0", + "@base-ui/react": "^1.7.0", + "@gitbook/api": "0.195.0", "@scalar/api-client-react": "^1.3.46", "@types/react": "^19.0.0", "@types/react-dom": "^19.0.0", diff --git a/packages/browser-types/package.json b/packages/browser-types/package.json index 7516cc174..d30c85780 100644 --- a/packages/browser-types/package.json +++ b/packages/browser-types/package.json @@ -25,7 +25,11 @@ "dev": "bun run build -- --watch ./src", "publish-to-npm": "../../scripts/publish-if-new.sh" }, - "files": ["dist", "README.md", "CHANGELOG.md"], + "files": [ + "dist", + "README.md", + "CHANGELOG.md" + ], "publishConfig": { "access": "public", "registry": "https://registry.npmjs.org/" diff --git a/packages/cache-tags/package.json b/packages/cache-tags/package.json index 60d658ad7..bd3e27624 100644 --- a/packages/cache-tags/package.json +++ b/packages/cache-tags/package.json @@ -24,7 +24,11 @@ "dev": "bun run build -- --watch ./src", "publish-to-npm": "../../scripts/publish-if-new.sh" }, - "files": ["dist", "README.md", "CHANGELOG.md"], + "files": [ + "dist", + "README.md", + "CHANGELOG.md" + ], "publishConfig": { "access": "public", "registry": "https://registry.npmjs.org/" diff --git a/packages/cache-tags/src/index.ts b/packages/cache-tags/src/index.ts index 072d7f00a..99e641256 100644 --- a/packages/cache-tags/src/index.ts +++ b/packages/cache-tags/src/index.ts @@ -1,14 +1,15 @@ -import type { ComputedContentSource } from '@gitbook/api'; import assertNever from 'assert-never'; +import type { ComputedContentSource } from '@gitbook/api'; + /** * Get a stringified cache tag for a given object. */ export function getCacheTag( spec: /** - * All data related to a user - * @deprecated - in v2, no tag as this is an immutable data - */ + * All data related to a user + * @deprecated - in v2, no tag as this is an immutable data + */ | { tag: 'user'; user: string; diff --git a/packages/colors/package.json b/packages/colors/package.json index 6bf6d0660..3eefce7b6 100644 --- a/packages/colors/package.json +++ b/packages/colors/package.json @@ -21,7 +21,11 @@ "dev": "bun run build -- --watch ./src", "publish-to-npm": "../../scripts/publish-if-new.sh" }, - "files": ["dist", "README.md", "CHANGELOG.md"], + "files": [ + "dist", + "README.md", + "CHANGELOG.md" + ], "publishConfig": { "access": "public", "registry": "https://registry.npmjs.org/" diff --git a/packages/embed/package.json b/packages/embed/package.json index 83a6ba0c6..720ad6474 100644 --- a/packages/embed/package.json +++ b/packages/embed/package.json @@ -39,7 +39,11 @@ "dev": "bun run build -- --watch ./src", "publish-to-npm": "../../scripts/publish-if-new.sh" }, - "files": ["dist", "README.md", "CHANGELOG.md"], + "files": [ + "dist", + "README.md", + "CHANGELOG.md" + ], "publishConfig": { "access": "public", "registry": "https://registry.npmjs.org/" diff --git a/packages/embed/src/client/createGitBookFrame.ts b/packages/embed/src/client/createGitBookFrame.ts index 579bb5725..b702229c0 100644 --- a/packages/embed/src/client/createGitBookFrame.ts +++ b/packages/embed/src/client/createGitBookFrame.ts @@ -1,4 +1,5 @@ import { createChannel } from 'bidc'; + import type { FrameToParentMessage, GitBookEmbeddableConfiguration, @@ -76,7 +77,7 @@ export function createGitBookFrame(iframe: HTMLIFrameElement): GitBookFrameClien channel.send(message); }; - const events = new Map void>>(); + const events = new Map void)[]>(); const configuration: GitBookEmbeddableConfiguration = { tabs: ['assistant', 'search', 'docs'], diff --git a/packages/embed/src/react/GitBookFrame.tsx b/packages/embed/src/react/GitBookFrame.tsx index e0fe7dcc0..e23e31c0b 100644 --- a/packages/embed/src/react/GitBookFrame.tsx +++ b/packages/embed/src/react/GitBookFrame.tsx @@ -1,6 +1,7 @@ 'use client'; import { useEffect, useMemo, useRef, useState } from 'react'; + import type { GetFrameURLOptions, GitBookEmbeddableConfiguration, diff --git a/packages/embed/src/react/GitBookProvider.tsx b/packages/embed/src/react/GitBookProvider.tsx index f7ab7b94f..95bcfdb77 100644 --- a/packages/embed/src/react/GitBookProvider.tsx +++ b/packages/embed/src/react/GitBookProvider.tsx @@ -1,6 +1,7 @@ 'use client'; import * as React from 'react'; + import { type CreateGitBookOptions, createGitBook } from '../client'; import { GitBookContext } from './context'; diff --git a/packages/embed/src/react/context.ts b/packages/embed/src/react/context.ts index b0c872c59..b6b3606a0 100644 --- a/packages/embed/src/react/context.ts +++ b/packages/embed/src/react/context.ts @@ -1,6 +1,7 @@ 'use client'; import * as React from 'react'; + import type { GitBookClient } from '../client'; export const GitBookContext = React.createContext(null); diff --git a/packages/emoji-codepoints/build.ts b/packages/emoji-codepoints/build.ts index 4883ecb51..67261868b 100644 --- a/packages/emoji-codepoints/build.ts +++ b/packages/emoji-codepoints/build.ts @@ -1,6 +1,6 @@ +import emojisRaws from 'emoji-assets/emoji.json'; import fs from 'node:fs'; import path from 'node:path'; -import emojisRaws from 'emoji-assets/emoji.json'; interface EmojiData { code_points: { diff --git a/packages/expr/package.json b/packages/expr/package.json index 7b4a0e8d1..06363f51c 100644 --- a/packages/expr/package.json +++ b/packages/expr/package.json @@ -36,7 +36,11 @@ "dev": "bun run build -- --watch ./src", "publish-to-npm": "../../scripts/publish-if-new.sh" }, - "files": ["dist", "README.md", "CHANGELOG.md"], + "files": [ + "dist", + "README.md", + "CHANGELOG.md" + ], "publishConfig": { "access": "public", "registry": "https://registry.npmjs.org/" diff --git a/packages/expr/src/__tests__/autocomplete.test.ts b/packages/expr/src/__tests__/autocomplete.test.ts index 64c7647ec..31632bba6 100644 --- a/packages/expr/src/__tests__/autocomplete.test.ts +++ b/packages/expr/src/__tests__/autocomplete.test.ts @@ -58,10 +58,10 @@ describe('autocomplete', () => { }), }; const context = new SymbolsTable(symbols); - const SCENARIOS: Array<{ + const SCENARIOS: { expressionWithCursor: string; expectedSuggestions: AutocompleteSuggestions; - }> = [ + }[] = [ { expressionWithCursor: 'visit', expectedSuggestions: [ diff --git a/packages/expr/src/autocomplete.ts b/packages/expr/src/autocomplete.ts index e87791f1b..4c36c62ea 100644 --- a/packages/expr/src/autocomplete.ts +++ b/packages/expr/src/autocomplete.ts @@ -11,7 +11,6 @@ import type { } from 'acorn'; import { isDummy } from 'acorn-loose'; import * as walk from 'acorn-walk'; - import assertNever from 'assert-never'; import { type ExtractSymbolDef, SymbolType, SymbolsTable } from './symbols'; @@ -312,7 +311,7 @@ export class AutoComplete { node: BinaryExpression, cursorOffset: number, context: SymbolsTable - ): Array { + ): AutocompleteLiteralValueSuggestion[] { const { left, right } = node; if (left.type !== 'MemberExpression' && left.type !== 'Identifier') { @@ -431,7 +430,7 @@ export class AutoComplete { node: AnyNode, cursorOffset: number, context: SymbolsTable - ): Array { + ): AutocompleteOperatorSuggestion[] { if (node.type === 'Literal') { const parent = findParentNode(node, ast); @@ -496,7 +495,7 @@ export class AutoComplete { */ private getOperatorSuggestionsForSymbol( symbol: ExtractSymbolDef - ): Array { + ): AutocompleteOperatorSuggestion[] { switch (symbol.type) { case SymbolType.Number: case SymbolType.Boolean: @@ -526,7 +525,7 @@ export class AutoComplete { case SymbolType.Function: return this.getOperatorSuggestionsForSymbol(symbol.returns); case SymbolType.Union: { - return symbol.members.reduce>((prev, cur) => { + return symbol.members.reduce((prev, cur) => { prev.push(...this.getOperatorSuggestionsForSymbol(cur)); return prev; }, []); diff --git a/packages/expr/src/input-values.ts b/packages/expr/src/input-values.ts index 6aa75cf46..b901d5b07 100644 --- a/packages/expr/src/input-values.ts +++ b/packages/expr/src/input-values.ts @@ -1,4 +1,5 @@ import type { JSONSchema7 } from 'json-schema'; + import { filterOutNullable } from './utils'; type InputValuesType = diff --git a/packages/expr/src/types.ts b/packages/expr/src/types.ts index 7d721480a..0840b0449 100644 --- a/packages/expr/src/types.ts +++ b/packages/expr/src/types.ts @@ -20,7 +20,7 @@ export interface ExpressionParserResult { /** * The information of the invalid (non-expression) nodes found from the other portions of the parsed expression. */ - invalidNodes: Array; + invalidNodes: ExpressionStatement[]; } export interface ExpressionAutocompleteResults { @@ -158,11 +158,11 @@ export interface AutocompleteSymbolSuggestion { symbol: SymbolInfo; } -export type AutocompleteSuggestions = Array< +export type AutocompleteSuggestions = ( | AutocompleteSymbolSuggestion | AutocompleteLiteralValueSuggestion | AutocompleteOperatorSuggestion ->; +)[]; type LoggerFn = (message: string, ...args: any[]) => void; diff --git a/packages/fonts/bin/generate.ts b/packages/fonts/bin/generate.ts index d4326d615..af2cb2861 100644 --- a/packages/fonts/bin/generate.ts +++ b/packages/fonts/bin/generate.ts @@ -1,8 +1,7 @@ +import { APIv2 } from 'google-font-metadata'; import fs from 'node:fs/promises'; import path from 'node:path'; -import { APIv2 } from 'google-font-metadata'; - import { CustomizationDefaultFont } from '@gitbook/api'; import type { FontDefinitions } from '../src/types'; diff --git a/packages/fonts/package.json b/packages/fonts/package.json index 935019b01..8e5277325 100644 --- a/packages/fonts/package.json +++ b/packages/fonts/package.json @@ -27,7 +27,12 @@ "unit": "bun test", "publish-to-npm": "../../scripts/publish-if-new.sh" }, - "files": ["dist", "bin", "README.md", "CHANGELOG.md"], + "files": [ + "dist", + "bin", + "README.md", + "CHANGELOG.md" + ], "engines": { "node": ">=20.0.0" }, diff --git a/packages/fonts/src/fonts.ts b/packages/fonts/src/fonts.ts index c9544efb1..f176276c0 100644 --- a/packages/fonts/src/fonts.ts +++ b/packages/fonts/src/fonts.ts @@ -1,5 +1,4 @@ +import rawFonts from './data/fonts.json' with { type: 'json' }; import type { FontDefinitions } from './types'; -import rawFonts from './data/fonts.json' with { type: 'json' }; - export const fonts: FontDefinitions = rawFonts; diff --git a/packages/fonts/src/getDefaultFont.test.ts b/packages/fonts/src/getDefaultFont.test.ts index 58afbeac9..8efa3196d 100644 --- a/packages/fonts/src/getDefaultFont.test.ts +++ b/packages/fonts/src/getDefaultFont.test.ts @@ -1,5 +1,7 @@ import { describe, expect, it } from 'bun:test'; + import { CustomizationDefaultFont } from '@gitbook/api'; + import { getDefaultFont } from './getDefaultFont'; describe('getDefaultFont', () => { diff --git a/packages/fonts/src/getDefaultFont.ts b/packages/fonts/src/getDefaultFont.ts index d5ffa48df..5fdabc837 100644 --- a/packages/fonts/src/getDefaultFont.ts +++ b/packages/fonts/src/getDefaultFont.ts @@ -1,4 +1,5 @@ import type { CustomizationDefaultFont } from '@gitbook/api'; + import { fonts } from './fonts'; import type { FontWeight } from './types'; @@ -86,7 +87,7 @@ function getBestUnicodeRange(text: string, ranges: Record): stri // ---------- tally code-point hits ---------- const hits: Record = Object.fromEntries(Object.keys(parsed).map((k) => [k, 0])); - for (let i = 0; i < text.length; ) { + for (let i = 0; i < text.length;) { const cp = text.codePointAt(i)!; i += cp > 0xffff ? 2 : 1; // advance by 1 UTF-16 code-unit (or 2 for surrogates) diff --git a/packages/gitbook/e2e/customers.spec.ts b/packages/gitbook/e2e/customers.spec.ts index 8ccdcda75..4c7f417b7 100644 --- a/packages/gitbook/e2e/customers.spec.ts +++ b/packages/gitbook/e2e/customers.spec.ts @@ -360,7 +360,9 @@ const testCases: TestsCase[] = [ { name: 'docs.verifone.com', contentBaseURL: 'https://docs.verifone.com', - tests: [{ name: 'Home', url: '/', run: waitForCookiesDialog }], + // Verifone's custom Cookiebot integration races with and suppresses GitBook's built-in + // banner, so waitForCookiesDialog is not a stable invariant here. + tests: [{ name: 'Home', url: '/' }], }, // Deactivate it because of a custom Ask AI that causes flakiness. // { @@ -385,7 +387,7 @@ const testCases: TestsCase[] = [ { name: 'Home', url: '/docs', run: waitForCookiesDialog }, { name: 'OpenAPI', - url: '/docs/developers/gitbook-api/api-reference/docs-sites/site-ai-ask', + url: '/docs/developers/gitbook-api/api-reference/docs-sites/site-ai-ask/ask-a-question-in-a-site', run: waitForCookiesDialog, }, ], diff --git a/packages/gitbook/e2e/internal.spec.ts b/packages/gitbook/e2e/internal.spec.ts index 77ee57d9d..e7322e3d1 100644 --- a/packages/gitbook/e2e/internal.spec.ts +++ b/packages/gitbook/e2e/internal.spec.ts @@ -1,3 +1,6 @@ +import { expect } from '@playwright/test'; +import jwt from 'jsonwebtoken'; + import { CustomizationAIMode, CustomizationBackground, @@ -11,10 +14,6 @@ import { SiteSocialAccountPlatform, } from '@gitbook/api'; import type { GitBookStandalone } from '@gitbook/embed'; -import { expect } from '@playwright/test'; -import jwt from 'jsonwebtoken'; - -import { VISITOR_TOKEN_COOKIE } from '@/lib/visitors'; import { getGitBookPreviewURL, getSiteAPIToken } from '../tests/utils'; import { @@ -35,8 +34,10 @@ import { waitForAdminToolbar, waitForCookiesDialog, waitForCoverImages, + waitForHydration, waitForNotFound, } from './util'; +import { VISITOR_TOKEN_COOKIE } from '@/lib/visitors'; // Kept as deterministic as possible to reduce visual flakiness: no preamble, a // single fixed search, a concise answer, and a fixed number of follow-ups. The @@ -135,6 +136,23 @@ const searchTestCases: Test[] = [ await expect(page.getByTestId('search-input')).toBeFocused(); }, }, + { + // `fill()` bypasses key events, so it can't catch a swallowed key. RND-12484. + name: 'Search - AI Mode: None - Typing multi-word queries', + url: getCustomizationURL({ + ai: { + mode: CustomizationAIMode.None, + }, + }), + screenshot: false, + run: async (page) => { + await waitForCookiesDialog(page); + const searchInput = page.getByTestId('search-input'); + await searchInput.focus(); + await searchInput.pressSequentially('getting started'); + await expect(searchInput).toHaveValue('getting started'); + }, + }, { name: 'Search - AI Mode: None - URL query (Initial)', url: `${getCustomizationURL({ @@ -381,6 +399,7 @@ const testCases: TestsCase[] = [ name: 'Customized variant titles are displayed', url: '', run: async (page) => { + await waitForHydration(page); const spaceDropdown = page .locator('[data-testid="space-dropdown-button"]') .locator('visible=true'); @@ -408,6 +427,7 @@ const testCases: TestsCase[] = [ name: 'Switch variant with alternate link in metadata', url: 'rfcs', run: async (page) => { + await waitForHydration(page); const spaceDropdown = page .locator('[data-testid="space-dropdown-button"]') .locator('visible=true'); @@ -446,6 +466,7 @@ const testCases: TestsCase[] = [ url: 'api-multi-versions/reference/api-reference/pets', screenshot: false, run: async (page) => { + await waitForHydration(page); const spaceDropdown = await page .locator('[data-testid="space-dropdown-button"]') .locator('visible=true'); @@ -472,6 +493,7 @@ const testCases: TestsCase[] = [ url: 'api-multi-versions-share-links/8tNo6MeXg7CkFMzSSz81/reference/api-reference/pets', screenshot: false, run: async (page) => { + await waitForHydration(page); const spaceDropdown = await page .locator('[data-testid="space-dropdown-button"]') .locator('visible=true'); @@ -513,6 +535,7 @@ const testCases: TestsCase[] = [ return `api-multi-versions-va/reference/api-reference/pets?jwt_token=${token}`; }, run: async (page) => { + await waitForHydration(page); const spaceDropdown = await page .locator('[data-testid="space-dropdown-button"]') .locator('visible=true'); @@ -548,6 +571,7 @@ const testCases: TestsCase[] = [ url: 'ecosystem/connection-provider', screenshot: false, run: async (page) => { + await waitForHydration(page); const spaceDropdown = page .locator('[data-testid="space-dropdown-button"]') .locator('visible=true'); @@ -578,6 +602,7 @@ const testCases: TestsCase[] = [ url: 'nl/ecosysteem/connection-provider', screenshot: false, run: async (page) => { + await waitForHydration(page); const spaceDropdown = page .locator('[data-testid="space-dropdown-button"]') .locator('visible=true'); @@ -618,14 +643,14 @@ const testCases: TestsCase[] = [ url: '', screenshot: false, run: async (page) => { - const trigger = page.getByRole('button', { name: 'Test Section Group 1' }); - // Radix NavigationMenu opens the dropdown on a `pointermove`. A single - // synthetic hover can land before hydration and be lost, so re-hover - // until the dropdown content actually appears. - await expect(async () => { - await trigger.hover(); - await expect(page.getByText('Section B')).toBeVisible({ timeout: 1000 }); - }).toPass({ timeout: 15000 }); + // The menu only opens on `mouseenter`, which cannot fire again once the pointer + // is inside: a hover landing before hydration is lost for good. + await waitForHydration(page); + const trigger = page + .locator('[data-gb-sections]') + .getByRole('button', { name: 'Test Section Group 1' }); + await trigger.hover(); + await expect(page.getByText('Section B')).toBeVisible(); await page.getByText('Section B').click(); await page.waitForURL((url) => url.pathname.includes('/sections/sections-4')); }, @@ -1241,8 +1266,8 @@ const testCases: TestsCase[] = [ }, // New site themes ...allThemes.flatMap((theme) => [ - ...allTintColors.flatMap((tint) => [ - ...allSidebarBackgroundStyles.flatMap((sidebarStyle) => ({ + ...allTintColors.flatMap((tint) => + allSidebarBackgroundStyles.flatMap((sidebarStyle) => ({ name: `Theme ${theme} - Tint ${tint.label} - Sidebar ${sidebarStyle} - Mode ${themeMode}`, url: getCustomizationURL({ styling: { @@ -1262,8 +1287,8 @@ const testCases: TestsCase[] = [ }, }), run: waitForCookiesDialog, - })), - ]), + })) + ), ...allSearchStyles.flatMap((searchStyle) => ({ name: `Theme ${theme} – Search ${searchStyle} – Mode ${themeMode}`, url: getCustomizationURL({ @@ -1283,8 +1308,8 @@ const testCases: TestsCase[] = [ })), ]), // Deprecated header themes - ...allDeprecatedThemePresets.flatMap((preset) => [ - ...allSidebarBackgroundStyles.flatMap((sidebarStyle) => ({ + ...allDeprecatedThemePresets.flatMap((preset) => + allSidebarBackgroundStyles.flatMap((sidebarStyle) => ({ name: `With tint - Legacy header preset ${preset} - Sidebar ${sidebarStyle} - Theme mode ${themeMode}`, url: getCustomizationURL({ styling: { @@ -1310,8 +1335,8 @@ const testCases: TestsCase[] = [ }, }), run: waitForCookiesDialog, - })), - ]), + })) + ), { name: `With tint - Legacy background match - Theme mode ${themeMode}`, url: getCustomizationURL({ @@ -2405,7 +2430,7 @@ const testCases: TestsCase[] = [ actions.nth(1).click(), ]); // Verify the new page would have opened with the expected URL - expect(newPage.url()).toContain('gitbook.com'); + await expect(newPage).toHaveURL(/gitbook\.com/); // Close it immediately to avoid navigation await newPage.close(); @@ -2553,7 +2578,7 @@ const testCases: TestsCase[] = [ openInNewTabButton.click(), ]); // Verify the new page would have opened with the expected URL - expect(newPage.url()).toContain('gitbook.gitbook.io'); + await expect(newPage).toHaveURL(/gitbook\.gitbook\.io/); // Close it immediately to avoid navigation await newPage.close(); }, diff --git a/packages/gitbook/e2e/pdf.spec.ts b/packages/gitbook/e2e/pdf.spec.ts index b694689c9..b8ecc03b2 100644 --- a/packages/gitbook/e2e/pdf.spec.ts +++ b/packages/gitbook/e2e/pdf.spec.ts @@ -1,5 +1,6 @@ import { argosScreenshot } from '@argos-ci/playwright'; import { expect, test } from '@playwright/test'; + import { getContentTestURL } from '../tests/utils'; import { waitForIcons } from './util'; diff --git a/packages/gitbook/e2e/style-perf.spec.ts b/packages/gitbook/e2e/style-perf.spec.ts new file mode 100644 index 000000000..ae6b5017c --- /dev/null +++ b/packages/gitbook/e2e/style-perf.spec.ts @@ -0,0 +1,169 @@ +import { type CDPSession, type Locator, type Page, expect, test } from '@playwright/test'; +import { mkdirSync, writeFileSync } from 'node:fs'; +import { dirname } from 'node:path'; + +import { getContentTestURL } from '../tests/utils'; +import { waitForCookiesDialog } from './util'; + +/** Already covered by `customers.spec.ts`, and among the largest pages we render. */ +const LARGE_PAGE_URL = 'https://docs.snyk.io/snyk-api/reference/apps'; + +/** Table rows the preview workflow pastes into a PR comment. Relative to the package, gitignored. */ +const REPORT_FILE = 'test-results/style-perf.md'; + +// Share of the page one popup may restyle: a ratio so it survives the page growing, a count rather +// than a duration so it does not move with CI machine speed. `search` is above 1 because it still +// restyles the whole document — a ratchet against today's state, to lower as families get fixed. +const RESTYLE_BUDGET_RATIO = { + 'openapi-select': 0.25, + search: 1.25, +}; + +type TraceEvent = { name: string; args?: { elementCount?: number } }; + +/** Elements Blink restyled while `action` ran — DevTools reports this as "Elements affected". */ +async function countRestyledElements( + page: Page, + client: CDPSession, + action: () => Promise +): Promise { + // Style is computed lazily, so settle queued recalcs or earlier work lands in the trace. + await page.evaluate(() => void document.body.offsetHeight); + + await client.send('Tracing.start', { + categories: 'disabled-by-default-devtools.timeline', + transferMode: 'ReturnAsStream', + }); + + await action(); + await page.evaluate(() => void document.body.offsetHeight); + + const handle = await new Promise((resolve) => { + client.once('Tracing.tracingComplete', (event) => resolve(event.stream as string)); + void client.send('Tracing.end'); + }); + + let raw = ''; + for (let eof = false; !eof;) { + const chunk = await client.send('IO.read', { handle }); + raw += chunk.data; + eof = chunk.eof; + } + await client.send('IO.close', { handle }); + + const parsed = JSON.parse(raw); + const events: TraceEvent[] = Array.isArray(parsed) ? parsed : parsed.traceEvents; + + return events + .filter((event) => event.name === 'UpdateLayoutTree') + .reduce((total, event) => total + (event.args?.elementCount ?? 0), 0); +} + +/** + * Measure a *re*open: the first open also pays for mounting the popup, and waiting on anything + * looser than the popup being hidden again undercounts the reopen by ~10x. + */ +async function measureReopen( + page: Page, + client: CDPSession, + open: () => Promise, + popup: Locator +): Promise { + await open(); + await expect(popup).toBeVisible(); + await page.keyboard.press('Escape'); + await expect(popup).toBeHidden(); + + const restyled = await countRestyledElements(page, client, open); + await expect(popup, 'the measurement is meaningless if the popup did not open').toBeVisible(); + + // Leave the page as we found it, so the next measurement is not measuring this popup's teardown. + await page.keyboard.press('Escape'); + await expect(popup).toBeHidden(); + + return restyled; +} + +type Measurement = { name: keyof typeof RESTYLE_BUDGET_RATIO; restyled: number }; + +function expectWithinBudgets(measurements: Measurement[], total: number) { + const count = (value: number) => value.toLocaleString('en-US'); + + // Reported before asserting, so a blown budget still reaches the PR comment. + mkdirSync(dirname(REPORT_FILE), { recursive: true }); + writeFileSync( + REPORT_FILE, + measurements + .map(({ name, restyled }) => { + const ratio = restyled / total; + const budget = RESTYLE_BUDGET_RATIO[name]; + const status = ratio < budget ? '✅' : '❌'; + return `| \`${name}\` | ${count(restyled)} | ${count(total)} | ${(ratio * 100).toFixed(1)}% | ${(budget * 100).toFixed(0)}% | ${status} |\n`; + }) + .join('') + ); + + // Soft, so one breach still reports the other interaction rather than masking it. + for (const { name, restyled } of measurements) { + expect + .soft(restyled / total, `${name} restyled ${restyled} of ${total} elements`) + .toBeLessThan(RESTYLE_BUDGET_RATIO[name]); + } +} + +async function openLargePage(page: Page) { + await page.goto(getContentTestURL(LARGE_PAGE_URL)); + await waitForCookiesDialog(page); + + // Measure a settled page: before hydration the tree is smaller and no popup can open at all. + await page.locator('html.hydrated').waitFor(); + await expect(page.getByLabel('OpenAPI Select').first()).toBeAttached(); + await page.waitForLoadState('networkidle'); + + const client = await page.context().newCDPSession(page); + const totalElements = await page.evaluate(() => document.getElementsByTagName('*').length); + + return { client, totalElements }; +} + +// Guards the harness: if an idle window is busy, background work is leaking into the measurements +// and they mean nothing. Closing a popup leaves a few elements of teardown, so this is not zero — +// it only has to sit far below a real measurement (hundreds) and a whole-document restyle (~11k). +const IDLE_RESTYLE_TOLERANCE = 100; + +async function expectIdle(page: Page, client: CDPSession) { + const restyled = await countRestyledElements(page, client, async () => {}); + expect(restyled, 'an idle page should barely restyle').toBeLessThan(IDLE_RESTYLE_TOLERANCE); +} + +test('opening a popup restyles a bounded part of a large API reference', async ({ page }) => { + const { client, totalElements } = await openLargePage(page); + await expectIdle(page, client); + + const trigger = page.getByLabel('OpenAPI Select').first(); + await trigger.scrollIntoViewIfNeeded(); + const select = await measureReopen( + page, + client, + () => trigger.click(), + page.locator('.openapi-select-popover') + ); + + await expectIdle(page, client); + + const searchInput = page.getByTestId('search-input'); + const search = await measureReopen( + page, + client, + () => searchInput.focus(), + page.getByTestId('search-results') + ); + + expectWithinBudgets( + [ + { name: 'openapi-select', restyled: select }, + { name: 'search', restyled: search }, + ], + totalElements + ); +}); diff --git a/packages/gitbook/e2e/util.ts b/packages/gitbook/e2e/util.ts index 402f4aede..2040eb618 100644 --- a/packages/gitbook/e2e/util.ts +++ b/packages/gitbook/e2e/util.ts @@ -1,4 +1,16 @@ import { argosScreenshot } from '@argos-ci/playwright'; +import { + type BrowserContext, + type FrameLocator, + type Page, + type Response, + expect, + test, +} from '@playwright/test'; +import deepMerge from 'deepmerge'; +import rison from 'rison'; +import type { DeepPartial } from 'ts-essentials'; + import { CustomizationAIMode, CustomizationBackground, @@ -22,17 +34,6 @@ import { type SiteCustomizationSettings, SiteExternalLinksTarget, } from '@gitbook/api'; -import { - type BrowserContext, - type FrameLocator, - type Page, - type Response, - expect, - test, -} from '@playwright/test'; -import deepMerge from 'deepmerge'; -import rison from 'rison'; -import type { DeepPartial } from 'ts-essentials'; import { getContentTestURL, getTestURL } from '../tests/utils'; @@ -91,7 +92,7 @@ export interface Test { export type TestsCase = { name: string; skip?: boolean; - tests: Array; + tests: Test[]; contentBaseURL?: string; /** * Whether screenshots in this test case should capture the full scrollable page by default. @@ -111,10 +112,10 @@ export const allThemeModes: CustomizationDefaultThemeMode[] = [ CustomizationDefaultThemeMode.Dark, ]; -export const allTintColors: Array<{ +export const allTintColors: { label: string; value: CustomizationThemedColor | undefined; -}> = [ +}[] = [ { label: 'Off', value: undefined, @@ -172,6 +173,10 @@ export async function waitForCookiesDialog(page: Page) { }); } +export async function waitForHydration(page: Page) { + await page.locator('html.hydrated').waitFor(); +} + /** * Wait for the GitBook admin toolbar to be present. * diff --git a/packages/gitbook/openNext/customWorkers/default.js b/packages/gitbook/openNext/customWorkers/default.js index c7da9ee96..ce48cd4b7 100644 --- a/packages/gitbook/openNext/customWorkers/default.js +++ b/packages/gitbook/openNext/customWorkers/default.js @@ -1,7 +1,7 @@ -import { runWithCloudflareRequestContext } from '../../.open-next/cloudflare/init.js'; - import { DurableObject } from 'cloudflare:workers'; +import { runWithCloudflareRequestContext } from '../../.open-next/cloudflare/init.js'; + //Only needed to run locally, in prod we'll use the one from do.js export { DOShardedTagCache } from '../../.open-next/.build/durable-objects/sharded-tag-cache.js'; @@ -28,9 +28,8 @@ export default { async fetch(request, env, ctx) { return runWithCloudflareRequestContext(request, env, ctx, async () => { // We can't move the handler import to the top level, otherwise the runtime will not be properly initialized - const { handler } = await import( - '../../.open-next/server-functions/default/handler.mjs' - ); + const { handler } = + await import('../../.open-next/server-functions/default/handler.mjs'); // - `Request`s are handled by the Next server return handler(request, env, ctx); diff --git a/packages/gitbook/openNext/customWorkers/defaultWrangler.jsonc b/packages/gitbook/openNext/customWorkers/defaultWrangler.jsonc index 975361d64..9d98c9150 100644 --- a/packages/gitbook/openNext/customWorkers/defaultWrangler.jsonc +++ b/packages/gitbook/openNext/customWorkers/defaultWrangler.jsonc @@ -7,174 +7,174 @@ "compatibility_flags": [ "nodejs_compat", "allow_importable_env", - "global_fetch_strictly_public" + "global_fetch_strictly_public", ], "observability": { - "enabled": false + "enabled": false, }, "vars": { - "NEXT_CACHE_DO_QUEUE_DISABLE_SQLITE": "true" + "NEXT_CACHE_DO_QUEUE_DISABLE_SQLITE": "true", }, "env": { "dev": { "vars": { "STAGE": "dev", "OPEN_NEXT_REQUEST_ID_HEADER": "true", - "GITBOOK_URL": "http://localhost:8771" + "GITBOOK_URL": "http://localhost:8771", }, "r2_buckets": [ { "binding": "NEXT_INC_CACHE_R2_BUCKET", - "bucket_name": "gitbook-open-v2-cache-preview" - } + "bucket_name": "gitbook-open-v2-cache-preview", + }, ], "services": [ { "binding": "WORKER_SELF_REFERENCE", - "service": "gitbook-open-v2-server-dev" - } + "service": "gitbook-open-v2-server-dev", + }, ], "durable_objects": { "bindings": [ { "name": "WRITE_BUFFER", - "class_name": "R2WriteBuffer" + "class_name": "R2WriteBuffer", }, { "name": "NEXT_TAG_CACHE_DO_SHARDED", - "class_name": "DOShardedTagCache" - } - ] + "class_name": "DOShardedTagCache", + }, + ], }, "migrations": [ { "tag": "v1", - "new_sqlite_classes": ["R2WriteBuffer", "DOShardedTagCache"] - } - ] + "new_sqlite_classes": ["R2WriteBuffer", "DOShardedTagCache"], + }, + ], }, "preview": { "vars": { "STAGE": "preview", // Just as a test for the preview environment to check that everything works - "NEXT_PRIVATE_DEBUG_CACHE": "true" + "NEXT_PRIVATE_DEBUG_CACHE": "true", }, "r2_buckets": [ { "binding": "NEXT_INC_CACHE_R2_BUCKET", - "bucket_name": "gitbook-open-v2-cache-preview" - } + "bucket_name": "gitbook-open-v2-cache-preview", + }, ], "services": [ { "binding": "WORKER_SELF_REFERENCE", - "service": "gitbook-open-v2-server-preview" - } + "service": "gitbook-open-v2-server-preview", + }, ], "durable_objects": { "bindings": [ { "name": "WRITE_BUFFER", "class_name": "R2WriteBuffer", - "script_name": "gitbook-open-v2-do-preview" + "script_name": "gitbook-open-v2-do-preview", }, { "name": "NEXT_TAG_CACHE_DO_SHARDED", "class_name": "DOShardedTagCache", - "script_name": "gitbook-open-v2-do-preview" + "script_name": "gitbook-open-v2-do-preview", }, { "name": "NEXT_CACHE_DO_QUEUE", "class_name": "DOQueueHandler", - "script_name": "gitbook-open-v2-do-preview" - } - ] - } + "script_name": "gitbook-open-v2-do-preview", + }, + ], + }, }, "staging": { "vars": { - "OPEN_NEXT_REQUEST_ID_HEADER": "true" + "OPEN_NEXT_REQUEST_ID_HEADER": "true", }, "r2_buckets": [ { "binding": "NEXT_INC_CACHE_R2_BUCKET", - "bucket_name": "gitbook-open-v2-cache-staging" - } + "bucket_name": "gitbook-open-v2-cache-staging", + }, ], "services": [ { "binding": "WORKER_SELF_REFERENCE", - "service": "gitbook-open-v2-server-staging" - } + "service": "gitbook-open-v2-server-staging", + }, ], "durable_objects": { "bindings": [ { "name": "WRITE_BUFFER", "class_name": "R2WriteBuffer", - "script_name": "gitbook-open-v2-do-staging" + "script_name": "gitbook-open-v2-do-staging", }, { "name": "NEXT_TAG_CACHE_DO_SHARDED", "class_name": "DOShardedTagCache", - "script_name": "gitbook-open-v2-do-staging" + "script_name": "gitbook-open-v2-do-staging", }, { "name": "NEXT_CACHE_DO_QUEUE", "class_name": "DOQueueHandler", - "script_name": "gitbook-open-v2-do-staging" - } - ] + "script_name": "gitbook-open-v2-do-staging", + }, + ], }, "tail_consumers": [ { - "service": "gitbook-x-staging-tail" - } - ] + "service": "gitbook-x-staging-tail", + }, + ], }, "production": { "vars": { // This is a bit misleading, but it means that we can have 500 concurrent revalidations // This means that we'll have up to 100 durable objects instance running at the same time "MAX_REVALIDATE_CONCURRENCY": "100", - "OPEN_NEXT_REQUEST_ID_HEADER": "true" + "OPEN_NEXT_REQUEST_ID_HEADER": "true", }, "r2_buckets": [ { "binding": "NEXT_INC_CACHE_R2_BUCKET", - "bucket_name": "gitbook-open-v2-cache-production" - } + "bucket_name": "gitbook-open-v2-cache-production", + }, ], "services": [ { "binding": "WORKER_SELF_REFERENCE", - "service": "gitbook-open-v2-server-production" - } + "service": "gitbook-open-v2-server-production", + }, ], "durable_objects": { "bindings": [ { "name": "WRITE_BUFFER", "class_name": "R2WriteBuffer", - "script_name": "gitbook-open-v2-do-production" + "script_name": "gitbook-open-v2-do-production", }, { "name": "NEXT_TAG_CACHE_DO_SHARDED", "class_name": "DOShardedTagCache", - "script_name": "gitbook-open-v2-do-production" + "script_name": "gitbook-open-v2-do-production", }, { "name": "NEXT_CACHE_DO_QUEUE", "class_name": "DOQueueHandler", - "script_name": "gitbook-open-v2-do-production" - } - ] + "script_name": "gitbook-open-v2-do-production", + }, + ], }, "tail_consumers": [ { - "service": "gitbook-x-prod-tail" - } - ] - } - } + "service": "gitbook-x-prod-tail", + }, + ], + }, + }, } diff --git a/packages/gitbook/openNext/customWorkers/doWrangler.jsonc b/packages/gitbook/openNext/customWorkers/doWrangler.jsonc index 54c0ed644..48a72a3cb 100644 --- a/packages/gitbook/openNext/customWorkers/doWrangler.jsonc +++ b/packages/gitbook/openNext/customWorkers/doWrangler.jsonc @@ -6,96 +6,96 @@ "compatibility_flags": [ "nodejs_compat", "allow_importable_env", - "global_fetch_strictly_public" + "global_fetch_strictly_public", ], "observability": { - "enabled": false + "enabled": false, }, "env": { "preview": { "vars": { "STAGE": "preview", - "NEXT_CACHE_DO_QUEUE_DISABLE_SQLITE": "true" + "NEXT_CACHE_DO_QUEUE_DISABLE_SQLITE": "true", }, "r2_buckets": [ { "binding": "NEXT_INC_CACHE_R2_BUCKET", - "bucket_name": "gitbook-open-v2-cache-preview" - } + "bucket_name": "gitbook-open-v2-cache-preview", + }, ], "services": [ { "binding": "WORKER_SELF_REFERENCE", - "service": "gitbook-open-v2-preview" - } + "service": "gitbook-open-v2-preview", + }, ], "durable_objects": { "bindings": [ { "name": "NEXT_CACHE_DO_QUEUE", - "class_name": "DOQueueHandler" + "class_name": "DOQueueHandler", }, { "name": "NEXT_TAG_CACHE_DO_SHARDED", - "class_name": "DOShardedTagCache" + "class_name": "DOShardedTagCache", }, { "name": "WRITE_BUFFER", - "class_name": "R2WriteBuffer" - } - ] + "class_name": "R2WriteBuffer", + }, + ], }, "migrations": [ { "tag": "v1", - "new_sqlite_classes": ["DOQueueHandler", "DOShardedTagCache", "R2WriteBuffer"] - } - ] + "new_sqlite_classes": ["DOQueueHandler", "DOShardedTagCache", "R2WriteBuffer"], + }, + ], }, "staging": { "vars": { "STAGE": "staging", - "NEXT_CACHE_DO_QUEUE_DISABLE_SQLITE": "true" + "NEXT_CACHE_DO_QUEUE_DISABLE_SQLITE": "true", }, "r2_buckets": [ { "binding": "NEXT_INC_CACHE_R2_BUCKET", - "bucket_name": "gitbook-open-v2-cache-staging" - } + "bucket_name": "gitbook-open-v2-cache-staging", + }, ], "tail_consumers": [ { - "service": "gitbook-x-staging-tail" - } + "service": "gitbook-x-staging-tail", + }, ], "services": [ { "binding": "WORKER_SELF_REFERENCE", - "service": "gitbook-open-v2-staging" - } + "service": "gitbook-open-v2-staging", + }, ], "durable_objects": { "bindings": [ { "name": "NEXT_CACHE_DO_QUEUE", - "class_name": "DOQueueHandler" + "class_name": "DOQueueHandler", }, { "name": "NEXT_TAG_CACHE_DO_SHARDED", - "class_name": "DOShardedTagCache" + "class_name": "DOShardedTagCache", }, { "name": "WRITE_BUFFER", - "class_name": "R2WriteBuffer" - } - ] + "class_name": "R2WriteBuffer", + }, + ], }, "migrations": [ { "tag": "v1", - "new_sqlite_classes": ["DOQueueHandler", "DOShardedTagCache", "R2WriteBuffer"] - } - ] + "new_sqlite_classes": ["DOQueueHandler", "DOShardedTagCache", "R2WriteBuffer"], + }, + ], }, "production": { "vars": { @@ -104,47 +104,47 @@ // We don't want to pollute the memory with broken cache entries // Most of the time, those are fake requests. "NEXT_CACHE_DO_QUEUE_MAX_RETRIES": "1", - "STAGE": "production" + "STAGE": "production", }, "r2_buckets": [ { "binding": "NEXT_INC_CACHE_R2_BUCKET", - "bucket_name": "gitbook-open-v2-cache-production" - } + "bucket_name": "gitbook-open-v2-cache-production", + }, ], "tail_consumers": [ { - "service": "gitbook-x-prod-tail" - } + "service": "gitbook-x-prod-tail", + }, ], "services": [ { "binding": "WORKER_SELF_REFERENCE", - "service": "gitbook-open-v2-production" - } + "service": "gitbook-open-v2-production", + }, ], "durable_objects": { "bindings": [ { "name": "NEXT_CACHE_DO_QUEUE", - "class_name": "DOQueueHandler" + "class_name": "DOQueueHandler", }, { "name": "NEXT_TAG_CACHE_DO_SHARDED", - "class_name": "DOShardedTagCache" + "class_name": "DOShardedTagCache", }, { "name": "WRITE_BUFFER", - "class_name": "R2WriteBuffer" - } - ] + "class_name": "R2WriteBuffer", + }, + ], }, "migrations": [ { "tag": "v1", - "new_sqlite_classes": ["DOQueueHandler", "DOShardedTagCache", "R2WriteBuffer"] - } - ] - } - } + "new_sqlite_classes": ["DOQueueHandler", "DOShardedTagCache", "R2WriteBuffer"], + }, + ], + }, + }, } diff --git a/packages/gitbook/openNext/customWorkers/middleware.js b/packages/gitbook/openNext/customWorkers/middleware.js index e6fc2f751..0a519d278 100644 --- a/packages/gitbook/openNext/customWorkers/middleware.js +++ b/packages/gitbook/openNext/customWorkers/middleware.js @@ -1,6 +1,6 @@ import { WorkerEntrypoint } from 'cloudflare:workers'; -import { runWithCloudflareRequestContext } from '../../.open-next/cloudflare/init.js'; +import { runWithCloudflareRequestContext } from '../../.open-next/cloudflare/init.js'; import { handler as middlewareHandler } from '../../.open-next/middleware/handler.mjs'; export { DOQueueHandler } from '../../.open-next/.build/durable-objects/queue.js'; @@ -38,7 +38,7 @@ export default class extends WorkerEntrypoint { reqOrResp.headers.get('x-opennext-cache') ?? 'MISS', getResolvedRoute(reqOrResp, 'middleware') ); - // biome-ignore lint/suspicious/noConsole: + // oxlint-disable-next-line no-console console.log(logMessage); return reqOrResp; } @@ -61,7 +61,7 @@ export default class extends WorkerEntrypoint { `SERVER-${response.headers.get('x-nextjs-cache') ?? 'MISS'}`, getResolvedRoute(reqOrResp, 'unresolved') ); - // biome-ignore lint/suspicious/noConsole: + // oxlint-disable-next-line no-console console.log(formatedLog); return response; diff --git a/packages/gitbook/openNext/customWorkers/middlewareWrangler.jsonc b/packages/gitbook/openNext/customWorkers/middlewareWrangler.jsonc index 563aa689b..9e08e264d 100644 --- a/packages/gitbook/openNext/customWorkers/middlewareWrangler.jsonc +++ b/packages/gitbook/openNext/customWorkers/middlewareWrangler.jsonc @@ -6,17 +6,17 @@ "compatibility_flags": [ "nodejs_compat", "allow_importable_env", - "global_fetch_strictly_public" + "global_fetch_strictly_public", ], "observability": { - "enabled": false + "enabled": false, }, "assets": { "directory": "../../.open-next/assets", - "binding": "ASSETS" + "binding": "ASSETS", }, "vars": { - "NEXT_CACHE_DO_QUEUE_DISABLE_SQLITE": "true" + "NEXT_CACHE_DO_QUEUE_DISABLE_SQLITE": "true", }, "env": { "dev": { @@ -27,129 +27,129 @@ // we should just bypass the cache to go to the server directly "SHOULD_BYPASS_CACHE": "true", "OPEN_NEXT_REQUEST_ID_HEADER": "true", - "GITBOOK_URL": "http://localhost:8771" + "GITBOOK_URL": "http://localhost:8771", }, "r2_buckets": [ { "binding": "NEXT_INC_CACHE_R2_BUCKET", - "bucket_name": "gitbook-open-v2-cache-preview" - } + "bucket_name": "gitbook-open-v2-cache-preview", + }, ], "services": [ { "binding": "WORKER_SELF_REFERENCE", - "service": "gitbook-open-v2-dev" + "service": "gitbook-open-v2-dev", }, { "binding": "DEFAULT_WORKER", - "service": "gitbook-open-v2-server-dev" - } - ] + "service": "gitbook-open-v2-server-dev", + }, + ], }, "preview": { "vars": { "STAGE": "preview", "PREVIEW_HOSTNAME": "TO_REPLACE", - "WORKER_VERSION_ID": "TO_REPLACE" + "WORKER_VERSION_ID": "TO_REPLACE", }, "r2_buckets": [ { "binding": "NEXT_INC_CACHE_R2_BUCKET", - "bucket_name": "gitbook-open-v2-cache-preview" - } + "bucket_name": "gitbook-open-v2-cache-preview", + }, ], "services": [ { "binding": "WORKER_SELF_REFERENCE", - "service": "gitbook-open-v2-preview" + "service": "gitbook-open-v2-preview", }, { "binding": "DEFAULT_WORKER", - "service": "gitbook-open-v2-server-preview" - } + "service": "gitbook-open-v2-server-preview", + }, ], "durable_objects": { "bindings": [ { "name": "WRITE_BUFFER", "class_name": "R2WriteBuffer", - "script_name": "gitbook-open-v2-do-preview" + "script_name": "gitbook-open-v2-do-preview", }, { "name": "NEXT_TAG_CACHE_DO_SHARDED", "class_name": "DOShardedTagCache", - "script_name": "gitbook-open-v2-do-preview" + "script_name": "gitbook-open-v2-do-preview", }, { "name": "NEXT_CACHE_DO_QUEUE", "class_name": "DOQueueHandler", - "script_name": "gitbook-open-v2-do-preview" - } - ] - } + "script_name": "gitbook-open-v2-do-preview", + }, + ], + }, }, "staging": { "vars": { "STAGE": "staging", "WORKER_VERSION_ID": "TO_REPLACE", - "OPEN_NEXT_REQUEST_ID_HEADER": "true" + "OPEN_NEXT_REQUEST_ID_HEADER": "true", }, "routes": [ { "pattern": "open-2c.gitbook-staging.com/*", - "zone_name": "gitbook-staging.com" + "zone_name": "gitbook-staging.com", }, { "pattern": "static-2c.gitbook-staging.com/*", - "zone_name": "gitbook-staging.com" - } + "zone_name": "gitbook-staging.com", + }, ], "r2_buckets": [ { "binding": "NEXT_INC_CACHE_R2_BUCKET", - "bucket_name": "gitbook-open-v2-cache-staging" - } + "bucket_name": "gitbook-open-v2-cache-staging", + }, ], "services": [ { "binding": "WORKER_SELF_REFERENCE", - "service": "gitbook-open-v2-staging" + "service": "gitbook-open-v2-staging", }, { "binding": "DEFAULT_WORKER", - "service": "gitbook-open-v2-server-staging" - } + "service": "gitbook-open-v2-server-staging", + }, ], "tail_consumers": [ { - "service": "gitbook-x-staging-tail" - } + "service": "gitbook-x-staging-tail", + }, ], "durable_objects": { "bindings": [ { "name": "WRITE_BUFFER", "class_name": "R2WriteBuffer", - "script_name": "gitbook-open-v2-do-staging" + "script_name": "gitbook-open-v2-do-staging", }, { "name": "NEXT_TAG_CACHE_DO_SHARDED", "class_name": "DOShardedTagCache", - "script_name": "gitbook-open-v2-do-staging" + "script_name": "gitbook-open-v2-do-staging", }, { "name": "NEXT_CACHE_DO_QUEUE", "class_name": "DOQueueHandler", - "script_name": "gitbook-open-v2-do-staging" - } - ] + "script_name": "gitbook-open-v2-do-staging", + }, + ], }, "migrations": [ { "tag": "v1", - "new_sqlite_classes": ["DOQueueHandler", "DOShardedTagCache"] - } - ] + "new_sqlite_classes": ["DOQueueHandler", "DOShardedTagCache"], + }, + ], }, "production": { "vars": { @@ -161,64 +161,64 @@ "DEBUG_CLOUDFLARE": "true", "WORKER_VERSION_ID": "TO_REPLACE", "STAGE": "production", - "OPEN_NEXT_REQUEST_ID_HEADER": "true" + "OPEN_NEXT_REQUEST_ID_HEADER": "true", }, "routes": [ { "pattern": "open-2c.gitbook.com/*", - "zone_name": "gitbook.com" + "zone_name": "gitbook.com", }, { "pattern": "static-2c.gitbook.com/*", - "zone_name": "gitbook.com" - } + "zone_name": "gitbook.com", + }, ], "r2_buckets": [ { "binding": "NEXT_INC_CACHE_R2_BUCKET", - "bucket_name": "gitbook-open-v2-cache-production" - } + "bucket_name": "gitbook-open-v2-cache-production", + }, ], "services": [ { "binding": "WORKER_SELF_REFERENCE", - "service": "gitbook-open-v2-production" + "service": "gitbook-open-v2-production", }, { "binding": "DEFAULT_WORKER", - "service": "gitbook-open-v2-server-production" - } + "service": "gitbook-open-v2-server-production", + }, ], "tail_consumers": [ { - "service": "gitbook-x-prod-tail" - } + "service": "gitbook-x-prod-tail", + }, ], "durable_objects": { "bindings": [ { "name": "WRITE_BUFFER", "class_name": "R2WriteBuffer", - "script_name": "gitbook-open-v2-do-production" + "script_name": "gitbook-open-v2-do-production", }, { "name": "NEXT_TAG_CACHE_DO_SHARDED", "class_name": "DOShardedTagCache", - "script_name": "gitbook-open-v2-do-production" + "script_name": "gitbook-open-v2-do-production", }, { "name": "NEXT_CACHE_DO_QUEUE", "class_name": "DOQueueHandler", - "script_name": "gitbook-open-v2-do-production" - } - ] + "script_name": "gitbook-open-v2-do-production", + }, + ], }, "migrations": [ { "tag": "v1", - "new_sqlite_classes": ["DOQueueHandler", "DOShardedTagCache"] - } - ] - } - } + "new_sqlite_classes": ["DOQueueHandler", "DOShardedTagCache"], + }, + ], + }, + }, } diff --git a/packages/gitbook/openNext/incrementalCache/incrementalCache.ts b/packages/gitbook/openNext/incrementalCache/incrementalCache.ts index 11c0f8977..550c355ea 100644 --- a/packages/gitbook/openNext/incrementalCache/incrementalCache.ts +++ b/packages/gitbook/openNext/incrementalCache/incrementalCache.ts @@ -1,4 +1,4 @@ -import { createHash } from 'node:crypto'; +import type { DurableObjectNamespace, Rpc } from '@cloudflare/workers-types'; import type { CacheEntryType, CacheValue, @@ -6,8 +6,7 @@ import type { WithLastModified, } from '@opennextjs/aws/types/overrides.js'; import { getCloudflareContext } from '@opennextjs/cloudflare'; - -import type { DurableObjectNamespace, Rpc } from '@cloudflare/workers-types'; +import { createHash } from 'node:crypto'; export const BINDING_NAME = 'NEXT_INC_CACHE_R2_BUCKET'; export const DEFAULT_PREFIX = 'incremental-cache'; diff --git a/packages/gitbook/openNext/incrementalCache/middleware.ts b/packages/gitbook/openNext/incrementalCache/middleware.ts index 0f37e6563..2d116ec2b 100644 --- a/packages/gitbook/openNext/incrementalCache/middleware.ts +++ b/packages/gitbook/openNext/incrementalCache/middleware.ts @@ -1,4 +1,5 @@ import { withRegionalCache } from '@opennextjs/cloudflare/overrides/incremental-cache/regional-cache'; + import { GitbookIncrementalCache } from './incrementalCache'; export default withRegionalCache(new GitbookIncrementalCache(), { diff --git a/packages/gitbook/openNext/incrementalCache/server.ts b/packages/gitbook/openNext/incrementalCache/server.ts index 3b32d7580..359920de7 100644 --- a/packages/gitbook/openNext/incrementalCache/server.ts +++ b/packages/gitbook/openNext/incrementalCache/server.ts @@ -1,4 +1,5 @@ import { withRegionalCache } from '@opennextjs/cloudflare/overrides/incremental-cache/regional-cache'; + import { GitbookIncrementalCache } from './incrementalCache'; // We cannot have regional cache only in the middleware, otherwise it will override things on cache miss diff --git a/packages/gitbook/openNext/queue/server.ts b/packages/gitbook/openNext/queue/server.ts index 9e3756748..a0c6fd3da 100644 --- a/packages/gitbook/openNext/queue/server.ts +++ b/packages/gitbook/openNext/queue/server.ts @@ -1,6 +1,7 @@ -import { getLogger } from '@/lib/logger'; import type { Queue } from '@opennextjs/aws/types/overrides.js'; +import { getLogger } from '@/lib/logger'; + export default { name: 'GitbookISRQueue', send: async (msg) => { diff --git a/packages/gitbook/openNext/tagCache/middleware.ts b/packages/gitbook/openNext/tagCache/middleware.ts index eca3d0cde..6b26d0d1e 100644 --- a/packages/gitbook/openNext/tagCache/middleware.ts +++ b/packages/gitbook/openNext/tagCache/middleware.ts @@ -1,8 +1,9 @@ -import { createLogger, getLogger } from '@/lib/logger'; import type { NextModeTagCache } from '@opennextjs/aws/types/overrides.js'; import doShardedTagCache from '@opennextjs/cloudflare/overrides/tag-cache/do-sharded-tag-cache'; import { softTagFilter } from '@opennextjs/cloudflare/overrides/tag-cache/tag-cache-filter'; +import { createLogger, getLogger } from '@/lib/logger'; + const originalTagCache = doShardedTagCache({ baseShardSize: 12, regionalCache: true, diff --git a/packages/gitbook/package.json b/packages/gitbook/package.json index 127aaf61c..5ac494f75 100644 --- a/packages/gitbook/package.json +++ b/packages/gitbook/package.json @@ -3,6 +3,7 @@ "version": "0.27.2", "private": true, "dependencies": { + "@base-ui/react": "catalog:", "@cloudflare/workers-types": "^4.20251011.0", "@gitbook/api": "catalog:", "@gitbook/browser-types": "workspace:*", @@ -22,13 +23,6 @@ "@opennextjs/aws": "4.1.0", "@opennextjs/cloudflare": "1.20.2", "@panzoom/panzoom": "^4.6.1", - "@radix-ui/react-checkbox": "^1.0.4", - "@radix-ui/react-collapsible": "^1.1.12", - "@radix-ui/react-dropdown-menu": "^2.1.12", - "@radix-ui/react-hover-card": "^1.1.15", - "@radix-ui/react-navigation-menu": "^1.2.3", - "@radix-ui/react-popover": "^1.0.7", - "@radix-ui/react-tooltip": "^1.1.8", "@sindresorhus/fnv1a": "^3.1.0", "@tailwindcss/container-queries": "^0.1.1", "@tusbar/cache-control": "^1.0.2", @@ -67,7 +61,6 @@ "p-retry": "^8.0.0", "quick-lru": "^7.0.1", "react": "19.2.4", - "react-aria": "^3.44.0", "react-dom": "19.2.4", "react-hotkeys-hook": "^4.4.1", "rehype-raw": "^7.0.0", @@ -131,6 +124,7 @@ "build": "bun run generate:assets && next build --webpack", "build:local": "bun run generate:assets && GITBOOK_URL=http://localhost:3000 next build --webpack", "check:css-browser-compatibility": "bun scripts/check-css-browser-compatibility.ts", + "check:css-browser-compatibility:local": "bun run check:css-browser-compatibility --local origin/main", "start": "GITBOOK_URL=http://localhost:3000 next start", "build:cloudflare": "bun run generate:assets && GITBOOK_RUNTIME=cloudflare opennextjs-cloudflare build", "dev:cloudflare": "wrangler dev --port 8771 --env preview", @@ -139,6 +133,7 @@ "profile:cf:memory": "bun run build:cloudflare && bun ./scripts/profile-opennext-memory.ts", "e2e": "playwright test e2e/internal.spec.ts e2e/cookie-banner.spec.ts e2e/pdf.spec.ts e2e/select.spec.ts --project=chromium", "e2e-customers": "playwright test e2e/customers.spec.ts --project=chromium", + "e2e-style-perf": "playwright test e2e/style-perf.spec.ts --project=chromium --reporter=list", "unit": "bun run generate:assets && bun test {src,packages} --preload ./tests/preload-bun.ts", "e2e-browserless": "bun test ./tests/", "typecheck": "tsc --noEmit" diff --git a/packages/gitbook/scripts/check-css-browser-compatibility.ts b/packages/gitbook/scripts/check-css-browser-compatibility.ts index 2714f8034..87d3d48df 100644 --- a/packages/gitbook/scripts/check-css-browser-compatibility.ts +++ b/packages/gitbook/scripts/check-css-browser-compatibility.ts @@ -1,10 +1,10 @@ +import { execFileSync } from 'node:child_process'; import { readFile } from 'node:fs/promises'; +import { join } from 'node:path'; + import { type CompatibilityDiagnostic, - type IssueCommentClient, - formatCompatibilityComment, getCompatibilityDiagnostics, - upsertCompatibilityComment, } from '../src/lib/cssBrowserCompatibility'; interface PullRequestEvent { @@ -32,12 +32,6 @@ interface GitBlobResponse { encoding: string; } -interface IssueComment { - body: string; - id: number; - user: { login: string } | null; -} - class GitHubRequestError extends Error { constructor( readonly status: number, @@ -47,7 +41,7 @@ class GitHubRequestError extends Error { } } -class GitHubApi implements IssueCommentClient { +class GitHubApi { constructor( private readonly repository: string, private readonly token: string @@ -113,34 +107,6 @@ class GitHubApi implements IssueCommentClient { async getFileAtRef(path: string, ref: string): Promise { return this.getContent(path, ref); } - - async listIssueComments(issueNumber: number): Promise { - const comments: IssueComment[] = []; - - for (let page = 1; ; page += 1) { - const result = await this.request( - `/repos/${this.repository}/issues/${issueNumber}/comments?per_page=100&page=${page}` - ); - comments.push(...result); - if (result.length < 100) { - return comments; - } - } - } - - async createIssueComment(issueNumber: number, body: string): Promise { - await this.request(`/repos/${this.repository}/issues/${issueNumber}/comments`, { - body: JSON.stringify({ body }), - method: 'POST', - }); - } - - async updateIssueComment(commentId: number, body: string): Promise { - await this.request(`/repos/${this.repository}/issues/comments/${commentId}`, { - body: JSON.stringify({ body }), - method: 'PATCH', - }); - } } async function getBrowserslist(api: GitHubApi, headSha: string): Promise { @@ -174,6 +140,83 @@ async function getBaseContent( } } +function report(diagnostics: CompatibilityDiagnostic[]): boolean { + if (diagnostics.length === 0) { + console.log('CSS browser compatibility check passed.'); + return true; + } + + console.error( + `${diagnostics.length} newly added CSS declaration(s) are not fully supported by the configured Browserslist targets:` + ); + for (const diagnostic of diagnostics) { + // Workflow command so the failure is annotated on the PR diff. + console.error( + `::error file=${diagnostic.file},line=${diagnostic.line},col=${diagnostic.column}::${diagnostic.property} is not supported by ${diagnostic.unsupportedBrowsers}` + ); + } + return false; +} + +/** Same check as CI, but against a local `git diff` instead of the GitHub API. */ +async function runLocal(baseRef: string): Promise { + const git = (...args: string[]) => + execFileSync('git', args, { encoding: 'utf8', maxBuffer: 64 * 1024 * 1024 }); + const root = git('rev-parse', '--show-toplevel').trim(); + const mergeBase = git('merge-base', baseRef, 'HEAD').trim(); + const browsers = ( + JSON.parse(await readFile(join(root, 'packages/gitbook/package.json'), 'utf8')) as { + browserslist?: string[]; + } + ).browserslist; + + if (!browsers?.length) { + throw new Error('packages/gitbook/package.json must define a Browserslist configuration.'); + } + + // Working tree, so uncommitted changes are checked too. + const changes = git( + 'diff', + '--name-status', + '--find-renames', + '--diff-filter=ACMR', + mergeBase, + '--', + '*.css' + ) + .split('\n') + .filter(Boolean) + .map((line) => { + const [status, ...paths] = line.split('\t'); + const previousPath = paths.length > 1 ? paths[0] : undefined; + const path = paths.at(-1) as string; + return { added: status?.startsWith('A'), path, previousPath }; + }); + + const diagnostics: CompatibilityDiagnostic[] = []; + for (const change of changes) { + let base = ''; + if (!change.added) { + try { + base = git('show', `${mergeBase}:${change.previousPath ?? change.path}`); + } catch { + base = ''; + } + } + diagnostics.push( + ...(await getCompatibilityDiagnostics({ + base, + browsers, + file: change.path, + head: await readFile(join(root, change.path), 'utf8'), + })) + ); + } + + console.log(`Checked ${changes.length} changed CSS file(s) against ${baseRef}.`); + return report(diagnostics); +} + async function run(): Promise { const token = process.env.GITHUB_TOKEN; const repository = process.env.GITHUB_REPOSITORY; @@ -211,34 +254,19 @@ async function run(): Promise { ); } - const comment = formatCompatibilityComment({ - diagnostics, - headSha: pullRequest.head.sha, - repository, - }); - await upsertCompatibilityComment({ - body: comment, - createIfMissing: diagnostics.length > 0, - client: api, - issueNumber: pullRequest.number, - }); - - if (diagnostics.length === 0) { - console.log('CSS browser compatibility check passed.'); - return true; - } - - console.error('Unsupported CSS declarations found:'); - for (const diagnostic of diagnostics) { - console.error( - `${diagnostic.file}:${diagnostic.line} ${diagnostic.property} — ${diagnostic.unsupportedBrowsers}` - ); - } - return false; + return report(diagnostics); } +const localFlagIndex = process.argv.indexOf('--local'); + try { - process.exitCode = (await run()) ? 0 : 1; + let success: boolean; + if (localFlagIndex === -1) { + success = await run(); + } else { + success = await runLocal(process.argv[localFlagIndex + 1] ?? 'origin/main'); + } + process.exitCode = success ? 0 : 1; } catch (error) { console.error(error); process.exitCode = 1; diff --git a/packages/gitbook/scripts/generate-mermaid-runtime.ts b/packages/gitbook/scripts/generate-mermaid-runtime.ts index 3c452b969..f7dd914cb 100644 --- a/packages/gitbook/scripts/generate-mermaid-runtime.ts +++ b/packages/gitbook/scripts/generate-mermaid-runtime.ts @@ -1,8 +1,8 @@ +import { build } from 'bun'; import { mkdir, rename, rm } from 'node:fs/promises'; import { createRequire } from 'node:module'; import { dirname, join } from 'node:path'; import { fileURLToPath } from 'node:url'; -import { build } from 'bun'; import { MERMAID_RUNTIME_PATH } from '../src/components/DocumentView/CodeBlock/mermaid-runtime-path'; diff --git a/packages/gitbook/scripts/generate-scalar-runtime.ts b/packages/gitbook/scripts/generate-scalar-runtime.ts index 6495469f5..ab2eee91b 100644 --- a/packages/gitbook/scripts/generate-scalar-runtime.ts +++ b/packages/gitbook/scripts/generate-scalar-runtime.ts @@ -1,8 +1,8 @@ +import { build } from 'bun'; import { mkdir, rename, rm } from 'node:fs/promises'; import { createRequire } from 'node:module'; import { dirname, join } from 'node:path'; import { fileURLToPath } from 'node:url'; -import { build } from 'bun'; import { SCALAR_RUNTIME_PATH } from '../src/components/DocumentView/OpenAPI/scalar-runtime-path'; diff --git a/packages/gitbook/scripts/profile-opennext-memory.ts b/packages/gitbook/scripts/profile-opennext-memory.ts index 9cc538e6e..77ef84a86 100644 --- a/packages/gitbook/scripts/profile-opennext-memory.ts +++ b/packages/gitbook/scripts/profile-opennext-memory.ts @@ -1,7 +1,7 @@ +import { file, sleep, spawn } from 'bun'; import { stat } from 'node:fs/promises'; import { createConnection } from 'node:net'; import { join } from 'node:path'; -import { file, sleep, spawn } from 'bun'; import WebSocket from 'ws'; type HeapUsage = { @@ -60,7 +60,7 @@ try { const afterLoad = await getMeasurements(); const bundle = await getBundleMetrics(); - // biome-ignore lint/suspicious/noConsole: JSON on stdout is this script's public interface. + // oxlint-disable-next-line no-console -- JSON on stdout is this script's public interface. console.log( JSON.stringify( { diff --git a/packages/gitbook/src/app/global-error.tsx b/packages/gitbook/src/app/global-error.tsx index abf0186a4..5242e8c8c 100644 --- a/packages/gitbook/src/app/global-error.tsx +++ b/packages/gitbook/src/app/global-error.tsx @@ -2,11 +2,7 @@ import NextError from 'next/error'; -export default function GlobalError({ - error, -}: { - error: Error & { digest?: string }; -}) { +export default function GlobalError({ error }: { error: Error & { digest?: string } }) { console.error('Global error:', error); return ( diff --git a/packages/gitbook/src/app/sites/dynamic/[mode]/[siteURL]/[siteData]/(content)/[pagePath]/page.tsx b/packages/gitbook/src/app/sites/dynamic/[mode]/[siteURL]/[siteData]/(content)/[pagePath]/page.tsx index 8f426d7f4..3e30c573e 100644 --- a/packages/gitbook/src/app/sites/dynamic/[mode]/[siteURL]/[siteData]/(content)/[pagePath]/page.tsx +++ b/packages/gitbook/src/app/sites/dynamic/[mode]/[siteURL]/[siteData]/(content)/[pagePath]/page.tsx @@ -1,10 +1,11 @@ +import type { Metadata, Viewport } from 'next'; + import { type RouteParams, getDynamicSiteContext, getPagePathFromParams } from '@/app/utils'; import { SitePage, generateSitePageMetadata, generateSitePageViewport, } from '@/components/SitePage'; -import type { Metadata, Viewport } from 'next'; type PageProps = { params: Promise; diff --git a/packages/gitbook/src/app/sites/dynamic/[mode]/[siteURL]/[siteData]/(content)/layout.tsx b/packages/gitbook/src/app/sites/dynamic/[mode]/[siteURL]/[siteData]/(content)/layout.tsx index aa267b964..7129cfba1 100644 --- a/packages/gitbook/src/app/sites/dynamic/[mode]/[siteURL]/[siteData]/(content)/layout.tsx +++ b/packages/gitbook/src/app/sites/dynamic/[mode]/[siteURL]/[siteData]/(content)/layout.tsx @@ -1,3 +1,5 @@ +import { headers } from 'next/headers'; + import { type RouteLayoutParams, getDynamicSiteContext } from '@/app/utils'; import { CustomizationRootLayout } from '@/components/RootLayout'; import { @@ -7,7 +9,6 @@ import { } from '@/components/SiteLayout'; import { getThemeFromMiddleware } from '@/lib/middleware'; import { shouldTrackEvents } from '@/lib/tracking'; -import { headers } from 'next/headers'; interface SiteDynamicLayoutProps { params: Promise; diff --git a/packages/gitbook/src/app/sites/dynamic/[mode]/[siteURL]/[siteData]/~gitbook/auth/login/route.ts b/packages/gitbook/src/app/sites/dynamic/[mode]/[siteURL]/[siteData]/~gitbook/auth/login/route.ts index 3e2362db8..c6bbf09aa 100644 --- a/packages/gitbook/src/app/sites/dynamic/[mode]/[siteURL]/[siteData]/~gitbook/auth/login/route.ts +++ b/packages/gitbook/src/app/sites/dynamic/[mode]/[siteURL]/[siteData]/~gitbook/auth/login/route.ts @@ -1,7 +1,9 @@ -import { type RouteLayoutParams, getDynamicSiteContext } from '@/app/utils'; import type { NextRequest } from 'next/server'; import { NextResponse } from 'next/server'; +import { type RouteLayoutParams, getDynamicSiteContext } from '@/app/utils'; +import { resolveUpstreamAuthURL } from '@/lib/site-auth-urls'; + /** * Redirect to the upstream auth provider login URL of site, or to the site root when not configured. */ @@ -11,20 +13,10 @@ export async function GET( ) { const { context } = await getDynamicSiteContext(await params); const noLoginFallbackURL = context.linker.toAbsoluteURL(context.linker.toPathInSite('')); + const loginURL = resolveUpstreamAuthURL({ + siteAuthURL: context.site.urls.login, + location: request.nextUrl.searchParams.get('location'), + }); - if (!context.site.urls.login) { - return NextResponse.redirect(noLoginFallbackURL); - } - - try { - const loginURL = new URL(context.site.urls.login); - const location = request.nextUrl.searchParams.get('location'); - if (location) { - loginURL.searchParams.set('location', location); - } - - return NextResponse.redirect(loginURL); - } catch (_error) { - return NextResponse.redirect(noLoginFallbackURL); - } + return NextResponse.redirect(loginURL ?? noLoginFallbackURL); } diff --git a/packages/gitbook/src/app/sites/dynamic/[mode]/[siteURL]/[siteData]/~gitbook/auth/logout/route.ts b/packages/gitbook/src/app/sites/dynamic/[mode]/[siteURL]/[siteData]/~gitbook/auth/logout/route.ts index e3714719d..ee8750daf 100644 --- a/packages/gitbook/src/app/sites/dynamic/[mode]/[siteURL]/[siteData]/~gitbook/auth/logout/route.ts +++ b/packages/gitbook/src/app/sites/dynamic/[mode]/[siteURL]/[siteData]/~gitbook/auth/logout/route.ts @@ -1,16 +1,19 @@ +import { cookies } from 'next/headers'; +import type { NextRequest } from 'next/server'; +import { NextResponse } from 'next/server'; + import { type RouteLayoutParams, getDynamicSiteContext, getSiteURLDataFromParams, } from '@/app/utils'; import { getVisitorAuthBasePath } from '@/lib/data'; +import { resolveUpstreamAuthURL } from '@/lib/site-auth-urls'; import { getVisitorAuthCookieName } from '@/lib/visitors'; -import { cookies } from 'next/headers'; -import type { NextRequest } from 'next/server'; -import { NextResponse } from 'next/server'; /** - * Clear the site-scoped auth session cookies and redirect to the site root. + * Clear the site-scoped auth session cookies and redirect to the upstream auth provider + * logout URL of the site, or to the site root when not configured. */ export async function GET( request: NextRequest, @@ -29,8 +32,14 @@ export async function GET( ) ); - // TODO: Redirect to the site root for now. Once the API supports it, - // optionally redirect to a logoutURL (e.g when needing to logout from upstream auth too) - // when defined in visitor auth settings. - return NextResponse.redirect(context.linker.toAbsoluteURL(context.linker.toPathInSite(''))); + const noLogoutFallbackURL = context.linker.toAbsoluteURL(context.linker.toPathInSite('')); + const logoutURL = resolveUpstreamAuthURL({ + siteAuthURL: context.site.urls.logout, + // Default the location to the site root, so the upstream logout can send the visitor back + // to the site. On a site behind visitor auth, coming back re-enters the login flow and + // surfaces the upstream login page, as the visitor no longer has a session on either side. + location: request.nextUrl.searchParams.get('location') ?? '/', + }); + + return NextResponse.redirect(logoutURL ?? noLogoutFallbackURL); } diff --git a/packages/gitbook/src/app/sites/dynamic/[mode]/[siteURL]/[siteData]/~gitbook/embed/assistant/page.tsx b/packages/gitbook/src/app/sites/dynamic/[mode]/[siteURL]/[siteData]/~gitbook/embed/assistant/page.tsx index 274f55334..0eead01ec 100644 --- a/packages/gitbook/src/app/sites/dynamic/[mode]/[siteURL]/[siteData]/~gitbook/embed/assistant/page.tsx +++ b/packages/gitbook/src/app/sites/dynamic/[mode]/[siteURL]/[siteData]/~gitbook/embed/assistant/page.tsx @@ -1,8 +1,9 @@ +import { redirect } from 'next/navigation'; + import type { RouteLayoutParams } from '@/app/utils'; import { EmbeddableAssistantPage } from '@/components/Embeddable'; import { isAIChatEnabled } from '@/components/utils/isAIChatEnabled'; import { getEmbeddableDynamicContext } from '@/lib/embeddable'; -import { redirect } from 'next/navigation'; type PageProps = { params: Promise; diff --git a/packages/gitbook/src/app/sites/dynamic/[mode]/[siteURL]/[siteData]/~gitbook/embed/layout.tsx b/packages/gitbook/src/app/sites/dynamic/[mode]/[siteURL]/[siteData]/~gitbook/embed/layout.tsx index 349844fd5..f9e709952 100644 --- a/packages/gitbook/src/app/sites/dynamic/[mode]/[siteURL]/[siteData]/~gitbook/embed/layout.tsx +++ b/packages/gitbook/src/app/sites/dynamic/[mode]/[siteURL]/[siteData]/~gitbook/embed/layout.tsx @@ -1,3 +1,5 @@ +import { headers } from 'next/headers'; + import type { RouteLayoutParams } from '@/app/utils'; import { EmbeddableRootLayout, @@ -7,7 +9,6 @@ import { import { getEmbeddableStaticContext } from '@/lib/embeddable'; import { getThemeFromMiddleware } from '@/lib/middleware'; import { shouldTrackEvents } from '@/lib/tracking'; -import { headers } from 'next/headers'; interface SiteStaticLayoutProps { params: Promise; diff --git a/packages/gitbook/src/app/sites/dynamic/[mode]/[siteURL]/[siteData]/~gitbook/embed/page.tsx b/packages/gitbook/src/app/sites/dynamic/[mode]/[siteURL]/[siteData]/~gitbook/embed/page.tsx index 4abe02997..fd11d6d04 100644 --- a/packages/gitbook/src/app/sites/dynamic/[mode]/[siteURL]/[siteData]/~gitbook/embed/page.tsx +++ b/packages/gitbook/src/app/sites/dynamic/[mode]/[siteURL]/[siteData]/~gitbook/embed/page.tsx @@ -1,7 +1,8 @@ +import { redirect } from 'next/navigation'; + import type { RouteLayoutParams } from '@/app/utils'; import { isAIChatEnabled } from '@/components/utils/isAIChatEnabled'; import { getEmbeddableDynamicContext } from '@/lib/embeddable'; -import { redirect } from 'next/navigation'; type PageProps = { params: Promise; diff --git a/packages/gitbook/src/app/sites/dynamic/[mode]/[siteURL]/[siteData]/~gitbook/embed/page/[pagePath]/page.tsx b/packages/gitbook/src/app/sites/dynamic/[mode]/[siteURL]/[siteData]/~gitbook/embed/page/[pagePath]/page.tsx index 28774e02d..991194cd0 100644 --- a/packages/gitbook/src/app/sites/dynamic/[mode]/[siteURL]/[siteData]/~gitbook/embed/page/[pagePath]/page.tsx +++ b/packages/gitbook/src/app/sites/dynamic/[mode]/[siteURL]/[siteData]/~gitbook/embed/page/[pagePath]/page.tsx @@ -1,7 +1,8 @@ +import type { Metadata } from 'next'; + import { type RouteParams, getPagePathFromParams } from '@/app/utils'; import { EmbeddableDocsPage, generateEmbeddableDocsPageMetadata } from '@/components/Embeddable'; import { getEmbeddableDynamicContext } from '@/lib/embeddable'; -import type { Metadata } from 'next'; type PageProps = { params: Promise; diff --git a/packages/gitbook/src/app/sites/dynamic/[mode]/[siteURL]/[siteData]/~gitbook/mcp/auth/route.ts b/packages/gitbook/src/app/sites/dynamic/[mode]/[siteURL]/[siteData]/~gitbook/mcp/auth/route.ts index 3fd3c2ccc..28cc86d35 100644 --- a/packages/gitbook/src/app/sites/dynamic/[mode]/[siteURL]/[siteData]/~gitbook/mcp/auth/route.ts +++ b/packages/gitbook/src/app/sites/dynamic/[mode]/[siteURL]/[siteData]/~gitbook/mcp/auth/route.ts @@ -1,6 +1,7 @@ -import type { RouteLayoutParams } from '@/app/utils'; import type { NextRequest } from 'next/server'; + import { handleMcpRequest } from '../handler'; +import type { RouteLayoutParams } from '@/app/utils'; async function handler( rawRequest: NextRequest, diff --git a/packages/gitbook/src/app/sites/dynamic/[mode]/[siteURL]/[siteData]/~gitbook/mcp/handler.ts b/packages/gitbook/src/app/sites/dynamic/[mode]/[siteURL]/[siteData]/~gitbook/mcp/handler.ts index 9ee489665..7c4ca7ee9 100644 --- a/packages/gitbook/src/app/sites/dynamic/[mode]/[siteURL]/[siteData]/~gitbook/mcp/handler.ts +++ b/packages/gitbook/src/app/sites/dynamic/[mode]/[siteURL]/[siteData]/~gitbook/mcp/handler.ts @@ -1,3 +1,7 @@ +import { createMcpHandler } from 'mcp-handler'; +import type { NextRequest } from 'next/server'; +import { z } from 'zod'; + import { CustomizationPageActionType, SiteInsightsDisplayContext } from '@gitbook/api'; import { type RouteLayoutParams, getDynamicSiteContext } from '@/app/utils'; @@ -10,9 +14,6 @@ import { joinPathWithBaseURL } from '@/lib/paths'; import { findSiteSpaceBy, findSiteSpaceByUrl } from '@/lib/sites'; import { trackServerInsightsEvents } from '@/lib/tracking'; import { waitUntil } from '@/lib/waitUntil'; -import { createMcpHandler } from 'mcp-handler'; -import type { NextRequest } from 'next/server'; -import { z } from 'zod'; /** * Fire-and-forget insights tracking for the MCP endpoint. A tracking failure (e.g. a 422 from the diff --git a/packages/gitbook/src/app/sites/dynamic/[mode]/[siteURL]/[siteData]/~gitbook/mcp/route.ts b/packages/gitbook/src/app/sites/dynamic/[mode]/[siteURL]/[siteData]/~gitbook/mcp/route.ts index adce94298..7a9788ee2 100644 --- a/packages/gitbook/src/app/sites/dynamic/[mode]/[siteURL]/[siteData]/~gitbook/mcp/route.ts +++ b/packages/gitbook/src/app/sites/dynamic/[mode]/[siteURL]/[siteData]/~gitbook/mcp/route.ts @@ -1,6 +1,7 @@ -import type { RouteLayoutParams } from '@/app/utils'; import type { NextRequest } from 'next/server'; + import { handleMcpRequest } from './handler'; +import type { RouteLayoutParams } from '@/app/utils'; async function handler( rawRequest: NextRequest, diff --git a/packages/gitbook/src/app/sites/dynamic/[mode]/[siteURL]/[siteData]/~gitbook/pdf/page.tsx b/packages/gitbook/src/app/sites/dynamic/[mode]/[siteURL]/[siteData]/~gitbook/pdf/page.tsx index 6f1c13e03..bede37932 100644 --- a/packages/gitbook/src/app/sites/dynamic/[mode]/[siteURL]/[siteData]/~gitbook/pdf/page.tsx +++ b/packages/gitbook/src/app/sites/dynamic/[mode]/[siteURL]/[siteData]/~gitbook/pdf/page.tsx @@ -1,11 +1,7 @@ import { type RouteLayoutParams, getDynamicSiteContext } from '@/app/utils'; import { PDFPage, generatePDFMetadata } from '@/components/PDF'; -export async function generateMetadata({ - params, -}: { - params: Promise; -}) { +export async function generateMetadata({ params }: { params: Promise }) { const { context } = await getDynamicSiteContext(await params); return generatePDFMetadata(context); } diff --git a/packages/gitbook/src/app/sites/dynamic/[mode]/[siteURL]/[siteData]/~gitbook/search/route.ts b/packages/gitbook/src/app/sites/dynamic/[mode]/[siteURL]/[siteData]/~gitbook/search/route.ts index 24607f468..f0658ab8c 100644 --- a/packages/gitbook/src/app/sites/dynamic/[mode]/[siteURL]/[siteData]/~gitbook/search/route.ts +++ b/packages/gitbook/src/app/sites/dynamic/[mode]/[siteURL]/[siteData]/~gitbook/search/route.ts @@ -1,3 +1,14 @@ +import { type NextRequest, NextResponse } from 'next/server'; + +import type { + SearchPageResult, + SearchSpaceResult, + SiteSection, + SiteSectionGroup, + SiteSpace, +} from '@gitbook/api'; +import type { IconName } from '@gitbook/icons'; + import type { ComputedPageResult, ComputedSectionResult, @@ -10,15 +21,6 @@ import { getSiteURLDataFromMiddleware } from '@/lib/middleware'; import { joinPathWithBaseURL } from '@/lib/paths'; import { getServerActionBaseContext } from '@/lib/server-actions'; import { findSiteSpaceBy, getLocalizedTitle } from '@/lib/sites'; -import type { - SearchPageResult, - SearchSpaceResult, - SiteSection, - SiteSectionGroup, - SiteSpace, -} from '@gitbook/api'; -import type { IconName } from '@gitbook/icons'; -import { type NextRequest, NextResponse } from 'next/server'; export async function POST(request: NextRequest) { const { asEmbeddable, query, scope } = (await request.json()) as SearchSiteContentRequest; diff --git a/packages/gitbook/src/app/sites/static/[mode]/[siteURL]/[siteData]/(content)/[pagePath]/page.tsx b/packages/gitbook/src/app/sites/static/[mode]/[siteURL]/[siteData]/(content)/[pagePath]/page.tsx index 111eaadcd..832b73193 100644 --- a/packages/gitbook/src/app/sites/static/[mode]/[siteURL]/[siteData]/(content)/[pagePath]/page.tsx +++ b/packages/gitbook/src/app/sites/static/[mode]/[siteURL]/[siteData]/(content)/[pagePath]/page.tsx @@ -1,3 +1,5 @@ +import type { Metadata, Viewport } from 'next'; + import { type RouteParams, getPagePathFromParams, getStaticSiteContext } from '@/app/utils'; import { SitePage, @@ -5,8 +7,6 @@ import { generateSitePageViewport, } from '@/components/SitePage'; -import type { Metadata, Viewport } from 'next'; - export const dynamic = 'force-static'; type PageProps = { diff --git a/packages/gitbook/src/app/sites/static/[mode]/[siteURL]/[siteData]/~gitbook/embed/assistant/page.tsx b/packages/gitbook/src/app/sites/static/[mode]/[siteURL]/[siteData]/~gitbook/embed/assistant/page.tsx index b5e5cfa42..0ca3ce09a 100644 --- a/packages/gitbook/src/app/sites/static/[mode]/[siteURL]/[siteData]/~gitbook/embed/assistant/page.tsx +++ b/packages/gitbook/src/app/sites/static/[mode]/[siteURL]/[siteData]/~gitbook/embed/assistant/page.tsx @@ -1,8 +1,9 @@ +import { redirect } from 'next/navigation'; + import type { RouteParams } from '@/app/utils'; import { EmbeddableAssistantPage } from '@/components/Embeddable'; import { isAIChatEnabled } from '@/components/utils/isAIChatEnabled'; import { getEmbeddableStaticContext } from '@/lib/embeddable'; -import { redirect } from 'next/navigation'; export const dynamic = 'force-static'; diff --git a/packages/gitbook/src/app/sites/static/[mode]/[siteURL]/[siteData]/~gitbook/embed/demo/route.ts b/packages/gitbook/src/app/sites/static/[mode]/[siteURL]/[siteData]/~gitbook/embed/demo/route.ts index 381854f03..43330cc1c 100644 --- a/packages/gitbook/src/app/sites/static/[mode]/[siteURL]/[siteData]/~gitbook/embed/demo/route.ts +++ b/packages/gitbook/src/app/sites/static/[mode]/[siteURL]/[siteData]/~gitbook/embed/demo/route.ts @@ -1,6 +1,7 @@ -import { type RouteLayoutParams, getStaticSiteContext } from '@/app/utils'; import type { NextRequest } from 'next/server'; +import { type RouteLayoutParams, getStaticSiteContext } from '@/app/utils'; + export const dynamic = 'force-static'; /** diff --git a/packages/gitbook/src/app/sites/static/[mode]/[siteURL]/[siteData]/~gitbook/embed/page.tsx b/packages/gitbook/src/app/sites/static/[mode]/[siteURL]/[siteData]/~gitbook/embed/page.tsx index 0198f23f2..564c441f5 100644 --- a/packages/gitbook/src/app/sites/static/[mode]/[siteURL]/[siteData]/~gitbook/embed/page.tsx +++ b/packages/gitbook/src/app/sites/static/[mode]/[siteURL]/[siteData]/~gitbook/embed/page.tsx @@ -1,7 +1,8 @@ +import { redirect } from 'next/navigation'; + import type { RouteLayoutParams } from '@/app/utils'; import { isAIChatEnabled } from '@/components/utils/isAIChatEnabled'; import { getEmbeddableStaticContext } from '@/lib/embeddable'; -import { redirect } from 'next/navigation'; export const dynamic = 'force-static'; diff --git a/packages/gitbook/src/app/sites/static/[mode]/[siteURL]/[siteData]/~gitbook/embed/page/[pagePath]/page.tsx b/packages/gitbook/src/app/sites/static/[mode]/[siteURL]/[siteData]/~gitbook/embed/page/[pagePath]/page.tsx index 8b66c9163..eb5f30b60 100644 --- a/packages/gitbook/src/app/sites/static/[mode]/[siteURL]/[siteData]/~gitbook/embed/page/[pagePath]/page.tsx +++ b/packages/gitbook/src/app/sites/static/[mode]/[siteURL]/[siteData]/~gitbook/embed/page/[pagePath]/page.tsx @@ -1,7 +1,8 @@ +import type { Metadata } from 'next'; + import { type RouteParams, getPagePathFromParams } from '@/app/utils'; import { EmbeddableDocsPage, generateEmbeddableDocsPageMetadata } from '@/components/Embeddable'; import { getEmbeddableStaticContext } from '@/lib/embeddable'; -import type { Metadata } from 'next'; export const dynamic = 'force-static'; diff --git a/packages/gitbook/src/app/sites/static/[mode]/[siteURL]/[siteData]/~gitbook/embed/script.js/route.ts b/packages/gitbook/src/app/sites/static/[mode]/[siteURL]/[siteData]/~gitbook/embed/script.js/route.ts index 7801d5d17..6e34860f2 100644 --- a/packages/gitbook/src/app/sites/static/[mode]/[siteURL]/[siteData]/~gitbook/embed/script.js/route.ts +++ b/packages/gitbook/src/app/sites/static/[mode]/[siteURL]/[siteData]/~gitbook/embed/script.js/route.ts @@ -1,9 +1,11 @@ +import type { NextRequest } from 'next/server'; + +import type { CreateGitBookOptions } from '@gitbook/embed'; + import type { RouteLayoutParams } from '@/app/utils'; import { getAssetURL } from '@/lib/assets'; import { buildVersion } from '@/lib/build'; import { getEmbeddableStaticContext } from '@/lib/embeddable'; -import type { CreateGitBookOptions } from '@gitbook/embed'; -import type { NextRequest } from 'next/server'; export const dynamic = 'force-static'; diff --git a/packages/gitbook/src/app/sites/static/[mode]/[siteURL]/[siteData]/~gitbook/markdown-ask/[question]/[goal]/route.ts b/packages/gitbook/src/app/sites/static/[mode]/[siteURL]/[siteData]/~gitbook/markdown-ask/[question]/[goal]/route.ts index db90ed917..72ba6ecb0 100644 --- a/packages/gitbook/src/app/sites/static/[mode]/[siteURL]/[siteData]/~gitbook/markdown-ask/[question]/[goal]/route.ts +++ b/packages/gitbook/src/app/sites/static/[mode]/[siteURL]/[siteData]/~gitbook/markdown-ask/[question]/[goal]/route.ts @@ -1,6 +1,7 @@ +import type { NextRequest } from 'next/server'; + import { type RouteLayoutParams, getStaticSiteContext } from '@/app/utils'; import { serveAskMarkdown } from '@/routes/markdownAsk'; -import type { NextRequest } from 'next/server'; export const dynamic = 'force-static'; diff --git a/packages/gitbook/src/app/sites/static/[mode]/[siteURL]/[siteData]/~gitbook/markdown-ask/[question]/route.ts b/packages/gitbook/src/app/sites/static/[mode]/[siteURL]/[siteData]/~gitbook/markdown-ask/[question]/route.ts index 972bc0a95..ac01394f8 100644 --- a/packages/gitbook/src/app/sites/static/[mode]/[siteURL]/[siteData]/~gitbook/markdown-ask/[question]/route.ts +++ b/packages/gitbook/src/app/sites/static/[mode]/[siteURL]/[siteData]/~gitbook/markdown-ask/[question]/route.ts @@ -1,6 +1,7 @@ +import type { NextRequest } from 'next/server'; + import { type RouteLayoutParams, getStaticSiteContext } from '@/app/utils'; import { serveAskMarkdown } from '@/routes/markdownAsk'; -import type { NextRequest } from 'next/server'; export const dynamic = 'force-static'; diff --git a/packages/gitbook/src/app/sites/static/[mode]/[siteURL]/[siteData]/~gitbook/markdown/[pagePath]/route.ts b/packages/gitbook/src/app/sites/static/[mode]/[siteURL]/[siteData]/~gitbook/markdown/[pagePath]/route.ts index 1631baf31..1a2981bd6 100644 --- a/packages/gitbook/src/app/sites/static/[mode]/[siteURL]/[siteData]/~gitbook/markdown/[pagePath]/route.ts +++ b/packages/gitbook/src/app/sites/static/[mode]/[siteURL]/[siteData]/~gitbook/markdown/[pagePath]/route.ts @@ -1,6 +1,7 @@ +import type { NextRequest } from 'next/server'; + import { type RouteParams, getPagePathFromParams, getStaticSiteContext } from '@/app/utils'; import { servePageMarkdown } from '@/routes/markdownPage'; -import type { NextRequest } from 'next/server'; export const dynamic = 'force-static'; diff --git a/packages/gitbook/src/app/sites/static/[mode]/[siteURL]/[siteData]/~gitbook/rss/[pagePath]/route.ts b/packages/gitbook/src/app/sites/static/[mode]/[siteURL]/[siteData]/~gitbook/rss/[pagePath]/route.ts index 9499facf7..454ad5b19 100644 --- a/packages/gitbook/src/app/sites/static/[mode]/[siteURL]/[siteData]/~gitbook/rss/[pagePath]/route.ts +++ b/packages/gitbook/src/app/sites/static/[mode]/[siteURL]/[siteData]/~gitbook/rss/[pagePath]/route.ts @@ -1,6 +1,7 @@ +import type { NextRequest } from 'next/server'; + import { type RouteParams, getPagePathFromParams, getStaticSiteContext } from '@/app/utils'; import { servePageRSS } from '@/routes/rss'; -import type { NextRequest } from 'next/server'; export const dynamic = 'force-static'; diff --git a/packages/gitbook/src/app/sites/static/[mode]/[siteURL]/[siteData]/~gitbook/site-index/route.ts b/packages/gitbook/src/app/sites/static/[mode]/[siteURL]/[siteData]/~gitbook/site-index/route.ts index 7eeffbb1f..62f7068b6 100644 --- a/packages/gitbook/src/app/sites/static/[mode]/[siteURL]/[siteData]/~gitbook/site-index/route.ts +++ b/packages/gitbook/src/app/sites/static/[mode]/[siteURL]/[siteData]/~gitbook/site-index/route.ts @@ -1,10 +1,11 @@ +import type { NextRequest } from 'next/server'; + import { type RevisionPage, type RevisionPageDocument, type RevisionPageGroup, SiteVisibility, } from '@gitbook/api'; -import type { NextRequest } from 'next/server'; import { type RouteLayoutParams, getStaticSiteContext } from '@/app/utils'; import { throwIfDataError } from '@/lib/data'; diff --git a/packages/gitbook/src/app/utils.ts b/packages/gitbook/src/app/utils.ts index ca0c944fc..727105cd7 100644 --- a/packages/gitbook/src/app/utils.ts +++ b/packages/gitbook/src/app/utils.ts @@ -1,11 +1,13 @@ -import { getVisitorAuthClaims, getVisitorAuthClaimsFromToken } from '@/lib/adaptive'; -import { type SiteURLData, fetchSiteContextByURLLookup, getBaseContext } from '@/lib/context'; -import { getDynamicCustomizationSettings } from '@/lib/customization'; -import type { SiteAPIToken } from '@gitbook/api'; import { jwtDecode } from 'jwt-decode'; import { forbidden, notFound } from 'next/navigation'; import rison from 'rison'; +import type { SiteAPIToken } from '@gitbook/api'; + +import { getVisitorAuthClaims, getVisitorAuthClaimsFromToken } from '@/lib/adaptive'; +import { type SiteURLData, fetchSiteContextByURLLookup, getBaseContext } from '@/lib/context'; +import { getDynamicCustomizationSettings } from '@/lib/customization'; + export type RouteParamMode = 'url-host' | 'url'; export type RouteLayoutParams = { diff --git a/packages/gitbook/src/app/~gitbook/revalidate/route.ts b/packages/gitbook/src/app/~gitbook/revalidate/route.ts index 410c2347d..ebb769785 100644 --- a/packages/gitbook/src/app/~gitbook/revalidate/route.ts +++ b/packages/gitbook/src/app/~gitbook/revalidate/route.ts @@ -1,8 +1,8 @@ +import { revalidateTag } from 'next/cache'; import { type NextRequest, NextResponse } from 'next/server'; import { getLogger } from '@/lib/logger'; import { withVerifySignature } from '@/lib/routes'; -import { revalidateTag } from 'next/cache'; interface JsonBody { tags: string[]; diff --git a/packages/gitbook/src/app/~space/[spaceId]/~gitbook/pdf/page.tsx b/packages/gitbook/src/app/~space/[spaceId]/~gitbook/pdf/page.tsx index fdf11e13d..1418af01e 100644 --- a/packages/gitbook/src/app/~space/[spaceId]/~gitbook/pdf/page.tsx +++ b/packages/gitbook/src/app/~space/[spaceId]/~gitbook/pdf/page.tsx @@ -1,11 +1,7 @@ import { type SpacePDFRouteParams, getSpacePDFContext } from '@/app/~space/[spaceId]/pdf'; import { PDFPage, generatePDFMetadata } from '@/components/PDF'; -export async function generateMetadata({ - params, -}: { - params: Promise; -}) { +export async function generateMetadata({ params }: { params: Promise }) { const context = await getSpacePDFContext(await params); return generatePDFMetadata(context); } diff --git a/packages/gitbook/src/components/AI/controls/ConfirmControl.tsx b/packages/gitbook/src/components/AI/controls/ConfirmControl.tsx index 0daed3288..747e5297d 100644 --- a/packages/gitbook/src/components/AI/controls/ConfirmControl.tsx +++ b/packages/gitbook/src/components/AI/controls/ConfirmControl.tsx @@ -1,10 +1,11 @@ 'use client'; -import { Button } from '@/components/primitives'; -import { tString, useLanguage } from '@/intl/client'; import { z } from 'zod'; + import { AIToolContainer } from './common'; import { type GetAIControlProps, createAIControl } from './helpers'; +import { Button } from '@/components/primitives'; +import { tString, useLanguage } from '@/intl/client'; export const ConfirmControlOutputSchema = z.object({ result: z.enum(['confirmed', 'cancelled']), diff --git a/packages/gitbook/src/components/AI/controls/MultiChoiceControl.tsx b/packages/gitbook/src/components/AI/controls/MultiChoiceControl.tsx index 949a9e1f7..d8d036f22 100644 --- a/packages/gitbook/src/components/AI/controls/MultiChoiceControl.tsx +++ b/packages/gitbook/src/components/AI/controls/MultiChoiceControl.tsx @@ -1,14 +1,16 @@ 'use client'; +import * as React from 'react'; +import { z } from 'zod'; + +import { Icon, IconStyle } from '@gitbook/icons'; + +import { AIToolContainer } from './common'; +import { type GetAIControlProps, createAIControl } from './helpers'; import { Button, Input } from '@/components/primitives'; import { ScrollContainer } from '@/components/primitives/ScrollContainer'; import { tString, useLanguage } from '@/intl/client'; import { tcls } from '@/lib/tailwind'; -import { Icon, IconStyle } from '@gitbook/icons'; -import * as React from 'react'; -import { z } from 'zod'; -import { AIToolContainer } from './common'; -import { type GetAIControlProps, createAIControl } from './helpers'; const OTHER_OPTION_ID = '$other'; @@ -98,7 +100,7 @@ function MultiChoiceControl(props: GetAIControlProps -

{prompt}

+

{prompt}

{options.map((option) => { const isSelected = selectedIds.includes(option.id); return ( @@ -136,9 +138,9 @@ function MultiChoiceControl(props: GetAIControlProps -

{option.label}

+

{option.label}

{option.description ? ( -

+

{option.description}

) : null} diff --git a/packages/gitbook/src/components/AI/controls/SingleChoiceControl.tsx b/packages/gitbook/src/components/AI/controls/SingleChoiceControl.tsx index 17739f104..a69bd454c 100644 --- a/packages/gitbook/src/components/AI/controls/SingleChoiceControl.tsx +++ b/packages/gitbook/src/components/AI/controls/SingleChoiceControl.tsx @@ -1,13 +1,14 @@ 'use client'; +import * as React from 'react'; +import { z } from 'zod'; + +import { AIToolContainer } from './common'; +import { type GetAIControlProps, createAIControl } from './helpers'; import { Button, Input } from '@/components/primitives'; import { ScrollContainer } from '@/components/primitives/ScrollContainer'; import { tString, useLanguage } from '@/intl/client'; import { tcls } from '@/lib/tailwind'; -import * as React from 'react'; -import { z } from 'zod'; -import { AIToolContainer } from './common'; -import { type GetAIControlProps, createAIControl } from './helpers'; const OTHER_OPTION_ID = '$other'; @@ -81,7 +82,7 @@ function SingleChoiceControl(props: GetAIControlProps -

{prompt}

+

{prompt}

{options.map((option) => { const isSelected = selectedId === option.id; @@ -119,9 +120,9 @@ function SingleChoiceControl(props: GetAIControlProps
-

{option.label}

+

{option.label}

{option.description ? ( -

+

{option.description}

) : null} diff --git a/packages/gitbook/src/components/AI/controls/common.tsx b/packages/gitbook/src/components/AI/controls/common.tsx index ef4eeda29..829beff6e 100644 --- a/packages/gitbook/src/components/AI/controls/common.tsx +++ b/packages/gitbook/src/components/AI/controls/common.tsx @@ -1,6 +1,7 @@ -import { tcls } from '@/lib/tailwind'; import type { ComponentPropsWithRef } from 'react'; +import { tcls } from '@/lib/tailwind'; + export function AIToolContainer(props: ComponentPropsWithRef<'div'>) { return (
; diff --git a/packages/gitbook/src/components/AI/navigation.test.ts b/packages/gitbook/src/components/AI/navigation.test.ts index 4f2bc0d5a..16e2691d0 100644 --- a/packages/gitbook/src/components/AI/navigation.test.ts +++ b/packages/gitbook/src/components/AI/navigation.test.ts @@ -1,4 +1,5 @@ import { describe, expect, it } from 'bun:test'; + import { normalizePathname, resolveNavigationTarget, toInSiteHref } from './navigation'; const location = { diff --git a/packages/gitbook/src/components/AI/navigation.ts b/packages/gitbook/src/components/AI/navigation.ts index 478a068b8..8adc0b585 100644 --- a/packages/gitbook/src/components/AI/navigation.ts +++ b/packages/gitbook/src/components/AI/navigation.ts @@ -1,5 +1,5 @@ -import { withTrailingSlash } from '@/lib/paths'; import { isExternalLink } from '../utils/link'; +import { withTrailingSlash } from '@/lib/paths'; /** * Resolve a link into a same-site target to navigate to. diff --git a/packages/gitbook/src/components/AI/references.test.ts b/packages/gitbook/src/components/AI/references.test.ts index 8db6ac8eb..1e9c839a2 100644 --- a/packages/gitbook/src/components/AI/references.test.ts +++ b/packages/gitbook/src/components/AI/references.test.ts @@ -1,4 +1,5 @@ import { describe, expect, it } from 'bun:test'; + import { type AIChatReference, serializeReferences } from './references'; describe('serializeReferences', () => { diff --git a/packages/gitbook/src/components/AI/server-actions/AIMessageView.tsx b/packages/gitbook/src/components/AI/server-actions/AIMessageView.tsx index 4fd4c55b8..9370547d9 100644 --- a/packages/gitbook/src/components/AI/server-actions/AIMessageView.tsx +++ b/packages/gitbook/src/components/AI/server-actions/AIMessageView.tsx @@ -1,10 +1,11 @@ -import { CollapsibleContent } from '@/components/primitives'; -import type { GitBookSiteContext } from '@/lib/context'; -import { tcls } from '@/lib/tailwind'; import { type AIMessage, AIMessageStepPhase } from '@gitbook/api'; + import { DocumentView } from '../../DocumentView'; import { AIToolCallsSummary } from './AIToolCallsSummary'; import type { RenderAIMessageOptions } from './types'; +import { CollapsibleContent } from '@/components/primitives'; +import type { GitBookSiteContext } from '@/lib/context'; +import { tcls } from '@/lib/tailwind'; /** * Render a message from the API backend. diff --git a/packages/gitbook/src/components/AI/server-actions/AIToolCallsSummary.tsx b/packages/gitbook/src/components/AI/server-actions/AIToolCallsSummary.tsx index 1a9307e7d..6d5e2ddd8 100644 --- a/packages/gitbook/src/components/AI/server-actions/AIToolCallsSummary.tsx +++ b/packages/gitbook/src/components/AI/server-actions/AIToolCallsSummary.tsx @@ -1,11 +1,6 @@ -import { HighlightQuery } from '@/components/Search/HighlightQuery'; -import { Link, StyledLink } from '@/components/primitives'; -import { Favicon } from '@/components/utils'; -import { getSpaceLanguage } from '@/intl/server'; -import { t } from '@/intl/translate'; -import type { GitBookSiteContext } from '@/lib/context'; -import { resolveContentRef } from '@/lib/references'; -import { tcls } from '@/lib/tailwind'; +import assertNever from 'assert-never'; +import type * as React from 'react'; + import type { AIToolCall, AIToolCallGetPageContent, @@ -16,8 +11,15 @@ import type { ContentRef, } from '@gitbook/api'; import { Icon, type IconName } from '@gitbook/icons'; -import assertNever from 'assert-never'; -import type * as React from 'react'; + +import { Link, StyledLink } from '@/components/primitives'; +import { HighlightQuery } from '@/components/Search/HighlightQuery'; +import { Favicon } from '@/components/utils'; +import { getSpaceLanguage } from '@/intl/server'; +import { t } from '@/intl/translate'; +import type { GitBookSiteContext } from '@/lib/context'; +import { resolveContentRef } from '@/lib/references'; +import { tcls } from '@/lib/tailwind'; /** * Display the tool calls in a message or step. @@ -43,7 +45,7 @@ function ToolCallSummary(props: { toolCall: AIToolCall; context: GitBookSiteCont return (
0; return ( -
+

{t(language, 'searched_for', {toolCall.query})}

-

+

{hasResults ? t(language, 'search_results_count', toolCall.results.length) : t(language, 'search_no_results')} @@ -204,7 +206,7 @@ async function DescriptionForSearchToolCall(props: { ) : null}

{hasResults ? ( -
+
    {searchResultsWithHrefs.map((result, index) => { const resultKey = (() => { @@ -231,7 +233,7 @@ async function DescriptionForSearchToolCall(props: { > -

    +

    {result.description && ( -

    +

    - + @@ -121,6 +123,7 @@ export function AIChat() { suggestions={config.suggestions} trademark={config.trademark} assistantName={config.assistantName} + greeting={config.greeting} /> @@ -132,10 +135,7 @@ export function AIChat() { /** * Dynamic icon to indicate the AI chat state. */ -export function AIChatDynamicIcon(props: { - trademark: boolean; - className?: string; -}) { +export function AIChatDynamicIcon(props: { trademark: boolean; className?: string }) { const { trademark, className } = props; const chat = useAIChatState(); const status = getAIChatStatus(chat); @@ -152,9 +152,7 @@ export function AIChatDynamicIcon(props: { /** * Subtitle of the AI chat window. */ -export function AIChatSubtitle(props: { - chat: AIChatState; -}) { +export function AIChatSubtitle(props: { chat: AIChatState }) { const { chat } = props; const language = useLanguage(); const status = getAIChatStatus(chat); @@ -212,7 +210,7 @@ export function AIChatBody(props: { /** Custom assistant name override; falls back to the branded/unbranded default name. */ assistantName?: string; greeting?: { - title: string; + title?: string; subtitle: string; }; }) { @@ -235,7 +233,7 @@ export function AIChatBody(props: { return ( <>

    {greeting?.title || timeGreeting}

    @@ -284,7 +282,7 @@ export function AIChatBody(props: { )} -

    +
    {!chat.error && chat.queuedMessages.map((message, index) => ( +
    {t(language, 'ai_chat_error')} diff --git a/packages/gitbook/src/components/AIChat/AIChatButton.tsx b/packages/gitbook/src/components/AIChat/AIChatButton.tsx index abf533d34..22e3cd89f 100644 --- a/packages/gitbook/src/components/AIChat/AIChatButton.tsx +++ b/packages/gitbook/src/components/AIChat/AIChatButton.tsx @@ -1,10 +1,10 @@ 'use client'; -import { useLanguage } from '@/intl/client'; -import { t, tString } from '@/intl/translate'; import type { Assistant } from '../AI'; import { useIsMobile } from '../hooks/useIsMobile'; import { Button } from '../primitives'; import { KeyboardShortcut } from '../primitives/KeyboardShortcut'; +import { useLanguage } from '@/intl/client'; +import { t, tString } from '@/intl/translate'; const MOBILE_BREAKPOINT = 688; // 43rem, equal to Tailwind's @max-2xl container breakpoint diff --git a/packages/gitbook/src/components/AIChat/AIChatControlButton.tsx b/packages/gitbook/src/components/AIChat/AIChatControlButton.tsx index b71f3a9f3..a07e9c3db 100644 --- a/packages/gitbook/src/components/AIChat/AIChatControlButton.tsx +++ b/packages/gitbook/src/components/AIChat/AIChatControlButton.tsx @@ -1,9 +1,9 @@ 'use client'; -import { useLanguage } from '@/intl/client'; -import { t } from '@/intl/translate'; import { useAIChatController, useAIChatState } from '../AI'; import { Button } from '../primitives'; +import { useLanguage } from '@/intl/client'; +import { t } from '@/intl/translate'; /** * Button to control the chat (clear, etc.) diff --git a/packages/gitbook/src/components/AIChat/AIChatExpandButton.tsx b/packages/gitbook/src/components/AIChat/AIChatExpandButton.tsx index 11d12c7da..1ca747043 100644 --- a/packages/gitbook/src/components/AIChat/AIChatExpandButton.tsx +++ b/packages/gitbook/src/components/AIChat/AIChatExpandButton.tsx @@ -1,9 +1,10 @@ 'use client'; -import { tString, useLanguage } from '@/intl/client'; import { Icon } from '@gitbook/icons'; + import { Button } from '../primitives'; import { useAIChatWidthStore, useIsAIChatMaxWidth } from './useAIChatWidthStore'; +import { tString, useLanguage } from '@/intl/client'; export function AIChatExpandButton() { const language = useLanguage(); diff --git a/packages/gitbook/src/components/AIChat/AIChatIcon.tsx b/packages/gitbook/src/components/AIChat/AIChatIcon.tsx index 90e2825f3..1da741e3b 100644 --- a/packages/gitbook/src/components/AIChat/AIChatIcon.tsx +++ b/packages/gitbook/src/components/AIChat/AIChatIcon.tsx @@ -1,6 +1,7 @@ -import { Icon, IconStyle } from '@gitbook/icons'; import type React from 'react'; +import { Icon, IconStyle } from '@gitbook/icons'; + interface AIChatIconProps extends React.SVGProps { className?: string; size?: number; diff --git a/packages/gitbook/src/components/AIChat/AIChatInput.tsx b/packages/gitbook/src/components/AIChat/AIChatInput.tsx index c2ca5f379..c392faa87 100644 --- a/packages/gitbook/src/components/AIChat/AIChatInput.tsx +++ b/packages/gitbook/src/components/AIChat/AIChatInput.tsx @@ -1,12 +1,14 @@ -import { t, tString, useLanguage } from '@/intl/client'; -import { tcls } from '@/lib/tailwind'; -import { Icon } from '@gitbook/icons'; import { useEffect, useRef, useState } from 'react'; import { useHotkeys } from 'react-hotkeys-hook'; + +import { Icon } from '@gitbook/icons'; + import { useAIChatController, useAIChatState } from '../AI/useAIChat'; import { HoverCard, HoverCardRoot, HoverCardTrigger } from '../primitives'; import { Input } from '../primitives/Input'; import { AIChatReferenceChips } from './AIChatReferenceChips'; +import { t, tString, useLanguage } from '@/intl/client'; +import { tcls } from '@/lib/tailwind'; export function AIChatInput(props: { disabled?: boolean; @@ -122,7 +124,7 @@ export function AIChatInput(props: { /> } trailing={ - + {t(language, 'ai_chat_context_disclaimer')}

    - + {/* Negative margin to compensate for Input's padding, so the badge appears flush with the cursor */} -
    - +
    + {t(language, 'ai_chat_context_badge')} {' '} diff --git a/packages/gitbook/src/components/AIChat/AIChatMessages.tsx b/packages/gitbook/src/components/AIChat/AIChatMessages.tsx index ff99c0cbd..812e76043 100644 --- a/packages/gitbook/src/components/AIChat/AIChatMessages.tsx +++ b/packages/gitbook/src/components/AIChat/AIChatMessages.tsx @@ -1,8 +1,7 @@ -import { useLanguage } from '@/intl/client'; -import { t, tString } from '@/intl/translate'; -import { tcls } from '@/lib/tailwind'; +import { Fragment, useState } from 'react'; + import { AIMessageRole } from '@gitbook/api'; -import { Fragment } from 'react'; + import { type AIChatController, type AIChatMessage, @@ -12,22 +11,23 @@ import { import { ToggleChevron } from '../primitives'; import { Button } from '../primitives/Button'; import { Collapsible, CollapsibleTrigger } from '../primitives/Collapsible'; +import { AIChatFollowupSuggestions } from './AiChatFollowupSuggestions'; import { AIChatReferenceChips } from './AIChatReferenceChips'; import { AIResponseFeedback } from './AIResponseFeedback'; -import { AIChatFollowupSuggestions } from './AiChatFollowupSuggestions'; +import { useLanguage } from '@/intl/client'; +import { t, tString } from '@/intl/translate'; +import { tcls } from '@/lib/tailwind'; -export function AIChatMessages(props: { - chat: AIChatState; - chatController: AIChatController; -}) { +type MessageGroup = { message: AIChatMessage; originalIndex: number }; + +export function AIChatMessages(props: { chat: AIChatState; chatController: AIChatController }) { const { chat, chatController } = props; const status = getAIChatStatus(chat); const showLoadingShim = chat.responding && status !== 'working' && status !== 'done'; // Group messages: user messages start a new group, all following messages until next user message belong to that group - type MessageGroup = { message: AIChatMessage; originalIndex: number }; - const messageGroups: Array> = []; - let currentGroup: Array = []; + const messageGroups: MessageGroup[][] = []; + let currentGroup: MessageGroup[] = []; chat.messages.forEach((message, index) => { if (message.role === AIMessageRole.User) { @@ -47,8 +47,6 @@ export function AIChatMessages(props: { messageGroups.push(currentGroup); } - const language = useLanguage(); - return messageGroups.map((group, groupIndex) => { const isLastGroup = group === messageGroups[messageGroups.length - 1]; @@ -113,107 +111,148 @@ export function AIChatMessages(props: { ))} {assistantItems.length > 0 ? ( - - {hasCommentary && hasFinalAnswer ? ( - - - - ) : null} - - {assistantItems.map(({ message, originalIndex }) => ( - {message.content} - ))} - - {isLastMessage ? ( -
    - message.content) - ? 'hidden' - : '' - } - /> - -
    - ) : null} - - {isLastMessage ? ( - <> - {!chat.responding && - !chat.error && - chat.query && - chat.responseId && - !chat.control ? ( - - ) : null} - - - ) : null} -
    + ) : null}
    ); }); } +function AIChatAssistantGroup(props: { + chat: AIChatState; + chatController: AIChatController; + assistantItems: MessageGroup[]; + hasCommentary: boolean; + hasFinalAnswer: boolean; + toolCount: number; + firstAssistantIndex: number; + isLastMessage: boolean; + showLoadingShim: boolean; +}) { + const { + chat, + chatController, + assistantItems, + hasCommentary, + hasFinalAnswer, + toolCount, + firstAssistantIndex, + isLastMessage, + showLoadingShim, + } = props; + const language = useLanguage(); + // Base UI locks controlled/uncontrolled mode on first render, so once `hasFinalAnswer` + // flips the trigger over to being interactive, we need our own state to track manual toggles. + const [manuallyOpened, setManuallyOpened] = useState(false); + + return ( + + {hasCommentary && hasFinalAnswer ? ( + + } + > +
    + + {toolCount > 0 + ? t( + language, + 'ai_chat_explored_with', + tString( + language, + toolCount === 1 ? 'tool_count' : 'tool_count_plural', + toolCount.toString() + ) + ) + : t(language, 'ai_chat_explored')} + + +
    +
    + ) : null} + + {assistantItems.map(({ message, originalIndex }) => ( + {message.content} + ))} + + {isLastMessage ? ( +
    + message.content) ? 'hidden' : '' + } + /> + +
    + ) : null} + + {isLastMessage ? ( + <> + {!chat.responding && + !chat.error && + chat.query && + chat.responseId && + !chat.control ? ( + + ) : null} + + + ) : null} +
    + ); +} + export function HoldMessage({ breakLines = false, className, -}: { breakLines?: boolean; className?: string }) { +}: { + breakLines?: boolean; + className?: string; +}) { const language = useLanguage(); return ( @@ -260,7 +299,7 @@ function LoadingSkeleton() { {Array.from({ length: 7 }).map((_, index) => (
    +
    {ref.type === 'page' && ref.href ? ( // A page reference may be clicked from anywhere: render a link so it @@ -80,7 +81,7 @@ export function AIChatReferenceChips(props: { onRemove(ref.id); }} disabled={disabled} - className="inline-flex size-4 shrink-0 items-center justify-center circular-corners:rounded-full rounded-corners:rounded-sm text-tint/8 transition hover:bg-tint hover:text-tint-strong disabled:cursor-not-allowed disabled:opacity-5" + className="inline-flex size-4 shrink-0 items-center justify-center text-tint/8 transition hover:bg-tint hover:text-tint-strong disabled:cursor-not-allowed disabled:opacity-5 rounded-corners:rounded-sm circular-corners:rounded-full" > diff --git a/packages/gitbook/src/components/AIChat/AIChatResizeHandle.tsx b/packages/gitbook/src/components/AIChat/AIChatResizeHandle.tsx index 6c61faf31..930cd38fb 100644 --- a/packages/gitbook/src/components/AIChat/AIChatResizeHandle.tsx +++ b/packages/gitbook/src/components/AIChat/AIChatResizeHandle.tsx @@ -1,8 +1,9 @@ 'use client'; -import { tcls } from '@/lib/tailwind'; import React from 'react'; + import { useAIChatWidthStore } from './useAIChatWidthStore'; +import { tcls } from '@/lib/tailwind'; function setResizing(active: boolean) { document.documentElement.dataset.aiChatResizing = String(active); @@ -77,7 +78,7 @@ export function AIChatResizeHandle() { 'items-stretch justify-center' )} > - +
    ); } diff --git a/packages/gitbook/src/components/AIChat/AIChatSuggestedQuestions.tsx b/packages/gitbook/src/components/AIChat/AIChatSuggestedQuestions.tsx index 0ad59d763..649dd2e88 100644 --- a/packages/gitbook/src/components/AIChat/AIChatSuggestedQuestions.tsx +++ b/packages/gitbook/src/components/AIChat/AIChatSuggestedQuestions.tsx @@ -1,8 +1,8 @@ +import type { AIChatController } from '../AI'; +import { Button } from '../primitives'; +import { useRecentSearchQueries } from '../Search/recent-queries'; import { useCurrentContent } from '@/components/hooks'; import { tString, useLanguage } from '@/intl/client'; -import type { AIChatController } from '../AI'; -import { useRecentSearchQueries } from '../Search/recent-queries'; -import { Button } from '../primitives'; export default function AIChatSuggestedQuestions(props: { chatController: AIChatController; @@ -47,7 +47,7 @@ export default function AIChatSuggestedQuestions(props: { key={question} variant="blank" size="small" - className="max-w-full animate-blur-in-slow border-none bg-primary-solid/1 hover:bg-primary-hover" + className="animate-blur-in-slow max-w-full border-none bg-primary-solid/1 hover:bg-primary-hover" style={{ animationDelay: `${1000 + index * 100}ms`, }} diff --git a/packages/gitbook/src/components/AIChat/AIResponseFeedback.tsx b/packages/gitbook/src/components/AIChat/AIResponseFeedback.tsx index a93857288..6048b0762 100644 --- a/packages/gitbook/src/components/AIChat/AIResponseFeedback.tsx +++ b/packages/gitbook/src/components/AIChat/AIResponseFeedback.tsx @@ -1,11 +1,12 @@ 'use client'; +import { useState } from 'react'; + +import { useTrackEvent } from '../Insights'; +import { Button } from '../primitives'; import { useLanguage } from '@/intl/client'; import { t, tString } from '@/intl/translate'; import { type ClassValue, tcls } from '@/lib/tailwind'; -import { useState } from 'react'; -import { useTrackEvent } from '../Insights'; -import { Button } from '../primitives'; export function AIResponseFeedback(props: { className?: ClassValue; @@ -61,7 +62,7 @@ export function AIResponseFeedback(props: { /> {rating !== null ? ( {t(language, 'was_this_helpful_thank_you')} diff --git a/packages/gitbook/src/components/AIChat/AiChatFollowupSuggestions.tsx b/packages/gitbook/src/components/AIChat/AiChatFollowupSuggestions.tsx index 1346eef52..ea1b80082 100644 --- a/packages/gitbook/src/components/AIChat/AiChatFollowupSuggestions.tsx +++ b/packages/gitbook/src/components/AIChat/AiChatFollowupSuggestions.tsx @@ -29,7 +29,7 @@ export function AIChatFollowupSuggestions(props: { chatController.postMessage({ message: suggestion }); }} label={suggestion} - className="starting:h-0 max-w-full origin-left animate-blur-in-slow border-none bg-primary-11/1 starting:py-0 text-left transition-all transition-discrete duration-500 hover:bg-primary-hover" + className="starting:h-0 animate-blur-in-slow starting:py-0 transition-discrete max-w-full origin-left border-none bg-primary-11/1 text-left transition-all duration-500 hover:bg-primary-hover" size="small" variant="blank" style={{ diff --git a/packages/gitbook/src/components/AIChat/AskAIParagraphButton/AskAIParagraphButton.tsx b/packages/gitbook/src/components/AIChat/AskAIParagraphButton/AskAIParagraphButton.tsx index 0df53f8cc..b71b3d2bc 100644 --- a/packages/gitbook/src/components/AIChat/AskAIParagraphButton/AskAIParagraphButton.tsx +++ b/packages/gitbook/src/components/AIChat/AskAIParagraphButton/AskAIParagraphButton.tsx @@ -2,13 +2,12 @@ import fnv1a from '@sindresorhus/fnv1a'; +import { AIChatIcon } from '../AIChatIcon'; import { useAIChatController, useAIConfig } from '@/components/AI'; import { Button } from '@/components/primitives'; import { t, tString, useLanguage } from '@/intl/client'; import { type ClassValue, tcls } from '@/lib/tailwind'; -import { AIChatIcon } from '../AIChatIcon'; - /** * A small icon button revealed in the left margin of a top-level paragraph when it is hovered (on * devices with a fine pointer). Clicking it stages the paragraph's text as a reference and opens diff --git a/packages/gitbook/src/components/AIChat/AskAITextSelection/AskAITextSelection.tsx b/packages/gitbook/src/components/AIChat/AskAITextSelection/AskAITextSelection.tsx index ee3d00909..ba6db9854 100644 --- a/packages/gitbook/src/components/AIChat/AskAITextSelection/AskAITextSelection.tsx +++ b/packages/gitbook/src/components/AIChat/AskAITextSelection/AskAITextSelection.tsx @@ -5,6 +5,8 @@ import { AnimatePresence, motion } from 'motion/react'; import * as React from 'react'; import { createPortal } from 'react-dom'; +import { AIChatIcon } from '../AIChatIcon'; +import { useStableTextSelection } from './useStableTextSelection'; import { useAIChatController, useAIConfig } from '@/components/AI'; import { useIsMobile } from '@/components/hooks/useIsMobile'; import { useIsMounted } from '@/components/hooks/useIsMounted'; @@ -12,9 +14,6 @@ import { Button } from '@/components/primitives'; import { isAIChatEnabled } from '@/components/utils/isAIChatEnabled'; import { t, useLanguage } from '@/intl/client'; -import { AIChatIcon } from '../AIChatIcon'; -import { useStableTextSelection } from './useStableTextSelection'; - /** Gap between the selection and the button. */ const GAP = 8; /** Minimum distance to the viewport edges. */ diff --git a/packages/gitbook/src/components/AIChat/useAIChatWidthStore.ts b/packages/gitbook/src/components/AIChat/useAIChatWidthStore.ts index 79afebf24..a1a533ff5 100644 --- a/packages/gitbook/src/components/AIChat/useAIChatWidthStore.ts +++ b/packages/gitbook/src/components/AIChat/useAIChatWidthStore.ts @@ -1,12 +1,13 @@ 'use client'; +import { create } from 'zustand'; +import { type StorageValue, persist } from 'zustand/middleware'; + import { getLocalStorageItem, removeLocalStorageItem, setLocalStorageItem, } from '@/lib/browser/local-storage'; -import { create } from 'zustand'; -import { type StorageValue, persist } from 'zustand/middleware'; const AI_CHAT_MIN_WIDTH = 384; const AI_CHAT_MAX_WIDTH = 640; diff --git a/packages/gitbook/src/components/Adaptive/AdaptiveVisitorContextProvider.tsx b/packages/gitbook/src/components/Adaptive/AdaptiveVisitorContextProvider.tsx index 1edf65068..91b163246 100644 --- a/packages/gitbook/src/components/Adaptive/AdaptiveVisitorContextProvider.tsx +++ b/packages/gitbook/src/components/Adaptive/AdaptiveVisitorContextProvider.tsx @@ -1,10 +1,12 @@ 'use client'; -import type { GitBookSiteContext } from '@/lib/context'; -import { OpenAPIPrefillContextProvider } from '@gitbook/react-openapi'; import * as React from 'react'; import { createContext, useContext } from 'react'; + +import { OpenAPIPrefillContextProvider } from '@gitbook/react-openapi'; + import type { AdaptiveVisitorClaims } from './types'; +import type { GitBookSiteContext } from '@/lib/context'; /** * In-memory cache of visitor claim readers keyed by contextId. diff --git a/packages/gitbook/src/components/Adaptive/utils.ts b/packages/gitbook/src/components/Adaptive/utils.ts index 304410a7a..b085cacbd 100644 --- a/packages/gitbook/src/components/Adaptive/utils.ts +++ b/packages/gitbook/src/components/Adaptive/utils.ts @@ -1,4 +1,5 @@ import type { Variables } from '@gitbook/api'; + import type { AdaptiveVisitorClaims } from './types'; /** diff --git a/packages/gitbook/src/components/AdminToolbar/AdminToolbar.tsx b/packages/gitbook/src/components/AdminToolbar/AdminToolbar.tsx index a1c461f85..6d933a9cf 100644 --- a/packages/gitbook/src/components/AdminToolbar/AdminToolbar.tsx +++ b/packages/gitbook/src/components/AdminToolbar/AdminToolbar.tsx @@ -1,7 +1,7 @@ -import type { GitBookSiteContext } from '@/lib/context'; import { AdminToolbarClient } from './AdminToolbarClient'; import { getToolbarChangedPages } from './changedPages'; import type { AdminToolbarContext } from './types'; +import type { GitBookSiteContext } from '@/lib/context'; export interface AdminToolbarProps { context: GitBookSiteContext; diff --git a/packages/gitbook/src/components/AdminToolbar/AdminToolbarClient.tsx b/packages/gitbook/src/components/AdminToolbar/AdminToolbarClient.tsx index 0988db421..d0fe9a7d9 100644 --- a/packages/gitbook/src/components/AdminToolbar/AdminToolbarClient.tsx +++ b/packages/gitbook/src/components/AdminToolbar/AdminToolbarClient.tsx @@ -1,9 +1,11 @@ 'use client'; -import { Icon } from '@gitbook/icons'; import { MotionConfig, motion } from 'motion/react'; + +import { Icon } from '@gitbook/icons'; + import { useCheckForContentUpdate } from '../AutoRefreshContent'; -import { useVisitor } from '../Insights'; import { useCurrentPagePath } from '../hooks'; +import { useVisitor } from '../Insights'; import { ChangedPagesButton } from './ChangedPagesButton'; import { HideToolbarButton } from './HideToolbarButton'; import { IframeWrapper } from './IframeWrapper'; @@ -225,7 +227,7 @@ function RevisionToolbar(props: ToolbarViewProps) { ) : (
    Setup GitSync to edit using Git{' '} -
    +
    -
    {changedPagesLabel}
    +
    {changedPagesLabel}
    {changedPages.pages.map((page) => ( @@ -112,7 +114,7 @@ export function ChangedPagesButton(props: { {changedPages.more > 0 ? ( <> -
    +
    {changedPages.more} more changes not shown
    @@ -133,14 +135,14 @@ function ChangedPageMenuItem(props: { page: MinimalChangedPage }) { - + {page.title} - + /{page.path || ''} - + {actionLabel} diff --git a/packages/gitbook/src/components/AdminToolbar/HideToolbarButton.tsx b/packages/gitbook/src/components/AdminToolbar/HideToolbarButton.tsx index 577da8e10..c268eaecd 100644 --- a/packages/gitbook/src/components/AdminToolbar/HideToolbarButton.tsx +++ b/packages/gitbook/src/components/AdminToolbar/HideToolbarButton.tsx @@ -1,12 +1,14 @@ 'use client'; -import { tcls } from '@/lib/tailwind'; -import { Icon, type IconName, IconStyle } from '@gitbook/icons'; import { motion } from 'motion/react'; import React, { useRef } from 'react'; import { useOnClickOutside } from 'usehooks-ts'; + +import { Icon, type IconName, IconStyle } from '@gitbook/icons'; + import { ToolbarButton, type ToolbarButtonProps } from './Toolbar'; import styles from './Toolbar.module.css'; import { useToolbarControls } from './ToolbarControlsContext'; +import { tcls } from '@/lib/tailwind'; // Params for the expanding arc defined separately for easier tweaking. const ARC_PARAMS = { @@ -110,7 +112,7 @@ export function HideToolbarButton(props: HideToolbarButtonProps) { onClick: controls.closePersistent, } : null, - ].filter(Boolean) as Array; + ].filter(Boolean) as ArcMenuItem[]; const sharedMotionStyle = motionValues ? { @@ -124,7 +126,7 @@ export function HideToolbarButton(props: HideToolbarButtonProps) { title={open ? undefined : 'Hide toolbar'} className={ open || closing - ? 'border-[0.5px] border-neutral-5 border-solid dark:border-neutral-8' + ? 'border-[0.5px] border-solid border-neutral-5 dark:border-neutral-8' : undefined } onClick={() => { diff --git a/packages/gitbook/src/components/AdminToolbar/Toolbar.tsx b/packages/gitbook/src/components/AdminToolbar/Toolbar.tsx index 93f70d63a..7cd4901e2 100644 --- a/packages/gitbook/src/components/AdminToolbar/Toolbar.tsx +++ b/packages/gitbook/src/components/AdminToolbar/Toolbar.tsx @@ -7,15 +7,16 @@ import { useSpring, } from 'motion/react'; import React, { isValidElement } from 'react'; + +import { Icon, type IconName, IconStyle } from '@gitbook/icons'; + +import { Tooltip } from '../primitives'; import { AnimatedLogo } from './AnimatedLogo'; import { useToolbarControls } from './ToolbarControlsContext'; import { ToolbarVisibilityHint } from './ToolbarVisibilityHint'; - -import { tcls } from '@/lib/tailwind'; -import { Icon, type IconName, IconStyle } from '@gitbook/icons'; -import { Tooltip } from '../primitives'; import { getCopyVariants, toolbarEasings } from './transitions'; import { useMagnificationEffect } from './useMagnificationEffect'; +import { tcls } from '@/lib/tailwind'; const DURATION_LOGO_APPEARANCE = 2000; const DELAY_BETWEEN_LOGO_AND_CONTENT = 100; @@ -107,7 +108,7 @@ export function Toolbar(props: ToolbarProps) { return ( @@ -182,7 +183,7 @@ export function ToolbarButtonGroup(props: { children: React.ReactNode }) { variants={toolbarEasings.parent} initial="hidden" animate="show" - className="flex items-center gap-1 overflow-visible pr-2 pl-4" + className="flex items-center gap-1 overflow-visible pl-4 pr-2" > {buttonChildren.map((child, index) => { const childEl = child as React.ReactElement; @@ -318,7 +319,7 @@ function ToolbarButtonWrapper(props: { export function ToolbarTitle(props: { prefix?: string; suffix: string }) { return ( -
    +
    {props.prefix ? : null}
    @@ -351,7 +352,7 @@ export function ToolbarSubtitle(props: { subtitle: React.ReactNode }) { return ( {props.subtitle} diff --git a/packages/gitbook/src/components/AdminToolbar/ToolbarDate.tsx b/packages/gitbook/src/components/AdminToolbar/ToolbarDate.tsx index aa2c021cd..312a4fee2 100644 --- a/packages/gitbook/src/components/AdminToolbar/ToolbarDate.tsx +++ b/packages/gitbook/src/components/AdminToolbar/ToolbarDate.tsx @@ -1,10 +1,10 @@ 'use client'; +import { AnimatePresence, motion } from 'motion/react'; import React from 'react'; -import { useLanguage } from '@/intl/client'; -import { AnimatePresence, motion } from 'motion/react'; import { formatDateTime, formatDateWeekday, formatRelative } from '../utils/dates'; +import { useLanguage } from '@/intl/client'; type DateFormat = 'relative' | 'weekday' | 'full'; diff --git a/packages/gitbook/src/components/AdminToolbar/ToolbarVisibilityHint.tsx b/packages/gitbook/src/components/AdminToolbar/ToolbarVisibilityHint.tsx index cc98a24cd..9db15ae0c 100644 --- a/packages/gitbook/src/components/AdminToolbar/ToolbarVisibilityHint.tsx +++ b/packages/gitbook/src/components/AdminToolbar/ToolbarVisibilityHint.tsx @@ -2,6 +2,7 @@ import { motion } from 'motion/react'; import React from 'react'; + import { getVisibilityHintDismissed, setVisibilityHintDismissed } from './utils'; interface ToolbarVisibilityHintProps { @@ -30,14 +31,14 @@ export function ToolbarVisibilityHint(props: ToolbarVisibilityHintProps) { stiffness: 300, damping: 25, }} - className="-translate-x-1/2 pointer-events-none absolute bottom-[calc(100%+2px)] left-1/2 flex items-center gap-1.5 rounded-lg border border-[#eaeaea] border-solid bg-white py-1 pr-1 pl-2" + className="pointer-events-none absolute bottom-[calc(100%+2px)] left-1/2 flex -translate-x-1/2 items-center gap-1.5 rounded-lg border border-solid border-[#eaeaea] bg-white py-1 pl-2 pr-1" > This toolbar appears only when signed in to GitBook.
    @@ -300,11 +291,7 @@ export function EmbeddableIframeCloseButton(props: { onClose?: () => void }) { onClose?.(); getChannel()?.send({ type: 'close' }); }} - tooltipProps={{ - contentProps: { - side: 'right', - }, - }} + tooltipProps={{ side: 'right' }} />
    ); diff --git a/packages/gitbook/src/components/Embeddable/EmbeddableRootLayout.tsx b/packages/gitbook/src/components/Embeddable/EmbeddableRootLayout.tsx index 13656d28d..0c91455ab 100644 --- a/packages/gitbook/src/components/Embeddable/EmbeddableRootLayout.tsx +++ b/packages/gitbook/src/components/Embeddable/EmbeddableRootLayout.tsx @@ -1,3 +1,12 @@ +import type { CustomizationDefaultThemeMode } from '@gitbook/api'; +import { SiteInsightsTrademarkPlacement } from '@gitbook/api'; + +import { NavigationLoader } from '../primitives/NavigationLoader'; +import { SpaceLayoutServerContext } from '../SpaceLayout'; +import { Trademark } from '../TableOfContents/Trademark'; +import { EmbeddableAIContextProvider } from './EmbeddableAIContextProvider'; +import { EmbeddableIframeAPI } from './EmbeddableIframeAPI'; +import { IfEmbeddableTrademark } from './EmbeddableTrademark'; import { CustomizationRootLayout } from '@/components/RootLayout'; import { SiteLayoutClientContexts, @@ -7,14 +16,6 @@ import { import type { VisitorAuthClaims } from '@/lib/adaptive'; import type { GitBookSiteContext } from '@/lib/context'; import { resolveEmbeddableTheme } from '@/lib/embeddable'; -import type { CustomizationDefaultThemeMode } from '@gitbook/api'; -import { SiteInsightsTrademarkPlacement } from '@gitbook/api'; -import { SpaceLayoutServerContext } from '../SpaceLayout'; -import { Trademark } from '../TableOfContents/Trademark'; -import { NavigationLoader } from '../primitives/NavigationLoader'; -import { EmbeddableAIContextProvider } from './EmbeddableAIContextProvider'; -import { EmbeddableIframeAPI } from './EmbeddableIframeAPI'; -import { IfEmbeddableTrademark } from './EmbeddableTrademark'; type EmbeddableRootLayoutProps = { context: GitBookSiteContext; @@ -70,7 +71,7 @@ export async function EmbeddableRootLayout({ {context.customization.trademark.enabled ? ( diff --git a/packages/gitbook/src/components/Embeddable/EmbeddableSearch.tsx b/packages/gitbook/src/components/Embeddable/EmbeddableSearch.tsx index 88e816f0a..711eafe60 100644 --- a/packages/gitbook/src/components/Embeddable/EmbeddableSearch.tsx +++ b/packages/gitbook/src/components/Embeddable/EmbeddableSearch.tsx @@ -1,14 +1,7 @@ 'use client'; -import { - type SearchBaseProps, - SearchFrame, - SearchInput, - SearchLiveResultsAnnouncer, - SearchScopeControl, - useSearchController, -} from '@/components/Search'; import React from 'react'; + import { useTrackEvent } from '../Insights'; import { LinkContext } from '../primitives'; import { @@ -17,6 +10,14 @@ import { EmbeddableIframeTabs, useEmbeddableLinkContext, } from './EmbeddableIframeAPI'; +import { + type SearchBaseProps, + SearchFrame, + SearchInput, + SearchLiveResultsAnnouncer, + SearchScopeControl, + useSearchController, +} from '@/components/Search'; type EmbeddableSearchProps = { baseURL: string; diff --git a/packages/gitbook/src/components/Embeddable/EmbeddableSearchPage.tsx b/packages/gitbook/src/components/Embeddable/EmbeddableSearchPage.tsx index b2299a3da..7406c17e3 100644 --- a/packages/gitbook/src/components/Embeddable/EmbeddableSearchPage.tsx +++ b/packages/gitbook/src/components/Embeddable/EmbeddableSearchPage.tsx @@ -1,6 +1,6 @@ +import { EmbeddableSearch } from './EmbeddableSearch'; import { getSearchBaseProps } from '@/components/Search/search-props'; import type { GitBookSiteContext } from '@/lib/context'; -import { EmbeddableSearch } from './EmbeddableSearch'; type EmbeddableSearchPageProps = { context: GitBookSiteContext; diff --git a/packages/gitbook/src/components/Embeddable/EmbeddableTrademark.tsx b/packages/gitbook/src/components/Embeddable/EmbeddableTrademark.tsx index ea40450da..0603fca70 100644 --- a/packages/gitbook/src/components/Embeddable/EmbeddableTrademark.tsx +++ b/packages/gitbook/src/components/Embeddable/EmbeddableTrademark.tsx @@ -1,11 +1,10 @@ 'use client'; import type React from 'react'; + import { useEmbeddableConfiguration } from './EmbeddableIframeAPI'; -export function IfEmbeddableTrademark(props: { - children: React.ReactNode; -}) { +export function IfEmbeddableTrademark(props: { children: React.ReactNode }) { const { children } = props; const embedTrademarkEnabled = useEmbeddableConfiguration((state) => state.trademark ?? true); diff --git a/packages/gitbook/src/components/Embeddable/channel.ts b/packages/gitbook/src/components/Embeddable/channel.ts index b90026e90..9377b848e 100644 --- a/packages/gitbook/src/components/Embeddable/channel.ts +++ b/packages/gitbook/src/components/Embeddable/channel.ts @@ -3,9 +3,9 @@ import { createChannel } from 'bidc'; import memoize from 'memoizee'; -// biome-ignore lint/suspicious/noExplicitAny: expected +// oxlint-disable-next-line typescript/no-explicit-any export function log(...data: any[]) { - // biome-ignore lint/suspicious/noConsole: expected + // oxlint-disable-next-line no-console console.log(...data); } diff --git a/packages/gitbook/src/components/Footer/Footer.tsx b/packages/gitbook/src/components/Footer/Footer.tsx index a6074c810..46c72ec39 100644 --- a/packages/gitbook/src/components/Footer/Footer.tsx +++ b/packages/gitbook/src/components/Footer/Footer.tsx @@ -1,14 +1,13 @@ -import type { GitBookSiteContext } from '@/lib/context'; import React from 'react'; -import { Image } from '@/components/utils'; -import { partition } from '@/lib/arrays'; -import { tcls } from '@/lib/tailwind'; - -import { ThemeToggler } from '../ThemeToggler'; import { CONTAINER_STYLE, CONTENT_STYLE } from '../layout'; +import { ThemeToggler } from '../ThemeToggler'; import { FooterLinksGroup } from './FooterLinksGroup'; import { SocialAccountButton } from './SocialAccounts'; +import { Image } from '@/components/utils'; +import { partition } from '@/lib/arrays'; +import type { GitBookSiteContext } from '@/lib/context'; +import { tcls } from '@/lib/tailwind'; const FOOTER_COLUMNS = 4; @@ -35,7 +34,7 @@ export function Footer(props: { context: GitBookSiteContext }) { mobileOnly ? 'xl:hidden' : null )} > -
    +
    0 ? (
    -
    +
    {partition(customization.footer.groups, FOOTER_COLUMNS).map( (column, columnIndex) => (
    +

    {customization.footer.copyright}

    ) : null diff --git a/packages/gitbook/src/components/Footer/FooterLinksGroup.tsx b/packages/gitbook/src/components/Footer/FooterLinksGroup.tsx index 8cad60c94..838ecda07 100644 --- a/packages/gitbook/src/components/Footer/FooterLinksGroup.tsx +++ b/packages/gitbook/src/components/Footer/FooterLinksGroup.tsx @@ -1,15 +1,14 @@ -import type { GitBookAnyContext } from '@/lib/context'; import { type CustomizationContentLink, type CustomizationFooterGroup, SiteInsightsLinkPosition, } from '@gitbook/api'; -import { resolveContentRef } from '@/lib/references'; -import { tcls } from '@/lib/tailwind'; - -import { getLocalizedTitle } from '@/lib/sites'; import { Link } from '../primitives'; +import type { GitBookAnyContext } from '@/lib/context'; +import { resolveContentRef } from '@/lib/references'; +import { getLocalizedTitle } from '@/lib/sites'; +import { tcls } from '@/lib/tailwind'; export function FooterLinksGroup(props: { group: CustomizationFooterGroup; diff --git a/packages/gitbook/src/components/Footer/SocialAccounts.tsx b/packages/gitbook/src/components/Footer/SocialAccounts.tsx index 2c595bf5b..b67f5a054 100644 --- a/packages/gitbook/src/components/Footer/SocialAccounts.tsx +++ b/packages/gitbook/src/components/Footer/SocialAccounts.tsx @@ -4,6 +4,7 @@ import { SiteSocialAccountPlatform, } from '@gitbook/api'; import type { IconName } from '@gitbook/icons'; + import { Button, type ButtonProps, DropdownMenuItem } from '../primitives'; type SocialPlatformData = { @@ -106,9 +107,7 @@ export function SocialAccountButton( ); } -export function SocialAccountLink(props: { - account: SiteSocialAccount; -}) { +export function SocialAccountLink(props: { account: SiteSocialAccount }) { const { account } = props; const platform = SOCIAL_PLATFORMS[account.platform]; diff --git a/packages/gitbook/src/components/Header/CurrentContentIcon.tsx b/packages/gitbook/src/components/Header/CurrentContentIcon.tsx index 39e0f4664..d4267f287 100644 --- a/packages/gitbook/src/components/Header/CurrentContentIcon.tsx +++ b/packages/gitbook/src/components/Header/CurrentContentIcon.tsx @@ -1,7 +1,6 @@ -import { Image } from '@/components/utils'; - -import type { GitBookSiteContext } from '@/lib/context'; import { Emoji } from '../primitives'; +import { Image } from '@/components/utils'; +import type { GitBookSiteContext } from '@/lib/context'; /** * Icon for the current content. diff --git a/packages/gitbook/src/components/Header/Header.tsx b/packages/gitbook/src/components/Header/Header.tsx index b4c791047..29abf62d6 100644 --- a/packages/gitbook/src/components/Header/Header.tsx +++ b/packages/gitbook/src/components/Header/Header.tsx @@ -1,9 +1,5 @@ -import type { GitBookSiteContext } from '@/lib/context'; - -import { CONTAINER_STYLE, HEADER_HEIGHT_DESKTOP } from '@/components/layout'; -import { getSpaceLanguage, t } from '@/intl/server'; -import { tcls } from '@/lib/tailwind'; import type { SiteSpace } from '@gitbook/api'; + import { SocialAccountButton } from '../Footer/SocialAccounts'; import { SearchContainer, getSearchBaseProps } from '../Search'; import { SiteSectionTabs, encodeClientSiteSections } from '../SiteSections'; @@ -13,6 +9,10 @@ import { HeaderLinks } from './HeaderLinks'; import { HeaderLogo } from './HeaderLogo'; import { HeaderMobileMenu } from './HeaderMobileMenu'; import { TranslationsDropdown } from './SpacesDropdown'; +import { CONTAINER_STYLE, HEADER_HEIGHT_DESKTOP } from '@/components/layout'; +import { getSpaceLanguage, t } from '@/intl/server'; +import type { GitBookSiteContext } from '@/lib/context'; +import { tcls } from '@/lib/tailwind'; /** * Render the header for the space. @@ -32,8 +32,8 @@ export async function Header(props: { const withSections = Boolean( visibleSections && - (visibleSections.list.length > 1 || // Show section tabs if there are at least 2 sections or at least 1 section group - visibleSections.list.some((s) => s.object === 'site-section-group')) + (visibleSections.list.length > 1 || // Show section tabs if there are at least 2 sections or at least 1 section group + visibleSections.list.some((s) => s.object === 'site-section-group')) ); const headerSocialAccounts = customization.socialAccounts.filter( @@ -75,7 +75,7 @@ export async function Header(props: { 'site-header:theme-bold:shadow-tint-12/2' )} > -
    +
    ); })} @@ -206,7 +206,7 @@ export async function Header(props: {
    {visibleSections && withSections ? ( -
    +
    {variants.translations.length > 1 ? ( ) } + nativeButton={false} openOnHover={true} > {children} @@ -144,12 +146,12 @@ function getHeaderLinkClassName(_props: { headerPreset: CustomizationHeaderPrese 'text-tint', 'links-default:hover:text-primary', - 'links-default:data-[state=open]:text-primary', + 'links-default:aria-expanded:text-primary', 'links-default:tint:hover:text-tint-strong', - 'links-default:tint:data-[state=open]:text-tint-strong', + 'links-default:tint:aria-expanded:text-tint-strong', 'underline-offset-2', 'links-accent:hover:underline', - 'links-accent:data-[state=open]:underline', + 'links-accent:aria-expanded:underline', 'links-accent:underline-offset-4', 'links-accent:decoration-primary-subtle', 'links-accent:decoration-[3px]', diff --git a/packages/gitbook/src/components/Header/HeaderLinkMore.tsx b/packages/gitbook/src/components/Header/HeaderLinkMore.tsx index e4456682a..76a99a229 100644 --- a/packages/gitbook/src/components/Header/HeaderLinkMore.tsx +++ b/packages/gitbook/src/components/Header/HeaderLinkMore.tsx @@ -1,26 +1,26 @@ -import { isSiteAuthLoginHref } from '@/lib/auth-login-link'; -import type { GitBookSiteContext } from '@/lib/context'; +import type React from 'react'; + import { type CustomizationContentLink, type CustomizationHeaderItem, SiteInsightsLinkPosition, type SiteSocialAccount, } from '@gitbook/api'; -import type React from 'react'; - -import { resolveContentRef } from '@/lib/references'; -import { getLocalizedTitle } from '@/lib/sites'; -import { tcls } from '@/lib/tailwind'; import { SocialAccountLink } from '../Footer/SocialAccounts'; -import { SiteAuthLoginDropdownMenuItem } from '../SiteAuth/SiteAuthLoginLink'; import { DropdownMenuItem, DropdownMenuSeparator, DropdownSubMenu, } from '../primitives/DropdownMenu'; +import { SiteAuthLoginDropdownMenuItem } from '../SiteAuth/SiteAuthLoginLink'; import { HeaderLinkMoreDropdown } from './HeaderLinkMoreClient'; import styles from './headerLinks.module.css'; +import { isSiteAuthLoginHref } from '@/lib/auth-login-link'; +import type { GitBookSiteContext } from '@/lib/context'; +import { resolveContentRef } from '@/lib/references'; +import { getLocalizedTitle } from '@/lib/sites'; +import { tcls } from '@/lib/tailwind'; /** * Dropdown menu for header links hidden at small screen size. diff --git a/packages/gitbook/src/components/Header/HeaderLinkMoreClient.tsx b/packages/gitbook/src/components/Header/HeaderLinkMoreClient.tsx index f1012c551..c8e9efa3d 100644 --- a/packages/gitbook/src/components/Header/HeaderLinkMoreClient.tsx +++ b/packages/gitbook/src/components/Header/HeaderLinkMoreClient.tsx @@ -1,15 +1,17 @@ 'use client'; -import { Icon } from '@gitbook/icons'; import type React from 'react'; -import { type ClassValue, tcls } from '@/lib/tailwind'; +import { Icon } from '@gitbook/icons'; + import { ToggleChevron } from '../primitives'; import { DropdownMenu } from '../primitives/DropdownMenu'; +import { type ClassValue, tcls } from '@/lib/tailwind'; /** * Client component for the "More" header link dropdown. - * Creates the trigger button internally to avoid Flight lazy chunk wrappers reaching Radix's Slot. + * Creates the trigger button internally to avoid Flight lazy chunk wrappers reaching the trigger's + * `render` prop. */ export function HeaderLinkMoreDropdown(props: { label: React.ReactNode; diff --git a/packages/gitbook/src/components/Header/HeaderLinks.tsx b/packages/gitbook/src/components/Header/HeaderLinks.tsx index da2e01e83..5a4222592 100644 --- a/packages/gitbook/src/components/Header/HeaderLinks.tsx +++ b/packages/gitbook/src/components/Header/HeaderLinks.tsx @@ -1,8 +1,7 @@ import type React from 'react'; -import { type ClassValue, tcls } from '@/lib/tailwind'; - import styles from './headerLinks.module.css'; +import { type ClassValue, tcls } from '@/lib/tailwind'; interface HeaderLinksProps { children: React.ReactNode; diff --git a/packages/gitbook/src/components/Header/HeaderLogo.tsx b/packages/gitbook/src/components/Header/HeaderLogo.tsx index c553b8178..557d046bd 100644 --- a/packages/gitbook/src/components/Header/HeaderLogo.tsx +++ b/packages/gitbook/src/components/Header/HeaderLogo.tsx @@ -1,11 +1,9 @@ -import type { GitBookSiteContext } from '@/lib/context'; - -import { Image } from '@/components/utils'; -import { tcls } from '@/lib/tailwind'; - -import { resolveContentRef } from '@/lib/references'; import { Link } from '../primitives'; import { CurrentContentIcon } from './CurrentContentIcon'; +import { Image } from '@/components/utils'; +import type { GitBookSiteContext } from '@/lib/context'; +import { resolveContentRef } from '@/lib/references'; +import { tcls } from '@/lib/tailwind'; interface HeaderLogoProps { context: GitBookSiteContext; diff --git a/packages/gitbook/src/components/Header/HeaderMobileMenu.tsx b/packages/gitbook/src/components/Header/HeaderMobileMenu.tsx index 1803296a9..1b020f8fb 100644 --- a/packages/gitbook/src/components/Header/HeaderMobileMenu.tsx +++ b/packages/gitbook/src/components/Header/HeaderMobileMenu.tsx @@ -2,9 +2,8 @@ import { usePathname } from 'next/navigation'; import { useEffect } from 'react'; -import { tString, useLanguage } from '@/intl/client'; - import { Button, type ButtonProps } from '../primitives'; +import { tString, useLanguage } from '@/intl/client'; const globalClassName = 'navigation-open'; diff --git a/packages/gitbook/src/components/Header/SpacesDropdown.tsx b/packages/gitbook/src/components/Header/SpacesDropdown.tsx index c9fa092bc..befded446 100644 --- a/packages/gitbook/src/components/Header/SpacesDropdown.tsx +++ b/packages/gitbook/src/components/Header/SpacesDropdown.tsx @@ -1,11 +1,11 @@ import type { SiteSpace } from '@gitbook/api'; import type { IconName } from '@gitbook/icons'; +import type { ButtonProps } from '../primitives'; +import { SpacesDropdownClient } from './SpacesDropdownClient'; import type { GitBookSiteContext } from '@/lib/context'; import { getLocalizedTitle, getSiteSpaceURL } from '@/lib/sites'; import { tcls } from '@/lib/tailwind'; -import type { ButtonProps } from '../primitives'; -import { SpacesDropdownClient } from './SpacesDropdownClient'; // Memoized regex for checking if a string starts with an emoji const EMOJI_REGEX = /^\p{Emoji}/u; diff --git a/packages/gitbook/src/components/Header/SpacesDropdownClient.tsx b/packages/gitbook/src/components/Header/SpacesDropdownClient.tsx index 3fe46ca52..7e69844c1 100644 --- a/packages/gitbook/src/components/Header/SpacesDropdownClient.tsx +++ b/packages/gitbook/src/components/Header/SpacesDropdownClient.tsx @@ -2,14 +2,14 @@ import type { IconName } from '@gitbook/icons'; -import { type ClassValue, tcls } from '@/lib/tailwind'; import { Button, type ButtonProps, ToggleChevron } from '../primitives'; import { DropdownMenu } from '../primitives/DropdownMenu'; import { SpacesDropdownMenuItems } from './SpacesDropdownMenuItem'; +import { type ClassValue, tcls } from '@/lib/tailwind'; /** - * Client component that creates the Button trigger and DropdownMenu internally, - * avoiding server→client element serialization through Radix's Slot. + * Client component that creates the Button trigger and DropdownMenu internally, avoiding + * server→client element serialization through the trigger's `render` prop. */ export function SpacesDropdownClient(props: { title: string; @@ -17,13 +17,13 @@ export function SpacesDropdownClient(props: { variant: ButtonProps['variant']; className?: ClassValue; dropdownClassName: string; - slimSpaces: Array<{ + slimSpaces: { id: string; title: string; url: string; isActive: boolean; spaceId: string; - }>; + }[]; curPath: string; }) { const { title, icon, variant, className, dropdownClassName, slimSpaces, curPath } = props; diff --git a/packages/gitbook/src/components/Header/SpacesDropdownMenuItem.tsx b/packages/gitbook/src/components/Header/SpacesDropdownMenuItem.tsx index 247010599..fed104203 100644 --- a/packages/gitbook/src/components/Header/SpacesDropdownMenuItem.tsx +++ b/packages/gitbook/src/components/Header/SpacesDropdownMenuItem.tsx @@ -1,8 +1,8 @@ 'use client'; -import { joinPath } from '@/lib/paths'; import { useCurrentPageMetadata, useCurrentPagePath } from '../hooks'; import { DropdownMenuItem } from '../primitives/DropdownMenu'; +import { joinPath } from '@/lib/paths'; export interface VariantSpace { id: string; @@ -66,10 +66,7 @@ export function SpacesDropdownMenuItem(props: { ); } -export function SpacesDropdownMenuItems(props: { - slimSpaces: VariantSpace[]; - curPath: string; -}) { +export function SpacesDropdownMenuItems(props: { slimSpaces: VariantSpace[]; curPath: string }) { const { slimSpaces, curPath } = props; return ( diff --git a/packages/gitbook/src/components/Insights/InsightsProvider.tsx b/packages/gitbook/src/components/Insights/InsightsProvider.tsx index 1209ac344..40789941d 100644 --- a/packages/gitbook/src/components/Insights/InsightsProvider.tsx +++ b/packages/gitbook/src/components/Insights/InsightsProvider.tsx @@ -1,14 +1,15 @@ 'use client'; -import type * as api from '@gitbook/api'; -import { OpenAPIOperationContextProvider } from '@gitbook/react-openapi'; import * as React from 'react'; import { useDebounceCallback, useEventCallback } from 'usehooks-ts'; -import { getAllBrowserCookiesMap } from '@/lib/browser'; +import type * as api from '@gitbook/api'; +import { OpenAPIOperationContextProvider } from '@gitbook/react-openapi'; + import { type CurrentContentContext, useCurrentContent } from '../hooks'; import { getSession } from './sessions'; import { type VisitorResponse, useVisitor } from './visitorId'; +import { getAllBrowserCookiesMap } from '@/lib/browser'; export type InsightsEventName = api.SiteInsightsEvent['type']; @@ -216,10 +217,7 @@ export function useTrackEvent(): TrackEventCallback { /** * Post the events to the server. */ -function sendEvents(args: { - eventUrl: string; - events: api.SiteInsightsEvent[]; -}) { +function sendEvents(args: { eventUrl: string; events: api.SiteInsightsEvent[] }) { const { eventUrl, events } = args; fetch(eventUrl, { diff --git a/packages/gitbook/src/components/Insights/TrackPageViewEvent.tsx b/packages/gitbook/src/components/Insights/TrackPageViewEvent.tsx index c2cfbf0ec..310ab4836 100644 --- a/packages/gitbook/src/components/Insights/TrackPageViewEvent.tsx +++ b/packages/gitbook/src/components/Insights/TrackPageViewEvent.tsx @@ -1,17 +1,16 @@ 'use client'; -import type { SiteInsightsDisplayContext } from '@gitbook/api'; import * as React from 'react'; +import type { SiteInsightsDisplayContext } from '@gitbook/api'; + import { useCurrentPage } from '../hooks'; import { useTrackEvent } from './InsightsProvider'; /** * Track a page view event. */ -export function TrackPageViewEvent(props: { - displayContext: SiteInsightsDisplayContext; -}) { +export function TrackPageViewEvent(props: { displayContext: SiteInsightsDisplayContext }) { const { displayContext } = props; const page = useCurrentPage(); const trackEvent = useTrackEvent(); diff --git a/packages/gitbook/src/components/Insights/sessions.ts b/packages/gitbook/src/components/Insights/sessions.ts index 1575dbd53..1715ef43a 100644 --- a/packages/gitbook/src/components/Insights/sessions.ts +++ b/packages/gitbook/src/components/Insights/sessions.ts @@ -1,8 +1,7 @@ 'use client'; -import { getLocalStorageItem, setLocalStorageItem } from '@/lib/browser'; - import { generateRandomId } from './utils'; +import { getLocalStorageItem, setLocalStorageItem } from '@/lib/browser'; const SESSION_TTL = 1000 * 60 * 30; // 30 minutes diff --git a/packages/gitbook/src/components/Insights/visitorId.tsx b/packages/gitbook/src/components/Insights/visitorId.tsx index 42dc815c5..07e0bc4a4 100644 --- a/packages/gitbook/src/components/Insights/visitorId.tsx +++ b/packages/gitbook/src/components/Insights/visitorId.tsx @@ -1,10 +1,14 @@ 'use client'; -import type { SiteInsightsSession } from '@gitbook/api'; import type { MaybePromise } from 'p-map'; import React from 'react'; import { createStore, useStore } from 'zustand'; +import type { SiteInsightsSession } from '@gitbook/api'; + +import { isCookiesTrackingDisabled } from './cookies'; +import { getSession } from './sessions'; +import { generateRandomId } from './utils'; import { getBrowserCookie, getLocalStorageItem, @@ -12,10 +16,6 @@ import { setLocalStorageItem, } from '@/lib/browser'; -import { isCookiesTrackingDisabled } from './cookies'; -import { getSession } from './sessions'; -import { generateRandomId } from './utils'; - const VISITORID_COOKIE = '__session'; const VISITOR_STORAGE_KEY = '__session_updated'; @@ -79,10 +79,10 @@ export type VisitorResponse = AnyVisitorResponse | VisitorUserResponse; function isVisitor(value: unknown): value is VisitorResponse { return Boolean( value && - typeof value === 'object' && - 'deviceId' in value && - typeof value.deviceId === 'string' && - value.deviceId + typeof value === 'object' && + 'deviceId' in value && + typeof value.deviceId === 'string' && + value.deviceId ); } diff --git a/packages/gitbook/src/components/Integrations/LoadIntegrations.tsx b/packages/gitbook/src/components/Integrations/LoadIntegrations.tsx index 4910c1498..83ea00f53 100644 --- a/packages/gitbook/src/components/Integrations/LoadIntegrations.tsx +++ b/packages/gitbook/src/components/Integrations/LoadIntegrations.tsx @@ -1,20 +1,22 @@ 'use client'; -import { - isCookiesTrackingDisabled, - isGlobalPrivacyControlEnabled, - setCookiesTracking, -} from '@/components/Insights'; -import { isAIUserAgent } from '@/lib/browser'; +import * as React from 'react'; +import * as zustand from 'zustand'; + import type { GitBookGlobal, GitBookIntegrationEvent, GitBookIntegrationEventCallback, GitBookIntegrationTool, } from '@gitbook/browser-types'; -import * as React from 'react'; -import * as zustand from 'zustand'; + import type { Assistant } from '../AI'; +import { + isCookiesTrackingDisabled, + isGlobalPrivacyControlEnabled, + setCookiesTracking, +} from '@/components/Insights'; +import { isAIUserAgent } from '@/lib/browser'; const events = new Map(); @@ -29,7 +31,7 @@ export const integrationsAssistantTools = zustand.createStore<{ }; }); -export const integrationAssistants = zustand.createStore>(() => []); +export const integrationAssistants = zustand.createStore(() => []); // Store to track when integrations have been loaded export const integrationsStore = zustand.createStore<{ @@ -121,7 +123,7 @@ if (typeof window !== 'undefined') { /** * Get the current state of the assistants. */ -export function useIntegrationAssistants(): Array { +export function useIntegrationAssistants(): Assistant[] { return zustand.useStore(integrationAssistants); } diff --git a/packages/gitbook/src/components/PDF/ImagesLoadingStatus.tsx b/packages/gitbook/src/components/PDF/ImagesLoadingStatus.tsx index e1237c42b..e87c4df60 100644 --- a/packages/gitbook/src/components/PDF/ImagesLoadingStatus.tsx +++ b/packages/gitbook/src/components/PDF/ImagesLoadingStatus.tsx @@ -1,17 +1,16 @@ 'use client'; -import { tString } from '@/intl/translate'; -import type { TranslationLanguage } from '@/intl/translations'; import assertNever from 'assert-never'; import * as React from 'react'; -export function ImagesLoadingStatus(props: { - language: TranslationLanguage; -}) { +import { tString } from '@/intl/translate'; +import type { TranslationLanguage } from '@/intl/translations'; + +export function ImagesLoadingStatus(props: { language: TranslationLanguage }) { const { language } = props; const state = useImagesLoadingState(); return ( -

    +

    {(() => { switch (state.status) { case 'pending': diff --git a/packages/gitbook/src/components/PDF/PDFPage.test.ts b/packages/gitbook/src/components/PDF/PDFPage.test.ts index 3bae0781c..3073a315b 100644 --- a/packages/gitbook/src/components/PDF/PDFPage.test.ts +++ b/packages/gitbook/src/components/PDF/PDFPage.test.ts @@ -1,9 +1,9 @@ import { describe, expect, it } from 'bun:test'; + import { RevisionPageType } from '@gitbook/api'; -import { createLinker } from '@/lib/links'; - import { createPDFLinker } from './linker'; +import { createLinker } from '@/lib/links'; function createDocumentPage(id: string, path: string) { return { diff --git a/packages/gitbook/src/components/PDF/PDFPage.tsx b/packages/gitbook/src/components/PDF/PDFPage.tsx index 64d783c47..86f56562d 100644 --- a/packages/gitbook/src/components/PDF/PDFPage.tsx +++ b/packages/gitbook/src/components/PDF/PDFPage.tsx @@ -1,4 +1,7 @@ -import type { GitBookSiteContext, GitBookSpaceContext } from '@/lib/context'; +import type { Metadata } from 'next'; +import { notFound } from 'next/navigation'; +import * as React from 'react'; + import { type Revision, type RevisionPageDocument, @@ -8,27 +11,24 @@ import { type Space, } from '@gitbook/api'; import { Icon } from '@gitbook/icons'; -import type { Metadata } from 'next'; -import { notFound } from 'next/navigation'; -import * as React from 'react'; +import { ImagesLoadingStatus } from './ImagesLoadingStatus'; +import { createPDFLinker, getPagePDFContainerId } from './linker'; +import { PageControlButtons } from './PageControlButtons'; +import { PDFPrintControls } from './PDFPrintControls'; +import { type PDFSearchParams, getPDFSearchParams } from './urls'; import { DocumentView } from '@/components/DocumentView'; import { Trademark } from '@/components/TableOfContents/Trademark'; import type { PolymorphicComponentProp } from '@/components/utils/types'; import { getSpaceLanguage } from '@/intl/server'; import { tString } from '@/intl/translate'; +import { sanitizeGitBookAppURL } from '@/lib/app'; +import type { GitBookSiteContext, GitBookSpaceContext } from '@/lib/context'; +import { getPageDocument } from '@/lib/data'; +import './pdf.css'; import { resolvePageId } from '@/lib/pages'; import { tcls } from '@/lib/tailwind'; import { defaultCustomization } from '@/lib/utils'; -import { type PDFSearchParams, getPDFSearchParams } from './urls'; - -import { PDFPrintControls } from './PDFPrintControls'; -import { PageControlButtons } from './PageControlButtons'; -import { createPDFLinker, getPagePDFContainerId } from './linker'; -import './pdf.css'; -import { sanitizeGitBookAppURL } from '@/lib/app'; -import { getPageDocument } from '@/lib/data'; -import { ImagesLoadingStatus } from './ImagesLoadingStatus'; const DEFAULT_LIMIT = 100; @@ -105,7 +105,7 @@ export async function PDFPage(props: {

    ) : null} -
    +
    @@ -147,16 +147,13 @@ export async function PDFPage(props: { ); } -async function PDFSpaceIntro(props: { - space: Space; - customization: SiteCustomizationSettings; -}) { +async function PDFSpaceIntro(props: { space: Space; customization: SiteCustomizationSettings }) { const { space, customization } = props; return (
    -

    {customization.title ?? space.title}

    +

    {customization.title ?? space.title}

    ); @@ -168,7 +165,7 @@ async function PDFPageGroup(props: { space: Space; page: RevisionPageGroup }) { return (
    -

    {page.title}

    +

    {page.title}

    ); @@ -183,9 +180,9 @@ async function PDFPageDocument(props: { return ( -

    {page.title}

    +

    {page.title}

    {page.description ? ( -

    {page.description}

    +

    {page.description}

    ) : null} {document ? ( diff --git a/packages/gitbook/src/components/PDF/PDFPrintControls.tsx b/packages/gitbook/src/components/PDF/PDFPrintControls.tsx index 4b5530375..dbd403a84 100644 --- a/packages/gitbook/src/components/PDF/PDFPrintControls.tsx +++ b/packages/gitbook/src/components/PDF/PDFPrintControls.tsx @@ -1,8 +1,8 @@ -import { tString } from '@/intl/translate'; -import type { TranslationLanguage } from '@/intl/translations'; import { Icon } from '@gitbook/icons'; import { PrintButton } from './PrintButton'; +import { tString } from '@/intl/translate'; +import type { TranslationLanguage } from '@/intl/translations'; export function PDFPrintControls(props: { language: TranslationLanguage }) { const { language } = props; @@ -10,7 +10,7 @@ export function PDFPrintControls(props: { language: TranslationLanguage }) { return ( diff --git a/packages/gitbook/src/components/PDF/PDFRootLayout.tsx b/packages/gitbook/src/components/PDF/PDFRootLayout.tsx index e6f71a910..086bf3078 100644 --- a/packages/gitbook/src/components/PDF/PDFRootLayout.tsx +++ b/packages/gitbook/src/components/PDF/PDFRootLayout.tsx @@ -1,6 +1,7 @@ +import { CustomizationDefaultThemeMode } from '@gitbook/api'; + import { CustomizationRootLayout } from '@/components/RootLayout'; import type { GitBookSiteContext, GitBookSpaceContext } from '@/lib/context'; -import { CustomizationDefaultThemeMode } from '@gitbook/api'; /** * Layout to be used for rendering the PDF. diff --git a/packages/gitbook/src/components/PDF/PageControlButtons.tsx b/packages/gitbook/src/components/PDF/PageControlButtons.tsx index 5bda9793c..455e28ffa 100644 --- a/packages/gitbook/src/components/PDF/PageControlButtons.tsx +++ b/packages/gitbook/src/components/PDF/PageControlButtons.tsx @@ -1,13 +1,14 @@ 'use client'; -import { Icon } from '@gitbook/icons'; import React from 'react'; +import { Icon } from '@gitbook/icons'; + +import { type PDFSearchParams, getPDFURLSearchParams } from './urls'; import { useScrollActiveId } from '@/components/hooks'; import { Button } from '@/components/primitives'; import { t, tString, useLanguage } from '@/intl/client'; import { tcls } from '@/lib/tailwind'; -import { type PDFSearchParams, getPDFURLSearchParams } from './urls'; const limitExtend = 50; @@ -17,7 +18,7 @@ const limitExtend = 50; export function PageControlButtons(props: { params: PDFSearchParams; /** Array of the [pageId, divId] */ - pageIds: Array<[string, string]>; + pageIds: [string, string][]; /** Total number of pages targetted by the generation */ total: number; /** Trademark to display */ diff --git a/packages/gitbook/src/components/PDF/linker.ts b/packages/gitbook/src/components/PDF/linker.ts index 188a3b651..a6b824a9c 100644 --- a/packages/gitbook/src/components/PDF/linker.ts +++ b/packages/gitbook/src/components/PDF/linker.ts @@ -36,7 +36,7 @@ export function getPagePDFContainerId( */ export function createPDFLinker( baseLinker: GitBookLinker, - pages: Array<{ page: Revision['pages'][number] }>, + pages: { page: Revision['pages'][number] }[], publishedSpaceURL?: string ): GitBookLinker { return { diff --git a/packages/gitbook/src/components/PageActions/PageActions.tsx b/packages/gitbook/src/components/PageActions/PageActions.tsx index 38b6ff31b..37eaa02ea 100644 --- a/packages/gitbook/src/components/PageActions/PageActions.tsx +++ b/packages/gitbook/src/components/PageActions/PageActions.tsx @@ -1,17 +1,19 @@ 'use client'; +import assertNever from 'assert-never'; +import QuickLRU from 'quick-lru'; +import React from 'react'; +import { createStore, useStore } from 'zustand'; + +import type { GitSyncState } from '@gitbook/api'; +import { Icon, type IconName, IconStyle } from '@gitbook/icons'; + import { useAIChatController, useAIChatState } from '@/components/AI'; import type { Assistant } from '@/components/AI'; import { Button } from '@/components/primitives/Button'; import { DropdownMenuItem, useDropdownMenuClose } from '@/components/primitives/DropdownMenu'; import { getURLForLLM } from '@/components/utils'; import { tString, useLanguage } from '@/intl/client'; -import type { GitSyncState } from '@gitbook/api'; -import { Icon, type IconName, IconStyle } from '@gitbook/icons'; -import assertNever from 'assert-never'; -import QuickLRU from 'quick-lru'; -import React from 'react'; -import { createStore, useStore } from 'zustand'; type PageActionType = 'button' | 'dropdown-menu-item'; @@ -515,12 +517,12 @@ function PageActionWrapper(props: {
    - {label} + {label} {href && target === '_blank' ? ( ) : null} - {description && {description}} + {description && {description}}
    ); diff --git a/packages/gitbook/src/components/PageActions/PageActionsDropdown.tsx b/packages/gitbook/src/components/PageActions/PageActionsDropdown.tsx index 3962358b6..a18a1c4db 100644 --- a/packages/gitbook/src/components/PageActions/PageActionsDropdown.tsx +++ b/packages/gitbook/src/components/PageActions/PageActionsDropdown.tsx @@ -1,14 +1,13 @@ 'use client'; -import { Button, ButtonGroup } from '@/components/primitives/Button'; -import { DropdownMenu, DropdownMenuSeparator } from '@/components/primitives/DropdownMenu'; -import { tString, useLanguage } from '@/intl/client'; +import { type ReactNode, useRef } from 'react'; + import type { CustomizationPageActionType, GitSyncState, SiteCustomizationSettings, } from '@gitbook/api'; -import { type ReactNode, useRef } from 'react'; + import { type Assistant, useAI } from '../AI'; import { ToggleChevron } from '../primitives'; import { @@ -24,6 +23,9 @@ import { ActionViewAsRSS, type PageActionAssistantContext, } from './PageActions'; +import { Button, ButtonGroup } from '@/components/primitives/Button'; +import { DropdownMenu, DropdownMenuSeparator } from '@/components/primitives/DropdownMenu'; +import { tString, useLanguage } from '@/intl/client'; /** * Type of a built-in page action that can be displayed in the page actions menu. diff --git a/packages/gitbook/src/components/PageAside/PageAside.tsx b/packages/gitbook/src/components/PageAside/PageAside.tsx index 791e42133..df94de58e 100644 --- a/packages/gitbook/src/components/PageAside/PageAside.tsx +++ b/packages/gitbook/src/components/PageAside/PageAside.tsx @@ -1,7 +1,5 @@ -import { getSpaceLanguage, t, tString } from '@/intl/server'; -import type { GitBookSiteContext } from '@/lib/context'; -import { getDocumentSections } from '@/lib/document-sections'; -import { tcls } from '@/lib/tailwind'; +import React from 'react'; + import { type JSONDocument, type RevisionPageDocument, @@ -9,17 +7,20 @@ import { SiteAdsStatus, SiteInsightsAdPlacement, } from '@gitbook/api'; -import React from 'react'; - import { Icon } from '@gitbook/icons'; + import { Ad } from '../Ads'; import { UpdatesTagFilters } from '../DocumentView/UpdatesFilter'; import { PageFeedbackForm } from '../PageFeedback'; -import { ThemeToggler } from '../ThemeToggler'; import { SideSheet } from '../primitives/SideSheet'; +import { ThemeToggler } from '../ThemeToggler'; import { PageAsideCloseButton } from './PageAsideButton'; import { ScrollSectionsList } from './ScrollSectionsList'; import { ScrollToTopButton } from './ScrollToTopButton'; +import { getSpaceLanguage, t, tString } from '@/intl/server'; +import type { GitBookSiteContext } from '@/lib/context'; +import { getDocumentSections } from '@/lib/document-sections'; +import { tcls } from '@/lib/tailwind'; /** * Aside listing the headings in the document. @@ -78,18 +79,18 @@ export async function PageAside(props: { 'lg:z-10', 'lg:hover:z-12', - 'layout-default:xl:not-chat-open:pr-0', - 'layout-default:xl:not-chat-open:pl-8', - 'layout-default:xl:not-chat-open:flex!', - 'layout-default:xl:not-chat-open:animate-none!', + 'layout-default:xl:chat-closed:pr-0', + 'layout-default:xl:chat-closed:pl-8', + 'layout-default:xl:chat-closed:flex!', + 'layout-default:xl:chat-closed:animate-none!', 'layout-default:3xl:flex!', 'layout-default:3xl:animate-none!', // In layout-wide mode, hide outline when viewport is too narrow // or when chat is open and viewport is narrow, to prevent layout overflow 'layout-wide:xl:-mr-68', - 'layout-wide:3xl:not-chat-open:flex!', - 'layout-wide:3xl:not-chat-open:animate-none!', + 'layout-wide:3xl:chat-closed:flex!', + 'layout-wide:3xl:chat-closed:animate-none!', // Show outline if page has OpenAPI block // TODO: remove this in favour of a nicer, more immediately accessible solution in the future. @@ -131,12 +132,12 @@ export async function PageAside(props: { > {' '} {t(language, 'on_this_page')} - +
    {document ? ( @@ -168,10 +169,7 @@ async function PageAsideSections(props: { document: JSONDocument; context: GitBo ) : null; } -function PageAsideActions(props: { - withPageFeedback: boolean; - page: RevisionPageDocument; -}) { +function PageAsideActions(props: { withPageFeedback: boolean; page: RevisionPageDocument }) { const { page, withPageFeedback } = props; return ( diff --git a/packages/gitbook/src/components/PageAside/PageAsideButton.tsx b/packages/gitbook/src/components/PageAside/PageAsideButton.tsx index 085498234..2e658ffaa 100644 --- a/packages/gitbook/src/components/PageAside/PageAsideButton.tsx +++ b/packages/gitbook/src/components/PageAside/PageAsideButton.tsx @@ -1,9 +1,10 @@ 'use client'; -import { useLanguage } from '@/intl/client'; -import { tString } from '@/intl/translate'; import { usePathname } from 'next/navigation'; import { useEffect } from 'react'; + import { Button } from '../primitives'; +import { useLanguage } from '@/intl/client'; +import { tString } from '@/intl/translate'; const globalClassName = 'outline-open'; @@ -27,7 +28,7 @@ export function PageAsideToggleButton() { onClick={() => { document.body.classList.toggle(globalClassName); }} - className="layout-default:hidden layout-wide:3xl:hidden page-no-outline:hidden layout-wide:max-xl:hidden page-api-block:min-[96rem]:hidden" + className="page-api-block:min-[96rem]:hidden layout-default:hidden page-no-outline:hidden layout-wide:max-xl:hidden layout-wide:3xl:hidden" />
    {rating ? ( submitted ? ( -
    +
    {tString(languages, 'was_this_helpful_thank_you')}
    diff --git a/packages/gitbook/src/components/RootLayout/CustomizationRootLayout.tsx b/packages/gitbook/src/components/RootLayout/CustomizationRootLayout.tsx index bf7878295..a7af18e60 100644 --- a/packages/gitbook/src/components/RootLayout/CustomizationRootLayout.tsx +++ b/packages/gitbook/src/components/RootLayout/CustomizationRootLayout.tsx @@ -1,3 +1,5 @@ +import * as ReactDOM from 'react-dom'; + import { CustomizationDefaultThemeMode, CustomizationSidebarBackgroundStyle, @@ -19,17 +21,16 @@ import { hexToRgb, } from '@gitbook/colors'; import { IconsProvider } from '@gitbook/icons'; -import * as ReactDOM from 'react-dom'; +import { AnnouncementDismissedScript } from '../Announcement'; +import { SelectStateScript } from '../Select'; +import { OperatingSystemClassScript } from './OperatingSystemClassScript'; +import { RootLayoutClientContexts } from './RootLayoutClientContexts'; import { type FontData, getFontData } from '@/fonts'; import { fontNotoColorEmoji, fonts } from '@/fonts/default'; +import './globals.css'; import { getContentLocale, getSpaceLanguage } from '@/intl/server'; import { getAssetURL } from '@/lib/assets'; -import { tcls } from '@/lib/tailwind'; - -import { RootLayoutClientContexts } from './RootLayoutClientContexts'; - -import './globals.css'; import type { GitBookAnyContext } from '@/lib/context'; import { GITBOOK_FONTS_URL, GITBOOK_ICONS_TOKEN, GITBOOK_ICONS_URL } from '@/lib/env'; import { @@ -38,10 +39,8 @@ import { getDefaultInlineIconSourceRequests, getInlineIconSources, } from '@/lib/icons/inline'; +import { tcls } from '@/lib/tailwind'; import { defaultCustomization } from '@/lib/utils'; -import { AnnouncementDismissedScript } from '../Announcement'; -import { SelectStateScript } from '../Select'; -import { OperatingSystemClassScript } from './OperatingSystemClassScript'; function preloadFont(fontData: FontData) { if (fontData.type === 'custom') { diff --git a/packages/gitbook/src/components/RootLayout/RootLayoutClientContexts.tsx b/packages/gitbook/src/components/RootLayout/RootLayoutClientContexts.tsx index c7c2b9fed..88957646d 100644 --- a/packages/gitbook/src/components/RootLayout/RootLayoutClientContexts.tsx +++ b/packages/gitbook/src/components/RootLayout/RootLayoutClientContexts.tsx @@ -1,12 +1,12 @@ 'use client'; +import { Tooltip } from '@base-ui/react/tooltip'; import type React from 'react'; -import { TranslateContext } from '@/intl/client'; -import type { TranslationLanguage } from '@/intl/translations'; -import { TooltipProvider } from '@radix-ui/react-tooltip'; import { NavigationStatusProvider, ScrollPage } from '../hooks'; import { LoadingStateProvider } from '../primitives/LoadingStateProvider'; +import { TranslateContext } from '@/intl/client'; +import type { TranslationLanguage } from '@/intl/translations'; /** * Client component context providers for the root layout. @@ -19,12 +19,12 @@ export function RootLayoutClientContexts(props: { return ( - + {children} - + ); } diff --git a/packages/gitbook/src/components/RootLayout/globals.css b/packages/gitbook/src/components/RootLayout/globals.css index c23375e51..1c542fd45 100644 --- a/packages/gitbook/src/components/RootLayout/globals.css +++ b/packages/gitbook/src/components/RootLayout/globals.css @@ -46,17 +46,6 @@ } } -/* - Radix renders tooltip content inside a portaled `[data-radix-popper-content-wrapper]` attached - to . A non-interactive tooltip (Tooltip with `disableHoverableContent`) marks its content - with `data-non-interactive`; without this rule the pointer-interactive wrapper could sit over - the trigger and steal its hover (e.g. breaking hover-revealed controls). We can't style the - wrapper from React, so let pointer events pass through it for these tooltips only. -*/ -[data-radix-popper-content-wrapper]:has([data-non-interactive]) { - pointer-events: none; -} - @utility linear-mask-gradient { mask-image: linear-gradient( to bottom, @@ -421,8 +410,13 @@ html.dark .shiki span { @apply rounded-t-md *:mt-1; } + &.highlighted > * { + margin-bottom: var(--highlighted-run-end-mb, 0); + } + &.highlighted:has(+ :not(.highlighted)) { - @apply rounded-b-md *:mb-1; + @apply rounded-b-md; + --highlighted-run-end-mb: calc(var(--spacing) * 1); } &:not(.highlighted) + .highlighted:has(+ :not(.highlighted)) { @@ -546,3 +540,15 @@ html.dark .highlight-line.diff-deleted .highlight-line-content::before { @apply pl-2; } } + +/* An open dropdown injects focus guards as siblings of its trigger, so `:last-child` is not the + last item of a button group: match the buttons and links themselves. */ +.button-group > :is(button, a):not(:only-child):first-child { + @apply rounded-r-none; +} +.button-group > :is(button, a):not(:first-child):not(:has(~ :is(button, a))) { + @apply rounded-l-none; +} +.button-group > :is(button, a):not(:first-child):has(~ :is(button, a)) { + @apply rounded-none!; +} diff --git a/packages/gitbook/src/components/Search/LocalSearchResults.tsx b/packages/gitbook/src/components/Search/LocalSearchResults.tsx index 84bdd432c..c12f32acc 100644 --- a/packages/gitbook/src/components/Search/LocalSearchResults.tsx +++ b/packages/gitbook/src/components/Search/LocalSearchResults.tsx @@ -1,10 +1,11 @@ 'use client'; -import { tcls } from '@/lib/tailwind'; import { Icon, type IconName } from '@gitbook/icons'; + import { Emoji } from '../primitives/Emoji/Emoji'; import { Link } from '../primitives/Link'; import type { LocalPageResult } from './useLocalSearchResults'; +import { tcls } from '@/lib/tailwind'; /** * Renders local search results above the main server results. @@ -80,7 +81,7 @@ function LocalSearchResultCard({ ) : null} -

    +

    {result.title}

    diff --git a/packages/gitbook/src/components/Search/SearchAskAnswer.tsx b/packages/gitbook/src/components/Search/SearchAskAnswer.tsx index de27d9816..120e0a209 100644 --- a/packages/gitbook/src/components/Search/SearchAskAnswer.tsx +++ b/packages/gitbook/src/components/Search/SearchAskAnswer.tsx @@ -1,13 +1,10 @@ 'use client'; -import { useLanguage } from '@/intl/client'; -import { t, tString } from '@/intl/translate'; -import type { TranslationLanguage } from '@/intl/translations'; -import { tcls } from '@/lib/tailwind'; -import { Icon } from '@gitbook/icons'; import { readStreamableValue } from 'ai/rsc'; import React from 'react'; +import { Icon } from '@gitbook/icons'; + import { AIResponseFeedback, AISearchIcon } from '../AIChat'; import { HoldMessage } from '../AIChat/AIChatMessages'; import { getInsightsSession, useTrackEvent } from '../Insights'; @@ -15,6 +12,10 @@ import { Button, Link } from '../primitives'; import { useSearchAskContext } from './SearchAskContext'; import { type AskAnswerResult, type AskAnswerSource, streamAskQuestion } from './server-actions'; import { useSearchLink, useSetSearchState } from './useSearch'; +import { useLanguage } from '@/intl/client'; +import { t, tString } from '@/intl/translate'; +import type { TranslationLanguage } from '@/intl/translations'; +import { tcls } from '@/lib/tailwind'; export type SearchAskState = | { @@ -138,13 +139,13 @@ function TransitionAnswerBody(props: { return display ? (
    -
    +