commit 6b9e808bfdc1aee415cb9af2f2f647e855dc9508 Author: hamid zarghami Date: Sat Feb 7 16:20:18 2026 +0330 copy dmenu-admin to dkala-admin diff --git a/.env b/.env new file mode 100644 index 0000000..6892ae9 --- /dev/null +++ b/.env @@ -0,0 +1,7 @@ +VITE_TOKEN_NAME = 'dmnu_a_t' +VITE_REFRESH_TOKEN_NAME = 'dmnu-a-rt' + +VITE_BASE_URL = 'https://dmenuplus-api-production.dev.danakcorp.com' +# VITE_BASE_URL = 'http://192.168.99.242:4000' + +VITE_SOCKET_URL = 'https://dmenuplus-api-production.dev.danakcorp.com' \ No newline at end of file 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..7af26a2 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,25 @@ +FROM node:20-alpine AS builder + +# Install tzdata to support timezone settings +RUN apk add --no-cache tzdata + +# 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 ./ +RUN npm install +COPY . ./ +RUN npm 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;"] \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..7959ce4 --- /dev/null +++ b/README.md @@ -0,0 +1,69 @@ +# React + TypeScript + Vite + +This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. + +Currently, two official plugins are available: + +- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) for Fast Refresh +- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh + +## Expanding the ESLint configuration + +If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules: + +```js +export default tseslint.config([ + globalIgnores(['dist']), + { + files: ['**/*.{ts,tsx}'], + extends: [ + // Other configs... + + // Remove tseslint.configs.recommended and replace with this + ...tseslint.configs.recommendedTypeChecked, + // Alternatively, use this for stricter rules + ...tseslint.configs.strictTypeChecked, + // Optionally, add this for stylistic rules + ...tseslint.configs.stylisticTypeChecked, + + // Other configs... + ], + languageOptions: { + parserOptions: { + project: ['./tsconfig.node.json', './tsconfig.app.json'], + tsconfigRootDir: import.meta.dirname, + }, + // other options... + }, + }, +]) +``` + +You can also install [eslint-plugin-react-x](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom) for React-specific lint rules: + +```js +// eslint.config.js +import reactX from 'eslint-plugin-react-x' +import reactDom from 'eslint-plugin-react-dom' + +export default tseslint.config([ + globalIgnores(['dist']), + { + files: ['**/*.{ts,tsx}'], + extends: [ + // Other configs... + // Enable lint rules for React + reactX.configs['recommended-typescript'], + // Enable lint rules for React DOM + reactDom.configs.recommended, + ], + languageOptions: { + parserOptions: { + project: ['./tsconfig.node.json', './tsconfig.app.json'], + tsconfigRootDir: import.meta.dirname, + }, + // other options... + }, + }, +]) +``` diff --git a/components.json b/components.json new file mode 100644 index 0000000..3dfc47e --- /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": "tailwind.config.js", + "css": "src/index.css", + "baseColor": "neutral", + "cssVariables": true, + "prefix": "" + }, + "aliases": { + "components": "@/components", + "utils": "@/lib/utils", + "ui": "@/components/ui", + "lib": "@/lib", + "hooks": "@/hooks" + } +} + diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 0000000..d94e7de --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,23 @@ +import js from '@eslint/js' +import globals from 'globals' +import reactHooks from 'eslint-plugin-react-hooks' +import reactRefresh from 'eslint-plugin-react-refresh' +import tseslint from 'typescript-eslint' +import { globalIgnores } from 'eslint/config' + +export default tseslint.config([ + globalIgnores(['dist']), + { + files: ['**/*.{ts,tsx}'], + extends: [ + js.configs.recommended, + tseslint.configs.recommended, + reactHooks.configs['recommended-latest'], + reactRefresh.configs.vite, + ], + languageOptions: { + ecmaVersion: 2020, + globals: globals.browser, + }, + }, +]) diff --git a/index.html b/index.html new file mode 100644 index 0000000..adaf877 --- /dev/null +++ b/index.html @@ -0,0 +1,16 @@ + + + + + + + + پنل مدیریت دی منو + + + +
+ + + + \ No newline at end of file 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-lock.json b/package-lock.json new file mode 100644 index 0000000..0996185 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,6008 @@ +{ + "name": "dmenu-admin", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "dmenu-admin", + "version": "0.0.0", + "dependencies": { + "@headlessui/react": "^2.2.7", + "@radix-ui/react-checkbox": "^1.3.3", + "@radix-ui/react-icons": "^1.3.2", + "@tailwindcss/vite": "^4.1.12", + "@tanstack/react-query": "^5.85.5", + "axios": "^1.11.0", + "clsx": "^2.1.1", + "formik": "^2.4.6", + "i18next": "^25.4.2", + "iconsax-react": "^0.0.8", + "leaflet": "^1.9.4", + "moment-jalaali": "^0.10.4", + "rc-rate": "^2.13.1", + "react": "^19.1.1", + "react-dom": "^19.1.1", + "react-dropzone": "^14.3.8", + "react-i18next": "^15.7.2", + "react-infinite-scroll-component": "^6.1.1", + "react-leaflet": "^5.0.0-rc.2", + "react-loading-skeleton": "^3.5.0", + "react-multi-date-picker": "^4.5.2", + "react-otp-input": "^3.1.1", + "react-router-dom": "^7.8.2", + "react-spinners": "^0.17.0", + "react-toastify": "^11.0.5", + "recharts": "^3.6.0", + "socket.io-client": "^4.8.1", + "swiper": "^11.2.10", + "tailwind-merge": "^3.3.1", + "yup": "^1.7.0", + "zustand": "^5.0.8" + }, + "devDependencies": { + "@eslint/js": "^9.33.0", + "@types/leaflet": "^1.9.21", + "@types/moment-jalaali": "^0.7.9", + "@types/node": "^24.10.1", + "@types/react": "^19.1.10", + "@types/react-dom": "^19.1.7", + "@vitejs/plugin-react": "^5.0.0", + "autoprefixer": "^10.4.21", + "eslint": "^9.33.0", + "eslint-plugin-react-hooks": "^5.2.0", + "eslint-plugin-react-refresh": "^0.4.20", + "globals": "^16.3.0", + "postcss": "^8.5.6", + "tailwindcss": "^4.1.12", + "typescript": "~5.8.3", + "typescript-eslint": "^8.39.1", + "vite": "^7.1.2" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.0.tgz", + "integrity": "sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.3.tgz", + "integrity": "sha512-yDBHV9kQNcr2/sUr9jghVyz9C3Y5G2zUM2H2lo+9mKv4sFgbA8s8Z9t8D1jiTkGoO/NoIfKMyKWr4s6CN23ZwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.3", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-module-transforms": "^7.28.3", + "@babel/helpers": "^7.28.3", + "@babel/parser": "^7.28.3", + "@babel/template": "^7.27.2", + "@babel/traverse": "^7.28.3", + "@babel/types": "^7.28.2", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.3.tgz", + "integrity": "sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.3", + "@babel/types": "^7.28.2", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", + "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.27.2", + "@babel/helper-validator-option": "^7.27.1", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", + "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz", + "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1", + "@babel/traverse": "^7.28.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", + "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", + "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.3.tgz", + "integrity": "sha512-PTNtvUQihsAsDHMOP5pfobP8C6CM4JWXmP8DrEIt46c3r2bf87Ua1zoqevsMo9g+tWDwgWrFP5EIxuBx5RudAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.3.tgz", + "integrity": "sha512-7+Ey1mAgYqFAx2h0RuoxcQT5+MlG3GTV0TQrgr7/ZliKsm/MNDxVVutlWaziMq7wJNAz8MTqz55XLpWvva6StA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.2" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz", + "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz", + "integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.3.tgz", + "integrity": "sha512-9uIQ10o0WGdpP6GDhXcdOJPJuDgFtIDtN/9+ArJQ2NAfAmiuhTQdzkaTGR33v43GYS2UrSA0eX2pPPHoFVvpxA==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", + "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/parser": "^7.27.2", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.3.tgz", + "integrity": "sha512-7w4kZYHneL3A6NP2nxzHvT3HCZ7puDZZjFMqDpBPECub79sTtSO5CGXDkKrTQq8ksAwfD/XI2MRFX23njdDaIQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.3", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.28.3", + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.2", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.28.2", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.2.tgz", + "integrity": "sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.9.tgz", + "integrity": "sha512-OaGtL73Jck6pBKjNIe24BnFE6agGl+6KxDtTfHhy1HmhthfKouEcOhqpSL64K4/0WCtbKFLOdzD/44cJ4k9opA==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.9.tgz", + "integrity": "sha512-5WNI1DaMtxQ7t7B6xa572XMXpHAaI/9Hnhk8lcxF4zVN4xstUgTlvuGDorBguKEnZO70qwEcLpfifMLoxiPqHQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.9.tgz", + "integrity": "sha512-IDrddSmpSv51ftWslJMvl3Q2ZT98fUSL2/rlUXuVqRXHCs5EUF1/f+jbjF5+NG9UffUDMCiTyh8iec7u8RlTLg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.9.tgz", + "integrity": "sha512-I853iMZ1hWZdNllhVZKm34f4wErd4lMyeV7BLzEExGEIZYsOzqDWDf+y082izYUE8gtJnYHdeDpN/6tUdwvfiw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.9.tgz", + "integrity": "sha512-XIpIDMAjOELi/9PB30vEbVMs3GV1v2zkkPnuyRRURbhqjyzIINwj+nbQATh4H9GxUgH1kFsEyQMxwiLFKUS6Rg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.9.tgz", + "integrity": "sha512-jhHfBzjYTA1IQu8VyrjCX4ApJDnH+ez+IYVEoJHeqJm9VhG9Dh2BYaJritkYK3vMaXrf7Ogr/0MQ8/MeIefsPQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.9.tgz", + "integrity": "sha512-z93DmbnY6fX9+KdD4Ue/H6sYs+bhFQJNCPZsi4XWJoYblUqT06MQUdBCpcSfuiN72AbqeBFu5LVQTjfXDE2A6Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.9.tgz", + "integrity": "sha512-mrKX6H/vOyo5v71YfXWJxLVxgy1kyt1MQaD8wZJgJfG4gq4DpQGpgTB74e5yBeQdyMTbgxp0YtNj7NuHN0PoZg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.9.tgz", + "integrity": "sha512-HBU2Xv78SMgaydBmdor38lg8YDnFKSARg1Q6AT0/y2ezUAKiZvc211RDFHlEZRFNRVhcMamiToo7bDx3VEOYQw==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.9.tgz", + "integrity": "sha512-BlB7bIcLT3G26urh5Dmse7fiLmLXnRlopw4s8DalgZ8ef79Jj4aUcYbk90g8iCa2467HX8SAIidbL7gsqXHdRw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.9.tgz", + "integrity": "sha512-e7S3MOJPZGp2QW6AK6+Ly81rC7oOSerQ+P8L0ta4FhVi+/j/v2yZzx5CqqDaWjtPFfYz21Vi1S0auHrap3Ma3A==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.9.tgz", + "integrity": "sha512-Sbe10Bnn0oUAB2AalYztvGcK+o6YFFA/9829PhOCUS9vkJElXGdphz0A3DbMdP8gmKkqPmPcMJmJOrI3VYB1JQ==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.9.tgz", + "integrity": "sha512-YcM5br0mVyZw2jcQeLIkhWtKPeVfAerES5PvOzaDxVtIyZ2NUBZKNLjC5z3/fUlDgT6w89VsxP2qzNipOaaDyA==", + "cpu": [ + "mips64el" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.9.tgz", + "integrity": "sha512-++0HQvasdo20JytyDpFvQtNrEsAgNG2CY1CLMwGXfFTKGBGQT3bOeLSYE2l1fYdvML5KUuwn9Z8L1EWe2tzs1w==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.9.tgz", + "integrity": "sha512-uNIBa279Y3fkjV+2cUjx36xkx7eSjb8IvnL01eXUKXez/CBHNRw5ekCGMPM0BcmqBxBcdgUWuUXmVWwm4CH9kg==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.9.tgz", + "integrity": "sha512-Mfiphvp3MjC/lctb+7D287Xw1DGzqJPb/J2aHHcHxflUo+8tmN/6d4k6I2yFR7BVo5/g7x2Monq4+Yew0EHRIA==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.9.tgz", + "integrity": "sha512-iSwByxzRe48YVkmpbgoxVzn76BXjlYFXC7NvLYq+b+kDjyyk30J0JY47DIn8z1MO3K0oSl9fZoRmZPQI4Hklzg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.9.tgz", + "integrity": "sha512-9jNJl6FqaUG+COdQMjSCGW4QiMHH88xWbvZ+kRVblZsWrkXlABuGdFJ1E9L7HK+T0Yqd4akKNa/lO0+jDxQD4Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.9.tgz", + "integrity": "sha512-RLLdkflmqRG8KanPGOU7Rpg829ZHu8nFy5Pqdi9U01VYtG9Y0zOG6Vr2z4/S+/3zIyOxiK6cCeYNWOFR9QP87g==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.9.tgz", + "integrity": "sha512-YaFBlPGeDasft5IIM+CQAhJAqS3St3nJzDEgsgFixcfZeyGPCd6eJBWzke5piZuZ7CtL656eOSYKk4Ls2C0FRQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.9.tgz", + "integrity": "sha512-1MkgTCuvMGWuqVtAvkpkXFmtL8XhWy+j4jaSO2wxfJtilVCi0ZE37b8uOdMItIHz4I6z1bWWtEX4CJwcKYLcuA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.9.tgz", + "integrity": "sha512-4Xd0xNiMVXKh6Fa7HEJQbrpP3m3DDn43jKxMjxLLRjWnRsfxjORYJlXPO4JNcXtOyfajXorRKY9NkOpTHptErg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.9.tgz", + "integrity": "sha512-WjH4s6hzo00nNezhp3wFIAfmGZ8U7KtrJNlFMRKxiI9mxEK1scOMAaa9i4crUtu+tBr+0IN6JCuAcSBJZfnphw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.9.tgz", + "integrity": "sha512-mGFrVJHmZiRqmP8xFOc6b84/7xa5y5YvR1x8djzXpJBSv/UsNK6aqec+6JDjConTgvvQefdGhFDAs2DLAds6gQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.9.tgz", + "integrity": "sha512-b33gLVU2k11nVx1OhX3C8QQP6UHQK4ZtN56oFWvVXvz2VkDoe6fbG8TOgHFxEvqeqohmRnIHe5A1+HADk4OQww==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.9.tgz", + "integrity": "sha512-PPOl1mi6lpLNQxnGoyAfschAodRFYXJ+9fs6WHXz7CSWKbOqiMZsubC+BQsVKuul+3vKLuwTHsS2c2y9EoKwxQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz", + "integrity": "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.0.tgz", + "integrity": "sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.6", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.3.1.tgz", + "integrity": "sha512-xR93k9WhrDYpXHORXpxVL5oHj3Era7wo6k/Wd8/IsQNnZUTzkGS29lyn3nAT05v6ltUuTFVCCYDEGfy2Or/sPA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.15.2.tgz", + "integrity": "sha512-78Md3/Rrxh83gCxoUc0EiciuOHsIITzLy53m3d9UyiW8y9Dj2D29FeETqyKA+BRK76tnTp6RXWb3pCay8Oyomg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", + "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/js": { + "version": "9.34.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.34.0.tgz", + "integrity": "sha512-EoyvqQnBNsV1CWaEJ559rxXL4c8V92gxirbawSmVUOWXlsRxxQXl6LmCpdUblgxgSkDIqKnhzba2SjRTI/A5Rw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz", + "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.5.tgz", + "integrity": "sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.15.2", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@floating-ui/core": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.3.tgz", + "integrity": "sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==", + "license": "MIT", + "dependencies": { + "@floating-ui/utils": "^0.2.10" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.4.tgz", + "integrity": "sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA==", + "license": "MIT", + "dependencies": { + "@floating-ui/core": "^1.7.3", + "@floating-ui/utils": "^0.2.10" + } + }, + "node_modules/@floating-ui/react": { + "version": "0.26.28", + "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.26.28.tgz", + "integrity": "sha512-yORQuuAtVpiRjpMhdc0wJj06b9JFjrYF4qp96j++v2NBpbi6SEGF7donUJ3TMieerQ6qVkAv1tgr7L4r5roTqw==", + "license": "MIT", + "dependencies": { + "@floating-ui/react-dom": "^2.1.2", + "@floating-ui/utils": "^0.2.8", + "tabbable": "^6.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@floating-ui/react-dom": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.6.tgz", + "integrity": "sha512-4JX6rEatQEvlmgU80wZyq9RT96HZJa88q8hp0pBd+LrczeDI4o6uA2M+uvxngVHo4Ihr8uibXxH6+70zhAFrVw==", + "license": "MIT", + "dependencies": { + "@floating-ui/dom": "^1.7.4" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.10.tgz", + "integrity": "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==", + "license": "MIT" + }, + "node_modules/@headlessui/react": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/@headlessui/react/-/react-2.2.7.tgz", + "integrity": "sha512-WKdTymY8Y49H8/gUc/lIyYK1M+/6dq0Iywh4zTZVAaiTDprRfioxSgD0wnXTQTBpjpGJuTL1NO/mqEvc//5SSg==", + "license": "MIT", + "dependencies": { + "@floating-ui/react": "^0.26.16", + "@react-aria/focus": "^3.20.2", + "@react-aria/interactions": "^3.25.0", + "@tanstack/react-virtual": "^3.13.9", + "use-sync-external-store": "^1.5.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "react": "^18 || ^19 || ^19.0.0-rc", + "react-dom": "^18 || ^19 || ^19.0.0-rc" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.6", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", + "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.3.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", + "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@isaacs/fs-minipass": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", + "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", + "license": "ISC", + "dependencies": { + "minipass": "^7.0.4" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.30", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.30.tgz", + "integrity": "sha512-GQ7Nw5G2lTu/BtHTKfXhKHok2WGetd4XYcVKGx00SjAk8GMwgJM3zr6zORiPGuOE+/vkc90KtTosSSvaCjKb2Q==", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@radix-ui/primitive": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.3.tgz", + "integrity": "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==", + "license": "MIT" + }, + "node_modules/@radix-ui/react-checkbox": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-checkbox/-/react-checkbox-1.3.3.tgz", + "integrity": "sha512-wBbpv+NQftHDdG86Qc0pIyXk5IR3tM8Vd0nWLKDcX8nNn4nXFOFwsKuqw2okA/1D/mpaAkmuyndrPJTYDNZtFw==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-use-previous": "1.1.1", + "@radix-ui/react-use-size": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-compose-refs": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz", + "integrity": "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-context": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.2.tgz", + "integrity": "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-icons": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-icons/-/react-icons-1.3.2.tgz", + "integrity": "sha512-fyQIhGDhzfc9pK2kH6Pl9c4BDJGfMkPqkyIgYDthyNYoNg3wVhoJMMh19WS4Up/1KMPFVpNsT2q3WmXn2N1m6g==", + "license": "MIT", + "peerDependencies": { + "react": "^16.x || ^17.x || ^18.x || ^19.0.0 || ^19.0.0-rc" + } + }, + "node_modules/@radix-ui/react-presence": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.5.tgz", + "integrity": "sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-controllable-state": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.2.tgz", + "integrity": "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-effect-event": "0.0.2", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-effect-event": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-effect-event/-/react-use-effect-event-0.0.2.tgz", + "integrity": "sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-layout-effect": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.1.tgz", + "integrity": "sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-previous": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.1.tgz", + "integrity": "sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-size": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.1.tgz", + "integrity": "sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@react-aria/focus": { + "version": "3.21.1", + "resolved": "https://registry.npmjs.org/@react-aria/focus/-/focus-3.21.1.tgz", + "integrity": "sha512-hmH1IhHlcQ2lSIxmki1biWzMbGgnhdxJUM0MFfzc71Rv6YAzhlx4kX3GYn4VNcjCeb6cdPv4RZ5vunV4kgMZYQ==", + "license": "Apache-2.0", + "dependencies": { + "@react-aria/interactions": "^3.25.5", + "@react-aria/utils": "^3.30.1", + "@react-types/shared": "^3.32.0", + "@swc/helpers": "^0.5.0", + "clsx": "^2.0.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-aria/interactions": { + "version": "3.25.5", + "resolved": "https://registry.npmjs.org/@react-aria/interactions/-/interactions-3.25.5.tgz", + "integrity": "sha512-EweYHOEvMwef/wsiEqV73KurX/OqnmbzKQa2fLxdULbec5+yDj6wVGaRHIzM4NiijIDe+bldEl5DG05CAKOAHA==", + "license": "Apache-2.0", + "dependencies": { + "@react-aria/ssr": "^3.9.10", + "@react-aria/utils": "^3.30.1", + "@react-stately/flags": "^3.1.2", + "@react-types/shared": "^3.32.0", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-aria/ssr": { + "version": "3.9.10", + "resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.9.10.tgz", + "integrity": "sha512-hvTm77Pf+pMBhuBm760Li0BVIO38jv1IBws1xFm1NoL26PU+fe+FMW5+VZWyANR6nYL65joaJKZqOdTQMkO9IQ==", + "license": "Apache-2.0", + "dependencies": { + "@swc/helpers": "^0.5.0" + }, + "engines": { + "node": ">= 12" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-aria/utils": { + "version": "3.30.1", + "resolved": "https://registry.npmjs.org/@react-aria/utils/-/utils-3.30.1.tgz", + "integrity": "sha512-zETcbDd6Vf9GbLndO6RiWJadIZsBU2MMm23rBACXLmpRztkrIqPEb2RVdlLaq1+GklDx0Ii6PfveVjx+8S5U6A==", + "license": "Apache-2.0", + "dependencies": { + "@react-aria/ssr": "^3.9.10", + "@react-stately/flags": "^3.1.2", + "@react-stately/utils": "^3.10.8", + "@react-types/shared": "^3.32.0", + "@swc/helpers": "^0.5.0", + "clsx": "^2.0.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-leaflet/core": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@react-leaflet/core/-/core-3.0.0.tgz", + "integrity": "sha512-3EWmekh4Nz+pGcr+xjf0KNyYfC3U2JjnkWsh0zcqaexYqmmB5ZhH37kz41JXGmKzpaMZCnPofBBm64i+YrEvGQ==", + "license": "Hippocratic-2.1", + "peerDependencies": { + "leaflet": "^1.9.0", + "react": "^19.0.0", + "react-dom": "^19.0.0" + } + }, + "node_modules/@react-stately/flags": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@react-stately/flags/-/flags-3.1.2.tgz", + "integrity": "sha512-2HjFcZx1MyQXoPqcBGALwWWmgFVUk2TuKVIQxCbRq7fPyWXIl6VHcakCLurdtYC2Iks7zizvz0Idv48MQ38DWg==", + "license": "Apache-2.0", + "dependencies": { + "@swc/helpers": "^0.5.0" + } + }, + "node_modules/@react-stately/utils": { + "version": "3.10.8", + "resolved": "https://registry.npmjs.org/@react-stately/utils/-/utils-3.10.8.tgz", + "integrity": "sha512-SN3/h7SzRsusVQjQ4v10LaVsDc81jyyR0DD5HnsQitm/I5WDpaSr2nRHtyloPFU48jlql1XX/S04T2DLQM7Y3g==", + "license": "Apache-2.0", + "dependencies": { + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-types/shared": { + "version": "3.32.0", + "resolved": "https://registry.npmjs.org/@react-types/shared/-/shared-3.32.0.tgz", + "integrity": "sha512-t+cligIJsZYFMSPFMvsJMjzlzde06tZMOIOFa1OV5Z0BcMowrb2g4mB57j/9nP28iJIRYn10xCniQts+qadrqQ==", + "license": "Apache-2.0", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@reduxjs/toolkit": { + "version": "2.11.2", + "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.11.2.tgz", + "integrity": "sha512-Kd6kAHTA6/nUpp8mySPqj3en3dm0tdMIgbttnQ1xFMVpufoj+ADi8pXLBsd4xzTRHQa7t/Jv8W5UnCuW4kuWMQ==", + "license": "MIT", + "dependencies": { + "@standard-schema/spec": "^1.0.0", + "@standard-schema/utils": "^0.3.0", + "immer": "^11.0.0", + "redux": "^5.0.1", + "redux-thunk": "^3.1.0", + "reselect": "^5.1.0" + }, + "peerDependencies": { + "react": "^16.9.0 || ^17.0.0 || ^18 || ^19", + "react-redux": "^7.2.1 || ^8.1.3 || ^9.0.0" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + }, + "react-redux": { + "optional": true + } + } + }, + "node_modules/@reduxjs/toolkit/node_modules/immer": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/immer/-/immer-11.0.1.tgz", + "integrity": "sha512-naDCyggtcBWANtIrjQEajhhBEuL9b0Zg4zmlWK2CzS6xCWSE39/vvf4LqnMjUAWHBhot4m9MHCM/Z+mfWhUkiA==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-beta.32", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.32.tgz", + "integrity": "sha512-QReCdvxiUZAPkvp1xpAg62IeNzykOFA6syH2CnClif4YmALN1XKpB39XneL80008UbtMShthSVDKmrx05N1q/g==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.48.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.48.1.tgz", + "integrity": "sha512-rGmb8qoG/zdmKoYELCBwu7vt+9HxZ7Koos3pD0+sH5fR3u3Wb/jGcpnqxcnWsPEKDUyzeLSqksN8LJtgXjqBYw==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.48.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.48.1.tgz", + "integrity": "sha512-4e9WtTxrk3gu1DFE+imNJr4WsL13nWbD/Y6wQcyku5qadlKHY3OQ3LJ/INrrjngv2BJIHnIzbqMk1GTAC2P8yQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.48.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.48.1.tgz", + "integrity": "sha512-+XjmyChHfc4TSs6WUQGmVf7Hkg8ferMAE2aNYYWjiLzAS/T62uOsdfnqv+GHRjq7rKRnYh4mwWb4Hz7h/alp8A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.48.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.48.1.tgz", + "integrity": "sha512-upGEY7Ftw8M6BAJyGwnwMw91rSqXTcOKZnnveKrVWsMTF8/k5mleKSuh7D4v4IV1pLxKAk3Tbs0Lo9qYmii5mQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.48.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.48.1.tgz", + "integrity": "sha512-P9ViWakdoynYFUOZhqq97vBrhuvRLAbN/p2tAVJvhLb8SvN7rbBnJQcBu8e/rQts42pXGLVhfsAP0k9KXWa3nQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.48.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.48.1.tgz", + "integrity": "sha512-VLKIwIpnBya5/saccM8JshpbxfyJt0Dsli0PjXozHwbSVaHTvWXJH1bbCwPXxnMzU4zVEfgD1HpW3VQHomi2AQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.48.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.48.1.tgz", + "integrity": "sha512-3zEuZsXfKaw8n/yF7t8N6NNdhyFw3s8xJTqjbTDXlipwrEHo4GtIKcMJr5Ed29leLpB9AugtAQpAHW0jvtKKaQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.48.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.48.1.tgz", + "integrity": "sha512-leo9tOIlKrcBmmEypzunV/2w946JeLbTdDlwEZ7OnnsUyelZ72NMnT4B2vsikSgwQifjnJUbdXzuW4ToN1wV+Q==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.48.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.48.1.tgz", + "integrity": "sha512-Vy/WS4z4jEyvnJm+CnPfExIv5sSKqZrUr98h03hpAMbE2aI0aD2wvK6GiSe8Gx2wGp3eD81cYDpLLBqNb2ydwQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.48.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.48.1.tgz", + "integrity": "sha512-x5Kzn7XTwIssU9UYqWDB9VpLpfHYuXw5c6bJr4Mzv9kIv242vmJHbI5PJJEnmBYitUIfoMCODDhR7KoZLot2VQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loongarch64-gnu": { + "version": "4.48.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.48.1.tgz", + "integrity": "sha512-yzCaBbwkkWt/EcgJOKDUdUpMHjhiZT/eDktOPWvSRpqrVE04p0Nd6EGV4/g7MARXXeOqstflqsKuXVM3H9wOIQ==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.48.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.48.1.tgz", + "integrity": "sha512-UK0WzWUjMAJccHIeOpPhPcKBqax7QFg47hwZTp6kiMhQHeOYJeaMwzeRZe1q5IiTKsaLnHu9s6toSYVUlZ2QtQ==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.48.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.48.1.tgz", + "integrity": "sha512-3NADEIlt+aCdCbWVZ7D3tBjBX1lHpXxcvrLt/kdXTiBrOds8APTdtk2yRL2GgmnSVeX4YS1JIf0imFujg78vpw==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.48.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.48.1.tgz", + "integrity": "sha512-euuwm/QTXAMOcyiFCcrx0/S2jGvFlKJ2Iro8rsmYL53dlblp3LkUQVFzEidHhvIPPvcIsxDhl2wkBE+I6YVGzA==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.48.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.48.1.tgz", + "integrity": "sha512-w8mULUjmPdWLJgmTYJx/W6Qhln1a+yqvgwmGXcQl2vFBkWsKGUBRbtLRuKJUln8Uaimf07zgJNxOhHOvjSQmBQ==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.48.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.48.1.tgz", + "integrity": "sha512-90taWXCWxTbClWuMZD0DKYohY1EovA+W5iytpE89oUPmT5O1HFdf8cuuVIylE6vCbrGdIGv85lVRzTcpTRZ+kA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.48.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.48.1.tgz", + "integrity": "sha512-2Gu29SkFh1FfTRuN1GR1afMuND2GKzlORQUP3mNMJbqdndOg7gNsa81JnORctazHRokiDzQ5+MLE5XYmZW5VWg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.48.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.48.1.tgz", + "integrity": "sha512-6kQFR1WuAO50bxkIlAVeIYsz3RUx+xymwhTo9j94dJ+kmHe9ly7muH23sdfWduD0BA8pD9/yhonUvAjxGh34jQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.48.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.48.1.tgz", + "integrity": "sha512-RUyZZ/mga88lMI3RlXFs4WQ7n3VyU07sPXmMG7/C1NOi8qisUg57Y7LRarqoGoAiopmGmChUhSwfpvQ3H5iGSQ==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.48.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.48.1.tgz", + "integrity": "sha512-8a/caCUN4vkTChxkaIJcMtwIVcBhi4X2PQRoT+yCK3qRYaZ7cURrmJFL5Ux9H9RaMIXj9RuihckdmkBX3zZsgg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@socket.io/component-emitter": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz", + "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==", + "license": "MIT" + }, + "node_modules/@standard-schema/spec": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", + "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", + "license": "MIT" + }, + "node_modules/@standard-schema/utils": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@standard-schema/utils/-/utils-0.3.0.tgz", + "integrity": "sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==", + "license": "MIT" + }, + "node_modules/@swc/helpers": { + "version": "0.5.17", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.17.tgz", + "integrity": "sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.8.0" + } + }, + "node_modules/@tailwindcss/node": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.12.tgz", + "integrity": "sha512-3hm9brwvQkZFe++SBt+oLjo4OLDtkvlE8q2WalaD/7QWaeM7KEJbAiY/LJZUaCs7Xa8aUu4xy3uoyX4q54UVdQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/remapping": "^2.3.4", + "enhanced-resolve": "^5.18.3", + "jiti": "^2.5.1", + "lightningcss": "1.30.1", + "magic-string": "^0.30.17", + "source-map-js": "^1.2.1", + "tailwindcss": "4.1.12" + } + }, + "node_modules/@tailwindcss/oxide": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.12.tgz", + "integrity": "sha512-gM5EoKHW/ukmlEtphNwaGx45fGoEmP10v51t9unv55voWh6WrOL19hfuIdo2FjxIaZzw776/BUQg7Pck++cIVw==", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "detect-libc": "^2.0.4", + "tar": "^7.4.3" + }, + "engines": { + "node": ">= 10" + }, + "optionalDependencies": { + "@tailwindcss/oxide-android-arm64": "4.1.12", + "@tailwindcss/oxide-darwin-arm64": "4.1.12", + "@tailwindcss/oxide-darwin-x64": "4.1.12", + "@tailwindcss/oxide-freebsd-x64": "4.1.12", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.12", + "@tailwindcss/oxide-linux-arm64-gnu": "4.1.12", + "@tailwindcss/oxide-linux-arm64-musl": "4.1.12", + "@tailwindcss/oxide-linux-x64-gnu": "4.1.12", + "@tailwindcss/oxide-linux-x64-musl": "4.1.12", + "@tailwindcss/oxide-wasm32-wasi": "4.1.12", + "@tailwindcss/oxide-win32-arm64-msvc": "4.1.12", + "@tailwindcss/oxide-win32-x64-msvc": "4.1.12" + } + }, + "node_modules/@tailwindcss/oxide-android-arm64": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.12.tgz", + "integrity": "sha512-oNY5pq+1gc4T6QVTsZKwZaGpBb2N1H1fsc1GD4o7yinFySqIuRZ2E4NvGasWc6PhYJwGK2+5YT1f9Tp80zUQZQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-darwin-arm64": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.12.tgz", + "integrity": "sha512-cq1qmq2HEtDV9HvZlTtrj671mCdGB93bVY6J29mwCyaMYCP/JaUBXxrQQQm7Qn33AXXASPUb2HFZlWiiHWFytw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-darwin-x64": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.12.tgz", + "integrity": "sha512-6UCsIeFUcBfpangqlXay9Ffty9XhFH1QuUFn0WV83W8lGdX8cD5/+2ONLluALJD5+yJ7k8mVtwy3zMZmzEfbLg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-freebsd-x64": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.12.tgz", + "integrity": "sha512-JOH/f7j6+nYXIrHobRYCtoArJdMJh5zy5lr0FV0Qu47MID/vqJAY3r/OElPzx1C/wdT1uS7cPq+xdYYelny1ww==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.12.tgz", + "integrity": "sha512-v4Ghvi9AU1SYgGr3/j38PD8PEe6bRfTnNSUE3YCMIRrrNigCFtHZ2TCm8142X8fcSqHBZBceDx+JlFJEfNg5zQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.12.tgz", + "integrity": "sha512-YP5s1LmetL9UsvVAKusHSyPlzSRqYyRB0f+Kl/xcYQSPLEw/BvGfxzbH+ihUciePDjiXwHh+p+qbSP3SlJw+6g==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-musl": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.12.tgz", + "integrity": "sha512-V8pAM3s8gsrXcCv6kCHSuwyb/gPsd863iT+v1PGXC4fSL/OJqsKhfK//v8P+w9ThKIoqNbEnsZqNy+WDnwQqCA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-gnu": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.12.tgz", + "integrity": "sha512-xYfqYLjvm2UQ3TZggTGrwxjYaLB62b1Wiysw/YE3Yqbh86sOMoTn0feF98PonP7LtjsWOWcXEbGqDL7zv0uW8Q==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-musl": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.12.tgz", + "integrity": "sha512-ha0pHPamN+fWZY7GCzz5rKunlv9L5R8kdh+YNvP5awe3LtuXb5nRi/H27GeL2U+TdhDOptU7T6Is7mdwh5Ar3A==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.12.tgz", + "integrity": "sha512-4tSyu3dW+ktzdEpuk6g49KdEangu3eCYoqPhWNsZgUhyegEda3M9rG0/j1GV/JjVVsj+lG7jWAyrTlLzd/WEBg==", + "bundleDependencies": [ + "@napi-rs/wasm-runtime", + "@emnapi/core", + "@emnapi/runtime", + "@tybys/wasm-util", + "@emnapi/wasi-threads", + "tslib" + ], + "cpu": [ + "wasm32" + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.4.5", + "@emnapi/runtime": "^1.4.5", + "@emnapi/wasi-threads": "^1.0.4", + "@napi-rs/wasm-runtime": "^0.2.12", + "@tybys/wasm-util": "^0.10.0", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.12.tgz", + "integrity": "sha512-iGLyD/cVP724+FGtMWslhcFyg4xyYyM+5F4hGvKA7eifPkXHRAUDFaimu53fpNg9X8dfP75pXx/zFt/jlNF+lg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-win32-x64-msvc": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.12.tgz", + "integrity": "sha512-NKIh5rzw6CpEodv/++r0hGLlfgT/gFN+5WNdZtvh6wpU2BpGNgdjvj6H2oFc8nCM839QM1YOhjpgbAONUb4IxA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/vite": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.1.12.tgz", + "integrity": "sha512-4pt0AMFDx7gzIrAOIYgYP0KCBuKWqyW8ayrdiLEjoJTT4pKTjrzG/e4uzWtTLDziC+66R9wbUqZBccJalSE5vQ==", + "license": "MIT", + "dependencies": { + "@tailwindcss/node": "4.1.12", + "@tailwindcss/oxide": "4.1.12", + "tailwindcss": "4.1.12" + }, + "peerDependencies": { + "vite": "^5.2.0 || ^6 || ^7" + } + }, + "node_modules/@tanstack/query-core": { + "version": "5.85.5", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.85.5.tgz", + "integrity": "sha512-KO0WTob4JEApv69iYp1eGvfMSUkgw//IpMnq+//cORBzXf0smyRwPLrUvEe5qtAEGjwZTXrjxg+oJNP/C00t6w==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/react-query": { + "version": "5.85.5", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.85.5.tgz", + "integrity": "sha512-/X4EFNcnPiSs8wM2v+b6DqS5mmGeuJQvxBglmDxl6ZQb5V26ouD2SJYAcC3VjbNwqhY2zjxVD15rDA5nGbMn3A==", + "license": "MIT", + "dependencies": { + "@tanstack/query-core": "5.85.5" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^18 || ^19" + } + }, + "node_modules/@tanstack/react-virtual": { + "version": "3.13.12", + "resolved": "https://registry.npmjs.org/@tanstack/react-virtual/-/react-virtual-3.13.12.tgz", + "integrity": "sha512-Gd13QdxPSukP8ZrkbgS2RwoZseTTbQPLnQEn7HY/rqtM+8Zt95f7xKC7N0EsKs7aoz0WzZ+fditZux+F8EzYxA==", + "license": "MIT", + "dependencies": { + "@tanstack/virtual-core": "3.13.12" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/@tanstack/virtual-core": { + "version": "3.13.12", + "resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.13.12.tgz", + "integrity": "sha512-1YBOJfRHV4sXUmWsFSf5rQor4Ss82G8dQWLRbnk3GA4jeP8hQt1hxXh0tmflpC0dz3VgEv/1+qwPyLeWkQuPFA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", + "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.2" + } + }, + "node_modules/@types/d3-array": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.2.tgz", + "integrity": "sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw==", + "license": "MIT" + }, + "node_modules/@types/d3-color": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz", + "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==", + "license": "MIT" + }, + "node_modules/@types/d3-ease": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz", + "integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==", + "license": "MIT" + }, + "node_modules/@types/d3-interpolate": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz", + "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==", + "license": "MIT", + "dependencies": { + "@types/d3-color": "*" + } + }, + "node_modules/@types/d3-path": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.1.tgz", + "integrity": "sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==", + "license": "MIT" + }, + "node_modules/@types/d3-scale": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.9.tgz", + "integrity": "sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==", + "license": "MIT", + "dependencies": { + "@types/d3-time": "*" + } + }, + "node_modules/@types/d3-shape": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.7.tgz", + "integrity": "sha512-VLvUQ33C+3J+8p+Daf+nYSOsjB4GXp19/S/aGo60m9h1v6XaxjiT82lKVWJCfzhtuZ3yD7i/TPeC/fuKLLOSmg==", + "license": "MIT", + "dependencies": { + "@types/d3-path": "*" + } + }, + "node_modules/@types/d3-time": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.4.tgz", + "integrity": "sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==", + "license": "MIT" + }, + "node_modules/@types/d3-timer": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz", + "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==", + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "license": "MIT" + }, + "node_modules/@types/geojson": { + "version": "7946.0.16", + "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.16.tgz", + "integrity": "sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/hoist-non-react-statics": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.7.tgz", + "integrity": "sha512-PQTyIulDkIDro8P+IHbKCsw7U2xxBYflVzW/FgWdCAePD9xGSidgA76/GeJ6lBKoblyhf9pBY763gbrN+1dI8g==", + "license": "MIT", + "dependencies": { + "hoist-non-react-statics": "^3.3.0" + }, + "peerDependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/leaflet": { + "version": "1.9.21", + "resolved": "https://registry.npmjs.org/@types/leaflet/-/leaflet-1.9.21.tgz", + "integrity": "sha512-TbAd9DaPGSnzp6QvtYngntMZgcRk+igFELwR2N99XZn7RXUdKgsXMR+28bUO0rPsWp8MIu/f47luLIQuSLYv/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/geojson": "*" + } + }, + "node_modules/@types/moment-jalaali": { + "version": "0.7.9", + "resolved": "https://registry.npmjs.org/@types/moment-jalaali/-/moment-jalaali-0.7.9.tgz", + "integrity": "sha512-gsDOoAzRnCfQTbfdlUrCvX6R0wIto6CvwfvV2C3j4qJLK+DEiTK8Rl/xlOCBO9C6qeUfX8oyZ2UfjnXJTOvHSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "moment": ">=2.14.0" + } + }, + "node_modules/@types/node": { + "version": "24.10.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.1.tgz", + "integrity": "sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "undici-types": "~7.16.0" + } + }, + "node_modules/@types/react": { + "version": "19.1.11", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.11.tgz", + "integrity": "sha512-lr3jdBw/BGj49Eps7EvqlUaoeA0xpj3pc0RoJkHpYaCHkVK7i28dKyImLQb3JVlqs3aYSXf7qYuWOW/fgZnTXQ==", + "license": "MIT", + "dependencies": { + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "19.1.8", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.1.8.tgz", + "integrity": "sha512-xG7xaBMJCpcK0RpN8jDbAACQo54ycO6h4dSSmgv8+fu6ZIAdANkx/WsawASUjVXYfy+J9AbUpRMNNEsXCDfDBQ==", + "devOptional": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^19.0.0" + } + }, + "node_modules/@types/use-sync-external-store": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.6.tgz", + "integrity": "sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==", + "license": "MIT" + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.41.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.41.0.tgz", + "integrity": "sha512-8fz6oa6wEKZrhXWro/S3n2eRJqlRcIa6SlDh59FXJ5Wp5XRZ8B9ixpJDcjadHq47hMx0u+HW6SNa6LjJQ6NLtw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "8.41.0", + "@typescript-eslint/type-utils": "8.41.0", + "@typescript-eslint/utils": "8.41.0", + "@typescript-eslint/visitor-keys": "8.41.0", + "graphemer": "^1.4.0", + "ignore": "^7.0.0", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.41.0", + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.41.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.41.0.tgz", + "integrity": "sha512-gTtSdWX9xiMPA/7MV9STjJOOYtWwIJIYxkQxnSV1U3xcE+mnJSH3f6zI0RYP+ew66WSlZ5ed+h0VCxsvdC1jJg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/scope-manager": "8.41.0", + "@typescript-eslint/types": "8.41.0", + "@typescript-eslint/typescript-estree": "8.41.0", + "@typescript-eslint/visitor-keys": "8.41.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/project-service": { + "version": "8.41.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.41.0.tgz", + "integrity": "sha512-b8V9SdGBQzQdjJ/IO3eDifGpDBJfvrNTp2QD9P2BeqWTGrRibgfgIlBSw6z3b6R7dPzg752tOs4u/7yCLxksSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.41.0", + "@typescript-eslint/types": "^8.41.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.41.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.41.0.tgz", + "integrity": "sha512-n6m05bXn/Cd6DZDGyrpXrELCPVaTnLdPToyhBoFkLIMznRUQUEQdSp96s/pcWSQdqOhrgR1mzJ+yItK7T+WPMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.41.0", + "@typescript-eslint/visitor-keys": "8.41.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.41.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.41.0.tgz", + "integrity": "sha512-TDhxYFPUYRFxFhuU5hTIJk+auzM/wKvWgoNYOPcOf6i4ReYlOoYN8q1dV5kOTjNQNJgzWN3TUUQMtlLOcUgdUw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.41.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.41.0.tgz", + "integrity": "sha512-63qt1h91vg3KsjVVonFJWjgSK7pZHSQFKH6uwqxAH9bBrsyRhO6ONoKyXxyVBzG1lJnFAJcKAcxLS54N1ee1OQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.41.0", + "@typescript-eslint/typescript-estree": "8.41.0", + "@typescript-eslint/utils": "8.41.0", + "debug": "^4.3.4", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.41.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.41.0.tgz", + "integrity": "sha512-9EwxsWdVqh42afLbHP90n2VdHaWU/oWgbH2P0CfcNfdKL7CuKpwMQGjwev56vWu9cSKU7FWSu6r9zck6CVfnag==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.41.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.41.0.tgz", + "integrity": "sha512-D43UwUYJmGhuwHfY7MtNKRZMmfd8+p/eNSfFe6tH5mbVDto+VQCayeAt35rOx3Cs6wxD16DQtIKw/YXxt5E0UQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.41.0", + "@typescript-eslint/tsconfig-utils": "8.41.0", + "@typescript-eslint/types": "8.41.0", + "@typescript-eslint/visitor-keys": "8.41.0", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.41.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.41.0.tgz", + "integrity": "sha512-udbCVstxZ5jiPIXrdH+BZWnPatjlYwJuJkDA4Tbo3WyYLh8NvB+h/bKeSZHDOFKfphsZYJQqaFtLeXEqurQn1A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.7.0", + "@typescript-eslint/scope-manager": "8.41.0", + "@typescript-eslint/types": "8.41.0", + "@typescript-eslint/typescript-estree": "8.41.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.41.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.41.0.tgz", + "integrity": "sha512-+GeGMebMCy0elMNg67LRNoVnUFPIm37iu5CmHESVx56/9Jsfdpsvbv605DQ81Pi/x11IdKUsS5nzgTYbCQU9fg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.41.0", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@vitejs/plugin-react": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-5.0.1.tgz", + "integrity": "sha512-DE4UNaBXwtVoDJ0ccBdLVjFTWL70NRuWNCxEieTI3lrq9ORB9aOCQEKstwDXBl87NvFdbqh/p7eINGyj0BthJA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.28.3", + "@babel/plugin-transform-react-jsx-self": "^7.27.1", + "@babel/plugin-transform-react-jsx-source": "^7.27.1", + "@rolldown/pluginutils": "1.0.0-beta.32", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.17.0" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "peerDependencies": { + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" + } + }, + "node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, + "node_modules/attr-accept": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/attr-accept/-/attr-accept-2.2.5.tgz", + "integrity": "sha512-0bDNnY/u6pPwHDMoF0FieU354oBi0a8rD9FcsLwzcGWbc8KS8KPIi7y+s13OlVY+gMWc/9xEMUgNE6Qm8ZllYQ==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/autoprefixer": { + "version": "10.4.21", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.21.tgz", + "integrity": "sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "browserslist": "^4.24.4", + "caniuse-lite": "^1.0.30001702", + "fraction.js": "^4.3.7", + "normalize-range": "^0.1.2", + "picocolors": "^1.1.1", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/axios": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.1.tgz", + "integrity": "sha512-hU4EGxxt+j7TQijx1oYdAjw4xuIp1wRQSsbMFwSthCWeBQur1eF+qJ5iQ5sN3Tw8YRzQNKb8jszgBdMDVqwJcw==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.4", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.25.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.3.tgz", + "integrity": "sha512-cDGv1kkDI4/0e5yON9yM5G/0A5u8sf5TnmdX5C9qHzI9PPu++sQ9zjm1k9NiOrf3riY4OkK0zSGqfvJyJsgCBQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "caniuse-lite": "^1.0.30001735", + "electron-to-chromium": "^1.5.204", + "node-releases": "^2.0.19", + "update-browserslist-db": "^1.1.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001737", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001737.tgz", + "integrity": "sha512-BiloLiXtQNrY5UyF0+1nSJLXUENuhka2pzy2Fx5pGxqavdrxSCW4U6Pn/PoG3Efspi2frRbHpBV2XsrPE6EDlw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chownr": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/classnames": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz", + "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==", + "license": "MIT" + }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/cookie": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz", + "integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "license": "MIT" + }, + "node_modules/d3-array": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", + "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", + "license": "ISC", + "dependencies": { + "internmap": "1 - 2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-ease": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", + "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-format": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", + "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "license": "ISC", + "dependencies": { + "d3-color": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-scale": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", + "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", + "license": "ISC", + "dependencies": { + "d3-array": "2.10.0 - 3", + "d3-format": "1 - 3", + "d3-interpolate": "1.2.0 - 3", + "d3-time": "2.1.1 - 3", + "d3-time-format": "2 - 4" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-shape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", + "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", + "license": "ISC", + "dependencies": { + "d3-path": "^3.1.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", + "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", + "license": "ISC", + "dependencies": { + "d3-array": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time-format": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", + "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", + "license": "ISC", + "dependencies": { + "d3-time": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-timer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", + "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/debug": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decimal.js-light": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/decimal.js-light/-/decimal.js-light-2.5.1.tgz", + "integrity": "sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==", + "license": "MIT" + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/deepmerge": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.2.1.tgz", + "integrity": "sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/detect-libc": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", + "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==", + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.209", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.209.tgz", + "integrity": "sha512-Xoz0uMrim9ZETCQt8UgM5FxQF9+imA7PBpokoGcZloA1uw2LeHzTlip5cb5KOAsXZLjh/moN2vReN3ZjJmjI9A==", + "dev": true, + "license": "ISC" + }, + "node_modules/engine.io-client": { + "version": "6.6.3", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.6.3.tgz", + "integrity": "sha512-T0iLjnyNWahNyv/lcjS2y4oE358tVS/SYQNxYXGAJ9/GLgH4VCvOQ/mhTjqU88mLZCQgiG8RIegFHYCdVC+j5w==", + "license": "MIT", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1", + "engine.io-parser": "~5.2.1", + "ws": "~8.17.1", + "xmlhttprequest-ssl": "~2.1.1" + } + }, + "node_modules/engine.io-client/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/engine.io-parser": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz", + "integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/enhanced-resolve": { + "version": "5.18.3", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.3.tgz", + "integrity": "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-toolkit": { + "version": "1.43.0", + "resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.43.0.tgz", + "integrity": "sha512-SKCT8AsWvYzBBuUqMk4NPwFlSdqLpJwmy6AP322ERn8W2YLIB6JBXnwMI2Qsh2gfphT3q7EKAxKb23cvFHFwKA==", + "license": "MIT", + "workspaces": [ + "docs", + "benchmarks" + ] + }, + "node_modules/esbuild": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.9.tgz", + "integrity": "sha512-CRbODhYyQx3qp7ZEwzxOk4JBqmD/seJrzPa/cGjY1VtIn5E09Oi9/dB4JwctnfZ8Q8iT7rioVv5k/FNT/uf54g==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.9", + "@esbuild/android-arm": "0.25.9", + "@esbuild/android-arm64": "0.25.9", + "@esbuild/android-x64": "0.25.9", + "@esbuild/darwin-arm64": "0.25.9", + "@esbuild/darwin-x64": "0.25.9", + "@esbuild/freebsd-arm64": "0.25.9", + "@esbuild/freebsd-x64": "0.25.9", + "@esbuild/linux-arm": "0.25.9", + "@esbuild/linux-arm64": "0.25.9", + "@esbuild/linux-ia32": "0.25.9", + "@esbuild/linux-loong64": "0.25.9", + "@esbuild/linux-mips64el": "0.25.9", + "@esbuild/linux-ppc64": "0.25.9", + "@esbuild/linux-riscv64": "0.25.9", + "@esbuild/linux-s390x": "0.25.9", + "@esbuild/linux-x64": "0.25.9", + "@esbuild/netbsd-arm64": "0.25.9", + "@esbuild/netbsd-x64": "0.25.9", + "@esbuild/openbsd-arm64": "0.25.9", + "@esbuild/openbsd-x64": "0.25.9", + "@esbuild/openharmony-arm64": "0.25.9", + "@esbuild/sunos-x64": "0.25.9", + "@esbuild/win32-arm64": "0.25.9", + "@esbuild/win32-ia32": "0.25.9", + "@esbuild/win32-x64": "0.25.9" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "9.34.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.34.0.tgz", + "integrity": "sha512-RNCHRX5EwdrESy3Jc9o8ie8Bog+PeYvvSR8sDGoZxNFTvZ4dlxUB3WzQ3bQMztFrSRODGrLLj8g6OFuGY/aiQg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.21.0", + "@eslint/config-helpers": "^0.3.1", + "@eslint/core": "^0.15.2", + "@eslint/eslintrc": "^3.3.1", + "@eslint/js": "9.34.0", + "@eslint/plugin-kit": "^0.3.5", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.4.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.2.0.tgz", + "integrity": "sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==", + "dev": true, + "license": "MIT", + "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" + } + }, + "node_modules/eslint-plugin-react-refresh": { + "version": "0.4.20", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.20.tgz", + "integrity": "sha512-XpbHQ2q5gUF8BGOX4dHe+71qoirYMhApEPZ7sfhF/dNnOF1UXnCMGZf79SFTBO7Bz5YEIT4TMieSlJBWhP9WBA==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "eslint": ">=8.40" + } + }, + "node_modules/eslint-scope": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", + "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.15.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "license": "MIT" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fastq": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/file-selector": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/file-selector/-/file-selector-2.1.2.tgz", + "integrity": "sha512-QgXo+mXTe8ljeqUFaX3QVHc5osSItJ/Km+xpocx0aSqWGMSCf6qYs/VnzZgS864Pjn5iceMRFigeAV7AfTlaig==", + "license": "MIT", + "dependencies": { + "tslib": "^2.7.0" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "dev": true, + "license": "ISC" + }, + "node_modules/follow-redirects": { + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", + "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", + "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/formik": { + "version": "2.4.6", + "resolved": "https://registry.npmjs.org/formik/-/formik-2.4.6.tgz", + "integrity": "sha512-A+2EI7U7aG296q2TLGvNapDNTZp1khVt5Vk0Q/fyfSROss0V/V6+txt2aJnwEos44IxTCW/LYAi/zgWzlevj+g==", + "funding": [ + { + "type": "individual", + "url": "https://opencollective.com/formik" + } + ], + "license": "Apache-2.0", + "dependencies": { + "@types/hoist-non-react-statics": "^3.3.1", + "deepmerge": "^2.1.1", + "hoist-non-react-statics": "^3.3.0", + "lodash": "^4.17.21", + "lodash-es": "^4.17.21", + "react-fast-compare": "^2.0.1", + "tiny-warning": "^1.0.2", + "tslib": "^2.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/fraction.js": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "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" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "16.3.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-16.3.0.tgz", + "integrity": "sha512-bqWEnJ1Nt3neqx2q5SFfGS8r/ahumIakg3HcwtNlrVlwXIeNumWn/c7Pn/wKzGhf6SaW6H6uWXLqC30STCMchQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "license": "ISC" + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true, + "license": "MIT" + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "license": "BSD-3-Clause", + "dependencies": { + "react-is": "^16.7.0" + } + }, + "node_modules/hoist-non-react-statics/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "license": "MIT" + }, + "node_modules/html-parse-stringify": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz", + "integrity": "sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==", + "license": "MIT", + "dependencies": { + "void-elements": "3.1.0" + } + }, + "node_modules/i18next": { + "version": "25.4.2", + "resolved": "https://registry.npmjs.org/i18next/-/i18next-25.4.2.tgz", + "integrity": "sha512-gD4T25a6ovNXsfXY1TwHXXXLnD/K2t99jyYMCSimSCBnBRJVQr5j+VAaU83RJCPzrTGhVQ6dqIga66xO2rtd5g==", + "funding": [ + { + "type": "individual", + "url": "https://locize.com" + }, + { + "type": "individual", + "url": "https://locize.com/i18next.html" + }, + { + "type": "individual", + "url": "https://www.i18next.com/how-to/faq#i18next-is-awesome.-how-can-i-support-the-project" + } + ], + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.27.6" + }, + "peerDependencies": { + "typescript": "^5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/iconsax-react": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/iconsax-react/-/iconsax-react-0.0.8.tgz", + "integrity": "sha512-l3dVk4zGtkkJHgvNYqAf0wDKqnKxXykee5/DoESGo2JvSYwaxajJUHSX2YrPRXSov8Hd8ClGFwJxCEaEjrFD1Q==", + "license": "MIT", + "dependencies": { + "prop-types": "^15.7.2" + }, + "peerDependencies": { + "react": "*" + } + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/immer": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/immer/-/immer-10.2.0.tgz", + "integrity": "sha512-d/+XTN3zfODyjr89gM3mPq1WNX2B8pYsu7eORitdwyA2sBubnTl3laYlBk4sXY5FUa5qTZGBDPJICVbvqzjlbw==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" + } + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/internmap": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", + "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/jalaali-js": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/jalaali-js/-/jalaali-js-1.2.8.tgz", + "integrity": "sha512-Jl/EwY84JwjW2wsWqeU4pNd22VNQ7EkjI36bDuLw31wH98WQW4fPjD0+mG7cdCK+Y8D6s9R3zLiQ3LaKu6bD8A==", + "license": "MIT" + }, + "node_modules/jiti": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.5.1.tgz", + "integrity": "sha512-twQoecYPiVA5K/h6SxtORw/Bs3ar+mLUtoPSc7iMXzQzK8d7eJ/R09wmTwAjiamETn1cXYPGfNnu7DMoHgu12w==", + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/leaflet": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.9.4.tgz", + "integrity": "sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA==", + "license": "BSD-2-Clause" + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lightningcss": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.1.tgz", + "integrity": "sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg==", + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-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" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.1.tgz", + "integrity": "sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.1.tgz", + "integrity": "sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.1.tgz", + "integrity": "sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.1.tgz", + "integrity": "sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q==", + "cpu": [ + "arm" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.1.tgz", + "integrity": "sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.1.tgz", + "integrity": "sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.1.tgz", + "integrity": "sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.1.tgz", + "integrity": "sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.1.tgz", + "integrity": "sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.1.tgz", + "integrity": "sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "license": "MIT" + }, + "node_modules/lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", + "license": "MIT" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/magic-string": { + "version": "0.30.18", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.18.tgz", + "integrity": "sha512-yi8swmWbO17qHhwIBNeeZxTceJMeBvWJaId6dyvTSOwTipqeHhMhOrz6513r1sOKnpvQ7zkhlG8tPrpilwTxHQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minizlib": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.0.2.tgz", + "integrity": "sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA==", + "license": "MIT", + "dependencies": { + "minipass": "^7.1.2" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/mkdirp": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", + "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", + "license": "MIT", + "bin": { + "mkdirp": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/moment": { + "version": "2.30.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", + "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==", + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/moment-jalaali": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/moment-jalaali/-/moment-jalaali-0.10.4.tgz", + "integrity": "sha512-/eD0HeyvATznb5iE0G1BHjKRZAFEpJ9ZNUkcHwXhNgt1WJJVVzHD7+uDmqzZWVFLdbGme2gvIXKb3ezDYOXcZA==", + "license": "MIT", + "dependencies": { + "jalaali-js": "^1.2.7", + "moment": "^2.29.4", + "moment-timezone": "^0.5.46" + } + }, + "node_modules/moment-timezone": { + "version": "0.5.48", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.48.tgz", + "integrity": "sha512-f22b8LV1gbTO2ms2j2z13MuPogNoh5UzxL3nzNAYKGraILnbGc9NEE6dyiiiLv46DGRb8A4kg8UKWLjPthxBHw==", + "license": "MIT", + "dependencies": { + "moment": "^2.29.4" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-releases": { + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", + "dev": true, + "license": "MIT" + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/prop-types/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "license": "MIT" + }, + "node_modules/property-expr": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/property-expr/-/property-expr-2.0.6.tgz", + "integrity": "sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA==", + "license": "MIT" + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "license": "MIT" + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/rc-rate": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/rc-rate/-/rc-rate-2.13.1.tgz", + "integrity": "sha512-QUhQ9ivQ8Gy7mtMZPAjLbxBt5y9GRp65VcUyGUMF3N3fhiftivPHdpuDIaWIMOTEprAjZPC08bls1dQB+I1F2Q==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.5", + "rc-util": "^5.0.1" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-util": { + "version": "5.44.4", + "resolved": "https://registry.npmjs.org/rc-util/-/rc-util-5.44.4.tgz", + "integrity": "sha512-resueRJzmHG9Q6rI/DfK6Kdv9/Lfls05vzMs1Sk3M2P+3cJa+MakaZyWY8IPfehVuhPJFKrIY1IK4GqbiaiY5w==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.18.3", + "react-is": "^18.2.0" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/react": { + "version": "19.1.1", + "resolved": "https://registry.npmjs.org/react/-/react-19.1.1.tgz", + "integrity": "sha512-w8nqGImo45dmMIfljjMwOGtbmC/mk4CMYhWIicdSflH91J9TyCyczcPFXJzrZ/ZXcgGRFeP6BU0BEJTw6tZdfQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-date-object": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/react-date-object/-/react-date-object-2.1.9.tgz", + "integrity": "sha512-BHxD/quWOTo9fLKV/cfL/M31ePoj4a1JaJ/CnOf8Ndg3mrkh4x9wEMMkCfTrzduxDOgU8ZgR8uarhqI5G71sTg==", + "license": "MIT" + }, + "node_modules/react-dom": { + "version": "19.1.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.1.tgz", + "integrity": "sha512-Dlq/5LAZgF0Gaz6yiqZCf6VCcZs1ghAJyrsu84Q/GT0gV+mCxbfmKNoGRKBYMJ8IEdGPqu49YWXD02GCknEDkw==", + "license": "MIT", + "dependencies": { + "scheduler": "^0.26.0" + }, + "peerDependencies": { + "react": "^19.1.1" + } + }, + "node_modules/react-dropzone": { + "version": "14.3.8", + "resolved": "https://registry.npmjs.org/react-dropzone/-/react-dropzone-14.3.8.tgz", + "integrity": "sha512-sBgODnq+lcA4P296DY4wacOZz3JFpD99fp+hb//iBO2HHnyeZU3FwWyXJ6salNpqQdsZrgMrotuko/BdJMV8Ug==", + "license": "MIT", + "dependencies": { + "attr-accept": "^2.2.4", + "file-selector": "^2.1.0", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">= 10.13" + }, + "peerDependencies": { + "react": ">= 16.8 || 18.0.0" + } + }, + "node_modules/react-element-popper": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/react-element-popper/-/react-element-popper-2.1.7.tgz", + "integrity": "sha512-tuM2OxKlW32h+6uFSK6EENHPeZ2OGgOipHfOAl+VLWEv9/j3QkSGbD+ADX3A9uJlmq24i37n28RjJmAbGTfpEg==", + "license": "MIT", + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/react-fast-compare": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-2.0.4.tgz", + "integrity": "sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw==", + "license": "MIT" + }, + "node_modules/react-i18next": { + "version": "15.7.2", + "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-15.7.2.tgz", + "integrity": "sha512-xJxq7ibnhUlMvd82lNC4te1GxGUMoM1A05KKyqoqsBXVZtEvZg/fz/fnVzdlY/hhQ3SpP/79qCocZOtICGhd3g==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.27.6", + "html-parse-stringify": "^3.0.1" + }, + "peerDependencies": { + "i18next": ">= 25.4.1", + "react": ">= 16.8.0", + "typescript": "^5" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + }, + "react-native": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "node_modules/react-infinite-scroll-component": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/react-infinite-scroll-component/-/react-infinite-scroll-component-6.1.1.tgz", + "integrity": "sha512-R8YoOyiNDynSWmfVme5LHslsKrP+/xcRUWR2ies8UgUab9dtyw5ECnMCVPPmnmjjF4MWQmfVdRwRWcWaDgeyMA==", + "license": "MIT", + "dependencies": { + "throttle-debounce": "^2.1.0" + }, + "peerDependencies": { + "react": ">=16.0.0" + } + }, + "node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "license": "MIT" + }, + "node_modules/react-leaflet": { + "version": "5.0.0-rc.2", + "resolved": "https://registry.npmjs.org/react-leaflet/-/react-leaflet-5.0.0-rc.2.tgz", + "integrity": "sha512-1xQGYG9mEIW+nfkQhqgHImwUuB1UDlnzYFSzv6PrBFDBeYrFmv0BbpwpNAFdJg/UQ2yz5UZSL7ZwlUxjwb8MZw==", + "license": "Hippocratic-2.1", + "dependencies": { + "@react-leaflet/core": "^3.0.0-rc.2" + }, + "peerDependencies": { + "leaflet": "^1.9.0", + "react": "^19.0.0", + "react-dom": "^19.0.0" + } + }, + "node_modules/react-loading-skeleton": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/react-loading-skeleton/-/react-loading-skeleton-3.5.0.tgz", + "integrity": "sha512-gxxSyLbrEAdXTKgfbpBEFZCO/P153DnqSCQau2+o6lNy1jgMRr2MmRmOzMmyrwSaSYLRB8g7b0waYPmUjz7IhQ==", + "license": "MIT", + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/react-multi-date-picker": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/react-multi-date-picker/-/react-multi-date-picker-4.5.2.tgz", + "integrity": "sha512-FgWjZB3Z6IA6XpcWiLPk85PwcRUhOiYhKK42o5k672gD/n2I6rzPfQ8bUrldOIiF/Z7FfOCdH7a6FeubzqteLg==", + "license": "MIT", + "dependencies": { + "react-date-object": "^2.1.8", + "react-element-popper": "^2.1.6" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/react-otp-input": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/react-otp-input/-/react-otp-input-3.1.1.tgz", + "integrity": "sha512-bjPavgJ0/Zmf/AYi4onj8FbH93IjeD+e8pWwxIJreDEWsU1ILR5fs8jEJmMGWSBe/yyvPP6X/W6Mk9UkOCkTPw==", + "license": "MIT", + "peerDependencies": { + "react": ">=16.8.6 || ^17.0.0 || ^18.0.0", + "react-dom": ">=16.8.6 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/react-redux": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.2.0.tgz", + "integrity": "sha512-ROY9fvHhwOD9ySfrF0wmvu//bKCQ6AeZZq1nJNtbDC+kk5DuSuNX/n6YWYF/SYy7bSba4D4FSz8DJeKY/S/r+g==", + "license": "MIT", + "dependencies": { + "@types/use-sync-external-store": "^0.0.6", + "use-sync-external-store": "^1.4.0" + }, + "peerDependencies": { + "@types/react": "^18.2.25 || ^19", + "react": "^18.0 || ^19", + "redux": "^5.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "redux": { + "optional": true + } + } + }, + "node_modules/react-refresh": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz", + "integrity": "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-router": { + "version": "7.8.2", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.8.2.tgz", + "integrity": "sha512-7M2fR1JbIZ/jFWqelpvSZx+7vd7UlBTfdZqf6OSdF9g6+sfdqJDAWcak6ervbHph200ePlu+7G8LdoiC3ReyAQ==", + "license": "MIT", + "dependencies": { + "cookie": "^1.0.1", + "set-cookie-parser": "^2.6.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + } + } + }, + "node_modules/react-router-dom": { + "version": "7.8.2", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.8.2.tgz", + "integrity": "sha512-Z4VM5mKDipal2jQ385H6UBhiiEDlnJPx6jyWsTYoZQdl5TrjxEV2a9yl3Fi60NBJxYzOTGTTHXPi0pdizvTwow==", + "license": "MIT", + "dependencies": { + "react-router": "7.8.2" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + } + }, + "node_modules/react-spinners": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/react-spinners/-/react-spinners-0.17.0.tgz", + "integrity": "sha512-L/8HTylaBmIWwQzIjMq+0vyaRXuoAevzWoD35wKpNTxxtYXWZp+xtgkfD7Y4WItuX0YvdxMPU79+7VhhmbmuTQ==", + "license": "MIT", + "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" + } + }, + "node_modules/react-toastify": { + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-11.0.5.tgz", + "integrity": "sha512-EpqHBGvnSTtHYhCPLxML05NLY2ZX0JURbAdNYa6BUkk+amz4wbKBQvoKQAB0ardvSarUBuY4Q4s1sluAzZwkmA==", + "license": "MIT", + "dependencies": { + "clsx": "^2.1.1" + }, + "peerDependencies": { + "react": "^18 || ^19", + "react-dom": "^18 || ^19" + } + }, + "node_modules/recharts": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/recharts/-/recharts-3.6.0.tgz", + "integrity": "sha512-L5bjxvQRAe26RlToBAziKUB7whaGKEwD3znoM6fz3DrTowCIC/FnJYnuq1GEzB8Zv2kdTfaxQfi5GoH0tBinyg==", + "license": "MIT", + "workspaces": [ + "www" + ], + "dependencies": { + "@reduxjs/toolkit": "1.x.x || 2.x.x", + "clsx": "^2.1.1", + "decimal.js-light": "^2.5.1", + "es-toolkit": "^1.39.3", + "eventemitter3": "^5.0.1", + "immer": "^10.1.1", + "react-redux": "8.x.x || 9.x.x", + "reselect": "5.1.1", + "tiny-invariant": "^1.3.3", + "use-sync-external-store": "^1.2.2", + "victory-vendor": "^37.0.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "react": "^16.8.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-is": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/redux": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz", + "integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==", + "license": "MIT" + }, + "node_modules/redux-thunk": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-3.1.0.tgz", + "integrity": "sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw==", + "license": "MIT", + "peerDependencies": { + "redux": "^5.0.0" + } + }, + "node_modules/reselect": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-5.1.1.tgz", + "integrity": "sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==", + "license": "MIT" + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rollup": { + "version": "4.48.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.48.1.tgz", + "integrity": "sha512-jVG20NvbhTYDkGAty2/Yh7HK6/q3DGSRH4o8ALKGArmMuaauM9kLfoMZ+WliPwA5+JHr2lTn3g557FxBV87ifg==", + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.48.1", + "@rollup/rollup-android-arm64": "4.48.1", + "@rollup/rollup-darwin-arm64": "4.48.1", + "@rollup/rollup-darwin-x64": "4.48.1", + "@rollup/rollup-freebsd-arm64": "4.48.1", + "@rollup/rollup-freebsd-x64": "4.48.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.48.1", + "@rollup/rollup-linux-arm-musleabihf": "4.48.1", + "@rollup/rollup-linux-arm64-gnu": "4.48.1", + "@rollup/rollup-linux-arm64-musl": "4.48.1", + "@rollup/rollup-linux-loongarch64-gnu": "4.48.1", + "@rollup/rollup-linux-ppc64-gnu": "4.48.1", + "@rollup/rollup-linux-riscv64-gnu": "4.48.1", + "@rollup/rollup-linux-riscv64-musl": "4.48.1", + "@rollup/rollup-linux-s390x-gnu": "4.48.1", + "@rollup/rollup-linux-x64-gnu": "4.48.1", + "@rollup/rollup-linux-x64-musl": "4.48.1", + "@rollup/rollup-win32-arm64-msvc": "4.48.1", + "@rollup/rollup-win32-ia32-msvc": "4.48.1", + "@rollup/rollup-win32-x64-msvc": "4.48.1", + "fsevents": "~2.3.2" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/scheduler": { + "version": "0.26.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz", + "integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==", + "license": "MIT" + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/set-cookie-parser": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz", + "integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==", + "license": "MIT" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/socket.io-client": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.8.1.tgz", + "integrity": "sha512-hJVXfu3E28NmzGk8o1sHhN3om52tRvwYeidbj7xKy2eIIse5IoKX3USlS6Tqt3BHAtflLIkCQBkzVrEEfWUyYQ==", + "license": "MIT", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.2", + "engine.io-client": "~6.6.1", + "socket.io-parser": "~4.2.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/socket.io-client/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/socket.io-parser": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz", + "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==", + "license": "MIT", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/socket.io-parser/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/swiper": { + "version": "11.2.10", + "resolved": "https://registry.npmjs.org/swiper/-/swiper-11.2.10.tgz", + "integrity": "sha512-RMeVUUjTQH+6N3ckimK93oxz6Sn5la4aDlgPzB+rBrG/smPdCTicXyhxa+woIpopz+jewEloiEE3lKo1h9w2YQ==", + "funding": [ + { + "type": "patreon", + "url": "https://www.patreon.com/swiperjs" + }, + { + "type": "open_collective", + "url": "http://opencollective.com/swiper" + } + ], + "license": "MIT", + "engines": { + "node": ">= 4.7.0" + } + }, + "node_modules/tabbable": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz", + "integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==", + "license": "MIT" + }, + "node_modules/tailwind-merge": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.3.1.tgz", + "integrity": "sha512-gBXpgUm/3rp1lMZZrM/w7D8GKqshif0zAymAhbCyIt8KMe+0v9DQ7cdYLR4FHH/cKpdTXb+A/tKKU3eolfsI+g==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/dcastil" + } + }, + "node_modules/tailwindcss": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.12.tgz", + "integrity": "sha512-DzFtxOi+7NsFf7DBtI3BJsynR+0Yp6etH+nRPTbpWnS2pZBaSksv/JGctNwSWzbFjp0vxSqknaUylseZqMDGrA==", + "license": "MIT" + }, + "node_modules/tapable": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.3.tgz", + "integrity": "sha512-ZL6DDuAlRlLGghwcfmSn9sK3Hr6ArtyudlSAiCqQ6IfE+b+HHbydbYDIG15IfS5do+7XQQBdBiubF/cV2dnDzg==", + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/tar": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz", + "integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==", + "license": "ISC", + "dependencies": { + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.0.1", + "mkdirp": "^3.0.1", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/tar/node_modules/yallist": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/throttle-debounce": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-2.3.0.tgz", + "integrity": "sha512-H7oLPV0P7+jgvrk+6mwwwBDmxTaxnu9HMXmloNLXwnNO0ZxZ31Orah2n8lU1eMPvsaowP2CX+USCgyovXfdOFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/tiny-case": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-case/-/tiny-case-1.0.3.tgz", + "integrity": "sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q==", + "license": "MIT" + }, + "node_modules/tiny-invariant": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", + "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==", + "license": "MIT" + }, + "node_modules/tiny-warning": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", + "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==", + "license": "MIT" + }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toposort": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/toposort/-/toposort-2.0.2.tgz", + "integrity": "sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==", + "license": "MIT" + }, + "node_modules/ts-api-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", + "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", + "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typescript": { + "version": "5.8.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", + "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", + "devOptional": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/typescript-eslint": { + "version": "8.41.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.41.0.tgz", + "integrity": "sha512-n66rzs5OBXW3SFSnZHr2T685q1i4ODm2nulFJhMZBotaTavsS8TrI3d7bDlRSs9yWo7HmyWrN9qDu14Qv7Y0Dw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/eslint-plugin": "8.41.0", + "@typescript-eslint/parser": "8.41.0", + "@typescript-eslint/typescript-estree": "8.41.0", + "@typescript-eslint/utils": "8.41.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/undici-types": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", + "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/update-browserslist-db": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", + "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/use-sync-external-store": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.5.0.tgz", + "integrity": "sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/victory-vendor": { + "version": "37.3.6", + "resolved": "https://registry.npmjs.org/victory-vendor/-/victory-vendor-37.3.6.tgz", + "integrity": "sha512-SbPDPdDBYp+5MJHhBCAyI7wKM3d5ivekigc2Dk2s7pgbZ9wIgIBYGVw4zGHBml/qTFbexrofXW6Gu4noGxrOwQ==", + "license": "MIT AND ISC", + "dependencies": { + "@types/d3-array": "^3.0.3", + "@types/d3-ease": "^3.0.0", + "@types/d3-interpolate": "^3.0.1", + "@types/d3-scale": "^4.0.2", + "@types/d3-shape": "^3.1.0", + "@types/d3-time": "^3.0.0", + "@types/d3-timer": "^3.0.0", + "d3-array": "^3.1.6", + "d3-ease": "^3.0.1", + "d3-interpolate": "^3.0.1", + "d3-scale": "^4.0.2", + "d3-shape": "^3.1.0", + "d3-time": "^3.0.0", + "d3-timer": "^3.0.1" + } + }, + "node_modules/vite": { + "version": "7.1.12", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.1.12.tgz", + "integrity": "sha512-ZWyE8YXEXqJrrSLvYgrRP7p62OziLW7xI5HYGWFzOvupfAlrLvURSzv/FyGyy0eidogEM3ujU+kUG1zuHgb6Ug==", + "license": "MIT", + "dependencies": { + "esbuild": "^0.25.0", + "fdir": "^6.5.0", + "picomatch": "^4.0.3", + "postcss": "^8.5.6", + "rollup": "^4.43.0", + "tinyglobby": "^0.2.15" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "lightningcss": "^1.21.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vite/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/vite/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/void-elements": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", + "integrity": "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ws": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xmlhttprequest-ssl": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.1.2.tgz", + "integrity": "sha512-TEU+nJVUUnA4CYJFLvK5X9AOeH4KvDvhIfm0vV1GaQRtchnG0hgK5p8hw/xjv8cunWYCsiPCSDzObPyhEwq3KQ==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yup": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/yup/-/yup-1.7.0.tgz", + "integrity": "sha512-VJce62dBd+JQvoc+fCVq+KZfPHr+hXaxCcVgotfwWvlR0Ja3ffYKaJBT8rptPOSKOGJDCUnW2C2JWpud7aRP6Q==", + "license": "MIT", + "dependencies": { + "property-expr": "^2.0.5", + "tiny-case": "^1.0.3", + "toposort": "^2.0.2", + "type-fest": "^2.19.0" + } + }, + "node_modules/zustand": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.8.tgz", + "integrity": "sha512-gyPKpIaxY9XcO2vSMrLbiER7QMAMGOQZVRdJ6Zi782jkbzZygq5GI9nG8g+sMgitRtndwaBSl7uiqC49o1SSiw==", + "license": "MIT", + "engines": { + "node": ">=12.20.0" + }, + "peerDependencies": { + "@types/react": ">=18.0.0", + "immer": ">=9.0.6", + "react": ">=18.0.0", + "use-sync-external-store": ">=1.2.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "immer": { + "optional": true + }, + "react": { + "optional": true + }, + "use-sync-external-store": { + "optional": true + } + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..feed5a3 --- /dev/null +++ b/package.json @@ -0,0 +1,64 @@ +{ + "name": "dmenu-admin", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "tsc -b && vite build", + "lint": "eslint .", + "preview": "vite preview" + }, + "dependencies": { + "@headlessui/react": "^2.2.7", + "@radix-ui/react-checkbox": "^1.3.3", + "@radix-ui/react-icons": "^1.3.2", + "@tailwindcss/vite": "^4.1.12", + "@tanstack/react-query": "^5.85.5", + "axios": "^1.11.0", + "clsx": "^2.1.1", + "formik": "^2.4.6", + "i18next": "^25.4.2", + "iconsax-react": "^0.0.8", + "leaflet": "^1.9.4", + "moment-jalaali": "^0.10.4", + "rc-rate": "^2.13.1", + "react": "^19.1.1", + "react-dom": "^19.1.1", + "react-dropzone": "^14.3.8", + "react-i18next": "^15.7.2", + "react-infinite-scroll-component": "^6.1.1", + "react-leaflet": "^5.0.0-rc.2", + "react-loading-skeleton": "^3.5.0", + "react-multi-date-picker": "^4.5.2", + "react-otp-input": "^3.1.1", + "react-router-dom": "^7.8.2", + "react-spinners": "^0.17.0", + "react-toastify": "^11.0.5", + "recharts": "^3.6.0", + "socket.io-client": "^4.8.1", + "swiper": "^11.2.10", + "tailwind-merge": "^3.3.1", + "yup": "^1.7.0", + "zustand": "^5.0.8" + }, + "devDependencies": { + "@eslint/js": "^9.33.0", + "@types/leaflet": "^1.9.21", + "@types/moment-jalaali": "^0.7.9", + "@types/node": "^24.10.1", + "@types/react": "^19.1.10", + "@types/react-dom": "^19.1.7", + "@vitejs/plugin-react": "^5.0.0", + "autoprefixer": "^10.4.21", + "eslint": "^9.33.0", + "eslint-plugin-react-hooks": "^5.2.0", + "eslint-plugin-react-refresh": "^0.4.20", + "globals": "^16.3.0", + "postcss": "^8.5.6", + "tailwindcss": "^4.1.12", + "typescript": "~5.8.3", + "typescript-eslint": "^8.39.1", + "vite": "^7.1.2" + } +} diff --git a/public/favicon.svg b/public/favicon.svg new file mode 100644 index 0000000..f4ed6b7 --- /dev/null +++ b/public/favicon.svg @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/public/mixkit-correct-answer-tone-2870.wav b/public/mixkit-correct-answer-tone-2870.wav new file mode 100644 index 0000000..88a18e1 Binary files /dev/null and b/public/mixkit-correct-answer-tone-2870.wav differ diff --git a/public/robots.txt b/public/robots.txt new file mode 100644 index 0000000..6ffbc30 --- /dev/null +++ b/public/robots.txt @@ -0,0 +1,3 @@ +User-agent: * +Disallow: / + 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..5367b8f --- /dev/null +++ b/src/App.tsx @@ -0,0 +1,201 @@ +import { type FC, useEffect, useState } from 'react' +import { BrowserRouter } from 'react-router-dom' +import 'swiper/swiper-bundle.css'; +// import 'rc-rate/assets/index.css'; +import "react-multi-date-picker/styles/layouts/mobile.css" +import 'leaflet/dist/leaflet.css'; +import './assets/fonts/irancell/style.css' +import i18next from 'i18next' +import { I18nextProvider } from 'react-i18next' +import { QueryCache, QueryClient, QueryClientProvider } from '@tanstack/react-query' +import { ToastContainer } from 'react-toastify' +import FaJson from './langs/fa.json' +import { type IApiErrorRepsonse } from './types/error.types' +import MainRouter from './router/Main' +import AuthRouter from './router/Auth' +import { Pages } from './config/Pages' +import { getRefreshToken, setToken, setRefreshToken, removeToken, removeRefreshToken, getToken } from './config/func'; +import { refreshToken } from './pages/auth/service/AuthService'; + +i18next.init({ + interpolation: { escapeValue: false }, + lng: 'fa', + resources: { + fa: { + global: FaJson + } + } +}) + +declare global { + interface Window { + isRefreshingToken?: boolean; + isRefreshTokenExpired?: boolean; + } +} + +const queryClient = new QueryClient({ + queryCache: new QueryCache({ + onError: async (error: IApiErrorRepsonse) => { + if (error?.response?.status === 401) { + // اگر refresh token منقضی شده باشد، دیگر تلاش نکن + if (window.isRefreshTokenExpired) { + return; + } + + // بررسی کن که آیا خطا از refresh endpoint است + const isRefreshEndpoint = error?.config?.url?.includes('/admin/auth/refresh'); + + // اگر خطا از refresh endpoint است، refresh token منقضی شده + if (isRefreshEndpoint) { + window.isRefreshTokenExpired = true; + await removeToken(); + await removeRefreshToken(); + window.location.href = Pages.auth.login; + return; + } + + 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(); + + if (!refreshTokenValue) { + window.isRefreshTokenExpired = true; + await removeToken(); + await removeRefreshToken(); + window.location.href = Pages.auth.login; + return; + } + + 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); + } + + // Reset expired flag if refresh was successful + window.isRefreshTokenExpired = false; + + // 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); + + // بررسی کن که آیا خطا از refresh endpoint است + const errorWithConfig = refreshError as IApiErrorRepsonse; + const isRefreshError = errorWithConfig?.config?.url?.includes('/admin/auth/refresh'); + + // اگر refresh token خودش 401 خورده، آن را منقضی شده علامت بزن + if (isRefreshError || errorWithConfig?.response?.status === 401) { + window.isRefreshTokenExpired = true; + } + + // Clear tokens and redirect to login + await removeToken(); + await removeRefreshToken(); + window.location.href = Pages.auth.login; + } + } + } + }), + defaultOptions: { + queries: { + refetchOnWindowFocus: false, + retry: false + // staleTime: 86400000 // 1 day in milliseconds + } + } +}); + +const App: FC = () => { + + const [isLogin, setIsLogin] = useState<'checking' | 'isLogin' | 'isNotLogin'>('checking') + + useEffect(() => { + // استخراج توکن‌ها از URL در صورت وجود + const urlParams = new URLSearchParams(window.location.search) + const tokenFromUrl = urlParams.get('token') + const refreshTokenFromUrl = urlParams.get('refreshToken') + + if (tokenFromUrl && refreshTokenFromUrl) { + // ذخیره توکن‌ها (جایگزین کردن توکن‌های قبلی اگر وجود داشته باشند) + setToken(tokenFromUrl) + setRefreshToken(refreshTokenFromUrl) + + // حذف پارامترها از URL + const newUrl = window.location.pathname + window.history.replaceState({}, '', newUrl) + + // تنظیم وضعیت لاگین و هدایت به صفحه اصلی + setIsLogin('isLogin') + if (window.location.pathname === Pages.auth.login) { + window.location.href = Pages.dashboard + } + return + } + + const token = getToken() + if (token) { + setIsLogin('isLogin') + } else { + setIsLogin('isNotLogin') + if (window.location.href.split('auth').length === 1) { + window.location.href = Pages.auth.login + } + } + + }, []) + + + + + return ( + + + + { + isLogin === 'checking' ? +
loading
+ : + isLogin === 'isLogin' ? + + : + + } + +
+
+
+ ) +} + +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/Avatar.png b/src/assets/images/Avatar.png new file mode 100644 index 0000000..42269de Binary files /dev/null and b/src/assets/images/Avatar.png differ diff --git a/src/assets/images/accessbility.jpg b/src/assets/images/accessbility.jpg new file mode 100644 index 0000000..4447c18 Binary files /dev/null and b/src/assets/images/accessbility.jpg differ diff --git a/src/assets/images/appimage.png b/src/assets/images/appimage.png new file mode 100644 index 0000000..6495d79 Binary files /dev/null and b/src/assets/images/appimage.png differ diff --git a/src/assets/images/arrow-left.svg b/src/assets/images/arrow-left.svg new file mode 100644 index 0000000..b848f88 --- /dev/null +++ b/src/assets/images/arrow-left.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/assets/images/avatar_image.png b/src/assets/images/avatar_image.png new file mode 100644 index 0000000..96000aa Binary files /dev/null and b/src/assets/images/avatar_image.png differ diff --git a/src/assets/images/banner.png b/src/assets/images/banner.png new file mode 100644 index 0000000..e259ce2 Binary files /dev/null and b/src/assets/images/banner.png differ diff --git a/src/assets/images/banner2.jpeg b/src/assets/images/banner2.jpeg new file mode 100644 index 0000000..422be2d Binary files /dev/null and b/src/assets/images/banner2.jpeg differ diff --git a/src/assets/images/calendar.svg b/src/assets/images/calendar.svg new file mode 100644 index 0000000..63391d1 --- /dev/null +++ b/src/assets/images/calendar.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/src/assets/images/close-circle.svg b/src/assets/images/close-circle.svg new file mode 100644 index 0000000..8238cd0 --- /dev/null +++ b/src/assets/images/close-circle.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/assets/images/color.png b/src/assets/images/color.png new file mode 100644 index 0000000..f6bc357 Binary files /dev/null and b/src/assets/images/color.png differ diff --git a/src/assets/images/eye.svg b/src/assets/images/eye.svg new file mode 100644 index 0000000..de3cfe0 --- /dev/null +++ b/src/assets/images/eye.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/assets/images/learning.png b/src/assets/images/learning.png new file mode 100644 index 0000000..2d22284 Binary files /dev/null and b/src/assets/images/learning.png differ diff --git a/src/assets/images/logo-small.png b/src/assets/images/logo-small.png new file mode 100644 index 0000000..e761aad Binary files /dev/null and b/src/assets/images/logo-small.png differ diff --git a/src/assets/images/logo.png b/src/assets/images/logo.png new file mode 100644 index 0000000..97e71fd Binary files /dev/null and b/src/assets/images/logo.png differ diff --git a/src/assets/images/logo_orig.svg b/src/assets/images/logo_orig.svg new file mode 100644 index 0000000..a764edd --- /dev/null +++ b/src/assets/images/logo_orig.svg @@ -0,0 +1,45 @@ + \ No newline at end of file diff --git a/src/assets/images/robot.jpeg b/src/assets/images/robot.jpeg new file mode 100644 index 0000000..83e987b Binary files /dev/null and b/src/assets/images/robot.jpeg differ diff --git a/src/assets/images/saman.png b/src/assets/images/saman.png new file mode 100644 index 0000000..42e72b1 Binary files /dev/null and b/src/assets/images/saman.png differ diff --git a/src/assets/images/share.svg b/src/assets/images/share.svg new file mode 100644 index 0000000..b5618e5 --- /dev/null +++ b/src/assets/images/share.svg @@ -0,0 +1,3 @@ + + + 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..386e153 --- /dev/null +++ b/src/components/Button.tsx @@ -0,0 +1,33 @@ +import { type ButtonHTMLAttributes, type FC, memo, type ReactNode } from 'react' +import MoonLoader from "react-spinners/MoonLoader" +import { type XOR } from '../helpers/types' +import { clx } from '../helpers/utils' + +type Props = { + className?: string; + isloading?: boolean, + colorLoading?: string, +} & ButtonHTMLAttributes & + XOR<{ children: ReactNode }, { label: string }>; + +const Button: FC = memo((props: Props) => { + + const buttonClass = clx( + 'flex rounded-xl items-center justify-center text-center h-10 text-sm bg-primary text-white w-full', + props.disabled && 'cursor-not-allowed opacity-60', + 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..18def66 --- /dev/null +++ b/src/components/ColorPicker.tsx @@ -0,0 +1,102 @@ +import { type FC, type InputHTMLAttributes, useState, useRef, useEffect } from 'react' +import { clx } from '../helpers/utils' +import Error from './Error' +import ColorfilterIcon from '@/assets/images/color.png' + +type Props = { + label?: string + className?: string + error_text?: string + isNotRequired?: boolean + value?: string + onChange?: (value: string) => void +} & Omit, 'onChange' | 'value'> + +const ColorPicker: FC = (props: Props) => { + const [color, setColor] = useState(props.value || '#000000') + const colorInputRef = useRef(null) + + const inputClass = clx( + 'w-full bg-white h-10 text-black block pl-10 pr-10 text-xs rounded-xl border border-border', + props.readOnly && 'bg-gray-100 border-0 text-description', + props.className + ) + + const handleColorChange = (event: React.ChangeEvent) => { + const newColor = event.target.value + setColor(newColor) + props.onChange?.(newColor) + } + + const handleTextChange = (event: React.ChangeEvent) => { + const value = event.target.value + if (/^#[0-9A-Fa-f]{0,6}$/.test(value) || value === '') { + const finalColor = value || '#000000' + setColor(finalColor) + props.onChange?.(finalColor) + } + } + + const handleColorIconClick = () => { + if (!props.readOnly) { + colorInputRef.current?.click() + } + } + + useEffect(() => { + if (props.value !== undefined) { + setColor(props.value) + } + }, [props.value]) + + return ( +
+ + +
+ + + + +
+ + + + {props.error_text && ( + + )} +
+
+ ) +} + +export default ColorPicker + diff --git a/src/components/CustomerStats.tsx b/src/components/CustomerStats.tsx new file mode 100644 index 0000000..a4ec6de --- /dev/null +++ b/src/components/CustomerStats.tsx @@ -0,0 +1,41 @@ +import { EmptyWallet, Star1 } from 'iconsax-react' +import { type FC } from 'react' + +interface CustomerStatsProps { + points?: number | string + walletBalance?: string +} + +const CustomerStats: FC = ({ + points = '124', + walletBalance = '۲۴۰.۰۰۰ تومان' +}) => { + return ( +
+
+
+ +
امتیاز
+
+ +
+ +
{points} امتیاز
+
+ +
+
+ +
موجودی کیف پول
+
+ +
+ +
{walletBalance}
+
+
+ ) +} + +export default CustomerStats + diff --git a/src/components/DatePicker.tsx b/src/components/DatePicker.tsx new file mode 100644 index 0000000..6c10758 --- /dev/null +++ b/src/components/DatePicker.tsx @@ -0,0 +1,116 @@ +import { useState, useEffect, useRef, type 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 CalenderIcon from '../assets/images/calendar.svg' +import { clx } from '../helpers/utils'; + +type Props = { + onChange: (date: string) => void; + defaulValue?: string; + error_text?: string; + placeholder: string; + reset?: boolean; + isDateTime?: boolean; + className?: string; + label?: string +}; + +const DatePickerComponent: FC = (props: Props) => { + const [value, setValue] = useState(null); + const isSettingDefaultValue = useRef(false); + const isInitialized = useRef(false); + + useEffect(() => { + if (props.reset) { + setValue(null); + } + }, [props.reset]); + + useEffect(() => { + // فقط وقتی کاربر تاریخ رو تغییر داده onChange رو صدا بزن + if (isSettingDefaultValue.current) { + isSettingDefaultValue.current = false; + return; + } + + // اگر هنوز initialize نشده و value null هست، onChange رو صدا نزن + if (!isInitialized.current && !value) { + return; + } + + isInitialized.current = true; + + if (value) { + // تبدیل تاریخ شمسی به میلادی + const gregorianDate = value.toDate(); + const year = gregorianDate.getFullYear(); + const month = String(gregorianDate.getMonth() + 1).padStart(2, '0'); + const day = String(gregorianDate.getDate()).padStart(2, '0'); + const formattedDate = `${year}-${month}-${day}`; + props.onChange(formattedDate); + } else { + props.onChange(''); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [value]); + + useEffect(() => { + if (props.defaulValue) { + try { + const defaultDate = new DateObject({ + date: props.defaulValue, + calendar: persian, + locale: persian_fa, + }); + + const currentValueStr = value ? `${value.year}-${value.month.number}-${value.day}` : null; + const defaultValueStr = `${defaultDate.year}-${defaultDate.month.number}-${defaultDate.day}`; + + if (currentValueStr !== defaultValueStr) { + isSettingDefaultValue.current = true; + setValue(defaultDate); + } + } catch (error) { + console.error('Error parsing date:', error); + } + } else if (!props.defaulValue && value) { + isSettingDefaultValue.current = true; + setValue(null); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [props.defaulValue]); + + return ( +
+ {props.label && +
+ {props.label} +
} +
+ setValue(date as DateObject)} + calendar={persian} + locale={persian_fa} + calendarPosition="bottom-right" + className={`rmdp-mobile ${props.className}`} + /> + {props.error_text && props.error_text !== '' && ( +
+ {props.error_text} +
+ )} + + +
+
+ ); +}; + +export default DatePickerComponent; \ No newline at end of file diff --git a/src/components/DefaulModal.tsx b/src/components/DefaulModal.tsx new file mode 100644 index 0000000..0c00d88 --- /dev/null +++ b/src/components/DefaulModal.tsx @@ -0,0 +1,62 @@ +import { type FC, Fragment, type ReactNode, useEffect } from 'react' +import { createPortal } from 'react-dom' +import HeaderModal from './HeaderModal' + +interface Props { + open: boolean, + close: () => void, + children: ReactNode, + isHeader?: boolean, + title_header?: string, + width?: number +} + +const DefaulModal: FC = (props: Props) => { + + useEffect(() => { + if (props.open) { + document.body.style.overflow = 'hidden' + } else { + document.body.style.overflow = 'auto' + } + }, [props.open]) + + + const modalContent = props.open ? ( + +
+
+
e.stopPropagation()} + > +
+ + + { + props.isHeader && props.title_header && +
+
+ +
+ } + + {props.children} + + +
+
+
+ + ) : null + + return createPortal(modalContent, document.body) +} + +export default DefaulModal \ No newline at end of file diff --git a/src/components/DefaultTableSkeleton.tsx b/src/components/DefaultTableSkeleton.tsx new file mode 100644 index 0000000..962d9dc --- /dev/null +++ b/src/components/DefaultTableSkeleton.tsx @@ -0,0 +1,29 @@ +import { type FC, Fragment } from 'react' +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..dc6aeac --- /dev/null +++ b/src/components/Error.tsx @@ -0,0 +1,15 @@ +import { type 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..e1381ab --- /dev/null +++ b/src/components/Filters.tsx @@ -0,0 +1,272 @@ +import { type FC, useEffect, useState, type ChangeEvent, useRef } from 'react'; +import { Filter } from 'iconsax-react'; +import DatePicker from './DatePicker'; +import Input from './Input'; +import Select, { type ItemsSelectType } from './Select'; +import MultiSelect from './MultiSelect'; +import DefaulModal from './DefaulModal'; +import moment from 'moment-jalaali' +import Button from './Button'; + +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 MultiSelectFieldType = { + type: 'multiselect'; + name: string; + placeholder: string; + options: ItemsSelectType[]; + defaultValue?: string[]; +}; + +export type InputFieldType = { + type: 'input'; + name: string; + placeholder: string; + defaultValue?: string; +}; + +export type FieldType = DateFieldType | SelectFieldType | MultiSelectFieldType | 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 = "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" +}) => { + const [filters, setFilters] = useState({}); + const [isFiltersOpen, setIsFiltersOpen] = useState(false); + const [inputValues, setInputValues] = useState>({}); + const [multiSelectValues, setMultiSelectValues] = useState>({}); + const onChangeRef = useRef(onChange); + + useEffect(() => { + onChangeRef.current = onChange; + }, [onChange]); + + useEffect(() => { + if (Object.keys(initialValues).length > 0) { + setFilters(initialValues); + const inputFields: Record = {}; + const multiSelectFields: Record = {}; + fields.forEach(field => { + if (field.type === 'input' && initialValues[field.name]) { + inputFields[field.name] = initialValues[field.name] as string; + } + if (field.type === 'multiselect' && initialValues[field.name]) { + multiSelectFields[field.name] = Array.isArray(initialValues[field.name]) + ? (initialValues[field.name] as string[]) + : []; + } + }); + setInputValues(inputFields); + setMultiSelectValues(multiSelectFields); + } else { + const defaultValues: FilterValues = {}; + const defaultInputs: Record = {}; + const defaultMultiSelects: Record = {}; + fields.forEach(field => { + if ('defaultValue' in field && field.defaultValue !== undefined) { + if (field.type === 'multiselect') { + defaultValues[field.name] = field.defaultValue as string[]; + defaultMultiSelects[field.name] = field.defaultValue as string[]; + } else { + defaultValues[field.name] = field.defaultValue; + if (field.type === 'input') { + defaultInputs[field.name] = field.defaultValue; + } + } + } + }); + + if (Object.keys(defaultValues).length > 0) { + setFilters(defaultValues); + setInputValues(defaultInputs); + setMultiSelectValues(defaultMultiSelects); + onChange(defaultValues); + } + } + }, [fields, initialValues, onChange]); + + useEffect(() => { + const timeouts: Record> = {}; + + Object.keys(inputValues).forEach(fieldName => { + timeouts[fieldName] = setTimeout(() => { + setFilters(currentFilters => { + const currentFilter = currentFilters[fieldName]; + const newValue = inputValues[fieldName]; + + if (currentFilter !== newValue) { + const newFilters = { ...currentFilters, [fieldName]: newValue || null }; + onChangeRef.current(newFilters); + return newFilters; + } + return currentFilters; + }); + }, 1000); + }); + + return () => { + Object.values(timeouts).forEach(timeout => clearTimeout(timeout)); + }; + }, [inputValues]); + + const handleChange = (name: string, value: string | null) => { + const newFilters = { ...filters, [name]: value }; + setFilters(newFilters); + onChange(newFilters); + }; + + const handleMultiSelectChange = (name: string, values: string[]) => { + const newFilters = { ...filters, [name]: values.length > 0 ? values : null }; + setFilters(newFilters); + setMultiSelectValues(prev => ({ ...prev, [name]: values })); + onChange(newFilters); + }; + + const handleInputChange = (name: string, event: ChangeEvent) => { + const value = event.target.value; + setInputValues(prev => ({ ...prev, [name]: value })); + }; + + const renderField = (field: FieldType) => { + const currentValue = field.type === 'input' ? inputValues[field.name] : filters[field.name]; + const currentMultiSelectValue = field.type === 'multiselect' + ? (multiSelectValues[field.name] || (field.defaultValue as string[]) || []) + : undefined; + + switch (field.type) { + case 'date': + return ( + handleChange(field.name, moment(value, 'jYYYY/jMM/jDD').format('YYYY-MM-DD'))} + defaulValue={currentValue as string || 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)} +
+ )} +
+ +
+
+ {fields.map(renderField)} +
+
+ + setIsFiltersOpen(false)} + isHeader={true} + title_header="فیلتر کردن نتایج" + > +
+ {otherFields.map(field => ( +
+ +
+ {renderField(field)} +
+
+ ))} +
+
+
+
+
+ ); +}; + +export default Filters; \ No newline at end of file diff --git a/src/components/HeaderModal.tsx b/src/components/HeaderModal.tsx new file mode 100644 index 0000000..08b56c0 --- /dev/null +++ b/src/components/HeaderModal.tsx @@ -0,0 +1,21 @@ +import { type FC } from 'react' +import XIcon from '../assets/images/close-circle.svg' + + +type Props = { + label: string, + close: () => void, +} + +const HeaderModal: FC = (props: Props) => { + return ( +
+
{props.label}
+
+ close +
+
+ ) +} + +export default HeaderModal \ No newline at end of file diff --git a/src/components/Input.tsx b/src/components/Input.tsx new file mode 100644 index 0000000..8dd6e96 --- /dev/null +++ b/src/components/Input.tsx @@ -0,0 +1,118 @@ +import { type FC, type InputHTMLAttributes, useEffect, useState } from 'react' +import { clx } from '../helpers/utils'; +import EyeIcon from '../assets/images/eye.svg' +import { 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; +} & 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' && 'border-0 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` والد + const syntheticEvent = { + ...event, + target: { + ...event.target, + name: event.target.name, + value: inputValue, + }, + } as React.ChangeEvent; + + props.onChange?.(syntheticEvent); + } 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)} src={EyeIcon} className='w-5 absolute top-0 bottom-0 cursor-pointer my-auto left-3' /> + } + + { + props.variant === 'search' && + + } + + { + props.error_text && + + } +
+
+ ) +} + +export default Input \ No newline at end of file diff --git a/src/components/ModalConfrim.tsx b/src/components/ModalConfrim.tsx new file mode 100644 index 0000000..8d690a5 --- /dev/null +++ b/src/components/ModalConfrim.tsx @@ -0,0 +1,67 @@ +import { type FC, useState } from 'react' +import DefaulModal from './DefaulModal' +import { useTranslation } from 'react-i18next' +import Button from './Button' +import Textarea from './Textarea' + +type Props = { + isloading?: boolean, + close: () => void, + isOpen: boolean, + onConfrim: (text?: string) => void, + label?: string, + isHasDescription?: boolean +} + +const ModalConfrim: FC = (props: Props) => { + + const { t } = useTranslation('global') + const [description, setDescription] = useState('') + + return ( + +
+
+ { + props.label ? + props.label + : + t('confrim.content') + } + + { + props.isHasDescription && +
+ + + { + props.error_text && + + } + +
+ ) +} + +export default Textarea \ No newline at end of file diff --git a/src/components/TimePicker.tsx b/src/components/TimePicker.tsx new file mode 100644 index 0000000..dd0b8b3 --- /dev/null +++ b/src/components/TimePicker.tsx @@ -0,0 +1,91 @@ +import { useState, useRef, useEffect, type FC } from 'react'; +import { clx, formatTimeToHHmm } from '../helpers/utils'; +import { Clock } from 'iconsax-react'; +import Error from './Error'; + +type Props = { + onChange: (time: string) => void; + defaultValue?: string; + error_text?: string; + placeholder?: string; + className?: string; + label?: string; +}; + +const TimePickerComponent: FC = (props: Props) => { + const [inputValue, setInputValue] = useState(''); + const inputRef = useRef(null); + + useEffect(() => { + if (props.defaultValue) { + const timeValue = formatTimeToHHmm(props.defaultValue.replace('.', ':')); + setInputValue(timeValue); + } + }, [props.defaultValue]); + + const handleChange = (e: React.ChangeEvent) => { + const timeValue = e.target.value; // فرمت: HH:mm + setInputValue(timeValue); + + if (timeValue) { + // فرمت HH:mm را مستقیماً ارسال می‌کنیم + props.onChange(timeValue); + } else { + props.onChange(''); + } + }; + + const handleWrapperClick = () => { + inputRef.current?.showPicker?.(); + inputRef.current?.focus(); + inputRef.current?.click(); + }; + + return ( +
+ {props.label && ( +
+ {props.label} +
+ )} +
+
+ + {!inputValue && ( + + {props.placeholder || 'انتخاب زمان'} + + )} + {inputValue && ( + + {inputValue} + + )} + +
+ {props.error_text && props.error_text !== '' && ( + + )} +
+
+ ); +}; + +export default TimePickerComponent; + diff --git a/src/components/TitleLine.tsx b/src/components/TitleLine.tsx new file mode 100644 index 0000000..ebf5cbc --- /dev/null +++ b/src/components/TitleLine.tsx @@ -0,0 +1,18 @@ +import { type FC } from 'react' + +type Props = { + title: string, +} + +const TitleLine: FC = (props: Props) => { + return ( +
+
{props.title}
+ + + +
+ ) +} + +export default TitleLine \ No newline at end of file diff --git a/src/components/TrashWithConfrim.tsx b/src/components/TrashWithConfrim.tsx new file mode 100644 index 0000000..1a712e9 --- /dev/null +++ b/src/components/TrashWithConfrim.tsx @@ -0,0 +1,30 @@ +import { Trash } from 'iconsax-react' +import { type FC, useState } from 'react' +import ModalConfrim from './ModalConfrim' + +interface Props { + onDelete: () => void, + isloading?: boolean +} + +const TrashWithConfrim: FC = ({ onDelete, isloading = false }) => { + const [isConfirm, setIsConfirm] = useState(false) + return ( +
+ setIsConfirm(true)} + className='size-5' + color='#888' + /> + + setIsConfirm(false)} + onConfrim={() => onDelete()} + isloading={isloading} + /> +
+ ) +} + +export default TrashWithConfrim \ No newline at end of file diff --git a/src/components/UploadBox.tsx b/src/components/UploadBox.tsx new file mode 100644 index 0000000..7df13fc --- /dev/null +++ b/src/components/UploadBox.tsx @@ -0,0 +1,91 @@ +import { type 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) + if (props.onChange) { + props.onChange(array); + } + } else { + setFiles([acceptedFiles[0]]) + if (props.onChange) { + props.onChange([acceptedFiles[0]]) + } + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [files]) + const { getRootProps, getInputProps } = useDropzone({ onDrop }) + + const handleRemove = (index: number) => { + const array = [...files] + array.splice(index, 1) + setFiles(array) + if (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..00cd240 --- /dev/null +++ b/src/components/UploadBoxDraggble.tsx @@ -0,0 +1,170 @@ +import { CloseCircle, DocumentUpload, Gallery } from 'iconsax-react' +import { type 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, + imageSize?: 'small' | 'medium' | 'large' +} + +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]]) + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [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]) + + + return ( +
+
+ + +
+ {props.label} +
+ +
+ +
{t('upload')}
+
+
+ + { + files.length > 0 || perviews ? ( +
+ { + perviews && perviews.map((item, index) => { + const imageSizeClass = props.imageSize === 'large' + ? 'w-full h-32 rounded-lg' + : props.imageSize === 'medium' + ? 'size-20 rounded-lg' + : 'size-10 rounded-full' + return ( +
+
+ { + if (props.getCover) { + setCover(item) + props.getCover(item) + } + }} src={item} + className={clx( + imageSizeClass, + 'object-cover cursor-pointer', + 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 cursor-pointer z-10'> + +
+
+
+ ) + }) + } + { + files.map((file, index) => { + if (props.isFile) { + return ( +
+
+
{file.name}
+
+ handleDelete(index)} className='size-4 ' color='red' /> +
+
+
+ ) + } + else { + const imageSizeClass = props.imageSize === 'large' + ? 'w-full h-32 rounded-lg' + : props.imageSize === 'medium' + ? 'size-20 rounded-lg' + : 'size-10 rounded-full' + 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/types/TableTypes.ts b/src/components/types/TableTypes.ts new file mode 100644 index 0000000..e0e0b8a --- /dev/null +++ b/src/components/types/TableTypes.ts @@ -0,0 +1,47 @@ +export interface RowDataType { + id: string | number; + [key: string]: unknown; +} + +export interface ColumnType { + title: string; + key: string; + align?: "left" | "center" | "right"; + className?: string; + width?: string | number; + render?: (item: T, index?: number) => React.ReactNode; +} + +export interface PaginationType { + currentPage: number; + totalPages: number; + onPageChange: (page: number) => void; +} + +export interface ActionType { + label: string; + onClick: () => void; + icon?: React.ReactNode; + className?: string; + disabled?: boolean; +} + +export interface TableProps { + columns: ColumnType[]; + data?: T[]; + isloading?: boolean; + onRowClick?: (id: string | number, item: T) => void; + className?: string; + rowClassName?: string | ((item: T, index: number) => string); + noDataMessage?: string; + headerClassName?: string; + emptyRowsCount?: number; + showHeader?: boolean; + actions?: React.ReactNode; + actionsPosition?: "top" | "above-header" | "bottom" | "header-replace"; + selectable?: boolean; + selectedActions?: React.ReactNode; + onSelectionChange?: (selectedRows: T[]) => void; + rowActions?: (item: T) => ActionType[]; + pagination?: PaginationType; +} diff --git a/src/components/ui/checkbox.tsx b/src/components/ui/checkbox.tsx new file mode 100644 index 0000000..c7ff07b --- /dev/null +++ b/src/components/ui/checkbox.tsx @@ -0,0 +1,27 @@ +import * as React from "react" +import * as CheckboxPrimitive from "@radix-ui/react-checkbox" +import { cn } from "@/lib/utils" +import { CheckIcon } from "@radix-ui/react-icons" + +const Checkbox = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + + + + + +)) +Checkbox.displayName = CheckboxPrimitive.Root.displayName + +export { Checkbox } diff --git a/src/config/Const.ts b/src/config/Const.ts new file mode 100644 index 0000000..af5ee98 --- /dev/null +++ b/src/config/Const.ts @@ -0,0 +1 @@ +export const SIDEBAR_SIZE_LEFT = 300; diff --git a/src/config/Pages.ts b/src/config/Pages.ts new file mode 100644 index 0000000..240bd60 --- /dev/null +++ b/src/config/Pages.ts @@ -0,0 +1,87 @@ +export const Pages = { + auth: { + login: "/auth/login", + register: "/auth/register", + forgotPassword: "/auth/forgot", + }, + dashboard: "/dashboard", + schedule: { + list: "/schedule/list", + update: "/schedule/update/", + create: "/schedule/create", + }, + payment_methods: { + list: "/payment_methods/list", + add: "/payment_methods/create", + update: "/payment_methods/update/", + }, + foods: { + list: "/foods/list", + add: "/foods/add", + category: "/foods/category", + update: "/foods/update/", + }, + orders: { + list: "/orders/list", + add: "/orders/add", + detail: "/orders/detail/", + }, + customers: { + list: "/customers/list", + add: "/customers/add", + detail: "/customers/detail/", + update: "/customers/update/", + }, + discount: { + list: "/discounts/list", + add: "/discounts/add", + detail: "/discounts/detail/", + update: "/discounts/update/", + }, + announcements: { + list: "/announcements/list", + add: "/announcements/add", + detail: "/announcements/detail/", + }, + reports: { + list: "/reports/list", + }, + comments: { + list: "/comments/list", + detail: "/comments/detail/", + }, + setting: "/setting", + roles: { + list: "/roles/list", + add: "/roles/add", + update: "/roles/update/", + }, + admins: { + list: "/admins/list", + add: "/admins/add", + update: "/admins/update/", + }, + shipment_methods: { + list: "/shipment_methods/list", + add: "/shipment_methods/add", + update: "/shipment_methods/update/", + }, + coupons: { + list: "/coupons/list", + add: "/coupons/add", + update: "/coupons/update/", + }, + reviews: { + list: "/reviews/list", + detail: "/reviews/detail/", + }, + pagers: { + list: "/pagers/list", + }, + notifications: { + list: "/notifications/list", + }, + statistics: { + list: "/statistics", + }, +}; diff --git a/src/config/SideBarSubMenu.ts b/src/config/SideBarSubMenu.ts new file mode 100644 index 0000000..6361893 --- /dev/null +++ b/src/config/SideBarSubMenu.ts @@ -0,0 +1,6 @@ +export const SideBarItemHasSubMenu = [ + "foods", + "orders", + "customers", + "discounts", +]; diff --git a/src/config/axios.ts b/src/config/axios.ts new file mode 100644 index 0000000..bc69c04 --- /dev/null +++ b/src/config/axios.ts @@ -0,0 +1,124 @@ +import axios from "axios"; +import { + getToken, + getRefreshToken, + setToken, + setRefreshToken, + removeToken, + removeRefreshToken, +} from "./func"; +import { refreshToken } from "../pages/auth/service/AuthService"; + +declare global { + interface Window { + isRefreshingToken?: boolean; + isRefreshTokenExpired?: boolean; + } +} + +const axiosInstance = axios.create({ + baseURL: import.meta.env.VITE_BASE_URL, +}); + +axiosInstance.interceptors.response.use( + (response) => response, + async (error) => { + const originalRequest = error.config; + + if (error?.response?.status === 401 && !originalRequest._retry) { + // اگر refresh token منقضی شده باشد، دیگر تلاش نکن + if (window.isRefreshTokenExpired) { + return Promise.reject(error); + } + + // بررسی کن که آیا خطا از refresh endpoint است + const isRefreshEndpoint = originalRequest?.url?.includes('/admin/auth/refresh'); + + // اگر خطا از refresh endpoint است، refresh token منقضی شده + if (isRefreshEndpoint) { + window.isRefreshTokenExpired = true; + await removeToken(); + await removeRefreshToken(); + window.location.href = `/`; + return Promise.reject(error); + } + + 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 axiosInstance(originalRequest); + } + + originalRequest._retry = true; + window.isRefreshingToken = true; + + try { + const refreshTokenValue = await getRefreshToken(); + if (!refreshTokenValue) { + window.isRefreshTokenExpired = true; + await removeRefreshToken(); + await removeToken(); + window.location.href = `/`; + return Promise.reject(error); + } + const data = await refreshToken({ + refreshToken: refreshTokenValue, + }); + + if (data?.data?.accessToken?.token) { + await setToken(data.data.accessToken.token); + if (data?.data?.refreshToken?.token) { + await setRefreshToken(data.data.refreshToken.token); + } + + // Reset expired flag if refresh was successful + window.isRefreshTokenExpired = false; + + originalRequest.headers.Authorization = `Bearer ${data.data.accessToken.token}`; + return axiosInstance(originalRequest); + } else { + window.isRefreshTokenExpired = true; + await removeRefreshToken(); + await removeToken(); + window.location.href = `/`; + return Promise.reject(error); + } + } catch (refreshError) { + console.error("Token refresh failed:", refreshError); + + // بررسی کن که آیا خطا از refresh endpoint است + const isRefreshError = (refreshError as { response?: { config?: { url?: string }; status?: number } })?.response?.config?.url?.includes('/admin/auth/refresh'); + const is401Error = (refreshError as { response?: { status?: number } })?.response?.status === 401; + + // اگر refresh token خودش 401 خورده، آن را منقضی شده علامت بزن + if (isRefreshError || is401Error) { + window.isRefreshTokenExpired = true; + } + + await removeToken(); + await removeRefreshToken(); + window.location.href = `/`; + return Promise.reject(refreshError); + } finally { + window.isRefreshingToken = false; + } + } + return Promise.reject(error); + } +); + +axiosInstance.interceptors.request.use(async function (config) { + const tokenValue = await getToken(); + const token = tokenValue ? tokenValue : ""; + config.headers.Authorization = "Bearer " + token; + return config; +}); + +export default axiosInstance; diff --git a/src/config/func.ts b/src/config/func.ts new file mode 100644 index 0000000..b7fe5bc --- /dev/null +++ b/src/config/func.ts @@ -0,0 +1,74 @@ +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 localStorage.getItem(import.meta.env.VITE_TOKEN_NAME); +}; + +export const getRefreshToken = () => { + return localStorage.getItem(import.meta.env.VITE_REFRESH_TOKEN_NAME); +}; + +export const setToken = (token: string) => { + localStorage.setItem(import.meta.env.VITE_TOKEN_NAME, token); +}; + +export const setRefreshToken = (refreshToken: string) => { + localStorage.setItem(import.meta.env.VITE_REFRESH_TOKEN_NAME, refreshToken); +}; + +export const removeToken = () => { + localStorage.removeItem(import.meta.env.VITE_TOKEN_NAME); +}; + +export const removeRefreshToken = () => { + localStorage.removeItem(import.meta.env.VITE_REFRESH_TOKEN_NAME); +}; + +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 interface IGeneralError { + status: number; + success: boolean; + error: { + message: string[]; + }; +} + +export const extractErrorMessage = ( + error: Error | unknown, + fallbackMessage: string = "خطایی رخ داده است" +): string => { + try { + const axiosError = error as { response?: { data: IGeneralError } }; + return axiosError?.response?.data?.error?.message?.[0] || fallbackMessage; + } catch { + return fallbackMessage; + } +}; diff --git a/src/helpers/func.ts b/src/helpers/func.ts new file mode 100644 index 0000000..14a2afc --- /dev/null +++ b/src/helpers/func.ts @@ -0,0 +1,55 @@ +export const formatDate = (dateString: string): string => { + const date = new Date(dateString); + return new Intl.DateTimeFormat("fa-IR", { + year: "numeric", + month: "long", + day: "numeric", + hour: "2-digit", + minute: "2-digit", + }).format(date); +}; + +export const formatDateShort = (dateString: string): string => { + const date = new Date(dateString); + return new Intl.DateTimeFormat("fa-IR", { + year: "numeric", + month: "short", + day: "numeric", + }).format(date); +}; + +export const formatOptionalDate = ( + value?: string | null, + options?: Intl.DateTimeFormatOptions +): string => { + if (!value) { + return "-"; + } + const date = new Date(value); + if (Number.isNaN(date.getTime())) { + return "-"; + } + return new Intl.DateTimeFormat( + "fa-IR", + options ?? { + year: "numeric", + month: "2-digit", + day: "2-digit", + } + ).format(date); +}; + +export const formatFaNumber = (value?: number | null): string => { + if (value === undefined || value === null || Number.isNaN(value)) { + return "0"; + } + return value.toLocaleString("fa-IR"); +}; + +export const formatPrice = (price: number): string => { + return ( + new Intl.NumberFormat("fa-IR", { + minimumFractionDigits: 0, + }).format(price) + " تومان" + ); +}; diff --git a/src/helpers/permissions.ts b/src/helpers/permissions.ts new file mode 100644 index 0000000..be8fcd2 --- /dev/null +++ b/src/helpers/permissions.ts @@ -0,0 +1,59 @@ +import type { PermissionType } from '@/pages/roles/types/Types'; + +/** + * Checks if user has a specific permission + * @param permissions - Array of user permissions + * @param permissionName - Name of the permission to check + * @returns boolean indicating if user has the permission + */ +export const hasPermission = ( + permissions: PermissionType[] | undefined, + permissionName: string +): boolean => { + if (!permissions || permissions.length === 0) { + return false; + } + + return permissions.some( + (permission) => permission.name === permissionName + ); +}; + +/** + * Checks if user has any of the specified permissions + * @param permissions - Array of user permissions + * @param permissionNames - Array of permission names to check + * @returns boolean indicating if user has at least one of the permissions + */ +export const hasAnyPermission = ( + permissions: PermissionType[] | undefined, + permissionNames: string[] +): boolean => { + if (!permissions || permissions.length === 0 || permissionNames.length === 0) { + return false; + } + + return permissionNames.some((permissionName) => + hasPermission(permissions, permissionName) + ); +}; + +/** + * Checks if user has all of the specified permissions + * @param permissions - Array of user permissions + * @param permissionNames - Array of permission names to check + * @returns boolean indicating if user has all of the permissions + */ +export const hasAllPermissions = ( + permissions: PermissionType[] | undefined, + permissionNames: string[] +): boolean => { + if (!permissions || permissions.length === 0 || permissionNames.length === 0) { + return false; + } + + return permissionNames.every((permissionName) => + hasPermission(permissions, permissionName) + ); +}; + 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..39f03ef --- /dev/null +++ b/src/helpers/utils.ts @@ -0,0 +1,26 @@ +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(" ")); +}; + +/** + * Converts time string to HH:mm format + * @param time - Time string in various formats (HH:mm:ss, HH:mm, etc.) + * @returns Time string in HH:mm format + */ +export const formatTimeToHHmm = (time: string): string => { + if (!time) return ''; + // اگر زمان به فرمت HH:mm:ss باشد، فقط HH:mm را برمی‌گرداند + if (time.includes(':') && time.split(':').length === 3) { + return time.substring(0, 5); + } + // اگر به فرمت HH:mm باشد، همان را برمی‌گرداند + return time; +}; diff --git a/src/hooks/useCountDown.ts b/src/hooks/useCountDown.ts new file mode 100755 index 0000000..944028b --- /dev/null +++ b/src/hooks/useCountDown.ts @@ -0,0 +1,71 @@ +import { useEffect, useState } from 'react'; + +export interface ICountDown { + m: number; + s: number; +} +/** + * + * @param minutes how many minutes. + * @param autoplay by default true. if you want play coundDown after an action, you can set it to false and manually play it. + * @param onEnd you can pass a callback function that will trigger at the END. + * @returns + */ + +export function useCountDown(minutes: number, autoplay = true, onEnd = () => {}) { + + const [countDown, setCountDown] = useState({m: minutes, s: 0}); + const [stop, setStop] = useState(!autoplay); + + useEffect(() => { + const handler = setTimeout(() => { + if (countDown.m !== 0 || countDown.s !== 0) { + setCountDown(calculateCountDown(countDown)); + } else { + onEnd(); + } + }, 1000); + + return () => { + clearTimeout(handler); + }; + }, [countDown]); + + const reset = () => { + setCountDown({m: minutes, s: 0}); + }; + const pause = () => { + setStop(true); + }; + const play = () => { + setStop(false); + setCountDown({...countDown}); + }; + + const calculateCountDown = (st: ICountDown): ICountDown => { + if (stop) { + return countDown; + } + const timeLeft = { m: 0, s: 0 }; + const remain = st.m * 60 + st.s - 1; + if (remain > 0) { + timeLeft.m = Math.floor((remain) / 60); + timeLeft.s = remain - timeLeft.m * 60; + return timeLeft; + } else { + if (remain === 0 && countDown.s === 1) { + return timeLeft; + } else { + return countDown; + } + } + }; + + + return { + value: `${countDown.m > 9 ? countDown.m : '0' + countDown.m}:${countDown.s > 9 ? countDown.s : '0' + countDown.s}`, + reset, + pause, + play + }; +} \ No newline at end of file diff --git a/src/hooks/useNotificationSocket.ts b/src/hooks/useNotificationSocket.ts new file mode 100644 index 0000000..f466998 --- /dev/null +++ b/src/hooks/useNotificationSocket.ts @@ -0,0 +1,180 @@ +import { getToken } from "@/config/func"; +import { useEffect, useRef, useState, useCallback } from "react"; +import type { Socket } from "socket.io-client"; +import { io } from "socket.io-client"; +import type { NotificationPayload } from "@/types/notification.types"; + +export type { NotificationPayload }; + +export interface NotificationSocketOptions { + serverUrl?: string; + token: string; + autoConnect?: boolean; + onNotification?: (notification: NotificationPayload) => void; + onJoined?: (data: { room: string; message: string }) => void; + onError?: (error: { message: string }) => void; + onConnect?: () => void; + onDisconnect?: (reason: string) => void; +} + +export interface NotificationSocketState { + isConnected: boolean; + isConnecting: boolean; + room: string | null; + error: string | null; +} + +export function useNotificationSocket(options: NotificationSocketOptions) { + const { + serverUrl = import.meta.env.VITE_SOCKET_URL, + token = getToken(), + autoConnect = true, + onNotification, + onJoined, + onError, + onConnect, + onDisconnect, + } = options; + + const socketRef = useRef(null); + const [state, setState] = useState({ + isConnected: false, + isConnecting: false, + room: null, + error: null, + }); + + // Store callbacks in refs to avoid recreating socket on callback changes + const callbacksRef = useRef({ + onNotification, + onJoined, + onError, + onConnect, + onDisconnect, + }); + + useEffect(() => { + callbacksRef.current = { + onNotification, + onJoined, + onError, + onConnect, + onDisconnect, + }; + }, [onNotification, onJoined, onError, onConnect, onDisconnect]); + + const connect = useCallback(() => { + if (socketRef.current?.connected) { + return; + } + + if (!token) { + setState((prev) => ({ + ...prev, + error: "Token is required for connection", + isConnecting: false, + })); + return; + } + + setState((prev) => ({ ...prev, isConnecting: true, error: null })); + + // Clean token - remove "Bearer " prefix if present + const cleanToken = token.startsWith("Bearer ") ? token.substring(7) : token; + + const socket = io(`${serverUrl}/notifications`, { + transports: ["websocket", "polling"], + reconnection: true, + reconnectionDelay: 1000, + reconnectionAttempts: 5, + auth: { + token: cleanToken, + }, + }); + + socket.on("connect", () => { + setState((prev) => ({ + ...prev, + isConnected: true, + isConnecting: false, + error: null, + })); + callbacksRef.current.onConnect?.(); + }); + + socket.on("disconnect", (reason: string) => { + setState((prev) => ({ + ...prev, + isConnected: false, + isConnecting: false, + room: null, + })); + callbacksRef.current.onDisconnect?.(reason); + }); + + socket.on("connect_error", (error: Error) => { + setState((prev) => ({ + ...prev, + isConnected: false, + isConnecting: false, + error: error.message || "Connection failed", + })); + callbacksRef.current.onError?.({ + message: error.message || "Connection failed", + }); + }); + + socket.on("joined", (data: { room: string; message: string }) => { + setState((prev) => ({ + ...prev, + room: data.room, + })); + callbacksRef.current.onJoined?.(data); + }); + + socket.on("notifications", (data: NotificationPayload) => { + callbacksRef.current.onNotification?.(data); + }); + + socket.on("error", (error: { message: string }) => { + setState((prev) => ({ + ...prev, + error: error.message, + })); + callbacksRef.current.onError?.(error); + }); + + socketRef.current = socket; + }, [serverUrl, token]); + + const disconnect = useCallback(() => { + if (socketRef.current) { + socketRef.current.disconnect(); + socketRef.current = null; + setState({ + isConnected: false, + isConnecting: false, + room: null, + error: null, + }); + } + }, []); + + useEffect(() => { + if (autoConnect && token) { + connect(); + } + + return () => { + disconnect(); + }; + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [autoConnect, token]); + + return { + ...state, + connect, + disconnect, + socket: socketRef.current, + }; +} diff --git a/src/hooks/useOutSideClick.tsx b/src/hooks/useOutSideClick.tsx new file mode 100644 index 0000000..0ef2f1b --- /dev/null +++ b/src/hooks/useOutSideClick.tsx @@ -0,0 +1,24 @@ +import { useEffect, useRef } from 'react'; + +export const useOutsideClick = (callback: () => void) => { + const ref = useRef(null); + + useEffect(() => { + const handleClickOutside = (event: MouseEvent | TouchEvent) => { + if (ref.current && !ref.current.contains(event.target as Node)) { + callback(); + } + }; + + document.addEventListener('mouseup', handleClickOutside); + document.addEventListener('touchend', handleClickOutside); + + + return () => { + document.removeEventListener('mouseup', handleClickOutside); + document.removeEventListener('touchend', handleClickOutside); + }; + }, [callback]); + + return ref; +}; \ No newline at end of file diff --git a/src/hooks/usePermissions.ts b/src/hooks/usePermissions.ts new file mode 100644 index 0000000..bd13ab6 --- /dev/null +++ b/src/hooks/usePermissions.ts @@ -0,0 +1,50 @@ +import { useMemo } from "react"; +import { useGetPermissions } from "@/pages/roles/hooks/useRolesData"; +import { + hasPermission, + hasAnyPermission, + hasAllPermissions, +} from "@/helpers/permissions"; + +/** + * Custom hook for managing user permissions + * @returns Object with permissions data and helper functions + */ +export const usePermissions = () => { + const { data: permissionsResponse, isLoading, error } = useGetPermissions(); + + const permissions = useMemo(() => { + return permissionsResponse?.data || []; + }, [permissionsResponse]); + + /** + * Checks if user has a specific permission + */ + const checkPermission = (permissionName: string): boolean => { + return hasPermission(permissions, permissionName); + }; + + /** + * Checks if user has any of the specified permissions + */ + const checkAnyPermission = (permissionNames: string[]): boolean => { + return hasAnyPermission(permissions, permissionNames); + }; + + /** + * Checks if user has all of the specified permissions + */ + const checkAllPermissions = (permissionNames: string[]): boolean => { + return hasAllPermissions(permissions, permissionNames); + }; + + return { + permissions, + isLoading, + error, + checkPermission, + checkAnyPermission, + checkAllPermissions, + hasPermission: checkPermission, + }; +}; diff --git a/src/index.css b/src/index.css new file mode 100644 index 0000000..ccac1a1 --- /dev/null +++ b/src/index.css @@ -0,0 +1,104 @@ +@import "tailwindcss"; +@import "react-loading-skeleton/dist/skeleton.css"; + +html { + direction: rtl; +} + +body { + font-family: irancell; + margin: 0; + padding: 0; + width: 100%; + direction: rtl; + overflow-x: hidden !important; + background: #eceef6; + font-weight: 300; + overflow: hidden; +} +html, +body, +#root { + min-height: 100% !important; + height: 100%; +} +* { + outline: none; + scrollbar-width: none; /* Firefox */ + -ms-overflow-style: none; /* IE and Edge */ +} + +*::-webkit-scrollbar { + display: none; /* Chrome, Safari, Opera */ +} +input::placeholder, +textarea::placeholder { + color: #888888; +} + +@theme { + --color-primary: black; + --color-primary-foreground: white; + --color-secondary: #f4f5f9; + --color-border: #d0d0d0; + --color-description: #888888; + --color-header: #c3c7dd; + --color-success: #00ba4b; + --width-sidebar: 300px; + --border-radius-2.5: 10px; +} + +.dltr { + direction: ltr; +} + +tbody tr:nth-child(odd) { + background: rgba(233, 235, 244, 0.2) !important; +} + +.rmdp-input { + min-height: 40px; + background-color: white; + border-radius: 12px !important; + border: 1px solid oklch(0.922 0 0) !important; + font-size: 12px !important; + width: 100% !important; + margin: 0px; + padding-right: 16px !important; + transition: background-color 0.3s ease, border-color 0.3s ease; +} +.readOny .rmdp-input { + background-color: #f5f5f5 !important; + border: none !important; +} + +.rmdp-container { + width: 100%; +} + +.rowTwoInput { + @apply flex flex-col sm:flex-row sm:gap-5 gap-5; +} + +.time-picker-input::-webkit-calendar-picker-indicator { + display: none !important; + -webkit-appearance: none; +} + +.time-picker-input::-webkit-inner-spin-button, +.time-picker-input::-webkit-outer-spin-button { + display: none !important; + -webkit-appearance: none; +} + +.time-picker-input { + -webkit-appearance: none; + -moz-appearance: textfield; +} + +.modalGlass3 { + background: rgba(62, 61, 61, 0.2); + background-blend-mode: multiply; + + backdrop-filter: blur(44px); +} diff --git a/src/langs/fa.json b/src/langs/fa.json new file mode 100644 index 0000000..03b2353 --- /dev/null +++ b/src/langs/fa.json @@ -0,0 +1,891 @@ +{ + "auth": { + "welcome": "خوش آمدید", + "enter_information": "برای ثبت نام اطلاعات خود را وارد کنید.", + "user_info": "اطلاعات کاربر", + "name": "نام", + "enter_name": "نام خود را وارد کنید", + "family": "نام خانوادگی", + "enter_family": "نام خانوادگی خود را وارد کنید", + "select_date": "انتخاب تاریخ", + "dateofbirth": "تاریخ تولد", + "national_code": "کد ملی", + "national_code_enter": "کد ملی خود را وارد کنید", + "email": "ایمیل", + "enter_email": "ایمیل خود را وارد کنید", + "phonen_number": "شماره تماس", + "enter_phone_number": "شماره تماس خود را وارد کنید", + "password": "رمز عبور", + "enter_password": "رمز عبور انتخابی خود را وارد کنید", + "next": "ادامه", + "before_registered": "آیا قبلا ثبت نام کردید؟", + "login": "ورود", + "enter_info_login": "لطفا اطلاعات خود را وارد کنید.", + "mobile_or_email": " شماره موبایل یا ایمیل", + "enter_mobile_or_email": " شماره موبایل یا ایمیل خود را وارد کنید", + "mobile": "شماره موبایل", + "enter_mobile": "شماره موبایل خود را وارد کنید", + "otp_sent": "کد تایید ارسال شد", + "have_account": "آیا حساب کاربری ندارید؟", + "register": "ثبت نام", + "enter_otp": "کد تایید را وارد کنید", + "verfify_code_text_1": "کد تایید برای ", + "verfify_code_text_2": "ارسال شد.", + "change_number": "تغییر شماره", + "verify_code": "کد تایید ", + "counter_otp": "مانده تا دریافت مجدد کد", + "login_with_password": "ورود با رمز عبور", + "enter_password_step3": "رمز عبور را وارد کنید", + "enter_your_password": "رمز عبور خود را وارد کنید.", + "forgot_password": "فراموشی رمز عبور", + "login_with_otp": "ورود با رمز عبور یکبار مصرف", + "slug": "نام کاربری", + "enter_slug": "نام کاربری خود را وارد کنید" + }, + "errors": { + "required": "این فیلد اجباری می باشد", + "upload_image": "تصاویر مربوطه باید انتخاب شوند" + }, + "description": "توضیحات", + "sidebar": { + "menu": "منو", + "mainpage": "صفحه اصلی", + "schedule": "زمان سفارش گیری", + "foods": "غذا ها", + "orders": "سفارشات", + "customers": "مشتریان", + "discount": "کد تخفیف", + "other": "سایر", + "announcements": "اطلاعیه ها", + "reports": "گزارش اشکال", + "comments": "نظرات", + "setting": "تنظیمات", + "logout": "خروج", + "roles": "سطح دسترسی ها", + "payment_methods": "روش های پرداخت", + "admins": "مدیران", + "shipment_methods": "روش های ارسال", + "reviews": "نظرات", + "pagers": "پیجرها", + "notifications": "تنظیمات اعلانات", + "statistics": "گزارشات" + }, + "shipment": { + "dineIn": "سرو در رستوران", + "customerPickup": "دریافت از محل", + "deliveryCar": "تحویل به خودرو", + "deliveryCourier": "بیرون بر" + }, + "slider": { + "new_slider": "اسلایدر جدید", + "submit": "ثبت اسلایدر", + "title": "عنوان", + "link": "لینک", + "description": "توضیحات", + "image": "تصویر", + "order": "ترتیب", + "isActive": "فعال / غیرفعال", + "image_required": "تصویر الزامی می باشد", + "list_slider": "لیست اسلایدر ها", + "submit_slider": "اسلایدر جدید", + "active": "فعال", + "inactive": "غیرفعال", + "slider_deleted": "اسلایدر با موفقیت حذف شد" + }, + "submenu": { + "foods_list": "لیست غذا ها", + "add_food": "افزودن غذا", + "categories": "دسته بندی ها", + "orders_list": "لیست سفارشات", + "add_order": "افزودن سفارش", + "discount_list": "لیست تخفیف", + "add_discount": "افزودن تخفیف", + "customers_list": "لیست مشتریان", + "add_customer": "افزودن مشتری" + }, + "guide": { + "list_guide": "لیست راهنمای سرویس", + "submit_guide": "افزودن راهنمای سرویس", + "order": "ترتیب", + "content": "محتوا" + }, + "review": { + "title": "عنوان", + "comment": "نظر", + "user": "کاربر", + "service": "سرویس", + "date": "تاریخ", + "status": "وضعیت", + "approved": "تایید شده", + "rejected": "رد شده", + "approve": "تایید", + "reject": "رد" + }, + "header": { + "search": "جستجو" + }, + "home": { + "new": "جدید", + "study": "مطالعه", + "myservice": "سرویس های من", + "active_service": "سرویس های فعال", + "ticket": "تیکت ها", + "unread_messages": "پیام خوانده نشده دارید ", + "announcement": "اطلاعیه ها", + "unread_announcement": "اطلاعیه خوانده نشده دارید", + "learnings": "آموزش ها", + "learning": "آموزش", + "access": "دسترسی سریع", + "add_access": "دسترسی سریع تازه ایجاد کنید.", + "danak_learning": "آموزش داناک", + "see_all": "دیدن همه", + "create_new_access": "ایجاد دسترسی سریع", + "services": "سرویس ها", + "service": "سرویس", + "customers": "مشتریان", + "customer": "مشتری", + "invoices": "صورت حساب ها", + "new_invoice": "صورت حساب جدید", + "ads": "تبلیغات", + "active_ads": "تبلیغ فعال" + }, + "all": "همه", + "service": { + "my_service": "سرویس های من", + "search": "جستجو در سرویس ها", + "active_menu": "منو فعال", + "selected_danak": "انتخاب داناک", + "buy": "خرید", + "other_services": "سایر سرویس ها", + "year": "سالانه", + "month3": "۳ ماهه", + "month": "ماهیانه", + "company_develop": "شرکت توسعه دهنده", + "company_danak": "شرکت داناک", + "user_count": "تعداد کاربران", + "year_make": "سال ساخت", + "lang_app": "زبان نرم افزار", + "persian": "فارسی", + "score": "امتیاز", + "compelete_description": "توضیحات تکمیلی", + "submit_comment": "ثبت نظر", + "hint_comment": "شما پس از خرید این سرویس میتوانید نظر خود را به ثبت برسانید.", + "fullName": "نام و نام خانوادگی", + "enter_your_name": "نام خود را واردکنید", + "title": "عنوان", + "enter_title_comment": "عنوان نظر خود را وارد کنید", + "your_comment": "نظر شما", + "write_your_comment": "نظر خود را راجع به این سرویس بنویسید", + "users_comments": "نظرات کاربران", + "add_service": "افزودن سرویس", + "service_name": "نام سرویس", + "description_short": "توضیح کوتاه سرویس", + "company_developed": "شرکت توسعه دهنده", + "service_status": "وضعیت سرویس", + "special_danak": "این سرویس پیشنهاد ویژه داناک هست", + "service_link": "لینک دریافت سرویس", + "category": "دسته بندی", + "service_icon": "آیکون سرویس", + "upload_icon_service": "آیکون سرویس مورد نظر را آپلود کنید", + "service_images": "تصاویر سرویس", + "upload_images_service": "تصاویر سرویس مورد نظر را آپلود کنید", + "submit_service": "ثبت سرویس", + "new_service": "سرویس جدید", + "list_service": "لیست سرویس ها", + "status": "وضعیت", + "publish_date": "تاریخ انتشار", + "cateory_services": "دسته بندی سرویس ها", + "parent_category": "دسته مادر", + "count_sub_category": "تعداد زیر دسته", + "count_service": "تعداد سرویس", + "add_category": "اضافه کردن دسته بندی", + "status_category": "وضعیت دسته بندی", + "title_category": "عنوان دسته بندی", + "category_parent_2": "دسته بندی مادر", + "icon_serice_category": "آیکون سرویس مورد نظر را آپلود کنید", + "active": "فعال", + "deactive": "غیرفعال", + "software_langauge": "زبان نرم افزار", + "link": "لینک", + "danak_sujescet": "پیشنهاد داناک", + "plans": "پلن ها", + "add_plan": "افزودن پلن", + "active_plan": "پلن فعال", + "slider": "نمایش در اسلایدر", + "slug": "اسلاگ", + "page_title": "عنوان صفحه", + "page_description": "توضیحات صفحه" + }, + "plan": { + "plans_list": "لیست پلن های ", + "new_plan": "پلن جدید", + "add_plan": "افزودن پلن", + "time": "مدت زمان", + "price": "قیمت", + "original_price": "قیمت اصلی", + "cancel": "لغو", + "submit_plan": "ثبت پلن", + "error_submit": "حداقل یک پلن باید اضافه شود", + "success_submit": "پلن با موفقیت ثبت شد", + "edit_plan": "ویرایش پلن" + }, + "save": "ذخیره", + "search": "جستجو", + "upload": "آپلود", + "select": "انتخاب", + "footer": { + "home": "صفحه اصلی", + "customers": "مشتریان", + "foods": "غذا ها", + "announcements": "اطلاعیه ها", + "orders": "سفارشات" + }, + "ticket": { + "tickets": "تیکت ها", + "new_ticket": "تیکت جدید", + "answered": "پاسخ داده شده", + "checking": "در حال بررسی", + "wait_answered": "در انتظار پاسخ", + "closed": "بسته شده", + "number": "شماره", + "title": "عنوان", + "team": "تیم", + "date": "تاریخ", + "status": "وضعیت", + "priority": "الویت", + "detail": "جزییات", + "submit_your_message": "ثبت پیام شما", + "name": "نام", + "email": "ایمیل", + "subject": "موضوع", + "enter_your_subject": "موضوع درخواست خودرا وارد کنید", + "select_your_service": "سرویس مربوطه", + "not_once": "هیچکدام", + "your_description": "توضیحات شما", + "attachment": "فایل های ضمیمه", + "send": "ارسال", + "title_hint": "جهت پاسخگویی بهتر به مسائل زیر توجه بفرمایید :", + "ticket_number": "تیکت شماره", + "user_name": "نام کاربر", + "expert": "کارشناس: ", + "answer": "پاسخ", + "send_answer": "ارسال پاسخ", + "close_ticket": "بستن تیکت", + "info_ticket": "اطلاعات تیکت", + "update_sms": "به روزرسانی این تیکت از طریق پیامک اطلاع داده میشود", + "category_ticket": "دسته بندی تیکت", + "users_count": "تعداد کاربر", + "add_category": "اضافه کردن دسته بندی", + "status_category": "وضعیت دسته بندی", + "title_category": "عنوان دسته بندی", + "users": "کاربران", + "MEDIUM": "متوسط", + "LOW": "پایین", + "HIGH": "بالا", + "PENDING": "در انتظار", + "ANSWERED": "پاسخ داده شده", + "CLOSED": "بسته شده", + "asignto": "کارشناس پاسخگویی", + "category": "دسته بندی", + "low": "پایین", + "medium": "متوسط", + "high": "بالا", + "service": "سرویس", + "refer_ticket": "ارجاع تیکت", + "user": "کاربر", + "assign_to": "کارشناس پاسخگویی", + "user_plan": "پلن کاربر", + "refer_ticket_success": "تیکت با موفقیت ارجاع شد", + "refer_ticket_error": "تیکت ارجاع نشد" + }, + "active": "فعال", + "inactive": "غیرفعال", + "attach": "پیوست", + "date": "تاریخ", + "status": "وضعیت", + "title": "عنوان", + "ads": { + "ads": "تبلیغات", + "upload": "آپلود", + "deactive": "غیرفعال", + "submit": "ثبت تبلیغ", + "upload_picture": "تصویر نمایش تبلیغ", + "to_upload_message": "تصویر مورد نظر را آپلود کنید", + "new_ads": "افزودن تبلیغ", + "location": "جایگاه", + "startDate": "تاریخ شروع نمایش", + "endDate": "تاریخ پایان نمایش", + "search": "جستجو", + "number": "شماره", + "title": "عنوان", + "date": "تاریخ", + "status": "وضعیت", + "enter_your_title": "عنوان تبلیغ را وارد کنید", + "link": "لینک", + "enter_your_link": "لینک تبلیغ را وارد کنید", + "HOMEPAGE_TOP": "بالای صفحه اصلی", + "SINGLE_SERVICE_PAGE": "صفحه سرویس تکی", + "MY_SERVICES_PAGE": "صفحه سرویس های من", + "OTHER_SERVICES_TOP": "بالای سایر سرویس ها", + "OTHER_SERVICES_LEFT": "سمت چپ سایر سرویس ها", + "SERVICE": "سرویس", + "file_error": "فایل مورد نظر باید انتخاب شود", + "BLOG_PAGE_TOP_RIGHT": "بالای صفحه بلاگ راست", + "BLOG_PAGE_BOTTOM_RIGHT": "پایین صفحه بلاگ راست", + "BLOG_PAGE_TOP_LEFT": "بالای صفحه بلاگ چپ" + }, + "discount": { + "list": "لیست تخفیفات", + "type": "نوع تخفیف", + "price": "مبلغ تخفیف", + "title": "عنوان کد", + "code": "کد تخفیف", + "CODE": "کد تخفیف", + "enter_discount_description": "عنوان کد تخفیف را وارد کنید", + "add_new_discount": "افزودن تخفیف", + "auto_generate_code": "ساخت کد", + "price_or_percent": "درصد / مبلغ تخفیف", + "enter_price_or_percent": "درصد / مبلغ تخفیف را وارد کنید", + "service": "سرویس", + "status": "وضعیت", + "number": "شماره", + "startDate": "تاریخ شروع", + "endDate": "تاریخ پایان", + "service_status": "وضعیت سرویس", + "availabe_service": "سرویس هایی که شامل تخفیف میشوند", + "new_discount": "کد تخفیف جدید", + "submit": "ثبت تخفیف", + "discount_code": "کد تخفیف", + "direct_discount": "تخفیف مستقیم", + "fixed_amount": "مبلغ ثابت", + "percent": "درصد", + "errors_plan": "سرویس و پلن را انتخاب کنید", + "DIRECT": "مستقیم", + "FIXED": "ثابت", + "plan": "پلن", + "user": "کاربر", + "0": "درصد", + "1": "مبلغ", + "update_discount": "ویرایش تخفیف", + "customer": "مشتری" + }, + "blog": { + "blog": "بلاگ", + "category": "دسته بندی", + "new_blog": "افزودن بلاگ", + "blog_title": "عنوان بلاگ", + "blog_summary": "خلاصه بلاگ", + "content": "محتوا", + "blog_status": "وضعیت بلاگ", + "featured_image": "تصویر شاخص", + "tags": "برچسب ها", + "tag_hint": "جدا کردن با کاما یا کلید Enter ", + "shareDate": "تاریخ انتشار", + "enter_your_title": "عنوان بلاگ را وارد کنید", + "add_blog": "افزودن بلاگ", + "blog_category": "دسته بندی بلاگ", + "add_category": "اضافه کردن دسته بندی", + "category_status": "وضعیت دسته بندی", + "category_title": "عنوان دسته بندی", + "parent_category": "دسته بندی مادر", + "price": "مبلغ تخفیف", + "title": "عنوان کد", + "code": "کد تخفیف", + "enter_discount_description": "عنوان کد تخفیف را وارد کنید", + "add_new_discount": "افزودن تخفیف", + "auto_generate_code": "ساخت کد", + "price_or_percent": "درصد / مبلغ تخفیف", + "enter_price_or_percent": "درصد / مبلغ تخفیف را وارد کنید", + "service": "سرویس", + "status": "وضعیت", + "number": "شماره", + "startDate": "تاریخ شروع", + "endDate": "تاریخ پایان", + "service_status": "وضعیت سرویس", + "availabe_service": "سرویس هایی که شامل تخفیف میشوند", + "new_discount": "کد تخفیف جدید", + "submit": "ثبت بلاگ", + "discount_code": "کد تخفیف", + "direct_discount": "تخفیف مستقیم", + "fixed_amount": "مبلغ ثابت", + "percent": "درصد", + "enter_your_summary": "خلاصه بلاگ را وارد کنید", + "enter_your_content": "محتوای بلاگ را وارد کنید", + "blog_content": "محتوای بلاگ", + "enter_tags": "برچسب ها را وارد کنید", + "enter_your_slug": "اسلاگ بلاگ را وارد کنید", + "slug": "اسلاگ", + "meta_title": "عنوان متا", + "enter_your_meta_title": "عنوان متا بلاگ را وارد کنید", + "meta_description": "توضیحات متا", + "enter_your_meta_description": "توضیحات متا بلاگ را وارد کنید", + "comments": "نظرات", + "user": "کاربر", + "comment": "نظر", + "picture": "تصویر" + }, + "receip": { + "receips": "صورتحساب ها", + "receip_list": "لیست صورتحساب ها", + "add_receip": "افزودن صورتحساب", + "dont_pay": "پرداخت نشده", + "dont_confrim": "تایید نشده", + "paid": "پرداخت شده", + "canceled": "لغو شده", + "returned": "پس داده شده", + "its_time": "سررسیده شده", + "archive": "بایگانی شده", + "detail_account": "جزییات صورتحساب ", + "personal_information": "اطلاعات شخصی", + "type_person": "نوع شخص : ", + "company": "حقوقی", + "representativeـname": "نام نماینده :", + "company_name": "نام شرکت/ سازمان :", + "registration_number": "شماره ثبت :", + "tel_company": "تلفن شرکت :", + "national_code": "کد ملی نماینده :", + "postal_code": "کد پستی :", + "state": "استان :", + "city": "شهر :", + "address": "آدرس :", + "detail_receip": "مشخصات صورتحساب", + "not_paid": "پرداخت نشده", + "description": "توضیحات", + "price": "مبلغ", + "receip_information": "اطلاعات صورتحساب", + "date_factor": "تاریخ صدور فاکتور", + "due_date": "تاریخ سررسید فاکتور", + "factor_number": "شماره فاکتور", + "status_factor": "وضعیت فاکتور", + "submit_receip": "ثبت صورتحساب", + "customer_information": "اطلاعات مشتری", + "customer": "مشتری", + "receipt_information": "اطلاعات صورتحساب", + "number": "شماره", + "product_name": "نام کالا", + "count": "تعداد", + "unit_amount": "مبلغ واحد", + "discount": "تخفیف(٪)", + "total_amount": "مبلغ کل(تومان)", + "tax": "مالیات بر ارزش افزوده (۱۰ درصد)", + "total": "جمع", + "error_empty": "همه فیلد ها را پر کنید", + "date_receipt": "تاریخ صورتحساب", + "last_date_receipt": "آخرین مهلت پرداخت", + "service": "سرویس", + "status": "وضعیت تایید", + "status_paid": "وضعیت پرداخت", + "PENDING": "در انتظار", + "PAID": "پرداخت شده", + "CANCELED": "لغو شده", + "EXPIRED": "منقضی شده", + "approved": "تایید شده", + "APPROVED": "تایید شده", + "ARCHIVED": "بایگانی شده", + "pending": "در انتظار", + "since": "از تاریخ", + "to": "تا تاریخ", + "recurring": "دوره ای", + "select_type": "انتخاب نوع دوره", + "1": "هفتگی", + "2": "ماهانه", + "3": "سه‌ماهه", + "4": "شش‌ماهه", + "5": "سالانه", + "maxRecurringCycles": "حداکثر تعداد تکرار دوره", + "WAIT_PAYMENT": "در انتظار پرداخت", + "overdue": "سررسید شده", + "OVERDUE": "سررسید شده", + "lateFee": "مبلغ جریمه", + "recurringPeriod": "دوره تکرار", + "WEEKLY": "هفتگی", + "MONTHLY": "ماهانه", + "QUARTERLY": "سه‌ماهه", + "SEMIANNUALLY": "شش‌ماهه", + "ANNUALLY": "سالانه" + }, + "edit": "ویرایش", + "transaction": { + "transaction": "تراکنش ها", + "totao_deposit": "مجموع واریز ها", + "total_withdrawal": "مجموع برداشت ها", + "balance": "موجودی کیف پول", + "transaction2": "تراکنش", + "type_deposit": "نوع واریز", + "status": "وضعیت", + "success_paid": "پرداخت موفق", + "print": "پرینت", + "download": "دانلود", + "type_getway": "نوع درگاه", + "doer": "انجام دهنده", + "tracking_number": "شماره پیگیری", + "description_transaction": "شرح تراکنش", + "amount": "مبلغ", + "date": "تاریخ تراکنش", + "order_number": "شماره سفارش", + "description": "توضیحات تراکنش", + "user_search": "جستجو کاربر" + }, + "announcement": { + "announcements": "اطلاعیه ها", + "search": "جستجو در اطلاعیه ها", + "new": "جدید", + "important": "مهم", + "text_announcement": "متن اطلاعیه", + "add_announcement": "افزودن اطلاعیه", + "submit_announcement": "ثبت اطلاعیه", + "title": "عنوان اطلاعیه", + "text": "متن اطلاعیه", + "publish_date": "زمان انتشار", + "info_publishdata": "اگر مایلید اطلاعیه در زمان دیگری منتشر شود تاریخ انتشار مورد نظر را انتخاب کنید", + "label_importance": "لیبل “مهم” در اطلاعیه درج شود", + "select_service": "انتخاب سرویس", + "select_customer": "انتخاب مشتری", + "contact_announcement": "مخاطب این اطلاعیه", + "date_created": "تاریخ ثبت", + "summary": "خلاصه اطلاعیه", + "user": "کاربر مخاطب", + "created_date": "زمان ایجاد", + "service": "سرویس" + }, + "back": "بازگشت", + "criticisms": { + "criticisms": "انتقادات", + "submit_your_criticisms": "ثبت انتقاد شما", + "description_criticisms": "با انتقاد خود راهگشای ما باشید.", + "subject": "موضوع", + "enter_your_subject": "موضوع انتقاد خودرا وارد کنید", + "description": "توضیحات", + "enter_description": "توضیحات شما", + "criticisms_list": "لیست انتقادات", + "number": "شماره", + "title_criticisms": "عنوان انتقاد", + "summary_criticisms": "خلاصه انتقاد", + "date_created": "تاریخ ثبت", + "criticism": "انتقاد", + "documents": "مستندات" + }, + "detail": "جزییات", + "select_file": "انتخاب فایل", + "no_select_file": "هیچ فایلی انتخاب نشده است", + "attachment": "فایل های ضمیمه", + "learning": { + "learning": "آموزش", + "learnings": "آموزش ها", + "new_learning": "افزودن آموزش", + "category_learning": "دسته بندی آموزش", + "submit_learning": "ثبت آموزش", + "title": "عنوان آموزش", + "category": "دسته بندی", + "description": "توضیحات", + "video_duration": "مدت زمان ویدیو", + "learning_cover": "کاور آموزش", + "upload_cover": "آپلود کاور", + "video": "آپلود ویدیو", + "upload_video": "آپلود ویدیو", + "error_video_cover_required": "آپلود ویدیو و کاور اجباری است", + "list_learning": "لیست آموزش ها" + }, + "setting": { + "setting": "تنظیمات", + "notification": "پیام و ایمیل", + "password": "رمز عبور", + "setting_email_message": "تنظیمات ارسال پیام و ایمیل", + "notification_announcement": "اعلانات و اطلاعیه ها", + "email": "ایمیل", + "sms": "پیامک", + "change_password": "تغییر رمز عبور", + "current_password": "رمز عبور فعلی", + "new_password": "رمز عبور جدید", + "reapeat_password": "تکرار رمز عبور", + "save_change": "ذخیره تغییرات", + "password_is": "رمز عبور می‌بایست:", + "min-8": "حداقل 8 کاراکتر باشد", + "mix_charachter_number": "ترکیبی از حروف کوچک و بزرگ باشد", + "exsist_number": "شامل اعداد باشد", + "exsist_special_character": "شامل کاراکتر های خاص (نماد ها) باشد" + }, + "wallet": { + "increese_wallet": "افزایش موجودی حساب اعتباری", + "online_pay": "پرداخت آنلاین", + "card_to_card": "کارت به کارت", + "select_price": "انتخاب مبلغ", + "optional_price": "مبلغ دلخواه‌ (به تومان وارد کنید)", + "enter_your_price": "مبلغ دلخواه خودرا وارد کنید", + "select_payment": "انتخاب درگاه پرداخت", + "pay": "پرداخت", + "amount": "مبلغ", + "enter_amount_card": "مبلغ کارت به کارت شده را وارد کنید", + "upload_deposit_slip": "آپلود فیش واریزی", + "submit_slip": "ثبت فیش", + "sheba": "شبا", + "pay_sheba": "پرداخت شبا", + "enter_sheba_deposit": "مبلغ شبا شده شده را وارد کنید" + }, + "notif": { + "natification": "اعلان ها", + "all_read": "همه خوانده شده" + }, + "user": { + "users_list": "لیست کاربران", + "add_user": "افزودن کاربر", + "name": "نام", + "title_job": "عنوان شغلی", + "email": "ایمیل", + "role": "نقش", + "submit_user": "ثبت کاربر", + "info_user": "اطلاعات کاربر", + "family": "نام خانوادگی", + "phone_number": "شماره تماس", + "password": "رمز عبور", + "reapeat_password": "تکرار رمز عبور", + "image": "تصویر حساب کاربری", + "roles_list": "لیست نقش ها", + "add_role": "افزودن نقش", + "role_search": "جستجو در نقش ها", + "title": "عنوان", + "user": "کاربر", + "submit_role": "ثبت نقش", + "title_role": "عنوان نقش", + "permissions": "دسترسی ها", + "status_role": "وضعیت نقش", + "error_count_permission": "حداقل به دسترسی رو باید انتخاب کنید", + "is_admin": "آیا ادمین است؟", + "user_group": "گروه کاربری", + "add_user_group": "ساخت گروه کاربری", + "users": "کاربران", + "group_add": "ساخت گروه", + "submit_group": "ثبت گروه", + "error_count_users": "حداقل یک کاربر باید انتخاب شود", + "list_user_group": "لیست گروه های کاربری", + "groups": "گروه ها", + "group_name": "نام گروه", + "update_user": "ویرایش کاربر" + }, + "submit": "ثبت", + "yes": "بله", + "no": "خیر", + "profile": { + "account_user": "حساب کاربری", + "image_profile": "تصویر حساب کاربری", + "image_profile_desc": "تصویر خود را در حساب کاربری قرار دهید.", + "upload_image": "آپلود تصویر", + "formats": "فرمت های", + "max_size": "حداکثر ۱مگابایت", + "format_image": " jpg, png,jpeg.", + "info_account": "اطلاعات حساب", + "auth_after_change_info": "در صورت تغییر اطلاعات حساب باید مجددا احراز هویت انجام شود.", + "username": "نام کاربری", + "phone_call": "شماره تماس", + "personal_information": "اطلاعات شخصی", + "enter_carefully_your_information": "اطلاعت شخصی خود را با دقت وارد کنید.", + "date_of_birth": "تاریخ تولد", + "national_code": "کد ملی", + "address": "آدرس", + "address_live": "آدرس محل سکونت خود را با دقت وارد کنید", + "province": "استان", + "city": "شهر", + "postal_code": "کد پستی", + "username_available": "نام کاربری موجود", + "username_not_available": "نام کاربری موجود نیست", + "username_save_success": "نام کاربری با موفقیت ذخیره شد", + "image_uploaded_successfully": "تصویر با موفقیت آپلود شد", + "confrim_email": "تایید ایمیل", + "confrim": "تایید صورتحساب ", + "link_email": "یک لینک برای تایید ایمیل برای شما ارسال شد.", + "email_not_verified": "ایمیل تایید نشده" + }, + "email": "ایمیل", + "customer": { + "customer_list": "لیست مشتریان", + "add_cutomer": "افزودن مشتری", + "name": "نام", + "company": "سازمان / شرکت", + "email": "ایمیل", + "active_services": "سرویس های فعال", + "factor": "صورت حساب ها", + "tickets": "تیکت ها", + "detail": "جزییات", + "submit_customer": "ثبت مشتری", + "family": "نام خانوادگی", + "dateofbirth": "تاریخ تولد", + "national_code": "کد ملی", + "phone_number": "شماره تماس", + "information_legal": "اطلاعات حقوقی", + "economic_code": "کد اقتصادی", + "id_national": "شناسه ملی", + "enter_nation_code": "کد ملی خود را وارد کنید", + "enter_email": "ایمیل خود را وارد کنید", + "enter_phone_number": "شماره تماس خود را وارد کنید", + "enter_economic_code": "کد اقتصادی را وارد کنید", + "enter_id_nation": "شناسه ملی خود را وارد کنید", + "registeration_id": "شناسه ثبت", + "enter_registeration_id": "شناسه ثبت خود را وارد کنید", + "your_phone_fixed": "شماره تماس ثابت", + "enter_phone_fixed": "شماره تماس خود را وارد کنید", + "state": "استان", + "city": "شهر", + "password": "رمز عبور", + "reapeat_password": "تکرار رمز عبور", + "copany_name": "نام شرکت", + "enter_company_name": "نام ثبتی شرکت را وارد کنید", + "postal_code": "کد پستی", + "enter_postal_code": "کد پستی را وارد کنید", + "address": "آدرس", + "image_profile": "تصویر پروفایل", + "upload_image": "آپلود تصویر", + "new_password": "رمز عبور جدید" + }, + "priority": "الویت", + "messages": { + "messages_list": "لیست پیام ها", + "submit_date": "تاریخ ثبت", + "number": "شماره", + "fullName": "نام و نام خانوادگی", + "email": "ایمیل", + "subject": "موضوع", + "date": "تاریخ", + "message": "پیام" + }, + "loading": "در حال بارگذاری...", + "success": "عملیات با موفقیت انجام شد.", + "confrim": { + "subject": "حذف", + "content": "برای حذف این آیتم مطمئن هستید؟", + "yes": "بله", + "cancel": "لغو" + }, + "cardBank": { + "new_account": "حساب جدید", + "submit_account": "ثبت حساب", + "account_information": "اطلاعات حساب", + "status_account": "وضعیت حساب", + "account_owner_name": "نام صاحب حساب", + "bank_name": "نام بانک", + "card_number": "شماره کارت", + "sheba": "شماره شبا", + "manage_banks": "مدیریت حساب های بانکی", + "add_account": "افزودن حساب" + }, + "payment": { + "Online": "آنلاین", + "Cash": "نقدی", + "CardOnDelivery": "کارت هنگام تحویل", + "Wallet": "کیف پول", + "zarinpal": "زرین‌پال", + "payments": "پرداخت ها", + "status_payment": "وضعیت پرداخت", + "user": "کاربر", + "card_number": "شماره کارت", + "sheba_number": "شماره شبا", + "amount": "مبلغ", + "date": "تاریخ", + "payment_type": "نوع پرداخت", + "PENDING": "در انتظار", + "FAILD": "ناموفق", + "COMPELETED": "تکمیل شده", + "CANCELED": "لغو شده", + "REJECTED": "رد شده", + "APPROVED": "تایید شده", + "aceept": "تایید", + "reject": "رد", + "accept_confrim": "آیا از تایید این پرداخت مطمئن هستید؟", + "reject_comment_error": "لطفا دلیل رد پرداخت را وارد کنید", + "receip_image": "تصویر فیش واریزی" + }, + "support": { + "support_plan": "پلن پشتیبانی", + "support_plan_list": "لیست پلن پشتیبانی", + "support_plan_create": "ایجاد پلن پشتیبانی", + "support_plan_edit": "ویرایش پلن پشتیبانی", + "1-learning_docs": "راهنما و مستندات آموزشی", + "2-ticket_support": "ارسال تیکت", + "3-ticket_limit": "ظرفیت ارسال تیکت", + "4-response_time": "زمان پاسخگویی به تیکت", + "5-technical_issue_resolution": "رفع ایراد فنی", + "6-phone_support": "پاسخگویی تلفنی", + "7-technical_expert_access": "دسترسی به متخصصین فنی", + "8-backup_version": "نسخه بکاپ", + "9-service_functionality_test": "تست عملکرد سرویس", + "10-on_site_support": "پشتیبانی در محل", + "11-on_site_training": "آموزش در محل", + "plans": "پلن ها", + "plan_name": "نام پلن", + "price": "قیمت", + "duration": "مدت", + "features": "ویژگی ها", + "actions": "عملیات", + "new_plan": "پلن جدید", + "plan_users": "کاربران ", + "ACTIVE": "فعال", + "INACTIVE": "غیرفعال", + "EXPIRED": "منقضی شده", + "start_date": "تاریخ شروع", + "end_date": "تاریخ پایان", + "status": "وضعیت", + "full_name": "نام و نام خانوادگی", + "users": "کاربران" + }, + "schedule": { + "multiple_shifts_hint": "برای یک روز میتوانید چند شیفت زمانی ثبت کنید مثلا 8 تا 12 و 14 تا 18", + "attention": "دقت کنید", + "order_time_limit": "فقط در زمان های فوق امکان سفارش گیری هست", + "weekDay": { + "0": "شنبه", + "1": "یکشنبه", + "2": "دوشنبه", + "3": "سه‌شنبه", + "4": "چهارشنبه", + "5": "پنج‌شنبه", + "6": "جمعه" + } + }, + "payment_methods": { + "payment_methods": "روش های پرداخت", + "payment_methods_list": "لیست روش های پرداخت", + "payment_methods_add": "افزودن روش پرداخت", + "payment_methods_update": "ویرایش روش پرداخت" + }, + "order_status": { + "pendingPayment": "در انتظار پرداخت", + "paid": "پرداخت شده", + "confirmed": "تایید شده", + "preparing": "در حال آماده سازی", + "ready": "آماده", + "shipped": "ارسال شده", + "completed": "تکمیل شده", + "canceled": "لغو شده", + "deliveredToWaiter": "تحویل به گارسون", + "deliveredToReceptionist": "تحویل به پیشخوان" + }, + "reviews": { + "reviews": "نظرات", + "reviews_list": "لیست نظرات", + "add_review": "افزودن نظر", + "edit_review": "ویرایش نظر", + "review_list": "لیست نظرات", + "review_name": "نام نظر", + "review_email": "ایمیل نظر", + "review_comment": "نظر", + "great_taste": "طعم عالی", + "fast_delivery": "تحویل سریع", + "good_quality": "کیفیت خوب", + "good_portion_size": "اندازه مناسب پرس", + "friendly_service": "خدمات دوستانه", + "small_portion": "پرس کوچک", + "slow_delivery": "تحویل کند", + "poor_quality": "کیفیت پایین", + "overpriced": "قیمت بالا", + "unfriendly_service": "خدمات نامناسب" + }, + "pager": { + "status": { + "pending": "در انتظار", + "acknowledged": "تایید شده", + "rejected": "رد شده", + "completed": "تکمیل شده" + }, + "change_status": "تغییر وضعیت", + "save": "ذخیره" + } +} diff --git a/src/lib/utils.ts b/src/lib/utils.ts new file mode 100644 index 0000000..6fcf374 --- /dev/null +++ b/src/lib/utils.ts @@ -0,0 +1,7 @@ +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/admin/Create.tsx b/src/pages/admin/Create.tsx new file mode 100644 index 0000000..3c91681 --- /dev/null +++ b/src/pages/admin/Create.tsx @@ -0,0 +1,119 @@ +import { type FC } from 'react' +import { useFormik } from 'formik' +import * as Yup from 'yup' +import { TickCircle } from 'iconsax-react' +import { toast } from 'react-toastify' +import { useNavigate } from 'react-router-dom' +import Button from '@/components/Button' +import Input from '@/components/Input' +import Select from '@/components/Select' +import { useCreateAdmin } from './hooks/useAdminData' +import { useGetRoles } from '@/pages/roles/hooks/useRolesData' +import type { CreateAdminType } from './types/Types' +import { Pages } from '@/config/Pages' +import type { ErrorType } from '@/helpers/types' +import { extractErrorMessage } from '@/config/func' + +const CreateAdmin: FC = () => { + const navigate = useNavigate() + const { mutate: createAdmin, isPending } = useCreateAdmin() + const { data: rolesData } = useGetRoles() + + const roles = rolesData?.data?.map(role => ({ + label: role.name, + value: role.id + })) || [] + + const formik = useFormik({ + initialValues: { + phone: '', + firstName: '', + lastName: '', + roleId: '', + }, + validationSchema: Yup.object().shape({ + phone: Yup.string().required('شماره تلفن الزامی است'), + firstName: Yup.string().required('نام الزامی است'), + lastName: Yup.string().required('نام خانوادگی الزامی است'), + roleId: Yup.string().required('نقش الزامی است'), + }), + onSubmit: (values) => { + createAdmin(values, { + onSuccess: () => { + toast.success('مدیر با موفقیت ایجاد شد') + navigate(Pages.admins.list) + }, + onError: (error: ErrorType) => { + toast.error(extractErrorMessage(error)) + }, + }) + }, + }) + + return ( +
+
+
+ مدیر جدید +
+
+ +
+
+ +
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ + + { + formik.touched.phone && formik.errors.phone && + + } + +
+ +
+ + + { + formik.touched.slug && formik.errors.slug && + + } + +
+ + +
+ ) +} + +export default LoginStep1 \ No newline at end of file diff --git a/src/pages/auth/components/LoginStep2.tsx b/src/pages/auth/components/LoginStep2.tsx new file mode 100644 index 0000000..404820a --- /dev/null +++ b/src/pages/auth/components/LoginStep2.tsx @@ -0,0 +1,125 @@ +import { type FC } from 'react' +import { useTranslation } from 'react-i18next' +import { type OtpVerifyType } from '../types/AuthTypes' +import { useFormik } from 'formik' +import * as Yup from 'yup' +import { useAuthStore } from '../store/AuthStore' +import Button from '../../../components/Button' +import OTPInput from 'react-otp-input' +import { useCountDown } from '../../../hooks/useCountDown' +import { Pages } from '../../../config/Pages' +import { useOtpVerify } from '../hooks/useAuthData' +import { type ErrorType } from '../../../helpers/types' +import { toast } from 'react-toastify' +import { setToken, setRefreshToken } from '../../../config/func' + +const LoginStep2: FC = () => { + + const { t } = useTranslation('global') + const { phone, setStepLogin, slug } = useAuthStore() + const { value } = useCountDown(2, true) + const otpVerify = useOtpVerify() + + const formik = useFormik<{ otp: string }>({ + initialValues: { + otp: '' + }, + validationSchema: Yup.object({ + otp: Yup.string() + .required(t('errors.required')) + }), + onSubmit(values) { + const params: OtpVerifyType = { + phone: phone, + otp: values.otp, + slug: slug + } + otpVerify.mutate(params, { + onSuccess(data) { + setToken(data?.data?.tokens?.accessToken?.token) + setRefreshToken(data?.data?.tokens?.refreshToken?.token) + window.location.href = Pages.dashboard + }, + onError(error: ErrorType) { + toast.error(error?.response?.data?.error?.message[0]) + }, + }) + }, + }) + + return ( +
+
+

+ {t('auth.enter_otp')} +

+

+

+
{t('auth.verfify_code_text_1')}
+
{phone}
+
+ {t('auth.verfify_code_text_2')} +
+
+
setStepLogin(1)} className='text-black cursor-pointer'> + {t('auth.change_number')} +
+

+
+ +
+
+ {t('auth.verify_code')} +
+
+ formik.setFieldValue('otp', otp)} + renderInput={(props) => + + } + /> +
+ + { + formik.touched.otp && formik.errors.otp && +
{formik.errors.otp}
+ } + +
+
+
{value}
+
{t('auth.counter_otp')}
+
+
+ +
+ + +
+ ) +} + +export default LoginStep2 \ No newline at end of file diff --git a/src/pages/auth/components/LoginStep3.tsx b/src/pages/auth/components/LoginStep3.tsx new file mode 100644 index 0000000..b3f96b3 --- /dev/null +++ b/src/pages/auth/components/LoginStep3.tsx @@ -0,0 +1,101 @@ +import { type FC } from 'react' +import Input from '../../../components/Input' +import { useTranslation } from 'react-i18next' +import { type LoginWithPasswordType } from '../types/AuthTypes' +import { useFormik } from 'formik' +import * as Yup from 'yup' +import { useAuthStore } from '../store/AuthStore' +import Error from '../../../components/Error' +import Button from '../../../components/Button' +import { Link } from 'react-router-dom' +import { Pages } from '../../../config/Pages' +import ArrowLeftIcon from '../../../assets/images/arrow-left.svg' +import { useLoginWithPassword } from '../hooks/useAuthData' +import { toast } from 'react-toastify' +import { type ErrorType } from '../../../helpers/types' +import { setRefreshToken } from '../../../config/func' +import { setToken } from '../../../config/func' + +const LoginStep3: FC = () => { + + const { t } = useTranslation('global') + const { setStepLogin, email } = useAuthStore() + const loginWithPassword = useLoginWithPassword() + + const formik = useFormik({ + initialValues: { + password: '', + email: email + }, + validationSchema: Yup.object({ + password: Yup.string() + .required(t('errors.required')) + }), + onSubmit(values) { + loginWithPassword.mutate(values, { + onSuccess(data) { + setToken(data?.data?.accessToken?.token) + setRefreshToken(data?.data?.refreshToken?.token) + window.location.href = Pages.dashboard + }, + onError(error: ErrorType) { + toast.error(error?.response?.data?.error?.message[0]) + }, + }) + + }, + }) + + return ( +
+
+

+ {t('auth.enter_password_step3')} +

+

+ {t('auth.enter_your_password')} +

+
+ +
+ + + { + formik.touched.password && formik.errors.password && + + } + +
+ +
+ {t('auth.forgot_password')} +
+ + +
+ ) +} + +export default LoginStep3 \ No newline at end of file diff --git a/src/pages/auth/components/RegisterStep1.tsx b/src/pages/auth/components/RegisterStep1.tsx new file mode 100644 index 0000000..dacb5d9 --- /dev/null +++ b/src/pages/auth/components/RegisterStep1.tsx @@ -0,0 +1,77 @@ +import { type FC } from 'react' +import Input from '../../../components/Input' +import { useTranslation } from 'react-i18next' +import { type CheckHasAccountPhoneType } from '../types/AuthTypes' +import { useFormik } from 'formik' +import * as Yup from 'yup' +import { useAuthStore } from '../store/AuthStore' +import Error from '../../../components/Error' +import Button from '../../../components/Button' +import { useCheckHasAccountRegister, useLoginWithOtp } from '../hooks/useAuthData' +import { toast } from 'react-toastify' +import { type ErrorType } from '../../../helpers/types' + +const RegisterStep1: FC = () => { + + const { t } = useTranslation('global') + const { setPhone, setStepLogin } = useAuthStore() + const loginWithOtp = useLoginWithOtp() + const checkHasAccount = useCheckHasAccountRegister() + + const formik = useFormik({ + initialValues: { + phone: '', + }, + validationSchema: Yup.object({ + phone: Yup.string() + .required(t('errors.required')) + }), + onSubmit(values) { + checkHasAccount.mutate(values, { + onSuccess() { + setPhone(values.phone) + setStepLogin(2) + }, + onError(error: ErrorType) { + toast.error(error?.response?.data?.error?.message[0]) + }, + }) + }, + }) + + return ( +
+ + +
+ + + { + formik.touched.phone && formik.errors.phone && + + } + +
+ + +
+ ) +} + +export default RegisterStep1 \ No newline at end of file diff --git a/src/pages/auth/hooks/useAuthData.tsx b/src/pages/auth/hooks/useAuthData.tsx new file mode 100644 index 0000000..0eb0d53 --- /dev/null +++ b/src/pages/auth/hooks/useAuthData.tsx @@ -0,0 +1,39 @@ +import { useMutation } from '@tanstack/react-query'; +import * as api from '../service/AuthService' +import type { CheckHasAccountPhoneType, CheckHasAccountType, LoginWithOtpType, LoginWithOtpResponse, LoginWithPasswordType, OtpVerifyType, RegisterType } from '../types/AuthTypes'; + +export const useLoginWithPassword = () => { + return useMutation({ + mutationFn: (variables: LoginWithPasswordType) => api.loginWithPassword(variables), + }); +}; + +export const useLoginWithOtp = () => { + return useMutation({ + mutationFn: (variables: LoginWithOtpType) => api.loginWithOtp(variables), + }); +}; + +export const useOtpVerify = () => { + return useMutation({ + mutationFn: (variables: OtpVerifyType) => api.otpVerify(variables), + }); +}; + +export const useCheckHasAccount = () => { + return useMutation({ + mutationFn: (variables: CheckHasAccountType) => api.checkHasAccount(variables), + }); +}; + +export const useCheckHasAccountRegister = () => { + return useMutation({ + mutationFn: (variables: CheckHasAccountPhoneType) => api.checkHasAccountRegister(variables), + }); +}; + +export const useRegister = () => { + return useMutation({ + mutationFn: (variables: RegisterType) => api.register(variables), + }); +}; \ No newline at end of file diff --git a/src/pages/auth/service/AuthService.ts b/src/pages/auth/service/AuthService.ts new file mode 100644 index 0000000..350b3c3 --- /dev/null +++ b/src/pages/auth/service/AuthService.ts @@ -0,0 +1,57 @@ +import axios from "../../../config/axios"; +import { + type CheckHasAccountPhoneType, + type CheckHasAccountType, + type LoginWithOtpType, + type LoginWithOtpResponse, + type LoginWithPasswordType, + type OtpVerifyType, + type RefreshTokenType, + type RefreshTokenResponse, + type RegisterType, +} from "../types/AuthTypes"; + +export const loginWithPassword = async (params: LoginWithPasswordType) => { + const { data } = await axios.post(`/auth/login/password/admin`, params); + return data; +}; + +export const loginWithOtp = async ( + params: LoginWithOtpType +): Promise => { + const { data } = await axios.post( + `/admin/auth/otp/request`, + params + ); + return data; +}; + +export const otpVerify = async (params: OtpVerifyType) => { + const { data } = await axios.post(`/admin/auth/otp/verify`, params); + return data; +}; +export const checkHasAccount = async (params: CheckHasAccountType) => { + const { data } = await axios.post(`/auth/check`, params); + return data; +}; + +export const checkHasAccountRegister = async ( + params: CheckHasAccountPhoneType +) => { + const { data } = await axios.post(`/auth/register/initiate`, params); + return data; +}; +export const register = async (params: RegisterType) => { + const { data } = await axios.post(`/auth/register/complete`, params); + return data; +}; + +export const refreshToken = async ( + params: RefreshTokenType +): Promise => { + const { data } = await axios.post( + `/admin/auth/refresh`, + params + ); + return data; +}; diff --git a/src/pages/auth/store/AuthStore.ts b/src/pages/auth/store/AuthStore.ts new file mode 100644 index 0000000..8337433 --- /dev/null +++ b/src/pages/auth/store/AuthStore.ts @@ -0,0 +1,25 @@ +import { create } from "zustand"; +import { type AuthStoreType } from "../../auth/types/AuthTypes"; + +export const useAuthStore = create((set) => ({ + phone: "", + slug: "", + setSlug(value) { + set({ slug: value }); + }, + setPhone(value) { + set({ phone: value }); + }, + email: "", + setEmail(value) { + set({ email: value }); + }, + stepLogin: 1, + setStepLogin(value) { + set({ stepLogin: value }); + }, + otp: "", + setOtp(value) { + set({ otp: value }); + }, +})); diff --git a/src/pages/auth/types/AuthTypes.ts b/src/pages/auth/types/AuthTypes.ts new file mode 100644 index 0000000..5204cd6 --- /dev/null +++ b/src/pages/auth/types/AuthTypes.ts @@ -0,0 +1,84 @@ +import { type XOR } from "../../../helpers/types"; +import { type IResponse } from "../../../types/response.types"; + +export type LoginType = { + phone_email: string; +}; +export type LoginPasswordType = { + password: string; +}; + +export type AuthStoreType = { + phone: string; + slug: string; + setSlug: (value: string) => void; + setPhone: (value: string) => void; + email: string; + setEmail: (value: string) => void; + stepLogin: number; + setStepLogin: (value: number) => void; + otp: string; + setOtp: (value: string) => void; +}; + +export type LoginWithPasswordType = XOR< + { email: string }, + { phone: number } +> & { + password: string; +}; + +export type LoginWithOtpType = { + phone: string; + slug: string; +}; + +export type OtpVerifyType = { + phone: string; + otp: string; + slug: string; +}; + +export type CheckHasAccountType = { + email: string; +}; + +export type CheckHasAccountPhoneType = { + phone: string; +}; + +export type RegisterType = { + phone: string; + firstName: string; + lastName: string; + birthDate: string; + nationalCode: string; + password: string; + code: number; +}; +export type RefreshTokenType = { + refreshToken: string; +}; + +export type AccessToken = { + token: string; + expire: number; +}; + +export type RefreshToken = { + token: string; + expire: number; +}; + +export type RefreshTokenResponseData = { + accessToken: AccessToken; + refreshToken: RefreshToken; +}; + +export type RefreshTokenResponse = IResponse; + +export type LoginWithOtpResponseData = { + code: string; +}; + +export type LoginWithOtpResponse = IResponse; diff --git a/src/pages/comments/Details.tsx b/src/pages/comments/Details.tsx new file mode 100644 index 0000000..7009dc9 --- /dev/null +++ b/src/pages/comments/Details.tsx @@ -0,0 +1,175 @@ +import { type FC, useState } from 'react' +import Button from '@/components/Button' +import Switch from '@/components/Switch' +import Input from '@/components/Input' +import { Checkbox } from '@/components/ui/checkbox' +import { TickCircle } from 'iconsax-react' + +const CommentsDetails: FC = () => { + const [isActive, setIsActive] = useState(true) + const [foodSearch, setFoodSearch] = useState('') + const [categorySearch, setCategorySearch] = useState('') + const [selectedFoods, setSelectedFoods] = useState([]) + const [selectedCategories, setSelectedCategories] = useState([]) + + const allFoods = ['پیتزا پپرونی', 'سالاد سزار', 'پاستا', 'همبرگر', 'سوشی'] + const allCategories = ['پیش غذا', 'غذای اصلی', 'دسر', 'نوشیدنی', 'سالاد'] + + const foods = ['همه', ...allFoods] + const categories = ['همه', ...allCategories] + + const filteredFoods = foods.filter(food => { + if (food === 'همه') return true + if (!foodSearch.trim()) return true + return food.includes(foodSearch) + }) + + const filteredCategories = categories.filter(category => { + if (category === 'همه') return true + if (!categorySearch.trim()) return true + return category.includes(categorySearch) + }) + + const handleFoodToggle = (food: string) => { + if (food === 'همه') { + setSelectedFoods(allFoods.length === selectedFoods.length ? [] : allFoods) + } else { + setSelectedFoods(prev => + prev.includes(food) ? prev.filter(f => f !== food) : [...prev, food] + ) + } + } + + const handleCategoryToggle = (category: string) => { + if (category === 'همه') { + setSelectedCategories(allCategories.length === selectedCategories.length ? [] : allCategories) + } else { + setSelectedCategories(prev => + prev.includes(category) ? prev.filter(c => c !== category) : [...prev, category] + ) + } + } + + const commentNumber = '۱۲۳۴۵' + + return ( +
+ +
+

نظر {commentNumber}#

+ +
+
+ {/* Main Content */} +
+ + +
+
+ + + +
+ + + +
+ + +
+ +

+ لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ، و با استفاده از طراحان گرافیک است، چاپگرها و متون بلکه روزنامه و مجله در ستون و سطرآنچنان که لازم است، و برای شرایط فعلی تکنولوژی مورد نیاز، و کاربردهای متنوع با هدف بهبود ابزارهای کاربردی می‌باشد، کتابهای زیادی در شصت و سه درصد گذشته حال و آینده، شناخت فراوان جامعه و متخصصان را می‌طلبد، تا با نرم افزارها شناخت بیشتری را برای طراحان رایانه‌ای علی الخصوص طراحان خلاقی، و فرهنگ پیشرو در زبان فارسی ایجاد کرد، در این صورت می‌توان امید داشت که تمام و دشواری موجود در ارائه راهکارها، و شرایط سخت تایپ به پایان رسد و زمان مورد نیاز شامل حروفچینی دستاوردهای اصلی، و جوابگوی سوالات پیوسته اهل دنیای موجود طراحی اساسا مورد استفاده قرار گیرد +

+
+
+ + {/* Sidebar */} +
+ +
+ فعال + +
+ +
+
وضعیت نمایش
+ +
+
نمایش در غذاهای
+ setFoodSearch(e.target.value)} + className='mb-3' + /> +
+ {filteredFoods.map((food, index) => ( +
+ handleFoodToggle(food)} + /> + +
+ ))} +
+
+ +
+
نمایش در دسته بندی های
+ setCategorySearch(e.target.value)} + className='mb-3' + /> +
+ {filteredCategories.map((category, index) => ( +
+ handleCategoryToggle(category)} + /> + +
+ ))} +
+
+
+
+
+
+ ) +} + +export default CommentsDetails \ No newline at end of file diff --git a/src/pages/comments/List.tsx b/src/pages/comments/List.tsx new file mode 100644 index 0000000..8358e57 --- /dev/null +++ b/src/pages/comments/List.tsx @@ -0,0 +1,212 @@ +import { type FC, useState } from 'react' +import Table from '@/components/Table' +import Filters from '@/components/Filters' +import Switch from '@/components/Switch' +import { Eye } from 'iconsax-react' +import type { RowDataType, ActionType } from '@/components/types/TableTypes' +import type { FilterValues } from '@/components/Filters' +import { Link } from 'react-router-dom' +import { Pages } from '@/config/Pages' +import { formatOptionalDate } from '@/helpers/func' + +interface CommentData extends RowDataType { + id: number + number: string + customerName: string + strengths: string + weaknesses: string + food: string + date: string + isDisplayed: boolean +} + +const CommentsList: FC = () => { + const [currentPage, setCurrentPage] = useState(1) + const totalPages = 2 + + const handlePageChange = (page: number) => { + setCurrentPage(page) + } + + const handleFiltersChange = (newFilters: FilterValues) => { + console.log('فیلترها:', newFilters) + } + + const handleRowActions = (item: CommentData): ActionType[] => { + return [ + { + label: 'ویرایش', + onClick: () => { + console.log('ویرایش کامنت:', item.id) + }, + }, + { + label: 'حذف', + onClick: () => { + console.log('حذف کامنت:', item.id) + }, + }, + ] + } + + const handleDisplayToggle = (item: CommentData, value: boolean) => { + console.log('تغییر وضعیت نمایش کامنت:', item.id, value) + } + + const columns = [ + { + key: 'number', + title: 'شماره', + }, + { + key: 'customerName', + title: 'نام و نام خانوادگی', + }, + { + key: 'strengths', + title: 'نقاط قوت', + }, + { + key: 'weaknesses', + title: 'نقاط ضعف', + }, + { + key: 'food', + title: 'غذا', + }, + { + key: 'date', + title: 'تاریخ', + render: (item: CommentData) => { + return {formatOptionalDate(item.date)} + }, + }, + { + key: 'isDisplayed', + title: 'نمایش', + render: (item: CommentData) => { + return ( + handleDisplayToggle(item, value)} + /> + ) + }, + }, + { + key: 'details', + title: 'جزییات', + render: (item: CommentData) => { + return ( + + + + ) + }, + }, + ] + + const data: CommentData[] = [ + { + id: 1, + number: '۱۲۳۳۴', + customerName: 'حمید ضرغامی', + strengths: 'بهداشت محیطی خوب', + weaknesses: 'تنوع کم و محدود', + food: 'سالاد سزار ، پیتزا پیرونی', + date: '2024-11-01', + isDisplayed: true, + }, + { + id: 2, + number: '۱۲۳۳۵', + customerName: 'محمد رضایی', + strengths: 'طعم عالی', + weaknesses: 'زمان تحویل طولانی', + food: 'برگر کلاسیک', + date: '2024-11-02', + isDisplayed: false, + }, + { + id: 3, + number: '۱۲۳۳۶', + customerName: 'فاطمه احمدی', + strengths: 'بسته‌بندی مناسب', + weaknesses: 'گران قیمت', + food: 'سوشی مخصوص', + date: '2024-11-03', + isDisplayed: true, + }, + { + id: 4, + number: '۱۲۳۳۷', + customerName: 'علی کریمی', + strengths: 'سرویس سریع', + weaknesses: 'کم بودن حجم غذا', + food: 'پاستا کربونارا', + date: '2024-11-04', + isDisplayed: true, + }, + { + id: 5, + number: '۱۲۳۳۸', + customerName: 'زهرا محمودی', + strengths: 'کیفیت بالا', + weaknesses: 'محدودیت در انتخاب', + food: 'استیک گوشت', + date: '2024-11-05', + isDisplayed: false, + }, + { + id: 6, + number: '۱۲۳۳۹', + customerName: 'حسن نوری', + strengths: 'ارزش غذایی مناسب', + weaknesses: 'بوی نامطبوع', + food: 'کباب ترکی', + date: '2024-11-06', + isDisplayed: true, + }, + ] + + return ( +
+
+

لیست کامنت‌ها

+
+ +
+ +
+ + + + ) +} + +export default CommentsList \ No newline at end of file diff --git a/src/pages/coupon/Create.tsx b/src/pages/coupon/Create.tsx new file mode 100644 index 0000000..a055e68 --- /dev/null +++ b/src/pages/coupon/Create.tsx @@ -0,0 +1,130 @@ +import { type FC, useState, useMemo } from 'react' +import { useFormik } from 'formik' +import * as Yup from 'yup' +import { TickCircle } from 'iconsax-react' +import { toast } from 'react-toastify' +import { useNavigate } from 'react-router-dom' +import Button from '@/components/Button' +import type { CreateCouponType } from './types/Types' +import { useCreateCoupon } from './hooks/useCouponData' +import { useGetCategories } from '@/pages/food/hooks/useFoodData' +import { useGetFoods } from '@/pages/food/hooks/useFoodData' +import { Pages } from '@/config/Pages' +import type { ErrorType } from '@/helpers/types' +import { extractErrorMessage } from '@/config/func' +import CouponBasicInfo from './components/CouponBasicInfo' +import CouponDiscountSettings from './components/CouponDiscountSettings' +import CouponUsageSettings from './components/CouponUsageSettings' +import CouponSidebar from './components/CouponSidebar' + +const CreateCoupon: FC = () => { + const navigate = useNavigate() + const { mutate: createCoupon, isPending: isCreating } = useCreateCoupon() + const { data: categoriesData } = useGetCategories() + const { data: foodsData } = useGetFoods() + + const [couponType, setCouponType] = useState<'PERCENTAGE' | 'FIXED'>('PERCENTAGE') + + const categories = useMemo(() => categoriesData?.data || [], [categoriesData?.data]) + const foods = useMemo(() => foodsData?.data || [], [foodsData?.data]) + + const formik = useFormik({ + initialValues: { + code: '', + name: '', + description: '', + value: 0, + maxDiscount: null, + minOrderAmount: 0, + maxUses: 0, + maxUsesPerUser: null, + startDate: null, + endDate: null, + isActive: true, + foodCategories: [], + foods: [], + userPhone: '', + type: 'PERCENTAGE', + }, + validationSchema: Yup.object().shape({ + type: Yup.string().required('نوع کوپن الزامی است'), + code: Yup.string().required('کد کوپن الزامی است'), + name: Yup.string().required('نام کوپن الزامی است'), + description: Yup.string(), + value: Yup.number().min(0, 'مقدار باید بیشتر از صفر باشد').required('مقدار کوپن الزامی است'), + maxDiscount: Yup.number().nullable().min(0, 'حداکثر تخفیف باید بیشتر از صفر باشد'), + minOrderAmount: Yup.number().min(0, 'حداقل مبلغ سفارش باید بیشتر از صفر باشد').required('حداقل مبلغ سفارش الزامی است'), + maxUses: Yup.number().min(0, 'حداکثر استفاده باید بیشتر از صفر باشد').required('حداکثر استفاده الزامی است'), + maxUsesPerUser: Yup.number().nullable().min(0, 'حداکثر استفاده برای هر کاربر باید بیشتر از صفر باشد'), + startDate: Yup.string().nullable(), + endDate: Yup.string().nullable(), + userPhone: Yup.string().nullable(), + }), + onSubmit: (values) => { + const submitValues = { + ...values, + userPhone: values.userPhone?.trim() || undefined, + } + createCoupon(submitValues, { + onSuccess: () => { + toast.success('کوپن با موفقیت ایجاد شد') + navigate(Pages.coupons.list) + }, + onError: (error: ErrorType) => { + toast.error(extractErrorMessage(error)) + }, + }) + }, + }) + + return ( +
+
+

کد تخفیف جدید

+
+ +
+ +
+ +
+
+
+
کد تخفیف جدید
+ + + + + + +
+
+ +
+ +
+
+
+ ) +} + +export default CreateCoupon diff --git a/src/pages/coupon/List.tsx b/src/pages/coupon/List.tsx new file mode 100644 index 0000000..5663731 --- /dev/null +++ b/src/pages/coupon/List.tsx @@ -0,0 +1,103 @@ +import { type FC, useMemo } from 'react' +import Table from '@/components/Table' +import Filters from '@/components/Filters' +import { useGetCoupons, useDeleteCoupon } from './hooks/useCouponData' +import { useCouponFilters } from './hooks/useCouponFilters' +import { getCouponTableColumns } from './components/CouponTableColumns' +import { useCouponFiltersFields } from './components/CouponFiltersFields' +import { Add } from 'iconsax-react' +import { Link } from 'react-router-dom' +import { Pages } from '@/config/Pages' +import Button from '@/components/Button' +import type { ICoupon } from './types/Types' +import type { RowDataType } from '@/components/types/TableTypes' + +const CouponsList: FC = () => { + const { + filters, + currentPage, + handleFiltersChange, + handlePageChange, + limit, + } = useCouponFilters() + + const { data: couponsData, isLoading } = useGetCoupons() + const { mutate: deleteCoupon, isPending: isDeleting } = useDeleteCoupon() + + const coupons = useMemo(() => couponsData?.data || [], [couponsData]) + + const filteredCoupons = useMemo(() => { + const searchValue = (filters.search as string || '').toLowerCase().trim() + const statusFilter = filters.status || 'all' + const typeFilter = filters.type || 'all' + + return coupons.filter((coupon: ICoupon) => { + const matchesSearch = + searchValue === '' || + (coupon.code || '').toLowerCase().includes(searchValue) || + (coupon.name || '').toLowerCase().includes(searchValue) + + const matchesStatus = + statusFilter === 'all' || + (statusFilter === 'active' && coupon.isActive) || + (statusFilter === 'inactive' && !coupon.isActive) + + const matchesType = + typeFilter === 'all' || + coupon.type === typeFilter + + return matchesSearch && matchesStatus && matchesType + }) + }, [coupons, filters]) + + const totalPages = Math.max(1, Math.ceil(filteredCoupons.length / limit) || 1) + + const paginatedCoupons = useMemo(() => { + const startIndex = (currentPage - 1) * limit + return filteredCoupons.slice(startIndex, startIndex + limit) + }, [filteredCoupons, currentPage, limit]) + + const columns = getCouponTableColumns({ + onDelete: (id: string) => deleteCoupon(id), + isDeleting + }) + const filterFields = useCouponFiltersFields() + + return ( +
+
+

لیست کوپن‌ها

+ + + +
+ +
+ +
+ + + columns={columns} + data={paginatedCoupons as (ICoupon & RowDataType)[]} + isloading={isLoading} + pagination={{ + currentPage, + totalPages, + onPageChange: handlePageChange, + }} + /> +
+ ) +} + +export default CouponsList \ No newline at end of file diff --git a/src/pages/coupon/Update.tsx b/src/pages/coupon/Update.tsx new file mode 100644 index 0000000..c745591 --- /dev/null +++ b/src/pages/coupon/Update.tsx @@ -0,0 +1,178 @@ +import { type FC, useState, useMemo, useEffect } from 'react' +import { useParams, useNavigate } from 'react-router-dom' +import { useFormik } from 'formik' +import * as Yup from 'yup' +import { TickCircle } from 'iconsax-react' +import { toast } from 'react-toastify' +import Button from '@/components/Button' +import type { CreateCouponType } from './types/Types' +import { useGetCouponDetails, useUpdateCoupon } from './hooks/useCouponData' +import { useGetCategories } from '@/pages/food/hooks/useFoodData' +import { useGetFoods } from '@/pages/food/hooks/useFoodData' +import { Pages } from '@/config/Pages' +import type { ErrorType } from '@/helpers/types' +import { extractErrorMessage } from '@/config/func' +import CouponBasicInfo from './components/CouponBasicInfo' +import CouponDiscountSettings from './components/CouponDiscountSettings' +import CouponUsageSettings from './components/CouponUsageSettings' +import CouponSidebar from './components/CouponSidebar' + +const UpdateCoupon: FC = () => { + const navigate = useNavigate() + const { id } = useParams<{ id: string }>() + const { data: couponData, isLoading } = useGetCouponDetails(id || '') + const { mutate: updateCoupon, isPending: isUpdating } = useUpdateCoupon() + const { data: categoriesData } = useGetCategories() + const { data: foodsData } = useGetFoods() + + const [couponType, setCouponType] = useState<'PERCENTAGE' | 'FIXED'>('PERCENTAGE') + + const categories = useMemo(() => categoriesData?.data || [], [categoriesData?.data]) + const foods = useMemo(() => foodsData?.data || [], [foodsData?.data]) + + const formik = useFormik({ + initialValues: { + code: '', + name: '', + description: '', + value: 0, + maxDiscount: null, + minOrderAmount: 0, + maxUses: 0, + maxUsesPerUser: null, + startDate: null, + endDate: null, + isActive: true, + foodCategories: [], + foods: [], + userPhone: '', + type: 'PERCENTAGE', + }, + validationSchema: Yup.object().shape({ + type: Yup.string().required('نوع کوپن الزامی است'), + code: Yup.string().required('کد کوپن الزامی است'), + name: Yup.string().required('نام کوپن الزامی است'), + description: Yup.string(), + value: Yup.number().min(0, 'مقدار باید بیشتر از صفر باشد').required('مقدار کوپن الزامی است'), + maxDiscount: Yup.number().nullable().min(0, 'حداکثر تخفیف باید بیشتر از صفر باشد'), + minOrderAmount: Yup.number().min(0, 'حداقل مبلغ سفارش باید بیشتر از صفر باشد').required('حداقل مبلغ سفارش الزامی است'), + maxUses: Yup.number().min(0, 'حداکثر استفاده باید بیشتر از صفر باشد').required('حداکثر استفاده الزامی است'), + maxUsesPerUser: Yup.number().nullable().min(0, 'حداکثر استفاده برای هر کاربر باید بیشتر از صفر باشد'), + startDate: Yup.string().nullable(), + endDate: Yup.string().nullable(), + userPhone: Yup.string().nullable(), + }), + enableReinitialize: true, + onSubmit: (values) => { + if (!id) { + toast.error('شناسه کوپن یافت نشد') + return + } + + const submitValues = { + ...values, + userPhone: values.userPhone?.trim() || undefined, + } + updateCoupon( + { id, params: submitValues }, + { + onSuccess: () => { + toast.success('کوپن با موفقیت به‌روزرسانی شد') + navigate(Pages.coupons.list) + }, + onError: (error: ErrorType) => { + toast.error(extractErrorMessage(error)) + }, + } + ) + }, + }) + + useEffect(() => { + if (couponData?.data) { + const coupon = couponData.data + setCouponType(coupon.type) + formik.setValues({ + code: coupon.code, + name: coupon.name, + description: coupon.description || '', + value: coupon.value, + maxDiscount: coupon.maxDiscount, + minOrderAmount: coupon.minOrderAmount, + maxUses: coupon.maxUses, + maxUsesPerUser: coupon.maxUsesPerUser, + startDate: coupon.startDate, + endDate: coupon.endDate, + isActive: coupon.isActive, + foodCategories: coupon.foodCategories || [], + foods: coupon.foods || [], + userPhone: coupon.userPhone || '', + type: coupon.type, + }) + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [couponData?.data]) + + if (isLoading) { + return ( +
+
در حال بارگذاری...
+
+ ) + } + + return ( +
+
+

ویرایش کد تخفیف

+
+ +
+ +
+ +
+
+
+
ویرایش کد تخفیف
+ + + + + + { + formik.values.startDate && ( + + ) + } +
+
+ +
+ +
+
+
+ ) +} + +export default UpdateCoupon \ No newline at end of file diff --git a/src/pages/coupon/components/CategorySelector.tsx b/src/pages/coupon/components/CategorySelector.tsx new file mode 100644 index 0000000..1166824 --- /dev/null +++ b/src/pages/coupon/components/CategorySelector.tsx @@ -0,0 +1,86 @@ +import { type FC, useState, useMemo } from 'react' +import type { FormikProps } from 'formik' +import Input from '@/components/Input' +import { Checkbox } from '@/components/ui/checkbox' +import type { CreateCouponType } from '../types/Types' + +interface Category { + id: string + title: string +} + +interface CategorySelectorProps { + formik: FormikProps + categories: Category[] +} + +const CategorySelector: FC = ({ formik, categories }) => { + const [search, setSearch] = useState('') + + const filteredCategories = useMemo(() => { + if (!search) return categories + return categories.filter((cat) => + cat.title.toLowerCase().includes(search.toLowerCase()) + ) + }, [categories, search]) + + const handleToggle = (categoryId: string, checked: boolean) => { + const currentIds = formik.values.foodCategories || [] + if (checked) { + formik.setFieldValue('foodCategories', [...currentIds, categoryId]) + } else { + formik.setFieldValue('foodCategories', currentIds.filter((id) => id !== categoryId)) + } + } + + const handleSelectAll = (checked: boolean) => { + if (checked) { + formik.setFieldValue('foodCategories', filteredCategories.map((cat) => cat.id)) + } else { + formik.setFieldValue('foodCategories', []) + } + } + + const isAllSelected = useMemo(() => { + return filteredCategories.length > 0 && + filteredCategories.every((cat) => formik.values.foodCategories?.includes(cat.id)) + }, [filteredCategories, formik.values.foodCategories]) + + return ( +
+
دسته بندیهایی که شامل تخفیف میشوند
+
+ setSearch(e.target.value)} + /> +
+
+ + +
+ {filteredCategories.map((category) => ( +
+ + handleToggle(category.id, checked as boolean) + } + /> + +
+ ))} +
+
+
+ ) +} + +export default CategorySelector + diff --git a/src/pages/coupon/components/CouponBasicInfo.tsx b/src/pages/coupon/components/CouponBasicInfo.tsx new file mode 100644 index 0000000..a6df2ca --- /dev/null +++ b/src/pages/coupon/components/CouponBasicInfo.tsx @@ -0,0 +1,90 @@ +import { type FC } from 'react' +import { Refresh } from 'iconsax-react' +import type { FormikProps } from 'formik' +import Input from '@/components/Input' +import Textarea from '@/components/Textarea' +import Button from '@/components/Button' +import type { CreateCouponType } from '../types/Types' +import { useGenerateCouponCode } from '../hooks/useCouponData' +import { extractErrorMessage } from '@/config/func' +import { toast } from 'react-toastify' + +interface CouponBasicInfoProps { + formik: FormikProps +} + +const CouponBasicInfo: FC = ({ + formik, +}) => { + + const { mutate: generateCouponCode, isPending: isGenerating } = useGenerateCouponCode() + + const handleGenerateCode = () => { + generateCouponCode(undefined, { + onSuccess: (data) => { + formik.setFieldValue('code', data.data) + + }, + onError: (error) => { + toast.error(extractErrorMessage(error)) + } + }) + } + + return ( + <> +
+
+
+ +
+
+
+ +
+