diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml
deleted file mode 100644
index eb74b85..0000000
--- a/.github/ISSUE_TEMPLATE/bug_report.yml
+++ /dev/null
@@ -1,80 +0,0 @@
-name: Bug Report
-description: Report a bug or unexpected behavior
-title: "[Bug]: "
-labels: ["bug"]
-body:
- - type: markdown
- attributes:
- value: |
- Thanks for taking the time to report a bug! Please fill out the form below.
-
- - type: dropdown
- id: component
- attributes:
- label: Component
- description: Which part of ATAuth is affected?
- options:
- - Rust Library
- - TypeScript Library
- - Gateway Server
- - Documentation
- - CI/CD
- validations:
- required: true
-
- - type: textarea
- id: description
- attributes:
- label: Bug Description
- description: A clear and concise description of what the bug is.
- placeholder: Describe the bug...
- validations:
- required: true
-
- - type: textarea
- id: reproduction
- attributes:
- label: Steps to Reproduce
- description: How can we reproduce this behavior?
- placeholder: |
- 1. Configure...
- 2. Call...
- 3. See error...
- validations:
- required: true
-
- - type: textarea
- id: expected
- attributes:
- label: Expected Behavior
- description: What did you expect to happen?
- validations:
- required: true
-
- - type: textarea
- id: environment
- attributes:
- label: Environment
- description: Please provide relevant environment information
- placeholder: |
- - OS: [e.g., Ubuntu 22.04, macOS 14]
- - Rust version: [e.g., 1.75.0]
- - Node.js version: [e.g., 20.10.0]
- - ATAuth version: [e.g., 1.0.0]
-
- - type: textarea
- id: logs
- attributes:
- label: Relevant Logs
- description: If applicable, add logs or error messages.
- render: shell
-
- - type: checkboxes
- id: terms
- attributes:
- label: Checklist
- options:
- - label: I have searched existing issues to ensure this is not a duplicate
- required: true
- - label: I have read the documentation
- required: true
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
deleted file mode 100644
index be5e175..0000000
--- a/.github/ISSUE_TEMPLATE/config.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-blank_issues_enabled: false
-contact_links:
- - name: Documentation
- url: https://github.com/Cache8063/atauth#readme
- about: Check out the documentation before opening an issue
- - name: Discussions
- url: https://github.com/Cache8063/atauth/discussions
- about: Ask questions and discuss ideas
diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml
deleted file mode 100644
index 06a3a2f..0000000
--- a/.github/ISSUE_TEMPLATE/feature_request.yml
+++ /dev/null
@@ -1,65 +0,0 @@
-name: Feature Request
-description: Suggest a new feature or enhancement
-title: "[Feature]: "
-labels: ["enhancement"]
-body:
- - type: markdown
- attributes:
- value: |
- Thanks for suggesting a new feature! Please fill out the form below.
-
- - type: dropdown
- id: component
- attributes:
- label: Component
- description: Which part of ATAuth would this feature affect?
- options:
- - Rust Library
- - TypeScript Library
- - Gateway Server
- - Documentation
- - CI/CD
- - New Component
- validations:
- required: true
-
- - type: textarea
- id: problem
- attributes:
- label: Problem Statement
- description: What problem does this feature solve? What use case does it address?
- placeholder: I'm trying to... but currently...
- validations:
- required: true
-
- - type: textarea
- id: solution
- attributes:
- label: Proposed Solution
- description: Describe the solution you'd like to see implemented.
- placeholder: It would be great if...
- validations:
- required: true
-
- - type: textarea
- id: alternatives
- attributes:
- label: Alternatives Considered
- description: Have you considered any alternative solutions or workarounds?
- placeholder: I also considered...
-
- - type: textarea
- id: additional
- attributes:
- label: Additional Context
- description: Add any other context, mockups, or examples about the feature request.
-
- - type: checkboxes
- id: terms
- attributes:
- label: Checklist
- options:
- - label: I have searched existing issues to ensure this is not a duplicate
- required: true
- - label: I have read the documentation
- required: true
diff --git a/.github/ISSUE_TEMPLATE/security_report.yml b/.github/ISSUE_TEMPLATE/security_report.yml
deleted file mode 100644
index 0e9ceec..0000000
--- a/.github/ISSUE_TEMPLATE/security_report.yml
+++ /dev/null
@@ -1,80 +0,0 @@
-name: Security Report
-description: Report a security vulnerability (for non-critical issues)
-title: "[Security]: "
-labels: ["security"]
-body:
- - type: markdown
- attributes:
- value: |
- Thank you for reporting a security issue. For critical vulnerabilities, please email the maintainers directly instead of opening a public issue.
-
- - type: dropdown
- id: severity
- attributes:
- label: Severity
- description: How severe is this security issue?
- options:
- - Low - Minor issue with limited impact
- - Medium - Moderate impact, workaround available
- - High - Significant impact, no easy workaround
- validations:
- required: true
-
- - type: dropdown
- id: component
- attributes:
- label: Affected Component
- description: Which part of ATAuth is affected?
- options:
- - Rust Library
- - TypeScript Library
- - Gateway Server
- - Dependencies
- - CI/CD
- validations:
- required: true
-
- - type: textarea
- id: description
- attributes:
- label: Vulnerability Description
- description: Describe the security issue. Be specific but avoid including exploit code.
- placeholder: The issue is...
- validations:
- required: true
-
- - type: textarea
- id: impact
- attributes:
- label: Potential Impact
- description: What could an attacker do by exploiting this vulnerability?
- placeholder: An attacker could...
- validations:
- required: true
-
- - type: textarea
- id: reproduction
- attributes:
- label: Steps to Reproduce
- description: How can we verify this vulnerability exists?
- placeholder: |
- 1. Configure...
- 2. Send request...
- 3. Observe...
-
- - type: textarea
- id: mitigation
- attributes:
- label: Suggested Mitigation
- description: If you have ideas for how to fix this, please share them.
- placeholder: This could be fixed by...
-
- - type: checkboxes
- id: terms
- attributes:
- label: Checklist
- options:
- - label: I have verified this is not a critical vulnerability that should be reported privately
- required: true
- - label: I have searched existing issues to ensure this is not a duplicate
- required: true
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
deleted file mode 100644
index 3874847..0000000
--- a/.github/pull_request_template.md
+++ /dev/null
@@ -1,26 +0,0 @@
-## Description
-
-Brief description of the changes in this PR.
-
-## Related Issues
-
-Fixes #(issue number)
-
-## Type of Change
-
-- [ ] Bug fix (non-breaking change that fixes an issue)
-- [ ] New feature (non-breaking change that adds functionality)
-- [ ] Breaking change (fix or feature that would cause existing functionality to change)
-- [ ] Documentation update
-
-## Checklist
-
-- [ ] My code follows the project's code style
-- [ ] I have added tests that prove my fix/feature works
-- [ ] All new and existing tests pass
-- [ ] I have updated the documentation accordingly
-- [ ] I have added entries to CHANGELOG.md (if applicable)
-
-## Testing
-
-Describe how you tested these changes.
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
deleted file mode 100644
index f7384b4..0000000
--- a/.github/workflows/ci.yml
+++ /dev/null
@@ -1,104 +0,0 @@
-name: CI
-
-on:
- push:
- branches: [main]
- pull_request:
- branches: [main]
-
-env:
- CARGO_TERM_COLOR: always
-
-jobs:
- rust:
- name: Rust
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v4
-
- - name: Install Rust toolchain
- uses: dtolnay/rust-toolchain@stable
- with:
- components: rustfmt, clippy
-
- - name: Cache cargo
- uses: actions/cache@v4
- with:
- path: |
- ~/.cargo/bin/
- ~/.cargo/registry/index/
- ~/.cargo/registry/cache/
- ~/.cargo/git/db/
- target/
- key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
-
- - name: Check formatting
- run: cargo fmt --all -- --check
-
- - name: Run clippy
- run: cargo clippy --all-features -- -D warnings
-
- - name: Build
- run: cargo build --all-features
-
- - name: Run tests
- run: cargo test --all-features
-
- typescript:
- name: TypeScript
- runs-on: ubuntu-latest
- defaults:
- run:
- working-directory: ts
- steps:
- - uses: actions/checkout@v4
-
- - name: Setup Node.js
- uses: actions/setup-node@v4
- with:
- node-version: '20'
- cache: 'npm'
- cache-dependency-path: ts/package-lock.json
-
- - name: Install dependencies
- run: npm ci
-
- - name: Type check
- run: npm run typecheck
-
- - name: Lint
- run: npm run lint
-
- - name: Build
- run: npm run build
-
- - name: Test
- run: npm test || echo "No tests found, skipping"
-
- gateway:
- name: Gateway
- runs-on: ubuntu-latest
- defaults:
- run:
- working-directory: gateway
- steps:
- - uses: actions/checkout@v4
-
- - name: Setup Node.js
- uses: actions/setup-node@v4
- with:
- node-version: '20'
- cache: 'npm'
- cache-dependency-path: gateway/package-lock.json
-
- - name: Install dependencies
- run: npm ci
-
- - name: Type check
- run: npm run typecheck
-
- - name: Lint
- run: npm run lint
-
- - name: Build
- run: npm run build
diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml
deleted file mode 100644
index 040d153..0000000
--- a/.github/workflows/docker.yml
+++ /dev/null
@@ -1,68 +0,0 @@
-name: Build and Push Docker Image
-
-on:
- push:
- branches: [main]
- tags: ['v*']
- pull_request:
- branches: [main]
-
-env:
- REGISTRY: ghcr.io
-
-jobs:
- build:
- runs-on: ubuntu-latest
- permissions:
- contents: read
- packages: write
-
- steps:
- - name: Checkout repository
- uses: actions/checkout@v4
-
- - name: Set image name (lowercase)
- id: image
- run: echo "name=${GITHUB_REPOSITORY_OWNER,,}/atauth-gateway" >> $GITHUB_OUTPUT
-
- - name: Set up Docker Buildx
- uses: docker/setup-buildx-action@v3
-
- - name: Log in to Container Registry
- if: github.event_name != 'pull_request'
- uses: docker/login-action@v3
- with:
- registry: ${{ env.REGISTRY }}
- username: ${{ github.actor }}
- password: ${{ secrets.GITHUB_TOKEN }}
-
- - name: Extract metadata
- id: meta
- uses: docker/metadata-action@v5
- with:
- images: ${{ env.REGISTRY }}/${{ steps.image.outputs.name }}
- tags: |
- type=ref,event=branch
- type=ref,event=pr
- type=semver,pattern={{version}}
- type=semver,pattern={{major}}.{{minor}}
- type=semver,pattern={{major}}
- type=raw,value=latest,enable={{is_default_branch}}
-
- - name: Build and push Docker image
- uses: docker/build-push-action@v5
- with:
- context: ./gateway
- file: ./gateway/Dockerfile
- push: ${{ github.event_name != 'pull_request' }}
- tags: ${{ steps.meta.outputs.tags }}
- labels: ${{ steps.meta.outputs.labels }}
- cache-from: type=gha
- cache-to: type=gha,mode=max
- platforms: linux/amd64,linux/arm64
-
- - name: Generate SBOM
- if: github.event_name != 'pull_request'
- uses: anchore/sbom-action@v0
- with:
- image: ${{ env.REGISTRY }}/${{ steps.image.outputs.name }}:latest
diff --git a/gateway/.dockerignore b/gateway/.dockerignore
index 61477b2..248f249 100644
--- a/gateway/.dockerignore
+++ b/gateway/.dockerignore
@@ -1,10 +1,8 @@
# Dependencies
node_modules/
-admin-ui/node_modules/
# Build output (rebuilt in container)
dist/
-public/admin/
# Development files
*.log
@@ -31,7 +29,3 @@ coverage/
# Data (mounted as volume)
data/
-
-# Kubernetes and Helm (not needed in image)
-k8s/
-helm/
diff --git a/gateway/.gitea/workflows/build.yaml b/gateway/.gitea/workflows/build.yaml
deleted file mode 100644
index b8e365a..0000000
--- a/gateway/.gitea/workflows/build.yaml
+++ /dev/null
@@ -1,84 +0,0 @@
-name: Build and Push
-
-on:
- push:
- branches:
- - main
- - develop
- tags:
- - 'v*'
- pull_request:
- branches:
- - main
-
-env:
- REGISTRY: gitea.cloudforest-basilisk.ts.net
- IMAGE_NAME: arcnode.xyz/atauth-gateway
-
-jobs:
- build:
- runs-on: ubuntu-latest
- steps:
- - name: Checkout
- uses: actions/checkout@v4
-
- - name: Set up Docker Buildx
- uses: docker/setup-buildx-action@v3
-
- - name: Log in to Container Registry
- uses: docker/login-action@v3
- with:
- registry: ${{ env.REGISTRY }}
- username: ${{ secrets.REGISTRY_USERNAME }}
- password: ${{ secrets.REGISTRY_PASSWORD }}
-
- - name: Extract metadata
- id: meta
- uses: docker/metadata-action@v5
- with:
- images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
- tags: |
- type=ref,event=branch
- type=ref,event=pr
- type=semver,pattern={{version}}
- type=semver,pattern={{major}}.{{minor}}
- type=sha,prefix=
- type=raw,value=latest,enable={{is_default_branch}}
-
- - name: Build and push
- uses: docker/build-push-action@v5
- with:
- context: ./gateway
- push: ${{ github.event_name != 'pull_request' }}
- tags: ${{ steps.meta.outputs.tags }}
- labels: ${{ steps.meta.outputs.labels }}
- cache-from: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache
- cache-to: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache,mode=max
-
- deploy:
- needs: build
- if: github.ref == 'refs/heads/main' && github.event_name == 'push'
- runs-on: ubuntu-latest
- steps:
- - name: Checkout
- uses: actions/checkout@v4
-
- - name: Set up kubectl
- uses: azure/setup-kubectl@v3
-
- - name: Configure kubeconfig
- run: |
- mkdir -p ~/.kube
- echo "${{ secrets.KUBECONFIG }}" | base64 -d > ~/.kube/config
- chmod 600 ~/.kube/config
-
- - name: Deploy to k3s
- run: |
- # Update image tag in kustomization
- cd gateway/k8s
- kubectl kustomize . | \
- sed "s|atauth-gateway:latest|${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}|g" | \
- kubectl apply -f -
-
- # Wait for rollout
- kubectl -n atauth rollout status deployment/atauth-gateway --timeout=300s
diff --git a/gateway/Dockerfile b/gateway/Dockerfile
index 3bd2d9f..4cd712a 100644
--- a/gateway/Dockerfile
+++ b/gateway/Dockerfile
@@ -5,22 +5,7 @@
# Run: docker run -p 3100:3100 -v ./data:/app/data atauth-gateway
# ============================================
-# Stage 1: Build Admin UI
-# ============================================
-FROM node:20-alpine AS admin-ui-builder
-
-WORKDIR /app/admin-ui
-
-# Install dependencies
-COPY admin-ui/package.json admin-ui/package-lock.json* ./
-RUN npm ci
-
-# Build admin UI
-COPY admin-ui/ ./
-RUN npm run build
-
-# ============================================
-# Stage 2: Build Gateway Backend
+# Stage 1: Build Gateway Backend
# ============================================
FROM node:20-alpine AS backend-builder
@@ -36,7 +21,7 @@ COPY src/ ./src/
RUN npm run build
# ============================================
-# Stage 3: Production Image
+# Stage 2: Production Image
# ============================================
FROM node:20-alpine
@@ -53,11 +38,8 @@ RUN npm ci --omit=dev && npm cache clean --force
# Copy built backend
COPY --from=backend-builder /app/dist ./dist
-# Copy built admin UI (built to ../public/admin relative to admin-ui)
-COPY --from=admin-ui-builder /app/public/admin ./public/admin
-
# Create writable data directory owned by app user
-# Note: node_modules/dist/public stay root-owned (read-only is fine)
+# Note: node_modules/dist stay root-owned (read-only is fine)
# Avoid chown -R /app which is extremely slow on overlay2+ZFS
RUN mkdir -p /app/data && chown atauth:atauth /app/data
diff --git a/gateway/admin-ui/.gitignore b/gateway/admin-ui/.gitignore
deleted file mode 100644
index a547bf3..0000000
--- a/gateway/admin-ui/.gitignore
+++ /dev/null
@@ -1,24 +0,0 @@
-# Logs
-logs
-*.log
-npm-debug.log*
-yarn-debug.log*
-yarn-error.log*
-pnpm-debug.log*
-lerna-debug.log*
-
-node_modules
-dist
-dist-ssr
-*.local
-
-# Editor directories and files
-.vscode/*
-!.vscode/extensions.json
-.idea
-.DS_Store
-*.suo
-*.ntvs*
-*.njsproj
-*.sln
-*.sw?
diff --git a/gateway/admin-ui/README.md b/gateway/admin-ui/README.md
deleted file mode 100644
index d2e7761..0000000
--- a/gateway/admin-ui/README.md
+++ /dev/null
@@ -1,73 +0,0 @@
-# React + TypeScript + Vite
-
-This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
-
-Currently, two official plugins are available:
-
-- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) (or [oxc](https://oxc.rs) when used in [rolldown-vite](https://vite.dev/guide/rolldown)) for Fast Refresh
-- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
-
-## React Compiler
-
-The React Compiler is not enabled on this template because of its impact on dev & build performances. To add it, see [this documentation](https://react.dev/learn/react-compiler/installation).
-
-## Expanding the ESLint configuration
-
-If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules:
-
-```js
-export default defineConfig([
- globalIgnores(['dist']),
- {
- files: ['**/*.{ts,tsx}'],
- extends: [
- // Other configs...
-
- // Remove tseslint.configs.recommended and replace with this
- tseslint.configs.recommendedTypeChecked,
- // Alternatively, use this for stricter rules
- tseslint.configs.strictTypeChecked,
- // Optionally, add this for stylistic rules
- tseslint.configs.stylisticTypeChecked,
-
- // Other configs...
- ],
- languageOptions: {
- parserOptions: {
- project: ['./tsconfig.node.json', './tsconfig.app.json'],
- tsconfigRootDir: import.meta.dirname,
- },
- // other options...
- },
- },
-])
-```
-
-You can also install [eslint-plugin-react-x](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom) for React-specific lint rules:
-
-```js
-// eslint.config.js
-import reactX from 'eslint-plugin-react-x'
-import reactDom from 'eslint-plugin-react-dom'
-
-export default defineConfig([
- globalIgnores(['dist']),
- {
- files: ['**/*.{ts,tsx}'],
- extends: [
- // Other configs...
- // Enable lint rules for React
- reactX.configs['recommended-typescript'],
- // Enable lint rules for React DOM
- reactDom.configs.recommended,
- ],
- languageOptions: {
- parserOptions: {
- project: ['./tsconfig.node.json', './tsconfig.app.json'],
- tsconfigRootDir: import.meta.dirname,
- },
- // other options...
- },
- },
-])
-```
diff --git a/gateway/admin-ui/eslint.config.js b/gateway/admin-ui/eslint.config.js
deleted file mode 100644
index 5e6b472..0000000
--- a/gateway/admin-ui/eslint.config.js
+++ /dev/null
@@ -1,23 +0,0 @@
-import js from '@eslint/js'
-import globals from 'globals'
-import reactHooks from 'eslint-plugin-react-hooks'
-import reactRefresh from 'eslint-plugin-react-refresh'
-import tseslint from 'typescript-eslint'
-import { defineConfig, globalIgnores } from 'eslint/config'
-
-export default defineConfig([
- globalIgnores(['dist']),
- {
- files: ['**/*.{ts,tsx}'],
- extends: [
- js.configs.recommended,
- tseslint.configs.recommended,
- reactHooks.configs.flat.recommended,
- reactRefresh.configs.vite,
- ],
- languageOptions: {
- ecmaVersion: 2020,
- globals: globals.browser,
- },
- },
-])
diff --git a/gateway/admin-ui/index.html b/gateway/admin-ui/index.html
deleted file mode 100644
index eeabc17..0000000
--- a/gateway/admin-ui/index.html
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
-
-
- admin-ui
-
-
-
-
-
-
diff --git a/gateway/admin-ui/package-lock.json b/gateway/admin-ui/package-lock.json
deleted file mode 100644
index be154d5..0000000
--- a/gateway/admin-ui/package-lock.json
+++ /dev/null
@@ -1,3877 +0,0 @@
-{
- "name": "admin-ui",
- "version": "0.0.0",
- "lockfileVersion": 3,
- "requires": true,
- "packages": {
- "": {
- "name": "admin-ui",
- "version": "0.0.0",
- "dependencies": {
- "@tailwindcss/vite": "^4.1.18",
- "@tanstack/react-query": "^5.90.20",
- "react": "^19.2.0",
- "react-dom": "^19.2.0",
- "react-router-dom": "^7.13.0",
- "tailwindcss": "^4.1.18",
- "zustand": "^5.0.11"
- },
- "devDependencies": {
- "@eslint/js": "^9.39.1",
- "@types/node": "^24.10.1",
- "@types/react": "^19.2.5",
- "@types/react-dom": "^19.2.3",
- "@vitejs/plugin-react": "^5.1.1",
- "eslint": "^9.39.1",
- "eslint-plugin-react-hooks": "^7.0.1",
- "eslint-plugin-react-refresh": "^0.4.24",
- "globals": "^16.5.0",
- "typescript": "~5.9.3",
- "typescript-eslint": "^8.46.4",
- "vite": "^7.2.4"
- }
- },
- "node_modules/@babel/code-frame": {
- "version": "7.29.0",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz",
- "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-validator-identifier": "^7.28.5",
- "js-tokens": "^4.0.0",
- "picocolors": "^1.1.1"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/compat-data": {
- "version": "7.29.0",
- "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.0.tgz",
- "integrity": "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/core": {
- "version": "7.29.0",
- "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.0.tgz",
- "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==",
- "dev": true,
- "license": "MIT",
- "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"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/babel"
- }
- },
- "node_modules/@babel/generator": {
- "version": "7.29.1",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz",
- "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==",
- "dev": true,
- "license": "MIT",
- "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"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-compilation-targets": {
- "version": "7.28.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz",
- "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==",
- "dev": true,
- "license": "MIT",
- "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"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-globals": {
- "version": "7.28.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz",
- "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-module-imports": {
- "version": "7.28.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz",
- "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/traverse": "^7.28.6",
- "@babel/types": "^7.28.6"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-module-transforms": {
- "version": "7.28.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz",
- "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-module-imports": "^7.28.6",
- "@babel/helper-validator-identifier": "^7.28.5",
- "@babel/traverse": "^7.28.6"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0"
- }
- },
- "node_modules/@babel/helper-plugin-utils": {
- "version": "7.28.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz",
- "integrity": "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-string-parser": {
- "version": "7.27.1",
- "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
- "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-validator-identifier": {
- "version": "7.28.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz",
- "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-validator-option": {
- "version": "7.27.1",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz",
- "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helpers": {
- "version": "7.28.6",
- "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.6.tgz",
- "integrity": "sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/template": "^7.28.6",
- "@babel/types": "^7.28.6"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/parser": {
- "version": "7.29.0",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.0.tgz",
- "integrity": "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/types": "^7.29.0"
- },
- "bin": {
- "parser": "bin/babel-parser.js"
- },
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@babel/plugin-transform-react-jsx-self": {
- "version": "7.27.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz",
- "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.27.1"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-react-jsx-source": {
- "version": "7.27.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz",
- "integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.27.1"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/template": {
- "version": "7.28.6",
- "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz",
- "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/code-frame": "^7.28.6",
- "@babel/parser": "^7.28.6",
- "@babel/types": "^7.28.6"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/traverse": {
- "version": "7.29.0",
- "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz",
- "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==",
- "dev": true,
- "license": "MIT",
- "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"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/types": {
- "version": "7.29.0",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz",
- "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-string-parser": "^7.27.1",
- "@babel/helper-validator-identifier": "^7.28.5"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@esbuild/aix-ppc64": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.2.tgz",
- "integrity": "sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==",
- "cpu": [
- "ppc64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "aix"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/android-arm": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.2.tgz",
- "integrity": "sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==",
- "cpu": [
- "arm"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/android-arm64": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.2.tgz",
- "integrity": "sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/android-x64": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.2.tgz",
- "integrity": "sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/darwin-arm64": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.2.tgz",
- "integrity": "sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/darwin-x64": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.2.tgz",
- "integrity": "sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/freebsd-arm64": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.2.tgz",
- "integrity": "sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/freebsd-x64": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.2.tgz",
- "integrity": "sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-arm": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.2.tgz",
- "integrity": "sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==",
- "cpu": [
- "arm"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-arm64": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.2.tgz",
- "integrity": "sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-ia32": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.2.tgz",
- "integrity": "sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==",
- "cpu": [
- "ia32"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-loong64": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.2.tgz",
- "integrity": "sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==",
- "cpu": [
- "loong64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-mips64el": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.2.tgz",
- "integrity": "sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==",
- "cpu": [
- "mips64el"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-ppc64": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.2.tgz",
- "integrity": "sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==",
- "cpu": [
- "ppc64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-riscv64": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.2.tgz",
- "integrity": "sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==",
- "cpu": [
- "riscv64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-s390x": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.2.tgz",
- "integrity": "sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==",
- "cpu": [
- "s390x"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-x64": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.2.tgz",
- "integrity": "sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/netbsd-arm64": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.2.tgz",
- "integrity": "sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "netbsd"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/netbsd-x64": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.2.tgz",
- "integrity": "sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "netbsd"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/openbsd-arm64": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.2.tgz",
- "integrity": "sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "openbsd"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/openbsd-x64": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.2.tgz",
- "integrity": "sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "openbsd"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/openharmony-arm64": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.2.tgz",
- "integrity": "sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "openharmony"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/sunos-x64": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.2.tgz",
- "integrity": "sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "sunos"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/win32-arm64": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.2.tgz",
- "integrity": "sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/win32-ia32": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.2.tgz",
- "integrity": "sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==",
- "cpu": [
- "ia32"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/win32-x64": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.2.tgz",
- "integrity": "sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@eslint-community/eslint-utils": {
- "version": "4.9.1",
- "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz",
- "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "eslint-visitor-keys": "^3.4.3"
- },
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/eslint"
- },
- "peerDependencies": {
- "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
- }
- },
- "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": {
- "version": "3.4.3",
- "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
- "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
- "dev": true,
- "license": "Apache-2.0",
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/eslint"
- }
- },
- "node_modules/@eslint-community/regexpp": {
- "version": "4.12.2",
- "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz",
- "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
- }
- },
- "node_modules/@eslint/config-array": {
- "version": "0.21.1",
- "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz",
- "integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "@eslint/object-schema": "^2.1.7",
- "debug": "^4.3.1",
- "minimatch": "^3.1.2"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- }
- },
- "node_modules/@eslint/config-helpers": {
- "version": "0.4.2",
- "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz",
- "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "@eslint/core": "^0.17.0"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- }
- },
- "node_modules/@eslint/core": {
- "version": "0.17.0",
- "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz",
- "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "@types/json-schema": "^7.0.15"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- }
- },
- "node_modules/@eslint/eslintrc": {
- "version": "3.3.3",
- "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.3.tgz",
- "integrity": "sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ajv": "^6.12.4",
- "debug": "^4.3.2",
- "espree": "^10.0.1",
- "globals": "^14.0.0",
- "ignore": "^5.2.0",
- "import-fresh": "^3.2.1",
- "js-yaml": "^4.1.1",
- "minimatch": "^3.1.2",
- "strip-json-comments": "^3.1.1"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "url": "https://opencollective.com/eslint"
- }
- },
- "node_modules/@eslint/eslintrc/node_modules/globals": {
- "version": "14.0.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz",
- "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/@eslint/js": {
- "version": "9.39.2",
- "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.2.tgz",
- "integrity": "sha512-q1mjIoW1VX4IvSocvM/vbTiveKC4k9eLrajNEuSsmjymSDEbpGddtpfOoN7YGAqBK3NG+uqo8ia4PDTt8buCYA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "url": "https://eslint.org/donate"
- }
- },
- "node_modules/@eslint/object-schema": {
- "version": "2.1.7",
- "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz",
- "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==",
- "dev": true,
- "license": "Apache-2.0",
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- }
- },
- "node_modules/@eslint/plugin-kit": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz",
- "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "@eslint/core": "^0.17.0",
- "levn": "^0.4.1"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- }
- },
- "node_modules/@humanfs/core": {
- "version": "0.19.1",
- "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz",
- "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==",
- "dev": true,
- "license": "Apache-2.0",
- "engines": {
- "node": ">=18.18.0"
- }
- },
- "node_modules/@humanfs/node": {
- "version": "0.16.7",
- "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz",
- "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "@humanfs/core": "^0.19.1",
- "@humanwhocodes/retry": "^0.4.0"
- },
- "engines": {
- "node": ">=18.18.0"
- }
- },
- "node_modules/@humanwhocodes/module-importer": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
- "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
- "dev": true,
- "license": "Apache-2.0",
- "engines": {
- "node": ">=12.22"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/nzakas"
- }
- },
- "node_modules/@humanwhocodes/retry": {
- "version": "0.4.3",
- "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz",
- "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==",
- "dev": true,
- "license": "Apache-2.0",
- "engines": {
- "node": ">=18.18"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/nzakas"
- }
- },
- "node_modules/@jridgewell/gen-mapping": {
- "version": "0.3.13",
- "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
- "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
- "license": "MIT",
- "dependencies": {
- "@jridgewell/sourcemap-codec": "^1.5.0",
- "@jridgewell/trace-mapping": "^0.3.24"
- }
- },
- "node_modules/@jridgewell/remapping": {
- "version": "2.3.5",
- "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz",
- "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==",
- "license": "MIT",
- "dependencies": {
- "@jridgewell/gen-mapping": "^0.3.5",
- "@jridgewell/trace-mapping": "^0.3.24"
- }
- },
- "node_modules/@jridgewell/resolve-uri": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
- "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
- "license": "MIT",
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@jridgewell/sourcemap-codec": {
- "version": "1.5.5",
- "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
- "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
- "license": "MIT"
- },
- "node_modules/@jridgewell/trace-mapping": {
- "version": "0.3.31",
- "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
- "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
- "license": "MIT",
- "dependencies": {
- "@jridgewell/resolve-uri": "^3.1.0",
- "@jridgewell/sourcemap-codec": "^1.4.14"
- }
- },
- "node_modules/@rolldown/pluginutils": {
- "version": "1.0.0-rc.2",
- "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.2.tgz",
- "integrity": "sha512-izyXV/v+cHiRfozX62W9htOAvwMo4/bXKDrQ+vom1L1qRuexPock/7VZDAhnpHCLNejd3NJ6hiab+tO0D44Rgw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@rollup/rollup-android-arm-eabi": {
- "version": "4.57.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.57.1.tgz",
- "integrity": "sha512-A6ehUVSiSaaliTxai040ZpZ2zTevHYbvu/lDoeAteHI8QnaosIzm4qwtezfRg1jOYaUmnzLX1AOD6Z+UJjtifg==",
- "cpu": [
- "arm"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ]
- },
- "node_modules/@rollup/rollup-android-arm64": {
- "version": "4.57.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.57.1.tgz",
- "integrity": "sha512-dQaAddCY9YgkFHZcFNS/606Exo8vcLHwArFZ7vxXq4rigo2bb494/xKMMwRRQW6ug7Js6yXmBZhSBRuBvCCQ3w==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ]
- },
- "node_modules/@rollup/rollup-darwin-arm64": {
- "version": "4.57.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.57.1.tgz",
- "integrity": "sha512-crNPrwJOrRxagUYeMn/DZwqN88SDmwaJ8Cvi/TN1HnWBU7GwknckyosC2gd0IqYRsHDEnXf328o9/HC6OkPgOg==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ]
- },
- "node_modules/@rollup/rollup-darwin-x64": {
- "version": "4.57.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.57.1.tgz",
- "integrity": "sha512-Ji8g8ChVbKrhFtig5QBV7iMaJrGtpHelkB3lsaKzadFBe58gmjfGXAOfI5FV0lYMH8wiqsxKQ1C9B0YTRXVy4w==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ]
- },
- "node_modules/@rollup/rollup-freebsd-arm64": {
- "version": "4.57.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.57.1.tgz",
- "integrity": "sha512-R+/WwhsjmwodAcz65guCGFRkMb4gKWTcIeLy60JJQbXrJ97BOXHxnkPFrP+YwFlaS0m+uWJTstrUA9o+UchFug==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ]
- },
- "node_modules/@rollup/rollup-freebsd-x64": {
- "version": "4.57.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.57.1.tgz",
- "integrity": "sha512-IEQTCHeiTOnAUC3IDQdzRAGj3jOAYNr9kBguI7MQAAZK3caezRrg0GxAb6Hchg4lxdZEI5Oq3iov/w/hnFWY9Q==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ]
- },
- "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
- "version": "4.57.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.57.1.tgz",
- "integrity": "sha512-F8sWbhZ7tyuEfsmOxwc2giKDQzN3+kuBLPwwZGyVkLlKGdV1nvnNwYD0fKQ8+XS6hp9nY7B+ZeK01EBUE7aHaw==",
- "cpu": [
- "arm"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-arm-musleabihf": {
- "version": "4.57.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.57.1.tgz",
- "integrity": "sha512-rGfNUfn0GIeXtBP1wL5MnzSj98+PZe/AXaGBCRmT0ts80lU5CATYGxXukeTX39XBKsxzFpEeK+Mrp9faXOlmrw==",
- "cpu": [
- "arm"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-arm64-gnu": {
- "version": "4.57.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.57.1.tgz",
- "integrity": "sha512-MMtej3YHWeg/0klK2Qodf3yrNzz6CGjo2UntLvk2RSPlhzgLvYEB3frRvbEF2wRKh1Z2fDIg9KRPe1fawv7C+g==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-arm64-musl": {
- "version": "4.57.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.57.1.tgz",
- "integrity": "sha512-1a/qhaaOXhqXGpMFMET9VqwZakkljWHLmZOX48R0I/YLbhdxr1m4gtG1Hq7++VhVUmf+L3sTAf9op4JlhQ5u1Q==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-loong64-gnu": {
- "version": "4.57.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.57.1.tgz",
- "integrity": "sha512-QWO6RQTZ/cqYtJMtxhkRkidoNGXc7ERPbZN7dVW5SdURuLeVU7lwKMpo18XdcmpWYd0qsP1bwKPf7DNSUinhvA==",
- "cpu": [
- "loong64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-loong64-musl": {
- "version": "4.57.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.57.1.tgz",
- "integrity": "sha512-xpObYIf+8gprgWaPP32xiN5RVTi/s5FCR+XMXSKmhfoJjrpRAjCuuqQXyxUa/eJTdAE6eJ+KDKaoEqjZQxh3Gw==",
- "cpu": [
- "loong64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-ppc64-gnu": {
- "version": "4.57.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.57.1.tgz",
- "integrity": "sha512-4BrCgrpZo4hvzMDKRqEaW1zeecScDCR+2nZ86ATLhAoJ5FQ+lbHVD3ttKe74/c7tNT9c6F2viwB3ufwp01Oh2w==",
- "cpu": [
- "ppc64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-ppc64-musl": {
- "version": "4.57.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.57.1.tgz",
- "integrity": "sha512-NOlUuzesGauESAyEYFSe3QTUguL+lvrN1HtwEEsU2rOwdUDeTMJdO5dUYl/2hKf9jWydJrO9OL/XSSf65R5+Xw==",
- "cpu": [
- "ppc64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-riscv64-gnu": {
- "version": "4.57.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.57.1.tgz",
- "integrity": "sha512-ptA88htVp0AwUUqhVghwDIKlvJMD/fmL/wrQj99PRHFRAG6Z5nbWoWG4o81Nt9FT+IuqUQi+L31ZKAFeJ5Is+A==",
- "cpu": [
- "riscv64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-riscv64-musl": {
- "version": "4.57.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.57.1.tgz",
- "integrity": "sha512-S51t7aMMTNdmAMPpBg7OOsTdn4tySRQvklmL3RpDRyknk87+Sp3xaumlatU+ppQ+5raY7sSTcC2beGgvhENfuw==",
- "cpu": [
- "riscv64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-s390x-gnu": {
- "version": "4.57.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.57.1.tgz",
- "integrity": "sha512-Bl00OFnVFkL82FHbEqy3k5CUCKH6OEJL54KCyx2oqsmZnFTR8IoNqBF+mjQVcRCT5sB6yOvK8A37LNm/kPJiZg==",
- "cpu": [
- "s390x"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-x64-gnu": {
- "version": "4.57.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.57.1.tgz",
- "integrity": "sha512-ABca4ceT4N+Tv/GtotnWAeXZUZuM/9AQyCyKYyKnpk4yoA7QIAuBt6Hkgpw8kActYlew2mvckXkvx0FfoInnLg==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-x64-musl": {
- "version": "4.57.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.57.1.tgz",
- "integrity": "sha512-HFps0JeGtuOR2convgRRkHCekD7j+gdAuXM+/i6kGzQtFhlCtQkpwtNzkNj6QhCDp7DRJ7+qC/1Vg2jt5iSOFw==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-openbsd-x64": {
- "version": "4.57.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.57.1.tgz",
- "integrity": "sha512-H+hXEv9gdVQuDTgnqD+SQffoWoc0Of59AStSzTEj/feWTBAnSfSD3+Dql1ZruJQxmykT/JVY0dE8Ka7z0DH1hw==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "openbsd"
- ]
- },
- "node_modules/@rollup/rollup-openharmony-arm64": {
- "version": "4.57.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.57.1.tgz",
- "integrity": "sha512-4wYoDpNg6o/oPximyc/NG+mYUejZrCU2q+2w6YZqrAs2UcNUChIZXjtafAiiZSUc7On8v5NyNj34Kzj/Ltk6dQ==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "openharmony"
- ]
- },
- "node_modules/@rollup/rollup-win32-arm64-msvc": {
- "version": "4.57.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.57.1.tgz",
- "integrity": "sha512-O54mtsV/6LW3P8qdTcamQmuC990HDfR71lo44oZMZlXU4tzLrbvTii87Ni9opq60ds0YzuAlEr/GNwuNluZyMQ==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ]
- },
- "node_modules/@rollup/rollup-win32-ia32-msvc": {
- "version": "4.57.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.57.1.tgz",
- "integrity": "sha512-P3dLS+IerxCT/7D2q2FYcRdWRl22dNbrbBEtxdWhXrfIMPP9lQhb5h4Du04mdl5Woq05jVCDPCMF7Ub0NAjIew==",
- "cpu": [
- "ia32"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ]
- },
- "node_modules/@rollup/rollup-win32-x64-gnu": {
- "version": "4.57.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.57.1.tgz",
- "integrity": "sha512-VMBH2eOOaKGtIJYleXsi2B8CPVADrh+TyNxJ4mWPnKfLB/DBUmzW+5m1xUrcwWoMfSLagIRpjUFeW5CO5hyciQ==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ]
- },
- "node_modules/@rollup/rollup-win32-x64-msvc": {
- "version": "4.57.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.57.1.tgz",
- "integrity": "sha512-mxRFDdHIWRxg3UfIIAwCm6NzvxG0jDX/wBN6KsQFTvKFqqg9vTrWUE68qEjHt19A5wwx5X5aUi2zuZT7YR0jrA==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ]
- },
- "node_modules/@tailwindcss/node": {
- "version": "4.1.18",
- "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.18.tgz",
- "integrity": "sha512-DoR7U1P7iYhw16qJ49fgXUlry1t4CpXeErJHnQ44JgTSKMaZUdf17cfn5mHchfJ4KRBZRFA/Coo+MUF5+gOaCQ==",
- "license": "MIT",
- "dependencies": {
- "@jridgewell/remapping": "^2.3.4",
- "enhanced-resolve": "^5.18.3",
- "jiti": "^2.6.1",
- "lightningcss": "1.30.2",
- "magic-string": "^0.30.21",
- "source-map-js": "^1.2.1",
- "tailwindcss": "4.1.18"
- }
- },
- "node_modules/@tailwindcss/oxide": {
- "version": "4.1.18",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.18.tgz",
- "integrity": "sha512-EgCR5tTS5bUSKQgzeMClT6iCY3ToqE1y+ZB0AKldj809QXk1Y+3jB0upOYZrn9aGIzPtUsP7sX4QQ4XtjBB95A==",
- "license": "MIT",
- "engines": {
- "node": ">= 10"
- },
- "optionalDependencies": {
- "@tailwindcss/oxide-android-arm64": "4.1.18",
- "@tailwindcss/oxide-darwin-arm64": "4.1.18",
- "@tailwindcss/oxide-darwin-x64": "4.1.18",
- "@tailwindcss/oxide-freebsd-x64": "4.1.18",
- "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.18",
- "@tailwindcss/oxide-linux-arm64-gnu": "4.1.18",
- "@tailwindcss/oxide-linux-arm64-musl": "4.1.18",
- "@tailwindcss/oxide-linux-x64-gnu": "4.1.18",
- "@tailwindcss/oxide-linux-x64-musl": "4.1.18",
- "@tailwindcss/oxide-wasm32-wasi": "4.1.18",
- "@tailwindcss/oxide-win32-arm64-msvc": "4.1.18",
- "@tailwindcss/oxide-win32-x64-msvc": "4.1.18"
- }
- },
- "node_modules/@tailwindcss/oxide-android-arm64": {
- "version": "4.1.18",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.18.tgz",
- "integrity": "sha512-dJHz7+Ugr9U/diKJA0W6N/6/cjI+ZTAoxPf9Iz9BFRF2GzEX8IvXxFIi/dZBloVJX/MZGvRuFA9rqwdiIEZQ0Q==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/oxide-darwin-arm64": {
- "version": "4.1.18",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.18.tgz",
- "integrity": "sha512-Gc2q4Qhs660bhjyBSKgq6BYvwDz4G+BuyJ5H1xfhmDR3D8HnHCmT/BSkvSL0vQLy/nkMLY20PQ2OoYMO15Jd0A==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/oxide-darwin-x64": {
- "version": "4.1.18",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.18.tgz",
- "integrity": "sha512-FL5oxr2xQsFrc3X9o1fjHKBYBMD1QZNyc1Xzw/h5Qu4XnEBi3dZn96HcHm41c/euGV+GRiXFfh2hUCyKi/e+yw==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/oxide-freebsd-x64": {
- "version": "4.1.18",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.18.tgz",
- "integrity": "sha512-Fj+RHgu5bDodmV1dM9yAxlfJwkkWvLiRjbhuO2LEtwtlYlBgiAT4x/j5wQr1tC3SANAgD+0YcmWVrj8R9trVMA==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": {
- "version": "4.1.18",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.18.tgz",
- "integrity": "sha512-Fp+Wzk/Ws4dZn+LV2Nqx3IilnhH51YZoRaYHQsVq3RQvEl+71VGKFpkfHrLM/Li+kt5c0DJe/bHXK1eHgDmdiA==",
- "cpu": [
- "arm"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/oxide-linux-arm64-gnu": {
- "version": "4.1.18",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.18.tgz",
- "integrity": "sha512-S0n3jboLysNbh55Vrt7pk9wgpyTTPD0fdQeh7wQfMqLPM/Hrxi+dVsLsPrycQjGKEQk85Kgbx+6+QnYNiHalnw==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/oxide-linux-arm64-musl": {
- "version": "4.1.18",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.18.tgz",
- "integrity": "sha512-1px92582HkPQlaaCkdRcio71p8bc8i/ap5807tPRDK/uw953cauQBT8c5tVGkOwrHMfc2Yh6UuxaH4vtTjGvHg==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/oxide-linux-x64-gnu": {
- "version": "4.1.18",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.18.tgz",
- "integrity": "sha512-v3gyT0ivkfBLoZGF9LyHmts0Isc8jHZyVcbzio6Wpzifg/+5ZJpDiRiUhDLkcr7f/r38SWNe7ucxmGW3j3Kb/g==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/oxide-linux-x64-musl": {
- "version": "4.1.18",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.18.tgz",
- "integrity": "sha512-bhJ2y2OQNlcRwwgOAGMY0xTFStt4/wyU6pvI6LSuZpRgKQwxTec0/3Scu91O8ir7qCR3AuepQKLU/kX99FouqQ==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/oxide-wasm32-wasi": {
- "version": "4.1.18",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.18.tgz",
- "integrity": "sha512-LffYTvPjODiP6PT16oNeUQJzNVyJl1cjIebq/rWWBF+3eDst5JGEFSc5cWxyRCJ0Mxl+KyIkqRxk1XPEs9x8TA==",
- "bundleDependencies": [
- "@napi-rs/wasm-runtime",
- "@emnapi/core",
- "@emnapi/runtime",
- "@tybys/wasm-util",
- "@emnapi/wasi-threads",
- "tslib"
- ],
- "cpu": [
- "wasm32"
- ],
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "@emnapi/core": "^1.7.1",
- "@emnapi/runtime": "^1.7.1",
- "@emnapi/wasi-threads": "^1.1.0",
- "@napi-rs/wasm-runtime": "^1.1.0",
- "@tybys/wasm-util": "^0.10.1",
- "tslib": "^2.4.0"
- },
- "engines": {
- "node": ">=14.0.0"
- }
- },
- "node_modules/@tailwindcss/oxide-win32-arm64-msvc": {
- "version": "4.1.18",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.18.tgz",
- "integrity": "sha512-HjSA7mr9HmC8fu6bdsZvZ+dhjyGCLdotjVOgLA2vEqxEBZaQo9YTX4kwgEvPCpRh8o4uWc4J/wEoFzhEmjvPbA==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/oxide-win32-x64-msvc": {
- "version": "4.1.18",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.18.tgz",
- "integrity": "sha512-bJWbyYpUlqamC8dpR7pfjA0I7vdF6t5VpUGMWRkXVE3AXgIZjYUYAK7II1GNaxR8J1SSrSrppRar8G++JekE3Q==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/vite": {
- "version": "4.1.18",
- "resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.1.18.tgz",
- "integrity": "sha512-jVA+/UpKL1vRLg6Hkao5jldawNmRo7mQYrZtNHMIVpLfLhDml5nMRUo/8MwoX2vNXvnaXNNMedrMfMugAVX1nA==",
- "license": "MIT",
- "dependencies": {
- "@tailwindcss/node": "4.1.18",
- "@tailwindcss/oxide": "4.1.18",
- "tailwindcss": "4.1.18"
- },
- "peerDependencies": {
- "vite": "^5.2.0 || ^6 || ^7"
- }
- },
- "node_modules/@tanstack/query-core": {
- "version": "5.90.20",
- "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.90.20.tgz",
- "integrity": "sha512-OMD2HLpNouXEfZJWcKeVKUgQ5n+n3A2JFmBaScpNDUqSrQSjiveC7dKMe53uJUg1nDG16ttFPz2xfilz6i2uVg==",
- "license": "MIT",
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/tannerlinsley"
- }
- },
- "node_modules/@tanstack/react-query": {
- "version": "5.90.20",
- "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.90.20.tgz",
- "integrity": "sha512-vXBxa+qeyveVO7OA0jX1z+DeyCA4JKnThKv411jd5SORpBKgkcVnYKCiBgECvADvniBX7tobwBmg01qq9JmMJw==",
- "license": "MIT",
- "dependencies": {
- "@tanstack/query-core": "5.90.20"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/tannerlinsley"
- },
- "peerDependencies": {
- "react": "^18 || ^19"
- }
- },
- "node_modules/@types/babel__core": {
- "version": "7.20.5",
- "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
- "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/parser": "^7.20.7",
- "@babel/types": "^7.20.7",
- "@types/babel__generator": "*",
- "@types/babel__template": "*",
- "@types/babel__traverse": "*"
- }
- },
- "node_modules/@types/babel__generator": {
- "version": "7.27.0",
- "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz",
- "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/types": "^7.0.0"
- }
- },
- "node_modules/@types/babel__template": {
- "version": "7.4.4",
- "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz",
- "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/parser": "^7.1.0",
- "@babel/types": "^7.0.0"
- }
- },
- "node_modules/@types/babel__traverse": {
- "version": "7.28.0",
- "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz",
- "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/types": "^7.28.2"
- }
- },
- "node_modules/@types/estree": {
- "version": "1.0.8",
- "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
- "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
- "license": "MIT"
- },
- "node_modules/@types/json-schema": {
- "version": "7.0.15",
- "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
- "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@types/node": {
- "version": "24.10.10",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.10.tgz",
- "integrity": "sha512-+0/4J266CBGPUq/ELg7QUHhN25WYjE0wYTPSQJn1xeu8DOlIOPxXxrNGiLmfAWl7HMMgWFWXpt9IDjMWrF5Iow==",
- "devOptional": true,
- "license": "MIT",
- "dependencies": {
- "undici-types": "~7.16.0"
- }
- },
- "node_modules/@types/react": {
- "version": "19.2.11",
- "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.11.tgz",
- "integrity": "sha512-tORuanb01iEzWvMGVGv2ZDhYZVeRMrw453DCSAIn/5yvcSVnMoUMTyf33nQJLahYEnv9xqrTNbgz4qY5EfSh0g==",
- "devOptional": true,
- "license": "MIT",
- "dependencies": {
- "csstype": "^3.2.2"
- }
- },
- "node_modules/@types/react-dom": {
- "version": "19.2.3",
- "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz",
- "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==",
- "dev": true,
- "license": "MIT",
- "peerDependencies": {
- "@types/react": "^19.2.0"
- }
- },
- "node_modules/@typescript-eslint/eslint-plugin": {
- "version": "8.54.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.54.0.tgz",
- "integrity": "sha512-hAAP5io/7csFStuOmR782YmTthKBJ9ND3WVL60hcOjvtGFb+HJxH4O5huAcmcZ9v9G8P+JETiZ/G1B8MALnWZQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@eslint-community/regexpp": "^4.12.2",
- "@typescript-eslint/scope-manager": "8.54.0",
- "@typescript-eslint/type-utils": "8.54.0",
- "@typescript-eslint/utils": "8.54.0",
- "@typescript-eslint/visitor-keys": "8.54.0",
- "ignore": "^7.0.5",
- "natural-compare": "^1.4.0",
- "ts-api-utils": "^2.4.0"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- },
- "peerDependencies": {
- "@typescript-eslint/parser": "^8.54.0",
- "eslint": "^8.57.0 || ^9.0.0",
- "typescript": ">=4.8.4 <6.0.0"
- }
- },
- "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": {
- "version": "7.0.5",
- "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz",
- "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 4"
- }
- },
- "node_modules/@typescript-eslint/parser": {
- "version": "8.54.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.54.0.tgz",
- "integrity": "sha512-BtE0k6cjwjLZoZixN0t5AKP0kSzlGu7FctRXYuPAm//aaiZhmfq1JwdYpYr1brzEspYyFeF+8XF5j2VK6oalrA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@typescript-eslint/scope-manager": "8.54.0",
- "@typescript-eslint/types": "8.54.0",
- "@typescript-eslint/typescript-estree": "8.54.0",
- "@typescript-eslint/visitor-keys": "8.54.0",
- "debug": "^4.4.3"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- },
- "peerDependencies": {
- "eslint": "^8.57.0 || ^9.0.0",
- "typescript": ">=4.8.4 <6.0.0"
- }
- },
- "node_modules/@typescript-eslint/project-service": {
- "version": "8.54.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.54.0.tgz",
- "integrity": "sha512-YPf+rvJ1s7MyiWM4uTRhE4DvBXrEV+d8oC3P9Y2eT7S+HBS0clybdMIPnhiATi9vZOYDc7OQ1L/i6ga6NFYK/g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@typescript-eslint/tsconfig-utils": "^8.54.0",
- "@typescript-eslint/types": "^8.54.0",
- "debug": "^4.4.3"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- },
- "peerDependencies": {
- "typescript": ">=4.8.4 <6.0.0"
- }
- },
- "node_modules/@typescript-eslint/scope-manager": {
- "version": "8.54.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.54.0.tgz",
- "integrity": "sha512-27rYVQku26j/PbHYcVfRPonmOlVI6gihHtXFbTdB5sb6qA0wdAQAbyXFVarQ5t4HRojIz64IV90YtsjQSSGlQg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@typescript-eslint/types": "8.54.0",
- "@typescript-eslint/visitor-keys": "8.54.0"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- }
- },
- "node_modules/@typescript-eslint/tsconfig-utils": {
- "version": "8.54.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.54.0.tgz",
- "integrity": "sha512-dRgOyT2hPk/JwxNMZDsIXDgyl9axdJI3ogZ2XWhBPsnZUv+hPesa5iuhdYt2gzwA9t8RE5ytOJ6xB0moV0Ujvw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- },
- "peerDependencies": {
- "typescript": ">=4.8.4 <6.0.0"
- }
- },
- "node_modules/@typescript-eslint/type-utils": {
- "version": "8.54.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.54.0.tgz",
- "integrity": "sha512-hiLguxJWHjjwL6xMBwD903ciAwd7DmK30Y9Axs/etOkftC3ZNN9K44IuRD/EB08amu+Zw6W37x9RecLkOo3pMA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@typescript-eslint/types": "8.54.0",
- "@typescript-eslint/typescript-estree": "8.54.0",
- "@typescript-eslint/utils": "8.54.0",
- "debug": "^4.4.3",
- "ts-api-utils": "^2.4.0"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- },
- "peerDependencies": {
- "eslint": "^8.57.0 || ^9.0.0",
- "typescript": ">=4.8.4 <6.0.0"
- }
- },
- "node_modules/@typescript-eslint/types": {
- "version": "8.54.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.54.0.tgz",
- "integrity": "sha512-PDUI9R1BVjqu7AUDsRBbKMtwmjWcn4J3le+5LpcFgWULN3LvHC5rkc9gCVxbrsrGmO1jfPybN5s6h4Jy+OnkAA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- }
- },
- "node_modules/@typescript-eslint/typescript-estree": {
- "version": "8.54.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.54.0.tgz",
- "integrity": "sha512-BUwcskRaPvTk6fzVWgDPdUndLjB87KYDrN5EYGetnktoeAvPtO4ONHlAZDnj5VFnUANg0Sjm7j4usBlnoVMHwA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@typescript-eslint/project-service": "8.54.0",
- "@typescript-eslint/tsconfig-utils": "8.54.0",
- "@typescript-eslint/types": "8.54.0",
- "@typescript-eslint/visitor-keys": "8.54.0",
- "debug": "^4.4.3",
- "minimatch": "^9.0.5",
- "semver": "^7.7.3",
- "tinyglobby": "^0.2.15",
- "ts-api-utils": "^2.4.0"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- },
- "peerDependencies": {
- "typescript": ">=4.8.4 <6.0.0"
- }
- },
- "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
- "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "balanced-match": "^1.0.0"
- }
- },
- "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": {
- "version": "9.0.5",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
- "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "brace-expansion": "^2.0.1"
- },
- "engines": {
- "node": ">=16 || 14 >=14.17"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": {
- "version": "7.7.3",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
- "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
- "dev": true,
- "license": "ISC",
- "bin": {
- "semver": "bin/semver.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/@typescript-eslint/utils": {
- "version": "8.54.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.54.0.tgz",
- "integrity": "sha512-9Cnda8GS57AQakvRyG0PTejJNlA2xhvyNtEVIMlDWOOeEyBkYWhGPnfrIAnqxLMTSTo6q8g12XVjjev5l1NvMA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@eslint-community/eslint-utils": "^4.9.1",
- "@typescript-eslint/scope-manager": "8.54.0",
- "@typescript-eslint/types": "8.54.0",
- "@typescript-eslint/typescript-estree": "8.54.0"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- },
- "peerDependencies": {
- "eslint": "^8.57.0 || ^9.0.0",
- "typescript": ">=4.8.4 <6.0.0"
- }
- },
- "node_modules/@typescript-eslint/visitor-keys": {
- "version": "8.54.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.54.0.tgz",
- "integrity": "sha512-VFlhGSl4opC0bprJiItPQ1RfUhGDIBokcPwaFH4yiBCaNPeld/9VeXbiPO1cLyorQi1G1vL+ecBk1x8o1axORA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@typescript-eslint/types": "8.54.0",
- "eslint-visitor-keys": "^4.2.1"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- }
- },
- "node_modules/@vitejs/plugin-react": {
- "version": "5.1.3",
- "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-5.1.3.tgz",
- "integrity": "sha512-NVUnA6gQCl8jfoYqKqQU5Clv0aPw14KkZYCsX6T9Lfu9slI0LOU10OTwFHS/WmptsMMpshNd/1tuWsHQ2Uk+cg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/core": "^7.29.0",
- "@babel/plugin-transform-react-jsx-self": "^7.27.1",
- "@babel/plugin-transform-react-jsx-source": "^7.27.1",
- "@rolldown/pluginutils": "1.0.0-rc.2",
- "@types/babel__core": "^7.20.5",
- "react-refresh": "^0.18.0"
- },
- "engines": {
- "node": "^20.19.0 || >=22.12.0"
- },
- "peerDependencies": {
- "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0"
- }
- },
- "node_modules/acorn": {
- "version": "8.15.0",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
- "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
- "dev": true,
- "license": "MIT",
- "bin": {
- "acorn": "bin/acorn"
- },
- "engines": {
- "node": ">=0.4.0"
- }
- },
- "node_modules/acorn-jsx": {
- "version": "5.3.2",
- "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
- "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
- "dev": true,
- "license": "MIT",
- "peerDependencies": {
- "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
- }
- },
- "node_modules/ajv": {
- "version": "6.12.6",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
- "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "fast-deep-equal": "^3.1.1",
- "fast-json-stable-stringify": "^2.0.0",
- "json-schema-traverse": "^0.4.1",
- "uri-js": "^4.2.2"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/epoberezkin"
- }
- },
- "node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/argparse": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
- "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
- "dev": true,
- "license": "Python-2.0"
- },
- "node_modules/balanced-match": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
- "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/baseline-browser-mapping": {
- "version": "2.9.19",
- "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.19.tgz",
- "integrity": "sha512-ipDqC8FrAl/76p2SSWKSI+H9tFwm7vYqXQrItCuiVPt26Km0jS+NzSsBWAaBusvSbQcfJG+JitdMm+wZAgTYqg==",
- "dev": true,
- "license": "Apache-2.0",
- "bin": {
- "baseline-browser-mapping": "dist/cli.js"
- }
- },
- "node_modules/brace-expansion": {
- "version": "1.1.12",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
- "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "balanced-match": "^1.0.0",
- "concat-map": "0.0.1"
- }
- },
- "node_modules/browserslist": {
- "version": "4.28.1",
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz",
- "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==",
- "dev": true,
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/browserslist"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/browserslist"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "baseline-browser-mapping": "^2.9.0",
- "caniuse-lite": "^1.0.30001759",
- "electron-to-chromium": "^1.5.263",
- "node-releases": "^2.0.27",
- "update-browserslist-db": "^1.2.0"
- },
- "bin": {
- "browserslist": "cli.js"
- },
- "engines": {
- "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
- }
- },
- "node_modules/callsites": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
- "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/caniuse-lite": {
- "version": "1.0.30001767",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001767.tgz",
- "integrity": "sha512-34+zUAMhSH+r+9eKmYG+k2Rpt8XttfE4yXAjoZvkAPs15xcYQhyBYdalJ65BzivAvGRMViEjy6oKr/S91loekQ==",
- "dev": true,
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/browserslist"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "CC-BY-4.0"
- },
- "node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/concat-map": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
- "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/convert-source-map": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
- "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/cookie": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz",
- "integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==",
- "license": "MIT",
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/express"
- }
- },
- "node_modules/cross-spawn": {
- "version": "7.0.6",
- "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
- "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "path-key": "^3.1.0",
- "shebang-command": "^2.0.0",
- "which": "^2.0.1"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/csstype": {
- "version": "3.2.3",
- "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
- "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
- "devOptional": true,
- "license": "MIT"
- },
- "node_modules/debug": {
- "version": "4.4.3",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
- "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ms": "^2.1.3"
- },
- "engines": {
- "node": ">=6.0"
- },
- "peerDependenciesMeta": {
- "supports-color": {
- "optional": true
- }
- }
- },
- "node_modules/deep-is": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
- "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/detect-libc": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
- "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
- "license": "Apache-2.0",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/electron-to-chromium": {
- "version": "1.5.286",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.286.tgz",
- "integrity": "sha512-9tfDXhJ4RKFNerfjdCcZfufu49vg620741MNs26a9+bhLThdB+plgMeou98CAaHu/WATj2iHOOHTp1hWtABj2A==",
- "dev": true,
- "license": "ISC"
- },
- "node_modules/enhanced-resolve": {
- "version": "5.19.0",
- "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.19.0.tgz",
- "integrity": "sha512-phv3E1Xl4tQOShqSte26C7Fl84EwUdZsyOuSSk9qtAGyyQs2s3jJzComh+Abf4g187lUUAvH+H26omrqia2aGg==",
- "license": "MIT",
- "dependencies": {
- "graceful-fs": "^4.2.4",
- "tapable": "^2.3.0"
- },
- "engines": {
- "node": ">=10.13.0"
- }
- },
- "node_modules/esbuild": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.2.tgz",
- "integrity": "sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==",
- "hasInstallScript": true,
- "license": "MIT",
- "bin": {
- "esbuild": "bin/esbuild"
- },
- "engines": {
- "node": ">=18"
- },
- "optionalDependencies": {
- "@esbuild/aix-ppc64": "0.27.2",
- "@esbuild/android-arm": "0.27.2",
- "@esbuild/android-arm64": "0.27.2",
- "@esbuild/android-x64": "0.27.2",
- "@esbuild/darwin-arm64": "0.27.2",
- "@esbuild/darwin-x64": "0.27.2",
- "@esbuild/freebsd-arm64": "0.27.2",
- "@esbuild/freebsd-x64": "0.27.2",
- "@esbuild/linux-arm": "0.27.2",
- "@esbuild/linux-arm64": "0.27.2",
- "@esbuild/linux-ia32": "0.27.2",
- "@esbuild/linux-loong64": "0.27.2",
- "@esbuild/linux-mips64el": "0.27.2",
- "@esbuild/linux-ppc64": "0.27.2",
- "@esbuild/linux-riscv64": "0.27.2",
- "@esbuild/linux-s390x": "0.27.2",
- "@esbuild/linux-x64": "0.27.2",
- "@esbuild/netbsd-arm64": "0.27.2",
- "@esbuild/netbsd-x64": "0.27.2",
- "@esbuild/openbsd-arm64": "0.27.2",
- "@esbuild/openbsd-x64": "0.27.2",
- "@esbuild/openharmony-arm64": "0.27.2",
- "@esbuild/sunos-x64": "0.27.2",
- "@esbuild/win32-arm64": "0.27.2",
- "@esbuild/win32-ia32": "0.27.2",
- "@esbuild/win32-x64": "0.27.2"
- }
- },
- "node_modules/escalade": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
- "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/escape-string-regexp": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
- "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/eslint": {
- "version": "9.39.2",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.2.tgz",
- "integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@eslint-community/eslint-utils": "^4.8.0",
- "@eslint-community/regexpp": "^4.12.1",
- "@eslint/config-array": "^0.21.1",
- "@eslint/config-helpers": "^0.4.2",
- "@eslint/core": "^0.17.0",
- "@eslint/eslintrc": "^3.3.1",
- "@eslint/js": "9.39.2",
- "@eslint/plugin-kit": "^0.4.1",
- "@humanfs/node": "^0.16.6",
- "@humanwhocodes/module-importer": "^1.0.1",
- "@humanwhocodes/retry": "^0.4.2",
- "@types/estree": "^1.0.6",
- "ajv": "^6.12.4",
- "chalk": "^4.0.0",
- "cross-spawn": "^7.0.6",
- "debug": "^4.3.2",
- "escape-string-regexp": "^4.0.0",
- "eslint-scope": "^8.4.0",
- "eslint-visitor-keys": "^4.2.1",
- "espree": "^10.4.0",
- "esquery": "^1.5.0",
- "esutils": "^2.0.2",
- "fast-deep-equal": "^3.1.3",
- "file-entry-cache": "^8.0.0",
- "find-up": "^5.0.0",
- "glob-parent": "^6.0.2",
- "ignore": "^5.2.0",
- "imurmurhash": "^0.1.4",
- "is-glob": "^4.0.0",
- "json-stable-stringify-without-jsonify": "^1.0.1",
- "lodash.merge": "^4.6.2",
- "minimatch": "^3.1.2",
- "natural-compare": "^1.4.0",
- "optionator": "^0.9.3"
- },
- "bin": {
- "eslint": "bin/eslint.js"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "url": "https://eslint.org/donate"
- },
- "peerDependencies": {
- "jiti": "*"
- },
- "peerDependenciesMeta": {
- "jiti": {
- "optional": true
- }
- }
- },
- "node_modules/eslint-plugin-react-hooks": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-7.0.1.tgz",
- "integrity": "sha512-O0d0m04evaNzEPoSW+59Mezf8Qt0InfgGIBJnpC0h3NH/WjUAR7BIKUfysC6todmtiZ/A0oUVS8Gce0WhBrHsA==",
- "dev": true,
- "license": "MIT",
- "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"
- },
- "engines": {
- "node": ">=18"
- },
- "peerDependencies": {
- "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0"
- }
- },
- "node_modules/eslint-plugin-react-refresh": {
- "version": "0.4.26",
- "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.26.tgz",
- "integrity": "sha512-1RETEylht2O6FM/MvgnyvT+8K21wLqDNg4qD51Zj3guhjt433XbnnkVttHMyaVyAFD03QSV4LPS5iE3VQmO7XQ==",
- "dev": true,
- "license": "MIT",
- "peerDependencies": {
- "eslint": ">=8.40"
- }
- },
- "node_modules/eslint-scope": {
- "version": "8.4.0",
- "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz",
- "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==",
- "dev": true,
- "license": "BSD-2-Clause",
- "dependencies": {
- "esrecurse": "^4.3.0",
- "estraverse": "^5.2.0"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "url": "https://opencollective.com/eslint"
- }
- },
- "node_modules/eslint-visitor-keys": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
- "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==",
- "dev": true,
- "license": "Apache-2.0",
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "url": "https://opencollective.com/eslint"
- }
- },
- "node_modules/espree": {
- "version": "10.4.0",
- "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz",
- "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==",
- "dev": true,
- "license": "BSD-2-Clause",
- "dependencies": {
- "acorn": "^8.15.0",
- "acorn-jsx": "^5.3.2",
- "eslint-visitor-keys": "^4.2.1"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "url": "https://opencollective.com/eslint"
- }
- },
- "node_modules/esquery": {
- "version": "1.7.0",
- "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz",
- "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==",
- "dev": true,
- "license": "BSD-3-Clause",
- "dependencies": {
- "estraverse": "^5.1.0"
- },
- "engines": {
- "node": ">=0.10"
- }
- },
- "node_modules/esrecurse": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
- "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
- "dev": true,
- "license": "BSD-2-Clause",
- "dependencies": {
- "estraverse": "^5.2.0"
- },
- "engines": {
- "node": ">=4.0"
- }
- },
- "node_modules/estraverse": {
- "version": "5.3.0",
- "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
- "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
- "dev": true,
- "license": "BSD-2-Clause",
- "engines": {
- "node": ">=4.0"
- }
- },
- "node_modules/esutils": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
- "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
- "dev": true,
- "license": "BSD-2-Clause",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/fast-deep-equal": {
- "version": "3.1.3",
- "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
- "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/fast-json-stable-stringify": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
- "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/fast-levenshtein": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
- "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/fdir": {
- "version": "6.5.0",
- "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
- "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
- "license": "MIT",
- "engines": {
- "node": ">=12.0.0"
- },
- "peerDependencies": {
- "picomatch": "^3 || ^4"
- },
- "peerDependenciesMeta": {
- "picomatch": {
- "optional": true
- }
- }
- },
- "node_modules/file-entry-cache": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz",
- "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "flat-cache": "^4.0.0"
- },
- "engines": {
- "node": ">=16.0.0"
- }
- },
- "node_modules/find-up": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
- "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "locate-path": "^6.0.0",
- "path-exists": "^4.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/flat-cache": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz",
- "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "flatted": "^3.2.9",
- "keyv": "^4.5.4"
- },
- "engines": {
- "node": ">=16"
- }
- },
- "node_modules/flatted": {
- "version": "3.3.3",
- "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz",
- "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==",
- "dev": true,
- "license": "ISC"
- },
- "node_modules/fsevents": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
- "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
- "hasInstallScript": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
- }
- },
- "node_modules/gensync": {
- "version": "1.0.0-beta.2",
- "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
- "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/glob-parent": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
- "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "is-glob": "^4.0.3"
- },
- "engines": {
- "node": ">=10.13.0"
- }
- },
- "node_modules/globals": {
- "version": "16.5.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-16.5.0.tgz",
- "integrity": "sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/graceful-fs": {
- "version": "4.2.11",
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
- "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
- "license": "ISC"
- },
- "node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/hermes-estree": {
- "version": "0.25.1",
- "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.25.1.tgz",
- "integrity": "sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/hermes-parser": {
- "version": "0.25.1",
- "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.25.1.tgz",
- "integrity": "sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "hermes-estree": "0.25.1"
- }
- },
- "node_modules/ignore": {
- "version": "5.3.2",
- "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
- "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 4"
- }
- },
- "node_modules/import-fresh": {
- "version": "3.3.1",
- "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
- "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "parent-module": "^1.0.0",
- "resolve-from": "^4.0.0"
- },
- "engines": {
- "node": ">=6"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/imurmurhash": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
- "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.8.19"
- }
- },
- "node_modules/is-extglob": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
- "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/is-glob": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
- "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "is-extglob": "^2.1.1"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/isexe": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
- "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
- "dev": true,
- "license": "ISC"
- },
- "node_modules/jiti": {
- "version": "2.6.1",
- "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz",
- "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==",
- "license": "MIT",
- "bin": {
- "jiti": "lib/jiti-cli.mjs"
- }
- },
- "node_modules/js-tokens": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
- "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/js-yaml": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz",
- "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "argparse": "^2.0.1"
- },
- "bin": {
- "js-yaml": "bin/js-yaml.js"
- }
- },
- "node_modules/jsesc": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
- "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
- "dev": true,
- "license": "MIT",
- "bin": {
- "jsesc": "bin/jsesc"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/json-buffer": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
- "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/json-schema-traverse": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
- "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/json-stable-stringify-without-jsonify": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
- "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/json5": {
- "version": "2.2.3",
- "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
- "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
- "dev": true,
- "license": "MIT",
- "bin": {
- "json5": "lib/cli.js"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/keyv": {
- "version": "4.5.4",
- "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
- "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "json-buffer": "3.0.1"
- }
- },
- "node_modules/levn": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
- "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "prelude-ls": "^1.2.1",
- "type-check": "~0.4.0"
- },
- "engines": {
- "node": ">= 0.8.0"
- }
- },
- "node_modules/lightningcss": {
- "version": "1.30.2",
- "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.2.tgz",
- "integrity": "sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ==",
- "license": "MPL-2.0",
- "dependencies": {
- "detect-libc": "^2.0.3"
- },
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- },
- "optionalDependencies": {
- "lightningcss-android-arm64": "1.30.2",
- "lightningcss-darwin-arm64": "1.30.2",
- "lightningcss-darwin-x64": "1.30.2",
- "lightningcss-freebsd-x64": "1.30.2",
- "lightningcss-linux-arm-gnueabihf": "1.30.2",
- "lightningcss-linux-arm64-gnu": "1.30.2",
- "lightningcss-linux-arm64-musl": "1.30.2",
- "lightningcss-linux-x64-gnu": "1.30.2",
- "lightningcss-linux-x64-musl": "1.30.2",
- "lightningcss-win32-arm64-msvc": "1.30.2",
- "lightningcss-win32-x64-msvc": "1.30.2"
- }
- },
- "node_modules/lightningcss-android-arm64": {
- "version": "1.30.2",
- "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.30.2.tgz",
- "integrity": "sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A==",
- "cpu": [
- "arm64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-darwin-arm64": {
- "version": "1.30.2",
- "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.2.tgz",
- "integrity": "sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA==",
- "cpu": [
- "arm64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-darwin-x64": {
- "version": "1.30.2",
- "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.2.tgz",
- "integrity": "sha512-oBZgKchomuDYxr7ilwLcyms6BCyLn0z8J0+ZZmfpjwg9fRVZIR5/GMXd7r9RH94iDhld3UmSjBM6nXWM2TfZTQ==",
- "cpu": [
- "x64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-freebsd-x64": {
- "version": "1.30.2",
- "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.2.tgz",
- "integrity": "sha512-c2bH6xTrf4BDpK8MoGG4Bd6zAMZDAXS569UxCAGcA7IKbHNMlhGQ89eRmvpIUGfKWNVdbhSbkQaWhEoMGmGslA==",
- "cpu": [
- "x64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "freebsd"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-linux-arm-gnueabihf": {
- "version": "1.30.2",
- "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.2.tgz",
- "integrity": "sha512-eVdpxh4wYcm0PofJIZVuYuLiqBIakQ9uFZmipf6LF/HRj5Bgm0eb3qL/mr1smyXIS1twwOxNWndd8z0E374hiA==",
- "cpu": [
- "arm"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-linux-arm64-gnu": {
- "version": "1.30.2",
- "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.2.tgz",
- "integrity": "sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A==",
- "cpu": [
- "arm64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-linux-arm64-musl": {
- "version": "1.30.2",
- "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.2.tgz",
- "integrity": "sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==",
- "cpu": [
- "arm64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-linux-x64-gnu": {
- "version": "1.30.2",
- "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.2.tgz",
- "integrity": "sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==",
- "cpu": [
- "x64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-linux-x64-musl": {
- "version": "1.30.2",
- "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.2.tgz",
- "integrity": "sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==",
- "cpu": [
- "x64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-win32-arm64-msvc": {
- "version": "1.30.2",
- "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.2.tgz",
- "integrity": "sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ==",
- "cpu": [
- "arm64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-win32-x64-msvc": {
- "version": "1.30.2",
- "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.2.tgz",
- "integrity": "sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw==",
- "cpu": [
- "x64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/locate-path": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
- "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "p-locate": "^5.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/lodash.merge": {
- "version": "4.6.2",
- "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
- "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/lru-cache": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
- "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "yallist": "^3.0.2"
- }
- },
- "node_modules/magic-string": {
- "version": "0.30.21",
- "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz",
- "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==",
- "license": "MIT",
- "dependencies": {
- "@jridgewell/sourcemap-codec": "^1.5.5"
- }
- },
- "node_modules/minimatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "brace-expansion": "^1.1.7"
- },
- "engines": {
- "node": "*"
- }
- },
- "node_modules/ms": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
- "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/nanoid": {
- "version": "3.3.11",
- "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
- "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "MIT",
- "bin": {
- "nanoid": "bin/nanoid.cjs"
- },
- "engines": {
- "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
- }
- },
- "node_modules/natural-compare": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
- "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/node-releases": {
- "version": "2.0.27",
- "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz",
- "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/optionator": {
- "version": "0.9.4",
- "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
- "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "deep-is": "^0.1.3",
- "fast-levenshtein": "^2.0.6",
- "levn": "^0.4.1",
- "prelude-ls": "^1.2.1",
- "type-check": "^0.4.0",
- "word-wrap": "^1.2.5"
- },
- "engines": {
- "node": ">= 0.8.0"
- }
- },
- "node_modules/p-limit": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
- "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "yocto-queue": "^0.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/p-locate": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
- "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "p-limit": "^3.0.2"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/parent-module": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
- "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "callsites": "^3.0.0"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/path-exists": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
- "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/path-key": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
- "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/picocolors": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
- "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
- "license": "ISC"
- },
- "node_modules/picomatch": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
- "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
- "license": "MIT",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/jonschlinkert"
- }
- },
- "node_modules/postcss": {
- "version": "8.5.6",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz",
- "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==",
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/postcss/"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/postcss"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "nanoid": "^3.3.11",
- "picocolors": "^1.1.1",
- "source-map-js": "^1.2.1"
- },
- "engines": {
- "node": "^10 || ^12 || >=14"
- }
- },
- "node_modules/prelude-ls": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
- "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.8.0"
- }
- },
- "node_modules/punycode": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
- "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/react": {
- "version": "19.2.4",
- "resolved": "https://registry.npmjs.org/react/-/react-19.2.4.tgz",
- "integrity": "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==",
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/react-dom": {
- "version": "19.2.4",
- "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.4.tgz",
- "integrity": "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==",
- "license": "MIT",
- "dependencies": {
- "scheduler": "^0.27.0"
- },
- "peerDependencies": {
- "react": "^19.2.4"
- }
- },
- "node_modules/react-refresh": {
- "version": "0.18.0",
- "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.18.0.tgz",
- "integrity": "sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/react-router": {
- "version": "7.13.0",
- "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.13.0.tgz",
- "integrity": "sha512-PZgus8ETambRT17BUm/LL8lX3Of+oiLaPuVTRH3l1eLvSPpKO3AvhAEb5N7ihAFZQrYDqkvvWfFh9p0z9VsjLw==",
- "license": "MIT",
- "dependencies": {
- "cookie": "^1.0.1",
- "set-cookie-parser": "^2.6.0"
- },
- "engines": {
- "node": ">=20.0.0"
- },
- "peerDependencies": {
- "react": ">=18",
- "react-dom": ">=18"
- },
- "peerDependenciesMeta": {
- "react-dom": {
- "optional": true
- }
- }
- },
- "node_modules/react-router-dom": {
- "version": "7.13.0",
- "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.13.0.tgz",
- "integrity": "sha512-5CO/l5Yahi2SKC6rGZ+HDEjpjkGaG/ncEP7eWFTvFxbHP8yeeI0PxTDjimtpXYlR3b3i9/WIL4VJttPrESIf2g==",
- "license": "MIT",
- "dependencies": {
- "react-router": "7.13.0"
- },
- "engines": {
- "node": ">=20.0.0"
- },
- "peerDependencies": {
- "react": ">=18",
- "react-dom": ">=18"
- }
- },
- "node_modules/resolve-from": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
- "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/rollup": {
- "version": "4.57.1",
- "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.57.1.tgz",
- "integrity": "sha512-oQL6lgK3e2QZeQ7gcgIkS2YZPg5slw37hYufJ3edKlfQSGGm8ICoxswK15ntSzF/a8+h7ekRy7k7oWc3BQ7y8A==",
- "license": "MIT",
- "dependencies": {
- "@types/estree": "1.0.8"
- },
- "bin": {
- "rollup": "dist/bin/rollup"
- },
- "engines": {
- "node": ">=18.0.0",
- "npm": ">=8.0.0"
- },
- "optionalDependencies": {
- "@rollup/rollup-android-arm-eabi": "4.57.1",
- "@rollup/rollup-android-arm64": "4.57.1",
- "@rollup/rollup-darwin-arm64": "4.57.1",
- "@rollup/rollup-darwin-x64": "4.57.1",
- "@rollup/rollup-freebsd-arm64": "4.57.1",
- "@rollup/rollup-freebsd-x64": "4.57.1",
- "@rollup/rollup-linux-arm-gnueabihf": "4.57.1",
- "@rollup/rollup-linux-arm-musleabihf": "4.57.1",
- "@rollup/rollup-linux-arm64-gnu": "4.57.1",
- "@rollup/rollup-linux-arm64-musl": "4.57.1",
- "@rollup/rollup-linux-loong64-gnu": "4.57.1",
- "@rollup/rollup-linux-loong64-musl": "4.57.1",
- "@rollup/rollup-linux-ppc64-gnu": "4.57.1",
- "@rollup/rollup-linux-ppc64-musl": "4.57.1",
- "@rollup/rollup-linux-riscv64-gnu": "4.57.1",
- "@rollup/rollup-linux-riscv64-musl": "4.57.1",
- "@rollup/rollup-linux-s390x-gnu": "4.57.1",
- "@rollup/rollup-linux-x64-gnu": "4.57.1",
- "@rollup/rollup-linux-x64-musl": "4.57.1",
- "@rollup/rollup-openbsd-x64": "4.57.1",
- "@rollup/rollup-openharmony-arm64": "4.57.1",
- "@rollup/rollup-win32-arm64-msvc": "4.57.1",
- "@rollup/rollup-win32-ia32-msvc": "4.57.1",
- "@rollup/rollup-win32-x64-gnu": "4.57.1",
- "@rollup/rollup-win32-x64-msvc": "4.57.1",
- "fsevents": "~2.3.2"
- }
- },
- "node_modules/scheduler": {
- "version": "0.27.0",
- "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz",
- "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==",
- "license": "MIT"
- },
- "node_modules/semver": {
- "version": "6.3.1",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
- "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
- "dev": true,
- "license": "ISC",
- "bin": {
- "semver": "bin/semver.js"
- }
- },
- "node_modules/set-cookie-parser": {
- "version": "2.7.2",
- "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.2.tgz",
- "integrity": "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==",
- "license": "MIT"
- },
- "node_modules/shebang-command": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
- "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "shebang-regex": "^3.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/shebang-regex": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
- "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/source-map-js": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
- "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
- "license": "BSD-3-Clause",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/strip-json-comments": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
- "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/tailwindcss": {
- "version": "4.1.18",
- "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.18.tgz",
- "integrity": "sha512-4+Z+0yiYyEtUVCScyfHCxOYP06L5Ne+JiHhY2IjR2KWMIWhJOYZKLSGZaP5HkZ8+bY0cxfzwDE5uOmzFXyIwxw==",
- "license": "MIT"
- },
- "node_modules/tapable": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz",
- "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==",
- "license": "MIT",
- "engines": {
- "node": ">=6"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/webpack"
- }
- },
- "node_modules/tinyglobby": {
- "version": "0.2.15",
- "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz",
- "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==",
- "license": "MIT",
- "dependencies": {
- "fdir": "^6.5.0",
- "picomatch": "^4.0.3"
- },
- "engines": {
- "node": ">=12.0.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/SuperchupuDev"
- }
- },
- "node_modules/ts-api-utils": {
- "version": "2.4.0",
- "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.4.0.tgz",
- "integrity": "sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=18.12"
- },
- "peerDependencies": {
- "typescript": ">=4.8.4"
- }
- },
- "node_modules/type-check": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
- "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "prelude-ls": "^1.2.1"
- },
- "engines": {
- "node": ">= 0.8.0"
- }
- },
- "node_modules/typescript": {
- "version": "5.9.3",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
- "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
- "dev": true,
- "license": "Apache-2.0",
- "bin": {
- "tsc": "bin/tsc",
- "tsserver": "bin/tsserver"
- },
- "engines": {
- "node": ">=14.17"
- }
- },
- "node_modules/typescript-eslint": {
- "version": "8.54.0",
- "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.54.0.tgz",
- "integrity": "sha512-CKsJ+g53QpsNPqbzUsfKVgd3Lny4yKZ1pP4qN3jdMOg/sisIDLGyDMezycquXLE5JsEU0wp3dGNdzig0/fmSVQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@typescript-eslint/eslint-plugin": "8.54.0",
- "@typescript-eslint/parser": "8.54.0",
- "@typescript-eslint/typescript-estree": "8.54.0",
- "@typescript-eslint/utils": "8.54.0"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- },
- "peerDependencies": {
- "eslint": "^8.57.0 || ^9.0.0",
- "typescript": ">=4.8.4 <6.0.0"
- }
- },
- "node_modules/undici-types": {
- "version": "7.16.0",
- "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz",
- "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==",
- "devOptional": true,
- "license": "MIT"
- },
- "node_modules/update-browserslist-db": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz",
- "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==",
- "dev": true,
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/browserslist"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/browserslist"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "escalade": "^3.2.0",
- "picocolors": "^1.1.1"
- },
- "bin": {
- "update-browserslist-db": "cli.js"
- },
- "peerDependencies": {
- "browserslist": ">= 4.21.0"
- }
- },
- "node_modules/uri-js": {
- "version": "4.4.1",
- "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
- "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
- "dev": true,
- "license": "BSD-2-Clause",
- "dependencies": {
- "punycode": "^2.1.0"
- }
- },
- "node_modules/vite": {
- "version": "7.3.1",
- "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.1.tgz",
- "integrity": "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==",
- "license": "MIT",
- "dependencies": {
- "esbuild": "^0.27.0",
- "fdir": "^6.5.0",
- "picomatch": "^4.0.3",
- "postcss": "^8.5.6",
- "rollup": "^4.43.0",
- "tinyglobby": "^0.2.15"
- },
- "bin": {
- "vite": "bin/vite.js"
- },
- "engines": {
- "node": "^20.19.0 || >=22.12.0"
- },
- "funding": {
- "url": "https://github.com/vitejs/vite?sponsor=1"
- },
- "optionalDependencies": {
- "fsevents": "~2.3.3"
- },
- "peerDependencies": {
- "@types/node": "^20.19.0 || >=22.12.0",
- "jiti": ">=1.21.0",
- "less": "^4.0.0",
- "lightningcss": "^1.21.0",
- "sass": "^1.70.0",
- "sass-embedded": "^1.70.0",
- "stylus": ">=0.54.8",
- "sugarss": "^5.0.0",
- "terser": "^5.16.0",
- "tsx": "^4.8.1",
- "yaml": "^2.4.2"
- },
- "peerDependenciesMeta": {
- "@types/node": {
- "optional": true
- },
- "jiti": {
- "optional": true
- },
- "less": {
- "optional": true
- },
- "lightningcss": {
- "optional": true
- },
- "sass": {
- "optional": true
- },
- "sass-embedded": {
- "optional": true
- },
- "stylus": {
- "optional": true
- },
- "sugarss": {
- "optional": true
- },
- "terser": {
- "optional": true
- },
- "tsx": {
- "optional": true
- },
- "yaml": {
- "optional": true
- }
- }
- },
- "node_modules/which": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
- "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "isexe": "^2.0.0"
- },
- "bin": {
- "node-which": "bin/node-which"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/word-wrap": {
- "version": "1.2.5",
- "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz",
- "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/yallist": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
- "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
- "dev": true,
- "license": "ISC"
- },
- "node_modules/yocto-queue": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
- "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/zod": {
- "version": "4.3.6",
- "resolved": "https://registry.npmjs.org/zod/-/zod-4.3.6.tgz",
- "integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==",
- "dev": true,
- "license": "MIT",
- "funding": {
- "url": "https://github.com/sponsors/colinhacks"
- }
- },
- "node_modules/zod-validation-error": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/zod-validation-error/-/zod-validation-error-4.0.2.tgz",
- "integrity": "sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=18.0.0"
- },
- "peerDependencies": {
- "zod": "^3.25.0 || ^4.0.0"
- }
- },
- "node_modules/zustand": {
- "version": "5.0.11",
- "resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.11.tgz",
- "integrity": "sha512-fdZY+dk7zn/vbWNCYmzZULHRrss0jx5pPFiOuMZ/5HJN6Yv3u+1Wswy/4MpZEkEGhtNH+pwxZB8OKgUBPzYAGg==",
- "license": "MIT",
- "engines": {
- "node": ">=12.20.0"
- },
- "peerDependencies": {
- "@types/react": ">=18.0.0",
- "immer": ">=9.0.6",
- "react": ">=18.0.0",
- "use-sync-external-store": ">=1.2.0"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "immer": {
- "optional": true
- },
- "react": {
- "optional": true
- },
- "use-sync-external-store": {
- "optional": true
- }
- }
- }
- }
-}
diff --git a/gateway/admin-ui/package.json b/gateway/admin-ui/package.json
deleted file mode 100644
index 68b9661..0000000
--- a/gateway/admin-ui/package.json
+++ /dev/null
@@ -1,35 +0,0 @@
-{
- "name": "admin-ui",
- "private": true,
- "version": "0.0.0",
- "type": "module",
- "scripts": {
- "dev": "vite",
- "build": "tsc -b && vite build",
- "lint": "eslint .",
- "preview": "vite preview"
- },
- "dependencies": {
- "@tailwindcss/vite": "^4.1.18",
- "@tanstack/react-query": "^5.90.20",
- "react": "^19.2.0",
- "react-dom": "^19.2.0",
- "react-router-dom": "^7.13.0",
- "tailwindcss": "^4.1.18",
- "zustand": "^5.0.11"
- },
- "devDependencies": {
- "@eslint/js": "^9.39.1",
- "@types/node": "^24.10.1",
- "@types/react": "^19.2.5",
- "@types/react-dom": "^19.2.3",
- "@vitejs/plugin-react": "^5.1.1",
- "eslint": "^9.39.1",
- "eslint-plugin-react-hooks": "^7.0.1",
- "eslint-plugin-react-refresh": "^0.4.24",
- "globals": "^16.5.0",
- "typescript": "~5.9.3",
- "typescript-eslint": "^8.46.4",
- "vite": "^7.2.4"
- }
-}
diff --git a/gateway/admin-ui/public/vite.svg b/gateway/admin-ui/public/vite.svg
deleted file mode 100644
index e7b8dfb..0000000
--- a/gateway/admin-ui/public/vite.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/gateway/admin-ui/src/App.tsx b/gateway/admin-ui/src/App.tsx
deleted file mode 100644
index 9741c60..0000000
--- a/gateway/admin-ui/src/App.tsx
+++ /dev/null
@@ -1,61 +0,0 @@
-import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom';
-import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
-import { useAuthStore } from './stores/auth';
-import { Layout } from './components/Layout';
-import {
- LoginPage,
- DashboardPage,
- AppsPage,
- OIDCClientsPage,
- SessionsPage,
- KeysPage,
- UsersPage,
-} from './pages';
-
-const queryClient = new QueryClient({
- defaultOptions: {
- queries: {
- staleTime: 30000,
- retry: 1,
- },
- },
-});
-
-function ProtectedRoute({ children }: { children: React.ReactNode }) {
- const isAuthenticated = useAuthStore((s) => s.isAuthenticated);
-
- if (!isAuthenticated) {
- return ;
- }
-
- return <>{children}>;
-}
-
-function App() {
- return (
-
-
-
- } />
-
-
-
- }
- >
- } />
- } />
- } />
- } />
- } />
- } />
- } />
-
-
-
-
- );
-}
-
-export default App;
diff --git a/gateway/admin-ui/src/api/client.ts b/gateway/admin-ui/src/api/client.ts
deleted file mode 100644
index 7e86e64..0000000
--- a/gateway/admin-ui/src/api/client.ts
+++ /dev/null
@@ -1,306 +0,0 @@
-/**
- * API Client for ATAuth Admin
- */
-
-const API_BASE = import.meta.env.DEV ? '/admin/api' : '/admin';
-
-interface ApiError {
- error: string;
- message: string;
-}
-
-class AdminApiClient {
- private token: string | null = null;
-
- setToken(token: string | null) {
- this.token = token;
- }
-
- getToken(): string | null {
- return this.token;
- }
-
- private async request(
- path: string,
- options: RequestInit = {}
- ): Promise {
- const headers: Record = {
- 'Content-Type': 'application/json',
- ...(options.headers as Record),
- };
-
- if (this.token) {
- headers['Authorization'] = `Bearer ${this.token}`;
- }
-
- const response = await fetch(`${API_BASE}${path}`, {
- ...options,
- headers,
- });
-
- if (!response.ok) {
- const error: ApiError = await response.json().catch(() => ({
- error: 'unknown_error',
- message: response.statusText,
- }));
- throw new Error(error.message || error.error);
- }
-
- return response.json();
- }
-
- // Stats
- async getStats() {
- return this.request<{
- apps_count: number;
- oidc_clients_count: number;
- active_sessions_count: number;
- users_count: number;
- passkeys_count: number;
- mfa_enabled_count: number;
- verified_emails_count: number;
- }>('/stats');
- }
-
- // Apps (Legacy)
- async getApps() {
- return this.request<{
- apps: Array<{
- id: string;
- name: string;
- token_ttl_seconds: number;
- callback_url: string;
- created_at: string;
- }>;
- }>('/apps');
- }
-
- async createApp(data: {
- name: string;
- callback_url: string;
- token_ttl_seconds?: number;
- }) {
- return this.request<{
- id: string;
- hmac_secret: string;
- }>('/apps', {
- method: 'POST',
- body: JSON.stringify(data),
- });
- }
-
- async deleteApp(appId: string) {
- return this.request<{ success: boolean }>(`/apps/${appId}`, {
- method: 'DELETE',
- });
- }
-
- async rotateAppSecret(appId: string) {
- return this.request<{ hmac_secret: string }>(`/apps/${appId}/rotate`, {
- method: 'POST',
- });
- }
-
- // OIDC Clients
- async getOIDCClients() {
- return this.request<{
- clients: Array<{
- id: string;
- name: string;
- client_type: string;
- redirect_uris: string[];
- allowed_scopes: string[];
- grant_types: string[];
- require_pkce: boolean;
- access_token_ttl_seconds: number;
- id_token_ttl_seconds: number;
- refresh_token_ttl_seconds: number;
- created_at: string;
- }>;
- }>('/oidc/clients');
- }
-
- async createOIDCClient(data: {
- name: string;
- redirect_uris: string[];
- allowed_scopes?: string[];
- grant_types?: string[];
- require_pkce?: boolean;
- access_token_ttl_seconds?: number;
- id_token_ttl_seconds?: number;
- refresh_token_ttl_seconds?: number;
- }) {
- return this.request<{
- id: string;
- client_secret: string;
- }>('/oidc/clients', {
- method: 'POST',
- body: JSON.stringify(data),
- });
- }
-
- async updateOIDCClient(
- clientId: string,
- data: {
- name?: string;
- redirect_uris?: string[];
- allowed_scopes?: string[];
- grant_types?: string[];
- require_pkce?: boolean;
- access_token_ttl_seconds?: number;
- id_token_ttl_seconds?: number;
- refresh_token_ttl_seconds?: number;
- }
- ) {
- return this.request<{ success: boolean }>(`/oidc/clients/${clientId}`, {
- method: 'PUT',
- body: JSON.stringify(data),
- });
- }
-
- async deleteOIDCClient(clientId: string) {
- return this.request<{ success: boolean }>(`/oidc/clients/${clientId}`, {
- method: 'DELETE',
- });
- }
-
- async rotateOIDCClientSecret(clientId: string) {
- return this.request<{ client_secret: string }>(
- `/oidc/clients/${clientId}/rotate-secret`,
- {
- method: 'POST',
- }
- );
- }
-
- // Sessions
- async getSessions(params?: { app_id?: string; did?: string; limit?: number }) {
- const query = new URLSearchParams();
- if (params?.app_id) query.set('app_id', params.app_id);
- if (params?.did) query.set('did', params.did);
- if (params?.limit) query.set('limit', params.limit.toString());
-
- const queryStr = query.toString();
- return this.request<{
- sessions: Array<{
- id: string;
- did: string;
- handle: string;
- app_id: string;
- created_at: string;
- expires_at: string;
- connection_state: string;
- last_activity: string;
- }>;
- }>(`/sessions${queryStr ? `?${queryStr}` : ''}`);
- }
-
- async revokeSession(sessionId: string) {
- return this.request<{ success: boolean }>(`/sessions/${sessionId}`, {
- method: 'DELETE',
- });
- }
-
- async revokeAllSessions(did: string, appId?: string) {
- return this.request<{ revoked: number }>('/sessions/revoke-all', {
- method: 'POST',
- body: JSON.stringify({ did, app_id: appId }),
- });
- }
-
- // Keys
- async getKeys() {
- return this.request<{
- keys: Array<{
- kid: string;
- algorithm: string;
- is_active: boolean;
- use_for_signing: boolean;
- created_at: string;
- }>;
- }>('/keys');
- }
-
- async rotateKeys() {
- return this.request<{
- kid: string;
- message: string;
- }>('/keys/rotate', {
- method: 'POST',
- });
- }
-
- async deleteKey(kid: string) {
- return this.request<{ success: boolean }>(`/keys/${kid}`, {
- method: 'DELETE',
- });
- }
-
- // Users
- async getUsers(params?: { limit?: number; offset?: number }) {
- const query = new URLSearchParams();
- if (params?.limit) query.set('limit', params.limit.toString());
- if (params?.offset) query.set('offset', params.offset.toString());
-
- const queryStr = query.toString();
- return this.request<{
- users: Array<{
- did: string;
- handle: string;
- passkeys_count: number;
- mfa_enabled: boolean;
- emails_count: number;
- sessions_count: number;
- }>;
- }>(`/users${queryStr ? `?${queryStr}` : ''}`);
- }
-
- async getUser(did: string) {
- return this.request<{
- user: {
- did: string;
- handle: string;
- passkeys: Array<{
- id: string;
- name: string | null;
- device_type: string;
- backed_up: boolean;
- last_used_at: string | null;
- created_at: string;
- }>;
- mfa_enabled: boolean;
- emails: Array<{
- email: string;
- verified: boolean;
- is_primary: boolean;
- }>;
- sessions: Array<{
- id: string;
- app_id: string;
- created_at: string;
- expires_at: string;
- }>;
- };
- }>(`/users/${encodeURIComponent(did)}`);
- }
-
- async revokeUserMFA(did: string) {
- return this.request<{ success: boolean }>(
- `/users/${encodeURIComponent(did)}/mfa`,
- {
- method: 'DELETE',
- }
- );
- }
-
- async deleteUserPasskey(did: string, credentialId: string) {
- return this.request<{ success: boolean }>(
- `/users/${encodeURIComponent(did)}/passkeys/${encodeURIComponent(credentialId)}`,
- {
- method: 'DELETE',
- }
- );
- }
-}
-
-export const api = new AdminApiClient();
diff --git a/gateway/admin-ui/src/components/Layout/Header.tsx b/gateway/admin-ui/src/components/Layout/Header.tsx
deleted file mode 100644
index dd76b5e..0000000
--- a/gateway/admin-ui/src/components/Layout/Header.tsx
+++ /dev/null
@@ -1,24 +0,0 @@
-import { useAuthStore } from '../../stores/auth';
-
-interface HeaderProps {
- title: string;
-}
-
-export function Header({ title }: HeaderProps) {
- const logout = useAuthStore((s) => s.logout);
-
- return (
-
-
- {title}
-
-
-
-
- );
-}
diff --git a/gateway/admin-ui/src/components/Layout/Layout.tsx b/gateway/admin-ui/src/components/Layout/Layout.tsx
deleted file mode 100644
index 2c2720b..0000000
--- a/gateway/admin-ui/src/components/Layout/Layout.tsx
+++ /dev/null
@@ -1,13 +0,0 @@
-import { Outlet } from 'react-router-dom';
-import { Sidebar } from './Sidebar';
-
-export function Layout() {
- return (
-
-
-
-
-
-
- );
-}
diff --git a/gateway/admin-ui/src/components/Layout/Sidebar.tsx b/gateway/admin-ui/src/components/Layout/Sidebar.tsx
deleted file mode 100644
index 485b604..0000000
--- a/gateway/admin-ui/src/components/Layout/Sidebar.tsx
+++ /dev/null
@@ -1,93 +0,0 @@
-import { NavLink } from 'react-router-dom';
-
-const navItems = [
- { to: '/dashboard', label: 'Dashboard', icon: HomeIcon },
- { to: '/apps', label: 'Legacy Apps', icon: AppIcon },
- { to: '/oidc-clients', label: 'OIDC Clients', icon: KeyIcon },
- { to: '/sessions', label: 'Sessions', icon: UsersIcon },
- { to: '/keys', label: 'Signing Keys', icon: LockIcon },
- { to: '/users', label: 'Users', icon: UserIcon },
-];
-
-export function Sidebar() {
- return (
-
- );
-}
-
-// Simple icon components
-function HomeIcon({ className }: { className?: string }) {
- return (
-
- );
-}
-
-function AppIcon({ className }: { className?: string }) {
- return (
-
- );
-}
-
-function KeyIcon({ className }: { className?: string }) {
- return (
-
- );
-}
-
-function UsersIcon({ className }: { className?: string }) {
- return (
-
- );
-}
-
-function LockIcon({ className }: { className?: string }) {
- return (
-
- );
-}
-
-function UserIcon({ className }: { className?: string }) {
- return (
-
- );
-}
diff --git a/gateway/admin-ui/src/components/Layout/index.ts b/gateway/admin-ui/src/components/Layout/index.ts
deleted file mode 100644
index a92e21a..0000000
--- a/gateway/admin-ui/src/components/Layout/index.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export { Layout } from './Layout';
-export { Sidebar } from './Sidebar';
-export { Header } from './Header';
diff --git a/gateway/admin-ui/src/index.css b/gateway/admin-ui/src/index.css
deleted file mode 100644
index 22fe741..0000000
--- a/gateway/admin-ui/src/index.css
+++ /dev/null
@@ -1,22 +0,0 @@
-@import "tailwindcss";
-
-/* Custom theme variables */
-:root {
- --color-primary: #3b82f6;
- --color-primary-dark: #2563eb;
- --color-success: #10b981;
- --color-warning: #f59e0b;
- --color-danger: #ef4444;
-}
-
-/* Base styles */
-body {
- @apply bg-gray-50 text-gray-900 antialiased;
-}
-
-/* Dark mode */
-@media (prefers-color-scheme: dark) {
- body {
- @apply bg-gray-900 text-gray-100;
- }
-}
diff --git a/gateway/admin-ui/src/main.tsx b/gateway/admin-ui/src/main.tsx
deleted file mode 100644
index bef5202..0000000
--- a/gateway/admin-ui/src/main.tsx
+++ /dev/null
@@ -1,10 +0,0 @@
-import { StrictMode } from 'react'
-import { createRoot } from 'react-dom/client'
-import './index.css'
-import App from './App.tsx'
-
-createRoot(document.getElementById('root')!).render(
-
-
- ,
-)
diff --git a/gateway/admin-ui/src/pages/AppsPage.tsx b/gateway/admin-ui/src/pages/AppsPage.tsx
deleted file mode 100644
index dbdf120..0000000
--- a/gateway/admin-ui/src/pages/AppsPage.tsx
+++ /dev/null
@@ -1,332 +0,0 @@
-import { useState } from 'react';
-import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
-import { Header } from '../components/Layout';
-import { api } from '../api/client';
-
-export function AppsPage() {
- const queryClient = useQueryClient();
- const [showCreate, setShowCreate] = useState(false);
- const [newSecret, setNewSecret] = useState<{ appId: string; secret: string } | null>(null);
-
- const { data, isLoading, error } = useQuery({
- queryKey: ['apps'],
- queryFn: () => api.getApps(),
- });
-
- const deleteMutation = useMutation({
- mutationFn: (appId: string) => api.deleteApp(appId),
- onSuccess: () => {
- queryClient.invalidateQueries({ queryKey: ['apps'] });
- queryClient.invalidateQueries({ queryKey: ['stats'] });
- },
- });
-
- const rotateMutation = useMutation({
- mutationFn: (appId: string) => api.rotateAppSecret(appId),
- onSuccess: (data, appId) => {
- setNewSecret({ appId, secret: data.hmac_secret });
- },
- });
-
- const handleDelete = (appId: string, appName: string) => {
- if (confirm(`Are you sure you want to delete "${appName}"? This cannot be undone.`)) {
- deleteMutation.mutate(appId);
- }
- };
-
- const handleRotate = (appId: string, appName: string) => {
- if (confirm(`Rotate secret for "${appName}"? The old secret will stop working immediately.`)) {
- rotateMutation.mutate(appId);
- }
- };
-
- return (
-
-
-
-
-
-
- Manage legacy apps using HMAC-signed tokens
-
-
-
-
- {showCreate && (
-
setShowCreate(false)}
- onCreated={(secret) => {
- setShowCreate(false);
- setNewSecret(secret);
- queryClient.invalidateQueries({ queryKey: ['apps'] });
- queryClient.invalidateQueries({ queryKey: ['stats'] });
- }}
- />
- )}
-
- {newSecret && (
- setNewSecret(null)}
- />
- )}
-
- {isLoading ? (
- Loading apps...
- ) : error ? (
-
- Failed to load apps
-
- ) : data?.apps.length === 0 ? (
-
-
No apps registered yet
-
- ) : (
-
-
-
-
- |
- Name
- |
-
- App ID
- |
-
- Token TTL
- |
-
- Created
- |
-
- Actions
- |
-
-
-
- {data?.apps.map((app) => (
-
- |
-
- {app.name}
-
-
- {app.callback_url}
-
- |
-
- {app.id.substring(0, 8)}...
- |
-
- {formatDuration(app.token_ttl_seconds)}
- |
-
- {new Date(app.created_at).toLocaleDateString()}
- |
-
-
-
- |
-
- ))}
-
-
-
- )}
-
-
- );
-}
-
-interface CreateAppModalProps {
- onClose: () => void;
- onCreated: (secret: { appId: string; secret: string }) => void;
-}
-
-function CreateAppModal({ onClose, onCreated }: CreateAppModalProps) {
- const [name, setName] = useState('');
- const [callbackUrl, setCallbackUrl] = useState('');
- const [ttl, setTtl] = useState('3600');
-
- const createMutation = useMutation({
- mutationFn: () =>
- api.createApp({
- name,
- callback_url: callbackUrl,
- token_ttl_seconds: parseInt(ttl, 10),
- }),
- onSuccess: (data) => {
- onCreated({ appId: data.id, secret: data.hmac_secret });
- },
- });
-
- const handleSubmit = (e: React.FormEvent) => {
- e.preventDefault();
- createMutation.mutate();
- };
-
- return (
-
-
-
- Create Legacy App
-
-
-
-
-
- );
-}
-
-interface SecretModalProps {
- appId: string;
- secret: string;
- onClose: () => void;
-}
-
-function SecretModal({ appId, secret, onClose }: SecretModalProps) {
- const [copied, setCopied] = useState(false);
-
- const handleCopy = async () => {
- await navigator.clipboard.writeText(secret);
- setCopied(true);
- setTimeout(() => setCopied(false), 2000);
- };
-
- return (
-
-
-
- App Secret
-
-
- Save this secret now! It won't be shown again.
-
-
-
-
-
- {appId}
-
-
-
-
-
-
-
- {secret}
-
-
-
-
-
-
-
-
- );
-}
-
-function formatDuration(seconds: number): string {
- if (seconds < 60) return `${seconds}s`;
- if (seconds < 3600) return `${Math.floor(seconds / 60)}m`;
- if (seconds < 86400) return `${Math.floor(seconds / 3600)}h`;
- return `${Math.floor(seconds / 86400)}d`;
-}
diff --git a/gateway/admin-ui/src/pages/DashboardPage.tsx b/gateway/admin-ui/src/pages/DashboardPage.tsx
deleted file mode 100644
index 33d32fc..0000000
--- a/gateway/admin-ui/src/pages/DashboardPage.tsx
+++ /dev/null
@@ -1,130 +0,0 @@
-import { useQuery } from '@tanstack/react-query';
-import { Header } from '../components/Layout';
-import { api } from '../api/client';
-
-export function DashboardPage() {
- const { data: stats, isLoading, error } = useQuery({
- queryKey: ['stats'],
- queryFn: () => api.getStats(),
- refetchInterval: 30000, // Refresh every 30 seconds
- });
-
- return (
-
-
-
-
- {isLoading ? (
-
Loading statistics...
- ) : error ? (
-
- Failed to load statistics
-
- ) : stats ? (
-
-
-
-
-
-
-
-
-
- ) : null}
-
-
-
- Quick Actions
-
-
-
-
-
-
-
-
-
- );
-}
-
-interface StatCardProps {
- title: string;
- value: number;
- subtitle: string;
-}
-
-function StatCard({ title, value, subtitle }: StatCardProps) {
- return (
-
-
- {title}
-
-
- {value.toLocaleString()}
-
-
- {subtitle}
-
-
- );
-}
-
-interface QuickActionProps {
- title: string;
- description: string;
- href: string;
-}
-
-function QuickAction({ title, description, href }: QuickActionProps) {
- return (
-
- {title}
-
- {description}
-
-
- );
-}
diff --git a/gateway/admin-ui/src/pages/KeysPage.tsx b/gateway/admin-ui/src/pages/KeysPage.tsx
deleted file mode 100644
index 3958b09..0000000
--- a/gateway/admin-ui/src/pages/KeysPage.tsx
+++ /dev/null
@@ -1,154 +0,0 @@
-import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
-import { Header } from '../components/Layout';
-import { api } from '../api/client';
-
-export function KeysPage() {
- const queryClient = useQueryClient();
-
- const { data, isLoading, error } = useQuery({
- queryKey: ['keys'],
- queryFn: () => api.getKeys(),
- });
-
- const rotateMutation = useMutation({
- mutationFn: () => api.rotateKeys(),
- onSuccess: () => {
- queryClient.invalidateQueries({ queryKey: ['keys'] });
- },
- });
-
- const deleteMutation = useMutation({
- mutationFn: (kid: string) => api.deleteKey(kid),
- onSuccess: () => {
- queryClient.invalidateQueries({ queryKey: ['keys'] });
- },
- });
-
- const handleRotate = () => {
- if (confirm('Generate a new signing key? The current key will remain valid but not be used for new tokens.')) {
- rotateMutation.mutate();
- }
- };
-
- const handleDelete = (kid: string, isActive: boolean) => {
- if (isActive) {
- alert('Cannot delete the active signing key. Rotate first to create a new key.');
- return;
- }
- if (confirm(`Delete key ${kid}? Any tokens signed with this key will become invalid.`)) {
- deleteMutation.mutate(kid);
- }
- };
-
- return (
-
-
-
-
-
-
-
- Manage JWT signing keys for OIDC tokens
-
-
- Keys are used to sign ID tokens, access tokens, and other JWTs
-
-
-
-
-
- {rotateMutation.isSuccess && (
-
- New signing key generated: {rotateMutation.data.kid}
-
- )}
-
- {isLoading ? (
-
Loading keys...
- ) : error ? (
-
- Failed to load keys
-
- ) : data?.keys.length === 0 ? (
-
-
No signing keys configured
-
- Click "Rotate Keys" to generate an initial signing key
-
-
- ) : (
-
- {data?.keys.map((key) => (
-
-
-
-
-
- {key.kid}
-
- {key.use_for_signing && (
-
- Active Signing Key
-
- )}
- {key.is_active && !key.use_for_signing && (
-
- Valid for Verification
-
- )}
- {!key.is_active && (
-
- Inactive
-
- )}
-
-
- Algorithm: {key.algorithm}
-
-
- Created: {new Date(key.created_at).toLocaleString()}
-
-
-
-
-
- ))}
-
- )}
-
-
-
- Key Rotation Best Practices
-
-
- - - Rotate keys periodically (e.g., every 90 days)
- - - Keep old keys active for verification until all existing tokens expire
- - - Only delete old keys after their tokens have expired
- - - The JWKS endpoint automatically publishes all active keys
-
-
-
-
- );
-}
diff --git a/gateway/admin-ui/src/pages/LoginPage.tsx b/gateway/admin-ui/src/pages/LoginPage.tsx
deleted file mode 100644
index 3c34182..0000000
--- a/gateway/admin-ui/src/pages/LoginPage.tsx
+++ /dev/null
@@ -1,86 +0,0 @@
-import { useState } from 'react';
-import { useNavigate } from 'react-router-dom';
-import { useAuthStore } from '../stores/auth';
-import { api } from '../api/client';
-
-export function LoginPage() {
- const [token, setToken] = useState('');
- const [error, setError] = useState('');
- const [loading, setLoading] = useState(false);
- const navigate = useNavigate();
- const setAuthToken = useAuthStore((s) => s.setToken);
-
- const handleSubmit = async (e: React.FormEvent) => {
- e.preventDefault();
- setError('');
- setLoading(true);
-
- try {
- // Test the token by fetching stats
- api.setToken(token);
- await api.getStats();
- setAuthToken(token);
- navigate('/dashboard');
- } catch (err) {
- setError(err instanceof Error ? err.message : 'Invalid admin token');
- api.setToken(null);
- } finally {
- setLoading(false);
- }
- };
-
- return (
-
-
-
-
-
- ATAuth Admin
-
-
- Enter your admin token to continue
-
-
-
-
-
-
- The admin token is set via the ADMIN_TOKEN environment variable on the gateway server.
-
-
-
-
- );
-}
diff --git a/gateway/admin-ui/src/pages/OIDCClientsPage.tsx b/gateway/admin-ui/src/pages/OIDCClientsPage.tsx
deleted file mode 100644
index 7dd76b3..0000000
--- a/gateway/admin-ui/src/pages/OIDCClientsPage.tsx
+++ /dev/null
@@ -1,589 +0,0 @@
-import { useState } from 'react';
-import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
-import { Header } from '../components/Layout';
-import { api } from '../api/client';
-
-export function OIDCClientsPage() {
- const queryClient = useQueryClient();
- const [showCreate, setShowCreate] = useState(false);
- const [editingClient, setEditingClient] = useState(null);
- const [newSecret, setNewSecret] = useState<{ clientId: string; secret: string } | null>(null);
-
- const { data, isLoading, error } = useQuery({
- queryKey: ['oidc-clients'],
- queryFn: () => api.getOIDCClients(),
- });
-
- const deleteMutation = useMutation({
- mutationFn: (clientId: string) => api.deleteOIDCClient(clientId),
- onSuccess: () => {
- queryClient.invalidateQueries({ queryKey: ['oidc-clients'] });
- queryClient.invalidateQueries({ queryKey: ['stats'] });
- },
- });
-
- const rotateMutation = useMutation({
- mutationFn: (clientId: string) => api.rotateOIDCClientSecret(clientId),
- onSuccess: (data, clientId) => {
- setNewSecret({ clientId, secret: data.client_secret });
- },
- });
-
- const handleDelete = (clientId: string, clientName: string) => {
- if (confirm(`Delete OIDC client "${clientName}"? All associated tokens will be invalidated.`)) {
- deleteMutation.mutate(clientId);
- }
- };
-
- const handleRotate = (clientId: string, clientName: string) => {
- if (confirm(`Rotate secret for "${clientName}"? The old secret will stop working.`)) {
- rotateMutation.mutate(clientId);
- }
- };
-
- return (
-
-
-
-
-
-
- Manage OpenID Connect clients for OAuth 2.0 authentication
-
-
-
-
- {showCreate && (
-
setShowCreate(false)}
- onCreated={(secret) => {
- setShowCreate(false);
- setNewSecret(secret);
- queryClient.invalidateQueries({ queryKey: ['oidc-clients'] });
- queryClient.invalidateQueries({ queryKey: ['stats'] });
- }}
- />
- )}
-
- {editingClient && (
- c.id === editingClient)}
- onClose={() => setEditingClient(null)}
- onSaved={() => {
- setEditingClient(null);
- queryClient.invalidateQueries({ queryKey: ['oidc-clients'] });
- }}
- />
- )}
-
- {newSecret && (
- setNewSecret(null)}
- />
- )}
-
- {isLoading ? (
- Loading OIDC clients...
- ) : error ? (
-
- Failed to load OIDC clients
-
- ) : data?.clients.length === 0 ? (
-
-
No OIDC clients registered
-
- Create an OIDC client to enable OAuth 2.0 / OpenID Connect authentication
-
-
- ) : (
-
- {data?.clients.map((client) => (
-
-
-
-
- {client.name}
-
-
- Client ID: {client.id}
-
-
-
-
-
-
-
-
-
-
-
-
Redirect URIs:
-
- {client.redirect_uris.map((uri, i) => (
- -
- {uri}
-
- ))}
-
-
-
-
Scopes:
-
- {client.allowed_scopes.map((scope) => (
-
- {scope}
-
- ))}
-
-
-
-
-
- PKCE: {client.require_pkce ? 'Required' : 'Optional'}
- Access Token: {formatDuration(client.access_token_ttl_seconds)}
- ID Token: {formatDuration(client.id_token_ttl_seconds)}
- Refresh Token: {formatDuration(client.refresh_token_ttl_seconds)}
-
-
- ))}
-
- )}
-
-
- );
-}
-
-interface CreateOIDCClientModalProps {
- onClose: () => void;
- onCreated: (secret: { clientId: string; secret: string }) => void;
-}
-
-function CreateOIDCClientModal({ onClose, onCreated }: CreateOIDCClientModalProps) {
- const [name, setName] = useState('');
- const [redirectUris, setRedirectUris] = useState('');
- const [scopes, setScopes] = useState('openid profile email');
- const [requirePkce, setRequirePkce] = useState(true);
- const [accessTtl, setAccessTtl] = useState('3600');
- const [idTtl, setIdTtl] = useState('3600');
- const [refreshTtl, setRefreshTtl] = useState('604800');
-
- const createMutation = useMutation({
- mutationFn: () =>
- api.createOIDCClient({
- name,
- redirect_uris: redirectUris.split('\n').map((u) => u.trim()).filter(Boolean),
- allowed_scopes: scopes.split(' ').filter(Boolean),
- require_pkce: requirePkce,
- access_token_ttl_seconds: parseInt(accessTtl, 10),
- id_token_ttl_seconds: parseInt(idTtl, 10),
- refresh_token_ttl_seconds: parseInt(refreshTtl, 10),
- }),
- onSuccess: (data) => {
- onCreated({ clientId: data.id, secret: data.client_secret });
- },
- });
-
- const handleSubmit = (e: React.FormEvent) => {
- e.preventDefault();
- createMutation.mutate();
- };
-
- return (
-
-
-
- Create OIDC Client
-
-
-
-
-
- );
-}
-
-interface EditOIDCClientModalProps {
- clientId: string;
- client?: {
- name: string;
- redirect_uris: string[];
- allowed_scopes: string[];
- require_pkce: boolean;
- access_token_ttl_seconds: number;
- id_token_ttl_seconds: number;
- refresh_token_ttl_seconds: number;
- };
- onClose: () => void;
- onSaved: () => void;
-}
-
-function EditOIDCClientModal({ clientId, client, onClose, onSaved }: EditOIDCClientModalProps) {
- const [name, setName] = useState(client?.name || '');
- const [redirectUris, setRedirectUris] = useState(client?.redirect_uris.join('\n') || '');
- const [scopes, setScopes] = useState(client?.allowed_scopes.join(' ') || '');
- const [requirePkce, setRequirePkce] = useState(client?.require_pkce ?? true);
- const [accessTtl, setAccessTtl] = useState(String(client?.access_token_ttl_seconds || 3600));
- const [idTtl, setIdTtl] = useState(String(client?.id_token_ttl_seconds || 3600));
- const [refreshTtl, setRefreshTtl] = useState(String(client?.refresh_token_ttl_seconds || 604800));
-
- const updateMutation = useMutation({
- mutationFn: () =>
- api.updateOIDCClient(clientId, {
- name,
- redirect_uris: redirectUris.split('\n').map((u) => u.trim()).filter(Boolean),
- allowed_scopes: scopes.split(' ').filter(Boolean),
- require_pkce: requirePkce,
- access_token_ttl_seconds: parseInt(accessTtl, 10),
- id_token_ttl_seconds: parseInt(idTtl, 10),
- refresh_token_ttl_seconds: parseInt(refreshTtl, 10),
- }),
- onSuccess: onSaved,
- });
-
- const handleSubmit = (e: React.FormEvent) => {
- e.preventDefault();
- updateMutation.mutate();
- };
-
- if (!client) return null;
-
- return (
-
-
-
- Edit OIDC Client
-
-
-
-
-
- );
-}
-
-interface SecretModalProps {
- clientId: string;
- secret: string;
- onClose: () => void;
-}
-
-function SecretModal({ clientId, secret, onClose }: SecretModalProps) {
- const [copied, setCopied] = useState(false);
-
- const handleCopy = async () => {
- await navigator.clipboard.writeText(secret);
- setCopied(true);
- setTimeout(() => setCopied(false), 2000);
- };
-
- return (
-
-
-
- Client Secret
-
-
- Save this secret now! It won't be shown again.
-
-
-
-
-
- {clientId}
-
-
-
-
-
-
-
- {secret}
-
-
-
-
-
-
-
-
- );
-}
-
-function formatDuration(seconds: number): string {
- if (seconds < 60) return `${seconds}s`;
- if (seconds < 3600) return `${Math.floor(seconds / 60)}m`;
- if (seconds < 86400) return `${Math.floor(seconds / 3600)}h`;
- return `${Math.floor(seconds / 86400)}d`;
-}
diff --git a/gateway/admin-ui/src/pages/SessionsPage.tsx b/gateway/admin-ui/src/pages/SessionsPage.tsx
deleted file mode 100644
index 4c5dd89..0000000
--- a/gateway/admin-ui/src/pages/SessionsPage.tsx
+++ /dev/null
@@ -1,211 +0,0 @@
-import { useState } from 'react';
-import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
-import { Header } from '../components/Layout';
-import { api } from '../api/client';
-
-export function SessionsPage() {
- const queryClient = useQueryClient();
- const [filterDid, setFilterDid] = useState('');
- const [filterAppId, setFilterAppId] = useState('');
-
- const { data, isLoading, error, refetch } = useQuery({
- queryKey: ['sessions', filterDid, filterAppId],
- queryFn: () =>
- api.getSessions({
- did: filterDid || undefined,
- app_id: filterAppId || undefined,
- limit: 100,
- }),
- refetchInterval: 30000,
- });
-
- const revokeMutation = useMutation({
- mutationFn: (sessionId: string) => api.revokeSession(sessionId),
- onSuccess: () => {
- queryClient.invalidateQueries({ queryKey: ['sessions'] });
- queryClient.invalidateQueries({ queryKey: ['stats'] });
- },
- });
-
- const revokeAllMutation = useMutation({
- mutationFn: ({ did, appId }: { did: string; appId?: string }) =>
- api.revokeAllSessions(did, appId),
- onSuccess: () => {
- queryClient.invalidateQueries({ queryKey: ['sessions'] });
- queryClient.invalidateQueries({ queryKey: ['stats'] });
- },
- });
-
- const handleRevoke = (sessionId: string) => {
- if (confirm('Revoke this session?')) {
- revokeMutation.mutate(sessionId);
- }
- };
-
- const handleRevokeAll = () => {
- if (!filterDid) {
- alert('Enter a DID to revoke all sessions for that user');
- return;
- }
- if (confirm(`Revoke all sessions for ${filterDid}?`)) {
- revokeAllMutation.mutate({
- did: filterDid,
- appId: filterAppId || undefined,
- });
- }
- };
-
- return (
-
-
-
-
-
-
- View and manage active user sessions
-
-
-
-
-
- setFilterDid(e.target.value)}
- className="block w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-900 dark:text-white"
- placeholder="did:plc:..."
- />
-
-
-
- setFilterAppId(e.target.value)}
- className="block w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-900 dark:text-white"
- placeholder="app-id"
- />
-
-
- {filterDid && (
-
- )}
-
-
-
- {isLoading ? (
-
Loading sessions...
- ) : error ? (
-
- Failed to load sessions
-
- ) : data?.sessions.length === 0 ? (
-
-
No active sessions found
-
- ) : (
-
-
-
-
- |
- User
- |
-
- App
- |
-
- Status
- |
-
- Created
- |
-
- Expires
- |
-
- Actions
- |
-
-
-
- {data?.sessions.map((session) => (
-
- |
-
- @{session.handle}
-
-
- {session.did.substring(0, 20)}...
-
- |
-
- {session.app_id.substring(0, 8)}...
- |
-
-
- |
-
- {formatDateTime(session.created_at)}
- |
-
- {formatDateTime(session.expires_at)}
- |
-
-
- |
-
- ))}
-
-
-
- )}
-
-
- );
-}
-
-function StatusBadge({ status }: { status: string }) {
- const colors: Record = {
- active: 'bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-400',
- pending: 'bg-yellow-100 text-yellow-800 dark:bg-yellow-900/30 dark:text-yellow-400',
- connected: 'bg-blue-100 text-blue-800 dark:bg-blue-900/30 dark:text-blue-400',
- disconnected: 'bg-gray-100 text-gray-800 dark:bg-gray-900/30 dark:text-gray-400',
- };
-
- return (
-
- {status}
-
- );
-}
-
-function formatDateTime(dateStr: string): string {
- const date = new Date(dateStr);
- return date.toLocaleDateString() + ' ' + date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
-}
diff --git a/gateway/admin-ui/src/pages/UsersPage.tsx b/gateway/admin-ui/src/pages/UsersPage.tsx
deleted file mode 100644
index bf51fb8..0000000
--- a/gateway/admin-ui/src/pages/UsersPage.tsx
+++ /dev/null
@@ -1,324 +0,0 @@
-import { useState } from 'react';
-import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
-import { Header } from '../components/Layout';
-import { api } from '../api/client';
-
-export function UsersPage() {
- const queryClient = useQueryClient();
- const [selectedUser, setSelectedUser] = useState(null);
-
- const { data, isLoading, error } = useQuery({
- queryKey: ['users'],
- queryFn: () => api.getUsers({ limit: 100 }),
- });
-
- const { data: userDetails, isLoading: detailsLoading } = useQuery({
- queryKey: ['user', selectedUser],
- queryFn: () => (selectedUser ? api.getUser(selectedUser) : null),
- enabled: !!selectedUser,
- });
-
- return (
-
-
-
-
-
- View and manage user accounts, passkeys, MFA, and sessions
-
-
- {isLoading ? (
-
Loading users...
- ) : error ? (
-
- Failed to load users
-
- ) : data?.users.length === 0 ? (
-
- ) : (
-
-
-
-
-
- Users ({data?.users.length})
-
-
-
- {data?.users.map((user) => (
-
- ))}
-
-
-
-
-
- {selectedUser ? (
- detailsLoading ? (
-
-
Loading user details...
-
- ) : userDetails?.user ? (
-
- queryClient.invalidateQueries({ queryKey: ['user', selectedUser] })
- }
- />
- ) : null
- ) : (
-
-
- Select a user to view details
-
-
- )}
-
-
- )}
-
-
- );
-}
-
-interface UserDetailsProps {
- user: {
- did: string;
- handle: string;
- passkeys: Array<{
- id: string;
- name: string | null;
- device_type: string;
- backed_up: boolean;
- last_used_at: string | null;
- created_at: string;
- }>;
- mfa_enabled: boolean;
- emails: Array<{
- email: string;
- verified: boolean;
- is_primary: boolean;
- }>;
- sessions: Array<{
- id: string;
- app_id: string;
- created_at: string;
- expires_at: string;
- }>;
- };
- onRefresh: () => void;
-}
-
-function UserDetails({ user, onRefresh }: UserDetailsProps) {
- const queryClient = useQueryClient();
-
- const revokeMfaMutation = useMutation({
- mutationFn: () => api.revokeUserMFA(user.did),
- onSuccess: () => {
- onRefresh();
- queryClient.invalidateQueries({ queryKey: ['stats'] });
- },
- });
-
- const deletePasskeyMutation = useMutation({
- mutationFn: (credentialId: string) => api.deleteUserPasskey(user.did, credentialId),
- onSuccess: () => {
- onRefresh();
- queryClient.invalidateQueries({ queryKey: ['stats'] });
- },
- });
-
- const handleRevokeMfa = () => {
- if (confirm('Disable MFA for this user? They will need to set it up again.')) {
- revokeMfaMutation.mutate();
- }
- };
-
- const handleDeletePasskey = (credentialId: string, name: string | null) => {
- if (confirm(`Delete passkey "${name || credentialId.substring(0, 8)}"?`)) {
- deletePasskeyMutation.mutate(credentialId);
- }
- };
-
- return (
-
- {/* User Info */}
-
-
- User Information
-
-
-
-
- Handle
- - @{user.handle}
-
-
-
- DID
- -
- {user.did}
-
-
-
-
-
- {/* Passkeys */}
-
-
-
- Passkeys ({user.passkeys.length})
-
-
- {user.passkeys.length === 0 ? (
-
No passkeys registered
- ) : (
-
- {user.passkeys.map((passkey) => (
-
-
-
- {passkey.name || `Passkey ${passkey.id.substring(0, 8)}...`}
-
-
- {passkey.device_type} • {passkey.backed_up ? 'Backed up' : 'Not backed up'}
- {passkey.last_used_at && (
- <> • Last used: {new Date(passkey.last_used_at).toLocaleDateString()}>
- )}
-
-
-
-
- ))}
-
- )}
-
-
- {/* MFA */}
-
-
-
- Two-Factor Authentication
-
- {user.mfa_enabled && (
-
- )}
-
-
- {user.mfa_enabled ? (
-
-
- TOTP Enabled
-
- ) : (
- 'Not configured'
- )}
-
-
-
- {/* Emails */}
-
-
- Email Addresses ({user.emails.length})
-
- {user.emails.length === 0 ? (
-
No emails registered
- ) : (
-
- {user.emails.map((email) => (
-
- {email.email}
- {email.is_primary && (
-
- Primary
-
- )}
- {email.verified ? (
-
- Verified
-
- ) : (
-
- Pending
-
- )}
-
- ))}
-
- )}
-
-
- {/* Sessions */}
-
-
- Active Sessions ({user.sessions.length})
-
- {user.sessions.length === 0 ? (
-
No active sessions
- ) : (
-
- {user.sessions.map((session) => (
-
-
-
- {session.app_id.substring(0, 12)}...
-
-
- Expires: {new Date(session.expires_at).toLocaleDateString()}
-
-
-
- ))}
-
- )}
-
-
- );
-}
diff --git a/gateway/admin-ui/src/pages/index.ts b/gateway/admin-ui/src/pages/index.ts
deleted file mode 100644
index 49f86c7..0000000
--- a/gateway/admin-ui/src/pages/index.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-export { LoginPage } from './LoginPage';
-export { DashboardPage } from './DashboardPage';
-export { AppsPage } from './AppsPage';
-export { OIDCClientsPage } from './OIDCClientsPage';
-export { SessionsPage } from './SessionsPage';
-export { KeysPage } from './KeysPage';
-export { UsersPage } from './UsersPage';
diff --git a/gateway/admin-ui/src/stores/auth.ts b/gateway/admin-ui/src/stores/auth.ts
deleted file mode 100644
index 87b88bf..0000000
--- a/gateway/admin-ui/src/stores/auth.ts
+++ /dev/null
@@ -1,38 +0,0 @@
-import { create } from 'zustand';
-import { persist } from 'zustand/middleware';
-import { api } from '../api/client';
-
-interface AuthState {
- token: string | null;
- isAuthenticated: boolean;
- setToken: (token: string) => void;
- logout: () => void;
-}
-
-export const useAuthStore = create()(
- persist(
- (set) => ({
- token: null,
- isAuthenticated: false,
-
- setToken: (token: string) => {
- api.setToken(token);
- set({ token, isAuthenticated: true });
- },
-
- logout: () => {
- api.setToken(null);
- set({ token: null, isAuthenticated: false });
- },
- }),
- {
- name: 'atauth-admin-auth',
- onRehydrateStorage: () => (state) => {
- // Restore token to API client on rehydration
- if (state?.token) {
- api.setToken(state.token);
- }
- },
- }
- )
-);
diff --git a/gateway/admin-ui/tsconfig.app.json b/gateway/admin-ui/tsconfig.app.json
deleted file mode 100644
index a9b5a59..0000000
--- a/gateway/admin-ui/tsconfig.app.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
- "compilerOptions": {
- "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
- "target": "ES2022",
- "useDefineForClassFields": true,
- "lib": ["ES2022", "DOM", "DOM.Iterable"],
- "module": "ESNext",
- "types": ["vite/client"],
- "skipLibCheck": true,
-
- /* Bundler mode */
- "moduleResolution": "bundler",
- "allowImportingTsExtensions": true,
- "verbatimModuleSyntax": true,
- "moduleDetection": "force",
- "noEmit": true,
- "jsx": "react-jsx",
-
- /* Linting */
- "strict": true,
- "noUnusedLocals": true,
- "noUnusedParameters": true,
- "erasableSyntaxOnly": true,
- "noFallthroughCasesInSwitch": true,
- "noUncheckedSideEffectImports": true
- },
- "include": ["src"]
-}
diff --git a/gateway/admin-ui/tsconfig.json b/gateway/admin-ui/tsconfig.json
deleted file mode 100644
index 1ffef60..0000000
--- a/gateway/admin-ui/tsconfig.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- "files": [],
- "references": [
- { "path": "./tsconfig.app.json" },
- { "path": "./tsconfig.node.json" }
- ]
-}
diff --git a/gateway/admin-ui/tsconfig.node.json b/gateway/admin-ui/tsconfig.node.json
deleted file mode 100644
index 8a67f62..0000000
--- a/gateway/admin-ui/tsconfig.node.json
+++ /dev/null
@@ -1,26 +0,0 @@
-{
- "compilerOptions": {
- "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
- "target": "ES2023",
- "lib": ["ES2023"],
- "module": "ESNext",
- "types": ["node"],
- "skipLibCheck": true,
-
- /* Bundler mode */
- "moduleResolution": "bundler",
- "allowImportingTsExtensions": true,
- "verbatimModuleSyntax": true,
- "moduleDetection": "force",
- "noEmit": true,
-
- /* Linting */
- "strict": true,
- "noUnusedLocals": true,
- "noUnusedParameters": true,
- "erasableSyntaxOnly": true,
- "noFallthroughCasesInSwitch": true,
- "noUncheckedSideEffectImports": true
- },
- "include": ["vite.config.ts"]
-}
diff --git a/gateway/admin-ui/vite.config.ts b/gateway/admin-ui/vite.config.ts
deleted file mode 100644
index 93256ee..0000000
--- a/gateway/admin-ui/vite.config.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-import { defineConfig } from 'vite'
-import react from '@vitejs/plugin-react'
-import tailwindcss from '@tailwindcss/vite'
-
-// https://vite.dev/config/
-export default defineConfig({
- plugins: [react(), tailwindcss()],
- base: '/admin/',
- build: {
- outDir: '../public/admin',
- emptyOutDir: true,
- },
- server: {
- proxy: {
- '/admin/api': {
- target: 'http://localhost:3100',
- changeOrigin: true,
- rewrite: (path) => path.replace(/^\/admin\/api/, '/admin'),
- },
- },
- },
-})
diff --git a/gateway/helm/atauth-gateway/Chart.yaml b/gateway/helm/atauth-gateway/Chart.yaml
deleted file mode 100644
index 8bd5bd4..0000000
--- a/gateway/helm/atauth-gateway/Chart.yaml
+++ /dev/null
@@ -1,16 +0,0 @@
-apiVersion: v2
-name: atauth-gateway
-description: ATAuth Gateway - AT Protocol OAuth gateway with OIDC provider support
-type: application
-version: 0.1.0
-appVersion: "1.3.0"
-keywords:
- - atproto
- - oauth
- - oidc
- - identity
- - authentication
-maintainers:
- - name: ATAuth
-sources:
- - https://github.com/Arcnode-xyz/atauth
diff --git a/gateway/helm/atauth-gateway/templates/_helpers.tpl b/gateway/helm/atauth-gateway/templates/_helpers.tpl
deleted file mode 100644
index d9a2631..0000000
--- a/gateway/helm/atauth-gateway/templates/_helpers.tpl
+++ /dev/null
@@ -1,71 +0,0 @@
-{{/*
-Expand the name of the chart.
-*/}}
-{{- define "atauth-gateway.name" -}}
-{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
-{{- end }}
-
-{{/*
-Create a default fully qualified app name.
-*/}}
-{{- define "atauth-gateway.fullname" -}}
-{{- if .Values.fullnameOverride }}
-{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
-{{- else }}
-{{- $name := default .Chart.Name .Values.nameOverride }}
-{{- if contains $name .Release.Name }}
-{{- .Release.Name | trunc 63 | trimSuffix "-" }}
-{{- else }}
-{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
-{{- end }}
-{{- end }}
-{{- end }}
-
-{{/*
-Create chart name and version as used by the chart label.
-*/}}
-{{- define "atauth-gateway.chart" -}}
-{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
-{{- end }}
-
-{{/*
-Common labels
-*/}}
-{{- define "atauth-gateway.labels" -}}
-helm.sh/chart: {{ include "atauth-gateway.chart" . }}
-{{ include "atauth-gateway.selectorLabels" . }}
-{{- if .Chart.AppVersion }}
-app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
-{{- end }}
-app.kubernetes.io/managed-by: {{ .Release.Service }}
-{{- end }}
-
-{{/*
-Selector labels
-*/}}
-{{- define "atauth-gateway.selectorLabels" -}}
-app.kubernetes.io/name: {{ include "atauth-gateway.name" . }}
-app.kubernetes.io/instance: {{ .Release.Name }}
-{{- end }}
-
-{{/*
-Create the name of the service account to use
-*/}}
-{{- define "atauth-gateway.serviceAccountName" -}}
-{{- if .Values.serviceAccount.create }}
-{{- default (include "atauth-gateway.fullname" .) .Values.serviceAccount.name }}
-{{- else }}
-{{- default "default" .Values.serviceAccount.name }}
-{{- end }}
-{{- end }}
-
-{{/*
-Secret name
-*/}}
-{{- define "atauth-gateway.secretName" -}}
-{{- if .Values.externalSecrets.enabled }}
-{{- .Values.externalSecrets.secretName }}
-{{- else }}
-{{- include "atauth-gateway.fullname" . }}-secrets
-{{- end }}
-{{- end }}
diff --git a/gateway/helm/atauth-gateway/templates/configmap.yaml b/gateway/helm/atauth-gateway/templates/configmap.yaml
deleted file mode 100644
index 296fe5a..0000000
--- a/gateway/helm/atauth-gateway/templates/configmap.yaml
+++ /dev/null
@@ -1,32 +0,0 @@
-apiVersion: v1
-kind: ConfigMap
-metadata:
- name: {{ include "atauth-gateway.fullname" . }}-config
- labels:
- {{- include "atauth-gateway.labels" . | nindent 4 }}
-data:
- PORT: {{ .Values.config.port | quote }}
- HOST: {{ .Values.config.host | quote }}
- NODE_ENV: "production"
-
- OAUTH_CLIENT_ID: {{ .Values.config.oauthClientId | quote }}
- OAUTH_REDIRECT_URI: {{ .Values.config.oauthRedirectUri | quote }}
- CORS_ORIGINS: {{ .Values.config.corsOrigins | quote }}
-
- OIDC_ENABLED: {{ .Values.config.oidc.enabled | quote }}
- OIDC_ISSUER: {{ .Values.config.oidc.issuer | quote }}
- OIDC_KEY_ALGORITHM: {{ .Values.config.oidc.keyAlgorithm | quote }}
-
- PASSKEY_ENABLED: {{ .Values.config.passkey.enabled | quote }}
- WEBAUTHN_RP_NAME: {{ .Values.config.passkey.rpName | quote }}
- WEBAUTHN_RP_ID: {{ .Values.config.passkey.rpId | quote }}
- WEBAUTHN_ORIGIN: {{ .Values.config.passkey.origin | quote }}
-
- MFA_ENABLED: {{ .Values.config.mfa.enabled | quote }}
- MFA_TOTP_ISSUER: {{ .Values.config.mfa.totpIssuer | quote }}
- MFA_BACKUP_CODES_COUNT: {{ .Values.config.mfa.backupCodesCount | quote }}
-
- EMAIL_ENABLED: {{ .Values.config.email.enabled | quote }}
- EMAIL_PROVIDER: {{ .Values.config.email.provider | quote }}
- EMAIL_FROM: {{ .Values.config.email.from | quote }}
- EMAIL_CODE_EXPIRY: {{ .Values.config.email.codeExpiry | quote }}
diff --git a/gateway/helm/atauth-gateway/templates/deployment.yaml b/gateway/helm/atauth-gateway/templates/deployment.yaml
deleted file mode 100644
index 40ae255..0000000
--- a/gateway/helm/atauth-gateway/templates/deployment.yaml
+++ /dev/null
@@ -1,87 +0,0 @@
-apiVersion: apps/v1
-kind: Deployment
-metadata:
- name: {{ include "atauth-gateway.fullname" . }}
- labels:
- {{- include "atauth-gateway.labels" . | nindent 4 }}
-spec:
- replicas: {{ .Values.replicaCount }}
- selector:
- matchLabels:
- {{- include "atauth-gateway.selectorLabels" . | nindent 6 }}
- strategy:
- type: Recreate
- template:
- metadata:
- annotations:
- checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
- checksum/secret: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }}
- labels:
- {{- include "atauth-gateway.selectorLabels" . | nindent 8 }}
- spec:
- {{- with .Values.imagePullSecrets }}
- imagePullSecrets:
- {{- toYaml . | nindent 8 }}
- {{- end }}
- serviceAccountName: {{ include "atauth-gateway.serviceAccountName" . }}
- securityContext:
- {{- toYaml .Values.podSecurityContext | nindent 8 }}
- containers:
- - name: {{ .Chart.Name }}
- securityContext:
- {{- toYaml .Values.securityContext | nindent 12 }}
- image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
- imagePullPolicy: {{ .Values.image.pullPolicy }}
- ports:
- - name: http
- containerPort: {{ .Values.config.port }}
- protocol: TCP
- envFrom:
- - configMapRef:
- name: {{ include "atauth-gateway.fullname" . }}-config
- - secretRef:
- name: {{ include "atauth-gateway.secretName" . }}
- env:
- - name: DB_PATH
- value: /app/data/gateway.db
- {{- if .Values.persistence.enabled }}
- volumeMounts:
- - name: data
- mountPath: /app/data
- {{- end }}
- resources:
- {{- toYaml .Values.resources | nindent 12 }}
- livenessProbe:
- httpGet:
- path: /health
- port: http
- initialDelaySeconds: 10
- periodSeconds: 30
- timeoutSeconds: 5
- failureThreshold: 3
- readinessProbe:
- httpGet:
- path: /health
- port: http
- initialDelaySeconds: 5
- periodSeconds: 10
- timeoutSeconds: 3
- failureThreshold: 3
- {{- if .Values.persistence.enabled }}
- volumes:
- - name: data
- persistentVolumeClaim:
- claimName: {{ .Values.persistence.existingClaim | default (printf "%s-data" (include "atauth-gateway.fullname" .)) }}
- {{- end }}
- {{- with .Values.nodeSelector }}
- nodeSelector:
- {{- toYaml . | nindent 8 }}
- {{- end }}
- {{- with .Values.affinity }}
- affinity:
- {{- toYaml . | nindent 8 }}
- {{- end }}
- {{- with .Values.tolerations }}
- tolerations:
- {{- toYaml . | nindent 8 }}
- {{- end }}
diff --git a/gateway/helm/atauth-gateway/templates/ingress.yaml b/gateway/helm/atauth-gateway/templates/ingress.yaml
deleted file mode 100644
index 331754c..0000000
--- a/gateway/helm/atauth-gateway/templates/ingress.yaml
+++ /dev/null
@@ -1,41 +0,0 @@
-{{- if .Values.ingress.enabled -}}
-apiVersion: networking.k8s.io/v1
-kind: Ingress
-metadata:
- name: {{ include "atauth-gateway.fullname" . }}
- labels:
- {{- include "atauth-gateway.labels" . | nindent 4 }}
- {{- with .Values.ingress.annotations }}
- annotations:
- {{- toYaml . | nindent 4 }}
- {{- end }}
-spec:
- {{- if .Values.ingress.className }}
- ingressClassName: {{ .Values.ingress.className }}
- {{- end }}
- {{- if .Values.ingress.tls }}
- tls:
- {{- range .Values.ingress.tls }}
- - hosts:
- {{- range .hosts }}
- - {{ . | quote }}
- {{- end }}
- secretName: {{ .secretName }}
- {{- end }}
- {{- end }}
- rules:
- {{- range .Values.ingress.hosts }}
- - host: {{ .host | quote }}
- http:
- paths:
- {{- range .paths }}
- - path: {{ .path }}
- pathType: {{ .pathType }}
- backend:
- service:
- name: {{ include "atauth-gateway.fullname" $ }}
- port:
- name: http
- {{- end }}
- {{- end }}
-{{- end }}
diff --git a/gateway/helm/atauth-gateway/templates/pvc.yaml b/gateway/helm/atauth-gateway/templates/pvc.yaml
deleted file mode 100644
index 31c2f65..0000000
--- a/gateway/helm/atauth-gateway/templates/pvc.yaml
+++ /dev/null
@@ -1,17 +0,0 @@
-{{- if and .Values.persistence.enabled (not .Values.persistence.existingClaim) }}
-apiVersion: v1
-kind: PersistentVolumeClaim
-metadata:
- name: {{ include "atauth-gateway.fullname" . }}-data
- labels:
- {{- include "atauth-gateway.labels" . | nindent 4 }}
-spec:
- accessModes:
- - {{ .Values.persistence.accessMode }}
- resources:
- requests:
- storage: {{ .Values.persistence.size }}
- {{- if .Values.persistence.storageClass }}
- storageClassName: {{ .Values.persistence.storageClass | quote }}
- {{- end }}
-{{- end }}
diff --git a/gateway/helm/atauth-gateway/templates/secret.yaml b/gateway/helm/atauth-gateway/templates/secret.yaml
deleted file mode 100644
index 12569db..0000000
--- a/gateway/helm/atauth-gateway/templates/secret.yaml
+++ /dev/null
@@ -1,29 +0,0 @@
-{{- if not .Values.externalSecrets.enabled }}
-apiVersion: v1
-kind: Secret
-metadata:
- name: {{ include "atauth-gateway.fullname" . }}-secrets
- labels:
- {{- include "atauth-gateway.labels" . | nindent 4 }}
-type: Opaque
-stringData:
- {{- if .Values.secrets.adminToken }}
- ADMIN_TOKEN: {{ .Values.secrets.adminToken | quote }}
- {{- end }}
- {{- if .Values.secrets.oidcKeySecret }}
- OIDC_KEY_SECRET: {{ .Values.secrets.oidcKeySecret | quote }}
- {{- end }}
- {{- if .Values.secrets.mfaEncryptionKey }}
- MFA_ENCRYPTION_KEY: {{ .Values.secrets.mfaEncryptionKey | quote }}
- {{- end }}
- {{- if and .Values.config.email.enabled .Values.secrets.smtp.host }}
- SMTP_HOST: {{ .Values.secrets.smtp.host | quote }}
- SMTP_PORT: {{ .Values.secrets.smtp.port | quote }}
- SMTP_SECURE: {{ .Values.secrets.smtp.secure | quote }}
- SMTP_USER: {{ .Values.secrets.smtp.user | quote }}
- SMTP_PASS: {{ .Values.secrets.smtp.pass | quote }}
- {{- end }}
- {{- if .Values.secrets.emailApiKey }}
- EMAIL_API_KEY: {{ .Values.secrets.emailApiKey | quote }}
- {{- end }}
-{{- end }}
diff --git a/gateway/helm/atauth-gateway/templates/service.yaml b/gateway/helm/atauth-gateway/templates/service.yaml
deleted file mode 100644
index 9356946..0000000
--- a/gateway/helm/atauth-gateway/templates/service.yaml
+++ /dev/null
@@ -1,15 +0,0 @@
-apiVersion: v1
-kind: Service
-metadata:
- name: {{ include "atauth-gateway.fullname" . }}
- labels:
- {{- include "atauth-gateway.labels" . | nindent 4 }}
-spec:
- type: {{ .Values.service.type }}
- ports:
- - port: {{ .Values.service.port }}
- targetPort: http
- protocol: TCP
- name: http
- selector:
- {{- include "atauth-gateway.selectorLabels" . | nindent 4 }}
diff --git a/gateway/helm/atauth-gateway/templates/serviceaccount.yaml b/gateway/helm/atauth-gateway/templates/serviceaccount.yaml
deleted file mode 100644
index 4aa3532..0000000
--- a/gateway/helm/atauth-gateway/templates/serviceaccount.yaml
+++ /dev/null
@@ -1,12 +0,0 @@
-{{- if .Values.serviceAccount.create -}}
-apiVersion: v1
-kind: ServiceAccount
-metadata:
- name: {{ include "atauth-gateway.serviceAccountName" . }}
- labels:
- {{- include "atauth-gateway.labels" . | nindent 4 }}
- {{- with .Values.serviceAccount.annotations }}
- annotations:
- {{- toYaml . | nindent 4 }}
- {{- end }}
-{{- end }}
diff --git a/gateway/helm/atauth-gateway/values.yaml b/gateway/helm/atauth-gateway/values.yaml
deleted file mode 100644
index a2c8eb3..0000000
--- a/gateway/helm/atauth-gateway/values.yaml
+++ /dev/null
@@ -1,149 +0,0 @@
-# ATAuth Gateway Helm Values
-
-# Image configuration
-image:
- repository: atauth-gateway
- tag: latest
- pullPolicy: IfNotPresent
-
-# Image pull secrets (if using private registry)
-imagePullSecrets: []
-
-# Number of replicas (use 1 for SQLite)
-replicaCount: 1
-
-# Service account
-serviceAccount:
- create: true
- name: ""
- annotations: {}
-
-# Pod security context
-podSecurityContext:
- runAsNonRoot: true
- runAsUser: 1001
- runAsGroup: 1001
- fsGroup: 1001
-
-# Container security context
-securityContext:
- allowPrivilegeEscalation: false
- readOnlyRootFilesystem: false
- capabilities:
- drop:
- - ALL
-
-# Service configuration
-service:
- type: ClusterIP
- port: 80
-
-# Ingress configuration
-ingress:
- enabled: false
- className: ""
- annotations: {}
- # cert-manager.io/cluster-issuer: letsencrypt-prod
- hosts:
- - host: auth.example.com
- paths:
- - path: /
- pathType: Prefix
- tls: []
- # - secretName: atauth-gateway-tls
- # hosts:
- # - auth.example.com
-
-# Resource limits
-resources:
- requests:
- memory: "128Mi"
- cpu: "100m"
- limits:
- memory: "512Mi"
- cpu: "500m"
-
-# Persistent storage for SQLite database
-persistence:
- enabled: true
- storageClass: ""
- accessMode: ReadWriteOnce
- size: 1Gi
- existingClaim: ""
-
-# Node selector
-nodeSelector: {}
-
-# Tolerations
-tolerations: []
-
-# Affinity rules
-affinity: {}
-
-# ATAuth Gateway configuration
-config:
- # Server
- port: 3100
- host: "0.0.0.0"
-
- # OAuth client configuration (for AT Protocol)
- oauthClientId: "https://auth.example.com/client-metadata.json"
- oauthRedirectUri: "https://auth.example.com/auth/callback"
-
- # CORS origins (comma-separated)
- corsOrigins: "https://example.com"
-
- # OIDC configuration
- oidc:
- enabled: true
- issuer: "https://auth.example.com"
- keyAlgorithm: "ES256"
-
- # Passkey/WebAuthn configuration
- passkey:
- enabled: true
- rpName: "ATAuth"
- rpId: "auth.example.com"
- origin: "https://auth.example.com"
-
- # MFA configuration
- mfa:
- enabled: true
- totpIssuer: "ATAuth"
- backupCodesCount: 10
-
- # Email configuration
- email:
- enabled: false
- provider: "smtp"
- from: "ATAuth "
- codeExpiry: 900
-
-# Secrets (set via --set or external secret management)
-secrets:
- # Admin token for API access
- # Generate with: openssl rand -hex 32
- adminToken: ""
-
- # OIDC key encryption secret
- oidcKeySecret: ""
-
- # MFA encryption key (32 bytes hex)
- mfaEncryptionKey: ""
-
- # SMTP configuration (if email.enabled)
- smtp:
- host: ""
- port: "587"
- secure: "false"
- user: ""
- pass: ""
-
- # Email API key (alternative to SMTP)
- emailApiKey: ""
-
-# External secrets (use existing secrets)
-externalSecrets:
- # Use an existing secret for sensitive values
- enabled: false
- secretName: ""
diff --git a/gateway/k8s/base/configmap.yaml b/gateway/k8s/base/configmap.yaml
deleted file mode 100644
index f46e281..0000000
--- a/gateway/k8s/base/configmap.yaml
+++ /dev/null
@@ -1,48 +0,0 @@
-apiVersion: v1
-kind: ConfigMap
-metadata:
- name: atauth-gateway-config
- namespace: atauth
- labels:
- app.kubernetes.io/name: atauth-gateway
- app.kubernetes.io/component: config
-data:
- # Server configuration
- PORT: "3100"
- HOST: "0.0.0.0"
- NODE_ENV: "production"
-
- # OAuth client configuration (for AT Protocol)
- # Update these to match your deployment
- OAUTH_CLIENT_ID: "https://auth.example.com/client-metadata.json"
- OAUTH_REDIRECT_URI: "https://auth.example.com/auth/callback"
-
- # CORS origins (comma-separated)
- CORS_ORIGINS: "https://example.com,https://app.example.com"
-
- # OIDC configuration
- OIDC_ENABLED: "true"
- OIDC_ISSUER: "https://auth.example.com"
- OIDC_KEY_ALGORITHM: "ES256"
-
- # Passkey/WebAuthn configuration
- PASSKEY_ENABLED: "true"
- WEBAUTHN_RP_NAME: "ATAuth"
- WEBAUTHN_RP_ID: "auth.example.com"
- WEBAUTHN_ORIGIN: "https://auth.example.com"
-
- # MFA configuration
- MFA_ENABLED: "true"
- MFA_TOTP_ISSUER: "ATAuth"
- MFA_BACKUP_CODES_COUNT: "10"
-
- # Email configuration (disabled by default)
- EMAIL_ENABLED: "false"
- EMAIL_PROVIDER: "smtp"
- EMAIL_FROM: "ATAuth "
- EMAIL_CODE_EXPIRY: "900"
-
- # Forward-auth proxy configuration
- FORWARD_AUTH_ENABLED: "true"
- FORWARD_AUTH_SESSION_TTL: "604800"
- FORWARD_AUTH_PROXY_COOKIE_TTL: "86400"
diff --git a/gateway/k8s/base/deployment.yaml b/gateway/k8s/base/deployment.yaml
deleted file mode 100644
index 9309ba2..0000000
--- a/gateway/k8s/base/deployment.yaml
+++ /dev/null
@@ -1,97 +0,0 @@
-apiVersion: apps/v1
-kind: Deployment
-metadata:
- name: atauth-gateway
- namespace: atauth
- labels:
- app.kubernetes.io/name: atauth-gateway
- app.kubernetes.io/component: server
-spec:
- replicas: 1
- selector:
- matchLabels:
- app.kubernetes.io/name: atauth-gateway
- strategy:
- type: Recreate # Use Recreate due to SQLite file lock
- template:
- metadata:
- labels:
- app.kubernetes.io/name: atauth-gateway
- spec:
- securityContext:
- runAsNonRoot: true
- runAsUser: 1001
- runAsGroup: 1001
- fsGroup: 1001
-
- containers:
- - name: gateway
- image: atauth-gateway:latest
- imagePullPolicy: IfNotPresent
-
- ports:
- - name: http
- containerPort: 3100
- protocol: TCP
-
- envFrom:
- - configMapRef:
- name: atauth-gateway-config
- - secretRef:
- name: atauth-gateway-secrets
-
- env:
- - name: DB_PATH
- value: /app/data/gateway.db
-
- volumeMounts:
- - name: data
- mountPath: /app/data
-
- resources:
- requests:
- memory: "128Mi"
- cpu: "100m"
- limits:
- memory: "512Mi"
- cpu: "500m"
-
- livenessProbe:
- httpGet:
- path: /health
- port: http
- initialDelaySeconds: 10
- periodSeconds: 30
- timeoutSeconds: 5
- failureThreshold: 3
-
- readinessProbe:
- httpGet:
- path: /health
- port: http
- initialDelaySeconds: 5
- periodSeconds: 10
- timeoutSeconds: 3
- failureThreshold: 3
-
- securityContext:
- allowPrivilegeEscalation: false
- readOnlyRootFilesystem: false
- capabilities:
- drop:
- - ALL
-
- volumes:
- - name: data
- persistentVolumeClaim:
- claimName: atauth-gateway-data
-
- # Optional: Node selector for specific nodes
- # nodeSelector:
- # kubernetes.io/os: linux
-
- # Optional: Tolerations
- # tolerations:
- # - key: "node-role.kubernetes.io/control-plane"
- # operator: "Exists"
- # effect: "NoSchedule"
diff --git a/gateway/k8s/base/ingress.yaml b/gateway/k8s/base/ingress.yaml
deleted file mode 100644
index c8c9ba2..0000000
--- a/gateway/k8s/base/ingress.yaml
+++ /dev/null
@@ -1,37 +0,0 @@
-apiVersion: networking.k8s.io/v1
-kind: Ingress
-metadata:
- name: atauth-gateway
- namespace: atauth
- labels:
- app.kubernetes.io/name: atauth-gateway
- app.kubernetes.io/component: ingress
- annotations:
- # Traefik annotations (for k3s default)
- # traefik.ingress.kubernetes.io/router.entrypoints: websecure
- # traefik.ingress.kubernetes.io/router.tls: "true"
-
- # Nginx annotations (if using nginx-ingress)
- # nginx.ingress.kubernetes.io/ssl-redirect: "true"
- # nginx.ingress.kubernetes.io/proxy-body-size: "10m"
-
- # cert-manager for automatic TLS
- # cert-manager.io/cluster-issuer: letsencrypt-prod
-spec:
- # Uncomment for TLS
- # tls:
- # - hosts:
- # - auth.example.com
- # secretName: atauth-gateway-tls
-
- rules:
- - host: auth.example.com
- http:
- paths:
- - path: /
- pathType: Prefix
- backend:
- service:
- name: atauth-gateway
- port:
- name: http
diff --git a/gateway/k8s/base/kustomization.yaml b/gateway/k8s/base/kustomization.yaml
deleted file mode 100644
index 8a7fb11..0000000
--- a/gateway/k8s/base/kustomization.yaml
+++ /dev/null
@@ -1,15 +0,0 @@
-apiVersion: kustomize.config.k8s.io/v1beta1
-kind: Kustomization
-
-resources:
- - namespace.yaml
- - configmap.yaml
- - secret.yaml
- - pvc.yaml
- - deployment.yaml
- - service.yaml
- - ingress.yaml
-
-commonLabels:
- app.kubernetes.io/part-of: atauth
- app.kubernetes.io/managed-by: kustomize
diff --git a/gateway/k8s/base/namespace.yaml b/gateway/k8s/base/namespace.yaml
deleted file mode 100644
index e805811..0000000
--- a/gateway/k8s/base/namespace.yaml
+++ /dev/null
@@ -1,7 +0,0 @@
-apiVersion: v1
-kind: Namespace
-metadata:
- name: atauth
- labels:
- app.kubernetes.io/name: atauth
- app.kubernetes.io/component: identity
diff --git a/gateway/k8s/base/pvc.yaml b/gateway/k8s/base/pvc.yaml
deleted file mode 100644
index c7d2859..0000000
--- a/gateway/k8s/base/pvc.yaml
+++ /dev/null
@@ -1,16 +0,0 @@
-apiVersion: v1
-kind: PersistentVolumeClaim
-metadata:
- name: atauth-gateway-data
- namespace: atauth
- labels:
- app.kubernetes.io/name: atauth-gateway
- app.kubernetes.io/component: storage
-spec:
- accessModes:
- - ReadWriteOnce
- resources:
- requests:
- storage: 1Gi
- # Uncomment and set your storage class
- # storageClassName: local-path
diff --git a/gateway/k8s/base/secret.yaml b/gateway/k8s/base/secret.yaml
deleted file mode 100644
index aa61a94..0000000
--- a/gateway/k8s/base/secret.yaml
+++ /dev/null
@@ -1,31 +0,0 @@
-apiVersion: v1
-kind: Secret
-metadata:
- name: atauth-gateway-secrets
- namespace: atauth
- labels:
- app.kubernetes.io/name: atauth-gateway
- app.kubernetes.io/component: secrets
-type: Opaque
-stringData:
- # Admin token for API access
- # Generate with: openssl rand -hex 32
- ADMIN_TOKEN: "CHANGE_ME_generate_with_openssl_rand_hex_32"
-
- # OIDC key encryption secret (32 bytes)
- # Generate with: openssl rand -hex 32
- OIDC_KEY_SECRET: "CHANGE_ME_generate_with_openssl_rand_hex_32"
-
- # MFA encryption key (32 bytes hex = 64 characters)
- # Generate with: openssl rand -hex 32
- MFA_ENCRYPTION_KEY: "CHANGE_ME_generate_with_openssl_rand_hex_32"
-
- # SMTP credentials (if EMAIL_ENABLED=true)
- # SMTP_HOST: "smtp.example.com"
- # SMTP_PORT: "587"
- # SMTP_SECURE: "false"
- # SMTP_USER: "noreply@example.com"
- # SMTP_PASS: "your-smtp-password"
-
- # Or use API-based email provider
- # EMAIL_API_KEY: "your-api-key"
diff --git a/gateway/k8s/base/service.yaml b/gateway/k8s/base/service.yaml
deleted file mode 100644
index 659f398..0000000
--- a/gateway/k8s/base/service.yaml
+++ /dev/null
@@ -1,17 +0,0 @@
-apiVersion: v1
-kind: Service
-metadata:
- name: atauth-gateway
- namespace: atauth
- labels:
- app.kubernetes.io/name: atauth-gateway
- app.kubernetes.io/component: server
-spec:
- type: ClusterIP
- selector:
- app.kubernetes.io/name: atauth-gateway
- ports:
- - name: http
- port: 80
- targetPort: http
- protocol: TCP
diff --git a/gateway/k8s/kustomization.yaml b/gateway/k8s/kustomization.yaml
deleted file mode 100644
index ad49f84..0000000
--- a/gateway/k8s/kustomization.yaml
+++ /dev/null
@@ -1,11 +0,0 @@
-# Root kustomization - use overlays for deployment
-#
-# Deploy staging: kubectl apply -k k8s/overlays/staging
-# Deploy production: kubectl apply -k k8s/overlays/production
-#
-# This file points to production for backward compatibility
-apiVersion: kustomize.config.k8s.io/v1beta1
-kind: Kustomization
-
-resources:
- - overlays/production
diff --git a/gateway/k8s/overlays/do/kustomization.yaml b/gateway/k8s/overlays/do/kustomization.yaml
deleted file mode 100644
index b4e2d9c..0000000
--- a/gateway/k8s/overlays/do/kustomization.yaml
+++ /dev/null
@@ -1,37 +0,0 @@
-apiVersion: kustomize.config.k8s.io/v1beta1
-kind: Kustomization
-
-namespace: atauth
-
-resources:
- - ../../base
-
-images:
- - name: atauth-gateway
- newName: registry.digitalocean.com/ghostmesh-registry/atauth
- newTag: latest
-
-patches:
- # Set storageClass for DO block storage
- - target:
- kind: PersistentVolumeClaim
- name: atauth-gateway-data
- patch: |
- - op: add
- path: /spec/storageClassName
- value: do-block-storage
-
- # Use DO registry pull secret
- - target:
- kind: Deployment
- name: atauth-gateway
- patch: |
- - op: add
- path: /spec/template/spec/imagePullSecrets
- value:
- - name: registry-ghostmesh-registry
-
-labels:
- - pairs:
- environment: digitalocean
- includeSelectors: false
diff --git a/gateway/k8s/overlays/production/backup-cronjob.yaml b/gateway/k8s/overlays/production/backup-cronjob.yaml
deleted file mode 100644
index 1e8e1cd..0000000
--- a/gateway/k8s/overlays/production/backup-cronjob.yaml
+++ /dev/null
@@ -1,134 +0,0 @@
----
-# CronJob to backup SQLite database before deployments
-apiVersion: batch/v1
-kind: CronJob
-metadata:
- name: atauth-gateway-backup
- namespace: atauth
-spec:
- schedule: "0 */6 * * *" # Every 6 hours
- concurrencyPolicy: Forbid
- successfulJobsHistoryLimit: 3
- failedJobsHistoryLimit: 1
- jobTemplate:
- spec:
- template:
- spec:
- securityContext:
- runAsNonRoot: true
- runAsUser: 1001
- fsGroup: 1001
- containers:
- - name: backup
- image: alpine:3.19
- command:
- - /bin/sh
- - -c
- - |
- set -e
- TIMESTAMP=$(date +%Y%m%d-%H%M%S)
- BACKUP_FILE="/backups/gateway-${TIMESTAMP}.db"
-
- echo "Starting backup at ${TIMESTAMP}"
-
- # Copy database (SQLite safe copy)
- cp /data/gateway.db "${BACKUP_FILE}"
-
- # Verify backup
- sqlite3 "${BACKUP_FILE}" "PRAGMA integrity_check;"
-
- # Keep only last 10 backups
- ls -t /backups/gateway-*.db | tail -n +11 | xargs -r rm
-
- echo "Backup complete: ${BACKUP_FILE}"
- ls -la /backups/
- volumeMounts:
- - name: data
- mountPath: /data
- readOnly: true
- - name: backups
- mountPath: /backups
- resources:
- requests:
- memory: "32Mi"
- cpu: "10m"
- limits:
- memory: "64Mi"
- cpu: "100m"
- restartPolicy: OnFailure
- volumes:
- - name: data
- persistentVolumeClaim:
- claimName: atauth-gateway-data
- - name: backups
- persistentVolumeClaim:
- claimName: atauth-gateway-backups
----
-# PVC for backups
-apiVersion: v1
-kind: PersistentVolumeClaim
-metadata:
- name: atauth-gateway-backups
- namespace: atauth
-spec:
- accessModes:
- - ReadWriteOnce
- resources:
- requests:
- storage: 2Gi
----
-# Job to run backup before deployment (triggered manually or by CI)
-apiVersion: batch/v1
-kind: Job
-metadata:
- name: atauth-pre-deploy-backup
- namespace: atauth
- annotations:
- # This job is meant to be created fresh each time
- helm.sh/hook: pre-upgrade
- helm.sh/hook-delete-policy: before-hook-creation
-spec:
- ttlSecondsAfterFinished: 600
- template:
- spec:
- securityContext:
- runAsNonRoot: true
- runAsUser: 1001
- fsGroup: 1001
- containers:
- - name: backup
- image: alpine:3.19
- command:
- - /bin/sh
- - -c
- - |
- set -e
- TIMESTAMP=$(date +%Y%m%d-%H%M%S)
- BACKUP_FILE="/backups/pre-deploy-${TIMESTAMP}.db"
-
- echo "Creating pre-deployment backup"
- cp /data/gateway.db "${BACKUP_FILE}"
- sqlite3 "${BACKUP_FILE}" "PRAGMA integrity_check;"
-
- echo "Pre-deploy backup complete: ${BACKUP_FILE}"
- volumeMounts:
- - name: data
- mountPath: /data
- readOnly: true
- - name: backups
- mountPath: /backups
- resources:
- requests:
- memory: "32Mi"
- cpu: "10m"
- limits:
- memory: "64Mi"
- cpu: "100m"
- restartPolicy: Never
- volumes:
- - name: data
- persistentVolumeClaim:
- claimName: atauth-gateway-data
- - name: backups
- persistentVolumeClaim:
- claimName: atauth-gateway-backups
diff --git a/gateway/k8s/overlays/production/kustomization.yaml b/gateway/k8s/overlays/production/kustomization.yaml
deleted file mode 100644
index 4748815..0000000
--- a/gateway/k8s/overlays/production/kustomization.yaml
+++ /dev/null
@@ -1,28 +0,0 @@
-apiVersion: kustomize.config.k8s.io/v1beta1
-kind: Kustomization
-
-namespace: atauth
-
-resources:
- - ../../base
- - backup-cronjob.yaml
-
-commonLabels:
- environment: production
-
-images:
- - name: atauth-gateway
- newName: gitea.cloudforest-basilisk.ts.net/arcnode.xyz/atauth-gateway
- newTag: latest # Use specific version tags in production!
-
-# Production-specific patches
-patches:
- # Enable pod disruption budget for HA
- - target:
- kind: Deployment
- name: atauth-gateway
- patch: |
- - op: add
- path: /metadata/annotations
- value:
- reloader.stakater.com/auto: "true"
diff --git a/gateway/k8s/overlays/staging/kustomization.yaml b/gateway/k8s/overlays/staging/kustomization.yaml
deleted file mode 100644
index ae40981..0000000
--- a/gateway/k8s/overlays/staging/kustomization.yaml
+++ /dev/null
@@ -1,89 +0,0 @@
-apiVersion: kustomize.config.k8s.io/v1beta1
-kind: Kustomization
-
-namespace: atauth-staging
-
-resources:
- - ../../base
- - tailscale-ingress.yaml
-
-nameSuffix: -staging
-
-commonLabels:
- environment: staging
-
-# Use staging image tag
-images:
- - name: atauth-gateway
- newName: gitea.cloudforest-basilisk.ts.net/arcnode.xyz/atauth-gateway
- newTag: staging
-
-patches:
- # Rename namespace
- - target:
- kind: Namespace
- name: atauth
- patch: |
- - op: replace
- path: /metadata/name
- value: atauth-staging
-
- # Reduce resources for staging
- - target:
- kind: Deployment
- name: atauth-gateway
- patch: |
- - op: replace
- path: /spec/template/spec/containers/0/resources/requests/memory
- value: "64Mi"
- - op: replace
- path: /spec/template/spec/containers/0/resources/requests/cpu
- value: "50m"
- - op: replace
- path: /spec/template/spec/containers/0/resources/limits/memory
- value: "256Mi"
- - op: replace
- path: /spec/template/spec/containers/0/resources/limits/cpu
- value: "250m"
-
- # Smaller PVC for staging
- - target:
- kind: PersistentVolumeClaim
- name: atauth-gateway-data
- patch: |
- - op: replace
- path: /spec/resources/requests/storage
- value: "512Mi"
-
- # Update ingress host for staging
- - target:
- kind: Ingress
- name: atauth-gateway
- patch: |
- - op: replace
- path: /spec/rules/0/host
- value: auth-staging.cloudforest-basilisk.ts.net
-
- # Update ConfigMap with staging URLs
- - target:
- kind: ConfigMap
- name: atauth-gateway-config
- patch: |
- - op: replace
- path: /data/OIDC_ISSUER
- value: "https://auth-staging.cloudforest-basilisk.ts.net"
- - op: replace
- path: /data/OAUTH_CLIENT_ID
- value: "https://auth-staging.cloudforest-basilisk.ts.net/client-metadata.json"
- - op: replace
- path: /data/OAUTH_REDIRECT_URI
- value: "https://auth-staging.cloudforest-basilisk.ts.net/auth/callback"
- - op: replace
- path: /data/WEBAUTHN_RP_ID
- value: "auth-staging.cloudforest-basilisk.ts.net"
- - op: replace
- path: /data/WEBAUTHN_ORIGIN
- value: "https://auth-staging.cloudforest-basilisk.ts.net"
- - op: replace
- path: /data/CORS_ORIGINS
- value: "https://staging.example.com,http://localhost:3000"
diff --git a/gateway/k8s/overlays/staging/tailscale-ingress.yaml b/gateway/k8s/overlays/staging/tailscale-ingress.yaml
deleted file mode 100644
index 7b0d90d..0000000
--- a/gateway/k8s/overlays/staging/tailscale-ingress.yaml
+++ /dev/null
@@ -1,20 +0,0 @@
-apiVersion: networking.k8s.io/v1
-kind: Ingress
-metadata:
- name: atauth-gateway-staging-tailscale
- namespace: atauth-staging
- labels:
- app.kubernetes.io/name: atauth-gateway
- app.kubernetes.io/component: ingress
- environment: staging
- annotations: {}
-spec:
- ingressClassName: tailscale
- defaultBackend:
- service:
- name: atauth-gateway-staging
- port:
- number: 80
- tls:
- - hosts:
- - auth-staging
diff --git a/gateway/src/routes/admin-dashboard.test.ts b/gateway/src/routes/admin-dashboard.test.ts
index a953425..00dd48d 100644
--- a/gateway/src/routes/admin-dashboard.test.ts
+++ b/gateway/src/routes/admin-dashboard.test.ts
@@ -720,6 +720,34 @@ describe('Dashboard Setup Wizard', () => {
expect(client!.redirect_uris).toEqual(['https://abs.example.com/auth/openid/callback']);
});
+ it('should strip protocol prefix from domain in wizard', async () => {
+ const csrf = await getCsrf(app, '/admin/dashboard/clients/wizard/audiobookshelf');
+
+ const res = await request(app)
+ .post('/admin/dashboard/clients/wizard/audiobookshelf')
+ .set('Cookie', adminCookie())
+ .type('form')
+ .send({
+ _csrf: csrf,
+ preset: 'audiobookshelf',
+ domain: 'https://abs.example.com',
+ id: 'abs-protocol-test',
+ name: 'ABS Protocol Test',
+ grant_types: ['authorization_code', 'refresh_token'],
+ scopes: ['openid', 'profile', 'email'],
+ auth_method: 'client_secret_basic',
+ require_pkce: 'on',
+ id_token_ttl: '3600',
+ access_token_ttl: '3600',
+ refresh_token_ttl: '604800',
+ });
+
+ expect(res.status).toBe(302);
+ const client = db.getOIDCClient('abs-protocol-test');
+ expect(client).not.toBeNull();
+ expect(client!.redirect_uris).toEqual(['https://abs.example.com/auth/openid/callback']);
+ });
+
it('should show setup notes on created page', async () => {
const res = await request(app)
.get('/admin/dashboard/clients/created?id=abs&secret=abc123&preset=audiobookshelf')
diff --git a/gateway/src/routes/admin-dashboard.ts b/gateway/src/routes/admin-dashboard.ts
index bb0f76b..816749e 100644
--- a/gateway/src/routes/admin-dashboard.ts
+++ b/gateway/src/routes/admin-dashboard.ts
@@ -13,6 +13,11 @@ import { checkAccess } from '../utils/access-check.js';
import { generateHmacSecret } from '../utils/hmac.js';
import { OIDC_APP_PRESETS, getPresetByKey } from '../data/oidc-presets.js';
+/** Strip protocol scheme (e.g. https://) from user input to prevent double-protocol in URI templates. */
+function stripScheme(input: string): string {
+ return input.replace(/^[a-z][a-z0-9+.-]*:\/\//, '').trim();
+}
+
export function createAdminDashboardRoutes(
db: DatabaseService,
csrfSecret: string,
@@ -540,7 +545,7 @@ export function createAdminDashboardRoutes(
const defaults = presetData && domain ? {
id: presetData.suggested_client_id,
name: presetData.name,
- redirect_uris: presetData.redirect_uri_template.replace(/\{\{DOMAIN\}\}/g, domain),
+ redirect_uris: presetData.redirect_uri_template.replace(/\{\{DOMAIN\}\}/g, stripScheme(domain)),
grant_types: presetData.grant_types,
scopes: presetData.scopes,
auth_method: presetData.token_endpoint_auth_method,
@@ -974,7 +979,7 @@ export function createAdminDashboardRoutes(
// Build redirect URIs from template
const redirect_uris = presetData.redirect_uri_template
- .replace(/\{\{DOMAIN\}\}/g, domain.trim())
+ .replace(/\{\{DOMAIN\}\}/g, stripScheme(domain))
.split('\n')
.map(u => u.trim())
.filter(u => u.length > 0);
diff --git a/gateway/tekton/README.md b/gateway/tekton/README.md
deleted file mode 100644
index 22f9933..0000000
--- a/gateway/tekton/README.md
+++ /dev/null
@@ -1,183 +0,0 @@
-# Tekton CI/CD Pipeline for ATAuth Gateway
-
-This directory contains Tekton pipeline resources for building and deploying ATAuth Gateway on a k3s cluster.
-
-## Prerequisites
-
-1. **Tekton Pipelines** installed on your k3s cluster:
- ```bash
- kubectl apply -f https://storage.googleapis.com/tekton-releases/pipeline/latest/release.yaml
- ```
-
-2. **Tekton Triggers** for webhook support:
- ```bash
- kubectl apply -f https://storage.googleapis.com/tekton-releases/triggers/latest/release.yaml
- kubectl apply -f https://storage.googleapis.com/tekton-releases/triggers/latest/interceptors.yaml
- ```
-
-3. **Tekton Dashboard** (optional but recommended):
- ```bash
- kubectl apply -f https://storage.googleapis.com/tekton-releases/dashboard/latest/release.yaml
- ```
-
-## Setup
-
-### 1. Configure Registry Credentials
-
-Create a secret for your container registry:
-
-```bash
-kubectl create secret docker-registry registry-credentials \
- --docker-server=gitea.cloudforest-basilisk.ts.net \
- --docker-username= \
- --docker-password= \
- -n tekton-pipelines
-```
-
-Or edit `secrets.yaml` with your credentials and apply.
-
-### 2. Configure Git Credentials (if private repo)
-
-```bash
-kubectl create secret generic git-credentials \
- --from-literal=username= \
- --from-literal=password= \
- -n tekton-pipelines
-```
-
-### 3. Apply Pipeline Resources
-
-```bash
-# Apply all Tekton resources
-kubectl apply -k tekton/
-
-# Or apply individually
-kubectl apply -f tekton/rbac.yaml
-kubectl apply -f tekton/pipeline.yaml
-kubectl apply -f tekton/trigger.yaml
-kubectl apply -f tekton/ingress.yaml
-```
-
-### 4. Configure Gitea Webhook
-
-In your Gitea repository settings, add a webhook:
-
-- **URL**: `https://tekton-webhook.cloudforest-basilisk.ts.net/atauth`
-- **Content Type**: `application/json`
-- **Secret**: (optional, add CEL interceptor if using)
-- **Events**: Push events
-
-## Usage
-
-### Manual Pipeline Run
-
-Trigger a build manually:
-
-```bash
-kubectl create -f tekton/pipelinerun.yaml
-```
-
-Or with custom parameters:
-
-```bash
-cat <
-
-# Or use tkn CLI
-tkn pipelinerun logs -f -n tekton-pipelines
-```
-
-### Tekton Dashboard
-
-If installed, access the dashboard:
-
-```bash
-kubectl port-forward -n tekton-pipelines svc/tekton-dashboard 9097:9097
-```
-
-Then open http://localhost:9097
-
-## Pipeline Overview
-
-```
-┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
-│ fetch-source │────▶│ build-push │────▶│ deploy │
-│ (git-clone) │ │ (kaniko) │ │ (kubectl apply) │
-└─────────────────┘ └─────────────────┘ └─────────────────┘
-```
-
-1. **fetch-source**: Clones the Git repository
-2. **build-push**: Builds Docker image with Kaniko and pushes to registry
-3. **deploy**: Applies Kubernetes manifests with new image tag
-
-## Files
-
-| File | Description |
-|------|-------------|
-| `pipeline.yaml` | Main pipeline definition |
-| `pipelinerun.yaml` | Example manual run |
-| `trigger.yaml` | Webhook trigger configuration |
-| `rbac.yaml` | Service accounts and permissions |
-| `secrets.yaml` | Registry and Git credentials template |
-| `ingress.yaml` | Ingress for webhook endpoint |
-| `kustomization.yaml` | Kustomize configuration |
-
-## Troubleshooting
-
-### Build fails with permission denied
-
-Ensure the PVC has correct permissions:
-```yaml
-podTemplate:
- securityContext:
- fsGroup: 65532
-```
-
-### Kaniko can't push to registry
-
-Verify registry credentials:
-```bash
-kubectl get secret registry-credentials -n tekton-pipelines -o jsonpath='{.data.\.dockerconfigjson}' | base64 -d
-```
-
-### Webhook not triggering
-
-Check EventListener pods:
-```bash
-kubectl get pods -n tekton-pipelines -l eventlistener=atauth-gateway-listener
-kubectl logs -n tekton-pipelines -l eventlistener=atauth-gateway-listener
-```
diff --git a/gateway/tekton/ingress.yaml b/gateway/tekton/ingress.yaml
deleted file mode 100644
index 2470c72..0000000
--- a/gateway/tekton/ingress.yaml
+++ /dev/null
@@ -1,28 +0,0 @@
----
-# Ingress for Tekton EventListener webhook
-# This allows Gitea to trigger builds via webhook
-apiVersion: networking.k8s.io/v1
-kind: Ingress
-metadata:
- name: tekton-atauth-webhook
- namespace: tekton-pipelines
- annotations:
- # Traefik (k3s default)
- traefik.ingress.kubernetes.io/router.entrypoints: websecure
- traefik.ingress.kubernetes.io/router.tls: "true"
-spec:
- rules:
- - host: tekton-webhook.cloudforest-basilisk.ts.net
- http:
- paths:
- - path: /atauth
- pathType: Prefix
- backend:
- service:
- name: el-atauth-gateway-listener
- port:
- number: 8080
- tls:
- - hosts:
- - tekton-webhook.cloudforest-basilisk.ts.net
- secretName: tekton-webhook-tls
diff --git a/gateway/tekton/kustomization.yaml b/gateway/tekton/kustomization.yaml
deleted file mode 100644
index 24fc1eb..0000000
--- a/gateway/tekton/kustomization.yaml
+++ /dev/null
@@ -1,13 +0,0 @@
-apiVersion: kustomize.config.k8s.io/v1beta1
-kind: Kustomization
-
-namespace: tekton-pipelines
-
-resources:
- - rbac.yaml
- - secrets.yaml
- - pipeline.yaml
- - trigger.yaml
- - ingress.yaml
-
-# Don't include pipelinerun.yaml - it's for manual runs
diff --git a/gateway/tekton/pipeline.yaml b/gateway/tekton/pipeline.yaml
deleted file mode 100644
index 5c16427..0000000
--- a/gateway/tekton/pipeline.yaml
+++ /dev/null
@@ -1,104 +0,0 @@
-apiVersion: tekton.dev/v1beta1
-kind: Pipeline
-metadata:
- name: atauth-gateway-build
- namespace: tekton-pipelines
-spec:
- description: Build and deploy ATAuth Gateway
- params:
- - name: git-url
- type: string
- description: Git repository URL
- default: "https://gitea.cloudforest-basilisk.ts.net/Arcnode.xyz/atauth.git"
- - name: git-revision
- type: string
- description: Git revision to build
- default: "main"
- - name: image-registry
- type: string
- description: Container registry
- default: "gitea.cloudforest-basilisk.ts.net"
- - name: image-name
- type: string
- description: Image name
- default: "arcnode.xyz/atauth-gateway"
- - name: image-tag
- type: string
- description: Image tag
- default: "latest"
- - name: deploy-namespace
- type: string
- description: Kubernetes namespace for deployment
- default: "atauth"
-
- workspaces:
- - name: source
- description: Workspace for source code
- - name: docker-credentials
- description: Docker registry credentials
-
- tasks:
- - name: fetch-source
- taskRef:
- name: git-clone
- kind: ClusterTask
- workspaces:
- - name: output
- workspace: source
- params:
- - name: url
- value: $(params.git-url)
- - name: revision
- value: $(params.git-revision)
- - name: depth
- value: "1"
-
- - name: build-push
- taskRef:
- name: kaniko
- kind: ClusterTask
- runAfter:
- - fetch-source
- workspaces:
- - name: source
- workspace: source
- - name: dockerconfig
- workspace: docker-credentials
- params:
- - name: IMAGE
- value: $(params.image-registry)/$(params.image-name):$(params.image-tag)
- - name: CONTEXT
- value: ./gateway
- - name: DOCKERFILE
- value: ./gateway/Dockerfile
- - name: EXTRA_ARGS
- value:
- - --cache=true
- - --cache-repo=$(params.image-registry)/$(params.image-name)/cache
-
- - name: deploy
- taskRef:
- name: kubernetes-actions
- kind: ClusterTask
- runAfter:
- - build-push
- workspaces:
- - name: manifest-dir
- workspace: source
- params:
- - name: script
- value: |
- cd gateway/k8s
-
- # Create namespace if not exists
- kubectl create namespace $(params.deploy-namespace) --dry-run=client -o yaml | kubectl apply -f -
-
- # Apply kustomization with new image
- kubectl kustomize . | \
- sed "s|atauth-gateway:latest|$(params.image-registry)/$(params.image-name):$(params.image-tag)|g" | \
- kubectl apply -f -
-
- # Wait for deployment
- kubectl -n $(params.deploy-namespace) rollout status deployment/atauth-gateway --timeout=300s
-
- echo "Deployment complete!"
diff --git a/gateway/tekton/pipelinerun.yaml b/gateway/tekton/pipelinerun.yaml
deleted file mode 100644
index 5a4e05a..0000000
--- a/gateway/tekton/pipelinerun.yaml
+++ /dev/null
@@ -1,36 +0,0 @@
-apiVersion: tekton.dev/v1beta1
-kind: PipelineRun
-metadata:
- generateName: atauth-gateway-build-
- namespace: tekton-pipelines
-spec:
- pipelineRef:
- name: atauth-gateway-build
- params:
- - name: git-url
- value: "https://gitea.cloudforest-basilisk.ts.net/Arcnode.xyz/atauth.git"
- - name: git-revision
- value: "main"
- - name: image-registry
- value: "gitea.cloudforest-basilisk.ts.net"
- - name: image-name
- value: "arcnode.xyz/atauth-gateway"
- - name: image-tag
- value: "latest"
- - name: deploy-namespace
- value: "atauth"
- workspaces:
- - name: source
- volumeClaimTemplate:
- spec:
- accessModes:
- - ReadWriteOnce
- resources:
- requests:
- storage: 1Gi
- - name: docker-credentials
- secret:
- secretName: registry-credentials
- podTemplate:
- securityContext:
- fsGroup: 65532
diff --git a/gateway/tekton/rbac.yaml b/gateway/tekton/rbac.yaml
deleted file mode 100644
index 7a73b26..0000000
--- a/gateway/tekton/rbac.yaml
+++ /dev/null
@@ -1,71 +0,0 @@
----
-apiVersion: v1
-kind: ServiceAccount
-metadata:
- name: tekton-triggers-sa
- namespace: tekton-pipelines
-secrets:
- - name: registry-credentials
- - name: git-credentials
----
-apiVersion: rbac.authorization.k8s.io/v1
-kind: Role
-metadata:
- name: tekton-triggers-role
- namespace: tekton-pipelines
-rules:
- - apiGroups: ["triggers.tekton.dev"]
- resources: ["eventlisteners", "triggerbindings", "triggertemplates", "triggers"]
- verbs: ["get", "list", "watch"]
- - apiGroups: ["tekton.dev"]
- resources: ["pipelineruns", "pipelineresources"]
- verbs: ["create", "delete", "get", "list", "patch", "update", "watch"]
- - apiGroups: [""]
- resources: ["configmaps", "secrets"]
- verbs: ["get", "list", "watch"]
----
-apiVersion: rbac.authorization.k8s.io/v1
-kind: RoleBinding
-metadata:
- name: tekton-triggers-rolebinding
- namespace: tekton-pipelines
-subjects:
- - kind: ServiceAccount
- name: tekton-triggers-sa
- namespace: tekton-pipelines
-roleRef:
- kind: Role
- name: tekton-triggers-role
- apiGroup: rbac.authorization.k8s.io
----
-# ClusterRole for deploying to other namespaces
-apiVersion: rbac.authorization.k8s.io/v1
-kind: ClusterRole
-metadata:
- name: tekton-deploy-role
-rules:
- - apiGroups: [""]
- resources: ["namespaces"]
- verbs: ["create", "get", "list"]
- - apiGroups: [""]
- resources: ["configmaps", "secrets", "services", "persistentvolumeclaims"]
- verbs: ["create", "delete", "get", "list", "patch", "update", "watch"]
- - apiGroups: ["apps"]
- resources: ["deployments"]
- verbs: ["create", "delete", "get", "list", "patch", "update", "watch"]
- - apiGroups: ["networking.k8s.io"]
- resources: ["ingresses"]
- verbs: ["create", "delete", "get", "list", "patch", "update", "watch"]
----
-apiVersion: rbac.authorization.k8s.io/v1
-kind: ClusterRoleBinding
-metadata:
- name: tekton-deploy-rolebinding
-subjects:
- - kind: ServiceAccount
- name: tekton-triggers-sa
- namespace: tekton-pipelines
-roleRef:
- kind: ClusterRole
- name: tekton-deploy-role
- apiGroup: rbac.authorization.k8s.io
diff --git a/gateway/tekton/secrets.yaml b/gateway/tekton/secrets.yaml
deleted file mode 100644
index 063e2a9..0000000
--- a/gateway/tekton/secrets.yaml
+++ /dev/null
@@ -1,40 +0,0 @@
----
-# Registry credentials for Kaniko to push images
-# Create with: kubectl create secret docker-registry registry-credentials \
-# --docker-server=gitea.cloudforest-basilisk.ts.net \
-# --docker-username= \
-# --docker-password= \
-# -n tekton-pipelines
-apiVersion: v1
-kind: Secret
-metadata:
- name: registry-credentials
- namespace: tekton-pipelines
- annotations:
- tekton.dev/docker-0: https://gitea.cloudforest-basilisk.ts.net
-type: kubernetes.io/dockerconfigjson
-stringData:
- # Replace with actual credentials or use kubectl create secret
- .dockerconfigjson: |
- {
- "auths": {
- "gitea.cloudforest-basilisk.ts.net": {
- "username": "REPLACE_WITH_USERNAME",
- "password": "REPLACE_WITH_PASSWORD",
- "auth": "REPLACE_WITH_BASE64_USER_PASS"
- }
- }
- }
----
-# Git credentials for private repos (if needed)
-apiVersion: v1
-kind: Secret
-metadata:
- name: git-credentials
- namespace: tekton-pipelines
- annotations:
- tekton.dev/git-0: https://gitea.cloudforest-basilisk.ts.net
-type: kubernetes.io/basic-auth
-stringData:
- username: REPLACE_WITH_USERNAME
- password: REPLACE_WITH_TOKEN
diff --git a/gateway/tekton/trigger.yaml b/gateway/tekton/trigger.yaml
deleted file mode 100644
index ff8108c..0000000
--- a/gateway/tekton/trigger.yaml
+++ /dev/null
@@ -1,92 +0,0 @@
----
-apiVersion: triggers.tekton.dev/v1beta1
-kind: TriggerTemplate
-metadata:
- name: atauth-gateway-trigger-template
- namespace: tekton-pipelines
-spec:
- params:
- - name: git-revision
- description: The git revision
- default: main
- - name: git-url
- description: The git repository url
- resourcetemplates:
- - apiVersion: tekton.dev/v1beta1
- kind: PipelineRun
- metadata:
- generateName: atauth-gateway-build-
- spec:
- pipelineRef:
- name: atauth-gateway-build
- params:
- - name: git-url
- value: $(tt.params.git-url)
- - name: git-revision
- value: $(tt.params.git-revision)
- - name: image-tag
- value: $(tt.params.git-revision)
- workspaces:
- - name: source
- volumeClaimTemplate:
- spec:
- accessModes:
- - ReadWriteOnce
- resources:
- requests:
- storage: 1Gi
- - name: docker-credentials
- secret:
- secretName: registry-credentials
- podTemplate:
- securityContext:
- fsGroup: 65532
----
-apiVersion: triggers.tekton.dev/v1beta1
-kind: TriggerBinding
-metadata:
- name: atauth-gateway-trigger-binding
- namespace: tekton-pipelines
-spec:
- params:
- - name: git-revision
- value: $(body.ref)
- - name: git-url
- value: $(body.repository.clone_url)
----
-apiVersion: triggers.tekton.dev/v1beta1
-kind: EventListener
-metadata:
- name: atauth-gateway-listener
- namespace: tekton-pipelines
-spec:
- serviceAccountName: tekton-triggers-sa
- triggers:
- - name: gitea-push
- interceptors:
- - ref:
- name: "cel"
- params:
- - name: "filter"
- value: "body.ref in ['refs/heads/main', 'refs/heads/develop']"
- - name: "overlays"
- value:
- - key: truncated_sha
- expression: "body.after.truncate(7)"
- bindings:
- - ref: atauth-gateway-trigger-binding
- template:
- ref: atauth-gateway-trigger-template
----
-apiVersion: v1
-kind: Service
-metadata:
- name: el-atauth-gateway-listener
- namespace: tekton-pipelines
-spec:
- type: ClusterIP
- ports:
- - port: 8080
- targetPort: 8080
- selector:
- eventlistener: atauth-gateway-listener