diff --git a/.github/workflows/cleanup-preview-envs.yml b/.github/workflows/cleanup-preview-envs.yml new file mode 100644 index 00000000..f7592687 --- /dev/null +++ b/.github/workflows/cleanup-preview-envs.yml @@ -0,0 +1,187 @@ +name: Cleanup stale preview environments + +on: + schedule: + - cron: '0 2 * * 1' # Every Monday at 2am UTC + workflow_dispatch: + +jobs: + find-stale: + runs-on: ubuntu-latest + permissions: + contents: read + deployments: write + outputs: + stale_envs: ${{ steps.find.outputs.stale_envs }} + + steps: + - name: Find stale preview environments + id: find + uses: actions/github-script@v7 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const STALE_DAYS = 90; + const STALE_MS = STALE_DAYS * 24 * 60 * 60 * 1000; + const ENV_PREFIX = 'fairdataihub-website-'; + const now = Date.now(); + + function slugify(branch) { + return branch + .toLowerCase() + .replace(/[^a-z0-9-]/g, '-') + .replace(/-+/g, '-') + .replace(/^-|-$/g, ''); + } + + // List all branches + const branches = await github.paginate(github.rest.repos.listBranches, { + owner: context.repo.owner, + repo: context.repo.repo, + }); + + // Build map: expected environment name → branch object + const branchByEnv = new Map(); + for (const branch of branches) { + const envName = `${ENV_PREFIX}${slugify(branch.name)}`; + branchByEnv.set(envName, branch); + } + + // Get all GitHub environments + const { data: envData } = await github.rest.repos.getAllEnvironments({ + owner: context.repo.owner, + repo: context.repo.repo, + }); + + const previewEnvs = (envData.environments || []).filter(e => + e.name.startsWith(ENV_PREFIX) + ); + + const staleEnvs = []; + + for (const env of previewEnvs) { + const branch = branchByEnv.get(env.name); + + if (!branch) { + core.info(`${env.name}: branch no longer exists → stale`); + staleEnvs.push(env.name); + continue; + } + + // Check last commit date on the branch + const { data: commit } = await github.rest.repos.getCommit({ + owner: context.repo.owner, + repo: context.repo.repo, + ref: branch.commit.sha, + }); + + const lastPush = new Date(commit.commit.committer.date).getTime(); + const ageDays = Math.floor((now - lastPush) / (24 * 60 * 60 * 1000)); + + if (now - lastPush > STALE_MS) { + core.info(`${env.name}: last push ${ageDays} days ago → stale`); + staleEnvs.push(env.name); + } else { + core.info(`${env.name}: last push ${ageDays} days ago → active`); + } + } + + core.setOutput('stale_envs', JSON.stringify(staleEnvs)); + core.info(`Found ${staleEnvs.length} stale environment(s)`); + + cleanup: + needs: find-stale + runs-on: ubuntu-latest + if: needs.find-stale.outputs.stale_envs != '[]' + permissions: + contents: read + deployments: write + + env: + KAMAL_REGISTRY_LOGIN_SERVER: ${{ secrets.KAMAL_REGISTRY_LOGIN_SERVER }} + KAMAL_REGISTRY_USERNAME: ${{ secrets.KAMAL_REGISTRY_USERNAME }} + KAMAL_REGISTRY_PASSWORD: ${{ secrets.KAMAL_REGISTRY_PASSWORD }} + KAMAL_SERVER_IP: ${{ secrets.KAMAL_SERVER_IP }} + + steps: + - uses: actions/checkout@v4 + + - uses: ruby/setup-ruby@v1 + with: + ruby-version: 3.3.1 + bundler-cache: true + + - run: gem install kamal + + - uses: webfactory/ssh-agent@v0.9.0 + with: + ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }} + + - name: Remove stale Kamal preview deployments + run: | + echo '${{ needs.find-stale.outputs.stale_envs }}' | jq -r '.[]' | while read -r env_name; do + branch_slug="${env_name#fairdataihub-website-}" + export KAMAL_APP_NAME="$env_name" + export KAMAL_APP_DOMAIN="website-${branch_slug}.fairdataihub.org" + echo "Removing stale preview: $env_name" + kamal remove -y -d preview || echo "Warning: kamal remove failed for $env_name, continuing..." + done + + - name: Set up crane + uses: imjasonh/setup-crane@v0.4 + + - name: Delete stale registry images + run: | + crane auth login "$KAMAL_REGISTRY_LOGIN_SERVER" \ + -u "$KAMAL_REGISTRY_USERNAME" \ + -p "$KAMAL_REGISTRY_PASSWORD" + + echo '${{ needs.find-stale.outputs.stale_envs }}' | jq -r '.[]' | while read -r env_name; do + echo "Deleting registry image: $env_name" + crane ls "$KAMAL_REGISTRY_LOGIN_SERVER/$env_name" 2>/dev/null \ + | xargs -I{} crane delete "$KAMAL_REGISTRY_LOGIN_SERVER/$env_name:{}" 2>/dev/null \ + || true + done + + - name: Deactivate and delete GitHub environments + if: always() + uses: actions/github-script@v7 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const staleEnvs = JSON.parse('${{ needs.find-stale.outputs.stale_envs }}'); + + for (const envName of staleEnvs) { + try { + const { data: deployments } = await github.rest.repos.listDeployments({ + owner: context.repo.owner, + repo: context.repo.repo, + environment: envName, + per_page: 100, + }); + + for (const d of deployments) { + await github.rest.repos.createDeploymentStatus({ + owner: context.repo.owner, + repo: context.repo.repo, + deployment_id: d.id, + state: 'inactive', + }); + await github.rest.repos.deleteDeployment({ + owner: context.repo.owner, + repo: context.repo.repo, + deployment_id: d.id, + }); + } + + await github.rest.repos.deleteAnEnvironment({ + owner: context.repo.owner, + repo: context.repo.repo, + environment_name: envName, + }); + + core.info(`Cleaned up: ${envName}`); + } catch (e) { + core.warning(`Failed to clean up ${envName}: ${e.message}`); + } + } diff --git a/.github/workflows/deploy-app.yml b/.github/workflows/deploy-app.yml new file mode 100644 index 00000000..f4b3dbef --- /dev/null +++ b/.github/workflows/deploy-app.yml @@ -0,0 +1,120 @@ +# GitHub Actions workflow for deploying the application to production environment +name: Deploy to production environment + +# Concurrency control to prevent multiple deployments running simultaneously +# If a new deployment is triggered while one is running, the previous one will be cancelled +concurrency: + group: production-app-deploy + cancel-in-progress: true + +# Trigger conditions for this workflow +on: + push: + branches: + - next # Deploy on every push to next branch + workflow_dispatch: # Allow manual triggering from GitHub UI + +jobs: + # Job for deploying the UI/frontend application + deploy-ui: + runs-on: ubuntu-latest + permissions: + contents: read + deployments: write + + # Environment variables for Kamal deployment and container registry + env: + DOCKER_BUILDKIT: 1 # Enable Docker BuildKit for faster builds + KAMAL_REGISTRY_LOGIN_SERVER: ${{ secrets.KAMAL_REGISTRY_LOGIN_SERVER }} + KAMAL_REGISTRY_USERNAME: ${{ secrets.KAMAL_REGISTRY_USERNAME }} + KAMAL_REGISTRY_PASSWORD: ${{ secrets.KAMAL_REGISTRY_PASSWORD }} + KAMAL_SERVER_IP: ${{ secrets.KAMAL_SERVER_IP }} + KAMAL_APP_DOMAIN: ${{ secrets.KAMAL_APP_DOMAIN }} + KAMAL_APP_NAME: ${{ secrets.KAMAL_APP_NAME }} + + steps: + # Step 1: Checkout the repository code + - uses: actions/checkout@v4 + + # Step 2: Create GitHub deployment record and mark as in_progress + - name: Create GitHub deployment + id: create-deployment + continue-on-error: true + uses: actions/github-script@v7 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const deployment = await github.rest.repos.createDeployment({ + owner: context.repo.owner, + repo: context.repo.repo, + ref: context.ref, + environment: 'production', + auto_merge: false, + required_contexts: [], + }); + + core.setOutput('deployment_id', deployment.data.id); + + await github.rest.repos.createDeploymentStatus({ + owner: context.repo.owner, + repo: context.repo.repo, + deployment_id: deployment.data.id, + state: 'in_progress', + description: 'Deployment in progress', + }); + + # Step 3: Setup Ruby environment for Kamal deployment tool + - uses: ruby/setup-ruby@v1 + with: + ruby-version: 3.3.1 + bundler-cache: true # Cache Ruby dependencies for faster builds + + # Step 4: Install Kamal deployment tool + - run: gem install kamal + + # Step 5: Setup SSH agent for server access + - uses: webfactory/ssh-agent@v0.9.0 + with: + ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }} + + # Step 6: Setup Docker Buildx for better caching and performance + - name: Set up Docker Buildx for cache + uses: docker/setup-buildx-action@v3 + + # Step 7: Verify Kamal installation + - run: kamal version + + # Step 8: Release any existing deployment locks + # This prevents conflicts when redeploying while a previous deployment is running + - run: kamal lock release + # Uncomment for verbose output during troubleshooting: + # - run: kamal lock release --verbose + + # Step 9: Initial Kamal setup (only needed once per server) + # Note: This step might need to be run manually on the server first time + # to add the user to the docker group: `sudo usermod -aG docker $USER | newgrp docker | docker ps` + - id: kamal-deploy + run: kamal setup + + # Step 10: Update GitHub deployment status based on outcome + - name: Update GitHub deployment status + if: always() + uses: actions/github-script@v7 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const deploymentId = '${{ steps.create-deployment.outputs.deployment_id }}'; + if (!deploymentId) return; + + const deploySucceeded = '${{ steps.kamal-deploy.outcome }}' === 'success'; + const statusPayload = { + owner: context.repo.owner, + repo: context.repo.repo, + deployment_id: parseInt(deploymentId), + state: deploySucceeded ? 'success' : 'failure', + description: deploySucceeded ? 'Deployment succeeded' : 'Deployment failed', + }; + if (deploySucceeded) { + statusPayload.environment_url = `https://${process.env.KAMAL_APP_DOMAIN}`; + } + await github.rest.repos.createDeploymentStatus(statusPayload); diff --git a/.github/workflows/deploy-preview-app.yml b/.github/workflows/deploy-preview-app.yml new file mode 100644 index 00000000..11d0696d --- /dev/null +++ b/.github/workflows/deploy-preview-app.yml @@ -0,0 +1,481 @@ +name: Deploy preview environment + +concurrency: + group: preview-app-${{ github.ref_name || github.event.ref || github.event.pull_request.head.ref }} + cancel-in-progress: true + +on: + push: + branches-ignore: + - main + - next + pull_request: + types: [opened, reopened, closed] + delete: + +jobs: + deploy-ui: + runs-on: ubuntu-latest + if: github.event_name == 'push' + permissions: + contents: read + deployments: write + issues: write + pull-requests: write + + env: + DOCKER_BUILDKIT: 1 + KAMAL_REGISTRY_LOGIN_SERVER: ${{ secrets.KAMAL_REGISTRY_LOGIN_SERVER }} + KAMAL_REGISTRY_USERNAME: ${{ secrets.KAMAL_REGISTRY_USERNAME }} + KAMAL_REGISTRY_PASSWORD: ${{ secrets.KAMAL_REGISTRY_PASSWORD }} + KAMAL_SERVER_IP: ${{ secrets.KAMAL_SERVER_IP }} + KAMAL_APP_NAME: 'fairdataihub-website' + KAMAL_APP_DOMAIN: 'next.fairdataihub.org' + steps: + - uses: actions/checkout@v4 + + - name: Set preview app name and domain + run: | + BRANCH_SLUG=$(echo "${{ github.ref_name }}" \ + | tr '[:upper:]' '[:lower:]' \ + | sed 's/[^a-z0-9-]/-/g' \ + | sed 's/-\+/-/g' \ + | sed 's/^-//;s/-$//') + + APP_NAME="fairdataihub-website-${BRANCH_SLUG}" + APP_DOMAIN="website-${BRANCH_SLUG}.fairdataihub.org" + + echo "KAMAL_APP_NAME=${APP_NAME}" >> "$GITHUB_ENV" + echo "KAMAL_APP_DOMAIN=${APP_DOMAIN}" >> "$GITHUB_ENV" + + - name: Post in-progress comment on PR + id: post-comment + uses: actions/github-script@v7 + with: + github-token: ${{ secrets.GH_PAT || secrets.GITHUB_TOKEN }} + script: | + const branch = '${{ github.ref_name }}'; + const previewUrl = `https://${process.env.KAMAL_APP_DOMAIN}`; + + const { data: prs } = await github.rest.pulls.list({ + owner: context.repo.owner, + repo: context.repo.repo, + state: 'open', + head: `${context.repo.owner}:${branch}` + }); + + if (prs.length === 0) return; + + const issue_number = prs[0].number; + const body = `## Preview deployment in progress\n\nA preview environment is being built and will be available at [${previewUrl}](${previewUrl}) once ready. Please wait...`; + + const { data: comments } = await github.rest.issues.listComments({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number + }); + + const existing = comments.find( + c => c.body.startsWith('## Preview deployment') + ); + + let commentId; + if (existing) { + await github.rest.issues.updateComment({ + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: existing.id, + body + }); + commentId = existing.id; + } else { + const { data: newComment } = await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number, + body + }); + commentId = newComment.id; + } + + core.setOutput('comment_id', commentId); + + - uses: ruby/setup-ruby@v1 + with: + ruby-version: 3.3.1 + bundler-cache: true + + - run: gem install kamal + + - uses: webfactory/ssh-agent@v0.9.0 + with: + ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }} + + - id: kamal-deploy + run: kamal deploy -d preview + + - name: Manage GitHub deployment + if: always() + uses: actions/github-script@v7 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const deploySucceeded = '${{ steps.kamal-deploy.outcome }}' === 'success'; + + const deployment = await github.rest.repos.createDeployment({ + owner: context.repo.owner, + repo: context.repo.repo, + ref: context.ref, + environment: process.env.KAMAL_APP_NAME, + auto_merge: false, + required_contexts: [] + }); + + const statusPayload = { + owner: context.repo.owner, + repo: context.repo.repo, + deployment_id: deployment.data.id, + state: deploySucceeded ? 'success' : 'failure', + description: deploySucceeded ? 'Preview deployment ready' : 'Preview deployment failed' + }; + if (deploySucceeded) { + statusPayload.environment_url = `https://${process.env.KAMAL_APP_DOMAIN}`; + } + await github.rest.repos.createDeploymentStatus(statusPayload); + + const { data: deployments } = await github.rest.repos.listDeployments({ + owner: context.repo.owner, + repo: context.repo.repo, + environment: process.env.KAMAL_APP_NAME, + per_page: 100 + }); + + for (const d of deployments) { + if (d.id === deployment.data.id) continue; + await github.rest.repos.createDeploymentStatus({ + owner: context.repo.owner, + repo: context.repo.repo, + deployment_id: d.id, + state: 'inactive' + }); + } + + - name: Update PR comment + if: always() + uses: actions/github-script@v7 + with: + github-token: ${{ secrets.GH_PAT || secrets.GITHUB_TOKEN }} + script: | + const previewUrl = `https://${process.env.KAMAL_APP_DOMAIN}`; + const deploySucceeded = '${{ steps.kamal-deploy.outcome }}' === 'success'; + + const body = deploySucceeded + ? `## Preview deployment ready\n\n**Preview URL:** [${previewUrl}](${previewUrl})\n\n> Last deployed: ${new Date().toUTCString()}` + : `## Preview deployment failed\n\nThe deployment for this branch failed. Check the [workflow run](${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}) for details.`; + + const commentId = '${{ steps.post-comment.outputs.comment_id }}'; + + if (commentId) { + await github.rest.issues.updateComment({ + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: parseInt(commentId), + body + }); + return; + } + + // Fallback: no comment was posted at the start (no open PR at that time) + const branch = '${{ github.ref_name }}'; + const { data: prs } = await github.rest.pulls.list({ + owner: context.repo.owner, + repo: context.repo.repo, + state: 'open', + head: `${context.repo.owner}:${branch}` + }); + + if (prs.length === 0) return; + + const issue_number = prs[0].number; + const { data: comments } = await github.rest.issues.listComments({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number + }); + + const existing = comments.find( + c => c.body.startsWith('## Preview deployment') + ); + + if (existing) { + await github.rest.issues.updateComment({ + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: existing.id, + body + }); + } else { + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number, + body + }); + } + + notify-pr-on-open: + runs-on: ubuntu-latest + if: | + github.event_name == 'pull_request' && + (github.event.action == 'opened' || github.event.action == 'reopened') && + !contains(fromJson('["main","next"]'), github.event.pull_request.head.ref) + permissions: + contents: read + deployments: read + actions: read + issues: write + pull-requests: write + + steps: + - name: Set preview app name and domain + run: | + BRANCH_SLUG=$(echo "${{ github.event.pull_request.head.ref }}" \ + | tr '[:upper:]' '[:lower:]' \ + | sed 's/[^a-z0-9-]/-/g' \ + | sed 's/-\+/-/g' \ + | sed 's/^-//;s/-$//') + + APP_NAME="fairdataihub-website-${BRANCH_SLUG}" + APP_DOMAIN="website-${BRANCH_SLUG}.fairdataihub.org" + + echo "KAMAL_APP_NAME=${APP_NAME}" >> "$GITHUB_ENV" + echo "KAMAL_APP_DOMAIN=${APP_DOMAIN}" >> "$GITHUB_ENV" + + - name: Post preview status comment + uses: actions/github-script@v7 + with: + github-token: ${{ secrets.GH_PAT || secrets.GITHUB_TOKEN }} + script: | + const previewUrl = `https://${process.env.KAMAL_APP_DOMAIN}`; + const issue_number = context.payload.pull_request.number; + const branch = context.payload.pull_request.head.ref; + + // Look up the latest deployment for this preview environment + const { data: deployments } = await github.rest.repos.listDeployments({ + owner: context.repo.owner, + repo: context.repo.repo, + environment: process.env.KAMAL_APP_NAME, + per_page: 1, + }); + + let body; + if (deployments.length > 0) { + const { data: statuses } = await github.rest.repos.listDeploymentStatuses({ + owner: context.repo.owner, + repo: context.repo.repo, + deployment_id: deployments[0].id, + per_page: 1, + }); + const state = statuses[0]?.state; + if (state === 'success') { + const updatedAt = new Date(deployments[0].updated_at).toUTCString(); + body = `## Preview deployment ready\n\n**Preview URL:** [${previewUrl}](${previewUrl})\n\n> Last deployed: ${updatedAt}`; + } else if (state === 'in_progress') { + body = `## Preview deployment in progress\n\nA preview environment is being built and will be available at [${previewUrl}](${previewUrl}) once ready. Please wait...`; + } else { + body = `## Preview deployment\n\nA preview environment will be available at [${previewUrl}](${previewUrl}) after the next push to this branch.`; + } + } else { + // No deployment record yet — check if deploy-ui is currently running for this branch. + // The GitHub deployment record is only created after kamal completes, so a concurrent + // push can leave listDeployments empty while the workflow is still in progress. + const { data: runs } = await github.rest.actions.listWorkflowRunsForRepo({ + owner: context.repo.owner, + repo: context.repo.repo, + branch, + status: 'in_progress', + per_page: 10, + }); + const deployRunning = runs.workflow_runs.some(r => r.name === 'Deploy preview environment'); + if (deployRunning) { + body = `## Preview deployment in progress\n\nA preview environment is being built and will be available at [${previewUrl}](${previewUrl}) once ready. Please wait...`; + } else { + body = `## Preview deployment\n\nA preview environment will be available at [${previewUrl}](${previewUrl}) after the next push to this branch.`; + } + } + + const { data: comments } = await github.rest.issues.listComments({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number, + }); + + const existing = comments.find( + c => c.body.startsWith('## Preview deployment') + ); + + if (existing) { + await github.rest.issues.updateComment({ + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: existing.id, + body, + }); + } else { + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number, + body, + }); + } + + remove-preview: + runs-on: ubuntu-latest + if: | + (github.event_name == 'pull_request' && + github.event.action == 'closed' && + !contains(fromJson('["main","next"]'), github.event.pull_request.head.ref)) || + (github.event_name == 'delete' && + github.event.ref_type == 'branch' && + !contains(fromJson('["main","next"]'), github.event.ref)) + permissions: + contents: read + deployments: write + issues: write + pull-requests: read + + env: + DOCKER_BUILDKIT: 1 + KAMAL_REGISTRY_LOGIN_SERVER: ${{ secrets.KAMAL_REGISTRY_LOGIN_SERVER }} + KAMAL_REGISTRY_USERNAME: ${{ secrets.KAMAL_REGISTRY_USERNAME }} + KAMAL_REGISTRY_PASSWORD: ${{ secrets.KAMAL_REGISTRY_PASSWORD }} + KAMAL_SERVER_IP: ${{ secrets.KAMAL_SERVER_IP }} + KAMAL_APP_NAME: 'fairdataihub-website' + KAMAL_APP_DOMAIN: 'next.fairdataihub.org' + + steps: + - uses: actions/checkout@v4 + + - name: Set branch name for remove + id: branch + run: | + if [ "${{ github.event_name }}" = "pull_request" ]; then + BRANCH_NAME="${{ github.event.pull_request.head.ref }}" + else + BRANCH_NAME="${{ github.event.ref }}" + fi + echo "branch=${BRANCH_NAME}" >> "$GITHUB_OUTPUT" + + - name: Set preview app name and domain + run: | + BRANCH_SLUG=$(echo "${{ steps.branch.outputs.branch }}" \ + | tr '[:upper:]' '[:lower:]' \ + | sed 's/[^a-z0-9-]/-/g' \ + | sed 's/-\+/-/g' \ + | sed 's/^-//;s/-$//') + + APP_NAME="fairdataihub-website-${BRANCH_SLUG}" + APP_DOMAIN="website-${BRANCH_SLUG}.fairdataihub.org" + + echo "KAMAL_APP_NAME=${APP_NAME}" >> "$GITHUB_ENV" + echo "KAMAL_APP_DOMAIN=${APP_DOMAIN}" >> "$GITHUB_ENV" + + - uses: ruby/setup-ruby@v1 + with: + ruby-version: 3.3.1 + bundler-cache: true + + - run: gem install kamal + + - uses: webfactory/ssh-agent@v0.9.0 + with: + ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }} + + - run: kamal remove -y -d preview + + - name: Delete registry image + if: always() + uses: imjasonh/setup-crane@v0.4 + - name: Remove preview image from registry + if: always() + run: | + crane auth login "$KAMAL_REGISTRY_LOGIN_SERVER" \ + -u "$KAMAL_REGISTRY_USERNAME" \ + -p "$KAMAL_REGISTRY_PASSWORD" + crane ls "$KAMAL_REGISTRY_LOGIN_SERVER/$KAMAL_APP_NAME" 2>/dev/null \ + | xargs -I{} crane delete "$KAMAL_REGISTRY_LOGIN_SERVER/$KAMAL_APP_NAME:{}" 2>/dev/null \ + || true + + - name: Deactivate and delete GitHub environment + if: always() + uses: actions/github-script@v7 + with: + github-token: ${{ secrets.GH_PAT || secrets.GITHUB_TOKEN }} + script: | + const { data: deployments } = await github.rest.repos.listDeployments({ + owner: context.repo.owner, + repo: context.repo.repo, + environment: process.env.KAMAL_APP_NAME, + per_page: 100 + }); + + for (const deployment of deployments) { + await github.rest.repos.createDeploymentStatus({ + owner: context.repo.owner, + repo: context.repo.repo, + deployment_id: deployment.id, + state: 'inactive', + description: 'Preview environment removed' + }); + await github.rest.repos.deleteDeployment({ + owner: context.repo.owner, + repo: context.repo.repo, + deployment_id: deployment.id + }); + } + + try { + await github.rest.repos.deleteAnEnvironment({ + owner: context.repo.owner, + repo: context.repo.repo, + environment_name: process.env.KAMAL_APP_NAME + }); + } catch (e) { + core.warning(`Could not delete environment: ${e.message}`); + } + + - name: Update PR comment on removal + if: github.event_name == 'pull_request' + uses: actions/github-script@v7 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const issue_number = context.payload.pull_request.number; + const body = `## Preview deployment removed\n\nThe preview environment for this branch has been removed.`; + + const { data: comments } = await github.rest.issues.listComments({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number + }); + + const existing = comments.find( + c => c.body.startsWith('## Preview deployment') + ); + + if (existing) { + await github.rest.issues.updateComment({ + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: existing.id, + body + }); + } else { + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number, + body + }); + } diff --git a/.kamal/hooks/docker-setup.sample b/.kamal/hooks/docker-setup.sample new file mode 100644 index 00000000..2fb07d7d --- /dev/null +++ b/.kamal/hooks/docker-setup.sample @@ -0,0 +1,3 @@ +#!/bin/sh + +echo "Docker set up on $KAMAL_HOSTS..." diff --git a/.kamal/hooks/post-deploy.sample b/.kamal/hooks/post-deploy.sample new file mode 100644 index 00000000..75efafc1 --- /dev/null +++ b/.kamal/hooks/post-deploy.sample @@ -0,0 +1,14 @@ +#!/bin/sh + +# A sample post-deploy hook +# +# These environment variables are available: +# KAMAL_RECORDED_AT +# KAMAL_PERFORMER +# KAMAL_VERSION +# KAMAL_HOSTS +# KAMAL_ROLE (if set) +# KAMAL_DESTINATION (if set) +# KAMAL_RUNTIME + +echo "$KAMAL_PERFORMER deployed $KAMAL_VERSION to $KAMAL_DESTINATION in $KAMAL_RUNTIME seconds" diff --git a/.kamal/hooks/post-proxy-reboot.sample b/.kamal/hooks/post-proxy-reboot.sample new file mode 100644 index 00000000..1435a677 --- /dev/null +++ b/.kamal/hooks/post-proxy-reboot.sample @@ -0,0 +1,3 @@ +#!/bin/sh + +echo "Rebooted kamal-proxy on $KAMAL_HOSTS" diff --git a/.kamal/hooks/pre-build.sample b/.kamal/hooks/pre-build.sample new file mode 100644 index 00000000..f87d8113 --- /dev/null +++ b/.kamal/hooks/pre-build.sample @@ -0,0 +1,51 @@ +#!/bin/sh + +# A sample pre-build hook +# +# Checks: +# 1. We have a clean checkout +# 2. A remote is configured +# 3. The branch has been pushed to the remote +# 4. The version we are deploying matches the remote +# +# These environment variables are available: +# KAMAL_RECORDED_AT +# KAMAL_PERFORMER +# KAMAL_VERSION +# KAMAL_HOSTS +# KAMAL_ROLE (if set) +# KAMAL_DESTINATION (if set) + +if [ -n "$(git status --porcelain)" ]; then + echo "Git checkout is not clean, aborting..." >&2 + git status --porcelain >&2 + exit 1 +fi + +first_remote=$(git remote) + +if [ -z "$first_remote" ]; then + echo "No git remote set, aborting..." >&2 + exit 1 +fi + +current_branch=$(git branch --show-current) + +if [ -z "$current_branch" ]; then + echo "Not on a git branch, aborting..." >&2 + exit 1 +fi + +remote_head=$(git ls-remote $first_remote --tags $current_branch | cut -f1) + +if [ -z "$remote_head" ]; then + echo "Branch not pushed to remote, aborting..." >&2 + exit 1 +fi + +if [ "$KAMAL_VERSION" != "$remote_head" ]; then + echo "Version ($KAMAL_VERSION) does not match remote HEAD ($remote_head), aborting..." >&2 + exit 1 +fi + +exit 0 diff --git a/.kamal/hooks/pre-connect.sample b/.kamal/hooks/pre-connect.sample new file mode 100644 index 00000000..18e61d7e --- /dev/null +++ b/.kamal/hooks/pre-connect.sample @@ -0,0 +1,47 @@ +#!/usr/bin/env ruby + +# A sample pre-connect check +# +# Warms DNS before connecting to hosts in parallel +# +# These environment variables are available: +# KAMAL_RECORDED_AT +# KAMAL_PERFORMER +# KAMAL_VERSION +# KAMAL_HOSTS +# KAMAL_ROLE (if set) +# KAMAL_DESTINATION (if set) +# KAMAL_RUNTIME + +hosts = ENV["KAMAL_HOSTS"].split(",") +results = nil +max = 3 + +elapsed = Benchmark.realtime do + results = hosts.map do |host| + Thread.new do + tries = 1 + + begin + Socket.getaddrinfo(host, 0, Socket::AF_UNSPEC, Socket::SOCK_STREAM, nil, Socket::AI_CANONNAME) + rescue SocketError + if tries < max + puts "Retrying DNS warmup: #{host}" + tries += 1 + sleep rand + retry + else + puts "DNS warmup failed: #{host}" + host + end + end + + tries + end + end.map(&:value) +end + +retries = results.sum - hosts.size +nopes = results.count { |r| r == max } + +puts "Prewarmed %d DNS lookups in %.2f sec: %d retries, %d failures" % [ hosts.size, elapsed, retries, nopes ] diff --git a/.kamal/hooks/pre-deploy.sample b/.kamal/hooks/pre-deploy.sample new file mode 100644 index 00000000..1b280c71 --- /dev/null +++ b/.kamal/hooks/pre-deploy.sample @@ -0,0 +1,109 @@ +#!/usr/bin/env ruby + +# A sample pre-deploy hook +# +# Checks the Github status of the build, waiting for a pending build to complete for up to 720 seconds. +# +# Fails unless the combined status is "success" +# +# These environment variables are available: +# KAMAL_RECORDED_AT +# KAMAL_PERFORMER +# KAMAL_VERSION +# KAMAL_HOSTS +# KAMAL_COMMAND +# KAMAL_SUBCOMMAND +# KAMAL_ROLE (if set) +# KAMAL_DESTINATION (if set) + +# Only check the build status for production deployments +if ENV["KAMAL_COMMAND"] == "rollback" || ENV["KAMAL_DESTINATION"] != "production" + exit 0 +end + +require "bundler/inline" + +# true = install gems so this is fast on repeat invocations +gemfile(true, quiet: true) do + source "https://rubygems.org" + + gem "octokit" + gem "faraday-retry" +end + +MAX_ATTEMPTS = 72 +ATTEMPTS_GAP = 10 + +def exit_with_error(message) + $stderr.puts message + exit 1 +end + +class GithubStatusChecks + attr_reader :remote_url, :git_sha, :github_client, :combined_status + + def initialize + @remote_url = `git config --get remote.origin.url`.strip.delete_prefix("https://github.com/") + @git_sha = `git rev-parse HEAD`.strip + @github_client = Octokit::Client.new(access_token: ENV["GITHUB_TOKEN"]) + refresh! + end + + def refresh! + @combined_status = github_client.combined_status(remote_url, git_sha) + end + + def state + combined_status[:state] + end + + def first_status_url + first_status = combined_status[:statuses].find { |status| status[:state] == state } + first_status && first_status[:target_url] + end + + def complete_count + combined_status[:statuses].count { |status| status[:state] != "pending"} + end + + def total_count + combined_status[:statuses].count + end + + def current_status + if total_count > 0 + "Completed #{complete_count}/#{total_count} checks, see #{first_status_url} ..." + else + "Build not started..." + end + end +end + + +$stdout.sync = true + +puts "Checking build status..." +attempts = 0 +checks = GithubStatusChecks.new + +begin + loop do + case checks.state + when "success" + puts "Checks passed, see #{checks.first_status_url}" + exit 0 + when "failure" + exit_with_error "Checks failed, see #{checks.first_status_url}" + when "pending" + attempts += 1 + end + + exit_with_error "Checks are still pending, gave up after #{MAX_ATTEMPTS * ATTEMPTS_GAP} seconds" if attempts == MAX_ATTEMPTS + + puts checks.current_status + sleep(ATTEMPTS_GAP) + checks.refresh! + end +rescue Octokit::NotFound + exit_with_error "Build status could not be found" +end diff --git a/.kamal/hooks/pre-proxy-reboot.sample b/.kamal/hooks/pre-proxy-reboot.sample new file mode 100644 index 00000000..061f8059 --- /dev/null +++ b/.kamal/hooks/pre-proxy-reboot.sample @@ -0,0 +1,3 @@ +#!/bin/sh + +echo "Rebooting kamal-proxy on $KAMAL_HOSTS..." diff --git a/.kamal/secrets b/.kamal/secrets new file mode 100644 index 00000000..07df46fa --- /dev/null +++ b/.kamal/secrets @@ -0,0 +1 @@ +# production secrets only diff --git a/.kamal/secrets-common b/.kamal/secrets-common new file mode 100644 index 00000000..fa694ca2 --- /dev/null +++ b/.kamal/secrets-common @@ -0,0 +1,11 @@ +# Common secrets for all environments + +# Registry secrets +KAMAL_REGISTRY_PASSWORD=$KAMAL_REGISTRY_PASSWORD +KAMAL_REGISTRY_USERNAME=$KAMAL_REGISTRY_USERNAME +KAMAL_REGISTRY_LOGIN_SERVER=$KAMAL_REGISTRY_LOGIN_SERVER # only if you're not using docker hub + +# Host secrets +KAMAL_APP_NAME=$KAMAL_APP_NAME +KAMAL_APP_DOMAIN=$KAMAL_APP_DOMAIN +KAMAL_SERVER_IP=$KAMAL_SERVER_IP \ No newline at end of file diff --git a/.kamal/secrets-preview b/.kamal/secrets-preview new file mode 100644 index 00000000..8543e099 --- /dev/null +++ b/.kamal/secrets-preview @@ -0,0 +1 @@ +# Secrets for preview deployments \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..1e827a4b --- /dev/null +++ b/Dockerfile @@ -0,0 +1,103 @@ +# ============================================ +# Stage 1: Dependencies Installation Stage +# ============================================ + +# IMPORTANT: Node.js Version Maintenance +# This Dockerfile uses Node.js 22.18.0-slim to match the version pinned in package.json (via Volta). +# To ensure security and compatibility, regularly update the NODE_VERSION ARG to the latest LTS version you support. +ARG NODE_VERSION=22.18.0-slim + +FROM node:${NODE_VERSION} AS dependencies + +# Set working directory +WORKDIR /app + +# Copy package-related files first to leverage Docker's caching mechanism +COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* .npmrc* ./ + +# Install project dependencies with frozen lockfile for reproducible builds +RUN --mount=type=cache,target=/root/.npm \ + --mount=type=cache,target=/usr/local/share/.cache/yarn \ + --mount=type=cache,target=/root/.local/share/pnpm/store \ + if [ -f package-lock.json ]; then \ + npm ci --no-audit --no-fund; \ + elif [ -f yarn.lock ]; then \ + corepack enable yarn && yarn install --frozen-lockfile --production=false; \ + elif [ -f pnpm-lock.yaml ]; then \ + corepack enable pnpm && pnpm install --frozen-lockfile; \ + else \ + echo "No lockfile found." && exit 1; \ + fi + +# ============================================ +# Stage 2: Build Next.js application in standalone mode +# ============================================ + +FROM node:${NODE_VERSION} AS builder + +# Set working directory +WORKDIR /app + +# Copy project dependencies from dependencies stage +COPY --from=dependencies /app/node_modules ./node_modules + +# Copy application source code +COPY . . + +ENV NODE_ENV=production + +# Next.js collects completely anonymous telemetry data about general usage. +# Learn more here: https://nextjs.org/telemetry +# Uncomment the following line in case you want to disable telemetry during the build. +# ENV NEXT_TELEMETRY_DISABLED=1 + +# Build Next.js application +# If you want to speed up Docker rebuilds, you can cache the build artifacts +# by adding: --mount=type=cache,target=/app/.next/cache +# This caches the .next/cache directory across builds, but it also prevents +# .next/cache/fetch-cache from being included in the final image, meaning +# cached fetch responses from the build won't be available at runtime. +RUN if [ -f package-lock.json ]; then \ + npm run build; \ + elif [ -f yarn.lock ]; then \ + corepack enable yarn && yarn build; \ + elif [ -f pnpm-lock.yaml ]; then \ + corepack enable pnpm && pnpm build; \ + else \ + echo "No lockfile found." && exit 1; \ + fi + +# ============================================ +# Stage 3: Run Next.js application +# ============================================ + +FROM node:${NODE_VERSION} AS runner + +# Set working directory +WORKDIR /app + +# Set production environment variables +ENV NODE_ENV=production +ENV PORT=3000 +ENV HOSTNAME="0.0.0.0" + +# Next.js collects completely anonymous telemetry data about general usage. +# Learn more here: https://nextjs.org/telemetry +# Uncomment the following line in case you want to disable telemetry during the run time. +# ENV NEXT_TELEMETRY_DISABLED=1 + +# Copy standalone server output (includes its own minimal node_modules) +COPY --from=builder --chown=node:node /app/.next/standalone ./ +# Static assets must sit at .next/static inside the standalone dir +COPY --from=builder --chown=node:node /app/.next/static ./.next/static +# Public assets +COPY --from=builder --chown=node:node /app/public ./public + +# Switch to non-root user for security best practices +USER node + +# Expose port 3000 to allow HTTP traffic +EXPOSE 3000 + +# Start the standalone server directly (no next CLI needed) +CMD ["node", "server.js"] \ No newline at end of file diff --git a/config/deploy.preview.yml b/config/deploy.preview.yml new file mode 100644 index 00000000..8d0f32a1 --- /dev/null +++ b/config/deploy.preview.yml @@ -0,0 +1,8 @@ +# empty file for preview deployment +# We are setting up everything in the github action. +# This file is only for the preview deployment target by kamal + +env: + clear: + NODE_ENV: preview + NEXT_IMAGE_UNOPTIMIZED: 'true' diff --git a/config/deploy.yml b/config/deploy.yml new file mode 100644 index 00000000..ef359848 --- /dev/null +++ b/config/deploy.yml @@ -0,0 +1,73 @@ +# Kamal Deployment Configuration +# This file configures how your Nuxt.js application is deployed using Kamal +# Kamal is a deployment tool that automates containerized app deployment + +# Name of your application. Used to uniquely configure containers. +# This name will be used for container names, volumes, and network resources +service: <%= ENV["KAMAL_APP_NAME"] %> + +# Load environment variables from .env file for dynamic configuration +# This allows sensitive data to be kept out of version control +# <% require "dotenv" %> +# <% Dotenv.load(".env") %> + +# Name of the container image. +# This should match your Docker registry and image name +image: <%= ENV["KAMAL_APP_NAME"] %> + +# Deploy to these servers. +# Define different server roles for your application +servers: + web: + hosts: + - <%= ENV["KAMAL_SERVER_IP"] %> + # job: + # hosts: + # - 192.168.0.1 + # cmd: bin/jobs + +# Enable SSL auto certification via Let's Encrypt and allow for multiple apps on a single web server. +# Remove this section when using multiple web servers and ensure you terminate SSL at your load balancer. +# +# Note: If using Cloudflare, set encryption mode in SSL/TLS setting to "Full" to enable CF-to-app encryption. +proxy: + ssl: true # Automatically obtain and configure SSL certificates + host: <%= ENV["KAMAL_APP_DOMAIN"] %> # Your application's domain name + # Proxy connects to your container on port 80 by default. + app_port: 3000 # Port your Nuxt app runs on inside the container + forward_headers: true # Forward client headers to your application + healthcheck: + path: / # custom health check path + timeout: 60 # Health check timeout in seconds + +# Credentials for your image host. +# Configure access to your Docker registry (Docker Hub, GitHub Container Registry, etc.) +registry: + # Specify the registry server, if you're not using Docker Hub + # server: registry.digitalocean.com / ghcr.io / ... + server: <%= ENV["KAMAL_REGISTRY_LOGIN_SERVER"] %> + username: <%= ENV["KAMAL_REGISTRY_USERNAME"] %> + + # Always use an access token rather than real password (pulled from .kamal/secrets). + # This is more secure than using your actual password + password: + - KAMAL_REGISTRY_PASSWORD + +# Configure builder setup. +# Settings for building your Docker image +builder: + arch: amd64 # Target architecture for the built image + # Pass in additional build args needed for your Dockerfile. + # args: + # RUBY_VERSION: <%= ENV["RBENV_VERSION"] || ENV["rvm_ruby_string"] || "#{RUBY_ENGINE}-#{RUBY_ENGINE_VERSION}" %> + +# Inject ENV variables into all containers (secrets come from .kamal/secrets). +# Environment variables are available to your application at runtime +env: + clear: + NODE_ENV: production # Set to 'production' for production deployments +# Use a different ssh user than root +# Uncomment and configure if you need to use a non-root user for SSH access +# +# ssh: +# user: azureuser diff --git a/next.config.js b/next.config.js index cbc8d61d..4cf3a4e3 100644 --- a/next.config.js +++ b/next.config.js @@ -1,79 +1,125 @@ module.exports = { + output: 'standalone', reactStrictMode: true, images: { + // In Docker behind a reverse proxy (e.g. Kamal), the /_next/image endpoint can + // fail (timeouts, wrong host, or container can't fetch remote URLs). Set + // NEXT_IMAGE_UNOPTIMIZED=true in the container env to serve images directly. + unoptimized: process.env.NEXT_IMAGE_UNOPTIMIZED === 'true', dangerouslyAllowSVG: true, remotePatterns: [ { protocol: 'https', hostname: 'www.datocms-assets.com', + port: '', + pathname: '/**', }, { protocol: 'https', hostname: 'fair-biors.org', + port: '', + pathname: '/**', }, - { - protocol: 'https', - hostname: 'github.com', - }, + { protocol: 'https', hostname: 'github.com', port: '', pathname: '/**' }, { protocol: 'https', hostname: 'ucarecdn.com', + port: '', + pathname: '/**', }, { protocol: 'https', hostname: 'api.dicebear.com', + port: '', + pathname: '/**', }, - { - protocol: 'https', - hostname: 'i.imgur.com', - }, + { protocol: 'https', hostname: 'i.imgur.com', port: '', pathname: '/**' }, { protocol: 'https', hostname: 'unsplash.com', + port: '', + pathname: '/**', }, { protocol: 'https', hostname: 'berkeleybop.github.io', + port: '', + pathname: '/**', }, { protocol: 'https', hostname: 'img.shields.io', + port: '', + pathname: '/**', }, { protocol: 'https', hostname: 'researcherprofiles.org', + port: '', + pathname: '/**', }, { protocol: 'https', hostname: 'images.unsplash.com', + port: '', + pathname: '/**', }, { protocol: 'https', hostname: 'raw.githubusercontent.com', + port: '', + pathname: '/**', }, { protocol: 'https', hostname: 'elixir-europe.org', + port: '', + pathname: '/**', }, { protocol: 'https', hostname: 'cdn.jsdelivr.net', + port: '', + pathname: '/**', }, { protocol: 'https', hostname: 'cdn.fairdataihub.org', + port: '', + pathname: '/**', }, + { protocol: 'https', hostname: 'os.nav.fund', port: '', pathname: '/**' }, { protocol: 'https', - hostname: 'os.nav.fund', + hostname: 'api.microlink.io', + port: '', + pathname: '/**', }, { protocol: 'https', - hostname: 'api.microlink.io', + hostname: 'www.dailydoseofds.com', + port: '', + pathname: '/**', }, + + // often needed for GitHub-hosted images { protocol: 'https', - hostname: 'www.dailydoseofds.com', + hostname: 'user-images.githubusercontent.com', + port: '', + pathname: '/**', + }, + { + protocol: 'https', + hostname: 'avatars.githubusercontent.com', + port: '', + pathname: '/**', + }, + { + protocol: 'https', + hostname: 'githubusercontent.com', + port: '', + pathname: '/**', }, ], }, diff --git a/package.json b/package.json index 181b3a38..252c78ee 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "lint": "eslint --ignore-path .gitignore \"src/**/*.+(ts|js|tsx|jsx)\"", "format": "prettier --ignore-path .gitignore \"src/**/*.+(ts|js|tsx|jsx)\" --write", "prepare": "husky install", - "postinstall": "husky install && yarn scripts:gallery_id", + "postinstall": "husky install", "commit": "cz", "postbuild": "next-sitemap", "semantic-release": "semantic-release", @@ -32,7 +32,7 @@ "reset": "rm -rf node_modules .next && yarn install" }, "lint-staged": { - "./src/**/*.{ts,js,jsx,tsx}": [ + "./src/**/*.{mx}": [ "yarn lint --fix", "yarn format" ] @@ -66,13 +66,13 @@ "markdown-it": "14.1.1", "motion": "^12.23.24", "nanoid": "^5.1.6", - "next": "16.1.5", + "next": "^16.1.6", "next-themes": "^0.4.6", "plaiceholder": "2.5.0", "qss": "^3.0.0", - "react": "19.2.1", + "react": "^19.2.4", "react-day-picker": "^8.8.2", - "react-dom": "19.2.1", + "react-dom": "^19.2.4", "react-fast-marquee": "1.6.0", "react-hooks-global-state": "^2.1.0", "react-lottie-player": "1.5.6", @@ -126,7 +126,7 @@ "cypress": "12.17.0", "cz-conventional-changelog": "3.3.0", "eslint": "8.57.1", - "eslint-config-next": "13.4.2", + "eslint-config-next": "^16.1.6", "eslint-config-prettier": "9.1.0", "eslint-import-resolver-typescript": "3.6.1", "eslint-plugin-prettier": "5.2.1", @@ -164,4 +164,4 @@ "node": "22.18.0", "yarn": "1.22.22" } -} +} \ No newline at end of file diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 39da6c25..0c927b64 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -92,7 +92,7 @@ export default function Home() {

- The FAIR Data wave + The FAIR Data wave (next-21)

diff --git a/yarn.lock b/yarn.lock index 5e013137..25969473 100644 --- a/yarn.lock +++ b/yarn.lock @@ -16,16 +16,155 @@ js-tokens "^4.0.0" picocolors "^1.1.1" +"@babel/code-frame@^7.28.6", "@babel/code-frame@^7.29.0": + version "7.29.0" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.29.0.tgz#7cd7a59f15b3cc0dcd803038f7792712a7d0b15c" + integrity sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw== + dependencies: + "@babel/helper-validator-identifier" "^7.28.5" + js-tokens "^4.0.0" + picocolors "^1.1.1" + +"@babel/compat-data@^7.28.6": + version "7.29.0" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.29.0.tgz#00d03e8c0ac24dd9be942c5370990cbe1f17d88d" + integrity sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg== + +"@babel/core@^7.24.4": + version "7.29.0" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.29.0.tgz#5286ad785df7f79d656e88ce86e650d16ca5f322" + integrity sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA== + dependencies: + "@babel/code-frame" "^7.29.0" + "@babel/generator" "^7.29.0" + "@babel/helper-compilation-targets" "^7.28.6" + "@babel/helper-module-transforms" "^7.28.6" + "@babel/helpers" "^7.28.6" + "@babel/parser" "^7.29.0" + "@babel/template" "^7.28.6" + "@babel/traverse" "^7.29.0" + "@babel/types" "^7.29.0" + "@jridgewell/remapping" "^2.3.5" + convert-source-map "^2.0.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.3" + semver "^6.3.1" + +"@babel/generator@^7.29.0": + version "7.29.1" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.29.1.tgz#d09876290111abbb00ef962a7b83a5307fba0d50" + integrity sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw== + dependencies: + "@babel/parser" "^7.29.0" + "@babel/types" "^7.29.0" + "@jridgewell/gen-mapping" "^0.3.12" + "@jridgewell/trace-mapping" "^0.3.28" + jsesc "^3.0.2" + +"@babel/helper-compilation-targets@^7.28.6": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz#32c4a3f41f12ed1532179b108a4d746e105c2b25" + integrity sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA== + dependencies: + "@babel/compat-data" "^7.28.6" + "@babel/helper-validator-option" "^7.27.1" + browserslist "^4.24.0" + lru-cache "^5.1.1" + semver "^6.3.1" + +"@babel/helper-globals@^7.28.0": + version "7.28.0" + resolved "https://registry.yarnpkg.com/@babel/helper-globals/-/helper-globals-7.28.0.tgz#b9430df2aa4e17bc28665eadeae8aa1d985e6674" + integrity sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw== + +"@babel/helper-module-imports@^7.28.6": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz#60632cbd6ffb70b22823187201116762a03e2d5c" + integrity sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw== + dependencies: + "@babel/traverse" "^7.28.6" + "@babel/types" "^7.28.6" + +"@babel/helper-module-transforms@^7.28.6": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz#9312d9d9e56edc35aeb6e95c25d4106b50b9eb1e" + integrity sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA== + dependencies: + "@babel/helper-module-imports" "^7.28.6" + "@babel/helper-validator-identifier" "^7.28.5" + "@babel/traverse" "^7.28.6" + +"@babel/helper-string-parser@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz#54da796097ab19ce67ed9f88b47bb2ec49367687" + integrity sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA== + "@babel/helper-validator-identifier@^7.27.1": version "7.27.1" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz#a7054dcc145a967dd4dc8fee845a57c1316c9df8" integrity sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow== +"@babel/helper-validator-identifier@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz#010b6938fab7cb7df74aa2bbc06aa503b8fe5fb4" + integrity sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q== + +"@babel/helper-validator-option@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz#fa52f5b1e7db1ab049445b421c4471303897702f" + integrity sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg== + +"@babel/helpers@^7.28.6": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.28.6.tgz#fca903a313ae675617936e8998b814c415cbf5d7" + integrity sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw== + dependencies: + "@babel/template" "^7.28.6" + "@babel/types" "^7.28.6" + +"@babel/parser@^7.24.4", "@babel/parser@^7.28.6", "@babel/parser@^7.29.0": + version "7.29.0" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.29.0.tgz#669ef345add7d057e92b7ed15f0bac07611831b6" + integrity sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww== + dependencies: + "@babel/types" "^7.29.0" + "@babel/runtime@^7.21.0": version "7.28.4" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.28.4.tgz#a70226016fabe25c5783b2f22d3e1c9bc5ca3326" integrity sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ== +"@babel/template@^7.28.6": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.28.6.tgz#0e7e56ecedb78aeef66ce7972b082fce76a23e57" + integrity sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ== + dependencies: + "@babel/code-frame" "^7.28.6" + "@babel/parser" "^7.28.6" + "@babel/types" "^7.28.6" + +"@babel/traverse@^7.28.6", "@babel/traverse@^7.29.0": + version "7.29.0" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.29.0.tgz#f323d05001440253eead3c9c858adbe00b90310a" + integrity sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA== + dependencies: + "@babel/code-frame" "^7.29.0" + "@babel/generator" "^7.29.0" + "@babel/helper-globals" "^7.28.0" + "@babel/parser" "^7.29.0" + "@babel/template" "^7.28.6" + "@babel/types" "^7.29.0" + debug "^4.3.1" + +"@babel/types@^7.28.6", "@babel/types@^7.29.0": + version "7.29.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.29.0.tgz#9f5b1e838c446e72cf3cd4b918152b8c605e37c7" + integrity sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A== + dependencies: + "@babel/helper-string-parser" "^7.27.1" + "@babel/helper-validator-identifier" "^7.28.5" + "@colors/colors@1.5.0": version "1.5.0" resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9" @@ -389,6 +528,18 @@ dependencies: eslint-visitor-keys "^3.4.3" +"@eslint-community/eslint-utils@^4.9.1": + version "4.9.1" + resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz#4e90af67bc51ddee6cdef5284edf572ec376b595" + integrity sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ== + dependencies: + eslint-visitor-keys "^3.4.3" + +"@eslint-community/regexpp@^4.12.2": + version "4.12.2" + resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.12.2.tgz#bccdf615bcf7b6e8db830ec0b8d21c9a25de597b" + integrity sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew== + "@eslint-community/regexpp@^4.5.1", "@eslint-community/regexpp@^4.6.1": version "4.12.1" resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.12.1.tgz#cfc6cffe39df390a3841cde2abccf92eaa7ae0e0" @@ -691,7 +842,7 @@ resolved "https://registry.yarnpkg.com/@isaacs/string-locale-compare/-/string-locale-compare-1.1.0.tgz#291c227e93fd407a96ecd59879a35809120e432b" integrity sha512-SQ7Kzhh9+D+ZW9MA0zkYv3VXhIDNx+LzM6EJ+/65I3QY+enU6Itte7E5XX7EWrqLW2FN4n06GWzBnPoC3th2aQ== -"@jridgewell/gen-mapping@^0.3.5": +"@jridgewell/gen-mapping@^0.3.12", "@jridgewell/gen-mapping@^0.3.5": version "0.3.13" resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz#6342a19f44347518c93e43b1ac69deb3c4656a1f" integrity sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA== @@ -699,7 +850,7 @@ "@jridgewell/sourcemap-codec" "^1.5.0" "@jridgewell/trace-mapping" "^0.3.24" -"@jridgewell/remapping@^2.3.4": +"@jridgewell/remapping@^2.3.4", "@jridgewell/remapping@^2.3.5": version "2.3.5" resolved "https://registry.yarnpkg.com/@jridgewell/remapping/-/remapping-2.3.5.tgz#375c476d1972947851ba1e15ae8f123047445aa1" integrity sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ== @@ -717,7 +868,7 @@ resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz#6912b00d2c631c0d15ce1a7ab57cd657f2a8f8ba" integrity sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og== -"@jridgewell/trace-mapping@^0.3.24": +"@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.28": version "0.3.31" resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz#db15d6781c931f3a251a3dac39501c98a6082fd0" integrity sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw== @@ -764,62 +915,62 @@ "@emnapi/runtime" "^1.4.3" "@tybys/wasm-util" "^0.10.0" -"@next/env@16.1.5": - version "16.1.5" - resolved "https://registry.yarnpkg.com/@next/env/-/env-16.1.5.tgz#83740cf3a0e617848c53c154b41cf141f0f536ca" - integrity sha512-CRSCPJiSZoi4Pn69RYBDI9R7YK2g59vLexPQFXY0eyw+ILevIenCywzg+DqmlBik9zszEnw2HLFOUlLAcJbL7g== +"@next/env@16.1.6": + version "16.1.6" + resolved "https://registry.yarnpkg.com/@next/env/-/env-16.1.6.tgz#0f85979498249a94ef606ef535042a831f905e89" + integrity sha512-N1ySLuZjnAtN3kFnwhAwPvZah8RJxKasD7x1f8shFqhncnWZn4JMfg37diLNuoHsLAlrDfM3g4mawVdtAG8XLQ== "@next/env@^13.4.3": version "13.5.11" resolved "https://registry.yarnpkg.com/@next/env/-/env-13.5.11.tgz#6712d907e2682199aa1e8229b5ce028ee5a8001b" integrity sha512-fbb2C7HChgM7CemdCY+y3N1n8pcTKdqtQLbC7/EQtPdLvlMUT9JX/dBYl8MMZAtYG4uVMyPFHXckb68q/NRwqg== -"@next/eslint-plugin-next@13.4.2": - version "13.4.2" - resolved "https://registry.yarnpkg.com/@next/eslint-plugin-next/-/eslint-plugin-next-13.4.2.tgz#ce32730d6282af3151a07de6e865397dc6d3dbdf" - integrity sha512-ZeFWgrxwckxTpYM+ANeUL9E7LOGPbZKmI94LJIjbDU69iEIgqd4WD0l2pVbOJMr/+vgoZmJ9Dx1m0WJ7WScXHA== - dependencies: - glob "7.1.7" - -"@next/swc-darwin-arm64@16.1.5": - version "16.1.5" - resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-16.1.5.tgz#d664b92c24f2b96e5bd21251644540e5991e44fb" - integrity sha512-eK7Wdm3Hjy/SCL7TevlH0C9chrpeOYWx2iR7guJDaz4zEQKWcS1IMVfMb9UKBFMg1XgzcPTYPIp1Vcpukkjg6Q== - -"@next/swc-darwin-x64@16.1.5": - version "16.1.5" - resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-16.1.5.tgz#196cc91fcf535f0caceb21c9d4f656fe08d26caf" - integrity sha512-foQscSHD1dCuxBmGkbIr6ScAUF6pRoDZP6czajyvmXPAOFNnQUJu2Os1SGELODjKp/ULa4fulnBWoHV3XdPLfA== - -"@next/swc-linux-arm64-gnu@16.1.5": - version "16.1.5" - resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-16.1.5.tgz#3e55467655850d5daebaabcfc62be170589b4cbc" - integrity sha512-qNIb42o3C02ccIeSeKjacF3HXotGsxh/FMk/rSRmCzOVMtoWH88odn2uZqF8RLsSUWHcAqTgYmPD3pZ03L9ZAA== - -"@next/swc-linux-arm64-musl@16.1.5": - version "16.1.5" - resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-16.1.5.tgz#c034c1783338d597d5b9aa0735ce9648592b7dfb" - integrity sha512-U+kBxGUY1xMAzDTXmuVMfhaWUZQAwzRaHJ/I6ihtR5SbTVUEaDRiEU9YMjy1obBWpdOBuk1bcm+tsmifYSygfw== - -"@next/swc-linux-x64-gnu@16.1.5": - version "16.1.5" - resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-16.1.5.tgz#82d946ade981b8ee2cc308427817841d5ccb8fa4" - integrity sha512-gq2UtoCpN7Ke/7tKaU7i/1L7eFLfhMbXjNghSv0MVGF1dmuoaPeEVDvkDuO/9LVa44h5gqpWeJ4mRRznjDv7LA== - -"@next/swc-linux-x64-musl@16.1.5": - version "16.1.5" - resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-16.1.5.tgz#3f3738014c9555d7fd195e9413840a485cedfbba" - integrity sha512-bQWSE729PbXT6mMklWLf8dotislPle2L70E9q6iwETYEOt092GDn0c+TTNj26AjmeceSsC4ndyGsK5nKqHYXjQ== - -"@next/swc-win32-arm64-msvc@16.1.5": - version "16.1.5" - resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-16.1.5.tgz#359e0ab022a41389a8d9700e41b71338752bd0ba" - integrity sha512-LZli0anutkIllMtTAWZlDqdfvjWX/ch8AFK5WgkNTvaqwlouiD1oHM+WW8RXMiL0+vAkAJyAGEzPPjO+hnrSNQ== - -"@next/swc-win32-x64-msvc@16.1.5": - version "16.1.5" - resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-16.1.5.tgz#92c0161dec3c466b120a312199a376d029b92ce2" - integrity sha512-7is37HJTNQGhjPpQbkKjKEboHYQnCgpVt/4rBrrln0D9nderNxZ8ZWs8w1fAtzUx7wEyYjQ+/13myFgFj6K2Ng== +"@next/eslint-plugin-next@16.1.6": + version "16.1.6" + resolved "https://registry.yarnpkg.com/@next/eslint-plugin-next/-/eslint-plugin-next-16.1.6.tgz#73b56b01c9db506998bd1e2d303c2605b0a1b7b0" + integrity sha512-/Qq3PTagA6+nYVfryAtQ7/9FEr/6YVyvOtl6rZnGsbReGLf0jZU6gkpr1FuChAQpvV46a78p4cmHOVP8mbfSMQ== + dependencies: + fast-glob "3.3.1" + +"@next/swc-darwin-arm64@16.1.6": + version "16.1.6" + resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-16.1.6.tgz#fbe1e360efdcc9ebd0a10301518275bc59e12a91" + integrity sha512-wTzYulosJr/6nFnqGW7FrG3jfUUlEf8UjGA0/pyypJl42ExdVgC6xJgcXQ+V8QFn6niSG2Pb8+MIG1mZr2vczw== + +"@next/swc-darwin-x64@16.1.6": + version "16.1.6" + resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-16.1.6.tgz#0e3781ef3abc8251c2a21addc733d9a87f44829b" + integrity sha512-BLFPYPDO+MNJsiDWbeVzqvYd4NyuRrEYVB5k2N3JfWncuHAy2IVwMAOlVQDFjj+krkWzhY2apvmekMkfQR0CUQ== + +"@next/swc-linux-arm64-gnu@16.1.6": + version "16.1.6" + resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-16.1.6.tgz#b24511af2c6129f2deaf5c8c04d297fe09cd40d7" + integrity sha512-OJYkCd5pj/QloBvoEcJ2XiMnlJkRv9idWA/j0ugSuA34gMT6f5b7vOiCQHVRpvStoZUknhl6/UxOXL4OwtdaBw== + +"@next/swc-linux-arm64-musl@16.1.6": + version "16.1.6" + resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-16.1.6.tgz#9d4ed0565689fc6a867250f994736a5b8c542ccb" + integrity sha512-S4J2v+8tT3NIO9u2q+S0G5KdvNDjXfAv06OhfOzNDaBn5rw84DGXWndOEB7d5/x852A20sW1M56vhC/tRVbccQ== + +"@next/swc-linux-x64-gnu@16.1.6": + version "16.1.6" + resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-16.1.6.tgz#cc757f4384e7eab7d3dba704a97f737518bae0d2" + integrity sha512-2eEBDkFlMMNQnkTyPBhQOAyn2qMxyG2eE7GPH2WIDGEpEILcBPI/jdSv4t6xupSP+ot/jkfrCShLAa7+ZUPcJQ== + +"@next/swc-linux-x64-musl@16.1.6": + version "16.1.6" + resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-16.1.6.tgz#ef1341740f29717deea7c6ec27ae6269386e20d1" + integrity sha512-oicJwRlyOoZXVlxmIMaTq7f8pN9QNbdes0q2FXfRsPhfCi8n8JmOZJm5oo1pwDaFbnnD421rVU409M3evFbIqg== + +"@next/swc-win32-arm64-msvc@16.1.6": + version "16.1.6" + resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-16.1.6.tgz#fee8719242aecf9c39c3a66f1f73821f7884dd16" + integrity sha512-gQmm8izDTPgs+DCWH22kcDmuUp7NyiJgEl18bcr8irXA5N2m2O+JQIr6f3ct42GOs9c0h8QF3L5SzIxcYAAXXw== + +"@next/swc-win32-x64-msvc@16.1.6": + version "16.1.6" + resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-16.1.6.tgz#60c27323c30f35722b20fd6d62449fbb768e46d9" + integrity sha512-NRfO39AIrzBnixKbjuo2YiYhB6o9d8v/ymU9m/Xk8cyVk+k7XylniXkHwjs4s70wedVffc6bQNbufk5v0xEm0A== "@nodelib/fs.scandir@2.1.5": version "2.1.5" @@ -1539,11 +1690,6 @@ resolved "https://registry.yarnpkg.com/@rtsao/scc/-/scc-1.1.0.tgz#927dd2fae9bc3361403ac2c7a00c32ddce9ad7e8" integrity sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g== -"@rushstack/eslint-patch@^1.1.3": - version "1.12.0" - resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.12.0.tgz#326a7b46f6d4cfa54ae25bb888551697873069b4" - integrity sha512-5EwMtOqvJMMa3HbmxLlF74e+3/HhwBTMcvt3nqVJgGCozO6hzIPOBlwm8mGVNR9SN2IJpxSnlxczyDjcn7qIyw== - "@semantic-release/changelog@6.0.3": version "6.0.3" resolved "https://registry.yarnpkg.com/@semantic-release/changelog/-/changelog-6.0.3.tgz#6195630ecbeccad174461de727d5f975abc23eeb" @@ -2430,6 +2576,20 @@ semver "^7.5.4" ts-api-utils "^1.0.1" +"@typescript-eslint/eslint-plugin@8.56.1": + version "8.56.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.56.1.tgz#b1ce606d87221daec571e293009675992f0aae76" + integrity sha512-Jz9ZztpB37dNC+HU2HI28Bs9QXpzCz+y/twHOwhyrIRdbuVDxSytJNDl6z/aAKlaRIwC7y8wJdkBv7FxYGgi0A== + dependencies: + "@eslint-community/regexpp" "^4.12.2" + "@typescript-eslint/scope-manager" "8.56.1" + "@typescript-eslint/type-utils" "8.56.1" + "@typescript-eslint/utils" "8.56.1" + "@typescript-eslint/visitor-keys" "8.56.1" + ignore "^7.0.5" + natural-compare "^1.4.0" + ts-api-utils "^2.4.0" + "@typescript-eslint/parser@7.0.1": version "7.0.1" resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-7.0.1.tgz#e9c61d9a5e32242477d92756d36086dc40322eed" @@ -2441,23 +2601,25 @@ "@typescript-eslint/visitor-keys" "7.0.1" debug "^4.3.4" -"@typescript-eslint/parser@^5.42.0": - version "5.62.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.62.0.tgz#1b63d082d849a2fcae8a569248fbe2ee1b8a56c7" - integrity sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA== +"@typescript-eslint/parser@8.56.1": + version "8.56.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.56.1.tgz#21d13b3d456ffb08614c1d68bb9a4f8d9237cdc7" + integrity sha512-klQbnPAAiGYFyI02+znpBRLyjL4/BrBd0nyWkdC0s/6xFLkXYQ8OoRrSkqacS1ddVxf/LDyODIKbQ5TgKAf/Fg== dependencies: - "@typescript-eslint/scope-manager" "5.62.0" - "@typescript-eslint/types" "5.62.0" - "@typescript-eslint/typescript-estree" "5.62.0" - debug "^4.3.4" + "@typescript-eslint/scope-manager" "8.56.1" + "@typescript-eslint/types" "8.56.1" + "@typescript-eslint/typescript-estree" "8.56.1" + "@typescript-eslint/visitor-keys" "8.56.1" + debug "^4.4.3" -"@typescript-eslint/scope-manager@5.62.0": - version "5.62.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz#d9457ccc6a0b8d6b37d0eb252a23022478c5460c" - integrity sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w== +"@typescript-eslint/project-service@8.56.1": + version "8.56.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/project-service/-/project-service-8.56.1.tgz#65c8d645f028b927bfc4928593b54e2ecd809244" + integrity sha512-TAdqQTzHNNvlVFfR+hu2PDJrURiwKsUvxFn1M0h95BB8ah5jejas08jUWG4dBA68jDMI988IvtfdAI53JzEHOQ== dependencies: - "@typescript-eslint/types" "5.62.0" - "@typescript-eslint/visitor-keys" "5.62.0" + "@typescript-eslint/tsconfig-utils" "^8.56.1" + "@typescript-eslint/types" "^8.56.1" + debug "^4.4.3" "@typescript-eslint/scope-manager@7.0.1": version "7.0.1" @@ -2467,6 +2629,19 @@ "@typescript-eslint/types" "7.0.1" "@typescript-eslint/visitor-keys" "7.0.1" +"@typescript-eslint/scope-manager@8.56.1": + version "8.56.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.56.1.tgz#254df93b5789a871351335dd23e20bc164060f24" + integrity sha512-YAi4VDKcIZp0O4tz/haYKhmIDZFEUPOreKbfdAN3SzUDMcPhJ8QI99xQXqX+HoUVq8cs85eRKnD+rne2UAnj2w== + dependencies: + "@typescript-eslint/types" "8.56.1" + "@typescript-eslint/visitor-keys" "8.56.1" + +"@typescript-eslint/tsconfig-utils@8.56.1", "@typescript-eslint/tsconfig-utils@^8.56.1": + version "8.56.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.56.1.tgz#1afa830b0fada5865ddcabdc993b790114a879b7" + integrity sha512-qOtCYzKEeyr3aR9f28mPJqBty7+DBqsdd63eO0yyDwc6vgThj2UjWfJIcsFeSucYydqcuudMOprZ+x1SpF3ZuQ== + "@typescript-eslint/type-utils@7.0.1": version "7.0.1" resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-7.0.1.tgz#0fba92c1f81cad561d7b3adc812aa1cc0e35cdae" @@ -2477,28 +2652,26 @@ debug "^4.3.4" ts-api-utils "^1.0.1" -"@typescript-eslint/types@5.62.0": - version "5.62.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.62.0.tgz#258607e60effa309f067608931c3df6fed41fd2f" - integrity sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ== +"@typescript-eslint/type-utils@8.56.1": + version "8.56.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.56.1.tgz#7a6c4fabf225d674644931e004302cbbdd2f2e24" + integrity sha512-yB/7dxi7MgTtGhZdaHCemf7PuwrHMenHjmzgUW1aJpO+bBU43OycnM3Wn+DdvDO/8zzA9HlhaJ0AUGuvri4oGg== + dependencies: + "@typescript-eslint/types" "8.56.1" + "@typescript-eslint/typescript-estree" "8.56.1" + "@typescript-eslint/utils" "8.56.1" + debug "^4.4.3" + ts-api-utils "^2.4.0" "@typescript-eslint/types@7.0.1": version "7.0.1" resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-7.0.1.tgz#dcfabce192db5b8bf77ea3c82cfaabe6e6a3c901" integrity sha512-uJDfmirz4FHib6ENju/7cz9SdMSkeVvJDK3VcMFvf/hAShg8C74FW+06MaQPODHfDJp/z/zHfgawIJRjlu0RLg== -"@typescript-eslint/typescript-estree@5.62.0": - version "5.62.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz#7d17794b77fabcac615d6a48fb143330d962eb9b" - integrity sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA== - dependencies: - "@typescript-eslint/types" "5.62.0" - "@typescript-eslint/visitor-keys" "5.62.0" - debug "^4.3.4" - globby "^11.1.0" - is-glob "^4.0.3" - semver "^7.3.7" - tsutils "^3.21.0" +"@typescript-eslint/types@8.56.1", "@typescript-eslint/types@^8.56.1": + version "8.56.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.56.1.tgz#975e5942bf54895291337c91b9191f6eb0632ab9" + integrity sha512-dbMkdIUkIkchgGDIv7KLUpa0Mda4IYjo4IAMJUZ+3xNoUXxMsk9YtKpTHSChRS85o+H9ftm51gsK1dZReY9CVw== "@typescript-eslint/typescript-estree@7.0.1": version "7.0.1" @@ -2514,6 +2687,21 @@ semver "^7.5.4" ts-api-utils "^1.0.1" +"@typescript-eslint/typescript-estree@8.56.1": + version "8.56.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.56.1.tgz#3b9e57d8129a860c50864c42188f761bdef3eab0" + integrity sha512-qzUL1qgalIvKWAf9C1HpvBjif+Vm6rcT5wZd4VoMb9+Km3iS3Cv9DY6dMRMDtPnwRAFyAi7YXJpTIEXLvdfPxg== + dependencies: + "@typescript-eslint/project-service" "8.56.1" + "@typescript-eslint/tsconfig-utils" "8.56.1" + "@typescript-eslint/types" "8.56.1" + "@typescript-eslint/visitor-keys" "8.56.1" + debug "^4.4.3" + minimatch "^10.2.2" + semver "^7.7.3" + tinyglobby "^0.2.15" + ts-api-utils "^2.4.0" + "@typescript-eslint/utils@7.0.1": version "7.0.1" resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-7.0.1.tgz#b8ceac0ba5fef362b4a03a33c0e1fedeea3734ed" @@ -2527,13 +2715,15 @@ "@typescript-eslint/typescript-estree" "7.0.1" semver "^7.5.4" -"@typescript-eslint/visitor-keys@5.62.0": - version "5.62.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz#2174011917ce582875954ffe2f6912d5931e353e" - integrity sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw== +"@typescript-eslint/utils@8.56.1": + version "8.56.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.56.1.tgz#5a86acaf9f1b4c4a85a42effb217f73059f6deb7" + integrity sha512-HPAVNIME3tABJ61siYlHzSWCGtOoeP2RTIaHXFMPqjrQKCGB9OgUVdiNgH7TJS2JNIQ5qQ4RsAUDuGaGme/KOA== dependencies: - "@typescript-eslint/types" "5.62.0" - eslint-visitor-keys "^3.3.0" + "@eslint-community/eslint-utils" "^4.9.1" + "@typescript-eslint/scope-manager" "8.56.1" + "@typescript-eslint/types" "8.56.1" + "@typescript-eslint/typescript-estree" "8.56.1" "@typescript-eslint/visitor-keys@7.0.1": version "7.0.1" @@ -2543,6 +2733,14 @@ "@typescript-eslint/types" "7.0.1" eslint-visitor-keys "^3.4.1" +"@typescript-eslint/visitor-keys@8.56.1": + version "8.56.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.56.1.tgz#50e03475c33a42d123dc99e63acf1841c0231f87" + integrity sha512-KiROIzYdEV85YygXw6BI/Dx4fnBlFQu6Mq4QE4MOH9fFnhohw6wX/OAvDY2/C+ut0I3RSPKenvZJIVYqJNkhEw== + dependencies: + "@typescript-eslint/types" "8.56.1" + eslint-visitor-keys "^5.0.0" + "@ungap/structured-clone@^1.2.0": version "1.3.0" resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.3.0.tgz#d06bbb384ebcf6c505fde1c3d0ed4ddffe0aaff8" @@ -3036,6 +3234,11 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== +balanced-match@^4.0.2: + version "4.0.4" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-4.0.4.tgz#bfb10662feed8196a2c62e7c68e17720c274179a" + integrity sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA== + bare-events@^2.2.0, bare-events@^2.5.4: version "2.6.1" resolved "https://registry.yarnpkg.com/bare-events/-/bare-events-2.6.1.tgz#f793b28bdc3dcf147d7cf01f882a6f0b12ccc4a2" @@ -3088,6 +3291,11 @@ baseline-browser-mapping@^2.8.3: resolved "https://registry.yarnpkg.com/baseline-browser-mapping/-/baseline-browser-mapping-2.8.4.tgz#e553e12272c4965682743705efd8b4b4cf0d709b" integrity sha512-L+YvJwGAgwJBV1p6ffpSTa2KRc69EeeYGYjRVWKs0GKrK+LON0GC0gV+rKSNtALEDvMDqkvCFq9r1r94/Gjwxw== +baseline-browser-mapping@^2.9.0: + version "2.10.0" + resolved "https://registry.yarnpkg.com/baseline-browser-mapping/-/baseline-browser-mapping-2.10.0.tgz#5b09935025bf8a80e29130251e337c6a7fc8cbb9" + integrity sha512-lIyg0szRfYbiy67j9KN8IyeD7q7hcmqnJ1ddWmNt19ItGpNN64mnllmxUNFIOdOm6by97jlL6wfpTTJrmnjWAA== + bcrypt-pbkdf@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" @@ -3160,6 +3368,13 @@ brace-expansion@^2.0.1: dependencies: balanced-match "^1.0.0" +brace-expansion@^5.0.2: + version "5.0.4" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-5.0.4.tgz#614daaecd0a688f660bbbc909a8748c3d80d4336" + integrity sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg== + dependencies: + balanced-match "^4.0.2" + braces@^3.0.2, braces@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789" @@ -3178,6 +3393,17 @@ browserslist@^4.23.0: node-releases "^2.0.21" update-browserslist-db "^1.1.3" +browserslist@^4.24.0: + version "4.28.1" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.28.1.tgz#7f534594628c53c63101079e27e40de490456a95" + integrity sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA== + dependencies: + baseline-browser-mapping "^2.9.0" + caniuse-lite "^1.0.30001759" + electron-to-chromium "^1.5.263" + node-releases "^2.0.27" + update-browserslist-db "^1.2.0" + buffer-crc32@~0.2.3: version "0.2.13" resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" @@ -3269,6 +3495,11 @@ caniuse-lite@^1.0.30001579, caniuse-lite@^1.0.30001599, caniuse-lite@^1.0.300017 resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001743.tgz#50ff91a991220a1ee2df5af00650dd5c308ea7cd" integrity sha512-e6Ojr7RV14Un7dz6ASD0aZDmQPT/A+eZU+nuTNfjqmRrmkmQlnTNWH0SKmqagx9PeW87UVqapSurtAXifmtdmw== +caniuse-lite@^1.0.30001759: + version "1.0.30001776" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001776.tgz#3c64d006348a2e92037aa4302345129806a42d24" + integrity sha512-sg01JDPzZ9jGshqKSckOQthXnYwOEP50jeVFhaSFbZcOy05TiuuaffDOfcwtCisJ9kNQuLBFibYywv2Bgm9osw== + cardinal@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/cardinal/-/cardinal-2.1.1.tgz#7cc1055d822d212954d07b085dea251cc7bc5505" @@ -3722,6 +3953,11 @@ conventional-commits-parser@^5.0.0: meow "^12.0.1" split2 "^4.0.0" +convert-source-map@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" + integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== + cookie@^0.4.0: version "0.4.2" resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432" @@ -3932,7 +4168,7 @@ dayjs@^1.10.4: resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.18.tgz#835fa712aac52ab9dec8b1494098774ed7070a11" integrity sha512-zFBQ7WFRvVRhKcWoUh+ZA1g2HVgUbsZm9sbddh8EC5iv93sui8DVVz1Npvz+r6meo9VKfa8NyLWBsQK1VvIKPA== -debug@4, debug@^4.0.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@^4.4.0, debug@^4.4.1: +debug@4, debug@^4.0.0, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@^4.4.0, debug@^4.4.1, debug@^4.4.3: version "4.4.3" resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.3.tgz#c6ae432d9bd9662582fce08709b038c58e9e3d6a" integrity sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA== @@ -4132,6 +4368,11 @@ electron-to-chromium@^1.5.218: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.218.tgz#921042a011a98a4620853c9d391ab62bcc124400" integrity sha512-uwwdN0TUHs8u6iRgN8vKeWZMRll4gBkz+QMqdS7DDe49uiK68/UX92lFb61oiFPrpYZNeZIqa4bA7O6Aiasnzg== +electron-to-chromium@^1.5.263: + version "1.5.307" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.307.tgz#09f8973100c39fb0d003b890393cd1d58932b1c8" + integrity sha512-5z3uFKBWjiNR44nFcYdkcXjKMbg5KXNdciu7mhTPo9tB7NbqSNP2sSnGR+fqknZSCwKkBN+oxiiajWs4dT6ORg== + emoji-regex@^8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" @@ -4379,20 +4620,20 @@ escape-string-regexp@^4.0.0: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== -eslint-config-next@13.4.2: - version "13.4.2" - resolved "https://registry.yarnpkg.com/eslint-config-next/-/eslint-config-next-13.4.2.tgz#6ee5c53b6f56bddd6346d14c22713b71da7e7b51" - integrity sha512-zjLJ9B9bbeWSo5q+iHfdt8gVYyT+y2BpWDfjR6XMBtFRSMKRGjllDKxnuKBV1q2Y/QpwLM2PXHJTMRyblCmRAg== +eslint-config-next@^16.1.6: + version "16.1.6" + resolved "https://registry.yarnpkg.com/eslint-config-next/-/eslint-config-next-16.1.6.tgz#75dd33bf32eb34b1e5be59f546e3c808429bab41" + integrity sha512-vKq40io2B0XtkkNDYyleATwblNt8xuh3FWp8SpSz3pt7P01OkBFlKsJZ2mWt5WsCySlDQLckb1zMY9yE9Qy0LA== dependencies: - "@next/eslint-plugin-next" "13.4.2" - "@rushstack/eslint-patch" "^1.1.3" - "@typescript-eslint/parser" "^5.42.0" + "@next/eslint-plugin-next" "16.1.6" eslint-import-resolver-node "^0.3.6" eslint-import-resolver-typescript "^3.5.2" - eslint-plugin-import "^2.26.0" - eslint-plugin-jsx-a11y "^6.5.1" - eslint-plugin-react "^7.31.7" - eslint-plugin-react-hooks "^4.5.0" + eslint-plugin-import "^2.32.0" + eslint-plugin-jsx-a11y "^6.10.0" + eslint-plugin-react "^7.37.0" + eslint-plugin-react-hooks "^7.0.0" + globals "16.4.0" + typescript-eslint "^8.46.0" eslint-config-prettier@9.1.0: version "9.1.0" @@ -4441,7 +4682,7 @@ eslint-module-utils@^2.12.1, eslint-module-utils@^2.7.4: dependencies: debug "^3.2.7" -eslint-plugin-import@^2.26.0: +eslint-plugin-import@^2.32.0: version "2.32.0" resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.32.0.tgz#602b55faa6e4caeaa5e970c198b5c00a37708980" integrity sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA== @@ -4466,7 +4707,7 @@ eslint-plugin-import@^2.26.0: string.prototype.trimend "^1.0.9" tsconfig-paths "^3.15.0" -eslint-plugin-jsx-a11y@^6.5.1: +eslint-plugin-jsx-a11y@^6.10.0: version "6.10.2" resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.10.2.tgz#d2812bb23bf1ab4665f1718ea442e8372e638483" integrity sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q== @@ -4495,12 +4736,18 @@ eslint-plugin-prettier@5.2.1: prettier-linter-helpers "^1.0.0" synckit "^0.9.1" -eslint-plugin-react-hooks@^4.5.0: - version "4.6.2" - resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.2.tgz#c829eb06c0e6f484b3fbb85a97e57784f328c596" - integrity sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ== +eslint-plugin-react-hooks@^7.0.0: + version "7.0.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-7.0.1.tgz#66e258db58ece50723ef20cc159f8aa908219169" + integrity sha512-O0d0m04evaNzEPoSW+59Mezf8Qt0InfgGIBJnpC0h3NH/WjUAR7BIKUfysC6todmtiZ/A0oUVS8Gce0WhBrHsA== + dependencies: + "@babel/core" "^7.24.4" + "@babel/parser" "^7.24.4" + hermes-parser "^0.25.1" + zod "^3.25.0 || ^4.0.0" + zod-validation-error "^3.5.0 || ^4.0.0" -eslint-plugin-react@^7.31.7: +eslint-plugin-react@^7.37.0: version "7.37.5" resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.37.5.tgz#2975511472bdda1b272b34d779335c9b0e877065" integrity sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA== @@ -4549,11 +4796,16 @@ eslint-scope@^7.2.2: esrecurse "^4.3.0" estraverse "^5.2.0" -eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.3: +eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.3: version "3.4.3" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800" integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== +eslint-visitor-keys@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz#9e3c9489697824d2d4ce3a8ad12628f91e9f59be" + integrity sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA== + eslint@8.57.1: version "8.57.1" resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.57.1.tgz#7df109654aba7e3bbe5c8eae533c5e461d3c6ca9" @@ -4787,6 +5039,17 @@ fast-fifo@^1.2.0, fast-fifo@^1.3.2: resolved "https://registry.yarnpkg.com/fast-fifo/-/fast-fifo-1.3.2.tgz#286e31de96eb96d38a97899815740ba2a4f3640c" integrity sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ== +fast-glob@3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.1.tgz#784b4e897340f3dbbef17413b3f11acf03c874c4" + integrity sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + fast-glob@^3.2.12, fast-glob@^3.2.9, fast-glob@^3.3.0, fast-glob@^3.3.1, fast-glob@^3.3.3: version "3.3.3" resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.3.tgz#d06d585ce8dba90a16b0505c543c3ccfb3aeb818" @@ -5141,6 +5404,11 @@ functions-have-names@^1.2.3: resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== +gensync@^1.0.0-beta.2: + version "1.0.0-beta.2" + resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" + integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== + get-caller-file@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" @@ -5281,18 +5549,6 @@ glob-parent@^6.0.2: dependencies: is-glob "^4.0.3" -glob@7.1.7: - version "7.1.7" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" - integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - glob@7.2.3, glob@^7.1.3: version "7.2.3" resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" @@ -5363,6 +5619,11 @@ global-prefix@^1.0.1: is-windows "^1.0.1" which "^1.2.14" +globals@16.4.0: + version "16.4.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-16.4.0.tgz#574bc7e72993d40cf27cf6c241f324ee77808e51" + integrity sha512-ob/2LcVVaVGCYN+r14cnwnoDPUufjiYgSqRhiFD0Q1iI4Odora5RE8Iv1D24hAz5oMophRGkGz+yuvQmmUMnMw== + globals@^13.19.0: version "13.24.0" resolved "https://registry.yarnpkg.com/globals/-/globals-13.24.0.tgz#8432a19d78ce0c1e833949c36adb345400bb1171" @@ -5647,6 +5908,18 @@ hastscript@^7.0.0: property-information "^6.0.0" space-separated-tokens "^2.0.0" +hermes-estree@0.25.1: + version "0.25.1" + resolved "https://registry.yarnpkg.com/hermes-estree/-/hermes-estree-0.25.1.tgz#6aeec17d1983b4eabf69721f3aa3eb705b17f480" + integrity sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw== + +hermes-parser@^0.25.1: + version "0.25.1" + resolved "https://registry.yarnpkg.com/hermes-parser/-/hermes-parser-0.25.1.tgz#5be0e487b2090886c62bd8a11724cd766d5f54d1" + integrity sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA== + dependencies: + hermes-estree "0.25.1" + highlight.js@~11.8.0: version "11.8.0" resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-11.8.0.tgz#966518ea83257bae2e7c9a48596231856555bb65" @@ -5793,7 +6066,7 @@ ignore@^5.2.0, ignore@^5.2.4: resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.2.tgz#3cd40e729f3643fd87cb04e50bf0eb722bc596f5" integrity sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g== -ignore@^7.0.3: +ignore@^7.0.3, ignore@^7.0.5: version "7.0.5" resolved "https://registry.yarnpkg.com/ignore/-/ignore-7.0.5.tgz#4cb5f6cd7d4c7ab0365738c7aea888baa6d7efd9" integrity sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg== @@ -6367,6 +6640,11 @@ jsbn@~0.1.0: resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" integrity sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg== +jsesc@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-3.1.0.tgz#74d335a234f67ed19907fdadfac7ccf9d409825d" + integrity sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA== + json-buffer@3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" @@ -6436,6 +6714,11 @@ json5@^1.0.2: dependencies: minimist "^1.2.0" +json5@^2.2.3: + version "2.2.3" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" + integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== + jsonfile@^6.0.1: version "6.2.0" resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.2.0.tgz#7c265bd1b65de6977478300087c99f1c84383f62" @@ -7019,6 +7302,13 @@ lru-cache@^11.0.0: resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-11.2.1.tgz#d426ac471521729c6c1acda5f7a633eadaa28db2" integrity sha512-r8LA6i4LP4EeWOhqBaZZjDWwehd1xUJPCJd9Sv300H0ZmcUER4+JPh7bqqZeqs1o5pgtgvXm+d9UGrB5zZGDiQ== +lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + lru-cache@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" @@ -7574,7 +7864,7 @@ micromatch@4.0.5: braces "^3.0.2" picomatch "^2.3.1" -micromatch@^4.0.0, micromatch@^4.0.2, micromatch@^4.0.8: +micromatch@^4.0.0, micromatch@^4.0.2, micromatch@^4.0.4, micromatch@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.8.tgz#d66fa18f3a47076789320b9b1af32bd86d9fa202" integrity sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA== @@ -7638,7 +7928,14 @@ minimatch@^10.0.3: dependencies: "@isaacs/brace-expansion" "^5.0.0" -minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: +minimatch@^10.2.2: + version "10.2.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-10.2.4.tgz#465b3accbd0218b8281f5301e27cedc697f96fde" + integrity sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg== + dependencies: + brace-expansion "^5.0.2" + +minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== @@ -7869,26 +8166,26 @@ next-themes@^0.4.6: resolved "https://registry.yarnpkg.com/next-themes/-/next-themes-0.4.6.tgz#8d7e92d03b8fea6582892a50a928c9b23502e8b6" integrity sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA== -next@16.1.5: - version "16.1.5" - resolved "https://registry.yarnpkg.com/next/-/next-16.1.5.tgz#95c9bc91bfb1bb0d3f2d441fdbb550bf18939edf" - integrity sha512-f+wE+NSbiQgh3DSAlTaw2FwY5yGdVViAtp8TotNQj4kk4Q8Bh1sC/aL9aH+Rg1YAVn18OYXsRDT7U/079jgP7w== +next@^16.1.6: + version "16.1.6" + resolved "https://registry.yarnpkg.com/next/-/next-16.1.6.tgz#24a861371cbe211be7760d9a89ddf2415e3824de" + integrity sha512-hkyRkcu5x/41KoqnROkfTm2pZVbKxvbZRuNvKXLRXxs3VfyO0WhY50TQS40EuKO9SW3rBj/sF3WbVwDACeMZyw== dependencies: - "@next/env" "16.1.5" + "@next/env" "16.1.6" "@swc/helpers" "0.5.15" baseline-browser-mapping "^2.8.3" caniuse-lite "^1.0.30001579" postcss "8.4.31" styled-jsx "5.1.6" optionalDependencies: - "@next/swc-darwin-arm64" "16.1.5" - "@next/swc-darwin-x64" "16.1.5" - "@next/swc-linux-arm64-gnu" "16.1.5" - "@next/swc-linux-arm64-musl" "16.1.5" - "@next/swc-linux-x64-gnu" "16.1.5" - "@next/swc-linux-x64-musl" "16.1.5" - "@next/swc-win32-arm64-msvc" "16.1.5" - "@next/swc-win32-x64-msvc" "16.1.5" + "@next/swc-darwin-arm64" "16.1.6" + "@next/swc-darwin-x64" "16.1.6" + "@next/swc-linux-arm64-gnu" "16.1.6" + "@next/swc-linux-arm64-musl" "16.1.6" + "@next/swc-linux-x64-gnu" "16.1.6" + "@next/swc-linux-x64-musl" "16.1.6" + "@next/swc-win32-arm64-msvc" "16.1.6" + "@next/swc-win32-x64-msvc" "16.1.6" sharp "^0.34.4" node-abi@^3.3.0: @@ -7945,6 +8242,11 @@ node-releases@^2.0.21: resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.21.tgz#f59b018bc0048044be2d4c4c04e4c8b18160894c" integrity sha512-5b0pgg78U3hwXkCM8Z9b2FJdPZlr9Psr9V2gQPESdGHqbntyFJKFW4r5TeWGFzafGY3hzs1JC62VEQMbl1JFkw== +node-releases@^2.0.27: + version "2.0.36" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.36.tgz#99fd6552aaeda9e17c4713b57a63964a2e325e9d" + integrity sha512-TdC8FSgHz8Mwtw9g5L4gR/Sh9XhSP/0DEkQxfEFXOpiul5IiHgHan2VhYYb6agDSfp4KuvltmGApc8HMgUrIkA== + nopt@^8.0.0, nopt@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/nopt/-/nopt-8.1.0.tgz#b11d38caf0f8643ce885818518064127f602eae3" @@ -8895,10 +9197,10 @@ react-day-picker@^8.8.2: resolved "https://registry.yarnpkg.com/react-day-picker/-/react-day-picker-8.10.1.tgz#4762ec298865919b93ec09ba69621580835b8e80" integrity sha512-TMx7fNbhLk15eqcMt+7Z7S2KF7mfTId/XJDjKE8f+IUcFn0l08/kI4FiYTL/0yuOLmEcbR4Fwe3GJf/NiiMnPA== -react-dom@19.2.1: - version "19.2.1" - resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-19.2.1.tgz#ce3527560bda4f997e47d10dab754825b3061f59" - integrity sha512-ibrK8llX2a4eOskq1mXKu/TGZj9qzomO+sNfO98M6d9zIPOEhlBkMkBUBLd1vgS0gQsLDBzA+8jJBVXDnfHmJg== +react-dom@^19.2.4: + version "19.2.4" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-19.2.4.tgz#6fac6bd96f7db477d966c7ec17c1a2b1ad8e6591" + integrity sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ== dependencies: scheduler "^0.27.0" @@ -9001,10 +9303,10 @@ react-use-keypress@^1.3.1: dependencies: tiny-invariant "^1.2.0" -react@19.2.1: - version "19.2.1" - resolved "https://registry.yarnpkg.com/react/-/react-19.2.1.tgz#8600fa205e58e2e807f6ef431c9f6492591a2700" - integrity sha512-DGrYcCWK7tvYMnWh79yrPHt+vdx9tY+1gPZa7nJQtO/p8bLTDaHp4dzwEhQB7pZ4Xe3ok4XKuEPrVuc+wlpkmw== +react@^19.2.4: + version "19.2.4" + resolved "https://registry.yarnpkg.com/react/-/react-19.2.4.tgz#438e57baa19b77cb23aab516cf635cd0579ee09a" + integrity sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ== read-cmd-shim@^5.0.0: version "5.0.0" @@ -10359,7 +10661,7 @@ tinyexec@^1.0.0: resolved "https://registry.yarnpkg.com/tinyexec/-/tinyexec-1.0.1.tgz#70c31ab7abbb4aea0a24f55d120e5990bfa1e0b1" integrity sha512-5uC6DDlmeqiOwCPmK9jMSdOuZTh8bU39Ys6yidB+UTt5hfZUPGAypSgFRiEp+jbi9qH40BLDvy85jIU88wKSqw== -tinyglobby@^0.2.12, tinyglobby@^0.2.13: +tinyglobby@^0.2.12, tinyglobby@^0.2.13, tinyglobby@^0.2.15: version "0.2.15" resolved "https://registry.yarnpkg.com/tinyglobby/-/tinyglobby-0.2.15.tgz#e228dd1e638cea993d2fdb4fcd2d4602a79951c2" integrity sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ== @@ -10431,6 +10733,11 @@ ts-api-utils@^1.0.1: resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.4.3.tgz#bfc2215fe6528fecab2b0fba570a2e8a4263b064" integrity sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw== +ts-api-utils@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-2.4.0.tgz#2690579f96d2790253bdcf1ca35d569ad78f9ad8" + integrity sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA== + ts-interface-checker@1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/ts-interface-checker/-/ts-interface-checker-1.0.2.tgz#63f73a098b0ed34b982df1f490c54890e8e5e0b3" @@ -10446,23 +10753,11 @@ tsconfig-paths@^3.15.0: minimist "^1.2.6" strip-bom "^3.0.0" -tslib@^1.8.1: - version "1.14.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" - integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== - tslib@^2.0.0, tslib@^2.1.0, tslib@^2.4.0, tslib@^2.6.2, tslib@^2.8.0: version "2.8.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f" integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== -tsutils@^3.21.0: - version "3.21.0" - resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" - integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== - dependencies: - tslib "^1.8.1" - tsx@^4.21.0: version "4.21.0" resolved "https://registry.yarnpkg.com/tsx/-/tsx-4.21.0.tgz#32aa6cf17481e336f756195e6fe04dae3e6308b1" @@ -10591,6 +10886,16 @@ typed-array-length@^1.0.7: possible-typed-array-names "^1.0.0" reflect.getprototypeof "^1.0.6" +typescript-eslint@^8.46.0: + version "8.56.1" + resolved "https://registry.yarnpkg.com/typescript-eslint/-/typescript-eslint-8.56.1.tgz#15a9fcc5d2150a0d981772bb36f127a816fe103f" + integrity sha512-U4lM6pjmBX7J5wk4szltF7I1cGBHXZopnAXCMXb3+fZ3B/0Z3hq3wS/CCUB2NZBNAExK92mCU2tEohWuwVMsDQ== + dependencies: + "@typescript-eslint/eslint-plugin" "8.56.1" + "@typescript-eslint/parser" "8.56.1" + "@typescript-eslint/typescript-estree" "8.56.1" + "@typescript-eslint/utils" "8.56.1" + typescript@5.3.3: version "5.3.3" resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.3.3.tgz#b3ce6ba258e72e6305ba66f5c9b452aaee3ffe37" @@ -10776,6 +11081,14 @@ update-browserslist-db@^1.1.3: escalade "^3.2.0" picocolors "^1.1.1" +update-browserslist-db@^1.2.0: + version "1.2.3" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz#64d76db58713136acbeb4c49114366cc6cc2e80d" + integrity sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w== + dependencies: + escalade "^3.2.0" + picocolors "^1.1.1" + uri-js@^4.2.2: version "4.4.1" resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" @@ -11072,6 +11385,11 @@ y18n@^5.0.5: resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== +yallist@^3.0.2: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== + yallist@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" @@ -11128,6 +11446,16 @@ yocto-queue@^1.0.0: resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-1.2.1.tgz#36d7c4739f775b3cbc28e6136e21aa057adec418" integrity sha512-AyeEbWOu/TAXdxlV9wmGcR0+yh2j3vYPGOECcIj2S7MkrLyC7ne+oye2BKTItt0ii2PHk4cDy+95+LshzbXnGg== +"zod-validation-error@^3.5.0 || ^4.0.0": + version "4.0.2" + resolved "https://registry.yarnpkg.com/zod-validation-error/-/zod-validation-error-4.0.2.tgz#bc605eba49ce0fcd598c127fee1c236be3f22918" + integrity sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ== + +"zod@^3.25.0 || ^4.0.0": + version "4.3.6" + resolved "https://registry.yarnpkg.com/zod/-/zod-4.3.6.tgz#89c56e0aa7d2b05107d894412227087885ab112a" + integrity sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg== + zustand@4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/zustand/-/zustand-4.0.0.tgz#739cba69209ffe67b31e7d6741c25b51496114a7"