diff --git a/.env b/.env new file mode 100644 index 0000000..fb7a36c --- /dev/null +++ b/.env @@ -0,0 +1,6 @@ +VITE_TOKEN_NAME = 'dsc_token' +VITE_REFRESH_TOKEN_NAME = 'dsc_refresh_token' +VITE_DANAK_BASE_URL ='https://api.danakcorp.com' +VITE_BASE_URL = 'http://192.168.1.134:4000' +# VITE_BASE_URL = 'https://dmail-api.danakcorp.com' +VITE_SERVICE_ID = 'e51afdc3-ea0b-49cf-8f49-2a6f131b024e' diff --git a/.github/workflows/deploy.yaml b/.github/workflows/deploy.yaml new file mode 100644 index 0000000..076d224 --- /dev/null +++ b/.github/workflows/deploy.yaml @@ -0,0 +1,48 @@ +name: deploy to danak + +on: + push: + branches: + - master + +jobs: + build_and_deploy: + runs-on: ubuntu-latest + + env: + DANAK_SERVER: "https://captain.dev.danakcorp.com" + APP_TOKEN: deb2000a493e5291aed0e2f9d8791b413f6e2f2e6996e8633223fc40a35af15c + APP_NAME: dmail-front + GITHUB_TOKEN: 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 + + steps: + - name: Check out repositorys + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: zmihamid + password: ${{ env.GITHUB_TOKEN }} + + - name: Preset Image Name + run: echo "IMAGE_URL=$(echo ghcr.io/zmihamid/${{ github.event.repository.name }}:$(echo ${{ github.sha }} | cut -c1-7) | tr '[:upper:]' '[:lower:]')" >> $GITHUB_ENV + + - name: Build and push Docker Image + uses: docker/build-push-action@v5 + with: + context: . + file: ./Dockerfile + push: true + tags: ${{ env.IMAGE_URL }} + + - name: Install CapRover CLI + run: npm install -g caprover + + - name: deploy to server + run: | + caprover deploy -a $APP_NAME -u $DANAK_SERVER --appToken $APP_TOKEN -i "$IMAGE_URL" diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a547bf3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,24 @@ +# 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/Dockerfile b/Dockerfile new file mode 100644 index 0000000..e8a618d --- /dev/null +++ b/Dockerfile @@ -0,0 +1,26 @@ +FROM node:22-alpine AS builder + +# Install tzdata to support timezone settings +RUN apk add --no-cache tzdata +RUN npm install -g corepack@latest +RUN corepack enable && corepack prepare pnpm@10 --activate + +# Set the timezone to Asia/Tehran +RUN cp /usr/share/zoneinfo/Asia/Tehran /etc/localtime && echo "Asia/Tehran" > /etc/timezone + +WORKDIR /build +COPY package*.json pnpm-lock.yaml ./ +RUN pnpm install --frozen-lockfile --loglevel info +COPY . ./ +RUN pnpm run build + +FROM nginx:stable-alpine AS production-stage + +COPY --from=builder /build/dist /usr/share/nginx/html + +COPY --from=builder /build/nginx.con[f] /etc/nginx/conf.d/default.conf +RUN cat /etc/nginx/conf.d/default.conf + +EXPOSE 80 + +CMD ["nginx", "-g", "daemon off;"] diff --git a/components.json b/components.json new file mode 100644 index 0000000..73afbdb --- /dev/null +++ b/components.json @@ -0,0 +1,21 @@ +{ + "$schema": "https://ui.shadcn.com/schema.json", + "style": "new-york", + "rsc": false, + "tsx": true, + "tailwind": { + "config": "", + "css": "src/index.css", + "baseColor": "neutral", + "cssVariables": true, + "prefix": "" + }, + "aliases": { + "components": "@/components", + "utils": "@/lib/utils", + "ui": "@/components/ui", + "lib": "@/lib", + "hooks": "@/hooks" + }, + "iconLibrary": "lucide" +} \ No newline at end of file diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 0000000..b1cad5b --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,29 @@ +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' + +export default tseslint.config( + { ignores: ['dist'] }, + { + extends: [js.configs.recommended, ...tseslint.configs.recommended], + files: ['**/*.{ts,tsx}'], + languageOptions: { + ecmaVersion: 2020, + globals: globals.browser, + }, + plugins: { + 'react-hooks': reactHooks, + 'react-refresh': reactRefresh, + }, + rules: { + 'react-hooks/rules-of-hooks': 'off', + 'react-hooks/exhaustive-deps': 'off', + 'react-refresh/only-export-components': [ + 'warn', + { allowConstantExport: true }, + ], + }, + }, +) diff --git a/index.html b/index.html new file mode 100644 index 0000000..e4b78ea --- /dev/null +++ b/index.html @@ -0,0 +1,13 @@ + + + + + + + Vite + React + TS + + +
+ + + diff --git a/nginx.conf b/nginx.conf new file mode 100644 index 0000000..d6bbd54 --- /dev/null +++ b/nginx.conf @@ -0,0 +1,47 @@ +server { + listen 80; + server_name localhost; + root /usr/share/nginx/html; + index index.html; + + add_header X-Frame-Options "DENY" always; + add_header X-Content-Type-Options "nosniff" always; + add_header X-XSS-Protection "1; mode=block" always; + add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload" always; + # add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline';" always; + add_header Referrer-Policy "strict-origin-when-cross-origin" always; + + location /static/ { + expires 1y; + add_header Cache-Control "public, no-transform"; + } + + location / { + try_files $uri $uri/ /index.html; + expires -1; + add_header Cache-Control "no-store, no-cache, must-revalidate"; + } + + # location /health { + # access_log off; + # return 200; + # } + + location ~ /\. { + deny all; + return 403; + } + + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + internal; + } + + gzip on; + gzip_vary on; + gzip_min_length 10240; + gzip_proxied expired no-cache no-store private auth; + gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml application/javascript; + gzip_disable "MSIE [1-6]\."; +} \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..92f1890 --- /dev/null +++ b/package.json @@ -0,0 +1,71 @@ +{ + "name": "dmail-front", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "tsc -b && vite build", + "lint": "eslint .", + "preview": "vite preview", + "orval": "orval" + }, + "dependencies": { + "@hookform/resolvers": "^5.1.1", + "@radix-ui/react-checkbox": "^1.3.2", + "@radix-ui/react-switch": "^1.2.5", + "@react-three/drei": "^10.1.2", + "@react-three/fiber": "^9.1.2", + "@tailwindcss/vite": "^4.1.4", + "@tanstack/react-query": "^5.81.5", + "axios": "^1.10.0", + "class-variance-authority": "^0.7.1", + "clsx": "^2.1.1", + "i18next": "^25.0.1", + "iconsax-react": "^0.0.8", + "js-cookie": "^3.0.5", + "lucide-react": "^0.511.0", + "moment-jalaali": "^0.10.4", + "quill": "^2.0.3", + "react": "^19.0.0", + "react-colorful": "^5.6.1", + "react-date-object": "^2.1.9", + "react-dom": "^19.0.0", + "react-dropzone": "^14.3.8", + "react-hook-form": "^7.60.0", + "react-i18next": "^15.5.1", + "react-loading-skeleton": "^3.5.0", + "react-multi-date-picker": "^4.5.2", + "react-quill": "^2.0.0", + "react-quill-new": "^3.4.6", + "react-router-dom": "^7.5.2", + "react-spinners": "^0.17.0", + "swiper": "^11.2.6", + "tailwind-merge": "^3.2.0", + "tailwindcss": "^4.1.4", + "three": "^0.177.0", + "uuid": "^11.1.0", + "vite-tsconfig-paths": "^5.1.4", + "yup": "^1.6.1", + "zustand": "^5.0.3" + }, + "devDependencies": { + "@eslint/js": "^9.22.0", + "@types/js-cookie": "^3.0.6", + "@types/moment-jalaali": "^0.7.9", + "@types/react": "^19.0.10", + "@types/react-dom": "^19.0.4", + "@types/three": "^0.177.0", + "@vitejs/plugin-react": "^4.3.4", + "eslint": "^9.22.0", + "eslint-plugin-react-hooks": "^5.2.0", + "eslint-plugin-react-refresh": "^0.4.19", + "globals": "^16.0.0", + "orval": "^7.10.0", + "tw-animate-css": "^1.3.0", + "typescript": "~5.7.2", + "typescript-eslint": "^8.26.1", + "vite": "^6.3.1" + }, + "packageManager": "pnpm@10.12.4+sha512.5ea8b0deed94ed68691c9bad4c955492705c5eeb8a87ef86bc62c74a26b037b08ff9570f108b2e4dbd1dd1a9186fea925e527f141c648e85af45631074680184" +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..6530d44 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,6277 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@hookform/resolvers': + specifier: ^5.1.1 + version: 5.1.1(react-hook-form@7.60.0(react@19.1.0)) + '@radix-ui/react-checkbox': + specifier: ^1.3.2 + version: 1.3.2(@types/react-dom@19.1.5(@types/react@19.1.6))(@types/react@19.1.6)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-switch': + specifier: ^1.2.5 + version: 1.2.5(@types/react-dom@19.1.5(@types/react@19.1.6))(@types/react@19.1.6)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@react-three/drei': + specifier: ^10.1.2 + version: 10.1.2(@react-three/fiber@9.1.2(@types/react@19.1.6)(immer@9.0.21)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(three@0.177.0))(@types/react@19.1.6)(@types/three@0.177.0)(immer@9.0.21)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(three@0.177.0) + '@react-three/fiber': + specifier: ^9.1.2 + version: 9.1.2(@types/react@19.1.6)(immer@9.0.21)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(three@0.177.0) + '@tailwindcss/vite': + specifier: ^4.1.4 + version: 4.1.7(vite@6.3.5(@types/node@24.0.7)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + '@tanstack/react-query': + specifier: ^5.81.5 + version: 5.81.5(react@19.1.0) + axios: + specifier: ^1.10.0 + version: 1.10.0 + class-variance-authority: + specifier: ^0.7.1 + version: 0.7.1 + clsx: + specifier: ^2.1.1 + version: 2.1.1 + i18next: + specifier: ^25.0.1 + version: 25.2.1(typescript@5.7.3) + iconsax-react: + specifier: ^0.0.8 + version: 0.0.8(react@19.1.0) + js-cookie: + specifier: ^3.0.5 + version: 3.0.5 + lucide-react: + specifier: ^0.511.0 + version: 0.511.0(react@19.1.0) + moment-jalaali: + specifier: ^0.10.4 + version: 0.10.4 + quill: + specifier: ^2.0.3 + version: 2.0.3 + react: + specifier: ^19.0.0 + version: 19.1.0 + react-colorful: + specifier: ^5.6.1 + version: 5.6.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + react-date-object: + specifier: ^2.1.9 + version: 2.1.9 + react-dom: + specifier: ^19.0.0 + version: 19.1.0(react@19.1.0) + react-dropzone: + specifier: ^14.3.8 + version: 14.3.8(react@19.1.0) + react-hook-form: + specifier: ^7.60.0 + version: 7.60.0(react@19.1.0) + react-i18next: + specifier: ^15.5.1 + version: 15.5.2(i18next@25.2.1(typescript@5.7.3))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(typescript@5.7.3) + react-loading-skeleton: + specifier: ^3.5.0 + version: 3.5.0(react@19.1.0) + react-multi-date-picker: + specifier: ^4.5.2 + version: 4.5.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + react-quill: + specifier: ^2.0.0 + version: 2.0.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + react-quill-new: + specifier: ^3.4.6 + version: 3.4.6(quill-delta@5.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + react-router-dom: + specifier: ^7.5.2 + version: 7.6.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + react-spinners: + specifier: ^0.17.0 + version: 0.17.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + swiper: + specifier: ^11.2.6 + version: 11.2.8 + tailwind-merge: + specifier: ^3.2.0 + version: 3.3.0 + tailwindcss: + specifier: ^4.1.4 + version: 4.1.7 + three: + specifier: ^0.177.0 + version: 0.177.0 + uuid: + specifier: ^11.1.0 + version: 11.1.0 + vite-tsconfig-paths: + specifier: ^5.1.4 + version: 5.1.4(typescript@5.7.3)(vite@6.3.5(@types/node@24.0.7)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + yup: + specifier: ^1.6.1 + version: 1.6.1 + zustand: + specifier: ^5.0.3 + version: 5.0.5(@types/react@19.1.6)(immer@9.0.21)(react@19.1.0)(use-sync-external-store@1.5.0(react@19.1.0)) + devDependencies: + '@eslint/js': + specifier: ^9.22.0 + version: 9.27.0 + '@types/js-cookie': + specifier: ^3.0.6 + version: 3.0.6 + '@types/moment-jalaali': + specifier: ^0.7.9 + version: 0.7.9 + '@types/react': + specifier: ^19.0.10 + version: 19.1.6 + '@types/react-dom': + specifier: ^19.0.4 + version: 19.1.5(@types/react@19.1.6) + '@types/three': + specifier: ^0.177.0 + version: 0.177.0 + '@vitejs/plugin-react': + specifier: ^4.3.4 + version: 4.5.0(vite@6.3.5(@types/node@24.0.7)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + eslint: + specifier: ^9.22.0 + version: 9.27.0(jiti@2.4.2) + eslint-plugin-react-hooks: + specifier: ^5.2.0 + version: 5.2.0(eslint@9.27.0(jiti@2.4.2)) + eslint-plugin-react-refresh: + specifier: ^0.4.19 + version: 0.4.20(eslint@9.27.0(jiti@2.4.2)) + globals: + specifier: ^16.0.0 + version: 16.2.0 + orval: + specifier: ^7.10.0 + version: 7.10.0(openapi-types@12.1.3) + tw-animate-css: + specifier: ^1.3.0 + version: 1.3.0 + typescript: + specifier: ~5.7.2 + version: 5.7.3 + typescript-eslint: + specifier: ^8.26.1 + version: 8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.7.3) + vite: + specifier: ^6.3.1 + version: 6.3.5(@types/node@24.0.7)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + +packages: + + '@ampproject/remapping@2.3.0': + resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} + engines: {node: '>=6.0.0'} + + '@apidevtools/json-schema-ref-parser@11.7.2': + resolution: {integrity: sha512-4gY54eEGEstClvEkGnwVkTkrx0sqwemEFG5OSRRn3tD91XH0+Q8XIkYIfo7IwEWPpJZwILb9GUXeShtplRc/eA==} + engines: {node: '>= 16'} + + '@apidevtools/openapi-schemas@2.1.0': + resolution: {integrity: sha512-Zc1AlqrJlX3SlpupFGpiLi2EbteyP7fXmUOGup6/DnkRgjP9bgMM/ag+n91rsv0U1Gpz0H3VILA/o3bW7Ua6BQ==} + engines: {node: '>=10'} + + '@apidevtools/swagger-methods@3.0.2': + resolution: {integrity: sha512-QAkD5kK2b1WfjDS/UQn/qQkbwF31uqRjPTrsCs5ZG9BQGAkjwvqGFjjPqAuzac/IYzpPtRzjCP1WrTuAIjMrXg==} + + '@apidevtools/swagger-parser@10.1.1': + resolution: {integrity: sha512-u/kozRnsPO/x8QtKYJOqoGtC4kH6yg1lfYkB9Au0WhYB0FNLpyFusttQtvhlwjtG3rOwiRz4D8DnnXa8iEpIKA==} + peerDependencies: + openapi-types: '>=7' + + '@asyncapi/specs@6.8.1': + resolution: {integrity: sha512-czHoAk3PeXTLR+X8IUaD+IpT+g+zUvkcgMDJVothBsan+oHN3jfcFcFUNdOPAAFoUCQN1hXF1dWuphWy05THlA==} + + '@babel/code-frame@7.27.1': + resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} + engines: {node: '>=6.9.0'} + + '@babel/compat-data@7.27.3': + resolution: {integrity: sha512-V42wFfx1ymFte+ecf6iXghnnP8kWTO+ZLXIyZq+1LAXHHvTZdVxicn4yiVYdYMGaCO3tmqub11AorKkv+iodqw==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.27.3': + resolution: {integrity: sha512-hyrN8ivxfvJ4i0fIJuV4EOlV0WDMz5Ui4StRTgVaAvWeiRCilXgwVvxJKtFQ3TKtHgJscB2YiXKGNJuVwhQMtA==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.27.3': + resolution: {integrity: sha512-xnlJYj5zepml8NXtjkG0WquFUv8RskFqyFcVgTBp5k+NaA/8uw/K+OSVf8AMGw5e9HKP2ETd5xpK5MLZQD6b4Q==} + engines: {node: '>=6.9.0'} + + '@babel/helper-compilation-targets@7.27.2': + resolution: {integrity: sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.27.1': + resolution: {integrity: sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-transforms@7.27.3': + resolution: {integrity: sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-plugin-utils@7.27.1': + resolution: {integrity: sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@7.27.1': + resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.27.1': + resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-option@7.27.1': + resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.27.3': + resolution: {integrity: sha512-h/eKy9agOya1IGuLaZ9tEUgz+uIRXcbtOhRtUyyMf8JFmn1iT13vnl/IGVWSkdOCG/pC57U4S1jnAabAavTMwg==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.27.3': + resolution: {integrity: sha512-xyYxRj6+tLNDTWi0KCBcZ9V7yg3/lwL9DWh9Uwh/RIVlIfFidggcgxKX3GCXwCiswwcGRawBKbEg2LG/Y8eJhw==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/plugin-transform-react-jsx-self@7.27.1': + resolution: {integrity: sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-react-jsx-source@7.27.1': + resolution: {integrity: sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/runtime@7.27.3': + resolution: {integrity: sha512-7EYtGezsdiDMyY80+65EzwiGmcJqpmcZCojSXaRgdrBaGtWTgDZKq69cPIVped6MkIM78cTQ2GOiEYjwOlG4xw==} + engines: {node: '>=6.9.0'} + + '@babel/template@7.27.2': + resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.27.3': + resolution: {integrity: sha512-lId/IfN/Ye1CIu8xG7oKBHXd2iNb2aW1ilPszzGcJug6M8RCKfVNcYhpI5+bMvFYjK7lXIM0R+a+6r8xhHp2FQ==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.27.3': + resolution: {integrity: sha512-Y1GkI4ktrtvmawoSq+4FCVHNryea6uR+qUQy0AGxLSsjCX0nVmkYQMBLHDkXZuo5hGx7eYdnIaslsdBFm7zbUw==} + engines: {node: '>=6.9.0'} + + '@dimforge/rapier3d-compat@0.12.0': + resolution: {integrity: sha512-uekIGetywIgopfD97oDL5PfeezkFpNhwlzlaEYNOA0N6ghdsOvh/HYjSMek5Q2O1PYvRSDFcqFVJl4r4ZBwOow==} + + '@esbuild/aix-ppc64@0.25.5': + resolution: {integrity: sha512-9o3TMmpmftaCMepOdA5k/yDw8SfInyzWWTjYTFCX3kPSDJMROQTb8jg+h9Cnwnmm1vOzvxN7gIfB5V2ewpjtGA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.25.5': + resolution: {integrity: sha512-VGzGhj4lJO+TVGV1v8ntCZWJktV7SGCs3Pn1GRWI1SBFtRALoomm8k5E9Pmwg3HOAal2VDc2F9+PM/rEY6oIDg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.25.5': + resolution: {integrity: sha512-AdJKSPeEHgi7/ZhuIPtcQKr5RQdo6OO2IL87JkianiMYMPbCtot9fxPbrMiBADOWWm3T2si9stAiVsGbTQFkbA==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.25.5': + resolution: {integrity: sha512-D2GyJT1kjvO//drbRT3Hib9XPwQeWd9vZoBJn+bu/lVsOZ13cqNdDeqIF/xQ5/VmWvMduP6AmXvylO/PIc2isw==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.25.5': + resolution: {integrity: sha512-GtaBgammVvdF7aPIgH2jxMDdivezgFu6iKpmT+48+F8Hhg5J/sfnDieg0aeG/jfSvkYQU2/pceFPDKlqZzwnfQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.25.5': + resolution: {integrity: sha512-1iT4FVL0dJ76/q1wd7XDsXrSW+oLoquptvh4CLR4kITDtqi2e/xwXwdCVH8hVHU43wgJdsq7Gxuzcs6Iq/7bxQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.25.5': + resolution: {integrity: sha512-nk4tGP3JThz4La38Uy/gzyXtpkPW8zSAmoUhK9xKKXdBCzKODMc2adkB2+8om9BDYugz+uGV7sLmpTYzvmz6Sw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.25.5': + resolution: {integrity: sha512-PrikaNjiXdR2laW6OIjlbeuCPrPaAl0IwPIaRv+SMV8CiM8i2LqVUHFC1+8eORgWyY7yhQY+2U2fA55mBzReaw==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.25.5': + resolution: {integrity: sha512-Z9kfb1v6ZlGbWj8EJk9T6czVEjjq2ntSYLY2cw6pAZl4oKtfgQuS4HOq41M/BcoLPzrUbNd+R4BXFyH//nHxVg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.25.5': + resolution: {integrity: sha512-cPzojwW2okgh7ZlRpcBEtsX7WBuqbLrNXqLU89GxWbNt6uIg78ET82qifUy3W6OVww6ZWobWub5oqZOVtwolfw==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.25.5': + resolution: {integrity: sha512-sQ7l00M8bSv36GLV95BVAdhJ2QsIbCuCjh/uYrWiMQSUuV+LpXwIqhgJDcvMTj+VsQmqAHL2yYaasENvJ7CDKA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.25.5': + resolution: {integrity: sha512-0ur7ae16hDUC4OL5iEnDb0tZHDxYmuQyhKhsPBV8f99f6Z9KQM02g33f93rNH5A30agMS46u2HP6qTdEt6Q1kg==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.25.5': + resolution: {integrity: sha512-kB/66P1OsHO5zLz0i6X0RxlQ+3cu0mkxS3TKFvkb5lin6uwZ/ttOkP3Z8lfR9mJOBk14ZwZ9182SIIWFGNmqmg==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.25.5': + resolution: {integrity: sha512-UZCmJ7r9X2fe2D6jBmkLBMQetXPXIsZjQJCjgwpVDz+YMcS6oFR27alkgGv3Oqkv07bxdvw7fyB71/olceJhkQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.25.5': + resolution: {integrity: sha512-kTxwu4mLyeOlsVIFPfQo+fQJAV9mh24xL+y+Bm6ej067sYANjyEw1dNHmvoqxJUCMnkBdKpvOn0Ahql6+4VyeA==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.25.5': + resolution: {integrity: sha512-K2dSKTKfmdh78uJ3NcWFiqyRrimfdinS5ErLSn3vluHNeHVnBAFWC8a4X5N+7FgVE1EjXS1QDZbpqZBjfrqMTQ==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.25.5': + resolution: {integrity: sha512-uhj8N2obKTE6pSZ+aMUbqq+1nXxNjZIIjCjGLfsWvVpy7gKCOL6rsY1MhRh9zLtUtAI7vpgLMK6DxjO8Qm9lJw==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.25.5': + resolution: {integrity: sha512-pwHtMP9viAy1oHPvgxtOv+OkduK5ugofNTVDilIzBLpoWAM16r7b/mxBvfpuQDpRQFMfuVr5aLcn4yveGvBZvw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.25.5': + resolution: {integrity: sha512-WOb5fKrvVTRMfWFNCroYWWklbnXH0Q5rZppjq0vQIdlsQKuw6mdSihwSo4RV/YdQ5UCKKvBy7/0ZZYLBZKIbwQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.25.5': + resolution: {integrity: sha512-7A208+uQKgTxHd0G0uqZO8UjK2R0DDb4fDmERtARjSHWxqMTye4Erz4zZafx7Di9Cv+lNHYuncAkiGFySoD+Mw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.25.5': + resolution: {integrity: sha512-G4hE405ErTWraiZ8UiSoesH8DaCsMm0Cay4fsFWOOUcz8b8rC6uCvnagr+gnioEjWn0wC+o1/TAHt+It+MpIMg==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/sunos-x64@0.25.5': + resolution: {integrity: sha512-l+azKShMy7FxzY0Rj4RCt5VD/q8mG/e+mDivgspo+yL8zW7qEwctQ6YqKX34DTEleFAvCIUviCFX1SDZRSyMQA==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.25.5': + resolution: {integrity: sha512-O2S7SNZzdcFG7eFKgvwUEZ2VG9D/sn/eIiz8XRZ1Q/DO5a3s76Xv0mdBzVM5j5R639lXQmPmSo0iRpHqUUrsxw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.25.5': + resolution: {integrity: sha512-onOJ02pqs9h1iMJ1PQphR+VZv8qBMQ77Klcsqv9CNW2w6yLqoURLcgERAIurY6QE63bbLuqgP9ATqajFLK5AMQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.25.5': + resolution: {integrity: sha512-TXv6YnJ8ZMVdX+SXWVBo/0p8LTcrUYngpWjvm91TMjjBQii7Oz11Lw5lbDV5Y0TzuhSJHwiH4hEtC1I42mMS0g==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@eslint-community/eslint-utils@4.7.0': + resolution: {integrity: sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + + '@eslint-community/regexpp@4.12.1': + resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + '@eslint/config-array@0.20.0': + resolution: {integrity: sha512-fxlS1kkIjx8+vy2SjuCB94q3htSNrufYTXubwiBFeaQHbH6Ipi43gFJq2zCMt6PHhImH3Xmr0NksKDvchWlpQQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/config-helpers@0.2.2': + resolution: {integrity: sha512-+GPzk8PlG0sPpzdU5ZvIRMPidzAnZDl/s9L+y13iodqvb8leL53bTannOrQ/Im7UkpsmFU5Ily5U60LWixnmLg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/core@0.14.0': + resolution: {integrity: sha512-qIbV0/JZr7iSDjqAc60IqbLdsj9GDt16xQtWD+B78d/HAlvysGdZZ6rpJHGAc2T0FQx1X6thsSPdnoiGKdNtdg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/eslintrc@3.3.1': + resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/js@9.27.0': + resolution: {integrity: sha512-G5JD9Tu5HJEu4z2Uo4aHY2sLV64B7CDMXxFzqzjl3NKd6RVzSXNoE80jk7Y0lJkTTkjiIhBAqmlYwjuBY3tvpA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/object-schema@2.1.6': + resolution: {integrity: sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/plugin-kit@0.3.1': + resolution: {integrity: sha512-0J+zgWxHN+xXONWIyPWKFMgVuJoZuGiIFu8yxk7RJjxkzpGmyja5wRFqZIVtjDVOQpV+Rw0iOAjYPE2eQyjr0w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@exodus/schemasafe@1.3.0': + resolution: {integrity: sha512-5Aap/GaRupgNx/feGBwLLTVv8OQFfv3pq2lPRzPg9R+IOBnDgghTGW7l7EuVXOvg5cc/xSAlRW8rBrjIC3Nvqw==} + + '@gerrit0/mini-shiki@3.7.0': + resolution: {integrity: sha512-7iY9wg4FWXmeoFJpUL2u+tsmh0d0jcEJHAIzVxl3TG4KL493JNnisdLAILZ77zcD+z3J0keEXZ+lFzUgzQzPDg==} + + '@hookform/resolvers@5.1.1': + resolution: {integrity: sha512-J/NVING3LMAEvexJkyTLjruSm7aOFx7QX21pzkiJfMoNG0wl5aFEjLTl7ay7IQb9EWY6AkrBy7tHL2Alijpdcg==} + peerDependencies: + react-hook-form: ^7.55.0 + + '@humanfs/core@0.19.1': + resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} + engines: {node: '>=18.18.0'} + + '@humanfs/node@0.16.6': + resolution: {integrity: sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==} + engines: {node: '>=18.18.0'} + + '@humanwhocodes/module-importer@1.0.1': + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + + '@humanwhocodes/retry@0.3.1': + resolution: {integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==} + engines: {node: '>=18.18'} + + '@humanwhocodes/retry@0.4.3': + resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} + engines: {node: '>=18.18'} + + '@ibm-cloud/openapi-ruleset-utilities@1.9.0': + resolution: {integrity: sha512-AoFbSarOqFBYH+1TZ9Ahkm2IWYSi5v0pBk88fpV+5b3qGJukypX8PwvCWADjuyIccKg48/F73a6hTTkBzDQ2UA==} + engines: {node: '>=16.0.0'} + + '@ibm-cloud/openapi-ruleset@1.31.1': + resolution: {integrity: sha512-3WK2FREmDA2aadCjD71PE7tx5evyvmhg80ts1kXp2IzXIA0ZJ7guGM66tj40kxaqwpMSGchwEnnfYswntav76g==} + engines: {node: '>=16.0.0'} + + '@isaacs/fs-minipass@4.0.1': + resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} + engines: {node: '>=18.0.0'} + + '@jridgewell/gen-mapping@0.3.8': + resolution: {integrity: sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==} + engines: {node: '>=6.0.0'} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/set-array@1.2.1': + resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.5.0': + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + + '@jridgewell/trace-mapping@0.3.25': + resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + + '@jsdevtools/ono@7.1.3': + resolution: {integrity: sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==} + + '@jsep-plugin/assignment@1.3.0': + resolution: {integrity: sha512-VVgV+CXrhbMI3aSusQyclHkenWSAm95WaiKrMxRFam3JSUiIaQjoMIw2sEs/OX4XifnqeQUN4DYbJjlA8EfktQ==} + engines: {node: '>= 10.16.0'} + peerDependencies: + jsep: ^0.4.0||^1.0.0 + + '@jsep-plugin/regex@1.0.4': + resolution: {integrity: sha512-q7qL4Mgjs1vByCaTnDFcBnV9HS7GVPJX5vyVoCgZHNSC9rjwIlmbXG5sUuorR5ndfHAIlJ8pVStxvjXHbNvtUg==} + engines: {node: '>= 10.16.0'} + peerDependencies: + jsep: ^0.4.0||^1.0.0 + + '@jsep-plugin/ternary@1.1.4': + resolution: {integrity: sha512-ck5wiqIbqdMX6WRQztBL7ASDty9YLgJ3sSAK5ZpBzXeySvFGCzIvM6UiAI4hTZ22fEcYQVV/zhUbNscggW+Ukg==} + engines: {node: '>= 10.16.0'} + peerDependencies: + jsep: ^0.4.0||^1.0.0 + + '@mediapipe/tasks-vision@0.10.17': + resolution: {integrity: sha512-CZWV/q6TTe8ta61cZXjfnnHsfWIdFhms03M9T7Cnd5y2mdpylJM0rF1qRq+wsQVRMLz1OYPVEBU9ph2Bx8cxrg==} + + '@monogrid/gainmap-js@3.1.0': + resolution: {integrity: sha512-Obb0/gEd/HReTlg8ttaYk+0m62gQJmCblMOjHSMHRrBP2zdfKMHLCRbh/6ex9fSUJMKdjjIEiohwkbGD3wj2Nw==} + peerDependencies: + three: '>= 0.159.0' + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@orval/angular@7.10.0': + resolution: {integrity: sha512-M89GKo/PibxYXvOKp9+i6BLxhEW8YsO+evwuV2kMbDGNS3RiYDwzmMBcA9SVL7m8CumeZoxNEAXsupzq96ZAXA==} + + '@orval/axios@7.10.0': + resolution: {integrity: sha512-AB6BjEwyguIcH8olzOTFPvwUP8z63yP4Jfl3T2UoeFchK04KqWqxbUoxmDG9xVQ79uMs/uOrb0X+GFwdZ56gAg==} + + '@orval/core@7.10.0': + resolution: {integrity: sha512-Lm7HY4Kwzehe+2HNfi+Ov/IZ+m3nj3NskVGvOyJDAqaaHB7G/xydSCtgELG32ur4G+M/XmwChAjoP4TCNVh0VA==} + + '@orval/fetch@7.10.0': + resolution: {integrity: sha512-bWcXPmARcXhXRveBtUnkfPlkUcLEzfGaflAdqN4CtScS48LgNrXXtuyt2BV2wvEXAavCWIhnRyQvz2foTU4U8Q==} + + '@orval/hono@7.10.0': + resolution: {integrity: sha512-bOxTdZxx2BpGQf7fFuCeeUe//ZYDWc6Yz9WOhj3HrnsD06xTRKFWVBi/QZ29QcAPxqwunu/VWwbqoiHHuuX3bA==} + + '@orval/mcp@7.10.0': + resolution: {integrity: sha512-ztLXGOSxK7jFwPKAeYPR85BjKRh3KTClKEnM2MFmo2FHHojn72DPXRPCmy0Wbw5Ee+JOxK2kIpyx+HZi9XVxiA==} + + '@orval/mock@7.10.0': + resolution: {integrity: sha512-vkEWCaKEyMfWGJF5MtxVzl+blwc9vYzwdYxMoSdjA5yS2dNBrdNlt1aLtb4+aoI1jgBgpCg/OB7VtWaL5QYidA==} + + '@orval/query@7.10.0': + resolution: {integrity: sha512-DBVg8RyKWSQKhr5Zfvxx5XICUdDUkG4MJKSd4BQCrRjUWgN6vwGunMEKyfnjpS5mFUSCkwWD/I3rTkjW6aysJA==} + + '@orval/swr@7.10.0': + resolution: {integrity: sha512-ZdApomZQhJ5ZogjJgBK+haeCOP9gUaMaGKGjTVJr86jJaygDcKn54Ok1quiDUCbX42Eye+cgmQJeKeZvqnPohA==} + + '@orval/zod@7.10.0': + resolution: {integrity: sha512-AB/508IBMlVDBcGvlq+ASz7DvqU3nhoDnIeBCyjwNfQwhYzREU0qqiFBnH0XAW70c6SCMf9/bIcYbw8GAx/zxA==} + + '@radix-ui/primitive@1.1.2': + resolution: {integrity: sha512-XnbHrrprsNqZKQhStrSwgRUQzoCI1glLzdw79xiZPoofhGICeZRSQ3dIxAKH1gb3OHfNf4d6f+vAv3kil2eggA==} + + '@radix-ui/react-checkbox@1.3.2': + resolution: {integrity: sha512-yd+dI56KZqawxKZrJ31eENUwqc1QSqg4OZ15rybGjF2ZNwMO+wCyHzAVLRp9qoYJf7kYy0YpZ2b0JCzJ42HZpA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-compose-refs@1.1.2': + resolution: {integrity: sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-context@1.1.2': + resolution: {integrity: sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-presence@1.1.4': + resolution: {integrity: sha512-ueDqRbdc4/bkaQT3GIpLQssRlFgWaL/U2z/S31qRwwLWoxHLgry3SIfCwhxeQNbirEUXFa+lq3RL3oBYXtcmIA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-primitive@2.1.3': + resolution: {integrity: sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-slot@1.2.3': + resolution: {integrity: sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-switch@1.2.5': + resolution: {integrity: sha512-5ijLkak6ZMylXsaImpZ8u4Rlf5grRmoc0p0QeX9VJtlrM4f5m3nCTX8tWga/zOA8PZYIR/t0p2Mnvd7InrJ6yQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-use-controllable-state@1.2.2': + resolution: {integrity: sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-effect-event@0.0.2': + resolution: {integrity: sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-layout-effect@1.1.1': + resolution: {integrity: sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-previous@1.1.1': + resolution: {integrity: sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-size@1.1.1': + resolution: {integrity: sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@react-three/drei@10.1.2': + resolution: {integrity: sha512-CCcLAqZEvYiUErOcJgGzovY3RH6KgdrqD4ubeAx1nyGbSPLnKR9a8ynYbPdtZhIyiWqGc07z+RYQzpaOfN4ZIA==} + peerDependencies: + '@react-three/fiber': ^9.0.0 + react: ^19 + react-dom: ^19 + three: '>=0.159' + peerDependenciesMeta: + react-dom: + optional: true + + '@react-three/fiber@9.1.2': + resolution: {integrity: sha512-k8FR9yVHV9kIF3iuOD0ds5hVymXYXfgdKklqziBVod9ZEJ8uk05Zjw29J/omU3IKeUfLNAIHfxneN3TUYM4I2w==} + peerDependencies: + expo: '>=43.0' + expo-asset: '>=8.4' + expo-file-system: '>=11.0' + expo-gl: '>=11.0' + react: ^19.0.0 + react-dom: ^19.0.0 + react-native: '>=0.78' + three: '>=0.156' + peerDependenciesMeta: + expo: + optional: true + expo-asset: + optional: true + expo-file-system: + optional: true + expo-gl: + optional: true + react-dom: + optional: true + react-native: + optional: true + + '@rolldown/pluginutils@1.0.0-beta.9': + resolution: {integrity: sha512-e9MeMtVWo186sgvFFJOPGy7/d2j2mZhLJIdVW0C/xDluuOvymEATqz6zKsP0ZmXGzQtqlyjz5sC1sYQUoJG98w==} + + '@rollup/rollup-android-arm-eabi@4.41.1': + resolution: {integrity: sha512-NELNvyEWZ6R9QMkiytB4/L4zSEaBC03KIXEghptLGLZWJ6VPrL63ooZQCOnlx36aQPGhzuOMwDerC1Eb2VmrLw==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.41.1': + resolution: {integrity: sha512-DXdQe1BJ6TK47ukAoZLehRHhfKnKg9BjnQYUu9gzhI8Mwa1d2fzxA1aw2JixHVl403bwp1+/o/NhhHtxWJBgEA==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.41.1': + resolution: {integrity: sha512-5afxvwszzdulsU2w8JKWwY8/sJOLPzf0e1bFuvcW5h9zsEg+RQAojdW0ux2zyYAz7R8HvvzKCjLNJhVq965U7w==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.41.1': + resolution: {integrity: sha512-egpJACny8QOdHNNMZKf8xY0Is6gIMz+tuqXlusxquWu3F833DcMwmGM7WlvCO9sB3OsPjdC4U0wHw5FabzCGZg==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.41.1': + resolution: {integrity: sha512-DBVMZH5vbjgRk3r0OzgjS38z+atlupJ7xfKIDJdZZL6sM6wjfDNo64aowcLPKIx7LMQi8vybB56uh1Ftck/Atg==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.41.1': + resolution: {integrity: sha512-3FkydeohozEskBxNWEIbPfOE0aqQgB6ttTkJ159uWOFn42VLyfAiyD9UK5mhu+ItWzft60DycIN1Xdgiy8o/SA==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.41.1': + resolution: {integrity: sha512-wC53ZNDgt0pqx5xCAgNunkTzFE8GTgdZ9EwYGVcg+jEjJdZGtq9xPjDnFgfFozQI/Xm1mh+D9YlYtl+ueswNEg==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm-musleabihf@4.41.1': + resolution: {integrity: sha512-jwKCca1gbZkZLhLRtsrka5N8sFAaxrGz/7wRJ8Wwvq3jug7toO21vWlViihG85ei7uJTpzbXZRcORotE+xyrLA==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm64-gnu@4.41.1': + resolution: {integrity: sha512-g0UBcNknsmmNQ8V2d/zD2P7WWfJKU0F1nu0k5pW4rvdb+BIqMm8ToluW/eeRmxCared5dD76lS04uL4UaNgpNA==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-musl@4.41.1': + resolution: {integrity: sha512-XZpeGB5TKEZWzIrj7sXr+BEaSgo/ma/kCgrZgL0oo5qdB1JlTzIYQKel/RmhT6vMAvOdM2teYlAaOGJpJ9lahg==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-loongarch64-gnu@4.41.1': + resolution: {integrity: sha512-bkCfDJ4qzWfFRCNt5RVV4DOw6KEgFTUZi2r2RuYhGWC8WhCA8lCAJhDeAmrM/fdiAH54m0mA0Vk2FGRPyzI+tw==} + cpu: [loong64] + os: [linux] + + '@rollup/rollup-linux-powerpc64le-gnu@4.41.1': + resolution: {integrity: sha512-3mr3Xm+gvMX+/8EKogIZSIEF0WUu0HL9di+YWlJpO8CQBnoLAEL/roTCxuLncEdgcfJcvA4UMOf+2dnjl4Ut1A==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.41.1': + resolution: {integrity: sha512-3rwCIh6MQ1LGrvKJitQjZFuQnT2wxfU+ivhNBzmxXTXPllewOF7JR1s2vMX/tWtUYFgphygxjqMl76q4aMotGw==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-riscv64-musl@4.41.1': + resolution: {integrity: sha512-LdIUOb3gvfmpkgFZuccNa2uYiqtgZAz3PTzjuM5bH3nvuy9ty6RGc/Q0+HDFrHrizJGVpjnTZ1yS5TNNjFlklw==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-s390x-gnu@4.41.1': + resolution: {integrity: sha512-oIE6M8WC9ma6xYqjvPhzZYk6NbobIURvP/lEbh7FWplcMO6gn7MM2yHKA1eC/GvYwzNKK/1LYgqzdkZ8YFxR8g==} + cpu: [s390x] + os: [linux] + + '@rollup/rollup-linux-x64-gnu@4.41.1': + resolution: {integrity: sha512-cWBOvayNvA+SyeQMp79BHPK8ws6sHSsYnK5zDcsC3Hsxr1dgTABKjMnMslPq1DvZIp6uO7kIWhiGwaTdR4Og9A==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-musl@4.41.1': + resolution: {integrity: sha512-y5CbN44M+pUCdGDlZFzGGBSKCA4A/J2ZH4edTYSSxFg7ce1Xt3GtydbVKWLlzL+INfFIZAEg1ZV6hh9+QQf9YQ==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-win32-arm64-msvc@4.41.1': + resolution: {integrity: sha512-lZkCxIrjlJlMt1dLO/FbpZbzt6J/A8p4DnqzSa4PWqPEUUUnzXLeki/iyPLfV0BmHItlYgHUqJe+3KiyydmiNQ==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.41.1': + resolution: {integrity: sha512-+psFT9+pIh2iuGsxFYYa/LhS5MFKmuivRsx9iPJWNSGbh2XVEjk90fmpUEjCnILPEPJnikAU6SFDiEUyOv90Pg==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.41.1': + resolution: {integrity: sha512-Wq2zpapRYLfi4aKxf2Xff0tN+7slj2d4R87WEzqw7ZLsVvO5zwYCIuEGSZYiK41+GlwUo1HiR+GdkLEJnCKTCw==} + cpu: [x64] + os: [win32] + + '@shikijs/engine-oniguruma@3.7.0': + resolution: {integrity: sha512-5BxcD6LjVWsGu4xyaBC5bu8LdNgPCVBnAkWTtOCs/CZxcB22L8rcoWfv7Hh/3WooVjBZmFtyxhgvkQFedPGnFw==} + + '@shikijs/langs@3.7.0': + resolution: {integrity: sha512-1zYtdfXLr9xDKLTGy5kb7O0zDQsxXiIsw1iIBcNOO8Yi5/Y1qDbJ+0VsFoqTlzdmneO8Ij35g7QKF8kcLyznCQ==} + + '@shikijs/themes@3.7.0': + resolution: {integrity: sha512-VJx8497iZPy5zLiiCTSIaOChIcKQwR0FebwE9S3rcN0+J/GTWwQ1v/bqhTbpbY3zybPKeO8wdammqkpXc4NVjQ==} + + '@shikijs/types@3.7.0': + resolution: {integrity: sha512-MGaLeaRlSWpnP0XSAum3kP3a8vtcTsITqoEPYdt3lQG3YCdQH4DnEhodkYcNMcU0uW0RffhoD1O3e0vG5eSBBg==} + + '@shikijs/vscode-textmate@10.0.2': + resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==} + + '@standard-schema/utils@0.3.0': + resolution: {integrity: sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==} + + '@stoplight/better-ajv-errors@1.0.3': + resolution: {integrity: sha512-0p9uXkuB22qGdNfy3VeEhxkU5uwvp/KrBTAbrLBURv6ilxIVwanKwjMc41lQfIVgPGcOkmLbTolfFrSsueu7zA==} + engines: {node: ^12.20 || >= 14.13} + peerDependencies: + ajv: '>=8' + + '@stoplight/json-ref-readers@1.2.2': + resolution: {integrity: sha512-nty0tHUq2f1IKuFYsLM4CXLZGHdMn+X/IwEUIpeSOXt0QjMUbL0Em57iJUDzz+2MkWG83smIigNZ3fauGjqgdQ==} + engines: {node: '>=8.3.0'} + + '@stoplight/json-ref-resolver@3.1.6': + resolution: {integrity: sha512-YNcWv3R3n3U6iQYBsFOiWSuRGE5su1tJSiX6pAPRVk7dP0L7lqCteXGzuVRQ0gMZqUl8v1P0+fAKxF6PLo9B5A==} + engines: {node: '>=8.3.0'} + + '@stoplight/json@3.21.7': + resolution: {integrity: sha512-xcJXgKFqv/uCEgtGlPxy3tPA+4I+ZI4vAuMJ885+ThkTHFVkC+0Fm58lA9NlsyjnkpxFh4YiQWpH+KefHdbA0A==} + engines: {node: '>=8.3.0'} + + '@stoplight/ordered-object-literal@1.0.5': + resolution: {integrity: sha512-COTiuCU5bgMUtbIFBuyyh2/yVVzlr5Om0v5utQDgBCuQUOPgU1DwoffkTfg4UBQOvByi5foF4w4T+H9CoRe5wg==} + engines: {node: '>=8'} + + '@stoplight/path@1.3.2': + resolution: {integrity: sha512-lyIc6JUlUA8Ve5ELywPC8I2Sdnh1zc1zmbYgVarhXIp9YeAB0ReeqmGEOWNtlHkbP2DAA1AL65Wfn2ncjK/jtQ==} + engines: {node: '>=8'} + + '@stoplight/spectral-core@1.20.0': + resolution: {integrity: sha512-5hBP81nCC1zn1hJXL/uxPNRKNcB+/pEIHgCjPRpl/w/qy9yC9ver04tw1W0l/PMiv0UeB5dYgozXVQ4j5a6QQQ==} + engines: {node: ^16.20 || ^18.18 || >= 20.17} + + '@stoplight/spectral-formats@1.8.2': + resolution: {integrity: sha512-c06HB+rOKfe7tuxg0IdKDEA5XnjL2vrn/m/OVIIxtINtBzphZrOgtRn7epQ5bQF5SWp84Ue7UJWaGgDwVngMFw==} + engines: {node: ^16.20 || ^18.18 || >= 20.17} + + '@stoplight/spectral-functions@1.10.1': + resolution: {integrity: sha512-obu8ZfoHxELOapfGsCJixKZXZcffjg+lSoNuttpmUFuDzVLT3VmH8QkPXfOGOL5Pz80BR35ClNAToDkdnYIURg==} + engines: {node: ^16.20 || ^18.18 || >= 20.17} + + '@stoplight/spectral-parsers@1.0.5': + resolution: {integrity: sha512-ANDTp2IHWGvsQDAY85/jQi9ZrF4mRrA5bciNHX+PUxPr4DwS6iv4h+FVWJMVwcEYdpyoIdyL+SRmHdJfQEPmwQ==} + engines: {node: ^16.20 || ^18.18 || >= 20.17} + + '@stoplight/spectral-ref-resolver@1.0.5': + resolution: {integrity: sha512-gj3TieX5a9zMW29z3mBlAtDOCgN3GEc1VgZnCVlr5irmR4Qi5LuECuFItAq4pTn5Zu+sW5bqutsCH7D4PkpyAA==} + engines: {node: ^16.20 || ^18.18 || >= 20.17} + + '@stoplight/spectral-rulesets@1.22.0': + resolution: {integrity: sha512-l2EY2jiKKLsvnPfGy+pXC0LeGsbJzcQP5G/AojHgf+cwN//VYxW1Wvv4WKFx/CLmLxc42mJYF2juwWofjWYNIQ==} + engines: {node: ^16.20 || ^18.18 || >= 20.17} + + '@stoplight/spectral-runtime@1.1.4': + resolution: {integrity: sha512-YHbhX3dqW0do6DhiPSgSGQzr6yQLlWybhKwWx0cqxjMwxej3TqLv3BXMfIUYFKKUqIwH4Q2mV8rrMM8qD2N0rQ==} + engines: {node: ^16.20 || ^18.18 || >= 20.17} + + '@stoplight/types@13.20.0': + resolution: {integrity: sha512-2FNTv05If7ib79VPDA/r9eUet76jewXFH2y2K5vuge6SXbRHtWBhcaRmu+6QpF4/WRNoJj5XYRSwLGXDxysBGA==} + engines: {node: ^12.20 || >=14.13} + + '@stoplight/types@13.6.0': + resolution: {integrity: sha512-dzyuzvUjv3m1wmhPfq82lCVYGcXG0xUYgqnWfCq3PCVR4BKFhjdkHrnJ+jIDoMKvXb05AZP/ObQF6+NpDo29IQ==} + engines: {node: ^12.20 || >=14.13} + + '@stoplight/types@14.1.1': + resolution: {integrity: sha512-/kjtr+0t0tjKr+heVfviO9FrU/uGLc+QNX3fHJc19xsCNYqU7lVhaXxDmEID9BZTjG+/r9pK9xP/xU02XGg65g==} + engines: {node: ^12.20 || >=14.13} + + '@stoplight/yaml-ast-parser@0.0.50': + resolution: {integrity: sha512-Pb6M8TDO9DtSVla9yXSTAxmo9GVEouq5P40DWXdOie69bXogZTkgvopCq+yEvTMA0F6PEvdJmbtTV3ccIp11VQ==} + + '@stoplight/yaml@4.3.0': + resolution: {integrity: sha512-JZlVFE6/dYpP9tQmV0/ADfn32L9uFarHWxfcRhReKUnljz1ZiUM5zpX+PH8h5CJs6lao3TuFqnPm9IJJCEkE2w==} + engines: {node: '>=10.8'} + + '@tailwindcss/node@4.1.7': + resolution: {integrity: sha512-9rsOpdY9idRI2NH6CL4wORFY0+Q6fnx9XP9Ju+iq/0wJwGD5IByIgFmwVbyy4ymuyprj8Qh4ErxMKTUL4uNh3g==} + + '@tailwindcss/oxide-android-arm64@4.1.7': + resolution: {integrity: sha512-IWA410JZ8fF7kACus6BrUwY2Z1t1hm0+ZWNEzykKmMNM09wQooOcN/VXr0p/WJdtHZ90PvJf2AIBS/Ceqx1emg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [android] + + '@tailwindcss/oxide-darwin-arm64@4.1.7': + resolution: {integrity: sha512-81jUw9To7fimGGkuJ2W5h3/oGonTOZKZ8C2ghm/TTxbwvfSiFSDPd6/A/KE2N7Jp4mv3Ps9OFqg2fEKgZFfsvg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + + '@tailwindcss/oxide-darwin-x64@4.1.7': + resolution: {integrity: sha512-q77rWjEyGHV4PdDBtrzO0tgBBPlQWKY7wZK0cUok/HaGgbNKecegNxCGikuPJn5wFAlIywC3v+WMBt0PEBtwGw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + + '@tailwindcss/oxide-freebsd-x64@4.1.7': + resolution: {integrity: sha512-RfmdbbK6G6ptgF4qqbzoxmH+PKfP4KSVs7SRlTwcbRgBwezJkAO3Qta/7gDy10Q2DcUVkKxFLXUQO6J3CRvBGw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [freebsd] + + '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.7': + resolution: {integrity: sha512-OZqsGvpwOa13lVd1z6JVwQXadEobmesxQ4AxhrwRiPuE04quvZHWn/LnihMg7/XkN+dTioXp/VMu/p6A5eZP3g==} + engines: {node: '>= 10'} + cpu: [arm] + os: [linux] + + '@tailwindcss/oxide-linux-arm64-gnu@4.1.7': + resolution: {integrity: sha512-voMvBTnJSfKecJxGkoeAyW/2XRToLZ227LxswLAwKY7YslG/Xkw9/tJNH+3IVh5bdYzYE7DfiaPbRkSHFxY1xA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@tailwindcss/oxide-linux-arm64-musl@4.1.7': + resolution: {integrity: sha512-PjGuNNmJeKHnP58M7XyjJyla8LPo+RmwHQpBI+W/OxqrwojyuCQ+GUtygu7jUqTEexejZHr/z3nBc/gTiXBj4A==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@tailwindcss/oxide-linux-x64-gnu@4.1.7': + resolution: {integrity: sha512-HMs+Va+ZR3gC3mLZE00gXxtBo3JoSQxtu9lobbZd+DmfkIxR54NO7Z+UQNPsa0P/ITn1TevtFxXTpsRU7qEvWg==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@tailwindcss/oxide-linux-x64-musl@4.1.7': + resolution: {integrity: sha512-MHZ6jyNlutdHH8rd+YTdr3QbXrHXqwIhHw9e7yXEBcQdluGwhpQY2Eku8UZK6ReLaWtQ4gijIv5QoM5eE+qlsA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@tailwindcss/oxide-wasm32-wasi@4.1.7': + resolution: {integrity: sha512-ANaSKt74ZRzE2TvJmUcbFQ8zS201cIPxUDm5qez5rLEwWkie2SkGtA4P+GPTj+u8N6JbPrC8MtY8RmJA35Oo+A==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + bundledDependencies: + - '@napi-rs/wasm-runtime' + - '@emnapi/core' + - '@emnapi/runtime' + - '@tybys/wasm-util' + - '@emnapi/wasi-threads' + - tslib + + '@tailwindcss/oxide-win32-arm64-msvc@4.1.7': + resolution: {integrity: sha512-HUiSiXQ9gLJBAPCMVRk2RT1ZrBjto7WvqsPBwUrNK2BcdSxMnk19h4pjZjI7zgPhDxlAbJSumTC4ljeA9y0tEw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + + '@tailwindcss/oxide-win32-x64-msvc@4.1.7': + resolution: {integrity: sha512-rYHGmvoHiLJ8hWucSfSOEmdCBIGZIq7SpkPRSqLsH2Ab2YUNgKeAPT1Fi2cx3+hnYOrAb0jp9cRyode3bBW4mQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + + '@tailwindcss/oxide@4.1.7': + resolution: {integrity: sha512-5SF95Ctm9DFiUyjUPnDGkoKItPX/k+xifcQhcqX5RA85m50jw1pT/KzjdvlqxRja45Y52nR4MR9fD1JYd7f8NQ==} + engines: {node: '>= 10'} + + '@tailwindcss/vite@4.1.7': + resolution: {integrity: sha512-tYa2fO3zDe41I7WqijyVbRd8oWT0aEID1Eokz5hMT6wShLIHj3yvwj9XbfuloHP9glZ6H+aG2AN/+ZrxJ1Y5RQ==} + peerDependencies: + vite: ^5.2.0 || ^6 + + '@tanstack/query-core@5.81.5': + resolution: {integrity: sha512-ZJOgCy/z2qpZXWaj/oxvodDx07XcQa9BF92c0oINjHkoqUPsmm3uG08HpTaviviZ/N9eP1f9CM7mKSEkIo7O1Q==} + + '@tanstack/react-query@5.81.5': + resolution: {integrity: sha512-lOf2KqRRiYWpQT86eeeftAGnjuTR35myTP8MXyvHa81VlomoAWNEd8x5vkcAfQefu0qtYCvyqLropFZqgI2EQw==} + peerDependencies: + react: ^18 || ^19 + + '@tweenjs/tween.js@23.1.3': + resolution: {integrity: sha512-vJmvvwFxYuGnF2axRtPYocag6Clbb5YS7kLL+SO/TeVFzHqDIWrNKYtcsPMibjDx9O+bu+psAy9NKfWklassUA==} + + '@types/babel__core@7.20.5': + resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} + + '@types/babel__generator@7.27.0': + resolution: {integrity: sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==} + + '@types/babel__template@7.4.4': + resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} + + '@types/babel__traverse@7.20.7': + resolution: {integrity: sha512-dkO5fhS7+/oos4ciWxyEyjWe48zmG6wbCheo/G2ZnHx4fs3EU6YC6UM8rk56gAjNJ9P3MTH2jo5jb92/K6wbng==} + + '@types/draco3d@1.4.10': + resolution: {integrity: sha512-AX22jp8Y7wwaBgAixaSvkoG4M/+PlAcm3Qs4OW8yT9DM4xUpWKeFhLueTAyZF39pviAdcDdeJoACapiAceqNcw==} + + '@types/es-aggregate-error@1.0.6': + resolution: {integrity: sha512-qJ7LIFp06h1QE1aVxbVd+zJP2wdaugYXYfd6JxsyRMrYHaxb6itXPogW2tz+ylUJ1n1b+JF1PHyYCfYHm0dvUg==} + + '@types/estree@1.0.7': + resolution: {integrity: sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==} + + '@types/hast@3.0.4': + resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} + + '@types/js-cookie@3.0.6': + resolution: {integrity: sha512-wkw9yd1kEXOPnvEeEV1Go1MmxtBJL0RR79aOTAApecWFVu7w0NNXNqhcWgvw2YgZDYadliXkl14pa3WXw5jlCQ==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/moment-jalaali@0.7.9': + resolution: {integrity: sha512-gsDOoAzRnCfQTbfdlUrCvX6R0wIto6CvwfvV2C3j4qJLK+DEiTK8Rl/xlOCBO9C6qeUfX8oyZ2UfjnXJTOvHSA==} + + '@types/node@24.0.7': + resolution: {integrity: sha512-YIEUUr4yf8q8oQoXPpSlnvKNVKDQlPMWrmOcgzoduo7kvA2UF0/BwJ/eMKFTiTtkNL17I0M6Xe2tvwFU7be6iw==} + + '@types/offscreencanvas@2019.7.3': + resolution: {integrity: sha512-ieXiYmgSRXUDeOntE1InxjWyvEelZGP63M+cGuquuRLuIKKT1osnkXjxev9B7d1nXSug5vpunx+gNlbVxMlC9A==} + + '@types/quill@1.3.10': + resolution: {integrity: sha512-IhW3fPW+bkt9MLNlycw8u8fWb7oO7W5URC9MfZYHBlA24rex9rs23D5DETChu1zvgVdc5ka64ICjJOgQMr6Shw==} + + '@types/react-dom@19.1.5': + resolution: {integrity: sha512-CMCjrWucUBZvohgZxkjd6S9h0nZxXjzus6yDfUb+xLxYM7VvjKNH1tQrE9GWLql1XoOP4/Ds3bwFqShHUYraGg==} + peerDependencies: + '@types/react': ^19.0.0 + + '@types/react-reconciler@0.28.9': + resolution: {integrity: sha512-HHM3nxyUZ3zAylX8ZEyrDNd2XZOnQ0D5XfunJF5FLQnZbHHYq4UWvW1QfelQNXv1ICNkwYhfxjwfnqivYB6bFg==} + peerDependencies: + '@types/react': '*' + + '@types/react@19.1.6': + resolution: {integrity: sha512-JeG0rEWak0N6Itr6QUx+X60uQmN+5t3j9r/OVDtWzFXKaj6kD1BwJzOksD0FF6iWxZlbE1kB0q9vtnU2ekqa1Q==} + + '@types/stats.js@0.17.4': + resolution: {integrity: sha512-jIBvWWShCvlBqBNIZt0KAshWpvSjhkwkEu4ZUcASoAvhmrgAUI2t1dXrjSL4xXVLB4FznPrIsX3nKXFl/Dt4vA==} + + '@types/three@0.177.0': + resolution: {integrity: sha512-/ZAkn4OLUijKQySNci47lFO+4JLE1TihEjsGWPUT+4jWqxtwOPPEwJV1C3k5MEx0mcBPCdkFjzRzDOnHEI1R+A==} + + '@types/unist@3.0.3': + resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} + + '@types/urijs@1.19.25': + resolution: {integrity: sha512-XOfUup9r3Y06nFAZh3WvO0rBU4OtlfPB/vgxpjg+NRdGU6CN6djdc6OEiH+PcqHCY6eFLo9Ista73uarf4gnBg==} + + '@types/webxr@0.5.22': + resolution: {integrity: sha512-Vr6Stjv5jPRqH690f5I5GLjVk8GSsoQSYJ2FVd/3jJF7KaqfwPi3ehfBS96mlQ2kPCwZaX6U0rG2+NGHBKkA/A==} + + '@typescript-eslint/eslint-plugin@8.32.1': + resolution: {integrity: sha512-6u6Plg9nP/J1GRpe/vcjjabo6Uc5YQPAMxsgQyGC/I0RuukiG1wIe3+Vtg3IrSCVJDmqK3j8adrtzXSENRtFgg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + '@typescript-eslint/parser': ^8.0.0 || ^8.0.0-alpha.0 + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <5.9.0' + + '@typescript-eslint/parser@8.32.1': + resolution: {integrity: sha512-LKMrmwCPoLhM45Z00O1ulb6jwyVr2kr3XJp+G+tSEZcbauNnScewcQwtJqXDhXeYPDEjZ8C1SjXm015CirEmGg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <5.9.0' + + '@typescript-eslint/scope-manager@8.32.1': + resolution: {integrity: sha512-7IsIaIDeZn7kffk7qXC3o6Z4UblZJKV3UBpkvRNpr5NSyLji7tvTcvmnMNYuYLyh26mN8W723xpo3i4MlD33vA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/type-utils@8.32.1': + resolution: {integrity: sha512-mv9YpQGA8iIsl5KyUPi+FGLm7+bA4fgXaeRcFKRDRwDMu4iwrSHeDPipwueNXhdIIZltwCJv+NkxftECbIZWfA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <5.9.0' + + '@typescript-eslint/types@8.32.1': + resolution: {integrity: sha512-YmybwXUJcgGqgAp6bEsgpPXEg6dcCyPyCSr0CAAueacR/CCBi25G3V8gGQ2kRzQRBNol7VQknxMs9HvVa9Rvfg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/typescript-estree@8.32.1': + resolution: {integrity: sha512-Y3AP9EIfYwBb4kWGb+simvPaqQoT5oJuzzj9m0i6FCY6SPvlomY2Ei4UEMm7+FXtlNJbor80ximyslzaQF6xhg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <5.9.0' + + '@typescript-eslint/utils@8.32.1': + resolution: {integrity: sha512-DsSFNIgLSrc89gpq1LJB7Hm1YpuhK086DRDJSNrewcGvYloWW1vZLHBTIvarKZDcAORIy/uWNx8Gad+4oMpkSA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <5.9.0' + + '@typescript-eslint/visitor-keys@8.32.1': + resolution: {integrity: sha512-ar0tjQfObzhSaW3C3QNmTc5ofj0hDoNQ5XWrCy6zDyabdr0TWhCkClp+rywGNj/odAFBVzzJrK4tEq5M4Hmu4w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@use-gesture/core@10.3.1': + resolution: {integrity: sha512-WcINiDt8WjqBdUXye25anHiNxPc0VOrlT8F6LLkU6cycrOGUDyY/yyFmsg3k8i5OLvv25llc0QC45GhR/C8llw==} + + '@use-gesture/react@10.3.1': + resolution: {integrity: sha512-Yy19y6O2GJq8f7CHf7L0nxL8bf4PZCPaVOCgJrusOeFHY1LvHgYXnmnXg6N5iwAnbgbZCDjo60SiM6IPJi9C5g==} + peerDependencies: + react: '>= 16.8.0' + + '@vitejs/plugin-react@4.5.0': + resolution: {integrity: sha512-JuLWaEqypaJmOJPLWwO335Ig6jSgC1FTONCWAxnqcQthLTK/Yc9aH6hr9z/87xciejbQcnP3GnA1FWUSWeXaeg==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + vite: ^4.2.0 || ^5.0.0 || ^6.0.0 + + '@webgpu/types@0.1.61': + resolution: {integrity: sha512-w2HbBvH+qO19SB5pJOJFKs533CdZqxl3fcGonqL321VHkW7W/iBo6H8bjDy6pr/+pbMwIu5dnuaAxH7NxBqUrQ==} + + abort-controller@3.0.0: + resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} + engines: {node: '>=6.5'} + + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn@8.14.1: + resolution: {integrity: sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==} + engines: {node: '>=0.4.0'} + hasBin: true + + ajv-draft-04@1.0.0: + resolution: {integrity: sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==} + peerDependencies: + ajv: ^8.5.0 + peerDependenciesMeta: + ajv: + optional: true + + ajv-errors@3.0.0: + resolution: {integrity: sha512-V3wD15YHfHz6y0KdhYFjyy9vWtEVALT9UrxfN3zqlI6dMioHnJrqOYfyPKol3oqrnCM9uwkcdCwkJ0WUcbLMTQ==} + peerDependencies: + ajv: ^8.0.1 + + ajv-formats@2.1.1: + resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true + + ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + + ajv@8.17.1: + resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} + + ansi-colors@4.1.3: + resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} + engines: {node: '>=6'} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + array-buffer-byte-length@1.0.2: + resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==} + engines: {node: '>= 0.4'} + + array-union@2.1.0: + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} + engines: {node: '>=8'} + + arraybuffer.prototype.slice@1.0.4: + resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==} + engines: {node: '>= 0.4'} + + astring@1.9.0: + resolution: {integrity: sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==} + hasBin: true + + async-function@1.0.0: + resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} + engines: {node: '>= 0.4'} + + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + attr-accept@2.2.5: + resolution: {integrity: sha512-0bDNnY/u6pPwHDMoF0FieU354oBi0a8rD9FcsLwzcGWbc8KS8KPIi7y+s13OlVY+gMWc/9xEMUgNE6Qm8ZllYQ==} + engines: {node: '>=4'} + + available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} + engines: {node: '>= 0.4'} + + axios@1.10.0: + resolution: {integrity: sha512-/1xYAC4MP/HEG+3duIhFr4ZQXR4sQXOIe+o6sdqzeykGLx6Upp/1p8MHqhINOvGeP7xyNHe7tsiJByc4SSVUxw==} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + + bidi-js@1.0.3: + resolution: {integrity: sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==} + + brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + + brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + browserslist@4.24.5: + resolution: {integrity: sha512-FDToo4Wo82hIdgc1CQ+NQD0hEhmpPjrZ3hiUgwgOG6IuTdlpr8jdjyG24P6cNP1yJpTLzS5OcGgSw0xmDU1/Tw==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + buffer@6.0.3: + resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + + cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} + engines: {node: '>=8'} + + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + + call-bind@1.0.8: + resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==} + engines: {node: '>= 0.4'} + + call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} + + call-me-maybe@1.0.2: + resolution: {integrity: sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==} + + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + + camera-controls@2.10.1: + resolution: {integrity: sha512-KnaKdcvkBJ1Irbrzl8XD6WtZltkRjp869Jx8c0ujs9K+9WD+1D7ryBsCiVqJYUqt6i/HR5FxT7RLASieUD+Q5w==} + peerDependencies: + three: '>=0.126.1' + + caniuse-lite@1.0.30001718: + resolution: {integrity: sha512-AflseV1ahcSunK53NfEs9gFWgOEmzr0f+kaMFA4xiLZlr9Hzt7HxcSpIFcnNCUkz6R6dWKa54rUz3HUmI3nVcw==} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + chokidar@4.0.3: + resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} + engines: {node: '>= 14.16.0'} + + chownr@3.0.0: + resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==} + engines: {node: '>=18'} + + class-variance-authority@0.7.1: + resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==} + + cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + + clone@2.1.2: + resolution: {integrity: sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==} + engines: {node: '>=0.8'} + + clsx@2.1.1: + resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} + engines: {node: '>=6'} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + + compare-versions@6.1.1: + resolution: {integrity: sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + + cookie@1.0.2: + resolution: {integrity: sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==} + engines: {node: '>=18'} + + cross-env@7.0.3: + resolution: {integrity: sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==} + engines: {node: '>=10.14', npm: '>=6', yarn: '>=1'} + hasBin: true + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + csstype@3.1.3: + resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + + data-view-buffer@1.0.2: + resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==} + engines: {node: '>= 0.4'} + + data-view-byte-length@1.0.2: + resolution: {integrity: sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==} + engines: {node: '>= 0.4'} + + data-view-byte-offset@1.0.1: + resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==} + engines: {node: '>= 0.4'} + + debug@4.4.1: + resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + deep-equal@1.1.2: + resolution: {integrity: sha512-5tdhKF6DbU7iIzrIOa1AOUt39ZRm13cmL1cGEh//aqR8x9+tNfbywRf0n5FD/18OKMdo7DNEtrX2t22ZAkI+eg==} + engines: {node: '>= 0.4'} + + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + + define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} + engines: {node: '>= 0.4'} + + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + + dependency-graph@0.11.0: + resolution: {integrity: sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg==} + engines: {node: '>= 0.6.0'} + + detect-gpu@5.0.70: + resolution: {integrity: sha512-bqerEP1Ese6nt3rFkwPnGbsUF9a4q+gMmpTVVOEzoCyeCc+y7/RvJnQZJx1JwhgQI5Ntg0Kgat8Uu7XpBqnz1w==} + + detect-libc@2.0.4: + resolution: {integrity: sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==} + engines: {node: '>=8'} + + dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + + draco3d@1.5.7: + resolution: {integrity: sha512-m6WCKt/erDXcw+70IJXnG7M3awwQPAsZvJGX5zY7beBqpELw6RDGkYVU0W43AFxye4pDZ5i2Lbyc/NNGqwjUVQ==} + + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + + electron-to-chromium@1.5.158: + resolution: {integrity: sha512-9vcp2xHhkvraY6AHw2WMi+GDSLPX42qe2xjYaVoZqFRJiOcilVQFq9mZmpuHEQpzlgGDelKlV7ZiGcmMsc8WxQ==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + enhanced-resolve@5.18.1: + resolution: {integrity: sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==} + engines: {node: '>=10.13.0'} + + enquirer@2.4.1: + resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==} + engines: {node: '>=8.6'} + + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + + es-abstract@1.24.0: + resolution: {integrity: sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==} + engines: {node: '>= 0.4'} + + es-aggregate-error@1.0.14: + resolution: {integrity: sha512-3YxX6rVb07B5TV11AV5wsL7nQCHXNwoHPsQC8S4AmBiqYhyNCJ5BRKXkXyDJvs8QzXN20NgRtxe3dEEQD9NLHA==} + engines: {node: '>= 0.4'} + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-object-atoms@1.1.1: + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} + engines: {node: '>= 0.4'} + + es-set-tostringtag@2.1.0: + resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} + engines: {node: '>= 0.4'} + + es-to-primitive@1.3.0: + resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} + engines: {node: '>= 0.4'} + + es6-promise@3.3.1: + resolution: {integrity: sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==} + + esbuild@0.25.5: + resolution: {integrity: sha512-P8OtKZRv/5J5hhz0cUAdu/cLuPIKXpQl1R9pZtvmHWQvrAUVd0UNIPT4IB4W3rNOqVO0rlqHmCIbSwxh/c9yUQ==} + engines: {node: '>=18'} + hasBin: true + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + eslint-plugin-react-hooks@5.2.0: + resolution: {integrity: sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==} + engines: {node: '>=10'} + peerDependencies: + eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 + + eslint-plugin-react-refresh@0.4.20: + resolution: {integrity: sha512-XpbHQ2q5gUF8BGOX4dHe+71qoirYMhApEPZ7sfhF/dNnOF1UXnCMGZf79SFTBO7Bz5YEIT4TMieSlJBWhP9WBA==} + peerDependencies: + eslint: '>=8.40' + + eslint-scope@8.3.0: + resolution: {integrity: sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-visitor-keys@4.2.0: + resolution: {integrity: sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint@9.27.0: + resolution: {integrity: sha512-ixRawFQuMB9DZ7fjU3iGGganFDp3+45bPOdaRurcFHSXO1e/sYwUX/FtQZpLZJR6SjMoJH8hR2pPEAfDyCoU2Q==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + hasBin: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true + + espree@10.3.0: + resolution: {integrity: sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + esquery@1.6.0: + resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} + engines: {node: '>=0.10'} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + event-target-shim@5.0.1: + resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} + engines: {node: '>=6'} + + eventemitter3@2.0.3: + resolution: {integrity: sha512-jLN68Dx5kyFHaePoXWPsCGW5qdyZQtLYHkxkg02/Mz6g0kYpDx4FyP6XfArhQdlOC4b8Mv+EMxPo/8La7Tzghg==} + + eventemitter3@5.0.1: + resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} + + execa@5.1.1: + resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} + engines: {node: '>=10'} + + extend@3.0.2: + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-diff@1.1.2: + resolution: {integrity: sha512-KaJUt+M9t1qaIteSvjc6P3RbMdXsNhK61GRftR6SNxqmhthcd9MGIi4T+o0jD8LUSpSnSKXE20nLtJ3fOHxQig==} + + fast-diff@1.3.0: + resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} + + fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} + engines: {node: '>=8.6.0'} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + + fast-memoize@2.5.2: + resolution: {integrity: sha512-Ue0LwpDYErFbmNnZSF0UH6eImUwDmogUO1jyE+JbN2gsQz/jICm1Ve7t9QT0rNSsfJt+Hs4/S3GnsDVjL4HVrw==} + + fast-safe-stringify@2.1.1: + resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==} + + fast-uri@3.0.6: + resolution: {integrity: sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==} + + fastq@1.19.1: + resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} + + fdir@6.4.4: + resolution: {integrity: sha512-1NZP+GK4GfuAv3PqKvxQRDMjdSRZjnkq7KfhlNrCNNlZ0ygQFpebfrnfnq/W7fpUnAv9aGWmY1zKx7FYL3gwhg==} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + fflate@0.6.10: + resolution: {integrity: sha512-IQrh3lEPM93wVCEczc9SaAOvkmcoQn/G8Bo1e8ZPlY3X3bnAxWaBdvTdvM1hP62iZp0BXWDy4vTAy4fF0+Dlpg==} + + fflate@0.8.2: + resolution: {integrity: sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==} + + file-entry-cache@8.0.0: + resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} + engines: {node: '>=16.0.0'} + + file-selector@2.1.2: + resolution: {integrity: sha512-QgXo+mXTe8ljeqUFaX3QVHc5osSItJ/Km+xpocx0aSqWGMSCf6qYs/VnzZgS864Pjn5iceMRFigeAV7AfTlaig==} + engines: {node: '>= 12'} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + flat-cache@4.0.1: + resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} + engines: {node: '>=16'} + + flatted@3.3.3: + resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} + + follow-redirects@1.15.9: + resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + + for-each@0.3.5: + resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} + engines: {node: '>= 0.4'} + + form-data@4.0.3: + resolution: {integrity: sha512-qsITQPfmvMOSAdeyZ+12I1c+CKSstAFAwu+97zrnWAbIr5u8wfsExUzCesVLC8NgHuRUqNN4Zy6UPWUTRGslcA==} + engines: {node: '>= 6'} + + fs-extra@11.3.0: + resolution: {integrity: sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==} + engines: {node: '>=14.14'} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + function.prototype.name@1.1.8: + resolution: {integrity: sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==} + engines: {node: '>= 0.4'} + + functions-have-names@1.2.3: + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + + gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + + get-stream@6.0.1: + resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} + engines: {node: '>=10'} + + get-symbol-description@1.1.0: + resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} + engines: {node: '>= 0.4'} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + + globals@11.12.0: + resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} + engines: {node: '>=4'} + + globals@14.0.0: + resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} + engines: {node: '>=18'} + + globals@16.2.0: + resolution: {integrity: sha512-O+7l9tPdHCU320IigZZPj5zmRCFG9xHmx9cU8FqU2Rp+JN714seHV+2S9+JslCpY4gJwU2vOGox0wzgae/MCEg==} + engines: {node: '>=18'} + + globalthis@1.0.4: + resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} + engines: {node: '>= 0.4'} + + globby@11.1.0: + resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} + engines: {node: '>=10'} + + globrex@0.1.2: + resolution: {integrity: sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==} + + glsl-noise@0.0.0: + resolution: {integrity: sha512-b/ZCF6amfAUb7dJM/MxRs7AetQEahYzJ8PtgfrmEdtw6uyGOr+ZSGtgjFm6mfsBkxJ4d2W7kg+Nlqzqvn3Bc0w==} + + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + graphemer@1.4.0: + resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + + has-bigints@1.1.0: + resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==} + engines: {node: '>= 0.4'} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + + has-proto@1.2.0: + resolution: {integrity: sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==} + engines: {node: '>= 0.4'} + + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + hls.js@1.6.5: + resolution: {integrity: sha512-KMn5n7JBK+olC342740hDPHnGWfE8FiHtGMOdJPfUjRdARTWj9OB+8c13fnsf9sk1VtpuU2fKSgUjHvg4rNbzQ==} + + html-parse-stringify@3.0.1: + resolution: {integrity: sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==} + + http2-client@1.3.5: + resolution: {integrity: sha512-EC2utToWl4RKfs5zd36Mxq7nzHHBuomZboI0yYL6Y0RmBgT7Sgkq4rQ0ezFTYoIsSs7Tm9SJe+o2FcAg6GBhGA==} + + human-signals@2.1.0: + resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} + engines: {node: '>=10.17.0'} + + i18next@25.2.1: + resolution: {integrity: sha512-+UoXK5wh+VlE1Zy5p6MjcvctHXAhRwQKCxiJD8noKZzIXmnAX8gdHX5fLPA3MEVxEN4vbZkQFy8N0LyD9tUqPw==} + peerDependencies: + typescript: ^5 + peerDependenciesMeta: + typescript: + optional: true + + iconsax-react@0.0.8: + resolution: {integrity: sha512-l3dVk4zGtkkJHgvNYqAf0wDKqnKxXykee5/DoESGo2JvSYwaxajJUHSX2YrPRXSov8Hd8ClGFwJxCEaEjrFD1Q==} + peerDependencies: + react: '*' + + ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + ignore@7.0.4: + resolution: {integrity: sha512-gJzzk+PQNznz8ysRrC0aOkBNVRBDtE1n53IqyqEf3PXrYwomFs5q4pGMizBMJF+ykh03insJ27hB8gSrD2Hn8A==} + engines: {node: '>= 4'} + + immediate@3.0.6: + resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==} + + immer@9.0.21: + resolution: {integrity: sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==} + + import-fresh@3.3.1: + resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} + engines: {node: '>=6'} + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + internal-slot@1.1.0: + resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} + engines: {node: '>= 0.4'} + + is-arguments@1.2.0: + resolution: {integrity: sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==} + engines: {node: '>= 0.4'} + + is-array-buffer@3.0.5: + resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} + engines: {node: '>= 0.4'} + + is-async-function@2.1.1: + resolution: {integrity: sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==} + engines: {node: '>= 0.4'} + + is-bigint@1.1.0: + resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==} + engines: {node: '>= 0.4'} + + is-boolean-object@1.2.2: + resolution: {integrity: sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==} + engines: {node: '>= 0.4'} + + is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + + is-data-view@1.0.2: + resolution: {integrity: sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==} + engines: {node: '>= 0.4'} + + is-date-object@1.1.0: + resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==} + engines: {node: '>= 0.4'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-finalizationregistry@1.1.1: + resolution: {integrity: sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==} + engines: {node: '>= 0.4'} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-generator-function@1.1.0: + resolution: {integrity: sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==} + engines: {node: '>= 0.4'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-map@2.0.3: + resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} + engines: {node: '>= 0.4'} + + is-negative-zero@2.0.3: + resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} + engines: {node: '>= 0.4'} + + is-number-object@1.1.1: + resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==} + engines: {node: '>= 0.4'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-promise@2.2.2: + resolution: {integrity: sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==} + + is-regex@1.2.1: + resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} + engines: {node: '>= 0.4'} + + is-set@2.0.3: + resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} + engines: {node: '>= 0.4'} + + is-shared-array-buffer@1.0.4: + resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==} + engines: {node: '>= 0.4'} + + is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + + is-string@1.1.1: + resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==} + engines: {node: '>= 0.4'} + + is-symbol@1.1.1: + resolution: {integrity: sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==} + engines: {node: '>= 0.4'} + + is-typed-array@1.1.15: + resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} + engines: {node: '>= 0.4'} + + is-weakmap@2.0.2: + resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} + engines: {node: '>= 0.4'} + + is-weakref@1.1.1: + resolution: {integrity: sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==} + engines: {node: '>= 0.4'} + + is-weakset@2.0.4: + resolution: {integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==} + engines: {node: '>= 0.4'} + + isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + its-fine@2.0.0: + resolution: {integrity: sha512-KLViCmWx94zOvpLwSlsx6yOCeMhZYaxrJV87Po5k/FoZzcPSahvK5qJ7fYhS61sZi5ikmh2S3Hz55A2l3U69ng==} + peerDependencies: + react: ^19.0.0 + + jalaali-js@1.2.8: + resolution: {integrity: sha512-Jl/EwY84JwjW2wsWqeU4pNd22VNQ7EkjI36bDuLw31wH98WQW4fPjD0+mG7cdCK+Y8D6s9R3zLiQ3LaKu6bD8A==} + + jiti@2.4.2: + resolution: {integrity: sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==} + hasBin: true + + js-cookie@3.0.5: + resolution: {integrity: sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==} + engines: {node: '>=14'} + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + + jsep@1.4.0: + resolution: {integrity: sha512-B7qPcEVE3NVkmSJbaYxvv4cHkVW7DQsZz13pUMrfS8z8Q/BuShN+gcTXrUlPiGqM2/t/EEaI030bpxMqY8gMlw==} + engines: {node: '>= 10.16.0'} + + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} + hasBin: true + + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + + json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + + jsonc-parser@2.2.1: + resolution: {integrity: sha512-o6/yDBYccGvTz1+QFevz6l6OBZ2+fMVu2JZ9CIhzsYRX4mjaK5IyX9eldUdCmga16zlgQxyrj5pt9kzuj2C02w==} + + jsonfile@6.1.0: + resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + + jsonpath-plus@10.3.0: + resolution: {integrity: sha512-8TNmfeTCk2Le33A3vRRwtuworG/L5RrgMvdjhKZxvyShO+mBu2fP50OWUjRLNtvw344DdDarFh9buFAZs5ujeA==} + engines: {node: '>=18.0.0'} + hasBin: true + + jsonpointer@5.0.1: + resolution: {integrity: sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==} + engines: {node: '>=0.10.0'} + + jsonschema@1.5.0: + resolution: {integrity: sha512-K+A9hhqbn0f3pJX17Q/7H6yQfD/5OXgdrR5UE12gMXCiN9D5Xq2o5mddV2QEcX/bjla99ASsAAQUyMCCRWAEhw==} + + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + + leven@3.1.0: + resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} + engines: {node: '>=6'} + + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + + lie@3.3.0: + resolution: {integrity: sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==} + + lightningcss-darwin-arm64@1.30.1: + resolution: {integrity: sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [darwin] + + lightningcss-darwin-x64@1.30.1: + resolution: {integrity: sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [darwin] + + lightningcss-freebsd-x64@1.30.1: + resolution: {integrity: sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [freebsd] + + lightningcss-linux-arm-gnueabihf@1.30.1: + resolution: {integrity: sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q==} + engines: {node: '>= 12.0.0'} + cpu: [arm] + os: [linux] + + lightningcss-linux-arm64-gnu@1.30.1: + resolution: {integrity: sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + + lightningcss-linux-arm64-musl@1.30.1: + resolution: {integrity: sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + + lightningcss-linux-x64-gnu@1.30.1: + resolution: {integrity: sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + + lightningcss-linux-x64-musl@1.30.1: + resolution: {integrity: sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + + lightningcss-win32-arm64-msvc@1.30.1: + resolution: {integrity: sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [win32] + + lightningcss-win32-x64-msvc@1.30.1: + resolution: {integrity: sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [win32] + + lightningcss@1.30.1: + resolution: {integrity: sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg==} + engines: {node: '>= 12.0.0'} + + linkify-it@5.0.0: + resolution: {integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + lodash-es@4.17.21: + resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==} + + lodash.clonedeep@4.5.0: + resolution: {integrity: sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==} + + lodash.isempty@4.4.0: + resolution: {integrity: sha512-oKMuF3xEeqDltrGMfDxAPGIVMSSRv8tbRSODbrs4KGsRRLEhrW8N8Rd4DRgB2+621hY8A8XwwrTVhXWpxFvMzg==} + + lodash.isequal@4.5.0: + resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==} + deprecated: This package is deprecated. Use require('node:util').isDeepStrictEqual instead. + + lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + + lodash.omitby@4.6.0: + resolution: {integrity: sha512-5OrRcIVR75M288p4nbI2WLAf3ndw2GD9fyNv3Bc15+WCxJDdZ4lYndSxGd7hnG6PVjiJTeJE2dHEGhIuKGicIQ==} + + lodash.topath@4.5.2: + resolution: {integrity: sha512-1/W4dM+35DwvE/iEd1M9ekewOSTlpFekhw9mhAtrwjVqUr83/ilQiyAvmg4tVX7Unkcfl1KC+i9WdaT4B6aQcg==} + + lodash.uniq@4.5.0: + resolution: {integrity: sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==} + + lodash.uniqby@4.7.0: + resolution: {integrity: sha512-e/zcLx6CSbmaEgFHCA7BnoQKyCtKMxnuWrJygbwPs/AIn+IMKl66L8/s+wBUn5LRw2pZx3bUHibiV1b6aTWIww==} + + lodash.uniqwith@4.5.0: + resolution: {integrity: sha512-7lYL8bLopMoy4CTICbxygAUq6CdRJ36vFc80DucPueUee+d5NBRxz3FdT9Pes/HEx5mPoT9jwnsEJWz1N7uq7Q==} + + lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + + loglevel-plugin-prefix@0.8.4: + resolution: {integrity: sha512-WpG9CcFAOjz/FtNht+QJeGpvVl/cdR6P0z6OcXSkr8wFJOsV2GRj2j10JLfjuA4aYkcKCNIEqRGCyTife9R8/g==} + + loglevel@1.9.2: + resolution: {integrity: sha512-HgMmCqIJSAKqo68l0rS2AanEWfkxaZ5wNiEFb5ggm08lDs9Xl2KxBlX3PTcaD2chBM1gXAYf491/M2Rv8Jwayg==} + engines: {node: '>= 0.6.0'} + + loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + + lucide-react@0.511.0: + resolution: {integrity: sha512-VK5a2ydJ7xm8GvBeKLS9mu1pVK6ucef9780JVUjw6bAjJL/QXnd4Y0p7SPeOUMC27YhzNCZvm5d/QX0Tp3rc0w==} + peerDependencies: + react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + lunr@2.3.9: + resolution: {integrity: sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==} + + maath@0.10.8: + resolution: {integrity: sha512-tRvbDF0Pgqz+9XUa4jjfgAQ8/aPKmQdWXilFu2tMy4GWj4NOsx99HlULO4IeREfbO3a0sA145DZYyvXPkybm0g==} + peerDependencies: + '@types/three': '>=0.134.0' + three: '>=0.134.0' + + magic-string@0.30.17: + resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} + + markdown-it@14.1.0: + resolution: {integrity: sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==} + hasBin: true + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + mdurl@2.0.0: + resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==} + + merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + meshline@3.3.1: + resolution: {integrity: sha512-/TQj+JdZkeSUOl5Mk2J7eLcYTLiQm2IDzmlSvYm7ov15anEcDJ92GHqqazxTSreeNgfnYu24kiEvvv0WlbCdFQ==} + peerDependencies: + three: '>=0.137' + + meshoptimizer@0.18.1: + resolution: {integrity: sha512-ZhoIoL7TNV4s5B6+rx5mC//fw8/POGyNxS/DZyCJeiZ12ScLfVwRE/GfsxwiTkMYYD5DmK2/JXnEVXqL4rF+Sw==} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + mimic-fn@2.1.0: + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} + + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + + minimatch@6.2.0: + resolution: {integrity: sha512-sauLxniAmvnhhRjFwPNnJKaPFYyddAgbYdeUpHULtCT/GhzdCx/MDNy+Y40lBxTQUrMzDE8e0S43Z5uqfO0REg==} + engines: {node: '>=10'} + + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + engines: {node: '>=16 || 14 >=14.17'} + + minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + engines: {node: '>=16 || 14 >=14.17'} + + minizlib@3.0.2: + resolution: {integrity: sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA==} + engines: {node: '>= 18'} + + mkdirp@3.0.1: + resolution: {integrity: sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==} + engines: {node: '>=10'} + hasBin: true + + moment-jalaali@0.10.4: + resolution: {integrity: sha512-/eD0HeyvATznb5iE0G1BHjKRZAFEpJ9ZNUkcHwXhNgt1WJJVVzHD7+uDmqzZWVFLdbGme2gvIXKb3ezDYOXcZA==} + + moment-timezone@0.5.48: + resolution: {integrity: sha512-f22b8LV1gbTO2ms2j2z13MuPogNoh5UzxL3nzNAYKGraILnbGc9NEE6dyiiiLv46DGRb8A4kg8UKWLjPthxBHw==} + + moment@2.30.1: + resolution: {integrity: sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + + nimma@0.2.3: + resolution: {integrity: sha512-1ZOI8J+1PKKGceo/5CT5GfQOG6H8I2BencSK06YarZ2wXwH37BSSUWldqJmMJYA5JfqDqffxDXynt6f11AyKcA==} + engines: {node: ^12.20 || >=14.13} + + node-fetch-h2@2.3.0: + resolution: {integrity: sha512-ofRW94Ab0T4AOh5Fk8t0h8OBWrmjb0SSB20xh1H8YnPV9EJ+f5AMoYSUQ2zgJ4Iq2HAK0I2l5/Nequ8YzFS3Hg==} + engines: {node: 4.x || >=6.0.0} + + node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + + node-readfiles@0.2.0: + resolution: {integrity: sha512-SU00ZarexNlE4Rjdm83vglt5Y9yiQ+XI1XpflWlb7q7UTN1JUItm69xMeiQCTxtTfnzt+83T8Cx+vI2ED++VDA==} + + node-releases@2.0.19: + resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} + + npm-run-path@4.0.1: + resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} + engines: {node: '>=8'} + + oas-kit-common@1.0.8: + resolution: {integrity: sha512-pJTS2+T0oGIwgjGpw7sIRU8RQMcUoKCDWFLdBqKB2BNmGpbBMH2sdqAaOXUg8OzonZHU0L7vfJu1mJFEiYDWOQ==} + + oas-linter@3.2.2: + resolution: {integrity: sha512-KEGjPDVoU5K6swgo9hJVA/qYGlwfbFx+Kg2QB/kd7rzV5N8N5Mg6PlsoCMohVnQmo+pzJap/F610qTodKzecGQ==} + + oas-resolver@2.5.6: + resolution: {integrity: sha512-Yx5PWQNZomfEhPPOphFbZKi9W93CocQj18NlD2Pa4GWZzdZpSJvYwoiuurRI7m3SpcChrnO08hkuQDL3FGsVFQ==} + hasBin: true + + oas-schema-walker@1.1.5: + resolution: {integrity: sha512-2yucenq1a9YPmeNExoUa9Qwrt9RFkjqaMAA1X+U7sbb0AqBeTIdMHky9SQQ6iN94bO5NW0W4TRYXerG+BdAvAQ==} + + oas-validator@5.0.8: + resolution: {integrity: sha512-cu20/HE5N5HKqVygs3dt94eYJfBi0TsZvPVXDhbXQHiEityDN+RROTleefoKRKKJ9dFAF2JBkDHgvWj0sjKGmw==} + + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + object-inspect@1.13.4: + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} + engines: {node: '>= 0.4'} + + object-is@1.1.6: + resolution: {integrity: sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==} + engines: {node: '>= 0.4'} + + object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + + object.assign@4.1.7: + resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==} + engines: {node: '>= 0.4'} + + onetime@5.1.2: + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} + engines: {node: '>=6'} + + openapi-types@12.1.3: + resolution: {integrity: sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw==} + + openapi3-ts@4.2.2: + resolution: {integrity: sha512-+9g4actZKeb3czfi9gVQ4Br2Ju3KwhCAQJBNaKgye5KggqcBLIhFHH+nIkcm0BUX00TrAJl6dH4JWgM4G4JWrw==} + + openapi3-ts@4.4.0: + resolution: {integrity: sha512-9asTNB9IkKEzWMcHmVZE7Ts3kC9G7AFHfs8i7caD8HbI76gEjdkId4z/AkP83xdZsH7PLAnnbl47qZkXuxpArw==} + + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} + + orval@7.10.0: + resolution: {integrity: sha512-R1TlDDgK82dHfTXG0IuaIXHOrk6HQ1CuGejQQpQW9mBSCQA84AInp8U4Ovxw3upjMFNhghE8OlAQqD0ES8GgHQ==} + hasBin: true + + own-keys@1.0.1: + resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} + engines: {node: '>= 0.4'} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + + parchment@1.1.4: + resolution: {integrity: sha512-J5FBQt/pM2inLzg4hEWmzQx/8h8D0CiDxaG3vyp9rKrQRSDgBlhjdP5jQGgosEajXPSQouXGHOmVdgo7QmJuOg==} + + parchment@3.0.0: + resolution: {integrity: sha512-HUrJFQ/StvgmXRcQ1ftY6VEZUq3jA2t9ncFN4F84J/vN0/FPpQF+8FKXb3l6fLces6q0uOHj6NJn+2xvZnxO6A==} + + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + picomatch@4.0.2: + resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} + engines: {node: '>=12'} + + pony-cause@1.1.1: + resolution: {integrity: sha512-PxkIc/2ZpLiEzQXu5YRDOUgBlfGYBY8156HY5ZcRAwwonMk5W/MrJP2LLkG/hF7GEQzaHo2aS7ho6ZLCOvf+6g==} + engines: {node: '>=12.0.0'} + + possible-typed-array-names@1.1.0: + resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} + engines: {node: '>= 0.4'} + + postcss@8.5.3: + resolution: {integrity: sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==} + engines: {node: ^10 || ^12 || >=14} + + potpack@1.0.2: + resolution: {integrity: sha512-choctRBIV9EMT9WGAZHn3V7t0Z2pMQyl0EZE6pFc/6ml3ssw7Dlf/oAOvFwjm1HVsqfQN8GfeFyJ+d8tRzqueQ==} + + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + + promise-worker-transferable@1.0.4: + resolution: {integrity: sha512-bN+0ehEnrXfxV2ZQvU2PetO0n4gqBD4ulq3MI1WOPLgr7/Mg9yRQkX5+0v1vagr74ZTsl7XtzlaYDo2EuCeYJw==} + + prop-types@15.8.1: + resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + + property-expr@2.0.6: + resolution: {integrity: sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA==} + + proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + + punycode.js@2.3.1: + resolution: {integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==} + engines: {node: '>=6'} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + quill-delta@3.6.3: + resolution: {integrity: sha512-wdIGBlcX13tCHOXGMVnnTVFtGRLoP0imqxM696fIPwIf5ODIYUHIvHbZcyvGlZFiFhK5XzDC2lpjbxRhnM05Tg==} + engines: {node: '>=0.10'} + + quill-delta@5.1.0: + resolution: {integrity: sha512-X74oCeRI4/p0ucjb5Ma8adTXd9Scumz367kkMK5V/IatcX6A0vlgLgKbzXWy5nZmCGeNJm2oQX0d2Eqj+ZIlCA==} + engines: {node: '>= 12.0.0'} + + quill@1.3.7: + resolution: {integrity: sha512-hG/DVzh/TiknWtE6QmWAF/pxoZKYxfe3J/d/+ShUWkDvvkZQVTPeVmUJVu1uE6DDooC4fWTiCLh84ul89oNz5g==} + + quill@2.0.3: + resolution: {integrity: sha512-xEYQBqfYx/sfb33VJiKnSJp8ehloavImQ2A6564GAbqG55PGw1dAWUn1MUbQB62t0azawUS2CZZhWCjO8gRvTw==} + engines: {npm: '>=8.2.3'} + + react-colorful@5.6.1: + resolution: {integrity: sha512-1exovf0uGTGyq5mXQT0zgQ80uvj2PCwvF8zY1RN9/vbJVSjSo3fsB/4L3ObbF7u70NduSiK4xu4Y6q1MHoUGEw==} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' + + react-date-object@2.1.9: + resolution: {integrity: sha512-BHxD/quWOTo9fLKV/cfL/M31ePoj4a1JaJ/CnOf8Ndg3mrkh4x9wEMMkCfTrzduxDOgU8ZgR8uarhqI5G71sTg==} + + react-dom@19.1.0: + resolution: {integrity: sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==} + peerDependencies: + react: ^19.1.0 + + react-dropzone@14.3.8: + resolution: {integrity: sha512-sBgODnq+lcA4P296DY4wacOZz3JFpD99fp+hb//iBO2HHnyeZU3FwWyXJ6salNpqQdsZrgMrotuko/BdJMV8Ug==} + engines: {node: '>= 10.13'} + peerDependencies: + react: '>= 16.8 || 18.0.0' + + react-element-popper@2.1.7: + resolution: {integrity: sha512-tuM2OxKlW32h+6uFSK6EENHPeZ2OGgOipHfOAl+VLWEv9/j3QkSGbD+ADX3A9uJlmq24i37n28RjJmAbGTfpEg==} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' + + react-hook-form@7.60.0: + resolution: {integrity: sha512-SBrYOvMbDB7cV8ZfNpaiLcgjH/a1c7aK0lK+aNigpf4xWLO8q+o4tcvVurv3c4EOyzn/3dCsYt4GKD42VvJ/+A==} + engines: {node: '>=18.0.0'} + peerDependencies: + react: ^16.8.0 || ^17 || ^18 || ^19 + + react-i18next@15.5.2: + resolution: {integrity: sha512-ePODyXgmZQAOYTbZXQn5rRsSBu3Gszo69jxW6aKmlSgxKAI1fOhDwSu6bT4EKHciWPKQ7v7lPrjeiadR6Gi+1A==} + peerDependencies: + i18next: '>= 23.2.3' + react: '>= 16.8.0' + react-dom: '*' + react-native: '*' + typescript: ^5 + peerDependenciesMeta: + react-dom: + optional: true + react-native: + optional: true + typescript: + optional: true + + react-is@16.13.1: + resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + + react-loading-skeleton@3.5.0: + resolution: {integrity: sha512-gxxSyLbrEAdXTKgfbpBEFZCO/P153DnqSCQau2+o6lNy1jgMRr2MmRmOzMmyrwSaSYLRB8g7b0waYPmUjz7IhQ==} + peerDependencies: + react: '>=16.8.0' + + react-multi-date-picker@4.5.2: + resolution: {integrity: sha512-FgWjZB3Z6IA6XpcWiLPk85PwcRUhOiYhKK42o5k672gD/n2I6rzPfQ8bUrldOIiF/Z7FfOCdH7a6FeubzqteLg==} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' + + react-quill-new@3.4.6: + resolution: {integrity: sha512-S2kEAwoKRo+xUIAEpb94fwiPe2QU3FmwIfQ+7Lkchf+izPa2nRu1mr4i4QxyVYg8TjHDryDUiOEYZuFEV45QFA==} + peerDependencies: + quill-delta: ^5.1.0 + react: ^16 || ^17 || ^18 || ^19 + react-dom: ^16 || ^17 || ^18 || ^19 + + react-quill@2.0.0: + resolution: {integrity: sha512-4qQtv1FtCfLgoD3PXAur5RyxuUbPXQGOHgTlFie3jtxp43mXDtzCKaOgQ3mLyZfi1PUlyjycfivKelFhy13QUg==} + peerDependencies: + react: ^16 || ^17 || ^18 + react-dom: ^16 || ^17 || ^18 + + react-reconciler@0.31.0: + resolution: {integrity: sha512-7Ob7Z+URmesIsIVRjnLoDGwBEG/tVitidU0nMsqX/eeJaLY89RISO/10ERe0MqmzuKUUB1rmY+h1itMbUHg9BQ==} + engines: {node: '>=0.10.0'} + peerDependencies: + react: ^19.0.0 + + react-refresh@0.17.0: + resolution: {integrity: sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==} + engines: {node: '>=0.10.0'} + + react-router-dom@7.6.1: + resolution: {integrity: sha512-vxU7ei//UfPYQ3iZvHuO1D/5fX3/JOqhNTbRR+WjSBWxf9bIvpWK+ftjmdfJHzPOuMQKe2fiEdG+dZX6E8uUpA==} + engines: {node: '>=20.0.0'} + peerDependencies: + react: '>=18' + react-dom: '>=18' + + react-router@7.6.1: + resolution: {integrity: sha512-hPJXXxHJZEsPFNVbtATH7+MMX43UDeOauz+EAU4cgqTn7ojdI9qQORqS8Z0qmDlL1TclO/6jLRYUEtbWidtdHQ==} + engines: {node: '>=20.0.0'} + peerDependencies: + react: '>=18' + react-dom: '>=18' + peerDependenciesMeta: + react-dom: + optional: true + + react-spinners@0.17.0: + resolution: {integrity: sha512-L/8HTylaBmIWwQzIjMq+0vyaRXuoAevzWoD35wKpNTxxtYXWZp+xtgkfD7Y4WItuX0YvdxMPU79+7VhhmbmuTQ==} + peerDependencies: + react: ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + react-use-measure@2.1.7: + resolution: {integrity: sha512-KrvcAo13I/60HpwGO5jpW7E9DfusKyLPLvuHlUyP5zqnmAPhNc6qTRjUQrdTADl0lpPpDVU2/Gg51UlOGHXbdg==} + peerDependencies: + react: '>=16.13' + react-dom: '>=16.13' + peerDependenciesMeta: + react-dom: + optional: true + + react@19.1.0: + resolution: {integrity: sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==} + engines: {node: '>=0.10.0'} + + readdirp@4.1.2: + resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} + engines: {node: '>= 14.18.0'} + + reflect.getprototypeof@1.0.10: + resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} + engines: {node: '>= 0.4'} + + reftools@1.1.9: + resolution: {integrity: sha512-OVede/NQE13xBQ+ob5CKd5KyeJYU2YInb1bmV4nRoOfquZPkAkxuOXicSe1PvqIuZZ4kD13sPKBbR7UFDmli6w==} + + regexp.prototype.flags@1.5.4: + resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} + engines: {node: '>= 0.4'} + + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + + require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + + reusify@1.1.0: + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + rollup@4.41.1: + resolution: {integrity: sha512-cPmwD3FnFv8rKMBc1MxWCwVQFxwf1JEmSX3iQXrRVVG15zerAIXRjMFVWnd5Q5QvgKF7Aj+5ykXFhUl+QGnyOw==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + safe-array-concat@1.1.3: + resolution: {integrity: sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==} + engines: {node: '>=0.4'} + + safe-push-apply@1.0.0: + resolution: {integrity: sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==} + engines: {node: '>= 0.4'} + + safe-regex-test@1.1.0: + resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==} + engines: {node: '>= 0.4'} + + safe-stable-stringify@1.1.1: + resolution: {integrity: sha512-ERq4hUjKDbJfE4+XtZLFPCDi8Vb1JqaxAPTxWFLBx8XcAlf9Bda/ZJdVezs/NAfsMQScyIlUMx+Yeu7P7rx5jw==} + + scheduler@0.25.0: + resolution: {integrity: sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA==} + + scheduler@0.26.0: + resolution: {integrity: sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==} + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + semver@7.7.2: + resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==} + engines: {node: '>=10'} + hasBin: true + + set-cookie-parser@2.7.1: + resolution: {integrity: sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==} + + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + + set-function-name@2.0.2: + resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} + engines: {node: '>= 0.4'} + + set-proto@1.0.0: + resolution: {integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==} + engines: {node: '>= 0.4'} + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + should-equal@2.0.0: + resolution: {integrity: sha512-ZP36TMrK9euEuWQYBig9W55WPC7uo37qzAEmbjHz4gfyuXrEUgF8cUvQVO+w+d3OMfPvSRQJ22lSm8MQJ43LTA==} + + should-format@3.0.3: + resolution: {integrity: sha512-hZ58adtulAk0gKtua7QxevgUaXTTXxIi8t41L3zo9AHvjXO1/7sdLECuHeIN2SRtYXpNkmhoUP2pdeWgricQ+Q==} + + should-type-adaptors@1.1.0: + resolution: {integrity: sha512-JA4hdoLnN+kebEp2Vs8eBe9g7uy0zbRo+RMcU0EsNy+R+k049Ki+N5tT5Jagst2g7EAja+euFuoXFCa8vIklfA==} + + should-type@1.4.0: + resolution: {integrity: sha512-MdAsTu3n25yDbIe1NeN69G4n6mUnJGtSJHygX3+oN0ZbO3DTiATnf7XnYJdGT42JCXurTb1JI0qOBR65shvhPQ==} + + should-util@1.0.1: + resolution: {integrity: sha512-oXF8tfxx5cDk8r2kYqlkUJzZpDBqVY/II2WhvU0n9Y3XYvAYRmeaf1PvvIvTgPnv4KJ+ES5M0PyDq5Jp+Ygy2g==} + + should@13.2.3: + resolution: {integrity: sha512-ggLesLtu2xp+ZxI+ysJTmNjh2U0TsC+rQ/pfED9bUZZ4DKefP27D+7YJVVTvKsmjLpIi9jAa7itwDGkDDmt1GQ==} + + side-channel-list@1.0.0: + resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} + engines: {node: '>= 0.4'} + + side-channel-map@1.0.1: + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} + engines: {node: '>= 0.4'} + + side-channel-weakmap@1.0.2: + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} + engines: {node: '>= 0.4'} + + side-channel@1.1.0: + resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} + engines: {node: '>= 0.4'} + + signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + + simple-eval@1.0.1: + resolution: {integrity: sha512-LH7FpTAkeD+y5xQC4fzS+tFtaNlvt3Ib1zKzvhjv/Y+cioV4zIuw4IZr2yhRLu67CWL7FR9/6KXKnjRoZTvGGQ==} + engines: {node: '>=12'} + + slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + stats-gl@2.4.2: + resolution: {integrity: sha512-g5O9B0hm9CvnM36+v7SFl39T7hmAlv541tU81ME8YeSb3i1CIP5/QdDeSB3A0la0bKNHpxpwxOVRo2wFTYEosQ==} + peerDependencies: + '@types/three': '*' + three: '*' + + stats.js@0.17.0: + resolution: {integrity: sha512-hNKz8phvYLPEcRkeG1rsGmV5ChMjKDAWU7/OJJdDErPBNChQXxCo3WZurGpnWc6gZhAzEPFad1aVgyOANH1sMw==} + + stop-iteration-iterator@1.1.0: + resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} + engines: {node: '>= 0.4'} + + string-argv@0.3.2: + resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==} + engines: {node: '>=0.6.19'} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string.prototype.trim@1.2.10: + resolution: {integrity: sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==} + engines: {node: '>= 0.4'} + + string.prototype.trimend@1.0.9: + resolution: {integrity: sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==} + engines: {node: '>= 0.4'} + + string.prototype.trimstart@1.0.8: + resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} + engines: {node: '>= 0.4'} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-final-newline@2.0.0: + resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} + engines: {node: '>=6'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + suspend-react@0.1.3: + resolution: {integrity: sha512-aqldKgX9aZqpoDp3e8/BZ8Dm7x1pJl+qI3ZKxDN0i/IQTWUwBx/ManmlVJ3wowqbno6c2bmiIfs+Um6LbsjJyQ==} + peerDependencies: + react: '>=17.0' + + swagger2openapi@7.0.8: + resolution: {integrity: sha512-upi/0ZGkYgEcLeGieoz8gT74oWHA0E7JivX7aN9mAf+Tc7BQoRBvnIGHoPDw+f9TXTW4s6kGYCZJtauP6OYp7g==} + hasBin: true + + swiper@11.2.8: + resolution: {integrity: sha512-S5FVf6zWynPWooi7pJ7lZhSUe2snTzqLuUzbd5h5PHUOhzgvW0bLKBd2wv0ixn6/5o9vwc/IkQT74CRcLJQzeg==} + engines: {node: '>= 4.7.0'} + + tailwind-merge@3.3.0: + resolution: {integrity: sha512-fyW/pEfcQSiigd5SNn0nApUOxx0zB/dm6UDU/rEwc2c3sX2smWUNbapHv+QRqLGVp9GWX3THIa7MUGPo+YkDzQ==} + + tailwindcss@4.1.7: + resolution: {integrity: sha512-kr1o/ErIdNhTz8uzAYL7TpaUuzKIE6QPQ4qmSdxnoX/lo+5wmUHQA6h3L5yIqEImSRnAAURDirLu/BgiXGPAhg==} + + tapable@2.2.2: + resolution: {integrity: sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==} + engines: {node: '>=6'} + + tar@7.4.3: + resolution: {integrity: sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==} + engines: {node: '>=18'} + + three-mesh-bvh@0.8.3: + resolution: {integrity: sha512-4G5lBaF+g2auKX3P0yqx+MJC6oVt6sB5k+CchS6Ob0qvH0YIhuUk1eYr7ktsIpY+albCqE80/FVQGV190PmiAg==} + peerDependencies: + three: '>= 0.159.0' + + three-stdlib@2.36.0: + resolution: {integrity: sha512-kv0Byb++AXztEGsULgMAs8U2jgUdz6HPpAB/wDJnLiLlaWQX2APHhiTJIN7rqW+Of0eRgcp7jn05U1BsCP3xBA==} + peerDependencies: + three: '>=0.128.0' + + three@0.177.0: + resolution: {integrity: sha512-EiXv5/qWAaGI+Vz2A+JfavwYCMdGjxVsrn3oBwllUoqYeaBO75J63ZfyaQKoiLrqNHoTlUc6PFgMXnS0kI45zg==} + + tiny-case@1.0.3: + resolution: {integrity: sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q==} + + tinyglobby@0.2.14: + resolution: {integrity: sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==} + engines: {node: '>=12.0.0'} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + toposort@2.0.2: + resolution: {integrity: sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==} + + tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + + troika-three-text@0.52.4: + resolution: {integrity: sha512-V50EwcYGruV5rUZ9F4aNsrytGdKcXKALjEtQXIOBfhVoZU9VAqZNIoGQ3TMiooVqFAbR1w15T+f+8gkzoFzawg==} + peerDependencies: + three: '>=0.125.0' + + troika-three-utils@0.52.4: + resolution: {integrity: sha512-NORAStSVa/BDiG52Mfudk4j1FG4jC4ILutB3foPnfGbOeIs9+G5vZLa0pnmnaftZUGm4UwSoqEpWdqvC7zms3A==} + peerDependencies: + three: '>=0.125.0' + + troika-worker-utils@0.52.0: + resolution: {integrity: sha512-W1CpvTHykaPH5brv5VHLfQo9D1OYuo0cSBEUQFFT/nBUzM8iD6Lq2/tgG/f1OelbAS1WtaTPQzE5uM49egnngw==} + + ts-api-utils@2.1.0: + resolution: {integrity: sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==} + engines: {node: '>=18.12'} + peerDependencies: + typescript: '>=4.8.4' + + tsconfck@2.1.2: + resolution: {integrity: sha512-ghqN1b0puy3MhhviwO2kGF8SeMDNhEbnKxjK7h6+fvY9JAxqvXi8y5NAHSQv687OVboS2uZIByzGd45/YxrRHg==} + engines: {node: ^14.13.1 || ^16 || >=18} + hasBin: true + peerDependencies: + typescript: ^4.3.5 || ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + + tsconfck@3.1.6: + resolution: {integrity: sha512-ks6Vjr/jEw0P1gmOVwutM3B7fWxoWBL2KRDb1JfqGVawBmO5UsvmWOQFGHBPl5yxYz4eERr19E6L7NMv+Fej4w==} + engines: {node: ^18 || >=20} + hasBin: true + peerDependencies: + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + + tslib@1.14.1: + resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + tunnel-rat@0.1.2: + resolution: {integrity: sha512-lR5VHmkPhzdhrM092lI2nACsLO4QubF0/yoOhzX7c+wIpbN1GjHNzCc91QlpxBi+cnx8vVJ+Ur6vL5cEoQPFpQ==} + + tw-animate-css@1.3.0: + resolution: {integrity: sha512-jrJ0XenzS9KVuDThJDvnhalbl4IYiMQ/XvpA0a2FL8KmlK+6CSMviO7ROY/I7z1NnUs5NnDhlM6fXmF40xPxzw==} + + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + + type-fest@2.19.0: + resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==} + engines: {node: '>=12.20'} + + typed-array-buffer@1.0.3: + resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} + engines: {node: '>= 0.4'} + + typed-array-byte-length@1.0.3: + resolution: {integrity: sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==} + engines: {node: '>= 0.4'} + + typed-array-byte-offset@1.0.4: + resolution: {integrity: sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==} + engines: {node: '>= 0.4'} + + typed-array-length@1.0.7: + resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==} + engines: {node: '>= 0.4'} + + typedoc-plugin-markdown@4.7.0: + resolution: {integrity: sha512-PitbnAps2vpcqK2gargKoiFXLWFttvwUbyns/E6zGIFG5Gz8ZQJGttHnYR9csOlcSjB/uyjd8tnoayrtsXG17w==} + engines: {node: '>= 18'} + peerDependencies: + typedoc: 0.28.x + + typedoc@0.28.6: + resolution: {integrity: sha512-2VvfK6z3yupcu75qZB00LGICg4qa0lw4yPBrFcnZgqIMwpLjLWopTqNeJ4SSS/s92myvWBECY5zcOSMqpvW3CA==} + engines: {node: '>= 18', pnpm: '>= 10'} + hasBin: true + peerDependencies: + typescript: 5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x || 5.5.x || 5.6.x || 5.7.x || 5.8.x + + typescript-eslint@8.32.1: + resolution: {integrity: sha512-D7el+eaDHAmXvrZBy1zpzSNIRqnCOrkwTgZxTu3MUqRWk8k0q9m9Ho4+vPf7iHtgUfrK/o8IZaEApsxPlHTFCg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <5.9.0' + + typescript@5.7.3: + resolution: {integrity: sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==} + engines: {node: '>=14.17'} + hasBin: true + + uc.micro@2.1.0: + resolution: {integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==} + + unbox-primitive@1.1.0: + resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} + engines: {node: '>= 0.4'} + + undici-types@7.8.0: + resolution: {integrity: sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==} + + universalify@2.0.1: + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} + engines: {node: '>= 10.0.0'} + + update-browserslist-db@1.1.3: + resolution: {integrity: sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + urijs@1.19.11: + resolution: {integrity: sha512-HXgFDgDommxn5/bIv0cnQZsPhHDA90NPHD6+c/v21U5+Sx5hoP8+dP9IZXBU1gIfvdRfhG8cel9QNPeionfcCQ==} + + use-sync-external-store@1.5.0: + resolution: {integrity: sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + utility-types@3.11.0: + resolution: {integrity: sha512-6Z7Ma2aVEWisaL6TvBCy7P8rm2LQoPv6dJ7ecIaIixHcwfbJ0x7mWdbcwlIM5IGQxPZSFYeqRCqlOOeKoJYMkw==} + engines: {node: '>= 4'} + + uuid@11.1.0: + resolution: {integrity: sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==} + hasBin: true + + validator@13.15.15: + resolution: {integrity: sha512-BgWVbCI72aIQy937xbawcs+hrVaN/CZ2UwutgaJ36hGqRrLNM+f5LUT/YPRbo8IV/ASeFzXszezV+y2+rq3l8A==} + engines: {node: '>= 0.10'} + + vite-tsconfig-paths@5.1.4: + resolution: {integrity: sha512-cYj0LRuLV2c2sMqhqhGpaO3LretdtMn/BVX4cPLanIZuwwrkVl+lK84E/miEXkCHWXuq65rhNN4rXsBcOB3S4w==} + peerDependencies: + vite: '*' + peerDependenciesMeta: + vite: + optional: true + + vite@6.3.5: + resolution: {integrity: sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 + jiti: '>=1.21.0' + less: '*' + lightningcss: ^1.21.0 + sass: '*' + sass-embedded: '*' + stylus: '*' + sugarss: '*' + 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 + + void-elements@3.1.0: + resolution: {integrity: sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==} + engines: {node: '>=0.10.0'} + + webgl-constants@1.1.1: + resolution: {integrity: sha512-LkBXKjU5r9vAW7Gcu3T5u+5cvSvh5WwINdr0C+9jpzVB41cjQAP5ePArDtk/WHYdVj0GefCgM73BA7FlIiNtdg==} + + webgl-sdf-generator@1.1.1: + resolution: {integrity: sha512-9Z0JcMTFxeE+b2x1LJTdnaT8rT8aEp7MVxkNwoycNmJWwPdzoXzMh0BjJSh/AEFP+KPYZUli814h8bJZFIZ2jA==} + + webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + + whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + + which-boxed-primitive@1.1.1: + resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==} + engines: {node: '>= 0.4'} + + which-builtin-type@1.2.1: + resolution: {integrity: sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==} + engines: {node: '>= 0.4'} + + which-collection@1.0.2: + resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} + engines: {node: '>= 0.4'} + + which-typed-array@1.1.19: + resolution: {integrity: sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==} + engines: {node: '>= 0.4'} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + + yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + + yallist@5.0.0: + resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==} + engines: {node: '>=18'} + + yaml@1.10.2: + resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} + engines: {node: '>= 6'} + + yaml@2.8.0: + resolution: {integrity: sha512-4lLa/EcQCB0cJkyts+FpIRx5G/llPxfP6VQU5KByHEhLxY3IJCH0f0Hy1MHI8sClTvsIb8qwRJ6R/ZdlDJ/leQ==} + engines: {node: '>= 14.6'} + hasBin: true + + yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + + yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + + yup@1.6.1: + resolution: {integrity: sha512-JED8pB50qbA4FOkDol0bYF/p60qSEDQqBD0/qeIrUCG1KbPBIQ776fCUNb9ldbPcSTxA69g/47XTo4TqWiuXOA==} + + zustand@4.5.7: + resolution: {integrity: sha512-CHOUy7mu3lbD6o6LJLfllpjkzhHXSBlX8B9+qPddUsIfeF5S/UZ5q0kmCsnRqT1UHFQZchNFDDzMbQsuesHWlw==} + engines: {node: '>=12.7.0'} + peerDependencies: + '@types/react': '>=16.8' + immer: '>=9.0.6' + react: '>=16.8' + peerDependenciesMeta: + '@types/react': + optional: true + immer: + optional: true + react: + optional: true + + zustand@5.0.5: + resolution: {integrity: sha512-mILtRfKW9xM47hqxGIxCv12gXusoY/xTSHBYApXozR0HmQv299whhBeeAcRy+KrPPybzosvJBCOmVjq6x12fCg==} + 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 + +snapshots: + + '@ampproject/remapping@2.3.0': + dependencies: + '@jridgewell/gen-mapping': 0.3.8 + '@jridgewell/trace-mapping': 0.3.25 + + '@apidevtools/json-schema-ref-parser@11.7.2': + dependencies: + '@jsdevtools/ono': 7.1.3 + '@types/json-schema': 7.0.15 + js-yaml: 4.1.0 + + '@apidevtools/openapi-schemas@2.1.0': {} + + '@apidevtools/swagger-methods@3.0.2': {} + + '@apidevtools/swagger-parser@10.1.1(openapi-types@12.1.3)': + dependencies: + '@apidevtools/json-schema-ref-parser': 11.7.2 + '@apidevtools/openapi-schemas': 2.1.0 + '@apidevtools/swagger-methods': 3.0.2 + '@jsdevtools/ono': 7.1.3 + ajv: 8.17.1 + ajv-draft-04: 1.0.0(ajv@8.17.1) + call-me-maybe: 1.0.2 + openapi-types: 12.1.3 + + '@asyncapi/specs@6.8.1': + dependencies: + '@types/json-schema': 7.0.15 + + '@babel/code-frame@7.27.1': + dependencies: + '@babel/helper-validator-identifier': 7.27.1 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/compat-data@7.27.3': {} + + '@babel/core@7.27.3': + dependencies: + '@ampproject/remapping': 2.3.0 + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.27.3 + '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-module-transforms': 7.27.3(@babel/core@7.27.3) + '@babel/helpers': 7.27.3 + '@babel/parser': 7.27.3 + '@babel/template': 7.27.2 + '@babel/traverse': 7.27.3 + '@babel/types': 7.27.3 + convert-source-map: 2.0.0 + debug: 4.4.1 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/generator@7.27.3': + dependencies: + '@babel/parser': 7.27.3 + '@babel/types': 7.27.3 + '@jridgewell/gen-mapping': 0.3.8 + '@jridgewell/trace-mapping': 0.3.25 + jsesc: 3.1.0 + + '@babel/helper-compilation-targets@7.27.2': + dependencies: + '@babel/compat-data': 7.27.3 + '@babel/helper-validator-option': 7.27.1 + browserslist: 4.24.5 + lru-cache: 5.1.1 + semver: 6.3.1 + + '@babel/helper-module-imports@7.27.1': + dependencies: + '@babel/traverse': 7.27.3 + '@babel/types': 7.27.3 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.27.3(@babel/core@7.27.3)': + dependencies: + '@babel/core': 7.27.3 + '@babel/helper-module-imports': 7.27.1 + '@babel/helper-validator-identifier': 7.27.1 + '@babel/traverse': 7.27.3 + transitivePeerDependencies: + - supports-color + + '@babel/helper-plugin-utils@7.27.1': {} + + '@babel/helper-string-parser@7.27.1': {} + + '@babel/helper-validator-identifier@7.27.1': {} + + '@babel/helper-validator-option@7.27.1': {} + + '@babel/helpers@7.27.3': + dependencies: + '@babel/template': 7.27.2 + '@babel/types': 7.27.3 + + '@babel/parser@7.27.3': + dependencies: + '@babel/types': 7.27.3 + + '@babel/plugin-transform-react-jsx-self@7.27.1(@babel/core@7.27.3)': + dependencies: + '@babel/core': 7.27.3 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-react-jsx-source@7.27.1(@babel/core@7.27.3)': + dependencies: + '@babel/core': 7.27.3 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/runtime@7.27.3': {} + + '@babel/template@7.27.2': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/parser': 7.27.3 + '@babel/types': 7.27.3 + + '@babel/traverse@7.27.3': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.27.3 + '@babel/parser': 7.27.3 + '@babel/template': 7.27.2 + '@babel/types': 7.27.3 + debug: 4.4.1 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + + '@babel/types@7.27.3': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.27.1 + + '@dimforge/rapier3d-compat@0.12.0': {} + + '@esbuild/aix-ppc64@0.25.5': + optional: true + + '@esbuild/android-arm64@0.25.5': + optional: true + + '@esbuild/android-arm@0.25.5': + optional: true + + '@esbuild/android-x64@0.25.5': + optional: true + + '@esbuild/darwin-arm64@0.25.5': + optional: true + + '@esbuild/darwin-x64@0.25.5': + optional: true + + '@esbuild/freebsd-arm64@0.25.5': + optional: true + + '@esbuild/freebsd-x64@0.25.5': + optional: true + + '@esbuild/linux-arm64@0.25.5': + optional: true + + '@esbuild/linux-arm@0.25.5': + optional: true + + '@esbuild/linux-ia32@0.25.5': + optional: true + + '@esbuild/linux-loong64@0.25.5': + optional: true + + '@esbuild/linux-mips64el@0.25.5': + optional: true + + '@esbuild/linux-ppc64@0.25.5': + optional: true + + '@esbuild/linux-riscv64@0.25.5': + optional: true + + '@esbuild/linux-s390x@0.25.5': + optional: true + + '@esbuild/linux-x64@0.25.5': + optional: true + + '@esbuild/netbsd-arm64@0.25.5': + optional: true + + '@esbuild/netbsd-x64@0.25.5': + optional: true + + '@esbuild/openbsd-arm64@0.25.5': + optional: true + + '@esbuild/openbsd-x64@0.25.5': + optional: true + + '@esbuild/sunos-x64@0.25.5': + optional: true + + '@esbuild/win32-arm64@0.25.5': + optional: true + + '@esbuild/win32-ia32@0.25.5': + optional: true + + '@esbuild/win32-x64@0.25.5': + optional: true + + '@eslint-community/eslint-utils@4.7.0(eslint@9.27.0(jiti@2.4.2))': + dependencies: + eslint: 9.27.0(jiti@2.4.2) + eslint-visitor-keys: 3.4.3 + + '@eslint-community/regexpp@4.12.1': {} + + '@eslint/config-array@0.20.0': + dependencies: + '@eslint/object-schema': 2.1.6 + debug: 4.4.1 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + + '@eslint/config-helpers@0.2.2': {} + + '@eslint/core@0.14.0': + dependencies: + '@types/json-schema': 7.0.15 + + '@eslint/eslintrc@3.3.1': + dependencies: + ajv: 6.12.6 + debug: 4.4.1 + espree: 10.3.0 + globals: 14.0.0 + ignore: 5.3.2 + import-fresh: 3.3.1 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + '@eslint/js@9.27.0': {} + + '@eslint/object-schema@2.1.6': {} + + '@eslint/plugin-kit@0.3.1': + dependencies: + '@eslint/core': 0.14.0 + levn: 0.4.1 + + '@exodus/schemasafe@1.3.0': {} + + '@gerrit0/mini-shiki@3.7.0': + dependencies: + '@shikijs/engine-oniguruma': 3.7.0 + '@shikijs/langs': 3.7.0 + '@shikijs/themes': 3.7.0 + '@shikijs/types': 3.7.0 + '@shikijs/vscode-textmate': 10.0.2 + + '@hookform/resolvers@5.1.1(react-hook-form@7.60.0(react@19.1.0))': + dependencies: + '@standard-schema/utils': 0.3.0 + react-hook-form: 7.60.0(react@19.1.0) + + '@humanfs/core@0.19.1': {} + + '@humanfs/node@0.16.6': + dependencies: + '@humanfs/core': 0.19.1 + '@humanwhocodes/retry': 0.3.1 + + '@humanwhocodes/module-importer@1.0.1': {} + + '@humanwhocodes/retry@0.3.1': {} + + '@humanwhocodes/retry@0.4.3': {} + + '@ibm-cloud/openapi-ruleset-utilities@1.9.0': {} + + '@ibm-cloud/openapi-ruleset@1.31.1': + dependencies: + '@ibm-cloud/openapi-ruleset-utilities': 1.9.0 + '@stoplight/spectral-formats': 1.8.2 + '@stoplight/spectral-functions': 1.10.1 + '@stoplight/spectral-rulesets': 1.22.0 + chalk: 4.1.2 + jsonschema: 1.5.0 + lodash: 4.17.21 + loglevel: 1.9.2 + loglevel-plugin-prefix: 0.8.4 + minimatch: 6.2.0 + validator: 13.15.15 + transitivePeerDependencies: + - encoding + + '@isaacs/fs-minipass@4.0.1': + dependencies: + minipass: 7.1.2 + + '@jridgewell/gen-mapping@0.3.8': + dependencies: + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping': 0.3.25 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/set-array@1.2.1': {} + + '@jridgewell/sourcemap-codec@1.5.0': {} + + '@jridgewell/trace-mapping@0.3.25': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 + + '@jsdevtools/ono@7.1.3': {} + + '@jsep-plugin/assignment@1.3.0(jsep@1.4.0)': + dependencies: + jsep: 1.4.0 + + '@jsep-plugin/regex@1.0.4(jsep@1.4.0)': + dependencies: + jsep: 1.4.0 + + '@jsep-plugin/ternary@1.1.4(jsep@1.4.0)': + dependencies: + jsep: 1.4.0 + + '@mediapipe/tasks-vision@0.10.17': {} + + '@monogrid/gainmap-js@3.1.0(three@0.177.0)': + dependencies: + promise-worker-transferable: 1.0.4 + three: 0.177.0 + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.19.1 + + '@orval/angular@7.10.0(openapi-types@12.1.3)': + dependencies: + '@orval/core': 7.10.0(openapi-types@12.1.3) + transitivePeerDependencies: + - encoding + - openapi-types + - supports-color + + '@orval/axios@7.10.0(openapi-types@12.1.3)': + dependencies: + '@orval/core': 7.10.0(openapi-types@12.1.3) + transitivePeerDependencies: + - encoding + - openapi-types + - supports-color + + '@orval/core@7.10.0(openapi-types@12.1.3)': + dependencies: + '@apidevtools/swagger-parser': 10.1.1(openapi-types@12.1.3) + '@ibm-cloud/openapi-ruleset': 1.31.1 + acorn: 8.14.1 + ajv: 8.17.1 + chalk: 4.1.2 + compare-versions: 6.1.1 + debug: 4.4.1 + esbuild: 0.25.5 + esutils: 2.0.3 + fs-extra: 11.3.0 + globby: 11.1.0 + lodash.isempty: 4.4.0 + lodash.uniq: 4.5.0 + lodash.uniqby: 4.7.0 + lodash.uniqwith: 4.5.0 + micromatch: 4.0.8 + openapi3-ts: 4.4.0 + swagger2openapi: 7.0.8 + transitivePeerDependencies: + - encoding + - openapi-types + - supports-color + + '@orval/fetch@7.10.0(openapi-types@12.1.3)': + dependencies: + '@orval/core': 7.10.0(openapi-types@12.1.3) + transitivePeerDependencies: + - encoding + - openapi-types + - supports-color + + '@orval/hono@7.10.0(openapi-types@12.1.3)': + dependencies: + '@orval/core': 7.10.0(openapi-types@12.1.3) + '@orval/zod': 7.10.0(openapi-types@12.1.3) + lodash.uniq: 4.5.0 + transitivePeerDependencies: + - encoding + - openapi-types + - supports-color + + '@orval/mcp@7.10.0(openapi-types@12.1.3)': + dependencies: + '@orval/core': 7.10.0(openapi-types@12.1.3) + '@orval/zod': 7.10.0(openapi-types@12.1.3) + transitivePeerDependencies: + - encoding + - openapi-types + - supports-color + + '@orval/mock@7.10.0(openapi-types@12.1.3)': + dependencies: + '@orval/core': 7.10.0(openapi-types@12.1.3) + openapi3-ts: 4.2.2 + transitivePeerDependencies: + - encoding + - openapi-types + - supports-color + + '@orval/query@7.10.0(openapi-types@12.1.3)': + dependencies: + '@orval/core': 7.10.0(openapi-types@12.1.3) + '@orval/fetch': 7.10.0(openapi-types@12.1.3) + lodash.omitby: 4.6.0 + transitivePeerDependencies: + - encoding + - openapi-types + - supports-color + + '@orval/swr@7.10.0(openapi-types@12.1.3)': + dependencies: + '@orval/core': 7.10.0(openapi-types@12.1.3) + '@orval/fetch': 7.10.0(openapi-types@12.1.3) + transitivePeerDependencies: + - encoding + - openapi-types + - supports-color + + '@orval/zod@7.10.0(openapi-types@12.1.3)': + dependencies: + '@orval/core': 7.10.0(openapi-types@12.1.3) + lodash.uniq: 4.5.0 + transitivePeerDependencies: + - encoding + - openapi-types + - supports-color + + '@radix-ui/primitive@1.1.2': {} + + '@radix-ui/react-checkbox@1.3.2(@types/react-dom@19.1.5(@types/react@19.1.6))(@types/react@19.1.6)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/primitive': 1.1.2 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.6)(react@19.1.0) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.6)(react@19.1.0) + '@radix-ui/react-presence': 1.1.4(@types/react-dom@19.1.5(@types/react@19.1.6))(@types/react@19.1.6)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.5(@types/react@19.1.6))(@types/react@19.1.6)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.6)(react@19.1.0) + '@radix-ui/react-use-previous': 1.1.1(@types/react@19.1.6)(react@19.1.0) + '@radix-ui/react-use-size': 1.1.1(@types/react@19.1.6)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.6 + '@types/react-dom': 19.1.5(@types/react@19.1.6) + + '@radix-ui/react-compose-refs@1.1.2(@types/react@19.1.6)(react@19.1.0)': + dependencies: + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.6 + + '@radix-ui/react-context@1.1.2(@types/react@19.1.6)(react@19.1.0)': + dependencies: + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.6 + + '@radix-ui/react-presence@1.1.4(@types/react-dom@19.1.5(@types/react@19.1.6))(@types/react@19.1.6)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.6)(react@19.1.0) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.6)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.6 + '@types/react-dom': 19.1.5(@types/react@19.1.6) + + '@radix-ui/react-primitive@2.1.3(@types/react-dom@19.1.5(@types/react@19.1.6))(@types/react@19.1.6)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/react-slot': 1.2.3(@types/react@19.1.6)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.6 + '@types/react-dom': 19.1.5(@types/react@19.1.6) + + '@radix-ui/react-slot@1.2.3(@types/react@19.1.6)(react@19.1.0)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.6)(react@19.1.0) + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.6 + + '@radix-ui/react-switch@1.2.5(@types/react-dom@19.1.5(@types/react@19.1.6))(@types/react@19.1.6)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/primitive': 1.1.2 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.6)(react@19.1.0) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.6)(react@19.1.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.5(@types/react@19.1.6))(@types/react@19.1.6)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.6)(react@19.1.0) + '@radix-ui/react-use-previous': 1.1.1(@types/react@19.1.6)(react@19.1.0) + '@radix-ui/react-use-size': 1.1.1(@types/react@19.1.6)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.6 + '@types/react-dom': 19.1.5(@types/react@19.1.6) + + '@radix-ui/react-use-controllable-state@1.2.2(@types/react@19.1.6)(react@19.1.0)': + dependencies: + '@radix-ui/react-use-effect-event': 0.0.2(@types/react@19.1.6)(react@19.1.0) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.6)(react@19.1.0) + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.6 + + '@radix-ui/react-use-effect-event@0.0.2(@types/react@19.1.6)(react@19.1.0)': + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.6)(react@19.1.0) + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.6 + + '@radix-ui/react-use-layout-effect@1.1.1(@types/react@19.1.6)(react@19.1.0)': + dependencies: + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.6 + + '@radix-ui/react-use-previous@1.1.1(@types/react@19.1.6)(react@19.1.0)': + dependencies: + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.6 + + '@radix-ui/react-use-size@1.1.1(@types/react@19.1.6)(react@19.1.0)': + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.6)(react@19.1.0) + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.6 + + '@react-three/drei@10.1.2(@react-three/fiber@9.1.2(@types/react@19.1.6)(immer@9.0.21)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(three@0.177.0))(@types/react@19.1.6)(@types/three@0.177.0)(immer@9.0.21)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(three@0.177.0)': + dependencies: + '@babel/runtime': 7.27.3 + '@mediapipe/tasks-vision': 0.10.17 + '@monogrid/gainmap-js': 3.1.0(three@0.177.0) + '@react-three/fiber': 9.1.2(@types/react@19.1.6)(immer@9.0.21)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(three@0.177.0) + '@use-gesture/react': 10.3.1(react@19.1.0) + camera-controls: 2.10.1(three@0.177.0) + cross-env: 7.0.3 + detect-gpu: 5.0.70 + glsl-noise: 0.0.0 + hls.js: 1.6.5 + maath: 0.10.8(@types/three@0.177.0)(three@0.177.0) + meshline: 3.3.1(three@0.177.0) + react: 19.1.0 + stats-gl: 2.4.2(@types/three@0.177.0)(three@0.177.0) + stats.js: 0.17.0 + suspend-react: 0.1.3(react@19.1.0) + three: 0.177.0 + three-mesh-bvh: 0.8.3(three@0.177.0) + three-stdlib: 2.36.0(three@0.177.0) + troika-three-text: 0.52.4(three@0.177.0) + tunnel-rat: 0.1.2(@types/react@19.1.6)(immer@9.0.21)(react@19.1.0) + use-sync-external-store: 1.5.0(react@19.1.0) + utility-types: 3.11.0 + zustand: 5.0.5(@types/react@19.1.6)(immer@9.0.21)(react@19.1.0)(use-sync-external-store@1.5.0(react@19.1.0)) + optionalDependencies: + react-dom: 19.1.0(react@19.1.0) + transitivePeerDependencies: + - '@types/react' + - '@types/three' + - immer + + '@react-three/fiber@9.1.2(@types/react@19.1.6)(immer@9.0.21)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(three@0.177.0)': + dependencies: + '@babel/runtime': 7.27.3 + '@types/react-reconciler': 0.28.9(@types/react@19.1.6) + '@types/webxr': 0.5.22 + base64-js: 1.5.1 + buffer: 6.0.3 + its-fine: 2.0.0(@types/react@19.1.6)(react@19.1.0) + react: 19.1.0 + react-reconciler: 0.31.0(react@19.1.0) + react-use-measure: 2.1.7(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + scheduler: 0.25.0 + suspend-react: 0.1.3(react@19.1.0) + three: 0.177.0 + use-sync-external-store: 1.5.0(react@19.1.0) + zustand: 5.0.5(@types/react@19.1.6)(immer@9.0.21)(react@19.1.0)(use-sync-external-store@1.5.0(react@19.1.0)) + optionalDependencies: + react-dom: 19.1.0(react@19.1.0) + transitivePeerDependencies: + - '@types/react' + - immer + + '@rolldown/pluginutils@1.0.0-beta.9': {} + + '@rollup/rollup-android-arm-eabi@4.41.1': + optional: true + + '@rollup/rollup-android-arm64@4.41.1': + optional: true + + '@rollup/rollup-darwin-arm64@4.41.1': + optional: true + + '@rollup/rollup-darwin-x64@4.41.1': + optional: true + + '@rollup/rollup-freebsd-arm64@4.41.1': + optional: true + + '@rollup/rollup-freebsd-x64@4.41.1': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.41.1': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.41.1': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.41.1': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.41.1': + optional: true + + '@rollup/rollup-linux-loongarch64-gnu@4.41.1': + optional: true + + '@rollup/rollup-linux-powerpc64le-gnu@4.41.1': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.41.1': + optional: true + + '@rollup/rollup-linux-riscv64-musl@4.41.1': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.41.1': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.41.1': + optional: true + + '@rollup/rollup-linux-x64-musl@4.41.1': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.41.1': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.41.1': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.41.1': + optional: true + + '@shikijs/engine-oniguruma@3.7.0': + dependencies: + '@shikijs/types': 3.7.0 + '@shikijs/vscode-textmate': 10.0.2 + + '@shikijs/langs@3.7.0': + dependencies: + '@shikijs/types': 3.7.0 + + '@shikijs/themes@3.7.0': + dependencies: + '@shikijs/types': 3.7.0 + + '@shikijs/types@3.7.0': + dependencies: + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + + '@shikijs/vscode-textmate@10.0.2': {} + + '@standard-schema/utils@0.3.0': {} + + '@stoplight/better-ajv-errors@1.0.3(ajv@8.17.1)': + dependencies: + ajv: 8.17.1 + jsonpointer: 5.0.1 + leven: 3.1.0 + + '@stoplight/json-ref-readers@1.2.2': + dependencies: + node-fetch: 2.7.0 + tslib: 1.14.1 + transitivePeerDependencies: + - encoding + + '@stoplight/json-ref-resolver@3.1.6': + dependencies: + '@stoplight/json': 3.21.7 + '@stoplight/path': 1.3.2 + '@stoplight/types': 13.6.0 + '@types/urijs': 1.19.25 + dependency-graph: 0.11.0 + fast-memoize: 2.5.2 + immer: 9.0.21 + lodash: 4.17.21 + tslib: 2.8.1 + urijs: 1.19.11 + + '@stoplight/json@3.21.7': + dependencies: + '@stoplight/ordered-object-literal': 1.0.5 + '@stoplight/path': 1.3.2 + '@stoplight/types': 13.20.0 + jsonc-parser: 2.2.1 + lodash: 4.17.21 + safe-stable-stringify: 1.1.1 + + '@stoplight/ordered-object-literal@1.0.5': {} + + '@stoplight/path@1.3.2': {} + + '@stoplight/spectral-core@1.20.0': + dependencies: + '@stoplight/better-ajv-errors': 1.0.3(ajv@8.17.1) + '@stoplight/json': 3.21.7 + '@stoplight/path': 1.3.2 + '@stoplight/spectral-parsers': 1.0.5 + '@stoplight/spectral-ref-resolver': 1.0.5 + '@stoplight/spectral-runtime': 1.1.4 + '@stoplight/types': 13.6.0 + '@types/es-aggregate-error': 1.0.6 + '@types/json-schema': 7.0.15 + ajv: 8.17.1 + ajv-errors: 3.0.0(ajv@8.17.1) + ajv-formats: 2.1.1(ajv@8.17.1) + es-aggregate-error: 1.0.14 + jsonpath-plus: 10.3.0 + lodash: 4.17.21 + lodash.topath: 4.5.2 + minimatch: 3.1.2 + nimma: 0.2.3 + pony-cause: 1.1.1 + simple-eval: 1.0.1 + tslib: 2.8.1 + transitivePeerDependencies: + - encoding + + '@stoplight/spectral-formats@1.8.2': + dependencies: + '@stoplight/json': 3.21.7 + '@stoplight/spectral-core': 1.20.0 + '@types/json-schema': 7.0.15 + tslib: 2.8.1 + transitivePeerDependencies: + - encoding + + '@stoplight/spectral-functions@1.10.1': + dependencies: + '@stoplight/better-ajv-errors': 1.0.3(ajv@8.17.1) + '@stoplight/json': 3.21.7 + '@stoplight/spectral-core': 1.20.0 + '@stoplight/spectral-formats': 1.8.2 + '@stoplight/spectral-runtime': 1.1.4 + ajv: 8.17.1 + ajv-draft-04: 1.0.0(ajv@8.17.1) + ajv-errors: 3.0.0(ajv@8.17.1) + ajv-formats: 2.1.1(ajv@8.17.1) + lodash: 4.17.21 + tslib: 2.8.1 + transitivePeerDependencies: + - encoding + + '@stoplight/spectral-parsers@1.0.5': + dependencies: + '@stoplight/json': 3.21.7 + '@stoplight/types': 14.1.1 + '@stoplight/yaml': 4.3.0 + tslib: 2.8.1 + + '@stoplight/spectral-ref-resolver@1.0.5': + dependencies: + '@stoplight/json-ref-readers': 1.2.2 + '@stoplight/json-ref-resolver': 3.1.6 + '@stoplight/spectral-runtime': 1.1.4 + dependency-graph: 0.11.0 + tslib: 2.8.1 + transitivePeerDependencies: + - encoding + + '@stoplight/spectral-rulesets@1.22.0': + dependencies: + '@asyncapi/specs': 6.8.1 + '@stoplight/better-ajv-errors': 1.0.3(ajv@8.17.1) + '@stoplight/json': 3.21.7 + '@stoplight/spectral-core': 1.20.0 + '@stoplight/spectral-formats': 1.8.2 + '@stoplight/spectral-functions': 1.10.1 + '@stoplight/spectral-runtime': 1.1.4 + '@stoplight/types': 13.20.0 + '@types/json-schema': 7.0.15 + ajv: 8.17.1 + ajv-formats: 2.1.1(ajv@8.17.1) + json-schema-traverse: 1.0.0 + leven: 3.1.0 + lodash: 4.17.21 + tslib: 2.8.1 + transitivePeerDependencies: + - encoding + + '@stoplight/spectral-runtime@1.1.4': + dependencies: + '@stoplight/json': 3.21.7 + '@stoplight/path': 1.3.2 + '@stoplight/types': 13.20.0 + abort-controller: 3.0.0 + lodash: 4.17.21 + node-fetch: 2.7.0 + tslib: 2.8.1 + transitivePeerDependencies: + - encoding + + '@stoplight/types@13.20.0': + dependencies: + '@types/json-schema': 7.0.15 + utility-types: 3.11.0 + + '@stoplight/types@13.6.0': + dependencies: + '@types/json-schema': 7.0.15 + utility-types: 3.11.0 + + '@stoplight/types@14.1.1': + dependencies: + '@types/json-schema': 7.0.15 + utility-types: 3.11.0 + + '@stoplight/yaml-ast-parser@0.0.50': {} + + '@stoplight/yaml@4.3.0': + dependencies: + '@stoplight/ordered-object-literal': 1.0.5 + '@stoplight/types': 14.1.1 + '@stoplight/yaml-ast-parser': 0.0.50 + tslib: 2.8.1 + + '@tailwindcss/node@4.1.7': + dependencies: + '@ampproject/remapping': 2.3.0 + enhanced-resolve: 5.18.1 + jiti: 2.4.2 + lightningcss: 1.30.1 + magic-string: 0.30.17 + source-map-js: 1.2.1 + tailwindcss: 4.1.7 + + '@tailwindcss/oxide-android-arm64@4.1.7': + optional: true + + '@tailwindcss/oxide-darwin-arm64@4.1.7': + optional: true + + '@tailwindcss/oxide-darwin-x64@4.1.7': + optional: true + + '@tailwindcss/oxide-freebsd-x64@4.1.7': + optional: true + + '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.7': + optional: true + + '@tailwindcss/oxide-linux-arm64-gnu@4.1.7': + optional: true + + '@tailwindcss/oxide-linux-arm64-musl@4.1.7': + optional: true + + '@tailwindcss/oxide-linux-x64-gnu@4.1.7': + optional: true + + '@tailwindcss/oxide-linux-x64-musl@4.1.7': + optional: true + + '@tailwindcss/oxide-wasm32-wasi@4.1.7': + optional: true + + '@tailwindcss/oxide-win32-arm64-msvc@4.1.7': + optional: true + + '@tailwindcss/oxide-win32-x64-msvc@4.1.7': + optional: true + + '@tailwindcss/oxide@4.1.7': + dependencies: + detect-libc: 2.0.4 + tar: 7.4.3 + optionalDependencies: + '@tailwindcss/oxide-android-arm64': 4.1.7 + '@tailwindcss/oxide-darwin-arm64': 4.1.7 + '@tailwindcss/oxide-darwin-x64': 4.1.7 + '@tailwindcss/oxide-freebsd-x64': 4.1.7 + '@tailwindcss/oxide-linux-arm-gnueabihf': 4.1.7 + '@tailwindcss/oxide-linux-arm64-gnu': 4.1.7 + '@tailwindcss/oxide-linux-arm64-musl': 4.1.7 + '@tailwindcss/oxide-linux-x64-gnu': 4.1.7 + '@tailwindcss/oxide-linux-x64-musl': 4.1.7 + '@tailwindcss/oxide-wasm32-wasi': 4.1.7 + '@tailwindcss/oxide-win32-arm64-msvc': 4.1.7 + '@tailwindcss/oxide-win32-x64-msvc': 4.1.7 + + '@tailwindcss/vite@4.1.7(vite@6.3.5(@types/node@24.0.7)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0))': + dependencies: + '@tailwindcss/node': 4.1.7 + '@tailwindcss/oxide': 4.1.7 + tailwindcss: 4.1.7 + vite: 6.3.5(@types/node@24.0.7)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + + '@tanstack/query-core@5.81.5': {} + + '@tanstack/react-query@5.81.5(react@19.1.0)': + dependencies: + '@tanstack/query-core': 5.81.5 + react: 19.1.0 + + '@tweenjs/tween.js@23.1.3': {} + + '@types/babel__core@7.20.5': + dependencies: + '@babel/parser': 7.27.3 + '@babel/types': 7.27.3 + '@types/babel__generator': 7.27.0 + '@types/babel__template': 7.4.4 + '@types/babel__traverse': 7.20.7 + + '@types/babel__generator@7.27.0': + dependencies: + '@babel/types': 7.27.3 + + '@types/babel__template@7.4.4': + dependencies: + '@babel/parser': 7.27.3 + '@babel/types': 7.27.3 + + '@types/babel__traverse@7.20.7': + dependencies: + '@babel/types': 7.27.3 + + '@types/draco3d@1.4.10': {} + + '@types/es-aggregate-error@1.0.6': + dependencies: + '@types/node': 24.0.7 + + '@types/estree@1.0.7': {} + + '@types/hast@3.0.4': + dependencies: + '@types/unist': 3.0.3 + + '@types/js-cookie@3.0.6': {} + + '@types/json-schema@7.0.15': {} + + '@types/moment-jalaali@0.7.9': + dependencies: + moment: 2.30.1 + + '@types/node@24.0.7': + dependencies: + undici-types: 7.8.0 + + '@types/offscreencanvas@2019.7.3': {} + + '@types/quill@1.3.10': + dependencies: + parchment: 1.1.4 + + '@types/react-dom@19.1.5(@types/react@19.1.6)': + dependencies: + '@types/react': 19.1.6 + + '@types/react-reconciler@0.28.9(@types/react@19.1.6)': + dependencies: + '@types/react': 19.1.6 + + '@types/react@19.1.6': + dependencies: + csstype: 3.1.3 + + '@types/stats.js@0.17.4': {} + + '@types/three@0.177.0': + dependencies: + '@dimforge/rapier3d-compat': 0.12.0 + '@tweenjs/tween.js': 23.1.3 + '@types/stats.js': 0.17.4 + '@types/webxr': 0.5.22 + '@webgpu/types': 0.1.61 + fflate: 0.8.2 + meshoptimizer: 0.18.1 + + '@types/unist@3.0.3': {} + + '@types/urijs@1.19.25': {} + + '@types/webxr@0.5.22': {} + + '@typescript-eslint/eslint-plugin@8.32.1(@typescript-eslint/parser@8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.27.0(jiti@2.4.2))(typescript@5.7.3)': + dependencies: + '@eslint-community/regexpp': 4.12.1 + '@typescript-eslint/parser': 8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.7.3) + '@typescript-eslint/scope-manager': 8.32.1 + '@typescript-eslint/type-utils': 8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.7.3) + '@typescript-eslint/utils': 8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.7.3) + '@typescript-eslint/visitor-keys': 8.32.1 + eslint: 9.27.0(jiti@2.4.2) + graphemer: 1.4.0 + ignore: 7.0.4 + natural-compare: 1.4.0 + ts-api-utils: 2.1.0(typescript@5.7.3) + typescript: 5.7.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.7.3)': + dependencies: + '@typescript-eslint/scope-manager': 8.32.1 + '@typescript-eslint/types': 8.32.1 + '@typescript-eslint/typescript-estree': 8.32.1(typescript@5.7.3) + '@typescript-eslint/visitor-keys': 8.32.1 + debug: 4.4.1 + eslint: 9.27.0(jiti@2.4.2) + typescript: 5.7.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/scope-manager@8.32.1': + dependencies: + '@typescript-eslint/types': 8.32.1 + '@typescript-eslint/visitor-keys': 8.32.1 + + '@typescript-eslint/type-utils@8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.7.3)': + dependencies: + '@typescript-eslint/typescript-estree': 8.32.1(typescript@5.7.3) + '@typescript-eslint/utils': 8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.7.3) + debug: 4.4.1 + eslint: 9.27.0(jiti@2.4.2) + ts-api-utils: 2.1.0(typescript@5.7.3) + typescript: 5.7.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/types@8.32.1': {} + + '@typescript-eslint/typescript-estree@8.32.1(typescript@5.7.3)': + dependencies: + '@typescript-eslint/types': 8.32.1 + '@typescript-eslint/visitor-keys': 8.32.1 + debug: 4.4.1 + fast-glob: 3.3.3 + is-glob: 4.0.3 + minimatch: 9.0.5 + semver: 7.7.2 + ts-api-utils: 2.1.0(typescript@5.7.3) + typescript: 5.7.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.7.3)': + dependencies: + '@eslint-community/eslint-utils': 4.7.0(eslint@9.27.0(jiti@2.4.2)) + '@typescript-eslint/scope-manager': 8.32.1 + '@typescript-eslint/types': 8.32.1 + '@typescript-eslint/typescript-estree': 8.32.1(typescript@5.7.3) + eslint: 9.27.0(jiti@2.4.2) + typescript: 5.7.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/visitor-keys@8.32.1': + dependencies: + '@typescript-eslint/types': 8.32.1 + eslint-visitor-keys: 4.2.0 + + '@use-gesture/core@10.3.1': {} + + '@use-gesture/react@10.3.1(react@19.1.0)': + dependencies: + '@use-gesture/core': 10.3.1 + react: 19.1.0 + + '@vitejs/plugin-react@4.5.0(vite@6.3.5(@types/node@24.0.7)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0))': + dependencies: + '@babel/core': 7.27.3 + '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.27.3) + '@babel/plugin-transform-react-jsx-source': 7.27.1(@babel/core@7.27.3) + '@rolldown/pluginutils': 1.0.0-beta.9 + '@types/babel__core': 7.20.5 + react-refresh: 0.17.0 + vite: 6.3.5(@types/node@24.0.7)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + transitivePeerDependencies: + - supports-color + + '@webgpu/types@0.1.61': {} + + abort-controller@3.0.0: + dependencies: + event-target-shim: 5.0.1 + + acorn-jsx@5.3.2(acorn@8.14.1): + dependencies: + acorn: 8.14.1 + + acorn@8.14.1: {} + + ajv-draft-04@1.0.0(ajv@8.17.1): + optionalDependencies: + ajv: 8.17.1 + + ajv-errors@3.0.0(ajv@8.17.1): + dependencies: + ajv: 8.17.1 + + ajv-formats@2.1.1(ajv@8.17.1): + optionalDependencies: + ajv: 8.17.1 + + ajv@6.12.6: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + ajv@8.17.1: + dependencies: + fast-deep-equal: 3.1.3 + fast-uri: 3.0.6 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + + ansi-colors@4.1.3: {} + + ansi-regex@5.0.1: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + argparse@2.0.1: {} + + array-buffer-byte-length@1.0.2: + dependencies: + call-bound: 1.0.4 + is-array-buffer: 3.0.5 + + array-union@2.1.0: {} + + arraybuffer.prototype.slice@1.0.4: + dependencies: + array-buffer-byte-length: 1.0.2 + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.0 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + is-array-buffer: 3.0.5 + + astring@1.9.0: {} + + async-function@1.0.0: {} + + asynckit@0.4.0: {} + + attr-accept@2.2.5: {} + + available-typed-arrays@1.0.7: + dependencies: + possible-typed-array-names: 1.1.0 + + axios@1.10.0: + dependencies: + follow-redirects: 1.15.9 + form-data: 4.0.3 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + + balanced-match@1.0.2: {} + + base64-js@1.5.1: {} + + bidi-js@1.0.3: + dependencies: + require-from-string: 2.0.2 + + brace-expansion@1.1.11: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@2.0.1: + dependencies: + balanced-match: 1.0.2 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + browserslist@4.24.5: + dependencies: + caniuse-lite: 1.0.30001718 + electron-to-chromium: 1.5.158 + node-releases: 2.0.19 + update-browserslist-db: 1.1.3(browserslist@4.24.5) + + buffer@6.0.3: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + + cac@6.7.14: {} + + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + call-bind@1.0.8: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + get-intrinsic: 1.3.0 + set-function-length: 1.2.2 + + call-bound@1.0.4: + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + + call-me-maybe@1.0.2: {} + + callsites@3.1.0: {} + + camera-controls@2.10.1(three@0.177.0): + dependencies: + three: 0.177.0 + + caniuse-lite@1.0.30001718: {} + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + chokidar@4.0.3: + dependencies: + readdirp: 4.1.2 + + chownr@3.0.0: {} + + class-variance-authority@0.7.1: + dependencies: + clsx: 2.1.1 + + cliui@8.0.1: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + + clone@2.1.2: {} + + clsx@2.1.1: {} + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + + compare-versions@6.1.1: {} + + concat-map@0.0.1: {} + + convert-source-map@2.0.0: {} + + cookie@1.0.2: {} + + cross-env@7.0.3: + dependencies: + cross-spawn: 7.0.6 + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + csstype@3.1.3: {} + + data-view-buffer@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + data-view-byte-length@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + data-view-byte-offset@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + debug@4.4.1: + dependencies: + ms: 2.1.3 + + deep-equal@1.1.2: + dependencies: + is-arguments: 1.2.0 + is-date-object: 1.1.0 + is-regex: 1.2.1 + object-is: 1.1.6 + object-keys: 1.1.1 + regexp.prototype.flags: 1.5.4 + + deep-is@0.1.4: {} + + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.1 + es-errors: 1.3.0 + gopd: 1.2.0 + + define-properties@1.2.1: + dependencies: + define-data-property: 1.1.4 + has-property-descriptors: 1.0.2 + object-keys: 1.1.1 + + delayed-stream@1.0.0: {} + + dependency-graph@0.11.0: {} + + detect-gpu@5.0.70: + dependencies: + webgl-constants: 1.1.1 + + detect-libc@2.0.4: {} + + dir-glob@3.0.1: + dependencies: + path-type: 4.0.0 + + draco3d@1.5.7: {} + + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + electron-to-chromium@1.5.158: {} + + emoji-regex@8.0.0: {} + + enhanced-resolve@5.18.1: + dependencies: + graceful-fs: 4.2.11 + tapable: 2.2.2 + + enquirer@2.4.1: + dependencies: + ansi-colors: 4.1.3 + strip-ansi: 6.0.1 + + entities@4.5.0: {} + + es-abstract@1.24.0: + dependencies: + array-buffer-byte-length: 1.0.2 + arraybuffer.prototype.slice: 1.0.4 + available-typed-arrays: 1.0.7 + call-bind: 1.0.8 + call-bound: 1.0.4 + data-view-buffer: 1.0.2 + data-view-byte-length: 1.0.2 + data-view-byte-offset: 1.0.1 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + es-set-tostringtag: 2.1.0 + es-to-primitive: 1.3.0 + function.prototype.name: 1.1.8 + get-intrinsic: 1.3.0 + get-proto: 1.0.1 + get-symbol-description: 1.1.0 + globalthis: 1.0.4 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + has-proto: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + internal-slot: 1.1.0 + is-array-buffer: 3.0.5 + is-callable: 1.2.7 + is-data-view: 1.0.2 + is-negative-zero: 2.0.3 + is-regex: 1.2.1 + is-set: 2.0.3 + is-shared-array-buffer: 1.0.4 + is-string: 1.1.1 + is-typed-array: 1.1.15 + is-weakref: 1.1.1 + math-intrinsics: 1.1.0 + object-inspect: 1.13.4 + object-keys: 1.1.1 + object.assign: 4.1.7 + own-keys: 1.0.1 + regexp.prototype.flags: 1.5.4 + safe-array-concat: 1.1.3 + safe-push-apply: 1.0.0 + safe-regex-test: 1.1.0 + set-proto: 1.0.0 + stop-iteration-iterator: 1.1.0 + string.prototype.trim: 1.2.10 + string.prototype.trimend: 1.0.9 + string.prototype.trimstart: 1.0.8 + typed-array-buffer: 1.0.3 + typed-array-byte-length: 1.0.3 + typed-array-byte-offset: 1.0.4 + typed-array-length: 1.0.7 + unbox-primitive: 1.1.0 + which-typed-array: 1.1.19 + + es-aggregate-error@1.0.14: + dependencies: + define-data-property: 1.1.4 + define-properties: 1.2.1 + es-abstract: 1.24.0 + es-errors: 1.3.0 + function-bind: 1.1.2 + globalthis: 1.0.4 + has-property-descriptors: 1.0.2 + set-function-name: 2.0.2 + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-object-atoms@1.1.1: + dependencies: + es-errors: 1.3.0 + + es-set-tostringtag@2.1.0: + dependencies: + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + es-to-primitive@1.3.0: + dependencies: + is-callable: 1.2.7 + is-date-object: 1.1.0 + is-symbol: 1.1.1 + + es6-promise@3.3.1: {} + + esbuild@0.25.5: + optionalDependencies: + '@esbuild/aix-ppc64': 0.25.5 + '@esbuild/android-arm': 0.25.5 + '@esbuild/android-arm64': 0.25.5 + '@esbuild/android-x64': 0.25.5 + '@esbuild/darwin-arm64': 0.25.5 + '@esbuild/darwin-x64': 0.25.5 + '@esbuild/freebsd-arm64': 0.25.5 + '@esbuild/freebsd-x64': 0.25.5 + '@esbuild/linux-arm': 0.25.5 + '@esbuild/linux-arm64': 0.25.5 + '@esbuild/linux-ia32': 0.25.5 + '@esbuild/linux-loong64': 0.25.5 + '@esbuild/linux-mips64el': 0.25.5 + '@esbuild/linux-ppc64': 0.25.5 + '@esbuild/linux-riscv64': 0.25.5 + '@esbuild/linux-s390x': 0.25.5 + '@esbuild/linux-x64': 0.25.5 + '@esbuild/netbsd-arm64': 0.25.5 + '@esbuild/netbsd-x64': 0.25.5 + '@esbuild/openbsd-arm64': 0.25.5 + '@esbuild/openbsd-x64': 0.25.5 + '@esbuild/sunos-x64': 0.25.5 + '@esbuild/win32-arm64': 0.25.5 + '@esbuild/win32-ia32': 0.25.5 + '@esbuild/win32-x64': 0.25.5 + + escalade@3.2.0: {} + + escape-string-regexp@4.0.0: {} + + eslint-plugin-react-hooks@5.2.0(eslint@9.27.0(jiti@2.4.2)): + dependencies: + eslint: 9.27.0(jiti@2.4.2) + + eslint-plugin-react-refresh@0.4.20(eslint@9.27.0(jiti@2.4.2)): + dependencies: + eslint: 9.27.0(jiti@2.4.2) + + eslint-scope@8.3.0: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-visitor-keys@3.4.3: {} + + eslint-visitor-keys@4.2.0: {} + + eslint@9.27.0(jiti@2.4.2): + dependencies: + '@eslint-community/eslint-utils': 4.7.0(eslint@9.27.0(jiti@2.4.2)) + '@eslint-community/regexpp': 4.12.1 + '@eslint/config-array': 0.20.0 + '@eslint/config-helpers': 0.2.2 + '@eslint/core': 0.14.0 + '@eslint/eslintrc': 3.3.1 + '@eslint/js': 9.27.0 + '@eslint/plugin-kit': 0.3.1 + '@humanfs/node': 0.16.6 + '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.4.3 + '@types/estree': 1.0.7 + '@types/json-schema': 7.0.15 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.6 + debug: 4.4.1 + escape-string-regexp: 4.0.0 + eslint-scope: 8.3.0 + eslint-visitor-keys: 4.2.0 + espree: 10.3.0 + esquery: 1.6.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 8.0.0 + find-up: 5.0.0 + glob-parent: 6.0.2 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + json-stable-stringify-without-jsonify: 1.0.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.4 + optionalDependencies: + jiti: 2.4.2 + transitivePeerDependencies: + - supports-color + + espree@10.3.0: + dependencies: + acorn: 8.14.1 + acorn-jsx: 5.3.2(acorn@8.14.1) + eslint-visitor-keys: 4.2.0 + + esquery@1.6.0: + dependencies: + estraverse: 5.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@5.3.0: {} + + esutils@2.0.3: {} + + event-target-shim@5.0.1: {} + + eventemitter3@2.0.3: {} + + eventemitter3@5.0.1: {} + + execa@5.1.1: + dependencies: + cross-spawn: 7.0.6 + get-stream: 6.0.1 + human-signals: 2.1.0 + is-stream: 2.0.1 + merge-stream: 2.0.0 + npm-run-path: 4.0.1 + onetime: 5.1.2 + signal-exit: 3.0.7 + strip-final-newline: 2.0.0 + + extend@3.0.2: {} + + fast-deep-equal@3.1.3: {} + + fast-diff@1.1.2: {} + + fast-diff@1.3.0: {} + + fast-glob@3.3.3: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fast-json-stable-stringify@2.1.0: {} + + fast-levenshtein@2.0.6: {} + + fast-memoize@2.5.2: {} + + fast-safe-stringify@2.1.1: {} + + fast-uri@3.0.6: {} + + fastq@1.19.1: + dependencies: + reusify: 1.1.0 + + fdir@6.4.4(picomatch@4.0.2): + optionalDependencies: + picomatch: 4.0.2 + + fflate@0.6.10: {} + + fflate@0.8.2: {} + + file-entry-cache@8.0.0: + dependencies: + flat-cache: 4.0.1 + + file-selector@2.1.2: + dependencies: + tslib: 2.8.1 + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + flat-cache@4.0.1: + dependencies: + flatted: 3.3.3 + keyv: 4.5.4 + + flatted@3.3.3: {} + + follow-redirects@1.15.9: {} + + for-each@0.3.5: + dependencies: + is-callable: 1.2.7 + + form-data@4.0.3: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + es-set-tostringtag: 2.1.0 + hasown: 2.0.2 + mime-types: 2.1.35 + + fs-extra@11.3.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.1 + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + function.prototype.name@1.1.8: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + functions-have-names: 1.2.3 + hasown: 2.0.2 + is-callable: 1.2.7 + + functions-have-names@1.2.3: {} + + gensync@1.0.0-beta.2: {} + + get-caller-file@2.0.5: {} + + get-intrinsic@1.3.0: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + math-intrinsics: 1.1.0 + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 + + get-stream@6.0.1: {} + + get-symbol-description@1.1.0: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + + globals@11.12.0: {} + + globals@14.0.0: {} + + globals@16.2.0: {} + + globalthis@1.0.4: + dependencies: + define-properties: 1.2.1 + gopd: 1.2.0 + + globby@11.1.0: + dependencies: + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.3.3 + ignore: 5.3.2 + merge2: 1.4.1 + slash: 3.0.0 + + globrex@0.1.2: {} + + glsl-noise@0.0.0: {} + + gopd@1.2.0: {} + + graceful-fs@4.2.11: {} + + graphemer@1.4.0: {} + + has-bigints@1.1.0: {} + + has-flag@4.0.0: {} + + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.1 + + has-proto@1.2.0: + dependencies: + dunder-proto: 1.0.1 + + has-symbols@1.1.0: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.1.0 + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + hls.js@1.6.5: {} + + html-parse-stringify@3.0.1: + dependencies: + void-elements: 3.1.0 + + http2-client@1.3.5: {} + + human-signals@2.1.0: {} + + i18next@25.2.1(typescript@5.7.3): + dependencies: + '@babel/runtime': 7.27.3 + optionalDependencies: + typescript: 5.7.3 + + iconsax-react@0.0.8(react@19.1.0): + dependencies: + prop-types: 15.8.1 + react: 19.1.0 + + ieee754@1.2.1: {} + + ignore@5.3.2: {} + + ignore@7.0.4: {} + + immediate@3.0.6: {} + + immer@9.0.21: {} + + import-fresh@3.3.1: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + imurmurhash@0.1.4: {} + + internal-slot@1.1.0: + dependencies: + es-errors: 1.3.0 + hasown: 2.0.2 + side-channel: 1.1.0 + + is-arguments@1.2.0: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-array-buffer@3.0.5: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + + is-async-function@2.1.1: + dependencies: + async-function: 1.0.0 + call-bound: 1.0.4 + get-proto: 1.0.1 + has-tostringtag: 1.0.2 + safe-regex-test: 1.1.0 + + is-bigint@1.1.0: + dependencies: + has-bigints: 1.1.0 + + is-boolean-object@1.2.2: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-callable@1.2.7: {} + + is-data-view@1.0.2: + dependencies: + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + is-typed-array: 1.1.15 + + is-date-object@1.1.0: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-extglob@2.1.1: {} + + is-finalizationregistry@1.1.1: + dependencies: + call-bound: 1.0.4 + + is-fullwidth-code-point@3.0.0: {} + + is-generator-function@1.1.0: + dependencies: + call-bound: 1.0.4 + get-proto: 1.0.1 + has-tostringtag: 1.0.2 + safe-regex-test: 1.1.0 + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-map@2.0.3: {} + + is-negative-zero@2.0.3: {} + + is-number-object@1.1.1: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-number@7.0.0: {} + + is-promise@2.2.2: {} + + is-regex@1.2.1: + dependencies: + call-bound: 1.0.4 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + is-set@2.0.3: {} + + is-shared-array-buffer@1.0.4: + dependencies: + call-bound: 1.0.4 + + is-stream@2.0.1: {} + + is-string@1.1.1: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-symbol@1.1.1: + dependencies: + call-bound: 1.0.4 + has-symbols: 1.1.0 + safe-regex-test: 1.1.0 + + is-typed-array@1.1.15: + dependencies: + which-typed-array: 1.1.19 + + is-weakmap@2.0.2: {} + + is-weakref@1.1.1: + dependencies: + call-bound: 1.0.4 + + is-weakset@2.0.4: + dependencies: + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + + isarray@2.0.5: {} + + isexe@2.0.0: {} + + its-fine@2.0.0(@types/react@19.1.6)(react@19.1.0): + dependencies: + '@types/react-reconciler': 0.28.9(@types/react@19.1.6) + react: 19.1.0 + transitivePeerDependencies: + - '@types/react' + + jalaali-js@1.2.8: {} + + jiti@2.4.2: {} + + js-cookie@3.0.5: {} + + js-tokens@4.0.0: {} + + js-yaml@4.1.0: + dependencies: + argparse: 2.0.1 + + jsep@1.4.0: {} + + jsesc@3.1.0: {} + + json-buffer@3.0.1: {} + + json-schema-traverse@0.4.1: {} + + json-schema-traverse@1.0.0: {} + + json-stable-stringify-without-jsonify@1.0.1: {} + + json5@2.2.3: {} + + jsonc-parser@2.2.1: {} + + jsonfile@6.1.0: + dependencies: + universalify: 2.0.1 + optionalDependencies: + graceful-fs: 4.2.11 + + jsonpath-plus@10.3.0: + dependencies: + '@jsep-plugin/assignment': 1.3.0(jsep@1.4.0) + '@jsep-plugin/regex': 1.0.4(jsep@1.4.0) + jsep: 1.4.0 + + jsonpointer@5.0.1: {} + + jsonschema@1.5.0: {} + + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + + leven@3.1.0: {} + + levn@0.4.1: + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + + lie@3.3.0: + dependencies: + immediate: 3.0.6 + + lightningcss-darwin-arm64@1.30.1: + optional: true + + lightningcss-darwin-x64@1.30.1: + optional: true + + lightningcss-freebsd-x64@1.30.1: + optional: true + + lightningcss-linux-arm-gnueabihf@1.30.1: + optional: true + + lightningcss-linux-arm64-gnu@1.30.1: + optional: true + + lightningcss-linux-arm64-musl@1.30.1: + optional: true + + lightningcss-linux-x64-gnu@1.30.1: + optional: true + + lightningcss-linux-x64-musl@1.30.1: + optional: true + + lightningcss-win32-arm64-msvc@1.30.1: + optional: true + + lightningcss-win32-x64-msvc@1.30.1: + optional: true + + lightningcss@1.30.1: + dependencies: + detect-libc: 2.0.4 + optionalDependencies: + lightningcss-darwin-arm64: 1.30.1 + lightningcss-darwin-x64: 1.30.1 + lightningcss-freebsd-x64: 1.30.1 + lightningcss-linux-arm-gnueabihf: 1.30.1 + lightningcss-linux-arm64-gnu: 1.30.1 + lightningcss-linux-arm64-musl: 1.30.1 + lightningcss-linux-x64-gnu: 1.30.1 + lightningcss-linux-x64-musl: 1.30.1 + lightningcss-win32-arm64-msvc: 1.30.1 + lightningcss-win32-x64-msvc: 1.30.1 + + linkify-it@5.0.0: + dependencies: + uc.micro: 2.1.0 + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + lodash-es@4.17.21: {} + + lodash.clonedeep@4.5.0: {} + + lodash.isempty@4.4.0: {} + + lodash.isequal@4.5.0: {} + + lodash.merge@4.6.2: {} + + lodash.omitby@4.6.0: {} + + lodash.topath@4.5.2: {} + + lodash.uniq@4.5.0: {} + + lodash.uniqby@4.7.0: {} + + lodash.uniqwith@4.5.0: {} + + lodash@4.17.21: {} + + loglevel-plugin-prefix@0.8.4: {} + + loglevel@1.9.2: {} + + loose-envify@1.4.0: + dependencies: + js-tokens: 4.0.0 + + lru-cache@5.1.1: + dependencies: + yallist: 3.1.1 + + lucide-react@0.511.0(react@19.1.0): + dependencies: + react: 19.1.0 + + lunr@2.3.9: {} + + maath@0.10.8(@types/three@0.177.0)(three@0.177.0): + dependencies: + '@types/three': 0.177.0 + three: 0.177.0 + + magic-string@0.30.17: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.0 + + markdown-it@14.1.0: + dependencies: + argparse: 2.0.1 + entities: 4.5.0 + linkify-it: 5.0.0 + mdurl: 2.0.0 + punycode.js: 2.3.1 + uc.micro: 2.1.0 + + math-intrinsics@1.1.0: {} + + mdurl@2.0.0: {} + + merge-stream@2.0.0: {} + + merge2@1.4.1: {} + + meshline@3.3.1(three@0.177.0): + dependencies: + three: 0.177.0 + + meshoptimizer@0.18.1: {} + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + + mime-db@1.52.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + mimic-fn@2.1.0: {} + + minimatch@3.1.2: + dependencies: + brace-expansion: 1.1.11 + + minimatch@6.2.0: + dependencies: + brace-expansion: 2.0.1 + + minimatch@9.0.5: + dependencies: + brace-expansion: 2.0.1 + + minipass@7.1.2: {} + + minizlib@3.0.2: + dependencies: + minipass: 7.1.2 + + mkdirp@3.0.1: {} + + moment-jalaali@0.10.4: + dependencies: + jalaali-js: 1.2.8 + moment: 2.30.1 + moment-timezone: 0.5.48 + + moment-timezone@0.5.48: + dependencies: + moment: 2.30.1 + + moment@2.30.1: {} + + ms@2.1.3: {} + + nanoid@3.3.11: {} + + natural-compare@1.4.0: {} + + nimma@0.2.3: + dependencies: + '@jsep-plugin/regex': 1.0.4(jsep@1.4.0) + '@jsep-plugin/ternary': 1.1.4(jsep@1.4.0) + astring: 1.9.0 + jsep: 1.4.0 + optionalDependencies: + jsonpath-plus: 10.3.0 + lodash.topath: 4.5.2 + + node-fetch-h2@2.3.0: + dependencies: + http2-client: 1.3.5 + + node-fetch@2.7.0: + dependencies: + whatwg-url: 5.0.0 + + node-readfiles@0.2.0: + dependencies: + es6-promise: 3.3.1 + + node-releases@2.0.19: {} + + npm-run-path@4.0.1: + dependencies: + path-key: 3.1.1 + + oas-kit-common@1.0.8: + dependencies: + fast-safe-stringify: 2.1.1 + + oas-linter@3.2.2: + dependencies: + '@exodus/schemasafe': 1.3.0 + should: 13.2.3 + yaml: 1.10.2 + + oas-resolver@2.5.6: + dependencies: + node-fetch-h2: 2.3.0 + oas-kit-common: 1.0.8 + reftools: 1.1.9 + yaml: 1.10.2 + yargs: 17.7.2 + + oas-schema-walker@1.1.5: {} + + oas-validator@5.0.8: + dependencies: + call-me-maybe: 1.0.2 + oas-kit-common: 1.0.8 + oas-linter: 3.2.2 + oas-resolver: 2.5.6 + oas-schema-walker: 1.1.5 + reftools: 1.1.9 + should: 13.2.3 + yaml: 1.10.2 + + object-assign@4.1.1: {} + + object-inspect@1.13.4: {} + + object-is@1.1.6: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + + object-keys@1.1.1: {} + + object.assign@4.1.7: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + has-symbols: 1.1.0 + object-keys: 1.1.1 + + onetime@5.1.2: + dependencies: + mimic-fn: 2.1.0 + + openapi-types@12.1.3: {} + + openapi3-ts@4.2.2: + dependencies: + yaml: 2.8.0 + + openapi3-ts@4.4.0: + dependencies: + yaml: 2.8.0 + + optionator@0.9.4: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.5 + + orval@7.10.0(openapi-types@12.1.3): + dependencies: + '@apidevtools/swagger-parser': 10.1.1(openapi-types@12.1.3) + '@orval/angular': 7.10.0(openapi-types@12.1.3) + '@orval/axios': 7.10.0(openapi-types@12.1.3) + '@orval/core': 7.10.0(openapi-types@12.1.3) + '@orval/fetch': 7.10.0(openapi-types@12.1.3) + '@orval/hono': 7.10.0(openapi-types@12.1.3) + '@orval/mcp': 7.10.0(openapi-types@12.1.3) + '@orval/mock': 7.10.0(openapi-types@12.1.3) + '@orval/query': 7.10.0(openapi-types@12.1.3) + '@orval/swr': 7.10.0(openapi-types@12.1.3) + '@orval/zod': 7.10.0(openapi-types@12.1.3) + ajv: 8.17.1 + cac: 6.7.14 + chalk: 4.1.2 + chokidar: 4.0.3 + enquirer: 2.4.1 + execa: 5.1.1 + find-up: 5.0.0 + fs-extra: 11.3.0 + lodash.uniq: 4.5.0 + openapi3-ts: 4.2.2 + string-argv: 0.3.2 + tsconfck: 2.1.2(typescript@5.7.3) + typedoc: 0.28.6(typescript@5.7.3) + typedoc-plugin-markdown: 4.7.0(typedoc@0.28.6(typescript@5.7.3)) + typescript: 5.7.3 + transitivePeerDependencies: + - encoding + - openapi-types + - supports-color + + own-keys@1.0.1: + dependencies: + get-intrinsic: 1.3.0 + object-keys: 1.1.1 + safe-push-apply: 1.0.0 + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + + parchment@1.1.4: {} + + parchment@3.0.0: {} + + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + + path-exists@4.0.0: {} + + path-key@3.1.1: {} + + path-type@4.0.0: {} + + picocolors@1.1.1: {} + + picomatch@2.3.1: {} + + picomatch@4.0.2: {} + + pony-cause@1.1.1: {} + + possible-typed-array-names@1.1.0: {} + + postcss@8.5.3: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + potpack@1.0.2: {} + + prelude-ls@1.2.1: {} + + promise-worker-transferable@1.0.4: + dependencies: + is-promise: 2.2.2 + lie: 3.3.0 + + prop-types@15.8.1: + dependencies: + loose-envify: 1.4.0 + object-assign: 4.1.1 + react-is: 16.13.1 + + property-expr@2.0.6: {} + + proxy-from-env@1.1.0: {} + + punycode.js@2.3.1: {} + + punycode@2.3.1: {} + + queue-microtask@1.2.3: {} + + quill-delta@3.6.3: + dependencies: + deep-equal: 1.1.2 + extend: 3.0.2 + fast-diff: 1.1.2 + + quill-delta@5.1.0: + dependencies: + fast-diff: 1.3.0 + lodash.clonedeep: 4.5.0 + lodash.isequal: 4.5.0 + + quill@1.3.7: + dependencies: + clone: 2.1.2 + deep-equal: 1.1.2 + eventemitter3: 2.0.3 + extend: 3.0.2 + parchment: 1.1.4 + quill-delta: 3.6.3 + + quill@2.0.3: + dependencies: + eventemitter3: 5.0.1 + lodash-es: 4.17.21 + parchment: 3.0.0 + quill-delta: 5.1.0 + + react-colorful@5.6.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0): + dependencies: + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + + react-date-object@2.1.9: {} + + react-dom@19.1.0(react@19.1.0): + dependencies: + react: 19.1.0 + scheduler: 0.26.0 + + react-dropzone@14.3.8(react@19.1.0): + dependencies: + attr-accept: 2.2.5 + file-selector: 2.1.2 + prop-types: 15.8.1 + react: 19.1.0 + + react-element-popper@2.1.7(react-dom@19.1.0(react@19.1.0))(react@19.1.0): + dependencies: + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + + react-hook-form@7.60.0(react@19.1.0): + dependencies: + react: 19.1.0 + + react-i18next@15.5.2(i18next@25.2.1(typescript@5.7.3))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(typescript@5.7.3): + dependencies: + '@babel/runtime': 7.27.3 + html-parse-stringify: 3.0.1 + i18next: 25.2.1(typescript@5.7.3) + react: 19.1.0 + optionalDependencies: + react-dom: 19.1.0(react@19.1.0) + typescript: 5.7.3 + + react-is@16.13.1: {} + + react-loading-skeleton@3.5.0(react@19.1.0): + dependencies: + react: 19.1.0 + + react-multi-date-picker@4.5.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0): + dependencies: + react: 19.1.0 + react-date-object: 2.1.9 + react-dom: 19.1.0(react@19.1.0) + react-element-popper: 2.1.7(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + + react-quill-new@3.4.6(quill-delta@5.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0): + dependencies: + lodash-es: 4.17.21 + quill: 2.0.3 + quill-delta: 5.1.0 + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + + react-quill@2.0.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0): + dependencies: + '@types/quill': 1.3.10 + lodash: 4.17.21 + quill: 1.3.7 + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + + react-reconciler@0.31.0(react@19.1.0): + dependencies: + react: 19.1.0 + scheduler: 0.25.0 + + react-refresh@0.17.0: {} + + react-router-dom@7.6.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0): + dependencies: + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + react-router: 7.6.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + + react-router@7.6.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0): + dependencies: + cookie: 1.0.2 + react: 19.1.0 + set-cookie-parser: 2.7.1 + optionalDependencies: + react-dom: 19.1.0(react@19.1.0) + + react-spinners@0.17.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0): + dependencies: + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + + react-use-measure@2.1.7(react-dom@19.1.0(react@19.1.0))(react@19.1.0): + dependencies: + react: 19.1.0 + optionalDependencies: + react-dom: 19.1.0(react@19.1.0) + + react@19.1.0: {} + + readdirp@4.1.2: {} + + reflect.getprototypeof@1.0.10: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.0 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 + get-proto: 1.0.1 + which-builtin-type: 1.2.1 + + reftools@1.1.9: {} + + regexp.prototype.flags@1.5.4: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-errors: 1.3.0 + get-proto: 1.0.1 + gopd: 1.2.0 + set-function-name: 2.0.2 + + require-directory@2.1.1: {} + + require-from-string@2.0.2: {} + + resolve-from@4.0.0: {} + + reusify@1.1.0: {} + + rollup@4.41.1: + dependencies: + '@types/estree': 1.0.7 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.41.1 + '@rollup/rollup-android-arm64': 4.41.1 + '@rollup/rollup-darwin-arm64': 4.41.1 + '@rollup/rollup-darwin-x64': 4.41.1 + '@rollup/rollup-freebsd-arm64': 4.41.1 + '@rollup/rollup-freebsd-x64': 4.41.1 + '@rollup/rollup-linux-arm-gnueabihf': 4.41.1 + '@rollup/rollup-linux-arm-musleabihf': 4.41.1 + '@rollup/rollup-linux-arm64-gnu': 4.41.1 + '@rollup/rollup-linux-arm64-musl': 4.41.1 + '@rollup/rollup-linux-loongarch64-gnu': 4.41.1 + '@rollup/rollup-linux-powerpc64le-gnu': 4.41.1 + '@rollup/rollup-linux-riscv64-gnu': 4.41.1 + '@rollup/rollup-linux-riscv64-musl': 4.41.1 + '@rollup/rollup-linux-s390x-gnu': 4.41.1 + '@rollup/rollup-linux-x64-gnu': 4.41.1 + '@rollup/rollup-linux-x64-musl': 4.41.1 + '@rollup/rollup-win32-arm64-msvc': 4.41.1 + '@rollup/rollup-win32-ia32-msvc': 4.41.1 + '@rollup/rollup-win32-x64-msvc': 4.41.1 + fsevents: 2.3.3 + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + safe-array-concat@1.1.3: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + has-symbols: 1.1.0 + isarray: 2.0.5 + + safe-push-apply@1.0.0: + dependencies: + es-errors: 1.3.0 + isarray: 2.0.5 + + safe-regex-test@1.1.0: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-regex: 1.2.1 + + safe-stable-stringify@1.1.1: {} + + scheduler@0.25.0: {} + + scheduler@0.26.0: {} + + semver@6.3.1: {} + + semver@7.7.2: {} + + set-cookie-parser@2.7.1: {} + + set-function-length@1.2.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.3.0 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + + set-function-name@2.0.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + functions-have-names: 1.2.3 + has-property-descriptors: 1.0.2 + + set-proto@1.0.0: + dependencies: + dunder-proto: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + should-equal@2.0.0: + dependencies: + should-type: 1.4.0 + + should-format@3.0.3: + dependencies: + should-type: 1.4.0 + should-type-adaptors: 1.1.0 + + should-type-adaptors@1.1.0: + dependencies: + should-type: 1.4.0 + should-util: 1.0.1 + + should-type@1.4.0: {} + + should-util@1.0.1: {} + + should@13.2.3: + dependencies: + should-equal: 2.0.0 + should-format: 3.0.3 + should-type: 1.4.0 + should-type-adaptors: 1.1.0 + should-util: 1.0.1 + + side-channel-list@1.0.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + + side-channel-map@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + + side-channel-weakmap@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + side-channel-map: 1.0.1 + + side-channel@1.1.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + side-channel-list: 1.0.0 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 + + signal-exit@3.0.7: {} + + simple-eval@1.0.1: + dependencies: + jsep: 1.4.0 + + slash@3.0.0: {} + + source-map-js@1.2.1: {} + + stats-gl@2.4.2(@types/three@0.177.0)(three@0.177.0): + dependencies: + '@types/three': 0.177.0 + three: 0.177.0 + + stats.js@0.17.0: {} + + stop-iteration-iterator@1.1.0: + dependencies: + es-errors: 1.3.0 + internal-slot: 1.1.0 + + string-argv@0.3.2: {} + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string.prototype.trim@1.2.10: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-data-property: 1.1.4 + define-properties: 1.2.1 + es-abstract: 1.24.0 + es-object-atoms: 1.1.1 + has-property-descriptors: 1.0.2 + + string.prototype.trimend@1.0.9: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + + string.prototype.trimstart@1.0.8: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-final-newline@2.0.0: {} + + strip-json-comments@3.1.1: {} + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + suspend-react@0.1.3(react@19.1.0): + dependencies: + react: 19.1.0 + + swagger2openapi@7.0.8: + dependencies: + call-me-maybe: 1.0.2 + node-fetch: 2.7.0 + node-fetch-h2: 2.3.0 + node-readfiles: 0.2.0 + oas-kit-common: 1.0.8 + oas-resolver: 2.5.6 + oas-schema-walker: 1.1.5 + oas-validator: 5.0.8 + reftools: 1.1.9 + yaml: 1.10.2 + yargs: 17.7.2 + transitivePeerDependencies: + - encoding + + swiper@11.2.8: {} + + tailwind-merge@3.3.0: {} + + tailwindcss@4.1.7: {} + + tapable@2.2.2: {} + + tar@7.4.3: + dependencies: + '@isaacs/fs-minipass': 4.0.1 + chownr: 3.0.0 + minipass: 7.1.2 + minizlib: 3.0.2 + mkdirp: 3.0.1 + yallist: 5.0.0 + + three-mesh-bvh@0.8.3(three@0.177.0): + dependencies: + three: 0.177.0 + + three-stdlib@2.36.0(three@0.177.0): + dependencies: + '@types/draco3d': 1.4.10 + '@types/offscreencanvas': 2019.7.3 + '@types/webxr': 0.5.22 + draco3d: 1.5.7 + fflate: 0.6.10 + potpack: 1.0.2 + three: 0.177.0 + + three@0.177.0: {} + + tiny-case@1.0.3: {} + + tinyglobby@0.2.14: + dependencies: + fdir: 6.4.4(picomatch@4.0.2) + picomatch: 4.0.2 + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + toposort@2.0.2: {} + + tr46@0.0.3: {} + + troika-three-text@0.52.4(three@0.177.0): + dependencies: + bidi-js: 1.0.3 + three: 0.177.0 + troika-three-utils: 0.52.4(three@0.177.0) + troika-worker-utils: 0.52.0 + webgl-sdf-generator: 1.1.1 + + troika-three-utils@0.52.4(three@0.177.0): + dependencies: + three: 0.177.0 + + troika-worker-utils@0.52.0: {} + + ts-api-utils@2.1.0(typescript@5.7.3): + dependencies: + typescript: 5.7.3 + + tsconfck@2.1.2(typescript@5.7.3): + optionalDependencies: + typescript: 5.7.3 + + tsconfck@3.1.6(typescript@5.7.3): + optionalDependencies: + typescript: 5.7.3 + + tslib@1.14.1: {} + + tslib@2.8.1: {} + + tunnel-rat@0.1.2(@types/react@19.1.6)(immer@9.0.21)(react@19.1.0): + dependencies: + zustand: 4.5.7(@types/react@19.1.6)(immer@9.0.21)(react@19.1.0) + transitivePeerDependencies: + - '@types/react' + - immer + - react + + tw-animate-css@1.3.0: {} + + type-check@0.4.0: + dependencies: + prelude-ls: 1.2.1 + + type-fest@2.19.0: {} + + typed-array-buffer@1.0.3: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-typed-array: 1.1.15 + + typed-array-byte-length@1.0.3: + dependencies: + call-bind: 1.0.8 + for-each: 0.3.5 + gopd: 1.2.0 + has-proto: 1.2.0 + is-typed-array: 1.1.15 + + typed-array-byte-offset@1.0.4: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.8 + for-each: 0.3.5 + gopd: 1.2.0 + has-proto: 1.2.0 + is-typed-array: 1.1.15 + reflect.getprototypeof: 1.0.10 + + typed-array-length@1.0.7: + dependencies: + call-bind: 1.0.8 + for-each: 0.3.5 + gopd: 1.2.0 + is-typed-array: 1.1.15 + possible-typed-array-names: 1.1.0 + reflect.getprototypeof: 1.0.10 + + typedoc-plugin-markdown@4.7.0(typedoc@0.28.6(typescript@5.7.3)): + dependencies: + typedoc: 0.28.6(typescript@5.7.3) + + typedoc@0.28.6(typescript@5.7.3): + dependencies: + '@gerrit0/mini-shiki': 3.7.0 + lunr: 2.3.9 + markdown-it: 14.1.0 + minimatch: 9.0.5 + typescript: 5.7.3 + yaml: 2.8.0 + + typescript-eslint@8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.7.3): + dependencies: + '@typescript-eslint/eslint-plugin': 8.32.1(@typescript-eslint/parser@8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.27.0(jiti@2.4.2))(typescript@5.7.3) + '@typescript-eslint/parser': 8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.7.3) + '@typescript-eslint/utils': 8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.7.3) + eslint: 9.27.0(jiti@2.4.2) + typescript: 5.7.3 + transitivePeerDependencies: + - supports-color + + typescript@5.7.3: {} + + uc.micro@2.1.0: {} + + unbox-primitive@1.1.0: + dependencies: + call-bound: 1.0.4 + has-bigints: 1.1.0 + has-symbols: 1.1.0 + which-boxed-primitive: 1.1.1 + + undici-types@7.8.0: {} + + universalify@2.0.1: {} + + update-browserslist-db@1.1.3(browserslist@4.24.5): + dependencies: + browserslist: 4.24.5 + escalade: 3.2.0 + picocolors: 1.1.1 + + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + + urijs@1.19.11: {} + + use-sync-external-store@1.5.0(react@19.1.0): + dependencies: + react: 19.1.0 + + utility-types@3.11.0: {} + + uuid@11.1.0: {} + + validator@13.15.15: {} + + vite-tsconfig-paths@5.1.4(typescript@5.7.3)(vite@6.3.5(@types/node@24.0.7)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)): + dependencies: + debug: 4.4.1 + globrex: 0.1.2 + tsconfck: 3.1.6(typescript@5.7.3) + optionalDependencies: + vite: 6.3.5(@types/node@24.0.7)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + transitivePeerDependencies: + - supports-color + - typescript + + vite@6.3.5(@types/node@24.0.7)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0): + dependencies: + esbuild: 0.25.5 + fdir: 6.4.4(picomatch@4.0.2) + picomatch: 4.0.2 + postcss: 8.5.3 + rollup: 4.41.1 + tinyglobby: 0.2.14 + optionalDependencies: + '@types/node': 24.0.7 + fsevents: 2.3.3 + jiti: 2.4.2 + lightningcss: 1.30.1 + yaml: 2.8.0 + + void-elements@3.1.0: {} + + webgl-constants@1.1.1: {} + + webgl-sdf-generator@1.1.1: {} + + webidl-conversions@3.0.1: {} + + whatwg-url@5.0.0: + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + + which-boxed-primitive@1.1.1: + dependencies: + is-bigint: 1.1.0 + is-boolean-object: 1.2.2 + is-number-object: 1.1.1 + is-string: 1.1.1 + is-symbol: 1.1.1 + + which-builtin-type@1.2.1: + dependencies: + call-bound: 1.0.4 + function.prototype.name: 1.1.8 + has-tostringtag: 1.0.2 + is-async-function: 2.1.1 + is-date-object: 1.1.0 + is-finalizationregistry: 1.1.1 + is-generator-function: 1.1.0 + is-regex: 1.2.1 + is-weakref: 1.1.1 + isarray: 2.0.5 + which-boxed-primitive: 1.1.1 + which-collection: 1.0.2 + which-typed-array: 1.1.19 + + which-collection@1.0.2: + dependencies: + is-map: 2.0.3 + is-set: 2.0.3 + is-weakmap: 2.0.2 + is-weakset: 2.0.4 + + which-typed-array@1.1.19: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.8 + call-bound: 1.0.4 + for-each: 0.3.5 + get-proto: 1.0.1 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + word-wrap@1.2.5: {} + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + y18n@5.0.8: {} + + yallist@3.1.1: {} + + yallist@5.0.0: {} + + yaml@1.10.2: {} + + yaml@2.8.0: {} + + yargs-parser@21.1.1: {} + + yargs@17.7.2: + dependencies: + cliui: 8.0.1 + escalade: 3.2.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + + yocto-queue@0.1.0: {} + + yup@1.6.1: + dependencies: + property-expr: 2.0.6 + tiny-case: 1.0.3 + toposort: 2.0.2 + type-fest: 2.19.0 + + zustand@4.5.7(@types/react@19.1.6)(immer@9.0.21)(react@19.1.0): + dependencies: + use-sync-external-store: 1.5.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.6 + immer: 9.0.21 + react: 19.1.0 + + zustand@5.0.5(@types/react@19.1.6)(immer@9.0.21)(react@19.1.0)(use-sync-external-store@1.5.0(react@19.1.0)): + optionalDependencies: + '@types/react': 19.1.6 + immer: 9.0.21 + react: 19.1.0 + use-sync-external-store: 1.5.0(react@19.1.0) diff --git a/public/vite.svg b/public/vite.svg new file mode 100644 index 0000000..e7b8dfb --- /dev/null +++ b/public/vite.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/App.tsx b/src/App.tsx new file mode 100644 index 0000000..195e5f0 --- /dev/null +++ b/src/App.tsx @@ -0,0 +1,111 @@ +import { FC } from 'react' +import './assets/fonts/irancell/style.css' +import 'react-quill-new/dist/quill.snow.css'; +import 'react-loading-skeleton/dist/skeleton.css' +import 'swiper/swiper-bundle.css'; +import { BrowserRouter } from 'react-router-dom' +import Main from './shared/Main' +import i18next from 'i18next' +import FaJson from './langs/fa.json' +import { I18nextProvider } from 'react-i18next' +import { QueryCache, QueryClient, QueryClientProvider } from '@tanstack/react-query'; +import { IApiErrorRepsonse } from './types/error.types'; +import ToastContainer from './components/Toast'; +import { getRefreshToken, removeRefreshToken, removeToken, setRefreshToken, setToken } from './config/func'; +import { refreshToken } from './pages/auth/service/Service'; + +declare global { + interface Window { + isRefreshingToken?: boolean; + } +} + +i18next.init({ + interpolation: { escapeValue: false }, + lng: 'fa', + defaultNS: 'global', + resources: { + fa: { + global: FaJson + } + } +}) + +const queryClient = new QueryClient({ + queryCache: new QueryCache({ + onError: async (error: IApiErrorRepsonse) => { + if (error?.response?.status === 401) { + try { + // Use a flag to track if refresh is in progress + if (window.isRefreshingToken) { + // Wait for the refresh to complete + await new Promise(resolve => { + const checkComplete = setInterval(() => { + if (!window.isRefreshingToken) { + clearInterval(checkComplete); + resolve(true); + } + }, 100); + }); + return; + } + + // Set the flag to indicate refresh is in progress + window.isRefreshingToken = true; + + try { + const refreshTokenValue = await getRefreshToken(); + const { data } = await refreshToken({ refreshToken: refreshTokenValue || '' }); + + if (data?.accessToken?.token) { + // Save the new token + await setToken(data?.accessToken?.token); + + // If refresh token also returned, update it + if (data.refreshToken?.token) { + await setRefreshToken(data.refreshToken?.token); + } + + // Retry the failed request + queryClient.invalidateQueries(); + return; + } else { + throw new Error('Invalid token response'); + } + } finally { + window.isRefreshingToken = false; + } + } catch (refreshError: unknown) { + console.error('Token refresh failed:', refreshError); + // Clear tokens and redirect to login + await removeToken(); + await removeRefreshToken(); + window.location.href = '/auth/login'; + } + } + } + }), + defaultOptions: { + queries: { + refetchOnWindowFocus: false, + retry: false + // staleTime: 86400000 // 1 day in milliseconds + } + } +}); + +const App: FC = () => { + return ( + + + + +
+ + + + + ) +} + +export default App \ No newline at end of file diff --git a/src/assets/fonts/irancell/irancell-bold.ttf b/src/assets/fonts/irancell/irancell-bold.ttf new file mode 100644 index 0000000..dac6c53 Binary files /dev/null and b/src/assets/fonts/irancell/irancell-bold.ttf differ diff --git a/src/assets/fonts/irancell/irancell-extralight.ttf b/src/assets/fonts/irancell/irancell-extralight.ttf new file mode 100644 index 0000000..80e0d26 Binary files /dev/null and b/src/assets/fonts/irancell/irancell-extralight.ttf differ diff --git a/src/assets/fonts/irancell/irancell-light.ttf b/src/assets/fonts/irancell/irancell-light.ttf new file mode 100644 index 0000000..766ea21 Binary files /dev/null and b/src/assets/fonts/irancell/irancell-light.ttf differ diff --git a/src/assets/fonts/irancell/style.css b/src/assets/fonts/irancell/style.css new file mode 100644 index 0000000..7f72117 --- /dev/null +++ b/src/assets/fonts/irancell/style.css @@ -0,0 +1,18 @@ +@font-face { + font-family: "irancell"; + font-style: thin; + font-weight: 200; + src: url("./irancell-extralight.ttf"); +} +@font-face { + font-family: "irancell"; + font-style: normal; + font-weight: 300; + src: url("./irancell-light.ttf"); +} +@font-face { + font-family: "irancell"; + font-style: thin; + font-weight: 600; + src: url("./irancell-bold.ttf"); +} diff --git a/src/assets/images/answer.svg b/src/assets/images/answer.svg new file mode 100644 index 0000000..9d4e010 --- /dev/null +++ b/src/assets/images/answer.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/images/avatar.svg b/src/assets/images/avatar.svg new file mode 100644 index 0000000..9142ee2 --- /dev/null +++ b/src/assets/images/avatar.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/src/assets/images/color.png b/src/assets/images/color.png new file mode 100644 index 0000000..3560bcf Binary files /dev/null and b/src/assets/images/color.png differ diff --git a/src/assets/images/forward.svg b/src/assets/images/forward.svg new file mode 100644 index 0000000..8207904 --- /dev/null +++ b/src/assets/images/forward.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/src/assets/images/logo-small.svg b/src/assets/images/logo-small.svg new file mode 100644 index 0000000..af5e4f3 --- /dev/null +++ b/src/assets/images/logo-small.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/src/assets/images/logo.svg b/src/assets/images/logo.svg new file mode 100644 index 0000000..200db25 --- /dev/null +++ b/src/assets/images/logo.svg @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/react.svg b/src/assets/react.svg new file mode 100644 index 0000000..6c87de9 --- /dev/null +++ b/src/assets/react.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/components/Button.tsx b/src/components/Button.tsx new file mode 100644 index 0000000..4dd4cf6 --- /dev/null +++ b/src/components/Button.tsx @@ -0,0 +1,42 @@ +import { FC, ReactNode } from 'react' +import { clx } from '../helpers/utils' +import MoonLoader from "react-spinners/ClipLoader" + + +interface ButtonProps { + label?: string; + children?: ReactNode; + className?: string; + loading?: boolean; + onClick?: () => void; + type?: 'button' | 'submit' | 'reset'; + disabled?: boolean; + variant?: 'primary' | 'secondary' +} + +const Button: FC = (props) => { + + const buttonClass = clx( + 'w-full bg-primary text-white cursor-pointer rounded-xl font-normal text-xs md:text-sm h-10 px-3 md:px-4 transition-all duration-200 hover:bg-opacity-90 disabled:opacity-50 disabled:cursor-not-allowed', + props.variant === 'secondary' && 'bg-[#ECEEF5] text-black', + props.className + ) + + return ( + + ) +} + +export default Button \ No newline at end of file diff --git a/src/components/ColorPicker.tsx b/src/components/ColorPicker.tsx new file mode 100644 index 0000000..0c92681 --- /dev/null +++ b/src/components/ColorPicker.tsx @@ -0,0 +1,41 @@ +import { FC, useState } from 'react' +import ColorImage from '@/assets/images/color.png' +import { HexColorPicker } from 'react-colorful' + +type Props = { + defaultColor?: string + changeColor: (color: string) => void, + label: string +} + +const ColorPicker: FC = ({ defaultColor, changeColor, label }) => { + + const [showPicker, setShowPicker] = useState(false) + const [color, setColor] = useState(defaultColor || '#000') + + return ( +
+
+ {label} +
+
setShowPicker(!showPicker)} + className='mt-2 relative cursor-pointer h-10 border border-[#D0D0D0] rounded-xl px-4 flex justify-between items-center'> +
+
+
{color}
+
+ color + {showPicker && ( +
+ { + setColor(newColor) + changeColor(newColor) + }} /> +
+ )} +
+
+ ) +} + +export default ColorPicker \ No newline at end of file diff --git a/src/components/DatePicker.tsx b/src/components/DatePicker.tsx new file mode 100644 index 0000000..0112e99 --- /dev/null +++ b/src/components/DatePicker.tsx @@ -0,0 +1,87 @@ +import { useState, useEffect, FC } from 'react'; +import DatePicker from 'react-multi-date-picker'; +import persian from 'react-date-object/calendars/persian'; +import persian_fa from 'react-date-object/locales/persian_fa'; +import DateObject from 'react-date-object'; +import { Calendar } from 'iconsax-react'; +import { clx } from '../helpers/utils'; + +type Props = { + onChange: (date: string) => void; + defaultValue?: string; + error_text?: string; + placeholder: string; + reset?: boolean; + isDateTime?: boolean; + className?: string; + label?: string, + readOnly?: boolean; +}; + +const DatePickerComponent: FC = (props: Props) => { + const [value, setValue] = useState(null); + + useEffect(() => { + if (props.reset) { + setValue(null); + } + }, [props.reset]); + + useEffect(() => { + if (value) { + const formattedDate = `${value.year}/${value.month.number}/${value.day}`; + props.onChange(formattedDate); + } + }, [value]); + + useEffect(() => { + if (props.defaultValue && !value) { + const defaultDate = new DateObject({ + date: props.defaultValue, + calendar: persian, + locale: persian_fa, + }); + setValue(defaultDate); + } + }, [props.defaultValue, value]); + + return ( +
+ { + props.label && +
+ {props.label} +
+ } +
+ setValue(date as DateObject)} + calendar={persian} + locale={persian_fa} + calendarPosition="bottom-right" + className={props.className} + readOnly={props.readOnly} + /> + {props.error_text && props.error_text !== '' && ( +
+ {props.error_text} +
+ )} + + +
+
+ ); +}; + +export default DatePickerComponent; \ No newline at end of file diff --git a/src/components/DefaultTableSkeleton.tsx b/src/components/DefaultTableSkeleton.tsx new file mode 100644 index 0000000..9e7257a --- /dev/null +++ b/src/components/DefaultTableSkeleton.tsx @@ -0,0 +1,30 @@ +import { FC, Fragment } from 'react' +import Td from './Td' +import Skeleton from 'react-loading-skeleton' + +type Props = { + tdCount: number, + trCount?: number, +} + +const DefaultTableSkeleton: FC = ({ tdCount, trCount = 5 }) => { + return ( + + { + Array.from({ length: trCount }).map((_, rowIndex) => ( + + { + Array.from({ length: tdCount }).map((_, colIndex) => ( + + + + )) + } + + )) + } + + ) +} + +export default DefaultTableSkeleton diff --git a/src/components/Error.tsx b/src/components/Error.tsx new file mode 100644 index 0000000..7fec2e7 --- /dev/null +++ b/src/components/Error.tsx @@ -0,0 +1,15 @@ +import { FC } from 'react' + +type Props = { + errorText: string +} + +const Error: FC = (props: Props) => { + return ( +
+ {props.errorText} +
+ ) +} + +export default Error \ No newline at end of file diff --git a/src/components/Filters.tsx b/src/components/Filters.tsx new file mode 100644 index 0000000..04e307f --- /dev/null +++ b/src/components/Filters.tsx @@ -0,0 +1,191 @@ +import { FC, useEffect, useState, ChangeEvent } from 'react'; +import { Filter, CloseCircle } from 'iconsax-react'; +import DatePicker from './DatePicker'; +import Input from './Input'; +import Select, { ItemsSelectType } from './Select'; + +// تعریف نوع داده برای فیلدهای مختلف +export type DateFieldType = { + type: 'date'; + name: string; + placeholder: string; + defaultValue?: string; +}; + +export type SelectFieldType = { + type: 'select'; + name: string; + placeholder: string; + options: ItemsSelectType[]; + defaultValue?: string; +}; + +export type InputFieldType = { + type: 'input'; + name: string; + placeholder: string; + defaultValue?: string; +}; + +export type FieldType = DateFieldType | SelectFieldType | InputFieldType; + +// تعریف نوع داده برای مقادیر فیلترها +export type FilterValues = Record; + +interface FiltersProps { + fields: FieldType[]; + onChange: (filters: FilterValues) => void; + initialValues?: FilterValues; + className?: string; + fieldClassName?: string; + searchField?: string; // نام فیلد جستجو که باید در انتها نمایش داده شود +} + +const Filters: FC = ({ + fields, + onChange, + initialValues = {}, + className = "mt-6 md:mt-8 xl:mt-10 flex flex-col md:flex-row justify-between items-start md:items-center gap-4", + fieldClassName = "flex flex-col sm:flex-row gap-3 md:gap-4 w-full md:w-auto", + searchField = "search" // پیش‌فرض فیلد سرچ با نام search +}) => { + const [filters, setFilters] = useState({}); + const [isFiltersOpen, setIsFiltersOpen] = useState(false); + + // تنظیم مقادیر اولیه + useEffect(() => { + if (Object.keys(initialValues).length > 0) { + setFilters(initialValues); + } else { + // تنظیم مقادیر پیش‌فرض از فیلدها + const defaultValues: FilterValues = {}; + fields.forEach(field => { + if ('defaultValue' in field && field.defaultValue !== undefined) { + defaultValues[field.name] = field.defaultValue; + } + }); + + if (Object.keys(defaultValues).length > 0) { + setFilters(defaultValues); + onChange(defaultValues); + } + } + }, [fields, initialValues, onChange]); + + const handleChange = (name: string, value: string | null) => { + const newFilters = { ...filters, [name]: value }; + setFilters(newFilters); + onChange(newFilters); + }; + + const handleInputChange = (name: string, event: ChangeEvent) => { + handleChange(name, event.target.value); + }; + + const renderField = (field: FieldType) => { + const currentValue = filters[field.name]; + + switch (field.type) { + case 'date': + return ( + handleChange(field.name, value)} + defaultValue={currentValue || field.defaultValue || ''} + /> + ); + + case 'select': + return ( + handleInputChange(field.name, e)} + /> + ); + } + }; + + // جداسازی فیلد جستجو از سایر فیلدها + const searchFieldObj = fields.find(field => field.name === searchField); + const otherFields = fields.filter(field => field.name !== searchField); + + return ( +
+ {/* آیکون فیلتر برای موبایل */} +
+ + {searchFieldObj && ( +
+ {renderField(searchFieldObj)} +
+ )} +
+ + {/* فیلترها برای دسکتاپ (همیشه نمایش داده می‌شوند) */} +
+
+ {otherFields.map(renderField)} +
+ {searchFieldObj && ( +
+ {renderField(searchFieldObj)} +
+ )} +
+ + {/* فیلترها برای موبایل (قابل باز و بسته شدن) */} + {isFiltersOpen && ( +
+
+
+
+ + فیلتر کردن نتایج +
+ +
+ {otherFields.map(field => ( +
+ +
+ {renderField(field)} +
+
+ ))} +
+
+ )} +
+ ); +}; + +export default Filters; \ No newline at end of file diff --git a/src/components/Input.tsx b/src/components/Input.tsx new file mode 100644 index 0000000..de90b15 --- /dev/null +++ b/src/components/Input.tsx @@ -0,0 +1,125 @@ +import { FC, InputHTMLAttributes, useEffect, useState } from 'react' +import { clx } from '../helpers/utils'; +import { Eye, SearchNormal } from 'iconsax-react'; +import Error from './Error'; + +type Variant = "floating_outlined" | "primary" | "search"; + +type Props = { + label?: string; + className?: string; + variant?: Variant; + error_text?: string; + onEnter?: () => void; + unit?: string; + seprator?: boolean; + isNotRequired?: boolean; + onChangeSearchFinal?: (value: string) => void; + endIcon?: React.ReactNode; +} & InputHTMLAttributes + +const formatNumber = (value: string | number): string => { + if (!value) return ''; + const inputValue = String(value).replace(/,/g, ''); + return inputValue.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ','); +}; + +const Input: FC = (props: Props) => { + + const [formattedValue, setFormattedValue] = useState( + props.value ? formatNumber(props.value as string) : '' + ); + + const [showPassword, setShowPassword] = useState(false) + const [search, setSearch] = useState('') + + const inputClass = clx( + 'w-full bg-white h-10 text-black block px-4 text-xs rounded-xl border border-border', + props.readOnly && 'bg-gray-100 border-0 text-description', + props.variant === 'search' && 'ps-10', + props.className + ); + + const handleInputChange = (event: React.ChangeEvent) => { + if (props.seprator) { + const inputValue = event.target.value.replace(/,/g, ''); // حذف کاماها + const formatted = formatNumber(inputValue); + + // به‌روزرسانی مقدار قالب‌بندی‌شده + setFormattedValue(formatted); + + // ارسال مقدار خام به `onChange` والد + props.onChange?.({ + ...event, + target: { + ...event.target, + value: inputValue, + }, + }); + } else { + props.onChange?.(event); + } + }; + + useEffect(() => { + if (props.value) { + setFormattedValue(formatNumber(props.value as string)); + } else { + setFormattedValue(''); + } + }, [props.value]) + + useEffect(() => { + if (props.variant === 'search' && props.onChangeSearchFinal) { + const timeout = setTimeout(() => { + props.onChangeSearchFinal?.(search) + }, 1000) + return () => clearTimeout(timeout) + } + }, [search, props]) + + + return ( +
+ + +
+ { + setSearch(e.target.value) + handleInputChange(e) + }} value={props.seprator ? formattedValue : props.value} type={props.type === 'password' && showPassword ? 'text' : props.type === 'password' ? 'password' : undefined} className={inputClass} /> + + { + props.type === 'password' && + setShowPassword((oldValue) => !oldValue)} size={20} color='#8C90A3' className='absolute top-0 bottom-0 cursor-pointer my-auto left-3' /> + } + + { + props.variant === 'search' && + + } + + { + props.endIcon && +
+ {props.endIcon} +
+ } + + { + props.error_text && + + } +
+
+ ) +} + +export default Input \ No newline at end of file diff --git a/src/components/Pagination.tsx b/src/components/Pagination.tsx new file mode 100644 index 0000000..d381ceb --- /dev/null +++ b/src/components/Pagination.tsx @@ -0,0 +1,109 @@ +import React from "react"; + +interface PaginationProps { + currentPage: number; + totalPages: number; + onPageChange: (page: number) => void; +} + +const Pagination: React.FC = ({ + currentPage, + totalPages, + onPageChange, +}) => { + // اگر فقط یک صفحه داریم، pagination نمایش داده نمی‌شود + if (totalPages <= 1) return null; + + const getPageNumbers = () => { + const pageNumbers: (number | string)[] = []; + const maxVisiblePages = window.innerWidth < 768 ? 3 : 5; // تعداد کمتر برای موبایل + + if (totalPages <= maxVisiblePages) { + for (let i = 1; i <= totalPages; i++) { + pageNumbers.push(i); + } + } else { + // نمایش صفحه اول + pageNumbers.push(1); + + if (currentPage > 3) { + pageNumbers.push("..."); + } + + // صفحات میانی + const start = Math.max(2, Math.min(currentPage - 1, totalPages - 3)); + const end = Math.min(totalPages - 1, Math.max(currentPage + 1, 4)); + + for (let i = start; i <= end; i++) { + if (!pageNumbers.includes(i)) { + pageNumbers.push(i); + } + } + + if (currentPage < totalPages - 2) { + pageNumbers.push("..."); + } + + // نمایش صفحه آخر + if (!pageNumbers.includes(totalPages)) { + pageNumbers.push(totalPages); + } + } + + return pageNumbers; + }; + + const pageNumbers = getPageNumbers(); + + return ( +
+ {/* دکمه صفحه قبل */} + + + {/* شماره صفحات */} +
+ {pageNumbers.map((page, index) => + typeof page === "number" ? ( + + ) : ( + + {page} + + ) + )} +
+ + {/* دکمه صفحه بعد */} + +
+ ); +}; + +export default Pagination; \ No newline at end of file diff --git a/src/components/Radio.tsx b/src/components/Radio.tsx new file mode 100644 index 0000000..4f7dcdc --- /dev/null +++ b/src/components/Radio.tsx @@ -0,0 +1,20 @@ +import { FC } from 'react' + +type Props = { + isActive: boolean, + value: string, + onChange: (value: string) => void +} + +const Radio: FC = (props: Props) => { + return ( +
props.onChange(props.value)} className='size-4 cursor-pointer rounded-full bg-[#EAEDF5] flex justify-center items-center'> + { + props.isActive && +
+ } +
+ ) +} + +export default Radio \ No newline at end of file diff --git a/src/components/RadioGroup.tsx b/src/components/RadioGroup.tsx new file mode 100644 index 0000000..7eba07c --- /dev/null +++ b/src/components/RadioGroup.tsx @@ -0,0 +1,31 @@ +import { FC } from 'react' +import Radio from './Radio' + + +type Props = { + items: { + label: string + value: string + }[] + selected: string + onChange: (value: string) => void +} + +const RadioGroup: FC = (props: Props) => { + return ( +
+ { + props.items.map((item, index) => ( +
+ +
+ {item.label} +
+
+ )) + } +
+ ) +} + +export default RadioGroup \ No newline at end of file diff --git a/src/components/RowActionsDropdown.tsx b/src/components/RowActionsDropdown.tsx new file mode 100644 index 0000000..249cfff --- /dev/null +++ b/src/components/RowActionsDropdown.tsx @@ -0,0 +1,117 @@ +import React, { useState, useRef, useEffect } from 'react'; +import { createPortal } from 'react-dom'; +import { More } from 'iconsax-react'; + +export interface RowActionItem { + label: string; + icon?: React.ReactNode; + onClick: () => void; + className?: string; +} + +interface RowActionsDropdownProps { + actions: RowActionItem[]; + className?: string; +} + +const RowActionsDropdown: React.FC = ({ actions, className = '' }) => { + const [isOpen, setIsOpen] = useState(false); + const [position, setPosition] = useState({ top: 0, left: 0 }); + const dropdownRef = useRef(null); + const buttonRef = useRef(null); + + useEffect(() => { + const handleClickOutside = (event: MouseEvent) => { + if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) { + setIsOpen(false); + } + }; + + document.addEventListener('mousedown', handleClickOutside); + return () => { + document.removeEventListener('mousedown', handleClickOutside); + }; + }, []); + + const handleToggle = (e: React.MouseEvent) => { + e.stopPropagation(); + + if (!isOpen && buttonRef.current) { + const rect = buttonRef.current.getBoundingClientRect(); + const isMobile = window.innerWidth < 768; + const dropdownWidth = isMobile ? 140 : 150; + const dropdownHeight = actions.length * (isMobile ? 36 : 40); // تخمین ارتفاع منو + + let left = rect.left + window.scrollX - dropdownWidth + rect.width; + let top = rect.bottom + window.scrollY; + + // بررسی اینکه منو از سمت راست خارج نشود + if (left + dropdownWidth > window.innerWidth) { + left = rect.left + window.scrollX - dropdownWidth; + } + + // بررسی اینکه منو از سمت چپ خارج نشود + if (left < 0) { + left = isMobile ? 20 : 40; + } + + // بررسی اینکه منو از پایین خارج نشود + if (top + dropdownHeight > window.innerHeight + window.scrollY) { + top = rect.top + window.scrollY - dropdownHeight; + } + + setPosition({ top, left }); + } + + setIsOpen(!isOpen); + }; + + const handleActionClick = (action: RowActionItem) => { + action.onClick(); + setIsOpen(false); + }; + + const renderDropdown = () => { + if (!isOpen) return null; + + return createPortal( +
+ {actions.map((action, index) => ( + + ))} +
, + document.body + ); + }; + + return ( +
+ + + {renderDropdown()} +
+ ); +}; + +export default RowActionsDropdown; \ No newline at end of file diff --git a/src/components/Select.tsx b/src/components/Select.tsx new file mode 100644 index 0000000..f1eb7ea --- /dev/null +++ b/src/components/Select.tsx @@ -0,0 +1,65 @@ +import { FC, SelectHTMLAttributes } from 'react' +import { clx } from '../helpers/utils' +import { ArrowDown2 } from 'iconsax-react' + +export type ItemsSelectType = { + value: string, + label: string, +} +type Props = { + className?: string, + items: ItemsSelectType[], + error_text?: string, + placeholder?: string, + label?: string, + readOnly?: boolean, +} & SelectHTMLAttributes + +const Select: FC = (props: Props) => { + return ( +
+ { + props.label && + + } +
+ + +
+ { + props.error_text && props.error_text !== '' ? +
+ {props.error_text} +
+ : null + } +
+ + ) +} + +export default Select \ No newline at end of file diff --git a/src/components/Table.tsx b/src/components/Table.tsx new file mode 100644 index 0000000..49b5633 --- /dev/null +++ b/src/components/Table.tsx @@ -0,0 +1,363 @@ +import React, { Fragment, useState } from 'react'; +import DefaultTableSkeleton from './DefaultTableSkeleton'; +import Td from './Td'; +import { TableProps, RowDataType, ColumnType } from './types/TableTypes'; +import { Checkbox } from './ui/checkbox'; +import RowActionsDropdown from './RowActionsDropdown'; +import Pagination from './Pagination'; + +const Table = ({ + columns, + data, + isLoading = false, + onRowClick, + className = '', + rowClassName = '', + noDataMessage = 'هیچ داده‌ای یافت نشد', + headerClassName = 'bg-gray-50', + emptyRowsCount = 5, + showHeader = true, + actions = null, + actionsPosition = 'top', + selectable = false, + selectedActions = null, + onSelectionChange, + rowActions, + pagination, +}: TableProps): React.ReactElement => { + + const [selectedRows, setSelectedRows] = useState([]); + + const getRowClassName = (item: T, index: number): string => { + if (typeof rowClassName === 'function') { + return rowClassName(item, index); + } + return rowClassName; + }; + + const getCellClassName = (column: ColumnType): string => { + const alignClass = column.align ? `text-${column.align}` : ''; + return `px-3 md:px-6 py-3 md:py-4 whitespace-nowrap text-xs ${alignClass} ${column.className || ''}`.trim(); + }; + + const handleRowClick = (item: T) => { + if (onRowClick) { + onRowClick(item.id, item); + } + }; + + const handleSelectAll = () => { + const dataArray = data || []; + const newSelectedRows = selectedRows.length === dataArray.length ? [] : [...dataArray]; + setSelectedRows(newSelectedRows); + if (onSelectionChange) { + onSelectionChange(newSelectedRows); + } + }; + + const handleSingleRowSelect = (item: T, checked: boolean) => { + const newSelectedRows = checked + ? [...selectedRows, item] + : selectedRows.filter((row) => row.id !== item.id); + setSelectedRows(newSelectedRows); + if (onSelectionChange) { + onSelectionChange(newSelectedRows); + } + }; + + const isRowSelected = (item: T): boolean => { + return selectedRows.some((row) => row.id === item.id); + }; + + // Gmail-style layout برای وقتی header نمایش داده نمی‌شود + const renderGmailStyleRows = () => { + const hasActions = (actionsPosition === 'top' || actionsPosition === 'above-header') && (actions || (selectable && selectedRows.length > 0 && selectedActions)); + const roundedClass = hasActions ? 'rounded-b-2xl' : 'rounded-2xl'; + + if (isLoading) { + return ( +
+ {Array.from({ length: emptyRowsCount }).map((_, index) => ( +
+ ))} +
+ ); + } + + if (!data || data.length === 0) { + return ( +
+ {noDataMessage} +
+ ); + } + + return ( +
+ {data.map((item, rowIndex) => ( +
handleRowClick(item)} + > + {selectable && ( +
e.stopPropagation()} + > + handleSingleRowSelect(item, !!checked)} + /> +
+ )} + +
+ {/* محتوای اصلی - ستون اول */} +
+ {columns[0]?.render ? columns[0].render(item) : (item[columns[0]?.key] as React.ReactNode)} +
+ + {/* اطلاعات اضافی - سه ستون آخر در یک خط */} + {columns.length > 1 && ( +
+ {columns.slice(1).map((col) => ( +
+ {col.render ? col.render(item) : (item[col.key] as React.ReactNode)} +
+ ))} +
+ )} +
+ + {rowActions && ( +
e.stopPropagation()} + > + +
+ )} +
+ ))} +
+ ); + }; + + const renderTableBody = () => { + if (isLoading) { + return ( + + + + ); + } + + if (!data || data.length === 0) { + return ( + + + {noDataMessage} + + + ); + } + return (data || []).map((item, rowIndex) => ( + handleRowClick(item)} + > + {selectable && ( + e.stopPropagation()} + > + handleSingleRowSelect(item, !!checked)} + /> + + )} + {columns.map((col) => ( + + {col.render ? col.render(item) : item[col.key] as React.ReactNode} + + ))} + {rowActions && ( + e.stopPropagation()} + > + + + )} + + )); + }; + + const renderHeader = () => { + if (!showHeader || actionsPosition === 'header-replace') return null; + + return ( + + + {selectable && ( + e.stopPropagation()} + > + 0 && selectedRows.length === (data?.length || 0)} + onCheckedChange={handleSelectAll} + /> + + )} + {columns.map((col) => ( + + ))} + {rowActions && ( + + )} + + + ); + }; + + const renderActions = () => { + if (!actions && (!selectable || selectedRows.length === 0 || !selectedActions)) return null; + + return ( +
+
+ {actions} + {selectable && selectedRows.length > 0 && selectedActions && selectedActions} +
+
+ ); + }; + + // اگر header نشان داده نمی‌شود، از Gmail-style layout فقط در موبایل استفاده کن + if (!showHeader) { + return ( +
+ {/* نسخه موبایل - Gmail style */} +
+ {(actionsPosition === 'top' || actionsPosition === 'above-header') && ( +
+
+ {actions} + {selectable && selectedRows.length > 0 && selectedActions && selectedActions} +
+
+ )} + {renderGmailStyleRows()} +
+ + {/* نسخه دسکتاپ - Table معمولی */} +
+ {(actionsPosition === 'top' || actionsPosition === 'above-header') && ( +
+
+ {actions} + {selectable && selectedRows.length > 0 && selectedActions && selectedActions} +
+
+ )} +
0 && selectedActions)) ? 'rounded-b-3xl' : 'rounded-3xl'} bg-white`}> + + + {renderTableBody()} + +
+
+
+ + {pagination && ( + + )} +
+ ); + } + + return ( +
+ {(actionsPosition === 'top' || actionsPosition === 'above-header') && renderActions()} + +
+ + {renderHeader()} + {actionsPosition === 'header-replace' && ( + + + + + + )} + + {renderTableBody()} + +
+ {renderActions()} +
+
+ + {pagination && ( + + )} +
+ ); +}; + +export default Table; + +/* +مثال استفاده با pagination: + +import Table from '@/components/Table'; +import { useState } from 'react'; + +const MyComponent = () => { + const [currentPage, setCurrentPage] = useState(1); + const totalPages = 10; + + const columns = [ + { title: 'نام', key: 'name' }, + { title: 'ایمیل', key: 'email' }, + ]; + + const data = [ + { id: 1, name: 'علی', email: 'ali@example.com' }, + { id: 2, name: 'فاطمه', email: 'fateme@example.com' }, + ]; + + const handlePageChange = (page: number) => { + setCurrentPage(page); + // اینجا می‌توانید API call جدید برای دریافت داده‌های صفحه جدید بزنید + }; + + return ( + + ); +}; +*/ \ No newline at end of file diff --git a/src/components/Tabs.tsx b/src/components/Tabs.tsx new file mode 100644 index 0000000..062fb3d --- /dev/null +++ b/src/components/Tabs.tsx @@ -0,0 +1,50 @@ +import { FC, ReactNode } from 'react' +import { clx } from '../helpers/utils' +import { Swiper, SwiperSlide } from 'swiper/react' + +type Item = { + icon: ReactNode, + label: string, + value: string, +} + +type Props = { + items: Item[], + onChange: (value: string) => void, + active: string, +} + +const Tabs: FC = (props: Props) => { + + const SWIPER_SLIDE_STYLE = { + overflow: 'visible !important', + display: 'flex', + } + + return ( + + { + props.items.map((item: Item, index: number) => { + return ( + props.onChange(item.value)} key={item.value} className={clx( + 'flex flex-col max-w-fit mt-[10px] md:mt-[12px] xl:mt-[15px] items-center gap-1 md:gap-2 cursor-pointer', + index === 0 && 'pr-[15px] md:pr-[20px] xl:pr-[30px]', + index === props.items.length - 1 && props.items.length > 3 && 'pl-[5px]', + props.active === item.value && 'text-black' + )}> + {item.icon} +
+ {item.label} +
+
+ ) + }) + } +
+ ) +} + +export default Tabs \ No newline at end of file diff --git a/src/components/Td.tsx b/src/components/Td.tsx new file mode 100644 index 0000000..eb57c7f --- /dev/null +++ b/src/components/Td.tsx @@ -0,0 +1,23 @@ +import { FC, ReactNode } from 'react' + +interface Props { + text: string | number | ReactNode, + children?: ReactNode, + dir?: string, + className?: string, +} + +const Td: FC = (props: Props) => { + return ( +
+ ) +} + +export default Td \ No newline at end of file diff --git a/src/components/Textarea.tsx b/src/components/Textarea.tsx new file mode 100644 index 0000000..18831eb --- /dev/null +++ b/src/components/Textarea.tsx @@ -0,0 +1,36 @@ +import { FC, InputHTMLAttributes } from 'react' +import Error from './Error' +import { clx } from '../helpers/utils' + +type Props = { + label: string, + error_text?: string +} & InputHTMLAttributes + +const Textarea: FC = (props: Props) => { + return ( +
+ + + + { + props.error_text && + + } + +
+ ) +} + +export default Textarea \ No newline at end of file diff --git a/src/components/Toast.tsx b/src/components/Toast.tsx new file mode 100644 index 0000000..fe41eb7 --- /dev/null +++ b/src/components/Toast.tsx @@ -0,0 +1,72 @@ +import { CloseCircle, InfoCircle, TickCircle } from 'iconsax-react'; +import React, { useState, useEffect } from 'react'; + +interface Toast { + id: string; + message: string; + type?: 'success' | 'error' | 'info'; + isExiting?: boolean; +} + +let addToast: (toast: Toast) => void; + +const ToastContainer: React.FC = () => { + const [toasts, setToasts] = useState([]); + + // ثبت toast جدید + const showToast = (toast: Toast) => { + setToasts((prev) => [...prev, toast]); + + // حذف خودکار بعد از ۳ ثانیه + setTimeout(() => { + setToasts((prev) => prev.map(t => + t.id === toast.id ? { ...t, isExiting: true } : t + )); + + // حذف از DOM بعد از اتمام انیمیشن + setTimeout(() => { + setToasts((prev) => prev.filter((t) => t.id !== toast.id)); + }, 300); // مدت زمان انیمیشن خروج + }, 3000); + }; + + // تخصیص تابع نمایش toast به متغیر سراسری + useEffect(() => { + addToast = showToast; + }, []); + + return ( +
+ {toasts.map((toast) => ( +
+ { + toast.type === 'success' ? : + toast.type === 'error' ? : + + } + {toast.message} +
+ ))} +
+ ); +}; + +export const toast = (message?: string, type: 'success' | 'error' | 'info' = 'info') => { + addToast({ id: Date.now().toString(), message: message || '', type }); +}; + +export default ToastContainer; \ No newline at end of file diff --git a/src/components/UploadBox.tsx b/src/components/UploadBox.tsx new file mode 100644 index 0000000..96dad28 --- /dev/null +++ b/src/components/UploadBox.tsx @@ -0,0 +1,87 @@ +import { FC, useCallback, useEffect, useState } from 'react' +import { useTranslation } from 'react-i18next' +import { useDropzone } from 'react-dropzone' +import { CloseCircle } from 'iconsax-react' + + +type Props = { + label: string, + isMultiple?: boolean, + onChange?: (file: File[]) => void; + isReset?: boolean; +} + +const UploadBox: FC = (props: Props) => { + + const { t } = useTranslation('global') + const [files, setFiles] = useState([]) + + const onDrop = useCallback((acceptedFiles: File[]) => { + if (props.isMultiple) { + const array = [...files] + array.push(acceptedFiles[0]) + setFiles(array) + // eslint-disable-next-line @typescript-eslint/no-unused-expressions + props.onChange && props.onChange(array) + } else { + setFiles([acceptedFiles[0]]) + // eslint-disable-next-line @typescript-eslint/no-unused-expressions + props.onChange && props.onChange([acceptedFiles[0]]) + } + }, [files]) + const { getRootProps, getInputProps } = useDropzone({ onDrop }) + + const handleRemove = (index: number) => { + const array = [...files] + array.splice(index, 1) + setFiles(array) + // eslint-disable-next-line @typescript-eslint/no-unused-expressions + props.onChange && props.onChange(array) + } + + useEffect(() => { + + if (props.isReset) { + setFiles([]) + } + + }, [props.isReset]) + + + + return ( +
+
{props.label}
+
+ + +
+ { + files?.map((item, index) => ( +
+ handleRemove(index)} size={16} color='red' /> +
{item.name}
+
+ )) + } +
+
+
+ { + files?.map((item, index) => ( +
+ handleRemove(index)} size={16} color='red' /> +
{item.name}
+
+ )) + } +
+
+ ) +} + +export default UploadBox \ No newline at end of file diff --git a/src/components/UploadBoxDraggble.tsx b/src/components/UploadBoxDraggble.tsx new file mode 100644 index 0000000..b674fa7 --- /dev/null +++ b/src/components/UploadBoxDraggble.tsx @@ -0,0 +1,161 @@ +import { CloseCircle, DocumentUpload, Gallery } from 'iconsax-react' +import { FC, useCallback, useEffect, useState } from 'react' +import { useDropzone } from 'react-dropzone'; +import { useTranslation } from 'react-i18next'; +import { clx } from '../helpers/utils'; + +type Props = { + label: string; + onChange: (file: File[]) => void; + isMultiple?: boolean; + isFile?: boolean, + preview?: string[], + onChangePreview?: (preview: string[]) => void, + getCover?: (url: string) => void, + coverUrl?: string, + isReset?: boolean +} + +const UploadBoxDraggble: FC = (props: Props) => { + + const { t } = useTranslation('global') + const [files, setFiles] = useState([]) + const [perviews, setPerviews] = useState(props.preview ? props.preview : []) + const [isFill, setIsFill] = useState(false) + const [cover, setCover] = useState(props.coverUrl ? props.coverUrl : '') + + const onDrop = useCallback((acceptedFiles: File[]) => { + if (props.isMultiple) { + const array = [...files] + array.push(acceptedFiles[0]) + setFiles(array) + props.onChange(array) + } else { + setFiles([acceptedFiles[0]]) + props.onChange([acceptedFiles[0]]) + } + }, [files]) + const { getRootProps, getInputProps } = useDropzone({ onDrop }) + + const handleDelete = (index: number) => { + const array = [...files] + array.splice(index, 1) + setFiles(array) + props.onChange(array) + } + + const handleDeletePreview = (index: number) => { + const array = [...perviews]; + array.splice(index, 1); + setPerviews(array); + if (props.onChangePreview) { + props.onChangePreview(array); + } + } + + useEffect(() => { + + if (props.preview && props.preview.length > 0 && !isFill) { + setPerviews(props.preview) + console.log('preview', props.preview); + + setIsFill(true) + } + + }, [props.preview, isFill]) + + useEffect(() => { + setCover(props.coverUrl ? props.coverUrl : '') + }, [props.coverUrl]) + + useEffect(() => { + if (props.isReset) { + setFiles([]) + setPerviews([]) + } + }, [props.isReset]) + + + return ( +
+
+ + +
+ {props.label} +
+ +
+ +
{t('upload')}
+
+
+ + { + files.length > 0 || perviews ? ( +
+ { + perviews && perviews.map((item, index) => { + return ( +
+
+ { + if (props.getCover) { + setCover(item) + props.getCover(item) + } + }} src={item} + className={clx( + 'size-10 rounded-full object-cover', + cover === item ? 'border-2 border-red-400' : '' + )} /> +
handleDeletePreview(index)} className='absolute -left-2 -top-2 shadow-md bg-white size-5 rounded-full flex justify-center items-center'> + +
+
+
+ ) + }) + } + { + files.map((file, index) => { + if (props.isFile) { + return ( +
+
+
{file.name}
+
+ handleDelete(index)} className='size-4 ' color='red' /> +
+
+
+ ) + } + else + return ( +
+
+ {file.name} +
+ handleDelete(index)} className='size-4 ' color='red' /> +
+
+
+ ) + }) + } +
+ ) : null + } + +
+ ) +} + +export default UploadBoxDraggble \ No newline at end of file diff --git a/src/components/UploadButton.tsx b/src/components/UploadButton.tsx new file mode 100644 index 0000000..a2d597c --- /dev/null +++ b/src/components/UploadButton.tsx @@ -0,0 +1,50 @@ +import { CloseCircle, Paperclip2 } from 'iconsax-react' +import { FC, useCallback, useState } from 'react' +import { useTranslation } from 'react-i18next' +import { useDropzone } from 'react-dropzone' + + +type Props = { + title?: string +} + +const UploadButton: FC = (props) => { + + const { t } = useTranslation() + const { title } = props + + const [files, setFiles] = useState([]) + + const onDrop = useCallback((acceptedFiles: File[]) => { + setFiles((prev) => [...prev, ...acceptedFiles]) + }, []) + + const { getRootProps, getInputProps } = useDropzone({ onDrop }) + + const handleRemove = (index: number) => { + const array = [...files] + array.splice(index, 1) + setFiles(array) + } + + + return ( +
+
+ + + +
{title ? title : t('attachment_select')}
+
+ + {files.map((file, index) => ( +
+ {file.name} + handleRemove(index)} /> +
+ ))} +
+ ) +} + +export default UploadButton \ No newline at end of file diff --git a/src/components/types/TableTypes.ts b/src/components/types/TableTypes.ts new file mode 100644 index 0000000..37126df --- /dev/null +++ b/src/components/types/TableTypes.ts @@ -0,0 +1,41 @@ +import { ReactNode } from "react"; +import { RowActionItem } from "../RowActionsDropdown"; + +export type RowDataType = Record & { id: string | number }; + +export interface ColumnType { + title: string; + key: string; + render?: (item: T) => React.ReactNode; + width?: string | number; + align?: "left" | "center" | "right"; + sortable?: boolean; + className?: string; +} + +export interface PaginationConfig { + currentPage: number; + totalPages: number; + onPageChange: (page: number) => void; +} + +export interface TableProps { + columns: ColumnType[]; + data?: T[]; + isLoading?: boolean; + onRowClick?: (id: T["id"], item: T) => void; + className?: string; + rowClassName?: string | ((item: T, index: number) => string); + noDataMessage?: React.ReactNode; + headerClassName?: string; + emptyRowsCount?: number; + showHeader?: boolean; + actions?: ReactNode; + actionsClassName?: string; + actionsPosition?: "top" | "header-replace" | "above-header"; + selectable?: boolean; + selectedActions?: ReactNode; + onSelectionChange?: (selectedRows: T[]) => void; + rowActions?: (item: T) => RowActionItem[]; + pagination?: PaginationConfig; +} diff --git a/src/components/ui/checkbox.tsx b/src/components/ui/checkbox.tsx new file mode 100644 index 0000000..defeb01 --- /dev/null +++ b/src/components/ui/checkbox.tsx @@ -0,0 +1,30 @@ +import * as React from "react" +import * as CheckboxPrimitive from "@radix-ui/react-checkbox" +import { CheckIcon } from "lucide-react" + +import { cn } from "@/lib/utils" + +function Checkbox({ + className, + ...props +}: React.ComponentProps) { + return ( + + + + + + ) +} + +export { Checkbox } diff --git a/src/components/ui/switch.tsx b/src/components/ui/switch.tsx new file mode 100644 index 0000000..b0363e3 --- /dev/null +++ b/src/components/ui/switch.tsx @@ -0,0 +1,29 @@ +import * as React from "react" +import * as SwitchPrimitive from "@radix-ui/react-switch" + +import { cn } from "@/lib/utils" + +function Switch({ + className, + ...props +}: React.ComponentProps) { + return ( + + + + ) +} + +export { Switch } diff --git a/src/config/axios.ts b/src/config/axios.ts new file mode 100644 index 0000000..2af51c6 --- /dev/null +++ b/src/config/axios.ts @@ -0,0 +1,25 @@ +import axios from "axios"; +import { getToken } from "./func"; + +const axiosInstance = axios.create({ + baseURL: import.meta.env.VITE_BASE_URL, +}); + +axiosInstance.interceptors.response.use( + (response) => response, + (error) => { + return Promise.reject(error); + } +); + +axiosInstance.interceptors.request.use(async function (config) { + const token = getToken(); + + config.headers.Authorization = "Bearer " + token; + config.headers["x-business-id"] = localStorage.getItem( + import.meta.env.VITE_WORKSPACE_ID + ); + return config; +}); + +export default axiosInstance; diff --git a/src/config/axiosDanak.ts b/src/config/axiosDanak.ts new file mode 100644 index 0000000..580452f --- /dev/null +++ b/src/config/axiosDanak.ts @@ -0,0 +1,22 @@ +import axios from "axios"; +import { getToken } from "./func"; + +const axiosDanak = axios.create({ + baseURL: import.meta.env.VITE_DANAK_BASE_URL, +}); + +axiosDanak.interceptors.response.use( + (response) => response, + (error) => { + return Promise.reject(error); + } +); + +axiosDanak.interceptors.request.use(async function (config) { + const token = getToken(); + + config.headers.Authorization = "Bearer " + token; + return config; +}); + +export default axiosDanak; diff --git a/src/config/func.ts b/src/config/func.ts new file mode 100644 index 0000000..093bee3 --- /dev/null +++ b/src/config/func.ts @@ -0,0 +1,66 @@ +import Cookie from "js-cookie"; + +export function isEmail(input: string): boolean { + const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/; + return emailRegex.test(input); +} + +export function NumberFormat(number: number): string { + return Intl.NumberFormat("fa-IR").format(number); +} + +export const getToken = () => { + return Cookie.get(import.meta.env.VITE_TOKEN_NAME); +}; + +export const getRefreshToken = () => { + return Cookie.get(import.meta.env.VITE_REFRESH_TOKEN_NAME); +}; + +const isProduction = import.meta.env.MODE === "production"; +const domain = isProduction ? ".danakcorp.com" : undefined; + +export const setToken = async (token: string) => { + Cookie.set(import.meta.env.VITE_TOKEN_NAME, token, { domain }); +}; + +export const setRefreshToken = async (refreshToken: string) => { + Cookie.set(import.meta.env.VITE_REFRESH_TOKEN_NAME, refreshToken, { + domain, + }); +}; + +export const removeToken = async () => { + Cookie.remove(import.meta.env.VITE_TOKEN_NAME, { domain, path: "/" }); +}; + +export const removeRefreshToken = async () => { + Cookie.remove(import.meta.env.VITE_REFRESH_TOKEN_NAME, { domain, path: "/" }); +}; + +export const timeAgo = (date: string | Date): string => { + const now = new Date(); + const past = new Date(date); + const diff = Math.floor((now.getTime() - past.getTime()) / 1000); // اختلاف بر حسب ثانیه + + const units = [ + { name: "سال", value: 60 * 60 * 24 * 365 }, + { name: "ماه", value: 60 * 60 * 24 * 30 }, + { name: "روز", value: 60 * 60 * 24 }, + { name: "ساعت", value: 60 * 60 }, + { name: "دقیقه", value: 60 }, + { name: "ثانیه", value: 1 }, + ]; + + for (const unit of units) { + const amount = Math.floor(diff / unit.value); + if (amount >= 1) return `${amount} ${unit.name} پیش`; + } + + return "همین الان"; +}; + +export const convertToGB = (bytes: number): string => { + const GB = bytes / (1024 * 1024 * 1024); + return GB.toFixed(2); +}; diff --git a/src/config/orvalAxios.ts b/src/config/orvalAxios.ts new file mode 100644 index 0000000..22ea517 --- /dev/null +++ b/src/config/orvalAxios.ts @@ -0,0 +1,50 @@ +import axios, { AxiosRequestConfig } from "axios"; +import { getToken } from "./func"; + +const orvalAxiosInstance = axios.create({ + baseURL: import.meta.env.VITE_BASE_URL, +}); + +orvalAxiosInstance.interceptors.response.use( + (response) => response, + (error) => { + return Promise.reject(error); + } +); + +orvalAxiosInstance.interceptors.request.use(async (config) => { + const token = getToken(); + + config.headers["Content-Type"] = "application/json"; + config.headers["Accept"] = "application/json"; + + if (token) { + config.headers["Authorization"] = `Bearer ${token}`; + } + + const businessId = localStorage.getItem(import.meta.env.VITE_WORKSPACE_ID); + if (businessId) { + config.headers["x-business-id"] = businessId; + } + + return config; +}); + +export const customAxiosInstance = ( + config: AxiosRequestConfig, + options?: AxiosRequestConfig +): Promise => { + const source = axios.CancelToken.source(); + const promise = orvalAxiosInstance({ + ...config, + ...options, + cancelToken: source.token, + }).then(({ data }) => data); + + // @ts-expect-error - Adding cancel method to promise + promise.cancel = () => { + source.cancel("Query was cancelled"); + }; + + return promise; +}; diff --git a/src/helpers/types.ts b/src/helpers/types.ts new file mode 100644 index 0000000..d8f7039 --- /dev/null +++ b/src/helpers/types.ts @@ -0,0 +1,20 @@ +type Without = { [P in Exclude]?: never }; + +export type XOR = T | U extends object + ? (Without & U) | (Without & T) + : T | U; + +export type ItemsSelectType = { + value: string; + label: string; +}; + +export type ErrorType = Error & { + response?: { + data?: { + error: { + message: string[]; + }; + }; + }; +}; diff --git a/src/helpers/utils.ts b/src/helpers/utils.ts new file mode 100644 index 0000000..aa728fe --- /dev/null +++ b/src/helpers/utils.ts @@ -0,0 +1,11 @@ +import { twMerge } from "tailwind-merge"; + +/** + * Concatenates truthy classes into a space-separated string. + * + * @param classes - The classes to concatenate. + * @returns The concatenated classes. + */ +export const clx = (...classes: (string | boolean | undefined)[]): string => { + return twMerge(classes.filter(Boolean).join(" ")); +}; diff --git a/src/index.css b/src/index.css new file mode 100644 index 0000000..512fd2a --- /dev/null +++ b/src/index.css @@ -0,0 +1,249 @@ +@import "tailwindcss"; +@import "tw-animate-css"; + +@custom-variant dark (&:is(.dark *)); + +html { + direction: rtl; + overflow: hidden; + max-width: 100%; +} + +body { + font-family: irancell; + margin: 0; + padding: 0; + width: 100%; + direction: rtl; + overflow: hidden !important; + background: #eceef6; + font-weight: 300; + overflow: hidden; + font-feature-settings: "lnum"; /* اطمینان از نمایش اعداد انگلیسی */ +} + +/* ریسپانسیو شدن برای صفحات کوچک */ +@media (max-width: 768px) { + .no-scrollbar::-webkit-scrollbar { + display: none; + } + .no-scrollbar { + -ms-overflow-style: none; + scrollbar-width: none; + } +} + +html, +body { + height: 100%; + margin: 0; + overflow: hidden !important; /* اعمال overflow: hidden با !important */ +} + +html, +body, +#root { + min-height: 100% !important; + height: 100%; +} +* { + outline: none; +} + +input::placeholder, +textarea::placeholder { + color: #888888; +} + +@theme { + --color-primary: #000000; + --color-secondary: #eaecf4; + --color-border: #d0d0d0; + --color-description: #888888; + --radius-2.5: 10px; +} + +.rmdp-input { + min-height: 40px; + background-color: white; + border-radius: 12px !important; + border: 1px solid #d0d0d0 !important; + font-size: 12px !important; + width: 100% !important; + margin: 0px; + padding-right: 16px !important; +} +.readOny .rmdp-input { + background-color: #f5f5f5 !important; + border: none !important; +} +.rmdp-container { + width: 100%; +} + +@theme inline { + --radius-sm: calc(var(--radius) - 4px); + --radius-md: calc(var(--radius) - 2px); + --radius-lg: var(--radius); + --radius-xl: calc(var(--radius) + 4px); + --color-background: var(--background); + --color-foreground: var(--foreground); + --color-card: var(--card); + --color-card-foreground: var(--card-foreground); + --color-popover: var(--popover); + --color-popover-foreground: var(--popover-foreground); + --color-primary: var(--primary); + --color-primary-foreground: var(--primary-foreground); + --color-secondary: var(--secondary); + --color-secondary-foreground: var(--secondary-foreground); + --color-muted: var(--muted); + --color-muted-foreground: var(--muted-foreground); + --color-accent: var(--accent); + --color-accent-foreground: var(--accent-foreground); + --color-destructive: var(--destructive); + --color-border: var(--border); + --color-input: var(--input); + --color-ring: var(--ring); + --color-chart-1: var(--chart-1); + --color-chart-2: var(--chart-2); + --color-chart-3: var(--chart-3); + --color-chart-4: var(--chart-4); + --color-chart-5: var(--chart-5); + --color-sidebar: var(--sidebar); + --color-sidebar-foreground: var(--sidebar-foreground); + --color-sidebar-primary: var(--sidebar-primary); + --color-sidebar-primary-foreground: var(--sidebar-primary-foreground); + --color-sidebar-accent: var(--sidebar-accent); + --color-sidebar-accent-foreground: var(--sidebar-accent-foreground); + --color-sidebar-border: var(--sidebar-border); + --color-sidebar-ring: var(--sidebar-ring); +} + +:root { + --radius: 0.625rem; + --background: oklch(1 0 0); + --foreground: oklch(0.145 0 0); + --card: oklch(1 0 0); + --card-foreground: oklch(0.145 0 0); + --popover: oklch(1 0 0); + --popover-foreground: oklch(0.145 0 0); + --primary: oklch(0.205 0 0); + --primary-foreground: oklch(0.985 0 0); + --secondary: oklch(0.97 0 0); + --secondary-foreground: oklch(0.205 0 0); + --muted: oklch(0.97 0 0); + --muted-foreground: oklch(0.556 0 0); + --accent: oklch(0.97 0 0); + --accent-foreground: oklch(0.205 0 0); + --destructive: oklch(0.577 0.245 27.325); + --border: oklch(0.922 0 0); + --input: oklch(0.922 0 0); + --ring: oklch(0.708 0 0); + --chart-1: oklch(0.646 0.222 41.116); + --chart-2: oklch(0.6 0.118 184.704); + --chart-3: oklch(0.398 0.07 227.392); + --chart-4: oklch(0.828 0.189 84.429); + --chart-5: oklch(0.769 0.188 70.08); + --sidebar: oklch(0.985 0 0); + --sidebar-foreground: oklch(0.145 0 0); + --sidebar-primary: oklch(0.205 0 0); + --sidebar-primary-foreground: oklch(0.985 0 0); + --sidebar-accent: oklch(0.97 0 0); + --sidebar-accent-foreground: oklch(0.205 0 0); + --sidebar-border: oklch(0.922 0 0); + --sidebar-ring: oklch(0.708 0 0); +} + +.dark { + --background: oklch(0.145 0 0); + --foreground: oklch(0.985 0 0); + --card: oklch(0.205 0 0); + --card-foreground: oklch(0.985 0 0); + --popover: oklch(0.205 0 0); + --popover-foreground: oklch(0.985 0 0); + --primary: oklch(0.922 0 0); + --primary-foreground: oklch(0.205 0 0); + --secondary: oklch(0.269 0 0); + --secondary-foreground: oklch(0.985 0 0); + --muted: oklch(0.269 0 0); + --muted-foreground: oklch(0.708 0 0); + --accent: oklch(0.269 0 0); + --accent-foreground: oklch(0.985 0 0); + --destructive: oklch(0.704 0.191 22.216); + --border: oklch(1 0 0 / 10%); + --input: oklch(1 0 0 / 15%); + --ring: oklch(0.556 0 0); + --chart-1: oklch(0.488 0.243 264.376); + --chart-2: oklch(0.696 0.17 162.48); + --chart-3: oklch(0.769 0.188 70.08); + --chart-4: oklch(0.627 0.265 303.9); + --chart-5: oklch(0.645 0.246 16.439); + --sidebar: oklch(0.205 0 0); + --sidebar-foreground: oklch(0.985 0 0); + --sidebar-primary: oklch(0.488 0.243 264.376); + --sidebar-primary-foreground: oklch(0.985 0 0); + --sidebar-accent: oklch(0.269 0 0); + --sidebar-accent-foreground: oklch(0.985 0 0); + --sidebar-border: oklch(1 0 0 / 10%); + --sidebar-ring: oklch(0.556 0 0); +} + +@layer base { + * { + @apply border-border outline-ring/50; + } + body { + @apply bg-background text-foreground; + } +} + +.ql-container { + @apply rounded-b-xl text-right; + font-family: irancell !important; + direction: rtl; + min-height: 100px !important; +} +.ql-toolbar { + @apply rounded-t-xl; +} +.ql-editor { + @apply !text-right; +} + +.dltr { + direction: ltr; +} + +/* Start Generation Here */ +/* Hide scrollbar for all elements */ +* { + scrollbar-width: none; /* Firefox */ + -ms-overflow-style: none; /* Internet Explorer 10+ */ +} + +/* Hide scrollbar for WebKit browsers (Chrome, Safari, Edge) */ +*::-webkit-scrollbar { + display: none; +} + +/* End Generation Here */ + +/* انیمیشن برای فیلترهای موبایل */ +@keyframes fadeInDown { + from { + opacity: 0; + transform: translateY(-10px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +.animate-fadeInDown { + animation: fadeInDown 0.3s ease-out; +} + +.ql-snow .ql-picker:not(.ql-color-picker):not(.ql-icon-picker) svg { + display: none; +} diff --git a/src/langs/fa.json b/src/langs/fa.json new file mode 100644 index 0000000..c5a7860 --- /dev/null +++ b/src/langs/fa.json @@ -0,0 +1,165 @@ +{ + "sidebar": { + "menu": "منو", + "received": "دریافتی ها", + "sent": "ارسال شده ها", + "draft": "پیش نویس ها", + "archive": "آرشیو شده ها", + "profile": "پروفایل", + "trash": "سطل زباله", + "other": "سایر", + "favorite": "نشان شده ها", + "spam": "هرزنامه ها", + "setting": "تنظیمات", + "logout": "خروج", + "admin_panel": "پنل مدیریت" + }, + "header": { + "search": "جستجو" + }, + "errors": { + "required": "این فیلد اجباری است" + }, + "received": { + "title": "دریافتی ها", + "from_date": "از تاریخ", + "to_date": "تا تاریخ", + "all": "همه", + "read": "خوانده شده", + "unread": "خوانده نشده", + "search": "جستجو" + }, + "sent": { + "title": "ارسال شده ها", + "from_date": "از تاریخ", + "to_date": "تا تاریخ", + "all": "همه", + "read": "خوانده شده", + "unread": "خوانده نشده", + "search": "جستجو" + }, + "draft": { + "title": "پیش نویس ها", + "from_date": "از تاریخ", + "to_date": "تا تاریخ", + "search": "جستجو" + }, + "archive": { + "title": "آرشیو شده ها", + "from_date": "از تاریخ", + "to_date": "تا تاریخ", + "all": "همه", + "read": "خوانده شده", + "unread": "خوانده نشده", + "search": "جستجو" + }, + "trash": { + "title": "سطل زباله", + "from_date": "از تاریخ", + "to_date": "تا تاریخ", + "all": "همه", + "read": "خوانده شده", + "unread": "خوانده نشده", + "search": "جستجو" + }, + "setting": { + "title": "تنظیمات", + "personality": "شخصی سازی", + "mail_server": "تنظیمات میل سرور", + "domain": "تنظیمات دامنه", + "address": "نشانی ها", + "setting": "تنظیمات", + "background": "رنگ زمینه", + "upload_background": "تصویر پس زمینه مورد نظر را آپلود کنید", + "size": "سایز", + "horizontal_position": "موقعیت افقی", + "vertical_position": "موقعیت عمودی", + "text": "متن", + "add_text": "اضافه کردن متن", + "button": "دکمه", + "button_text": "متن دکمه", + "button_link": "لینک", + "select": "انتخاب", + "border": "حاشیه", + "text_color": "رنگ متن", + "background_color": "رنگ زمینه", + "border_color": "رنگ حاشیه", + "add_button": "اضافه کردن دکمه", + "image": "تصویر", + "upload_image": "تصویر مورد نظر را آپلود کنید", + "add_image": "اضافه کردن تصویر", + "setting_fetch": "تنظیمات فچ", + "setting_fetch_description": "تنظیمات فچ خود را با دقت انتخاب کنید.", + "setting_smtp": "تنظیمات SMTP", + "setting_smtp_description": "تنظیمات SMTP خود را با دقت وارد کنید.", + "smtp_server": "SMTP سرور", + "smtp_port": "SMTP پورت", + "username": "نام کاربری", + "password": "پسورد", + "record_dns": "رکوردهای DNS", + "record_dns_description": "در این قسمت میتوانید وضعیت رکوردهای DNS سرویس ایمیل خود را بررسی کنید.", + "your_domain": "دامنه شما", + "submit": "ثبت", + "status": "وضعیت", + "search": "جستجو", + "address_title": "عنوان نشانی", + "email": "ایمیل", + "marketing": "بازاریابی", + "actions": "عملیات", + "delete": "حذف کردن ایمیل", + "active": "فعال", + "inactive": "غیرفعال", + "add_address": "اضافه کردن نشانی", + "domain1": "دامنه", + "create": "ساخت", + "header_email": "هدر ایمیل شما", + "content_email": "محتوای ایمیل شما", + "footer_email": "پاورقی ایمیل شما", + "signature": "امضا", + "signature_description": "تصویر و توضیحات امضای خود را با دقت وارد کنید", + "upload_sign": "آپلود امضا", + "description_sign": "توضیحات امضا", + "select_section": "لطفا یک بخش انتخاب کنید", + "title1": "عنوان", + "quota": "فضا/ استفاده شده " + }, + "attachment_select": "اضافه کردن فایل ضمیمه", + "domain": { + "table": { + "record_type": "نوع رکورد", + "record_name": "نام رکورد", + "record_value": "مقدار رکورد", + "priority": "اولویت", + "ttl": "TTL", + "status": "وضعیت" + }, + "status": { + "verified": "تایید شده", + "pending": "در انتظار", + "failed": "ناموفق" + } + }, + "select_file": "انتخاب فایل", + "upload": "آپلود", + "new_message": { + "title": "ارسال پیام جدید", + "to": "ارسال به", + "subject": "موضوع", + "message": "پیام", + "send": "ارسال", + "draft": "پیش نویس", + "recipients_placeholder": "نام گیرنده", + "subject_placeholder": "موضوع پیام", + "message_placeholder": "متن پیام", + "select_priority": "انتخاب اولویت" + }, + "mail": { + "download": "دانلود", + "print": "چاپ", + "subject": "موضوع: ", + "attachments": "فایل های ضمیمه", + "answer": "پاسخ", + "forward": "ارسال به دیگران", + "message": "متن پبام" + } +} diff --git a/src/lib/utils.ts b/src/lib/utils.ts new file mode 100644 index 0000000..bd0c391 --- /dev/null +++ b/src/lib/utils.ts @@ -0,0 +1,6 @@ +import { clsx, type ClassValue } from "clsx" +import { twMerge } from "tailwind-merge" + +export function cn(...inputs: ClassValue[]) { + return twMerge(clsx(inputs)) +} diff --git a/src/main.tsx b/src/main.tsx new file mode 100644 index 0000000..bef5202 --- /dev/null +++ b/src/main.tsx @@ -0,0 +1,10 @@ +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/src/pages/auth/service/Service.ts b/src/pages/auth/service/Service.ts new file mode 100644 index 0000000..5c8c7cb --- /dev/null +++ b/src/pages/auth/service/Service.ts @@ -0,0 +1,7 @@ +import axiosDanak from "@/config/axiosDanak"; +import { RefreshTokenType } from "../types/Types"; + +export const refreshToken = async (params: RefreshTokenType) => { + const { data } = await axiosDanak.post(`/auth/refresh`, params); + return data; +}; diff --git a/src/pages/auth/types/Types.ts b/src/pages/auth/types/Types.ts new file mode 100644 index 0000000..5620433 --- /dev/null +++ b/src/pages/auth/types/Types.ts @@ -0,0 +1,3 @@ +export type RefreshTokenType = { + refreshToken: string; +}; diff --git a/src/pages/dashboard/Dashboard.tsx b/src/pages/dashboard/Dashboard.tsx new file mode 100644 index 0000000..e69de29 diff --git a/src/pages/home/Home.tsx b/src/pages/home/Home.tsx new file mode 100644 index 0000000..23630ea --- /dev/null +++ b/src/pages/home/Home.tsx @@ -0,0 +1,83 @@ +import { FC, useEffect, useState } from 'react' +import { useWorkspaces } from './hooks/useHomeData' +import { workspaceItem } from './types/HomeTypes' +import moment from 'moment-jalaali' + +const Home: FC = () => { + + const getWorkspaces = useWorkspaces() + const [selectedWorkspace, setSelectedWorkspace] = useState(null) + + useEffect(() => { + setSelectedWorkspace(localStorage.getItem(import.meta.env.VITE_WORKSPACE_ID)) + }, []) + + useEffect(() => { + if (getWorkspaces.isError && getWorkspaces.error instanceof Error) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const error = getWorkspaces.error as any; + if (error.response?.status === 403) { + localStorage.removeItem(import.meta.env.VITE_WORKSPACE_ID) + window.location.href = 'https://console.danakcorp.com' + } + } + }, [getWorkspaces.isError, getWorkspaces.data]) + + + const handleChangeWorkspace = (id: string) => { + localStorage.setItem(import.meta.env.VITE_WORKSPACE_ID, id) + setSelectedWorkspace(id) + window.location.reload() + } + + return ( +
+
+ +
+ { + getWorkspaces.data?.data?.workspaces?.map((item: workspaceItem) => { + return ( +
handleChangeWorkspace(item.id)} + > +
+ {item.businessName} +
+ +
+ {item.plan?.name} +
+ +
+
+
تاریخ پایان:
+
{moment(item?.endDate).format('jYYYY/jMM/jDD')}
+
+ + +
+ + + + +
+ ) + }) + } + +
+
+
+
+ ) +} + +export default Home \ No newline at end of file diff --git a/src/pages/home/components/DanakLearning.tsx b/src/pages/home/components/DanakLearning.tsx new file mode 100644 index 0000000..e87affa --- /dev/null +++ b/src/pages/home/components/DanakLearning.tsx @@ -0,0 +1,46 @@ +import { FC } from 'react' +import { useTranslation } from 'react-i18next' +import { ArrowLeft } from 'iconsax-react' +import CoverImage from '../../../assets/images/banner.png' + +const DanakLearning: FC = () => { + + const { t } = useTranslation('global') + + return ( +
+
+
+ {t('home.danak_learning')} +
+
+
{t('home.see_all')}
+ +
+
+ +
+
+
+ danak-learning-1 +
+ +
+
+ لورم ایپسوم متن ساختگی با تولید سادگی +
+
+
دیزاین ,
+
۲۴ دقیقه
+
+
+ آذر ماه 1403 +
+
+
+
+
+ ) +} + +export default DanakLearning \ No newline at end of file diff --git a/src/pages/home/components/ItemDashboard.tsx b/src/pages/home/components/ItemDashboard.tsx new file mode 100644 index 0000000..dd2f811 --- /dev/null +++ b/src/pages/home/components/ItemDashboard.tsx @@ -0,0 +1,37 @@ +import { FC, ReactNode } from 'react' +import { Link } from 'react-router-dom' + +type Props = { + title: string + icon: ReactNode, + color: string, + count: number, + description: string, + to?: string +} + +const ItemDashboard: FC = (props: Props) => { + + return ( + +
+ {props.icon} +
+
+ {props.title} +
+ +
+
+
+
{props.count}
+
+ {props.description} +
+
+
+ + ) +} + +export default ItemDashboard \ No newline at end of file diff --git a/src/pages/home/hooks/useHomeData.ts b/src/pages/home/hooks/useHomeData.ts new file mode 100644 index 0000000..3e3f463 --- /dev/null +++ b/src/pages/home/hooks/useHomeData.ts @@ -0,0 +1,9 @@ +import { useQuery } from "@tanstack/react-query"; +import * as api from "../service/HomeService"; + +export const useWorkspaces = () => { + return useQuery({ + queryKey: ["workspaces"], + queryFn: api.getWorkspaces, + }); +}; diff --git a/src/pages/home/service/HomeService.ts b/src/pages/home/service/HomeService.ts new file mode 100644 index 0000000..5a94ff0 --- /dev/null +++ b/src/pages/home/service/HomeService.ts @@ -0,0 +1,8 @@ +import danakAxios from "../../../config/axiosDanak"; + +export const getWorkspaces = async () => { + const { data } = await danakAxios.get( + `/subscriptions/workspaces/${import.meta.env.VITE_SERVICE_ID}` + ); + return data; +}; diff --git a/src/pages/home/types/HomeTypes.ts b/src/pages/home/types/HomeTypes.ts new file mode 100644 index 0000000..d3aea94 --- /dev/null +++ b/src/pages/home/types/HomeTypes.ts @@ -0,0 +1,48 @@ +import { UserItemType } from "../../users/types/UserTypes"; + +export type workspaceItem = { + id: string; + createdAt: string; + updatedAt: string; + plan: { + id: string; + createdAt: string; + updatedAt: string; + name: string; + duration: number; + price: number; + originalPrice: number; + isActive: boolean; + service: { + id: string; + createdAt: string; + updatedAt: string; + name: string; + title: string; + slug: string; + isDanakSuggest: boolean; + description: string; + author: string; + createDate: string; + userCount: number; + serviceLanguage: string; + softwareLanguage: string; + metaDescription: string; + isActive: boolean; + showInSlider: boolean; + link: string; + icon: string; + coverUrl: string; + deletedAt: string | null; + }; + deletedAt: string | null; + }; + startDate: string; + endDate: string; + businessName: string; + businessPhone: string; + description: string; + slug: string; + status: string; + staff: UserItemType[]; +}; diff --git a/src/pages/setting/Setting.tsx b/src/pages/setting/Setting.tsx new file mode 100644 index 0000000..b68947c --- /dev/null +++ b/src/pages/setting/Setting.tsx @@ -0,0 +1,81 @@ +import { FC, useState, useEffect } from 'react' +import { useTranslation } from 'react-i18next' +import { useLocation } from 'react-router-dom' +import { SettingTabEnum } from './enum/SettingEnum' +import Personality from './personality/Personality' +import Domain from './domain/Domain' +import MailServer from './mail-server/MailServer' +import Address from './address/Address' +import PersonalitySidebar from './personality/SideBar' +import Signture from './signture/Signture' +import { Paths } from '@/utils/Paths' + +const Setting: FC = () => { + const { t } = useTranslation() + const location = useLocation() + const [activeTab, setActiveTab] = useState(SettingTabEnum.SETTING_DOMAIN) + + // Map URL paths to setting tabs + const getTabFromPath = (pathname: string): SettingTabEnum => { + switch (pathname) { + case Paths.settingMailServer: + return SettingTabEnum.SETTING_MAIL_SERVER + case Paths.settingDomain: + return SettingTabEnum.SETTING_DOMAIN + case Paths.settingAddress: + return SettingTabEnum.SETTING_ADDRESS + case Paths.settingPersonality: + return SettingTabEnum.SETTING_PERSONALITY + case Paths.settingSignature: + return SettingTabEnum.SETTING_SIGNATURE + default: + return SettingTabEnum.SETTING_DOMAIN + } + } + + // Map setting tabs to URL paths + + // Update active tab when URL changes + useEffect(() => { + const tabFromPath = getTabFromPath(location.pathname) + setActiveTab(tabFromPath) + }, [location.pathname]) + + const renderActiveTab = () => { + switch (activeTab) { + case SettingTabEnum.SETTING_MAIL_SERVER: + return ; + case SettingTabEnum.SETTING_DOMAIN: + return ; + case SettingTabEnum.SETTING_ADDRESS: + return
; + case SettingTabEnum.SETTING_SIGNATURE: + return ; + case SettingTabEnum.SETTING_PERSONALITY: + return ( +
+
+ +
+
+ +
+
+ ); + default: + return null; + } + }; + + return ( +
+

{t('setting.title')}

+ +
+ {renderActiveTab()} +
+
+ ) +} + +export default Setting \ No newline at end of file diff --git a/src/pages/setting/address/Address.tsx b/src/pages/setting/address/Address.tsx new file mode 100644 index 0000000..912537a --- /dev/null +++ b/src/pages/setting/address/Address.tsx @@ -0,0 +1,218 @@ +import Input from '@/components/Input' +import Select from '@/components/Select' +import Table from '@/components/Table' +import { ColumnType } from '@/components/types/TableTypes' +import { FC, useState } from 'react' +import { useTranslation } from 'react-i18next' +import Button from '@/components/Button' +import { TickCircle } from 'iconsax-react' +import { useForm } from 'react-hook-form' +import { AddressData, CreateAddressType } from './types/Types' +import { useGetDomains } from '../domain/hooks/useDomainData' +import { yupResolver } from "@hookform/resolvers/yup" +import * as yup from "yup" +import { useCreateAddress, useGetAddress } from './hooks/useAddressData' +import { toast } from '@/components/Toast' +import { ErrorType } from '@/helpers/types' +import ProgressBarEmail from './components/ProgressBarEmail' +import ToggleStatus from './components/ToggleStatus' + + + +const Address: FC = () => { + const { t } = useTranslation() + + const schema = yup.object().shape({ + title: yup.string().required(t('errors.required')), + username: yup.string().required(t('errors.required')), + password: yup.string().required(t('errors.required')), + domainId: yup.string().required(t('errors.required')), + }) + + const [search, setSearch] = useState('') + const [status, setStatus] = useState('all') + + const { data: domain } = useGetDomains() + const { mutate: createAddress, isPending } = useCreateAddress() + const { data: addresses, isPending: isPendingAddress } = useGetAddress(search, status) + const { register, handleSubmit, formState: { errors }, + } = useForm({ + resolver: yupResolver(schema), + defaultValues: { + domainId: domain?.data?.domain?.id || '', + } + }) + + const columns: ColumnType[] = [ + { + title: t('setting.address_title'), + key: 'title', + width: '200px' + }, + { + title: t('setting.email'), + key: 'email', + width: '300px', + render: (item: AddressData) => ( +
+ {item.emailAddress} +
+ ) + }, + { + title: t('setting.quota'), + key: 'quota', + width: '300px', + render: (item: AddressData) => { + + return ( + + ) + } + }, + { + title: t('setting.status'), + key: 'status', + width: '120px', + align: 'center', + render: (item: AddressData) => ( +
+ +
+ ) + } + ] + + const statusOptions = [ + { value: 'all', label: 'همه' }, + { value: 'active', label: t('setting.active') }, + { value: 'inactive', label: t('setting.inactive') } + ] + + const onSubmit = (params: CreateAddressType) => { + createAddress(params, { + onSuccess: (data) => { + toast(data?.data?.message, 'success') + }, + onError: (error: ErrorType) => { + toast(error.response?.data?.error?.message[0], 'error') + } + }) + } + + return ( +
+
+
+
+ setSearch(e)} + /> +
+
+ +
+ { + props.text ? + props.text + : + props.children + } +
console.log('Page:', page) + }} + /> + + +
+
+ {t('setting.add_address')} +
+ + {/*
+
+ {t('setting.status')} +
+
+ +
+
*/} + +
+ +
+ +
+ +
+ +
+ +
+ @ {domain?.data?.domain?.name} +
+
+ +
+ +
+ +
+
رمز عبور می‌بایست:
+
    +
  • حداقل ۸ کاراکتر باشد
  • +
  • ترکیبی از حروف کوچک و بزرگ باشد
  • +
  • شامل اعداد باشد
  • +
  • شامل کاراکتر های خاص (نماد ها) باشد
  • +
+
+ +
+ +
+
+ + ) +} + +export default Address \ No newline at end of file diff --git a/src/pages/setting/address/components/ProgressBarEmail.tsx b/src/pages/setting/address/components/ProgressBarEmail.tsx new file mode 100644 index 0000000..ae5d37d --- /dev/null +++ b/src/pages/setting/address/components/ProgressBarEmail.tsx @@ -0,0 +1,33 @@ +import { convertToGB } from '@/config/func' +import { FC } from 'react' +import { AddressData } from '../types/Types' + +const ProgressBarEmail: FC<{ item: AddressData }> = ({ item }) => { + const usedQuota = item.emailQuotaUsed || 0; + const totalQuota = item.emailQuota || 0; + const percentage = Math.min((usedQuota / totalQuota) * 100, 100); + + return ( +
+
+ + {convertToGB(usedQuota)} GB / {convertToGB(totalQuota)} GB + + {/* + {percentage.toFixed(1)}% + */} +
+
+
90 ? 'bg-red-500' : + percentage > 70 ? 'bg-yellow-500' : + 'bg-green-500' + }`} + style={{ width: `${percentage}%` }} + >
+
+
+ ) +} + +export default ProgressBarEmail \ No newline at end of file diff --git a/src/pages/setting/address/components/ToggleStatus.tsx b/src/pages/setting/address/components/ToggleStatus.tsx new file mode 100644 index 0000000..d20336e --- /dev/null +++ b/src/pages/setting/address/components/ToggleStatus.tsx @@ -0,0 +1,18 @@ +import { Switch } from '@/components/ui/switch' +import { FC, useState } from 'react' +import { useToggleStatus } from '../hooks/useAddressData' + +const ToggleStatus: FC<{ defaultStatus: boolean, id: string }> = ({ defaultStatus, id }) => { + const [isActive, setIsActive] = useState(defaultStatus) + const { mutate: toggleStatus } = useToggleStatus() + + const handleToggleStatus = () => { + toggleStatus(id) + setIsActive(!isActive) + } + return ( + + ) +} + +export default ToggleStatus \ No newline at end of file diff --git a/src/pages/setting/address/hooks/useAddressData.ts b/src/pages/setting/address/hooks/useAddressData.ts new file mode 100644 index 0000000..9d3dd07 --- /dev/null +++ b/src/pages/setting/address/hooks/useAddressData.ts @@ -0,0 +1,26 @@ +import { useMutation, useQuery } from "@tanstack/react-query"; +import * as api from "../service/Service"; +import { useQueryClient } from "@tanstack/react-query"; + +export const useGetAddress = (search: string, status: string) => { + return useQuery({ + queryKey: ["address", search, status], + queryFn: () => api.getAddress(search, status), + }); +}; + +export const useCreateAddress = () => { + const queryClient = useQueryClient(); + return useMutation({ + mutationFn: api.createAddress, + onSuccess: () => { + queryClient.invalidateQueries({ queryKey: ["address"] }); + }, + }); +}; + +export const useToggleStatus = () => { + return useMutation({ + mutationFn: api.toggleStatus, + }); +}; diff --git a/src/pages/setting/address/service/Service.ts b/src/pages/setting/address/service/Service.ts new file mode 100644 index 0000000..2a41a62 --- /dev/null +++ b/src/pages/setting/address/service/Service.ts @@ -0,0 +1,21 @@ +import axios from "@/config/axios"; +import { CreateAddressType } from "../types/Types"; + +export const getAddress = async (search: string, status: string) => { + const query = new URLSearchParams(); + if (search) query.set("q", search); + if (status && status !== "all") + query.set("isActive", status === "active" ? "1" : "0"); + const { data } = await axios.get(`/users?${query.toString()}`); + return data; +}; + +export const createAddress = async (params: CreateAddressType) => { + const { data } = await axios.post(`/users`, params); + return data; +}; + +export const toggleStatus = async (id: string) => { + const { data } = await axios.patch(`/users/${id}/toggle-status`); + return data; +}; diff --git a/src/pages/setting/address/types/Types.ts b/src/pages/setting/address/types/Types.ts new file mode 100644 index 0000000..b423264 --- /dev/null +++ b/src/pages/setting/address/types/Types.ts @@ -0,0 +1,58 @@ +export type CreateAddressType = { + username: string; + password: string; + domainId: string; + title: string; +}; + +export interface AddressData extends Record { + id: string; + createdAt: string; + updatedAt: string; + deletedAt: string | null; + title: string; + userName: string; + password: string; + emailAddress: string; + emailEnabled: boolean; + emailQuota: number; + emailQuotaUsed: number; + emailAccountId: string; + displayName: string; + isActive: boolean; + emailSignature: string | null; + role: string; + business: { + id: string; + createdAt: string; + updatedAt: string; + deletedAt: string | null; + danakSubscriptionId: string; + name: string; + slug: string; + logoUrl: string | null; + domain: string; + }; + domain: { + id: string; + createdAt: string; + updatedAt: string; + deletedAt: string | null; + name: string; + status: string; + isVerified: boolean; + isActive: boolean; + verifiedAt: string; + lastCheckedAt: string | null; + notes: string; + dkimEnabled: boolean; + dkimSelector: string; + dkimPrivateKey: string; + dkimPublicKey: string; + spfEnabled: boolean; + spfRecord: string | null; + dmarcEnabled: boolean; + dmarcPolicy: string | null; + business: string; + }; +} diff --git a/src/pages/setting/domain/Domain.tsx b/src/pages/setting/domain/Domain.tsx new file mode 100644 index 0000000..87c52fb --- /dev/null +++ b/src/pages/setting/domain/Domain.tsx @@ -0,0 +1,156 @@ +import Table from '@/components/Table' +import { FC, useEffect, useState } from 'react' +import { useTranslation } from 'react-i18next' +import { TickCircle, Copy, CloseCircle, Clock, TickSquare } from 'iconsax-react' +import CreateDomain from './components/CreateDomain' +import { useGetDnsRecords } from './hooks/useDomainData' +import { DnsRecordType } from './types/Types' + +const Domain: FC = () => { + const { t } = useTranslation() + const [disabled, setDisabled] = useState(false) + const { data, isLoading } = useGetDnsRecords(disabled) + const [copiedField, setCopiedField] = useState(null) + + useEffect(() => { + if (data?.data?.overallStatus?.isVerified && !disabled) { + setDisabled(true) + } + }, [data]) + + const getStatusIcon = (status: DnsRecordType['status']) => { + switch (status) { + case 'VERIFIED': + return ( +
+ + {t('domain.status.verified')} +
+ ) + case 'PENDING': + return ( +
+ + {t('domain.status.pending')} +
+ ) + case 'FAILED': + return ( +
+ + {t('domain.status.failed')} +
+ ) + default: + return null + } + } + + const copyToClipboard = (text: string, fieldKey: string) => { + navigator.clipboard.writeText(text).then(() => { + setCopiedField(fieldKey) + setTimeout(() => { + setCopiedField(null) + }, 2000) + }) + } + + const columns = [ + { + title: t('domain.table.record_type'), + key: 'type', + width: '100px', + align: 'center' as const, + }, + { + title: t('domain.table.record_name'), + key: 'name', + render: (record: DnsRecordType) => { + const fieldKey = `name-${record.id}` + const isCopied = copiedField === fieldKey + + return ( +
+ + {record.name} +
+ ) + } + }, + { + title: t('domain.table.record_value'), + key: 'value', + render: (record: DnsRecordType) => { + const fieldKey = `value-${record.id}` + const isCopied = copiedField === fieldKey + + return ( +
+ + {record.value} +
+ ) + } + }, + { + title: t('domain.table.priority'), + key: 'priority', + width: '80px', + align: 'center' as const, + render: (record: DnsRecordType) => ( + {record.priority || '-'} + ) + }, + { + title: t('domain.table.ttl'), + key: 'ttl', + width: '80px', + align: 'center' as const, + render: (record: DnsRecordType) => ( + {record.ttl} + ) + }, + { + title: t('domain.table.status'), + key: 'status', + render: (record: DnsRecordType) => getStatusIcon(record.status) + }, + ] + + const dnsRecords = data?.data?.dnsRecords || [] + + return ( +
+ + +
+
+ + + ) +} + +export default Domain \ No newline at end of file diff --git a/src/pages/setting/domain/components/CreateDomain.tsx b/src/pages/setting/domain/components/CreateDomain.tsx new file mode 100644 index 0000000..1721bd9 --- /dev/null +++ b/src/pages/setting/domain/components/CreateDomain.tsx @@ -0,0 +1,76 @@ +import Button from '@/components/Button' +import Input from '@/components/Input' +import { toast } from '@/components/Toast' +import { FC, useEffect, useState } from 'react' +import { useTranslation } from 'react-i18next' +import { useCreateDomain, useGetDomains } from '../hooks/useDomainData' +import { ErrorType } from '@/helpers/types' + +const CreateDomain: FC = () => { + + const { t } = useTranslation() + const { mutate: createDomain, isPending } = useCreateDomain() + const { data: domains } = useGetDomains() + const [domain, setDomain] = useState('') + const [isVerified, setIsVerified] = useState(false) + + useEffect(() => { + if (domains?.data?.domain) { + setDomain(domains?.data?.domain?.name) + if (domains?.data?.domain?.isVerified) { + setIsVerified(true) + } + } + }, [domains]) + + + const handleCreateDomain = () => { + createDomain({ + name: domain, + notes: domain + }, { + onSuccess: (data) => { + toast(data.message, 'success') + setDomain('') + }, + onError: (error: ErrorType) => { + toast(error.response?.data?.error?.message[0], 'error') + } + }) + } + return ( +
+
+
+ {t('setting.record_dns')} +
+

+ {t('setting.record_dns_description')} +

+
+ +
+ setDomain(e.target.value)} + readOnly={isVerified} + /> + + { + !isVerified && +
+
+ ) +} + +export default CreateDomain \ No newline at end of file diff --git a/src/pages/setting/domain/hooks/useDomainData.ts b/src/pages/setting/domain/hooks/useDomainData.ts new file mode 100644 index 0000000..f807910 --- /dev/null +++ b/src/pages/setting/domain/hooks/useDomainData.ts @@ -0,0 +1,32 @@ +import { useMutation, useQuery } from "@tanstack/react-query"; +import { CreateDomainType } from "../types/Types"; +import * as api from "../service/DomainService"; + +export const useCreateDomain = () => { + return useMutation({ + mutationFn: (variables: CreateDomainType) => api.createDomain(variables), + }); +}; + +export const useGetDomains = () => { + return useQuery({ + queryKey: ["domains"], + queryFn: () => api.getDomains(), + }); +}; + +export const useGetDnsRecords = (disabled?: boolean) => { + return useQuery({ + queryKey: ["dns-records"], + queryFn: () => api.getDnsRecords(), + refetchInterval: 3000, + enabled: !disabled, + }); +}; + +export const useVerifyDnsRecord = () => { + return useQuery({ + queryKey: ["verify-dns-record"], + queryFn: () => api.verifyDnsRecord(), + }); +}; diff --git a/src/pages/setting/domain/service/DomainService.ts b/src/pages/setting/domain/service/DomainService.ts new file mode 100644 index 0000000..990f073 --- /dev/null +++ b/src/pages/setting/domain/service/DomainService.ts @@ -0,0 +1,22 @@ +import axios from "@/config/axios"; +import { CreateDomainType } from "../types/Types"; + +export const createDomain = async (params: CreateDomainType) => { + const { data } = await axios.post(`/domains`, params); + return data; +}; + +export const getDomains = async () => { + const { data } = await axios.get(`/domains`); + return data; +}; + +export const getDnsRecords = async () => { + const { data } = await axios.get(`/domains/dns-records`); + return data; +}; + +export const verifyDnsRecord = async () => { + const { data } = await axios.get(`/domains/verify-dns`); + return data; +}; diff --git a/src/pages/setting/domain/types/Types.ts b/src/pages/setting/domain/types/Types.ts new file mode 100644 index 0000000..33ed777 --- /dev/null +++ b/src/pages/setting/domain/types/Types.ts @@ -0,0 +1,33 @@ +import { IResponse } from "@/types/response.types"; + +export type CreateDomainType = { + name: string; + notes?: string; +}; + +export type DnsRecordType = { + id: string; + createdAt: string; + updatedAt: string; + deletedAt: string | null; + wildduckId: string | null; + name: string; + type: "MX" | "SPF" | "DMARC" | "DKIM" | "TXT" | "A" | "AAAA" | "CNAME"; + value: string; + ttl: number; + priority: number | null; + status: "PENDING" | "VERIFIED" | "FAILED"; + isRequired: boolean; + isActive: boolean; + lastVerifiedAt: string | null; + lastCheckedAt: string | null; + description: string; + errorMessage: string | null; + verificationAttempts: number; + nextVerificationAt: string | null; + domain: string; +}; + +export type DnsRecordResponseType = IResponse<{ + dnsRecords: DnsRecordType[]; +}>; diff --git a/src/pages/setting/enum/SettingEnum.ts b/src/pages/setting/enum/SettingEnum.ts new file mode 100644 index 0000000..952e899 --- /dev/null +++ b/src/pages/setting/enum/SettingEnum.ts @@ -0,0 +1,15 @@ +export enum SettingTabEnum { + SETTING_MAIL_SERVER = "setting_mail_server", + SETTING_DOMAIN = "setting_domain", + SETTING_ADDRESS = "setting_address", + SETTING_PERSONALITY = "setting_personality", + SETTING_SIGNATURE = "setting_signature", +} + +export enum SideBarTab { + SETTING = "setting", + TEXT = "text", + BUTTON = "button", + IMAGE = "image", + NONE = "none", +} diff --git a/src/pages/setting/mail-server/MailServer.tsx b/src/pages/setting/mail-server/MailServer.tsx new file mode 100644 index 0000000..4713c19 --- /dev/null +++ b/src/pages/setting/mail-server/MailServer.tsx @@ -0,0 +1,79 @@ +import Input from '@/components/Input' +import RadioGroup from '@/components/RadioGroup' +import { FC } from 'react' +import { useTranslation } from 'react-i18next' + +const Domain: FC = () => { + const { t } = useTranslation() + return ( +
+
+
+
+
+ {t('setting.setting_fetch')} +
+
+ {t('setting.setting_fetch_description')} +
+
+
+ null} + selected='1' + /> +
+
+
+
+
+
+
+ {t('setting.setting_smtp')} +
+
+ {t('setting.setting_smtp_description')} +
+
+ +
+ +
+ +
+
+ +
+
+ +
+
+
+
+
+ ) +} + +export default Domain \ No newline at end of file diff --git a/src/pages/setting/personality/Personality.tsx b/src/pages/setting/personality/Personality.tsx new file mode 100644 index 0000000..5f81164 --- /dev/null +++ b/src/pages/setting/personality/Personality.tsx @@ -0,0 +1,20 @@ +import { FC } from 'react' +import HeaderSection from './components/HeaderSection' +import ContentSection from './components/ContentSection' +import FooterSection from './components/FooterSection' + +const Personality: FC = () => { + return ( +
+
+ + + + + +
+ + ) +} + +export default Personality \ No newline at end of file diff --git a/src/pages/setting/personality/SideBar.tsx b/src/pages/setting/personality/SideBar.tsx new file mode 100644 index 0000000..7b3730d --- /dev/null +++ b/src/pages/setting/personality/SideBar.tsx @@ -0,0 +1,67 @@ +import { FC, useState, useRef, useEffect } from 'react' +import { Gallery, LinkSquare, Setting4, Text } from 'iconsax-react' +import Logo from '@/assets/images/logo-small.svg' +import SettingSideBar from './components/SettingSideBar' +import { SideBarTab } from '../enum/SettingEnum' +import TextSidebar from './components/TextSidebar' +import ButtonSidebar from './components/ButtonSidebar' +import ImageSideBar from './components/ImageSideBar' +import { clx } from '@/helpers/utils' + +const PersonalitySidebar: FC = () => { + + const [active, setActive] = useState(SideBarTab.SETTING) + const sidebarRef = useRef(null) + + useEffect(() => { + const handleClickOutside = (event: MouseEvent) => { + // فقط در موبایل (عرض کمتر از 1280px) کار کند + if (window.innerWidth < 1280 && sidebarRef.current && !sidebarRef.current.contains(event.target as Node)) { + setActive(SideBarTab.NONE) + } + } + + if (active !== SideBarTab.NONE) { + document.addEventListener('mousedown', handleClickOutside) + } + + return () => { + document.removeEventListener('mousedown', handleClickOutside) + } + }, [active]) + + return ( +
+ {active !== SideBarTab.NONE && ( +
+ { + active === SideBarTab.SETTING ? + : active === SideBarTab.TEXT ? + : active === SideBarTab.BUTTON ? + : active === SideBarTab.IMAGE ? + : null + } +
+ )} +
+ { + active !== SideBarTab.NONE && Logo + } +
+ setActive(SideBarTab.SETTING)} className='cursor-pointer' /> + setActive(SideBarTab.TEXT)} className='cursor-pointer' /> + setActive(SideBarTab.BUTTON)} className='cursor-pointer' /> + setActive(SideBarTab.IMAGE)} className='cursor-pointer' /> +
+
+
+ ) +} + +export default PersonalitySidebar \ No newline at end of file diff --git a/src/pages/setting/personality/components/ButtonRenderer.tsx b/src/pages/setting/personality/components/ButtonRenderer.tsx new file mode 100644 index 0000000..b68f3e2 --- /dev/null +++ b/src/pages/setting/personality/components/ButtonRenderer.tsx @@ -0,0 +1,94 @@ +import { FC } from 'react' +import { ButtonType, ButtonSize, HorizontalAlignment, VerticalAlignment } from '../types/Types' + +interface ButtonRendererProps { + buttons: ButtonType[] +} + +const ButtonRenderer: FC = ({ buttons }) => { + if (!buttons || buttons.length === 0) return null + + // تبدیل enum به string برای HTML attributes + const getHorizontalAlign = (alignment?: HorizontalAlignment) => { + switch (alignment) { + case HorizontalAlignment.LEFT: + return 'left' + case HorizontalAlignment.RIGHT: + return 'right' + case HorizontalAlignment.CENTER: + default: + return 'center' + } + } + + const getVerticalAlign = (verticalAlignment?: VerticalAlignment) => { + switch (verticalAlignment) { + case VerticalAlignment.TOP: + return 'top' + case VerticalAlignment.BOTTOM: + return 'bottom' + case VerticalAlignment.MIDDLE: + default: + return 'middle' + } + } + + return ( + + + + + + +
+ + + + {buttons.slice(0, 2).map((button, buttonIndex) => ( + + ))} + + +
1 ? '4px' : '0' }}> + + + + + + +
+ + {button.text} + +
+
+
+ ) +} + +export default ButtonRenderer \ No newline at end of file diff --git a/src/pages/setting/personality/components/ButtonSidebar.tsx b/src/pages/setting/personality/components/ButtonSidebar.tsx new file mode 100644 index 0000000..54cc5ff --- /dev/null +++ b/src/pages/setting/personality/components/ButtonSidebar.tsx @@ -0,0 +1,200 @@ +import Button from '@/components/Button' +import ColorPicker from '@/components/ColorPicker' +import Input from '@/components/Input' +import Select from '@/components/Select' +import { Checkbox } from '@/components/ui/checkbox' +import { AlignRight, AlignBottom, AlignHorizontally, AlignLeft, AlignTop, AlignVertically, Link2, Add } from 'iconsax-react' +import { FC, useState } from 'react' +import { useTranslation } from 'react-i18next' +import { usePersonalityStore } from '../store/Store' +import { ButtonSize, HorizontalAlignment, VerticalAlignment } from '../types/Types' + +const ButtonSidebar: FC = () => { + + const { t } = useTranslation() + const { addButtonToActiveItem } = usePersonalityStore() + + const [buttonText, setButtonText] = useState('') + const [buttonLink, setButtonLink] = useState('') + const [buttonSize, setButtonSize] = useState(ButtonSize.MEDIUM) + const [isBorder, setIsBorder] = useState(false) + const [borderSize, setBorderSize] = useState(1) + const [textColor, setTextColor] = useState('#fff') + const [backgroundColor, setBackgroundColor] = useState('#000') + const [borderColor, setBorderColor] = useState('#fff') + const [horizontalAlignment, setHorizontalAlignment] = useState(HorizontalAlignment.CENTER) + const [verticalAlignment, setVerticalAlignment] = useState(VerticalAlignment.MIDDLE) + + const sizeOptions = [ + { label: 'کوچک', value: ButtonSize.SMALL }, + { label: 'متوسط', value: ButtonSize.MEDIUM }, + { label: 'بزرگ', value: ButtonSize.LARGE } + ] + + const handleAddButton = () => { + addButtonToActiveItem({ + text: buttonText, + link: buttonLink, + size: buttonSize, + isBorder, + borderSize, + textColor, + backgroundColor, + borderColor, + alignment: horizontalAlignment, + verticalAlignment, + }) + + // Reset form after adding + setButtonText('') + setButtonLink('') + setButtonSize(ButtonSize.MEDIUM) + setIsBorder(false) + setBorderSize(1) + setTextColor('#fff') + setBackgroundColor('#000') + setBorderColor('#fff') + setHorizontalAlignment(HorizontalAlignment.CENTER) + setVerticalAlignment(VerticalAlignment.MIDDLE) + } + + return ( +
+
{t('setting.button')}
+ +
+ setButtonText(e.target.value)} + /> +
+ +
+ setButtonLink(e.target.value)} + endIcon={} + /> +
+ +
+ setBorderSize(Number(e.target.value))} + /> +
+ } + +
+ +
+ +
+ +
+ +
+ +
+ +
+
+
+ {t('setting.horizontal_position')} +
+
+
setHorizontalAlignment(HorizontalAlignment.RIGHT)} + > + +
+
setHorizontalAlignment(HorizontalAlignment.CENTER)} + > + +
+
setHorizontalAlignment(HorizontalAlignment.LEFT)} + > + +
+
+
+ +
+
+ {t('setting.vertical_position')} +
+
+
setVerticalAlignment(VerticalAlignment.TOP)} + > + +
+
setVerticalAlignment(VerticalAlignment.MIDDLE)} + > + +
+
setVerticalAlignment(VerticalAlignment.BOTTOM)} + > + +
+
+
+
+ +
+ +
+ +
+ ) +} + +export default ButtonSidebar \ No newline at end of file diff --git a/src/pages/setting/personality/components/ContentSection.tsx b/src/pages/setting/personality/components/ContentSection.tsx new file mode 100644 index 0000000..6ecb060 --- /dev/null +++ b/src/pages/setting/personality/components/ContentSection.tsx @@ -0,0 +1,198 @@ +import { FC } from 'react' +import { usePersonalityStore } from '../store/Store' +import { useTranslation } from 'react-i18next' +import { AddCircle } from 'iconsax-react' +import TextRenderer from './TextRenderer' +import ButtonRenderer from './ButtonRenderer' +import ImageRenderer from './ImageRenderer' +import { SectionName, VerticalAlignment, HorizontalAlignment } from '../types/Types' + +const ContentSection: FC = () => { + + const { t } = useTranslation() + const { activeSection, activeItemIndex, data, setActiveSection, setActiveItemIndex } = usePersonalityStore() + + const handleSectionClick = (section: SectionName) => { + setActiveSection(section) + } + + const handleItemClick = (index: number) => { + setActiveItemIndex(index) + } + + // تابع‌های helper برای تعیین alignment دکمه‌ها + const getButtonHorizontalAlign = (button?: { alignment?: HorizontalAlignment }) => { + if (!button || !button.alignment) return 'center' + switch (button.alignment) { + case HorizontalAlignment.LEFT: + return 'left' + case HorizontalAlignment.RIGHT: + return 'right' + case HorizontalAlignment.CENTER: + default: + return 'center' + } + } + + const getButtonVerticalAlign = (button?: { verticalAlignment?: VerticalAlignment }) => { + if (!button || !button.verticalAlignment) return 'middle' + switch (button.verticalAlignment) { + case VerticalAlignment.TOP: + return 'top' + case VerticalAlignment.BOTTOM: + return 'bottom' + case VerticalAlignment.MIDDLE: + default: + return 'middle' + } + } + + return ( + handleSectionClick(SectionName.CONTENT)}> + + { + data.content.columnsCount > 0 ? + + + + + + +
+ + + + { + Array.from({ length: data.content.columnsCount }, (_, index) => { + const item = data.content.items[index]; + const isActive = activeSection === SectionName.CONTENT && activeItemIndex === index; + + return ( + <> + + {index < data.content.columnsCount - 1 && ( + + )} + + ) + }) + } + + +
{ + e.stopPropagation(); + handleItemClick(index); + }} + key={index} + style={{ + width: `${100 / data.content.columnsCount}%`, + height: '246px', + border: isActive ? '1px dashed #0038FF' : '1px dashed #EAECF4', + backgroundColor: item?.backgroundColor || '#ffffff', + backgroundImage: item?.backgroundImage ? `url(${item.backgroundImage})` : 'none', + backgroundSize: item?.style?.backgroundSize || 'cover', + backgroundRepeat: item?.style?.backgroundRepeat || 'no-repeat', + backgroundPosition: item?.style?.backgroundPosition || 'center', + cursor: 'pointer', + padding: '0', + verticalAlign: 'top', + borderRadius: '8px', + position: 'relative' + }} + > + + + {/* اگر فقط دکمه داریم و متن نداریم */} + {(!item?.texts || item.texts.length === 0) && item?.buttons && item.buttons.length > 0 ? ( + + + + ) : ( + <> + {/* ردیف اصلی برای متن */} + + + + {/* ردیف دکمه‌ها */} + {item?.buttons && item.buttons.length > 0 && ( + + + + )} + + )} + +
+ +
0 ? "203" : "230"} + align={item?.texts?.[0]?.alignment || 'center'} + valign={item?.texts?.[0]?.verticalAlignment === VerticalAlignment.TOP ? 'top' : + item?.texts?.[0]?.verticalAlignment === VerticalAlignment.BOTTOM ? 'bottom' : 'middle'} + style={{ + padding: '8px', + fontSize: '14px', + lineHeight: '1.4' + }} + > + + +
+ +
+
+
+ : + + + + + + +
+
+ {t('setting.content_email')} +
+
+ +
+
+ } + + + ) +} + +export default ContentSection \ No newline at end of file diff --git a/src/pages/setting/personality/components/FooterSection.tsx b/src/pages/setting/personality/components/FooterSection.tsx new file mode 100644 index 0000000..311f580 --- /dev/null +++ b/src/pages/setting/personality/components/FooterSection.tsx @@ -0,0 +1,198 @@ +import { FC } from 'react' +import { usePersonalityStore } from '../store/Store' +import { useTranslation } from 'react-i18next' +import { AddCircle } from 'iconsax-react' +import TextRenderer from './TextRenderer' +import ButtonRenderer from './ButtonRenderer' +import ImageRenderer from './ImageRenderer' +import { SectionName, VerticalAlignment, HorizontalAlignment } from '../types/Types' + +const FooterSection: FC = () => { + + const { t } = useTranslation() + const { activeSection, activeItemIndex, data, setActiveSection, setActiveItemIndex } = usePersonalityStore() + + const handleSectionClick = (section: SectionName) => { + setActiveSection(section) + } + + const handleItemClick = (index: number) => { + setActiveItemIndex(index) + } + + // تابع‌های helper برای تعیین alignment دکمه‌ها + const getButtonHorizontalAlign = (button?: { alignment?: HorizontalAlignment }) => { + if (!button || !button.alignment) return 'center' + switch (button.alignment) { + case HorizontalAlignment.LEFT: + return 'left' + case HorizontalAlignment.RIGHT: + return 'right' + case HorizontalAlignment.CENTER: + default: + return 'center' + } + } + + const getButtonVerticalAlign = (button?: { verticalAlignment?: VerticalAlignment }) => { + if (!button || !button.verticalAlignment) return 'middle' + switch (button.verticalAlignment) { + case VerticalAlignment.TOP: + return 'top' + case VerticalAlignment.BOTTOM: + return 'bottom' + case VerticalAlignment.MIDDLE: + default: + return 'middle' + } + } + + return ( + handleSectionClick(SectionName.FOOTER)}> + + { + data.footer.columnsCount > 0 ? + + + + + + +
+ + + + { + Array.from({ length: data.footer.columnsCount }, (_, index) => { + const item = data.footer.items[index]; + const isActive = activeSection === SectionName.FOOTER && activeItemIndex === index; + + return ( + <> + + {index < data.footer.columnsCount - 1 && ( + + )} + + ) + }) + } + + +
{ + e.stopPropagation(); + handleItemClick(index); + }} + key={index} + style={{ + width: `${100 / data.footer.columnsCount}%`, + height: '123px', + border: isActive ? '1px dashed #0038FF' : '1px dashed #EAECF4', + backgroundColor: item?.backgroundColor || '#ffffff', + backgroundImage: item?.backgroundImage ? `url(${item.backgroundImage})` : 'none', + backgroundSize: item?.style?.backgroundSize || 'cover', + backgroundRepeat: item?.style?.backgroundRepeat || 'no-repeat', + backgroundPosition: item?.style?.backgroundPosition || 'center', + cursor: 'pointer', + padding: '0', + verticalAlign: 'top', + borderRadius: '8px', + position: 'relative' + }} + > + + + {/* اگر فقط دکمه داریم و متن نداریم */} + {(!item?.texts || item.texts.length === 0) && item?.buttons && item.buttons.length > 0 ? ( + + + + ) : ( + <> + {/* ردیف اصلی برای متن */} + + + + {/* ردیف دکمه‌ها */} + {item?.buttons && item.buttons.length > 0 && ( + + + + )} + + )} + +
+ +
0 ? "40" : "67"} + align={item?.texts?.[0]?.alignment || 'center'} + valign={item?.texts?.[0]?.verticalAlignment === VerticalAlignment.TOP ? 'top' : + item?.texts?.[0]?.verticalAlignment === VerticalAlignment.BOTTOM ? 'bottom' : 'middle'} + style={{ + padding: '8px', + fontSize: '14px', + lineHeight: '1.4' + }} + > + + +
+ +
+
+
+ : + + + + + + +
+
+ {t('setting.footer_email')} +
+
+ +
+
+ } + + + ) +} + +export default FooterSection \ No newline at end of file diff --git a/src/pages/setting/personality/components/HeaderSection.tsx b/src/pages/setting/personality/components/HeaderSection.tsx new file mode 100644 index 0000000..2e3b2ff --- /dev/null +++ b/src/pages/setting/personality/components/HeaderSection.tsx @@ -0,0 +1,184 @@ +import { FC } from 'react' +import { usePersonalityStore } from '../store/Store' +import { useTranslation } from 'react-i18next' +import { AddCircle } from 'iconsax-react' +import TextRenderer from './TextRenderer' +import ButtonRenderer from './ButtonRenderer' +import ImageRenderer from './ImageRenderer' +import { SectionName, VerticalAlignment, HorizontalAlignment } from '../types/Types' + +const HeaderSection: FC = () => { + + const { t } = useTranslation() + const { activeSection, activeItemIndex, data, setActiveSection, setActiveItemIndex } = usePersonalityStore() + + const handleSectionClick = (section: SectionName) => { + setActiveSection(section) + } + + const handleItemClick = (index: number) => { + setActiveItemIndex(index) + } + + // تابع‌های helper برای تعیین alignment دکمه‌ها + const getButtonHorizontalAlign = (button?: { alignment?: HorizontalAlignment }) => { + if (!button || !button.alignment) return 'center' + switch (button.alignment) { + case HorizontalAlignment.LEFT: + return 'left' + case HorizontalAlignment.RIGHT: + return 'right' + case HorizontalAlignment.CENTER: + default: + return 'center' + } + } + + const getButtonVerticalAlign = (button?: { verticalAlignment?: VerticalAlignment }) => { + if (!button || !button.verticalAlignment) return 'middle' + switch (button.verticalAlignment) { + case VerticalAlignment.TOP: + return 'top' + case VerticalAlignment.BOTTOM: + return 'bottom' + case VerticalAlignment.MIDDLE: + default: + return 'middle' + } + } + + return ( + handleSectionClick(SectionName.HEADER)}> + { + data.header.columnsCount > 0 ? + + + + + { + Array.from({ length: data.header.columnsCount }, (_, index) => { + const item = data.header.items[index]; + const isActive = activeSection === SectionName.HEADER && activeItemIndex === index; + + return ( + <> + + {index < data.header.columnsCount - 1 && ( + + )} + + ) + }) + } + + +
{ + e.stopPropagation(); + handleItemClick(index); + }} + key={index} + style={{ + width: `${100 / data.header.columnsCount}%`, + height: '123px', + border: isActive ? '1px dashed #0038FF' : '1px dashed #EAECF4', + backgroundColor: item?.backgroundColor || '#ffffff', + backgroundImage: item?.backgroundImage ? `url(${item.backgroundImage})` : 'none', + backgroundSize: item?.style?.backgroundSize || 'cover', + backgroundRepeat: item?.style?.backgroundRepeat || 'no-repeat', + backgroundPosition: item?.style?.backgroundPosition || 'center', + cursor: 'pointer', + padding: '0', + verticalAlign: 'top', + borderRadius: '8px', + position: 'relative' + }} + > + + + {/* اگر فقط دکمه داریم و متن نداریم */} + {(!item?.texts || item.texts.length === 0) && item?.buttons && item.buttons.length > 0 ? ( + + + + ) : ( + <> + {/* ردیف اصلی برای متن */} + + + + {/* ردیف دکمه‌ها */} + {item?.buttons && item.buttons.length > 0 && ( + + + + )} + + )} + +
+ +
0 ? "60" : "87"} + align={item?.texts?.[0]?.alignment || 'center'} + valign={item?.texts?.[0]?.verticalAlignment === VerticalAlignment.TOP ? 'top' : + item?.texts?.[0]?.verticalAlignment === VerticalAlignment.BOTTOM ? 'bottom' : 'middle'} + style={{ + padding: '8px', + fontSize: '14px', + lineHeight: '1.4' + }} + > + + +
+ +
+
+ + : + +
+ {t('setting.header_email')} +
+
+ +
+ + } + + ) +} + +export default HeaderSection \ No newline at end of file diff --git a/src/pages/setting/personality/components/ImageRenderer.tsx b/src/pages/setting/personality/components/ImageRenderer.tsx new file mode 100644 index 0000000..f6f7056 --- /dev/null +++ b/src/pages/setting/personality/components/ImageRenderer.tsx @@ -0,0 +1,149 @@ +import { FC } from 'react' +import { ImageType, ImageSize, HorizontalAlignment, VerticalAlignment } from '../types/Types' + +interface ImageRendererProps { + images: ImageType[] +} + +const ImageRenderer: FC = ({ images }) => { + if (!images || images.length === 0) return null + + // تابع‌های helper برای تبدیل enum به string + const getHorizontalAlign = (alignment?: HorizontalAlignment) => { + switch (alignment) { + case HorizontalAlignment.LEFT: + return 'left' + case HorizontalAlignment.RIGHT: + return 'right' + case HorizontalAlignment.CENTER: + default: + return 'center' + } + } + + const getVerticalAlign = (verticalAlignment?: VerticalAlignment) => { + switch (verticalAlignment) { + case VerticalAlignment.TOP: + return 'top' + case VerticalAlignment.BOTTOM: + return 'bottom' + case VerticalAlignment.MIDDLE: + default: + return 'middle' + } + } + + const getImageStyle = (image: ImageType) => { + return { + width: image.width || '100%', + height: image.height || 'auto', + border: '0' + } + } + + const shouldUseBackgroundImage = (imageSize: ImageSize) => { + return imageSize === ImageSize.REPEAT || + imageSize === ImageSize.REPEAT_X || + imageSize === ImageSize.REPEAT_Y + } + + const getBackgroundStyle = (image: ImageType) => { + let backgroundRepeat = 'no-repeat' + + switch (image.size) { + case ImageSize.REPEAT: + backgroundRepeat = 'repeat' + break + case ImageSize.REPEAT_X: + backgroundRepeat = 'repeat-x' + break + case ImageSize.REPEAT_Y: + backgroundRepeat = 'repeat-y' + break + default: + backgroundRepeat = 'no-repeat' + break + } + + const horizontal = image.alignment === HorizontalAlignment.LEFT ? 'left' : + image.alignment === HorizontalAlignment.RIGHT ? 'right' : 'center' + const vertical = image.verticalAlignment === VerticalAlignment.TOP ? 'top' : + image.verticalAlignment === VerticalAlignment.BOTTOM ? 'bottom' : 'center' + + return { + backgroundImage: `url(${image.src})`, + backgroundPosition: `${horizontal} ${vertical}`, + backgroundRepeat, + width: image.width || '100%', + height: image.height || '100px' + } + } + + const renderImage = (image: ImageType) => { + if (shouldUseBackgroundImage(image.size)) { + // برای pattern های repeat از background استفاده می‌کنیم + return ( +
+   +
+ ) + } + + // برای تصاویر عادی + if (image.size === ImageSize.CONTAIN) { + // برای contain از table wrapper استفاده می‌کنیم تا نسبت حفظ شود + return ( + + + + + + +
+ {image.alt +
+ ) + } + + // برای cover و auto + return ( + {image.alt + ) + } + + return ( + <> + {images.map((image, imageIndex) => ( + + + + + + +
+ {renderImage(image)} +
+ ))} + + ) +} + +export default ImageRenderer \ No newline at end of file diff --git a/src/pages/setting/personality/components/ImageSideBar.tsx b/src/pages/setting/personality/components/ImageSideBar.tsx new file mode 100644 index 0000000..bfff861 --- /dev/null +++ b/src/pages/setting/personality/components/ImageSideBar.tsx @@ -0,0 +1,194 @@ +import Button from '@/components/Button' +import Select from '@/components/Select' +import UploadBoxDraggble from '@/components/UploadBoxDraggble' +import { Add, AlignBottom, AlignHorizontally, AlignLeft, AlignRight, AlignTop, AlignVertically } from 'iconsax-react' +import { FC, useState } from 'react' +import { useTranslation } from 'react-i18next' +import { usePersonalityStore } from '../store/Store' +import { ImageSize, HorizontalAlignment, VerticalAlignment } from '../types/Types' + +const ImageSideBar: FC = () => { + + const { t } = useTranslation() + const { addImageToActiveItem, activeSection, activeItemIndex, data } = usePersonalityStore() + + const [imageSrc, setImageSrc] = useState('') + const [imageSize, setImageSize] = useState(ImageSize.COVER) + const [horizontalAlignment, setHorizontalAlignment] = useState(HorizontalAlignment.CENTER) + const [verticalAlignment, setVerticalAlignment] = useState(VerticalAlignment.MIDDLE) + const [isLoading, setIsLoading] = useState(false) + const [isReset, setIsReset] = useState(false) + + const sizeOptions = [ + { label: 'کاور - تمام فضا را پوشش دهد (Cover)', value: ImageSize.COVER }, + { label: 'در مقیاس - در فضا جا شود (Contain)', value: ImageSize.CONTAIN }, + { label: 'تکرار - عکس تکرار شود (Repeat)', value: ImageSize.REPEAT }, + { label: 'تکرار افقی (Repeat-X)', value: ImageSize.REPEAT_X }, + { label: 'تکرار عمودی (Repeat-Y)', value: ImageSize.REPEAT_Y }, + { label: 'بدون تکرار (No-Repeat)', value: ImageSize.NO_REPEAT }, + { label: 'اندازه اصلی (Auto)', value: ImageSize.AUTO } + ] + + const handleImageUpload = (files: File[]) => { + if (files.length === 0) return + + const file = files[0] // فقط اولین فایل را در نظر می‌گیریم + // در اینجا باید فایل آپلود شود و URL برگردانده شود + // فعلاً از FileReader استفاده می‌کنم برای تست + const reader = new FileReader() + reader.onload = (e) => { + const result = e.target?.result as string + setImageSrc(result) + } + reader.readAsDataURL(file) + } + + const handleAddImage = () => { + if (!imageSrc) return + + console.log('Store state before adding image:', { + activeSection, + activeItemIndex, + hasActiveItem: activeSection && data[activeSection as keyof typeof data]?.items[activeItemIndex], + }) + + // Validation + if (!activeSection) { + console.error('No active section selected') + return + } + + const sectionData = data[activeSection as keyof typeof data] + if (!sectionData?.items || activeItemIndex >= sectionData.items.length) { + console.error('No active item found or invalid index', { + activeItemIndex, + itemsLength: sectionData?.items?.length + }) + return + } + + console.log('Adding image with data:', { + src: imageSrc, + alt: 'عکس آپلود شده', + size: imageSize, + alignment: horizontalAlignment, + verticalAlignment, + }) + + setIsLoading(true) + + try { + addImageToActiveItem({ + src: imageSrc, + alt: 'عکس آپلود شده', + size: imageSize, + alignment: horizontalAlignment, + verticalAlignment, + }) + + console.log('Image added successfully') + + // Reset form after adding + setImageSrc('') + setImageSize(ImageSize.COVER) + setHorizontalAlignment(HorizontalAlignment.CENTER) + setVerticalAlignment(VerticalAlignment.MIDDLE) + setIsReset(true) + setTimeout(() => { + setIsReset(false) + }, 1000) + } catch (error) { + console.error('Error adding image:', error) + } finally { + setIsLoading(false) + } + } + + return ( +
+
{t('setting.image')}
+ +
+ +
+ +
+ { + const newSize = e.target.value as BackgroundSize + setBackgroundSize(newSize) + + const currentItem = activeSection ? data[activeSection as keyof typeof data]?.items[activeItemIndex] : null + updateActiveItem({ + style: { + ...currentItem?.style, + backgroundSize: getBackgroundSize(newSize), + backgroundRepeat: getBackgroundRepeat(newSize), + backgroundPosition: 'center center' + } + }) + }} + placeholder={t('setting.size')} + /> +
+
+ ) +} + +export default SettingSideBar \ No newline at end of file diff --git a/src/pages/setting/personality/components/TextRenderer.tsx b/src/pages/setting/personality/components/TextRenderer.tsx new file mode 100644 index 0000000..ea0355f --- /dev/null +++ b/src/pages/setting/personality/components/TextRenderer.tsx @@ -0,0 +1,33 @@ +import { FC } from 'react' +import { TextType } from '../types/Types' + +interface TextRendererProps { + texts: TextType[] +} + +const TextRenderer: FC = ({ texts }) => { + return ( + <> + {texts?.map((textItem, textIndex) => ( + + + + + +
+
+ ))} + + ) +} + +export default TextRenderer \ No newline at end of file diff --git a/src/pages/setting/personality/components/TextSidebar.tsx b/src/pages/setting/personality/components/TextSidebar.tsx new file mode 100644 index 0000000..09bc9a2 --- /dev/null +++ b/src/pages/setting/personality/components/TextSidebar.tsx @@ -0,0 +1,136 @@ +import Button from '@/components/Button'; +import { Add, AlignBottom, AlignHorizontally, AlignLeft, AlignRight, AlignTop, AlignVertically } from 'iconsax-react'; +import { FC, useState } from 'react' +import { useTranslation } from 'react-i18next' +import ReactQuill from 'react-quill-new'; +import { usePersonalityStore } from '../store/Store'; +import ColorPicker from '@/components/ColorPicker'; +import { HorizontalAlignment, VerticalAlignment } from '../types/Types'; + +const TextSidebar: FC = () => { + + const { t } = useTranslation() + const [value, setValue] = useState(''); + const [color, setColor] = useState('#000'); + const [horizontalPosition, setHorizontalPosition] = useState(HorizontalAlignment.CENTER); + const [verticalPosition, setVerticalPosition] = useState(VerticalAlignment.MIDDLE); + const { addTextToActiveItem } = usePersonalityStore(); + + const handleChange = (value: string) => { + setValue(value); + } + + const handleAddText = () => { + if (value.trim()) { + addTextToActiveItem({ + text: value, + color: color, + verticalAlignment: verticalPosition, + alignment: horizontalPosition, + }); + + // خالی کردن فیلدها بعد از ذخیره + setValue(''); + setColor('#000'); + setHorizontalPosition(HorizontalAlignment.CENTER); + setVerticalPosition(VerticalAlignment.MIDDLE); + } + } + + return ( +
+
{t('setting.text')}
+ +
+ +
+ +
+ +
+ +
+
+
+ {t('setting.horizontal_position')} +
+
+
setHorizontalPosition(HorizontalAlignment.RIGHT)} + > + +
+
setHorizontalPosition(HorizontalAlignment.CENTER)} + > + +
+
setHorizontalPosition(HorizontalAlignment.LEFT)} + > + +
+
+
+ +
+
+ {t('setting.vertical_position')} +
+
+
setVerticalPosition(VerticalAlignment.TOP)} + > + +
+
setVerticalPosition(VerticalAlignment.MIDDLE)} + > + +
+
setVerticalPosition(VerticalAlignment.BOTTOM)} + > + +
+
+
+
+ +
+ +
+ +
+ ) +} + +export default TextSidebar \ No newline at end of file diff --git a/src/pages/setting/personality/store/Store.ts b/src/pages/setting/personality/store/Store.ts new file mode 100644 index 0000000..6de33b8 --- /dev/null +++ b/src/pages/setting/personality/store/Store.ts @@ -0,0 +1,376 @@ +import { create } from "zustand"; +import { v4 as uuidv4 } from "uuid"; +import { + PersonalityStore, + PersonalityDataType, + SectionItemType, + TextType, + ButtonType, + ImageType, + SectionName, + HorizontalAlignment, + VerticalAlignment, +} from "../types/Types"; + +export const usePersonalityStore = create((set) => ({ + data: { + header: { columnsCount: 0, items: [] }, + content: { columnsCount: 0, items: [] }, + footer: { columnsCount: 0, items: [] }, + }, + + activeSection: "", + activeItemIndex: 0, + + setActiveSection: (section: SectionName) => + set({ activeSection: section, activeItemIndex: 0 }), + + setActiveItemIndex: (index: number) => set({ activeItemIndex: index }), + + setColumnsCount: ( + sectionKey: keyof PersonalityDataType, + columnsCount: number + ) => + set((state) => { + const currentItems = state.data[sectionKey].items; + const newItems = Array.from( + { length: columnsCount }, + (_, index) => + currentItems[index] || { + id: uuidv4(), + backgroundColor: "#ffffff", + texts: [], + buttons: [], + images: [], + alignment: HorizontalAlignment.CENTER, + verticalAlignment: VerticalAlignment.MIDDLE, + } + ); + + return { + data: { + ...state.data, + [sectionKey]: { + columnsCount, + items: newItems, + }, + }, + activeItemIndex: 0, + }; + }), + + setItems: (sectionKey: keyof PersonalityDataType, items: SectionItemType[]) => + set((state) => ({ + data: { + ...state.data, + [sectionKey]: { + ...state.data[sectionKey], + items, + }, + }, + })), + + addItem: ( + sectionKey: keyof PersonalityDataType, + item: Omit + ) => + set((state) => ({ + data: { + ...state.data, + [sectionKey]: { + ...state.data[sectionKey], + items: [...state.data[sectionKey].items, { ...item, id: uuidv4() }], + }, + }, + })), + + updateActiveItem: (updates: Partial) => + set((state) => { + if (!state.activeSection) return state; + + const sectionKey = state.activeSection as keyof PersonalityDataType; + const items = state.data[sectionKey].items; + const activeIndex = state.activeItemIndex; + + if (activeIndex >= items.length) return state; + + console.log("Updating active item:", { + sectionKey, + activeIndex, + updates, + }); + + const updatedItems = items.map((item, index) => + index === activeIndex ? { ...item, ...updates } : item + ); + + return { + data: { + ...state.data, + [sectionKey]: { + ...state.data[sectionKey], + items: updatedItems, + }, + }, + }; + }), + + updateItem: ( + sectionKey: keyof PersonalityDataType, + id: string, + updates: Partial + ) => + set((state) => ({ + data: { + ...state.data, + [sectionKey]: { + ...state.data[sectionKey], + items: state.data[sectionKey].items.map((item) => + item.id === id ? { ...item, ...updates } : item + ), + }, + }, + })), + + removeItem: (sectionKey: keyof PersonalityDataType, id: string) => + set((state) => ({ + data: { + ...state.data, + [sectionKey]: { + ...state.data[sectionKey], + items: state.data[sectionKey].items.filter((item) => item.id !== id), + }, + }, + })), + + addText: ( + sectionKey: keyof PersonalityDataType, + itemId: string, + text: Omit + ) => + set((state) => ({ + data: { + ...state.data, + [sectionKey]: { + ...state.data[sectionKey], + items: state.data[sectionKey].items.map((item) => + item.id === itemId + ? { + ...item, + texts: [...item.texts, { ...text, id: uuidv4() }], + } + : item + ), + }, + }, + })), + + addTextToActiveItem: (text: Omit) => + set((state) => { + if (!state.activeSection) return state; + + const sectionKey = state.activeSection as keyof PersonalityDataType; + const items = state.data[sectionKey].items; + const activeIndex = state.activeItemIndex; + + if (activeIndex >= items.length) return state; + + const updatedItems = items.map((item, index) => + index === activeIndex + ? { + ...item, + texts: [...item.texts, { ...text, id: uuidv4() }], + } + : item + ); + + return { + data: { + ...state.data, + [sectionKey]: { + ...state.data[sectionKey], + items: updatedItems, + }, + }, + }; + }), + + addButton: ( + sectionKey: keyof PersonalityDataType, + itemId: string, + button: Omit + ) => + set((state) => ({ + data: { + ...state.data, + [sectionKey]: { + ...state.data[sectionKey], + items: state.data[sectionKey].items.map((item) => + item.id === itemId + ? { + ...item, + buttons: [...item.buttons, { ...button, id: uuidv4() }], + } + : item + ), + }, + }, + })), + + addButtonToActiveItem: (button: Omit) => + set((state) => { + if (!state.activeSection) return state; + + const sectionKey = state.activeSection as keyof PersonalityDataType; + const items = state.data[sectionKey].items; + const activeIndex = state.activeItemIndex; + + if (activeIndex >= items.length) return state; + + const updatedItems = items.map((item, index) => + index === activeIndex + ? { + ...item, + buttons: [...item.buttons, { ...button, id: uuidv4() }], + } + : item + ); + + return { + data: { + ...state.data, + [sectionKey]: { + ...state.data[sectionKey], + items: updatedItems, + }, + }, + }; + }), + + updateText: ( + sectionKey: keyof PersonalityDataType, + itemId: string, + textId: string, + updates: Partial + ) => + set((state) => ({ + data: { + ...state.data, + [sectionKey]: { + ...state.data[sectionKey], + items: state.data[sectionKey].items.map((item) => + item.id === itemId + ? { + ...item, + texts: item.texts.map((text) => + text.id === textId ? { ...text, ...updates } : text + ), + } + : item + ), + }, + }, + })), + + updateButton: ( + sectionKey: keyof PersonalityDataType, + itemId: string, + buttonId: string, + updates: Partial + ) => + set((state) => ({ + data: { + ...state.data, + [sectionKey]: { + ...state.data[sectionKey], + items: state.data[sectionKey].items.map((item) => + item.id === itemId + ? { + ...item, + buttons: item.buttons.map((button) => + button.id === buttonId ? { ...button, ...updates } : button + ), + } + : item + ), + }, + }, + })), + + addImage: ( + sectionKey: keyof PersonalityDataType, + itemId: string, + image: Omit + ) => + set((state) => ({ + data: { + ...state.data, + [sectionKey]: { + ...state.data[sectionKey], + items: state.data[sectionKey].items.map((item) => + item.id === itemId + ? { + ...item, + images: [...item.images, { ...image, id: uuidv4() }], + } + : item + ), + }, + }, + })), + + addImageToActiveItem: (image: Omit) => + set((state) => { + if (!state.activeSection) return state; + + const sectionKey = state.activeSection as keyof PersonalityDataType; + const items = state.data[sectionKey].items; + const activeIndex = state.activeItemIndex; + + if (activeIndex >= items.length) return state; + + const updatedItems = items.map((item, index) => + index === activeIndex + ? { + ...item, + images: [...item.images, { ...image, id: uuidv4() }], + } + : item + ); + + return { + data: { + ...state.data, + [sectionKey]: { + ...state.data[sectionKey], + items: updatedItems, + }, + }, + }; + }), + + updateImage: ( + sectionKey: keyof PersonalityDataType, + itemId: string, + imageId: string, + updates: Partial + ) => + set((state) => ({ + data: { + ...state.data, + [sectionKey]: { + ...state.data[sectionKey], + items: state.data[sectionKey].items.map((item) => + item.id === itemId + ? { + ...item, + images: item.images.map((image) => + image.id === imageId ? { ...image, ...updates } : image + ), + } + : item + ), + }, + }, + })), +})); diff --git a/src/pages/setting/personality/types/Types.ts b/src/pages/setting/personality/types/Types.ts new file mode 100644 index 0000000..5f101c2 --- /dev/null +++ b/src/pages/setting/personality/types/Types.ts @@ -0,0 +1,170 @@ +// Enums for common types +export enum HorizontalAlignment { + LEFT = "left", + CENTER = "center", + RIGHT = "right", +} + +export enum VerticalAlignment { + TOP = "top", + MIDDLE = "middle", + BOTTOM = "bottom", +} + +export enum ButtonSize { + SMALL = "small", + MEDIUM = "medium", + LARGE = "large", +} + +export enum ImageSize { + COVER = "cover", + CONTAIN = "contain", + AUTO = "auto", + REPEAT = "repeat", + REPEAT_X = "repeat-x", + REPEAT_Y = "repeat-y", + NO_REPEAT = "no-repeat", +} + +export enum BackgroundSize { + COVER = "cover", + CONTAIN = "contain", + ROUND = "round", +} + +export enum SectionName { + HEADER = "header", + CONTENT = "content", + FOOTER = "footer", +} + +export type PersonalityDataType = { + header: SectionType; + content: SectionType; + footer: SectionType; +}; + +export type SectionType = { + columnsCount: number; + items: SectionItemType[]; +}; + +export type SectionItemType = { + id: string; + backgroundColor: string; + backgroundImage?: string; + texts: TextType[]; + buttons: ButtonType[]; + images: ImageType[]; + alignment?: HorizontalAlignment; + verticalAlignment?: VerticalAlignment; + style?: { + borderRadius?: number; + padding?: string; + fontFamily?: string; + backgroundSize?: string; + backgroundRepeat?: string; + backgroundPosition?: string; + }; +}; + +export type TextType = { + id: string; + text: string; + fontSize?: number; + fontFamily?: string; + color?: string; + alignment?: HorizontalAlignment; + verticalAlignment?: VerticalAlignment; +}; + +export type ButtonType = { + id: string; + text: string; + link: string; + size: ButtonSize; + isBorder: boolean; + borderSize: number; + textColor: string; + backgroundColor: string; + borderColor: string; + alignment?: HorizontalAlignment; + verticalAlignment?: VerticalAlignment; +}; + +export type ImageType = { + id: string; + src: string; + alt?: string; + size: ImageSize; + width?: string; + height?: string; + alignment?: HorizontalAlignment; + verticalAlignment?: VerticalAlignment; +}; + +export type PersonalityStore = { + data: PersonalityDataType; + activeSection: SectionName | ""; + activeItemIndex: number; + + setActiveSection: (section: SectionName) => void; + setActiveItemIndex: (index: number) => void; + + setItems: ( + sectionKey: keyof PersonalityDataType, + items: SectionItemType[] + ) => void; + addItem: ( + sectionKey: keyof PersonalityDataType, + item: Omit + ) => void; + updateItem: ( + sectionKey: keyof PersonalityDataType, + id: string, + updates: Partial + ) => void; + updateActiveItem: (updates: Partial) => void; + removeItem: (sectionKey: keyof PersonalityDataType, id: string) => void; + setColumnsCount: ( + sectionKey: keyof PersonalityDataType, + columnsCount: number + ) => void; + addText: ( + sectionKey: keyof PersonalityDataType, + itemId: string, + text: Omit + ) => void; + addTextToActiveItem: (text: Omit) => void; + addButton: ( + sectionKey: keyof PersonalityDataType, + itemId: string, + button: Omit + ) => void; + addButtonToActiveItem: (button: Omit) => void; + updateText: ( + sectionKey: keyof PersonalityDataType, + itemId: string, + textId: string, + updates: Partial + ) => void; + updateButton: ( + sectionKey: keyof PersonalityDataType, + itemId: string, + buttonId: string, + updates: Partial + ) => void; + addImage: ( + sectionKey: keyof PersonalityDataType, + itemId: string, + image: Omit + ) => void; + addImageToActiveItem: (image: Omit) => void; + updateImage: ( + sectionKey: keyof PersonalityDataType, + itemId: string, + imageId: string, + updates: Partial + ) => void; +}; diff --git a/src/pages/setting/signture/Signture.tsx b/src/pages/setting/signture/Signture.tsx new file mode 100644 index 0000000..ca697ec --- /dev/null +++ b/src/pages/setting/signture/Signture.tsx @@ -0,0 +1,38 @@ +import Textarea from '@/components/Textarea' +import UploadBox from '@/components/UploadBox' +import { FC } from 'react' +import { useTranslation } from 'react-i18next' + +const Signture: FC = () => { + + const { t } = useTranslation() + return ( +
+
+
+
+
+ {t('setting.signature')} +
+
+ {t('setting.signature_description')} +
+
+ +
+ +
+