diff --git a/fdev-ffrontend/.env.development b/fdev-ffrontend/.env.development
deleted file mode 100644
index b44b7f8f..00000000
--- a/fdev-ffrontend/.env.development
+++ /dev/null
@@ -1,23 +0,0 @@
-# API Configuration
-VITE_API_URL=http://localhost:8000/api/v1
-VITE_API_TIMEOUT=30000
-VITE_API_RETRIES=3
-VITE_API_RETRY_DELAY=1000
-VITE_API_LOGGING=true
-VITE_API_CACHING=true
-VITE_API_CACHE_TIMEOUT=300000
-
-# Feature Flags
-VITE_ENABLE_WEBSOCKETS=false
-VITE_ENABLE_OFFLINE=false
-VITE_ENABLE_OPTIMISTIC_UPDATES=true
-VITE_ENABLE_DEDUPLICATION=true
-VITE_ENABLE_METRICS=false
-
-# Stripe Configuration (Spanish Market)
-VITE_STRIPE_PUBLISHABLE_KEY=pk_test_example_key_for_development
-VITE_STRIPE_WEBHOOK_SECRET=whsec_example_webhook_secret_for_development
-
-# Development Flags
-VITE_BYPASS_PAYMENT=true
-VITE_DEV_MODE=true
\ No newline at end of file
diff --git a/fdev-ffrontend/.env.production b/fdev-ffrontend/.env.production
deleted file mode 100644
index f6bda9e6..00000000
--- a/fdev-ffrontend/.env.production
+++ /dev/null
@@ -1,23 +0,0 @@
-# API Configuration
-VITE_API_URL=https://api.pania.es/api/v1
-VITE_API_TIMEOUT=30000
-VITE_API_RETRIES=3
-VITE_API_RETRY_DELAY=1000
-VITE_API_LOGGING=false
-VITE_API_CACHING=true
-VITE_API_CACHE_TIMEOUT=300000
-
-# Feature Flags
-VITE_ENABLE_WEBSOCKETS=true
-VITE_ENABLE_OFFLINE=true
-VITE_ENABLE_OPTIMISTIC_UPDATES=true
-VITE_ENABLE_DEDUPLICATION=true
-VITE_ENABLE_METRICS=true
-
-# Stripe Configuration (Spanish Market)
-VITE_STRIPE_PUBLISHABLE_KEY=pk_live_your_production_stripe_key
-VITE_STRIPE_WEBHOOK_SECRET=whsec_your_production_webhook_secret
-
-# Development Flags (DISABLED IN PRODUCTION)
-VITE_BYPASS_PAYMENT=false
-VITE_DEV_MODE=false
\ No newline at end of file
diff --git a/fdev-ffrontend/Dockerfile.development b/fdev-ffrontend/Dockerfile.development
deleted file mode 100644
index 6069bda8..00000000
--- a/fdev-ffrontend/Dockerfile.development
+++ /dev/null
@@ -1,38 +0,0 @@
-# frontend/Dockerfile.development - FIXED VERSION
-FROM node:18-alpine
-
-# Install curl for healthchecks
-RUN apk add --no-cache curl
-
-# Set working directory
-WORKDIR /app
-
-# Create non-root user for security but don't switch yet
-RUN addgroup -g 1001 -S nodejs && \
- adduser -S reactjs -u 1001 -G nodejs
-
-# Copy package files first (better caching)
-COPY package*.json ./
-
-# Install all dependencies (including dev dependencies) as root
-RUN npm ci --verbose && \
- npm cache clean --force
-
-# Copy source code
-COPY . .
-
-# Change ownership of all files to the non-root user
-RUN chown -R reactjs:nodejs /app
-
-# Now switch to non-root user
-USER reactjs
-
-# Expose port 3000 (Vite default)
-EXPOSE 3000
-
-# Add healthcheck
-HEALTHCHECK --interval=30s --timeout=10s --start-period=30s --retries=3 \
- CMD curl -f http://localhost:3000/ || exit 1
-
-# Start development server with host binding
-CMD ["npm", "run", "dev", "--", "--host", "0.0.0.0"]
\ No newline at end of file
diff --git a/fdev-ffrontend/Dockerfile.production b/fdev-ffrontend/Dockerfile.production
deleted file mode 100644
index 98ba917c..00000000
--- a/fdev-ffrontend/Dockerfile.production
+++ /dev/null
@@ -1,41 +0,0 @@
-# frontend/Dockerfile.production
-# Multi-stage build for production
-
-# Build stage
-FROM node:18-alpine as builder
-
-WORKDIR /app
-
-# Copy package files
-COPY package*.json ./
-
-# Install dependencies
-RUN npm ci --only=production
-
-# Copy source code
-COPY . .
-
-# Build the application
-RUN npm run build
-
-# Production stage
-FROM nginx:alpine
-
-# Install curl for healthchecks
-RUN apk add --no-cache curl
-
-# Copy built app from builder stage
-COPY --from=builder /app/dist /usr/share/nginx/html
-
-# Copy nginx configuration
-COPY nginx.conf /etc/nginx/nginx.conf
-
-# Expose port 80
-EXPOSE 80
-
-# Add healthcheck
-HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \
- CMD curl -f http://localhost/ || exit 1
-
-# Start nginx
-CMD ["nginx", "-g", "daemon off;"]
\ No newline at end of file
diff --git a/fdev-ffrontend/index.html b/fdev-ffrontend/index.html
deleted file mode 100644
index 66ef8f1b..00000000
--- a/fdev-ffrontend/index.html
+++ /dev/null
@@ -1,170 +0,0 @@
-
-
-
-
-
-
-
- PanIA - Inteligencia Artificial para tu Panadería en Madrid
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
🥖
-
Cargando PanIA...
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/fdev-ffrontend/nginx.conf b/fdev-ffrontend/nginx.conf
deleted file mode 100644
index 149fec06..00000000
--- a/fdev-ffrontend/nginx.conf
+++ /dev/null
@@ -1,70 +0,0 @@
-# frontend/nginx.conf
-events {
- worker_connections 1024;
-}
-
-http {
- include /etc/nginx/mime.types;
- default_type application/octet-stream;
-
- # Enable gzip compression
- gzip on;
- gzip_vary on;
- gzip_min_length 1024;
- gzip_proxied any;
- gzip_comp_level 6;
- gzip_types
- text/plain
- text/css
- text/xml
- text/javascript
- application/json
- application/javascript
- application/xml+rss
- application/atom+xml
- image/svg+xml;
-
- server {
- listen 80;
- server_name localhost;
- root /usr/share/nginx/html;
- index index.html;
-
- # Security headers
- add_header X-Frame-Options "SAMEORIGIN" always;
- add_header X-Content-Type-Options "nosniff" always;
- add_header X-XSS-Protection "1; mode=block" always;
- add_header Referrer-Policy "strict-origin-when-cross-origin" always;
-
- # Handle React Router
- location / {
- try_files $uri $uri/ /index.html;
- }
-
- # API proxy to backend
- location /api/ {
- proxy_pass http://bakery-gateway:8000/api/;
- proxy_http_version 1.1;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection 'upgrade';
- proxy_set_header Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto $scheme;
- proxy_cache_bypass $http_upgrade;
- }
-
- # Cache static assets
- location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
- expires 1y;
- add_header Cache-Control "public, immutable";
- }
-
- # Health check endpoint
- location /health {
- access_log off;
- return 200 "healthy\n";
- add_header Content-Type text/plain;
- }
- }
-}
\ No newline at end of file
diff --git a/fdev-ffrontend/package-lock.json b/fdev-ffrontend/package-lock.json
deleted file mode 100644
index 52888e6f..00000000
--- a/fdev-ffrontend/package-lock.json
+++ /dev/null
@@ -1,7652 +0,0 @@
-{
- "name": "pania-frontend",
- "version": "1.0.0",
- "lockfileVersion": 3,
- "requires": true,
- "packages": {
- "": {
- "name": "pania-frontend",
- "version": "1.0.0",
- "license": "MIT",
- "dependencies": {
- "@hookform/resolvers": "^3.3.1",
- "@reduxjs/toolkit": "^1.9.5",
- "@stripe/react-stripe-js": "^3.9.0",
- "@stripe/stripe-js": "^7.8.0",
- "clsx": "^2.0.0",
- "date-fns": "^2.30.0",
- "date-fns-tz": "^2.0.0",
- "i18next": "^23.4.4",
- "i18next-browser-languagedetector": "^7.1.0",
- "lucide-react": "^0.263.1",
- "react": "^18.2.0",
- "react-dom": "^18.2.0",
- "react-hook-form": "^7.45.4",
- "react-hot-toast": "^2.4.1",
- "react-i18next": "^13.1.2",
- "react-redux": "^8.1.2",
- "react-router-dom": "^6.15.0",
- "recharts": "^2.8.0",
- "tailwind-merge": "^1.14.0",
- "zod": "^3.22.2"
- },
- "devDependencies": {
- "@tailwindcss/forms": "^0.5.4",
- "@tailwindcss/typography": "^0.5.9",
- "@testing-library/jest-dom": "^5.17.0",
- "@testing-library/react": "^13.4.0",
- "@testing-library/user-event": "^14.4.3",
- "@types/react": "^18.2.15",
- "@types/react-dom": "^18.2.7",
- "@typescript-eslint/eslint-plugin": "^6.0.0",
- "@typescript-eslint/parser": "^6.0.0",
- "@vitejs/plugin-react": "^4.0.3",
- "@vitest/ui": "^0.34.1",
- "autoprefixer": "^10.4.14",
- "eslint": "^8.45.0",
- "eslint-plugin-react-hooks": "^4.6.0",
- "eslint-plugin-react-refresh": "^0.4.3",
- "postcss": "^8.4.27",
- "tailwindcss": "^3.3.0",
- "typescript": "^5.0.2",
- "vite": "^4.4.5",
- "vitest": "^0.34.1"
- }
- },
- "node_modules/@adobe/css-tools": {
- "version": "4.4.3",
- "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.3.tgz",
- "integrity": "sha512-VQKMkwriZbaOgVCby1UDY/LDk5fIjhQicCvVPFqfe+69fWaPWydbWJ3wRt59/YzIwda1I81loas3oCoHxnqvdA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@alloc/quick-lru": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz",
- "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "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.0",
- "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.0.tgz",
- "integrity": "sha512-UlLAnTPrFdNGoFtbSXwcGFQBtQZJCNjaN6hQNP3UPvuNXT1i82N26KL3dZeIpNalWywr9IuQuncaAfUaS1g6sQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@ampproject/remapping": "^2.2.0",
- "@babel/code-frame": "^7.27.1",
- "@babel/generator": "^7.28.0",
- "@babel/helper-compilation-targets": "^7.27.2",
- "@babel/helper-module-transforms": "^7.27.3",
- "@babel/helpers": "^7.27.6",
- "@babel/parser": "^7.28.0",
- "@babel/template": "^7.27.2",
- "@babel/traverse": "^7.28.0",
- "@babel/types": "^7.28.0",
- "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/core/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/@babel/generator": {
- "version": "7.28.0",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.0.tgz",
- "integrity": "sha512-lJjzvrbEeWrhB4P3QBsH7tey117PjLZnDbLiQEKjQ/fNJTjuq4HSqgFA+UNSwZT8D7dxxbnuSBMsa1lrWzKlQg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/parser": "^7.28.0",
- "@babel/types": "^7.28.0",
- "@jridgewell/gen-mapping": "^0.3.12",
- "@jridgewell/trace-mapping": "^0.3.28",
- "jsesc": "^3.0.2"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-compilation-targets": {
- "version": "7.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-compilation-targets/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/@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.27.3",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.27.3.tgz",
- "integrity": "sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-module-imports": "^7.27.1",
- "@babel/helper-validator-identifier": "^7.27.1",
- "@babel/traverse": "^7.27.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.2",
- "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.2.tgz",
- "integrity": "sha512-/V9771t+EgXz62aCcyofnQhGM8DQACbRhvzKFsXKC9QM+5MadF8ZmIm0crDMaz3+o0h0zXfJnd4EhbYbxsrcFw==",
- "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.0",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.0.tgz",
- "integrity": "sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/types": "^7.28.0"
- },
- "bin": {
- "parser": "bin/babel-parser.js"
- },
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@babel/plugin-transform-react-jsx-self": {
- "version": "7.27.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz",
- "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.27.1"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-react-jsx-source": {
- "version": "7.27.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz",
- "integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.27.1"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/runtime": {
- "version": "7.28.2",
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.2.tgz",
- "integrity": "sha512-KHp2IflsnGywDjBWDkR9iEqiWSpc8GIi0lgTT3mOElT0PP1tG26P4tmFI2YvAdzgq9RGyoHZQEIEdZy6Ec5xCA==",
- "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.0",
- "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.0.tgz",
- "integrity": "sha512-mGe7UK5wWyh0bKRfupsUchrQGqvDbZDbKJw+kcRGSmdHVYrv+ltd0pnpDTVpiTqnaBru9iEvA8pz8W46v0Amwg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/code-frame": "^7.27.1",
- "@babel/generator": "^7.28.0",
- "@babel/helper-globals": "^7.28.0",
- "@babel/parser": "^7.28.0",
- "@babel/template": "^7.27.2",
- "@babel/types": "^7.28.0",
- "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/android-arm": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz",
- "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/android-arm64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz",
- "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/android-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz",
- "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/darwin-arm64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz",
- "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/darwin-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz",
- "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/freebsd-arm64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz",
- "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/freebsd-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz",
- "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/linux-arm": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz",
- "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/linux-arm64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz",
- "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/linux-ia32": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz",
- "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==",
- "cpu": [
- "ia32"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/linux-loong64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz",
- "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==",
- "cpu": [
- "loong64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/linux-mips64el": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz",
- "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==",
- "cpu": [
- "mips64el"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/linux-ppc64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz",
- "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==",
- "cpu": [
- "ppc64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/linux-riscv64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz",
- "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==",
- "cpu": [
- "riscv64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/linux-s390x": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz",
- "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==",
- "cpu": [
- "s390x"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/linux-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz",
- "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/netbsd-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz",
- "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "netbsd"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/openbsd-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz",
- "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "openbsd"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/sunos-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz",
- "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "sunos"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/win32-arm64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz",
- "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/win32-ia32": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz",
- "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==",
- "cpu": [
- "ia32"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/win32-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz",
- "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "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/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/eslintrc": {
- "version": "2.1.4",
- "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz",
- "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ajv": "^6.12.4",
- "debug": "^4.3.2",
- "espree": "^9.6.0",
- "globals": "^13.19.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": "^12.22.0 || ^14.17.0 || >=16.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/eslint"
- }
- },
- "node_modules/@eslint/eslintrc/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/@eslint/eslintrc/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/@eslint/js": {
- "version": "8.57.1",
- "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz",
- "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- }
- },
- "node_modules/@hookform/resolvers": {
- "version": "3.10.0",
- "resolved": "https://registry.npmjs.org/@hookform/resolvers/-/resolvers-3.10.0.tgz",
- "integrity": "sha512-79Dv+3mDF7i+2ajj7SkypSKHhl1cbln1OGavqrsF7p6mbUv11xpqpacPsGDCTRvCSjEEIez2ef1NveSVL3b0Ag==",
- "license": "MIT",
- "peerDependencies": {
- "react-hook-form": "^7.0.0"
- }
- },
- "node_modules/@humanwhocodes/config-array": {
- "version": "0.13.0",
- "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz",
- "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==",
- "deprecated": "Use @eslint/config-array instead",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "@humanwhocodes/object-schema": "^2.0.3",
- "debug": "^4.3.1",
- "minimatch": "^3.0.5"
- },
- "engines": {
- "node": ">=10.10.0"
- }
- },
- "node_modules/@humanwhocodes/config-array/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/@humanwhocodes/config-array/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/@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/object-schema": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz",
- "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==",
- "deprecated": "Use @eslint/object-schema instead",
- "dev": true,
- "license": "BSD-3-Clause"
- },
- "node_modules/@isaacs/cliui": {
- "version": "8.0.2",
- "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
- "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "string-width": "^5.1.2",
- "string-width-cjs": "npm:string-width@^4.2.0",
- "strip-ansi": "^7.0.1",
- "strip-ansi-cjs": "npm:strip-ansi@^6.0.1",
- "wrap-ansi": "^8.1.0",
- "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0"
- },
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@isaacs/cliui/node_modules/ansi-regex": {
- "version": "6.1.0",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz",
- "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-regex?sponsor=1"
- }
- },
- "node_modules/@isaacs/cliui/node_modules/strip-ansi": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
- "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ansi-regex": "^6.0.1"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/chalk/strip-ansi?sponsor=1"
- }
- },
- "node_modules/@jest/diff-sequences": {
- "version": "30.0.1",
- "resolved": "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.0.1.tgz",
- "integrity": "sha512-n5H8QLDJ47QqbCNn5SuFjCRDrOLEZ0h8vAHCK5RL9Ls7Xa8AQLa/YxAc9UjFqoEDM48muwtBGjtMY5cr0PLDCw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
- }
- },
- "node_modules/@jest/expect-utils": {
- "version": "30.0.5",
- "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-30.0.5.tgz",
- "integrity": "sha512-F3lmTT7CXWYywoVUGTCmom0vXq3HTTkaZyTAzIy+bXSBizB7o5qzlC9VCtq0arOa8GqmNsbg/cE9C6HLn7Szew==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/get-type": "30.0.1"
- },
- "engines": {
- "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
- }
- },
- "node_modules/@jest/get-type": {
- "version": "30.0.1",
- "resolved": "https://registry.npmjs.org/@jest/get-type/-/get-type-30.0.1.tgz",
- "integrity": "sha512-AyYdemXCptSRFirI5EPazNxyPwAL0jXt3zceFjaj8NFiKP9pOi0bfXonf6qkf82z2t3QWPeLCWWw4stPBzctLw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
- }
- },
- "node_modules/@jest/pattern": {
- "version": "30.0.1",
- "resolved": "https://registry.npmjs.org/@jest/pattern/-/pattern-30.0.1.tgz",
- "integrity": "sha512-gWp7NfQW27LaBQz3TITS8L7ZCQ0TLvtmI//4OwlQRx4rnWxcPNIYjxZpDcN4+UlGxgm3jS5QPz8IPTCkb59wZA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/node": "*",
- "jest-regex-util": "30.0.1"
- },
- "engines": {
- "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
- }
- },
- "node_modules/@jest/schemas": {
- "version": "30.0.5",
- "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz",
- "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@sinclair/typebox": "^0.34.0"
- },
- "engines": {
- "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
- }
- },
- "node_modules/@jest/types": {
- "version": "30.0.5",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.0.5.tgz",
- "integrity": "sha512-aREYa3aku9SSnea4aX6bhKn4bgv3AXkgijoQgbYV3yvbiGt6z+MQ85+6mIhx9DsKW2BuB/cLR/A+tcMThx+KLQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/pattern": "30.0.1",
- "@jest/schemas": "30.0.5",
- "@types/istanbul-lib-coverage": "^2.0.6",
- "@types/istanbul-reports": "^3.0.4",
- "@types/node": "*",
- "@types/yargs": "^17.0.33",
- "chalk": "^4.1.2"
- },
- "engines": {
- "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
- }
- },
- "node_modules/@jest/types/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/@jridgewell/gen-mapping": {
- "version": "0.3.12",
- "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.12.tgz",
- "integrity": "sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jridgewell/sourcemap-codec": "^1.5.0",
- "@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==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@jridgewell/sourcemap-codec": {
- "version": "1.5.4",
- "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.4.tgz",
- "integrity": "sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@jridgewell/trace-mapping": {
- "version": "0.3.29",
- "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.29.tgz",
- "integrity": "sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==",
- "dev": true,
- "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/@pkgjs/parseargs": {
- "version": "0.11.0",
- "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
- "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
- "dev": true,
- "license": "MIT",
- "optional": true,
- "engines": {
- "node": ">=14"
- }
- },
- "node_modules/@polka/url": {
- "version": "1.0.0-next.29",
- "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz",
- "integrity": "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@reduxjs/toolkit": {
- "version": "1.9.7",
- "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.9.7.tgz",
- "integrity": "sha512-t7v8ZPxhhKgOKtU+uyJT13lu4vL7az5aFi4IdoDs/eS548edn2M8Ik9h8fxgvMjGoAUVFSt6ZC1P5cWmQ014QQ==",
- "license": "MIT",
- "dependencies": {
- "immer": "^9.0.21",
- "redux": "^4.2.1",
- "redux-thunk": "^2.4.2",
- "reselect": "^4.1.8"
- },
- "peerDependencies": {
- "react": "^16.9.0 || ^17.0.0 || ^18",
- "react-redux": "^7.2.1 || ^8.0.2"
- },
- "peerDependenciesMeta": {
- "react": {
- "optional": true
- },
- "react-redux": {
- "optional": true
- }
- }
- },
- "node_modules/@remix-run/router": {
- "version": "1.23.0",
- "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.23.0.tgz",
- "integrity": "sha512-O3rHJzAQKamUz1fvE0Qaw0xSFqsA/yafi2iqeE0pvdFtCO1viYx8QL6f3Ln/aCCTLxs68SLf0KPM9eSeM8yBnA==",
- "license": "MIT",
- "engines": {
- "node": ">=14.0.0"
- }
- },
- "node_modules/@rolldown/pluginutils": {
- "version": "1.0.0-beta.27",
- "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.27.tgz",
- "integrity": "sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@sinclair/typebox": {
- "version": "0.34.38",
- "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.38.tgz",
- "integrity": "sha512-HpkxMmc2XmZKhvaKIZZThlHmx1L0I/V1hWK1NubtlFnr6ZqdiOpV72TKudZUNQjZNsyDBay72qFEhEvb+bcwcA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@stripe/react-stripe-js": {
- "version": "3.9.0",
- "resolved": "https://registry.npmjs.org/@stripe/react-stripe-js/-/react-stripe-js-3.9.0.tgz",
- "integrity": "sha512-pN1Re7zUc3m61FFQROok685g3zsBQRzCmZDmTzO8iPU6zhLvu2JnC0LrG0FCzSp6kgGa8AQSzq4rpFSgyhkjKg==",
- "license": "MIT",
- "dependencies": {
- "prop-types": "^15.7.2"
- },
- "peerDependencies": {
- "@stripe/stripe-js": ">=1.44.1 <8.0.0",
- "react": ">=16.8.0 <20.0.0",
- "react-dom": ">=16.8.0 <20.0.0"
- }
- },
- "node_modules/@stripe/stripe-js": {
- "version": "7.8.0",
- "resolved": "https://registry.npmjs.org/@stripe/stripe-js/-/stripe-js-7.8.0.tgz",
- "integrity": "sha512-DNXRfYUgkZlrniQORbA/wH8CdFRhiBSE0R56gYU0V5vvpJ9WZwvGrz9tBAZmfq2aTgw6SK7mNpmTizGzLWVezw==",
- "license": "MIT",
- "engines": {
- "node": ">=12.16"
- }
- },
- "node_modules/@tailwindcss/forms": {
- "version": "0.5.10",
- "resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.5.10.tgz",
- "integrity": "sha512-utI1ONF6uf/pPNO68kmN1b8rEwNXv3czukalo8VtJH8ksIkZXr3Q3VYudZLkCsDd4Wku120uF02hYK25XGPorw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "mini-svg-data-uri": "^1.2.3"
- },
- "peerDependencies": {
- "tailwindcss": ">=3.0.0 || >= 3.0.0-alpha.1 || >= 4.0.0-alpha.20 || >= 4.0.0-beta.1"
- }
- },
- "node_modules/@tailwindcss/typography": {
- "version": "0.5.16",
- "resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.16.tgz",
- "integrity": "sha512-0wDLwCVF5V3x3b1SGXPCDcdsbDHMBe+lkFzBRaHeLvNi+nrrnZ1lA18u+OTWO8iSWU2GxUOCvlXtDuqftc1oiA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "lodash.castarray": "^4.4.0",
- "lodash.isplainobject": "^4.0.6",
- "lodash.merge": "^4.6.2",
- "postcss-selector-parser": "6.0.10"
- },
- "peerDependencies": {
- "tailwindcss": ">=3.0.0 || insiders || >=4.0.0-alpha.20 || >=4.0.0-beta.1"
- }
- },
- "node_modules/@testing-library/dom": {
- "version": "10.4.1",
- "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.1.tgz",
- "integrity": "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==",
- "dev": true,
- "license": "MIT",
- "peer": true,
- "dependencies": {
- "@babel/code-frame": "^7.10.4",
- "@babel/runtime": "^7.12.5",
- "@types/aria-query": "^5.0.1",
- "aria-query": "5.3.0",
- "dom-accessibility-api": "^0.5.9",
- "lz-string": "^1.5.0",
- "picocolors": "1.1.1",
- "pretty-format": "^27.0.2"
- },
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@testing-library/jest-dom": {
- "version": "5.17.0",
- "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.17.0.tgz",
- "integrity": "sha512-ynmNeT7asXyH3aSVv4vvX4Rb+0qjOhdNHnO/3vuZNqPmhDpV/+rCSGwQ7bLcmU2cJ4dvoheIO85LQj0IbJHEtg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@adobe/css-tools": "^4.0.1",
- "@babel/runtime": "^7.9.2",
- "@types/testing-library__jest-dom": "^5.9.1",
- "aria-query": "^5.0.0",
- "chalk": "^3.0.0",
- "css.escape": "^1.5.1",
- "dom-accessibility-api": "^0.5.6",
- "lodash": "^4.17.15",
- "redent": "^3.0.0"
- },
- "engines": {
- "node": ">=8",
- "npm": ">=6",
- "yarn": ">=1"
- }
- },
- "node_modules/@testing-library/react": {
- "version": "13.4.0",
- "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-13.4.0.tgz",
- "integrity": "sha512-sXOGON+WNTh3MLE9rve97ftaZukN3oNf2KjDy7YTx6hcTO2uuLHuCGynMDhFwGw/jYf4OJ2Qk0i4i79qMNNkyw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/runtime": "^7.12.5",
- "@testing-library/dom": "^8.5.0",
- "@types/react-dom": "^18.0.0"
- },
- "engines": {
- "node": ">=12"
- },
- "peerDependencies": {
- "react": "^18.0.0",
- "react-dom": "^18.0.0"
- }
- },
- "node_modules/@testing-library/react/node_modules/@testing-library/dom": {
- "version": "8.20.1",
- "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.20.1.tgz",
- "integrity": "sha512-/DiOQ5xBxgdYRC8LNk7U+RWat0S3qRLeIw3ZIkMQ9kkVlRmwD/Eg8k8CqIpD6GW7u20JIUOfMKbxtiLutpjQ4g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/code-frame": "^7.10.4",
- "@babel/runtime": "^7.12.5",
- "@types/aria-query": "^5.0.1",
- "aria-query": "5.1.3",
- "chalk": "^4.1.0",
- "dom-accessibility-api": "^0.5.9",
- "lz-string": "^1.5.0",
- "pretty-format": "^27.0.2"
- },
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@testing-library/react/node_modules/aria-query": {
- "version": "5.1.3",
- "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz",
- "integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "deep-equal": "^2.0.5"
- }
- },
- "node_modules/@testing-library/react/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/@testing-library/user-event": {
- "version": "14.6.1",
- "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.6.1.tgz",
- "integrity": "sha512-vq7fv0rnt+QTXgPxr5Hjc210p6YKq2kmdziLgnsZGgLJ9e6VAShx1pACLuRjd/AS/sr7phAR58OIIpf0LlmQNw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=12",
- "npm": ">=6"
- },
- "peerDependencies": {
- "@testing-library/dom": ">=7.21.4"
- }
- },
- "node_modules/@types/aria-query": {
- "version": "5.0.4",
- "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz",
- "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==",
- "dev": true,
- "license": "MIT"
- },
- "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/chai": {
- "version": "4.3.20",
- "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.20.tgz",
- "integrity": "sha512-/pC9HAB5I/xMlc5FP77qjCnI16ChlJfW0tGa0IUcFn38VJrTV6DeZ60NU5KZBtaOZqjdpwTWohz5HU1RrhiYxQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@types/chai-subset": {
- "version": "1.3.6",
- "resolved": "https://registry.npmjs.org/@types/chai-subset/-/chai-subset-1.3.6.tgz",
- "integrity": "sha512-m8lERkkQj+uek18hXOZuec3W/fCRTrU4hrnXjH3qhHy96ytuPaPiWGgu7sJb7tZxZonO75vYAjCvpe/e4VUwRw==",
- "dev": true,
- "license": "MIT",
- "peerDependencies": {
- "@types/chai": "<5.2.0"
- }
- },
- "node_modules/@types/d3-array": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.1.tgz",
- "integrity": "sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==",
- "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/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/istanbul-lib-coverage": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz",
- "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@types/istanbul-lib-report": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz",
- "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/istanbul-lib-coverage": "*"
- }
- },
- "node_modules/@types/istanbul-reports": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz",
- "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/istanbul-lib-report": "*"
- }
- },
- "node_modules/@types/jest": {
- "version": "30.0.0",
- "resolved": "https://registry.npmjs.org/@types/jest/-/jest-30.0.0.tgz",
- "integrity": "sha512-XTYugzhuwqWjws0CVz8QpM36+T+Dz5mTEBKhNs/esGLnCIlGdRy+Dq78NRjd7ls7r8BC8ZRMOrKlkO1hU0JOwA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "expect": "^30.0.0",
- "pretty-format": "^30.0.0"
- }
- },
- "node_modules/@types/jest/node_modules/ansi-styles": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
- "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/@types/jest/node_modules/pretty-format": {
- "version": "30.0.5",
- "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.0.5.tgz",
- "integrity": "sha512-D1tKtYvByrBkFLe2wHJl2bwMJIiT8rW+XA+TiataH79/FszLQMrpGEvzUVkzPau7OCO0Qnrhpe87PqtOAIB8Yw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/schemas": "30.0.5",
- "ansi-styles": "^5.2.0",
- "react-is": "^18.3.1"
- },
- "engines": {
- "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
- }
- },
- "node_modules/@types/jest/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==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@types/json-schema": {
- "version": "7.0.15",
- "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
- "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@types/node": {
- "version": "24.2.1",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-24.2.1.tgz",
- "integrity": "sha512-DRh5K+ka5eJic8CjH7td8QpYEV6Zo10gfRkjHCO3weqZHWDtAaSTFtl4+VMqOJ4N5jcuhZ9/l+yy8rVgw7BQeQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "undici-types": "~7.10.0"
- }
- },
- "node_modules/@types/prop-types": {
- "version": "15.7.15",
- "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz",
- "integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==",
- "license": "MIT"
- },
- "node_modules/@types/react": {
- "version": "18.3.23",
- "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.23.tgz",
- "integrity": "sha512-/LDXMQh55EzZQ0uVAZmKKhfENivEvWz6E+EYzh+/MCjMhNsotd+ZHhBGIjFDTi6+fz0OhQQQLbTgdQIxxCsC0w==",
- "license": "MIT",
- "dependencies": {
- "@types/prop-types": "*",
- "csstype": "^3.0.2"
- }
- },
- "node_modules/@types/react-dom": {
- "version": "18.3.7",
- "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.7.tgz",
- "integrity": "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==",
- "devOptional": true,
- "license": "MIT",
- "peerDependencies": {
- "@types/react": "^18.0.0"
- }
- },
- "node_modules/@types/semver": {
- "version": "7.7.0",
- "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.7.0.tgz",
- "integrity": "sha512-k107IF4+Xr7UHjwDc7Cfd6PRQfbdkiRabXGRjo07b4WyPahFBZCZ1sE+BNxYIJPPg73UkfOsVOLwqVc/6ETrIA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@types/stack-utils": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz",
- "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@types/testing-library__jest-dom": {
- "version": "5.14.9",
- "resolved": "https://registry.npmjs.org/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.14.9.tgz",
- "integrity": "sha512-FSYhIjFlfOpGSRyVoMBMuS3ws5ehFQODymf3vlI7U1K8c7PHwWwFY7VREfmsuzHSOnoKs/9/Y983ayOs7eRzqw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/jest": "*"
- }
- },
- "node_modules/@types/use-sync-external-store": {
- "version": "0.0.3",
- "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz",
- "integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==",
- "license": "MIT"
- },
- "node_modules/@types/yargs": {
- "version": "17.0.33",
- "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz",
- "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/yargs-parser": "*"
- }
- },
- "node_modules/@types/yargs-parser": {
- "version": "21.0.3",
- "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz",
- "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@typescript-eslint/eslint-plugin": {
- "version": "6.21.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.21.0.tgz",
- "integrity": "sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@eslint-community/regexpp": "^4.5.1",
- "@typescript-eslint/scope-manager": "6.21.0",
- "@typescript-eslint/type-utils": "6.21.0",
- "@typescript-eslint/utils": "6.21.0",
- "@typescript-eslint/visitor-keys": "6.21.0",
- "debug": "^4.3.4",
- "graphemer": "^1.4.0",
- "ignore": "^5.2.4",
- "natural-compare": "^1.4.0",
- "semver": "^7.5.4",
- "ts-api-utils": "^1.0.1"
- },
- "engines": {
- "node": "^16.0.0 || >=18.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- },
- "peerDependencies": {
- "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha",
- "eslint": "^7.0.0 || ^8.0.0"
- },
- "peerDependenciesMeta": {
- "typescript": {
- "optional": true
- }
- }
- },
- "node_modules/@typescript-eslint/parser": {
- "version": "6.21.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz",
- "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==",
- "dev": true,
- "license": "BSD-2-Clause",
- "dependencies": {
- "@typescript-eslint/scope-manager": "6.21.0",
- "@typescript-eslint/types": "6.21.0",
- "@typescript-eslint/typescript-estree": "6.21.0",
- "@typescript-eslint/visitor-keys": "6.21.0",
- "debug": "^4.3.4"
- },
- "engines": {
- "node": "^16.0.0 || >=18.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- },
- "peerDependencies": {
- "eslint": "^7.0.0 || ^8.0.0"
- },
- "peerDependenciesMeta": {
- "typescript": {
- "optional": true
- }
- }
- },
- "node_modules/@typescript-eslint/scope-manager": {
- "version": "6.21.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz",
- "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@typescript-eslint/types": "6.21.0",
- "@typescript-eslint/visitor-keys": "6.21.0"
- },
- "engines": {
- "node": "^16.0.0 || >=18.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- }
- },
- "node_modules/@typescript-eslint/type-utils": {
- "version": "6.21.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.21.0.tgz",
- "integrity": "sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@typescript-eslint/typescript-estree": "6.21.0",
- "@typescript-eslint/utils": "6.21.0",
- "debug": "^4.3.4",
- "ts-api-utils": "^1.0.1"
- },
- "engines": {
- "node": "^16.0.0 || >=18.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- },
- "peerDependencies": {
- "eslint": "^7.0.0 || ^8.0.0"
- },
- "peerDependenciesMeta": {
- "typescript": {
- "optional": true
- }
- }
- },
- "node_modules/@typescript-eslint/types": {
- "version": "6.21.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz",
- "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": "^16.0.0 || >=18.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- }
- },
- "node_modules/@typescript-eslint/typescript-estree": {
- "version": "6.21.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz",
- "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==",
- "dev": true,
- "license": "BSD-2-Clause",
- "dependencies": {
- "@typescript-eslint/types": "6.21.0",
- "@typescript-eslint/visitor-keys": "6.21.0",
- "debug": "^4.3.4",
- "globby": "^11.1.0",
- "is-glob": "^4.0.3",
- "minimatch": "9.0.3",
- "semver": "^7.5.4",
- "ts-api-utils": "^1.0.1"
- },
- "engines": {
- "node": "^16.0.0 || >=18.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- },
- "peerDependenciesMeta": {
- "typescript": {
- "optional": true
- }
- }
- },
- "node_modules/@typescript-eslint/utils": {
- "version": "6.21.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz",
- "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@eslint-community/eslint-utils": "^4.4.0",
- "@types/json-schema": "^7.0.12",
- "@types/semver": "^7.5.0",
- "@typescript-eslint/scope-manager": "6.21.0",
- "@typescript-eslint/types": "6.21.0",
- "@typescript-eslint/typescript-estree": "6.21.0",
- "semver": "^7.5.4"
- },
- "engines": {
- "node": "^16.0.0 || >=18.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- },
- "peerDependencies": {
- "eslint": "^7.0.0 || ^8.0.0"
- }
- },
- "node_modules/@typescript-eslint/visitor-keys": {
- "version": "6.21.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz",
- "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@typescript-eslint/types": "6.21.0",
- "eslint-visitor-keys": "^3.4.1"
- },
- "engines": {
- "node": "^16.0.0 || >=18.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- }
- },
- "node_modules/@ungap/structured-clone": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz",
- "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==",
- "dev": true,
- "license": "ISC"
- },
- "node_modules/@vitejs/plugin-react": {
- "version": "4.7.0",
- "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.7.0.tgz",
- "integrity": "sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/core": "^7.28.0",
- "@babel/plugin-transform-react-jsx-self": "^7.27.1",
- "@babel/plugin-transform-react-jsx-source": "^7.27.1",
- "@rolldown/pluginutils": "1.0.0-beta.27",
- "@types/babel__core": "^7.20.5",
- "react-refresh": "^0.17.0"
- },
- "engines": {
- "node": "^14.18.0 || >=16.0.0"
- },
- "peerDependencies": {
- "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0"
- }
- },
- "node_modules/@vitest/expect": {
- "version": "0.34.6",
- "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-0.34.6.tgz",
- "integrity": "sha512-QUzKpUQRc1qC7qdGo7rMK3AkETI7w18gTCUrsNnyjjJKYiuUB9+TQK3QnR1unhCnWRC0AbKv2omLGQDF/mIjOw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@vitest/spy": "0.34.6",
- "@vitest/utils": "0.34.6",
- "chai": "^4.3.10"
- },
- "funding": {
- "url": "https://opencollective.com/vitest"
- }
- },
- "node_modules/@vitest/expect/node_modules/@jest/schemas": {
- "version": "29.6.3",
- "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz",
- "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@sinclair/typebox": "^0.27.8"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/@vitest/expect/node_modules/@sinclair/typebox": {
- "version": "0.27.8",
- "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz",
- "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@vitest/expect/node_modules/@vitest/utils": {
- "version": "0.34.6",
- "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-0.34.6.tgz",
- "integrity": "sha512-IG5aDD8S6zlvloDsnzHw0Ut5xczlF+kv2BOTo+iXfPr54Yhi5qbVOgGB1hZaVq4iJ4C/MZ2J0y15IlsV/ZcI0A==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "diff-sequences": "^29.4.3",
- "loupe": "^2.3.6",
- "pretty-format": "^29.5.0"
- },
- "funding": {
- "url": "https://opencollective.com/vitest"
- }
- },
- "node_modules/@vitest/expect/node_modules/ansi-styles": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
- "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/@vitest/expect/node_modules/pretty-format": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz",
- "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/schemas": "^29.6.3",
- "ansi-styles": "^5.0.0",
- "react-is": "^18.0.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/@vitest/expect/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==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@vitest/runner": {
- "version": "0.34.6",
- "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-0.34.6.tgz",
- "integrity": "sha512-1CUQgtJSLF47NnhN+F9X2ycxUP0kLHQ/JWvNHbeBfwW8CzEGgeskzNnHDyv1ieKTltuR6sdIHV+nmR6kPxQqzQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@vitest/utils": "0.34.6",
- "p-limit": "^4.0.0",
- "pathe": "^1.1.1"
- },
- "funding": {
- "url": "https://opencollective.com/vitest"
- }
- },
- "node_modules/@vitest/runner/node_modules/@jest/schemas": {
- "version": "29.6.3",
- "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz",
- "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@sinclair/typebox": "^0.27.8"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/@vitest/runner/node_modules/@sinclair/typebox": {
- "version": "0.27.8",
- "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz",
- "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@vitest/runner/node_modules/@vitest/utils": {
- "version": "0.34.6",
- "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-0.34.6.tgz",
- "integrity": "sha512-IG5aDD8S6zlvloDsnzHw0Ut5xczlF+kv2BOTo+iXfPr54Yhi5qbVOgGB1hZaVq4iJ4C/MZ2J0y15IlsV/ZcI0A==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "diff-sequences": "^29.4.3",
- "loupe": "^2.3.6",
- "pretty-format": "^29.5.0"
- },
- "funding": {
- "url": "https://opencollective.com/vitest"
- }
- },
- "node_modules/@vitest/runner/node_modules/ansi-styles": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
- "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/@vitest/runner/node_modules/p-limit": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz",
- "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "yocto-queue": "^1.0.0"
- },
- "engines": {
- "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/@vitest/runner/node_modules/pretty-format": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz",
- "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/schemas": "^29.6.3",
- "ansi-styles": "^5.0.0",
- "react-is": "^18.0.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/@vitest/runner/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==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@vitest/runner/node_modules/yocto-queue": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.2.1.tgz",
- "integrity": "sha512-AyeEbWOu/TAXdxlV9wmGcR0+yh2j3vYPGOECcIj2S7MkrLyC7ne+oye2BKTItt0ii2PHk4cDy+95+LshzbXnGg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=12.20"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/@vitest/snapshot": {
- "version": "0.34.6",
- "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-0.34.6.tgz",
- "integrity": "sha512-B3OZqYn6k4VaN011D+ve+AA4whM4QkcwcrwaKwAbyyvS/NB1hCWjFIBQxAQQSQir9/RtyAAGuq+4RJmbn2dH4w==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "magic-string": "^0.30.1",
- "pathe": "^1.1.1",
- "pretty-format": "^29.5.0"
- },
- "funding": {
- "url": "https://opencollective.com/vitest"
- }
- },
- "node_modules/@vitest/snapshot/node_modules/@jest/schemas": {
- "version": "29.6.3",
- "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz",
- "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@sinclair/typebox": "^0.27.8"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/@vitest/snapshot/node_modules/@sinclair/typebox": {
- "version": "0.27.8",
- "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz",
- "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@vitest/snapshot/node_modules/ansi-styles": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
- "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/@vitest/snapshot/node_modules/pretty-format": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz",
- "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/schemas": "^29.6.3",
- "ansi-styles": "^5.0.0",
- "react-is": "^18.0.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/@vitest/snapshot/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==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@vitest/spy": {
- "version": "0.34.6",
- "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-0.34.6.tgz",
- "integrity": "sha512-xaCvneSaeBw/cz8ySmF7ZwGvL0lBjfvqc1LpQ/vcdHEvpLn3Ff1vAvjw+CoGn0802l++5L/pxb7whwcWAw+DUQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "tinyspy": "^2.1.1"
- },
- "funding": {
- "url": "https://opencollective.com/vitest"
- }
- },
- "node_modules/@vitest/ui": {
- "version": "0.34.7",
- "resolved": "https://registry.npmjs.org/@vitest/ui/-/ui-0.34.7.tgz",
- "integrity": "sha512-iizUu9R5Rsvsq8FtdJ0suMqEfIsIIzziqnasMHe4VH8vG+FnZSA3UAtCHx6rLeRupIFVAVg7bptMmuvMcsn8WQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@vitest/utils": "0.34.7",
- "fast-glob": "^3.3.0",
- "fflate": "^0.8.0",
- "flatted": "^3.2.7",
- "pathe": "^1.1.1",
- "picocolors": "^1.0.0",
- "sirv": "^2.0.3"
- },
- "funding": {
- "url": "https://opencollective.com/vitest"
- },
- "peerDependencies": {
- "vitest": ">=0.30.1 <1"
- }
- },
- "node_modules/@vitest/utils": {
- "version": "0.34.7",
- "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-0.34.7.tgz",
- "integrity": "sha512-ziAavQLpCYS9sLOorGrFFKmy2gnfiNU0ZJ15TsMz/K92NAPS/rp9K4z6AJQQk5Y8adCy4Iwpxy7pQumQ/psnRg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "diff-sequences": "^29.4.3",
- "loupe": "^2.3.6",
- "pretty-format": "^29.5.0"
- },
- "funding": {
- "url": "https://opencollective.com/vitest"
- }
- },
- "node_modules/@vitest/utils/node_modules/@jest/schemas": {
- "version": "29.6.3",
- "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz",
- "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@sinclair/typebox": "^0.27.8"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/@vitest/utils/node_modules/@sinclair/typebox": {
- "version": "0.27.8",
- "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz",
- "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@vitest/utils/node_modules/ansi-styles": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
- "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/@vitest/utils/node_modules/pretty-format": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz",
- "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/schemas": "^29.6.3",
- "ansi-styles": "^5.0.0",
- "react-is": "^18.0.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/@vitest/utils/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==",
- "dev": true,
- "license": "MIT"
- },
- "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/acorn-walk": {
- "version": "8.3.4",
- "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz",
- "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "acorn": "^8.11.0"
- },
- "engines": {
- "node": ">=0.4.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-regex": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
- "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "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/any-promise": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
- "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/anymatch": {
- "version": "3.1.3",
- "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
- "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "normalize-path": "^3.0.0",
- "picomatch": "^2.0.4"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/anymatch/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/arg": {
- "version": "5.0.2",
- "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz",
- "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==",
- "dev": true,
- "license": "MIT"
- },
- "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/aria-query": {
- "version": "5.3.0",
- "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz",
- "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "dequal": "^2.0.3"
- }
- },
- "node_modules/array-buffer-byte-length": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz",
- "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bound": "^1.0.3",
- "is-array-buffer": "^3.0.5"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/array-union": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
- "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/assertion-error": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz",
- "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": "*"
- }
- },
- "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/available-typed-arrays": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz",
- "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "possible-typed-array-names": "^1.0.0"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "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/binary-extensions": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
- "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "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/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.2",
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.2.tgz",
- "integrity": "sha512-0si2SJK3ooGzIawRu61ZdPCO1IncZwS8IzuX73sPZsXW6EQ/w/DAfPyKI8l1ETTCr2MnvqWitmlCUxgdul45jA==",
- "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.30001733",
- "electron-to-chromium": "^1.5.199",
- "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/cac": {
- "version": "6.7.14",
- "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz",
- "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/call-bind": {
- "version": "1.0.8",
- "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz",
- "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bind-apply-helpers": "^1.0.0",
- "es-define-property": "^1.0.0",
- "get-intrinsic": "^1.2.4",
- "set-function-length": "^1.2.2"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "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==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "es-errors": "^1.3.0",
- "function-bind": "^1.1.2"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/call-bound": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
- "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bind-apply-helpers": "^1.0.2",
- "get-intrinsic": "^1.3.0"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "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/camelcase-css": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz",
- "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/caniuse-lite": {
- "version": "1.0.30001734",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001734.tgz",
- "integrity": "sha512-uhE1Ye5vgqju6OI71HTQqcBCZrvHugk0MjLak7Q+HfoBgoq5Bi+5YnwjP4fjDgrtYr/l8MVRBvzz9dPD4KyK0A==",
- "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/chai": {
- "version": "4.5.0",
- "resolved": "https://registry.npmjs.org/chai/-/chai-4.5.0.tgz",
- "integrity": "sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "assertion-error": "^1.1.0",
- "check-error": "^1.0.3",
- "deep-eql": "^4.1.3",
- "get-func-name": "^2.0.2",
- "loupe": "^2.3.6",
- "pathval": "^1.1.1",
- "type-detect": "^4.1.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/chalk": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
- "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/check-error": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz",
- "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "get-func-name": "^2.0.2"
- },
- "engines": {
- "node": "*"
- }
- },
- "node_modules/chokidar": {
- "version": "3.6.0",
- "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
- "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "anymatch": "~3.1.2",
- "braces": "~3.0.2",
- "glob-parent": "~5.1.2",
- "is-binary-path": "~2.1.0",
- "is-glob": "~4.0.1",
- "normalize-path": "~3.0.0",
- "readdirp": "~3.6.0"
- },
- "engines": {
- "node": ">= 8.10.0"
- },
- "funding": {
- "url": "https://paulmillr.com/funding/"
- },
- "optionalDependencies": {
- "fsevents": "~2.3.2"
- }
- },
- "node_modules/chokidar/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/ci-info": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.0.tgz",
- "integrity": "sha512-l+2bNRMiQgcfILUi33labAZYIWlH1kWDp+ecNo5iisRKrbm0xcRyCww71/YU0Fkw0mAFpz9bJayXPjey6vkmaQ==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/sibiraj-s"
- }
- ],
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "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/commander": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
- "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 6"
- }
- },
- "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/confbox": {
- "version": "0.1.8",
- "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz",
- "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==",
- "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/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/css.escape": {
- "version": "1.5.1",
- "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz",
- "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/cssesc": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
- "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
- "dev": true,
- "license": "MIT",
- "bin": {
- "cssesc": "bin/cssesc"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "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/date-fns": {
- "version": "2.30.0",
- "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz",
- "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==",
- "license": "MIT",
- "dependencies": {
- "@babel/runtime": "^7.21.0"
- },
- "engines": {
- "node": ">=0.11"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/date-fns"
- }
- },
- "node_modules/date-fns-tz": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/date-fns-tz/-/date-fns-tz-2.0.1.tgz",
- "integrity": "sha512-fJCG3Pwx8HUoLhkepdsP7Z5RsucUi+ZBOxyM5d0ZZ6c4SdYustq0VMmOu6Wf7bli+yS/Jwp91TOCqn9jMcVrUA==",
- "license": "MIT",
- "peerDependencies": {
- "date-fns": "2.x"
- }
- },
- "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-eql": {
- "version": "4.1.4",
- "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz",
- "integrity": "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "type-detect": "^4.0.0"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/deep-equal": {
- "version": "2.2.3",
- "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.3.tgz",
- "integrity": "sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "array-buffer-byte-length": "^1.0.0",
- "call-bind": "^1.0.5",
- "es-get-iterator": "^1.1.3",
- "get-intrinsic": "^1.2.2",
- "is-arguments": "^1.1.1",
- "is-array-buffer": "^3.0.2",
- "is-date-object": "^1.0.5",
- "is-regex": "^1.1.4",
- "is-shared-array-buffer": "^1.0.2",
- "isarray": "^2.0.5",
- "object-is": "^1.1.5",
- "object-keys": "^1.1.1",
- "object.assign": "^4.1.4",
- "regexp.prototype.flags": "^1.5.1",
- "side-channel": "^1.0.4",
- "which-boxed-primitive": "^1.0.2",
- "which-collection": "^1.0.1",
- "which-typed-array": "^1.1.13"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "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/define-data-property": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
- "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "es-define-property": "^1.0.0",
- "es-errors": "^1.3.0",
- "gopd": "^1.0.1"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/define-properties": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz",
- "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "define-data-property": "^1.0.1",
- "has-property-descriptors": "^1.0.0",
- "object-keys": "^1.1.1"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/dequal": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
- "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/didyoumean": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz",
- "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==",
- "dev": true,
- "license": "Apache-2.0"
- },
- "node_modules/diff-sequences": {
- "version": "29.6.3",
- "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz",
- "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/dir-glob": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
- "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "path-type": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/dlv": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz",
- "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/doctrine": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
- "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "esutils": "^2.0.2"
- },
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/dom-accessibility-api": {
- "version": "0.5.16",
- "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz",
- "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/dom-helpers": {
- "version": "5.2.1",
- "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz",
- "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==",
- "license": "MIT",
- "dependencies": {
- "@babel/runtime": "^7.8.7",
- "csstype": "^3.0.2"
- }
- },
- "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==",
- "dev": true,
- "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/eastasianwidth": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
- "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/electron-to-chromium": {
- "version": "1.5.199",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.199.tgz",
- "integrity": "sha512-3gl0S7zQd88kCAZRO/DnxtBKuhMO4h0EaQIN3YgZfV6+pW+5+bf2AdQeHNESCoaQqo/gjGVYEf2YM4O5HJQqpQ==",
- "dev": true,
- "license": "ISC"
- },
- "node_modules/emoji-regex": {
- "version": "9.2.2",
- "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
- "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
- "dev": true,
- "license": "MIT"
- },
- "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==",
- "dev": true,
- "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==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/es-get-iterator": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz",
- "integrity": "sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bind": "^1.0.2",
- "get-intrinsic": "^1.1.3",
- "has-symbols": "^1.0.3",
- "is-arguments": "^1.1.1",
- "is-map": "^2.0.2",
- "is-set": "^2.0.2",
- "is-string": "^1.0.7",
- "isarray": "^2.0.5",
- "stop-iteration-iterator": "^1.0.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "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==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "es-errors": "^1.3.0"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/esbuild": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz",
- "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==",
- "dev": true,
- "hasInstallScript": true,
- "license": "MIT",
- "bin": {
- "esbuild": "bin/esbuild"
- },
- "engines": {
- "node": ">=12"
- },
- "optionalDependencies": {
- "@esbuild/android-arm": "0.18.20",
- "@esbuild/android-arm64": "0.18.20",
- "@esbuild/android-x64": "0.18.20",
- "@esbuild/darwin-arm64": "0.18.20",
- "@esbuild/darwin-x64": "0.18.20",
- "@esbuild/freebsd-arm64": "0.18.20",
- "@esbuild/freebsd-x64": "0.18.20",
- "@esbuild/linux-arm": "0.18.20",
- "@esbuild/linux-arm64": "0.18.20",
- "@esbuild/linux-ia32": "0.18.20",
- "@esbuild/linux-loong64": "0.18.20",
- "@esbuild/linux-mips64el": "0.18.20",
- "@esbuild/linux-ppc64": "0.18.20",
- "@esbuild/linux-riscv64": "0.18.20",
- "@esbuild/linux-s390x": "0.18.20",
- "@esbuild/linux-x64": "0.18.20",
- "@esbuild/netbsd-x64": "0.18.20",
- "@esbuild/openbsd-x64": "0.18.20",
- "@esbuild/sunos-x64": "0.18.20",
- "@esbuild/win32-arm64": "0.18.20",
- "@esbuild/win32-ia32": "0.18.20",
- "@esbuild/win32-x64": "0.18.20"
- }
- },
- "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": "8.57.1",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz",
- "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==",
- "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@eslint-community/eslint-utils": "^4.2.0",
- "@eslint-community/regexpp": "^4.6.1",
- "@eslint/eslintrc": "^2.1.4",
- "@eslint/js": "8.57.1",
- "@humanwhocodes/config-array": "^0.13.0",
- "@humanwhocodes/module-importer": "^1.0.1",
- "@nodelib/fs.walk": "^1.2.8",
- "@ungap/structured-clone": "^1.2.0",
- "ajv": "^6.12.4",
- "chalk": "^4.0.0",
- "cross-spawn": "^7.0.2",
- "debug": "^4.3.2",
- "doctrine": "^3.0.0",
- "escape-string-regexp": "^4.0.0",
- "eslint-scope": "^7.2.2",
- "eslint-visitor-keys": "^3.4.3",
- "espree": "^9.6.1",
- "esquery": "^1.4.2",
- "esutils": "^2.0.2",
- "fast-deep-equal": "^3.1.3",
- "file-entry-cache": "^6.0.1",
- "find-up": "^5.0.0",
- "glob-parent": "^6.0.2",
- "globals": "^13.19.0",
- "graphemer": "^1.4.0",
- "ignore": "^5.2.0",
- "imurmurhash": "^0.1.4",
- "is-glob": "^4.0.0",
- "is-path-inside": "^3.0.3",
- "js-yaml": "^4.1.0",
- "json-stable-stringify-without-jsonify": "^1.0.1",
- "levn": "^0.4.1",
- "lodash.merge": "^4.6.2",
- "minimatch": "^3.1.2",
- "natural-compare": "^1.4.0",
- "optionator": "^0.9.3",
- "strip-ansi": "^6.0.1",
- "text-table": "^0.2.0"
- },
- "bin": {
- "eslint": "bin/eslint.js"
- },
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/eslint"
- }
- },
- "node_modules/eslint-plugin-react-hooks": {
- "version": "4.6.2",
- "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.2.tgz",
- "integrity": "sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==",
- "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"
- }
- },
- "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": "7.2.2",
- "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz",
- "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==",
- "dev": true,
- "license": "BSD-2-Clause",
- "dependencies": {
- "esrecurse": "^4.3.0",
- "estraverse": "^5.2.0"
- },
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/eslint"
- }
- },
- "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/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/eslint/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/eslint/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/espree": {
- "version": "9.6.1",
- "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz",
- "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==",
- "dev": true,
- "license": "BSD-2-Clause",
- "dependencies": {
- "acorn": "^8.9.0",
- "acorn-jsx": "^5.3.2",
- "eslint-visitor-keys": "^3.4.1"
- },
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.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": "4.0.7",
- "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz",
- "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==",
- "license": "MIT"
- },
- "node_modules/expect": {
- "version": "30.0.5",
- "resolved": "https://registry.npmjs.org/expect/-/expect-30.0.5.tgz",
- "integrity": "sha512-P0te2pt+hHI5qLJkIR+iMvS+lYUZml8rKKsohVHAGY+uClp9XVbdyYNJOIjSRpHVp8s8YqxJCiHUkSYZGr8rtQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/expect-utils": "30.0.5",
- "@jest/get-type": "30.0.1",
- "jest-matcher-utils": "30.0.5",
- "jest-message-util": "30.0.5",
- "jest-mock": "30.0.5",
- "jest-util": "30.0.5"
- },
- "engines": {
- "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
- }
- },
- "node_modules/fast-deep-equal": {
- "version": "3.1.3",
- "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
- "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/fast-equals": {
- "version": "5.2.2",
- "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-5.2.2.tgz",
- "integrity": "sha512-V7/RktU11J3I36Nwq2JnZEM7tNm17eBJz+u25qdxBZeCKiX6BkVSZQjwWIr+IobgnZy+ag73tTZgZi7tr0LrBw==",
- "license": "MIT",
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "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/fflate": {
- "version": "0.8.2",
- "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz",
- "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/file-entry-cache": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
- "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "flat-cache": "^3.0.4"
- },
- "engines": {
- "node": "^10.12.0 || >=12.0.0"
- }
- },
- "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": "3.2.0",
- "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz",
- "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "flatted": "^3.2.9",
- "keyv": "^4.5.3",
- "rimraf": "^3.0.2"
- },
- "engines": {
- "node": "^10.12.0 || >=12.0.0"
- }
- },
- "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/for-each": {
- "version": "0.3.5",
- "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz",
- "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "is-callable": "^1.2.7"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/foreground-child": {
- "version": "3.3.1",
- "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz",
- "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "cross-spawn": "^7.0.6",
- "signal-exit": "^4.0.1"
- },
- "engines": {
- "node": ">=14"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "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/fs.realpath": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
- "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
- "dev": true,
- "license": "ISC"
- },
- "node_modules/fsevents": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
- "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
- "dev": true,
- "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==",
- "dev": true,
- "license": "MIT",
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/functions-have-names": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz",
- "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==",
- "dev": true,
- "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-func-name": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz",
- "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": "*"
- }
- },
- "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==",
- "dev": true,
- "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==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "dunder-proto": "^1.0.1",
- "es-object-atoms": "^1.0.0"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/glob": {
- "version": "7.2.3",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
- "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
- "deprecated": "Glob versions prior to v9 are no longer supported",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "fs.realpath": "^1.0.0",
- "inflight": "^1.0.4",
- "inherits": "2",
- "minimatch": "^3.1.1",
- "once": "^1.3.0",
- "path-is-absolute": "^1.0.0"
- },
- "engines": {
- "node": "*"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "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/glob/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/glob/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/globals": {
- "version": "13.24.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz",
- "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "type-fest": "^0.20.2"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/globby": {
- "version": "11.1.0",
- "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
- "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "array-union": "^2.1.0",
- "dir-glob": "^3.0.1",
- "fast-glob": "^3.2.9",
- "ignore": "^5.2.0",
- "merge2": "^1.4.1",
- "slash": "^3.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/goober": {
- "version": "2.1.16",
- "resolved": "https://registry.npmjs.org/goober/-/goober-2.1.16.tgz",
- "integrity": "sha512-erjk19y1U33+XAMe1VTvIONHYoSqE4iS7BYUZfHaqeohLmnC0FdxEh7rQU+6MZ4OajItzjZFSRtVANrQwNq6/g==",
- "license": "MIT",
- "peerDependencies": {
- "csstype": "^3.0.10"
- }
- },
- "node_modules/gopd": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
- "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
- "dev": true,
- "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==",
- "dev": true,
- "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-bigints": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz",
- "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "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-property-descriptors": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
- "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "es-define-property": "^1.0.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "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==",
- "dev": true,
- "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==",
- "dev": true,
- "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==",
- "dev": true,
- "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": "23.16.8",
- "resolved": "https://registry.npmjs.org/i18next/-/i18next-23.16.8.tgz",
- "integrity": "sha512-06r/TitrM88Mg5FdUXAKL96dJMzgqLE5dv3ryBAra4KCwD9mJ4ndOTS95ZuymIGoE+2hzfdaMak2X11/es7ZWg==",
- "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.23.2"
- }
- },
- "node_modules/i18next-browser-languagedetector": {
- "version": "7.2.2",
- "resolved": "https://registry.npmjs.org/i18next-browser-languagedetector/-/i18next-browser-languagedetector-7.2.2.tgz",
- "integrity": "sha512-6b7r75uIJDWCcCflmbof+sJ94k9UQO4X0YR62oUfqGI/GjCLVzlCwu8TFdRZIqVLzWbzNcmkmhfqKEr4TLz4HQ==",
- "license": "MIT",
- "dependencies": {
- "@babel/runtime": "^7.23.2"
- }
- },
- "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": "9.0.21",
- "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz",
- "integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==",
- "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/indent-string": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
- "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/inflight": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
- "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
- "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "once": "^1.3.0",
- "wrappy": "1"
- }
- },
- "node_modules/inherits": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
- "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
- "dev": true,
- "license": "ISC"
- },
- "node_modules/internal-slot": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz",
- "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "es-errors": "^1.3.0",
- "hasown": "^2.0.2",
- "side-channel": "^1.1.0"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "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-arguments": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.2.0.tgz",
- "integrity": "sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bound": "^1.0.2",
- "has-tostringtag": "^1.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-array-buffer": {
- "version": "3.0.5",
- "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz",
- "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bind": "^1.0.8",
- "call-bound": "^1.0.3",
- "get-intrinsic": "^1.2.6"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-bigint": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz",
- "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "has-bigints": "^1.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-binary-path": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
- "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "binary-extensions": "^2.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/is-boolean-object": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz",
- "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bound": "^1.0.3",
- "has-tostringtag": "^1.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-callable": {
- "version": "1.2.7",
- "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
- "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-core-module": {
- "version": "2.16.1",
- "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
- "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "hasown": "^2.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-date-object": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz",
- "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bound": "^1.0.2",
- "has-tostringtag": "^1.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "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-fullwidth-code-point": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
- "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "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-map": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz",
- "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "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/is-number-object": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz",
- "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bound": "^1.0.3",
- "has-tostringtag": "^1.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-path-inside": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
- "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/is-regex": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz",
- "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bound": "^1.0.2",
- "gopd": "^1.2.0",
- "has-tostringtag": "^1.0.2",
- "hasown": "^2.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-set": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz",
- "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-shared-array-buffer": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz",
- "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bound": "^1.0.3"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-string": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz",
- "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bound": "^1.0.3",
- "has-tostringtag": "^1.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-symbol": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz",
- "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bound": "^1.0.2",
- "has-symbols": "^1.1.0",
- "safe-regex-test": "^1.1.0"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-weakmap": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz",
- "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-weakset": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz",
- "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bound": "^1.0.3",
- "get-intrinsic": "^1.2.6"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/isarray": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
- "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==",
- "dev": true,
- "license": "MIT"
- },
- "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/jackspeak": {
- "version": "3.4.3",
- "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
- "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==",
- "dev": true,
- "license": "BlueOak-1.0.0",
- "dependencies": {
- "@isaacs/cliui": "^8.0.2"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- },
- "optionalDependencies": {
- "@pkgjs/parseargs": "^0.11.0"
- }
- },
- "node_modules/jest-diff": {
- "version": "30.0.5",
- "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.0.5.tgz",
- "integrity": "sha512-1UIqE9PoEKaHcIKvq2vbibrCog4Y8G0zmOxgQUVEiTqwR5hJVMCoDsN1vFvI5JvwD37hjueZ1C4l2FyGnfpE0A==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/diff-sequences": "30.0.1",
- "@jest/get-type": "30.0.1",
- "chalk": "^4.1.2",
- "pretty-format": "30.0.5"
- },
- "engines": {
- "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
- }
- },
- "node_modules/jest-diff/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/jest-diff/node_modules/pretty-format": {
- "version": "30.0.5",
- "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.0.5.tgz",
- "integrity": "sha512-D1tKtYvByrBkFLe2wHJl2bwMJIiT8rW+XA+TiataH79/FszLQMrpGEvzUVkzPau7OCO0Qnrhpe87PqtOAIB8Yw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/schemas": "30.0.5",
- "ansi-styles": "^5.2.0",
- "react-is": "^18.3.1"
- },
- "engines": {
- "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
- }
- },
- "node_modules/jest-diff/node_modules/pretty-format/node_modules/ansi-styles": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
- "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/jest-diff/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==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/jest-matcher-utils": {
- "version": "30.0.5",
- "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-30.0.5.tgz",
- "integrity": "sha512-uQgGWt7GOrRLP1P7IwNWwK1WAQbq+m//ZY0yXygyfWp0rJlksMSLQAA4wYQC3b6wl3zfnchyTx+k3HZ5aPtCbQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/get-type": "30.0.1",
- "chalk": "^4.1.2",
- "jest-diff": "30.0.5",
- "pretty-format": "30.0.5"
- },
- "engines": {
- "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
- }
- },
- "node_modules/jest-matcher-utils/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/jest-matcher-utils/node_modules/pretty-format": {
- "version": "30.0.5",
- "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.0.5.tgz",
- "integrity": "sha512-D1tKtYvByrBkFLe2wHJl2bwMJIiT8rW+XA+TiataH79/FszLQMrpGEvzUVkzPau7OCO0Qnrhpe87PqtOAIB8Yw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/schemas": "30.0.5",
- "ansi-styles": "^5.2.0",
- "react-is": "^18.3.1"
- },
- "engines": {
- "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
- }
- },
- "node_modules/jest-matcher-utils/node_modules/pretty-format/node_modules/ansi-styles": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
- "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/jest-matcher-utils/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==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/jest-message-util": {
- "version": "30.0.5",
- "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.0.5.tgz",
- "integrity": "sha512-NAiDOhsK3V7RU0Aa/HnrQo+E4JlbarbmI3q6Pi4KcxicdtjV82gcIUrejOtczChtVQR4kddu1E1EJlW6EN9IyA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/code-frame": "^7.27.1",
- "@jest/types": "30.0.5",
- "@types/stack-utils": "^2.0.3",
- "chalk": "^4.1.2",
- "graceful-fs": "^4.2.11",
- "micromatch": "^4.0.8",
- "pretty-format": "30.0.5",
- "slash": "^3.0.0",
- "stack-utils": "^2.0.6"
- },
- "engines": {
- "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
- }
- },
- "node_modules/jest-message-util/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/jest-message-util/node_modules/pretty-format": {
- "version": "30.0.5",
- "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.0.5.tgz",
- "integrity": "sha512-D1tKtYvByrBkFLe2wHJl2bwMJIiT8rW+XA+TiataH79/FszLQMrpGEvzUVkzPau7OCO0Qnrhpe87PqtOAIB8Yw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/schemas": "30.0.5",
- "ansi-styles": "^5.2.0",
- "react-is": "^18.3.1"
- },
- "engines": {
- "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
- }
- },
- "node_modules/jest-message-util/node_modules/pretty-format/node_modules/ansi-styles": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
- "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/jest-message-util/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==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/jest-mock": {
- "version": "30.0.5",
- "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-30.0.5.tgz",
- "integrity": "sha512-Od7TyasAAQX/6S+QCbN6vZoWOMwlTtzzGuxJku1GhGanAjz9y+QsQkpScDmETvdc9aSXyJ/Op4rhpMYBWW91wQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/types": "30.0.5",
- "@types/node": "*",
- "jest-util": "30.0.5"
- },
- "engines": {
- "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
- }
- },
- "node_modules/jest-regex-util": {
- "version": "30.0.1",
- "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.0.1.tgz",
- "integrity": "sha512-jHEQgBXAgc+Gh4g0p3bCevgRCVRkB4VB70zhoAE48gxeSr1hfUOsM/C2WoJgVL7Eyg//hudYENbm3Ne+/dRVVA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
- }
- },
- "node_modules/jest-util": {
- "version": "30.0.5",
- "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.0.5.tgz",
- "integrity": "sha512-pvyPWssDZR0FlfMxCBoc0tvM8iUEskaRFALUtGQYzVEAqisAztmy+R8LnU14KT4XA0H/a5HMVTXat1jLne010g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/types": "30.0.5",
- "@types/node": "*",
- "chalk": "^4.1.2",
- "ci-info": "^4.2.0",
- "graceful-fs": "^4.2.11",
- "picomatch": "^4.0.2"
- },
- "engines": {
- "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
- }
- },
- "node_modules/jest-util/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/jiti": {
- "version": "1.21.7",
- "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz",
- "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==",
- "dev": true,
- "license": "MIT",
- "bin": {
- "jiti": "bin/jiti.js"
- }
- },
- "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.0",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
- "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "argparse": "^2.0.1"
- },
- "bin": {
- "js-yaml": "bin/js-yaml.js"
- }
- },
- "node_modules/jsesc": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
- "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
- "dev": true,
- "license": "MIT",
- "bin": {
- "jsesc": "bin/jsesc"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/json-buffer": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
- "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/json-schema-traverse": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
- "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/json-stable-stringify-without-jsonify": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
- "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/json5": {
- "version": "2.2.3",
- "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
- "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
- "dev": true,
- "license": "MIT",
- "bin": {
- "json5": "lib/cli.js"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/keyv": {
- "version": "4.5.4",
- "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
- "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "json-buffer": "3.0.1"
- }
- },
- "node_modules/levn": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
- "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "prelude-ls": "^1.2.1",
- "type-check": "~0.4.0"
- },
- "engines": {
- "node": ">= 0.8.0"
- }
- },
- "node_modules/lilconfig": {
- "version": "3.1.3",
- "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz",
- "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=14"
- },
- "funding": {
- "url": "https://github.com/sponsors/antonk52"
- }
- },
- "node_modules/lines-and-columns": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
- "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/local-pkg": {
- "version": "0.4.3",
- "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.4.3.tgz",
- "integrity": "sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=14"
- },
- "funding": {
- "url": "https://github.com/sponsors/antfu"
- }
- },
- "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.castarray": {
- "version": "4.4.0",
- "resolved": "https://registry.npmjs.org/lodash.castarray/-/lodash.castarray-4.4.0.tgz",
- "integrity": "sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/lodash.isplainobject": {
- "version": "4.0.6",
- "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
- "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==",
- "dev": true,
- "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/loupe": {
- "version": "2.3.7",
- "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz",
- "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "get-func-name": "^2.0.1"
- }
- },
- "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/lucide-react": {
- "version": "0.263.1",
- "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.263.1.tgz",
- "integrity": "sha512-keqxAx97PlaEN89PXZ6ki1N8nRjGWtDa4021GFYLNj0RgruM5odbpl8GHTExj0hhPq3sF6Up0gnxt6TSHu+ovw==",
- "license": "ISC",
- "peerDependencies": {
- "react": "^16.5.1 || ^17.0.0 || ^18.0.0"
- }
- },
- "node_modules/lz-string": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz",
- "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==",
- "dev": true,
- "license": "MIT",
- "bin": {
- "lz-string": "bin/bin.js"
- }
- },
- "node_modules/magic-string": {
- "version": "0.30.17",
- "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz",
- "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jridgewell/sourcemap-codec": "^1.5.0"
- }
- },
- "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==",
- "dev": true,
- "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/micromatch/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/min-indent": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz",
- "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/mini-svg-data-uri": {
- "version": "1.4.4",
- "resolved": "https://registry.npmjs.org/mini-svg-data-uri/-/mini-svg-data-uri-1.4.4.tgz",
- "integrity": "sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==",
- "dev": true,
- "license": "MIT",
- "bin": {
- "mini-svg-data-uri": "cli.js"
- }
- },
- "node_modules/minimatch": {
- "version": "9.0.3",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz",
- "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==",
- "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/minipass": {
- "version": "7.1.2",
- "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
- "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
- "dev": true,
- "license": "ISC",
- "engines": {
- "node": ">=16 || 14 >=14.17"
- }
- },
- "node_modules/mlly": {
- "version": "1.7.4",
- "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.4.tgz",
- "integrity": "sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "acorn": "^8.14.0",
- "pathe": "^2.0.1",
- "pkg-types": "^1.3.0",
- "ufo": "^1.5.4"
- }
- },
- "node_modules/mlly/node_modules/pathe": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz",
- "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/mrmime": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz",
- "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/ms": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
- "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/mz": {
- "version": "2.7.0",
- "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz",
- "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "any-promise": "^1.0.0",
- "object-assign": "^4.0.1",
- "thenify-all": "^1.0.0"
- }
- },
- "node_modules/nanoid": {
- "version": "3.3.11",
- "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
- "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
- "dev": true,
- "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-path": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
- "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "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/object-hash": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz",
- "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/object-inspect": {
- "version": "1.13.4",
- "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
- "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/object-is": {
- "version": "1.1.6",
- "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz",
- "integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bind": "^1.0.7",
- "define-properties": "^1.2.1"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/object-keys": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
- "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/object.assign": {
- "version": "4.1.7",
- "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz",
- "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bind": "^1.0.8",
- "call-bound": "^1.0.3",
- "define-properties": "^1.2.1",
- "es-object-atoms": "^1.0.0",
- "has-symbols": "^1.1.0",
- "object-keys": "^1.1.1"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/once": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
- "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "wrappy": "1"
- }
- },
- "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/package-json-from-dist": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz",
- "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==",
- "dev": true,
- "license": "BlueOak-1.0.0"
- },
- "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-is-absolute": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
- "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "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/path-parse": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
- "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/path-scurry": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
- "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
- "dev": true,
- "license": "BlueOak-1.0.0",
- "dependencies": {
- "lru-cache": "^10.2.0",
- "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
- },
- "engines": {
- "node": ">=16 || 14 >=14.18"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/path-scurry/node_modules/lru-cache": {
- "version": "10.4.3",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
- "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
- "dev": true,
- "license": "ISC"
- },
- "node_modules/path-type": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
- "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/pathe": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz",
- "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/pathval": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz",
- "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": "*"
- }
- },
- "node_modules/picocolors": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
- "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
- "dev": true,
- "license": "ISC"
- },
- "node_modules/picomatch": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
- "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/jonschlinkert"
- }
- },
- "node_modules/pify": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
- "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/pirates": {
- "version": "4.0.7",
- "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz",
- "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/pkg-types": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz",
- "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "confbox": "^0.1.8",
- "mlly": "^1.7.4",
- "pathe": "^2.0.1"
- }
- },
- "node_modules/pkg-types/node_modules/pathe": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz",
- "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/possible-typed-array-names": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz",
- "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/postcss": {
- "version": "8.5.6",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz",
- "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==",
- "dev": true,
- "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-import": {
- "version": "15.1.0",
- "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz",
- "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "postcss-value-parser": "^4.0.0",
- "read-cache": "^1.0.0",
- "resolve": "^1.1.7"
- },
- "engines": {
- "node": ">=14.0.0"
- },
- "peerDependencies": {
- "postcss": "^8.0.0"
- }
- },
- "node_modules/postcss-js": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz",
- "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "camelcase-css": "^2.0.1"
- },
- "engines": {
- "node": "^12 || ^14 || >= 16"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/postcss/"
- },
- "peerDependencies": {
- "postcss": "^8.4.21"
- }
- },
- "node_modules/postcss-load-config": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz",
- "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==",
- "dev": true,
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/postcss/"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "lilconfig": "^3.0.0",
- "yaml": "^2.3.4"
- },
- "engines": {
- "node": ">= 14"
- },
- "peerDependencies": {
- "postcss": ">=8.0.9",
- "ts-node": ">=9.0.0"
- },
- "peerDependenciesMeta": {
- "postcss": {
- "optional": true
- },
- "ts-node": {
- "optional": true
- }
- }
- },
- "node_modules/postcss-nested": {
- "version": "6.2.0",
- "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz",
- "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==",
- "dev": true,
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/postcss/"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "postcss-selector-parser": "^6.1.1"
- },
- "engines": {
- "node": ">=12.0"
- },
- "peerDependencies": {
- "postcss": "^8.2.14"
- }
- },
- "node_modules/postcss-nested/node_modules/postcss-selector-parser": {
- "version": "6.1.2",
- "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz",
- "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "cssesc": "^3.0.0",
- "util-deprecate": "^1.0.2"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/postcss-selector-parser": {
- "version": "6.0.10",
- "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz",
- "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "cssesc": "^3.0.0",
- "util-deprecate": "^1.0.2"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "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/pretty-format": {
- "version": "27.5.1",
- "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz",
- "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ansi-regex": "^5.0.1",
- "ansi-styles": "^5.0.0",
- "react-is": "^17.0.1"
- },
- "engines": {
- "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
- }
- },
- "node_modules/pretty-format/node_modules/ansi-styles": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
- "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "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/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/react": {
- "version": "18.3.1",
- "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz",
- "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==",
- "license": "MIT",
- "dependencies": {
- "loose-envify": "^1.1.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/react-dom": {
- "version": "18.3.1",
- "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",
- "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==",
- "license": "MIT",
- "dependencies": {
- "loose-envify": "^1.1.0",
- "scheduler": "^0.23.2"
- },
- "peerDependencies": {
- "react": "^18.3.1"
- }
- },
- "node_modules/react-hook-form": {
- "version": "7.62.0",
- "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.62.0.tgz",
- "integrity": "sha512-7KWFejc98xqG/F4bAxpL41NB3o1nnvQO1RWZT3TqRZYL8RryQETGfEdVnJN2fy1crCiBLLjkRBVK05j24FxJGA==",
- "license": "MIT",
- "engines": {
- "node": ">=18.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/react-hook-form"
- },
- "peerDependencies": {
- "react": "^16.8.0 || ^17 || ^18 || ^19"
- }
- },
- "node_modules/react-hot-toast": {
- "version": "2.5.2",
- "resolved": "https://registry.npmjs.org/react-hot-toast/-/react-hot-toast-2.5.2.tgz",
- "integrity": "sha512-Tun3BbCxzmXXM7C+NI4qiv6lT0uwGh4oAfeJyNOjYUejTsm35mK9iCaYLGv8cBz9L5YxZLx/2ii7zsIwPtPUdw==",
- "license": "MIT",
- "dependencies": {
- "csstype": "^3.1.3",
- "goober": "^2.1.16"
- },
- "engines": {
- "node": ">=10"
- },
- "peerDependencies": {
- "react": ">=16",
- "react-dom": ">=16"
- }
- },
- "node_modules/react-i18next": {
- "version": "13.5.0",
- "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-13.5.0.tgz",
- "integrity": "sha512-CFJ5NDGJ2MUyBohEHxljOq/39NQ972rh1ajnadG9BjTk+UXbHLq4z5DKEbEQBDoIhUmmbuS/fIMJKo6VOax1HA==",
- "license": "MIT",
- "dependencies": {
- "@babel/runtime": "^7.22.5",
- "html-parse-stringify": "^3.0.1"
- },
- "peerDependencies": {
- "i18next": ">= 23.2.3",
- "react": ">= 16.8.0"
- },
- "peerDependenciesMeta": {
- "react-dom": {
- "optional": true
- },
- "react-native": {
- "optional": true
- }
- }
- },
- "node_modules/react-is": {
- "version": "17.0.2",
- "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
- "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/react-redux": {
- "version": "8.1.3",
- "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-8.1.3.tgz",
- "integrity": "sha512-n0ZrutD7DaX/j9VscF+uTALI3oUPa/pO4Z3soOBIjuRn/FzVu6aehhysxZCLi6y7duMf52WNZGMl7CtuK5EnRw==",
- "license": "MIT",
- "dependencies": {
- "@babel/runtime": "^7.12.1",
- "@types/hoist-non-react-statics": "^3.3.1",
- "@types/use-sync-external-store": "^0.0.3",
- "hoist-non-react-statics": "^3.3.2",
- "react-is": "^18.0.0",
- "use-sync-external-store": "^1.0.0"
- },
- "peerDependencies": {
- "@types/react": "^16.8 || ^17.0 || ^18.0",
- "@types/react-dom": "^16.8 || ^17.0 || ^18.0",
- "react": "^16.8 || ^17.0 || ^18.0",
- "react-dom": "^16.8 || ^17.0 || ^18.0",
- "react-native": ">=0.59",
- "redux": "^4 || ^5.0.0-beta.0"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- },
- "react-dom": {
- "optional": true
- },
- "react-native": {
- "optional": true
- },
- "redux": {
- "optional": true
- }
- }
- },
- "node_modules/react-redux/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-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": "6.30.1",
- "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.30.1.tgz",
- "integrity": "sha512-X1m21aEmxGXqENEPG3T6u0Th7g0aS4ZmoNynhbs+Cn+q+QGTLt+d5IQ2bHAXKzKcxGJjxACpVbnYQSCRcfxHlQ==",
- "license": "MIT",
- "dependencies": {
- "@remix-run/router": "1.23.0"
- },
- "engines": {
- "node": ">=14.0.0"
- },
- "peerDependencies": {
- "react": ">=16.8"
- }
- },
- "node_modules/react-router-dom": {
- "version": "6.30.1",
- "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.30.1.tgz",
- "integrity": "sha512-llKsgOkZdbPU1Eg3zK8lCn+sjD9wMRZZPuzmdWWX5SUs8OFkN5HnFVC0u5KMeMaC9aoancFI/KoLuKPqN+hxHw==",
- "license": "MIT",
- "dependencies": {
- "@remix-run/router": "1.23.0",
- "react-router": "6.30.1"
- },
- "engines": {
- "node": ">=14.0.0"
- },
- "peerDependencies": {
- "react": ">=16.8",
- "react-dom": ">=16.8"
- }
- },
- "node_modules/react-smooth": {
- "version": "4.0.4",
- "resolved": "https://registry.npmjs.org/react-smooth/-/react-smooth-4.0.4.tgz",
- "integrity": "sha512-gnGKTpYwqL0Iii09gHobNolvX4Kiq4PKx6eWBCYYix+8cdw+cGo3do906l1NBPKkSWx1DghC1dlWG9L2uGd61Q==",
- "license": "MIT",
- "dependencies": {
- "fast-equals": "^5.0.1",
- "prop-types": "^15.8.1",
- "react-transition-group": "^4.4.5"
- },
- "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/react-transition-group": {
- "version": "4.4.5",
- "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz",
- "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==",
- "license": "BSD-3-Clause",
- "dependencies": {
- "@babel/runtime": "^7.5.5",
- "dom-helpers": "^5.0.1",
- "loose-envify": "^1.4.0",
- "prop-types": "^15.6.2"
- },
- "peerDependencies": {
- "react": ">=16.6.0",
- "react-dom": ">=16.6.0"
- }
- },
- "node_modules/read-cache": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
- "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "pify": "^2.3.0"
- }
- },
- "node_modules/readdirp": {
- "version": "3.6.0",
- "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
- "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "picomatch": "^2.2.1"
- },
- "engines": {
- "node": ">=8.10.0"
- }
- },
- "node_modules/readdirp/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/recharts": {
- "version": "2.15.4",
- "resolved": "https://registry.npmjs.org/recharts/-/recharts-2.15.4.tgz",
- "integrity": "sha512-UT/q6fwS3c1dHbXv2uFgYJ9BMFHu3fwnd7AYZaEQhXuYQ4hgsxLvsUXzGdKeZrW5xopzDCvuA2N41WJ88I7zIw==",
- "license": "MIT",
- "dependencies": {
- "clsx": "^2.0.0",
- "eventemitter3": "^4.0.1",
- "lodash": "^4.17.21",
- "react-is": "^18.3.1",
- "react-smooth": "^4.0.4",
- "recharts-scale": "^0.4.4",
- "tiny-invariant": "^1.3.1",
- "victory-vendor": "^36.6.8"
- },
- "engines": {
- "node": ">=14"
- },
- "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/recharts-scale": {
- "version": "0.4.5",
- "resolved": "https://registry.npmjs.org/recharts-scale/-/recharts-scale-0.4.5.tgz",
- "integrity": "sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w==",
- "license": "MIT",
- "dependencies": {
- "decimal.js-light": "^2.4.1"
- }
- },
- "node_modules/recharts/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/redent": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz",
- "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "indent-string": "^4.0.0",
- "strip-indent": "^3.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/redux": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz",
- "integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==",
- "license": "MIT",
- "dependencies": {
- "@babel/runtime": "^7.9.2"
- }
- },
- "node_modules/redux-thunk": {
- "version": "2.4.2",
- "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.4.2.tgz",
- "integrity": "sha512-+P3TjtnP0k/FEjcBL5FZpoovtvrTNT/UXd4/sluaSyrURlSlhLSzEdfsTBW7WsKB6yPvgd7q/iZPICFjW4o57Q==",
- "license": "MIT",
- "peerDependencies": {
- "redux": "^4"
- }
- },
- "node_modules/regexp.prototype.flags": {
- "version": "1.5.4",
- "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz",
- "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bind": "^1.0.8",
- "define-properties": "^1.2.1",
- "es-errors": "^1.3.0",
- "get-proto": "^1.0.1",
- "gopd": "^1.2.0",
- "set-function-name": "^2.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/reselect": {
- "version": "4.1.8",
- "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.8.tgz",
- "integrity": "sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ==",
- "license": "MIT"
- },
- "node_modules/resolve": {
- "version": "1.22.10",
- "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz",
- "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "is-core-module": "^2.16.0",
- "path-parse": "^1.0.7",
- "supports-preserve-symlinks-flag": "^1.0.0"
- },
- "bin": {
- "resolve": "bin/resolve"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "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/rimraf": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
- "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
- "deprecated": "Rimraf versions prior to v4 are no longer supported",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "glob": "^7.1.3"
- },
- "bin": {
- "rimraf": "bin.js"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/rollup": {
- "version": "3.29.5",
- "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.5.tgz",
- "integrity": "sha512-GVsDdsbJzzy4S/v3dqWPJ7EfvZJfCHiDqe80IyrF59LYuP+e6U1LJoUqeuqRbwAWoMNoXivMNeNAOf5E22VA1w==",
- "dev": true,
- "license": "MIT",
- "bin": {
- "rollup": "dist/bin/rollup"
- },
- "engines": {
- "node": ">=14.18.0",
- "npm": ">=8.0.0"
- },
- "optionalDependencies": {
- "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/safe-regex-test": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz",
- "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bound": "^1.0.2",
- "es-errors": "^1.3.0",
- "is-regex": "^1.2.1"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/scheduler": {
- "version": "0.23.2",
- "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz",
- "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==",
- "license": "MIT",
- "dependencies": {
- "loose-envify": "^1.1.0"
- }
- },
- "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/set-function-length": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
- "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "define-data-property": "^1.1.4",
- "es-errors": "^1.3.0",
- "function-bind": "^1.1.2",
- "get-intrinsic": "^1.2.4",
- "gopd": "^1.0.1",
- "has-property-descriptors": "^1.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/set-function-name": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz",
- "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "define-data-property": "^1.1.4",
- "es-errors": "^1.3.0",
- "functions-have-names": "^1.2.3",
- "has-property-descriptors": "^1.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "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/side-channel": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
- "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "es-errors": "^1.3.0",
- "object-inspect": "^1.13.3",
- "side-channel-list": "^1.0.0",
- "side-channel-map": "^1.0.1",
- "side-channel-weakmap": "^1.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/side-channel-list": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
- "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "es-errors": "^1.3.0",
- "object-inspect": "^1.13.3"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/side-channel-map": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
- "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bound": "^1.0.2",
- "es-errors": "^1.3.0",
- "get-intrinsic": "^1.2.5",
- "object-inspect": "^1.13.3"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/side-channel-weakmap": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
- "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bound": "^1.0.2",
- "es-errors": "^1.3.0",
- "get-intrinsic": "^1.2.5",
- "object-inspect": "^1.13.3",
- "side-channel-map": "^1.0.1"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/siginfo": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz",
- "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==",
- "dev": true,
- "license": "ISC"
- },
- "node_modules/signal-exit": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
- "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
- "dev": true,
- "license": "ISC",
- "engines": {
- "node": ">=14"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/sirv": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.4.tgz",
- "integrity": "sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@polka/url": "^1.0.0-next.24",
- "mrmime": "^2.0.0",
- "totalist": "^3.0.0"
- },
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/slash": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
- "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/source-map-js": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
- "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
- "dev": true,
- "license": "BSD-3-Clause",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/stack-utils": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz",
- "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "escape-string-regexp": "^2.0.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/stack-utils/node_modules/escape-string-regexp": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz",
- "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/stackback": {
- "version": "0.0.2",
- "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz",
- "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/std-env": {
- "version": "3.9.0",
- "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.9.0.tgz",
- "integrity": "sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/stop-iteration-iterator": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz",
- "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "es-errors": "^1.3.0",
- "internal-slot": "^1.1.0"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/string-width": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
- "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "eastasianwidth": "^0.2.0",
- "emoji-regex": "^9.2.2",
- "strip-ansi": "^7.0.1"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/string-width-cjs": {
- "name": "string-width",
- "version": "4.2.3",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
- "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "emoji-regex": "^8.0.0",
- "is-fullwidth-code-point": "^3.0.0",
- "strip-ansi": "^6.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/string-width-cjs/node_modules/emoji-regex": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
- "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/string-width/node_modules/ansi-regex": {
- "version": "6.1.0",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz",
- "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-regex?sponsor=1"
- }
- },
- "node_modules/string-width/node_modules/strip-ansi": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
- "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ansi-regex": "^6.0.1"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/chalk/strip-ansi?sponsor=1"
- }
- },
- "node_modules/strip-ansi": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
- "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ansi-regex": "^5.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/strip-ansi-cjs": {
- "name": "strip-ansi",
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
- "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ansi-regex": "^5.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/strip-indent": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz",
- "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "min-indent": "^1.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "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/strip-literal": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-1.3.0.tgz",
- "integrity": "sha512-PugKzOsyXpArk0yWmUwqOZecSO0GH0bPoctLcqNDH9J04pVW3lflYE0ujElBGTloevcxF5MofAOZ7C5l2b+wLg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "acorn": "^8.10.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/antfu"
- }
- },
- "node_modules/sucrase": {
- "version": "3.35.0",
- "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz",
- "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jridgewell/gen-mapping": "^0.3.2",
- "commander": "^4.0.0",
- "glob": "^10.3.10",
- "lines-and-columns": "^1.1.6",
- "mz": "^2.7.0",
- "pirates": "^4.0.1",
- "ts-interface-checker": "^0.1.9"
- },
- "bin": {
- "sucrase": "bin/sucrase",
- "sucrase-node": "bin/sucrase-node"
- },
- "engines": {
- "node": ">=16 || 14 >=14.17"
- }
- },
- "node_modules/sucrase/node_modules/glob": {
- "version": "10.4.5",
- "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
- "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "foreground-child": "^3.1.0",
- "jackspeak": "^3.1.2",
- "minimatch": "^9.0.4",
- "minipass": "^7.1.2",
- "package-json-from-dist": "^1.0.0",
- "path-scurry": "^1.11.1"
- },
- "bin": {
- "glob": "dist/esm/bin.mjs"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/sucrase/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/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/supports-preserve-symlinks-flag": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
- "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/tailwind-merge": {
- "version": "1.14.0",
- "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-1.14.0.tgz",
- "integrity": "sha512-3mFKyCo/MBcgyOTlrY8T7odzZFx+w+qKSMAmdFzRvqBfLlSigU6TZnlFHK0lkMwj9Bj8OYU+9yW9lmGuS0QEnQ==",
- "license": "MIT",
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/dcastil"
- }
- },
- "node_modules/tailwindcss": {
- "version": "3.4.17",
- "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.17.tgz",
- "integrity": "sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@alloc/quick-lru": "^5.2.0",
- "arg": "^5.0.2",
- "chokidar": "^3.6.0",
- "didyoumean": "^1.2.2",
- "dlv": "^1.1.3",
- "fast-glob": "^3.3.2",
- "glob-parent": "^6.0.2",
- "is-glob": "^4.0.3",
- "jiti": "^1.21.6",
- "lilconfig": "^3.1.3",
- "micromatch": "^4.0.8",
- "normalize-path": "^3.0.0",
- "object-hash": "^3.0.0",
- "picocolors": "^1.1.1",
- "postcss": "^8.4.47",
- "postcss-import": "^15.1.0",
- "postcss-js": "^4.0.1",
- "postcss-load-config": "^4.0.2",
- "postcss-nested": "^6.2.0",
- "postcss-selector-parser": "^6.1.2",
- "resolve": "^1.22.8",
- "sucrase": "^3.35.0"
- },
- "bin": {
- "tailwind": "lib/cli.js",
- "tailwindcss": "lib/cli.js"
- },
- "engines": {
- "node": ">=14.0.0"
- }
- },
- "node_modules/tailwindcss/node_modules/postcss-selector-parser": {
- "version": "6.1.2",
- "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz",
- "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "cssesc": "^3.0.0",
- "util-deprecate": "^1.0.2"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/text-table": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
- "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/thenify": {
- "version": "3.3.1",
- "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz",
- "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "any-promise": "^1.0.0"
- }
- },
- "node_modules/thenify-all": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz",
- "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "thenify": ">= 3.1.0 < 4"
- },
- "engines": {
- "node": ">=0.8"
- }
- },
- "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/tinybench": {
- "version": "2.9.0",
- "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz",
- "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/tinypool": {
- "version": "0.7.0",
- "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.7.0.tgz",
- "integrity": "sha512-zSYNUlYSMhJ6Zdou4cJwo/p7w5nmAH17GRfU/ui3ctvjXFErXXkruT4MWW6poDeXgCaIBlGLrfU6TbTXxyGMww==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=14.0.0"
- }
- },
- "node_modules/tinyspy": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-2.2.1.tgz",
- "integrity": "sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=14.0.0"
- }
- },
- "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/totalist": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz",
- "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/ts-api-utils": {
- "version": "1.4.3",
- "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.3.tgz",
- "integrity": "sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=16"
- },
- "peerDependencies": {
- "typescript": ">=4.2.0"
- }
- },
- "node_modules/ts-interface-checker": {
- "version": "0.1.13",
- "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz",
- "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==",
- "dev": true,
- "license": "Apache-2.0"
- },
- "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-detect": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz",
- "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/type-fest": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
- "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
- "dev": true,
- "license": "(MIT OR CC0-1.0)",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/typescript": {
- "version": "5.9.2",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz",
- "integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==",
- "dev": true,
- "license": "Apache-2.0",
- "bin": {
- "tsc": "bin/tsc",
- "tsserver": "bin/tsserver"
- },
- "engines": {
- "node": ">=14.17"
- }
- },
- "node_modules/ufo": {
- "version": "1.6.1",
- "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.1.tgz",
- "integrity": "sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/undici-types": {
- "version": "7.10.0",
- "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.10.0.tgz",
- "integrity": "sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==",
- "dev": 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/util-deprecate": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
- "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/victory-vendor": {
- "version": "36.9.2",
- "resolved": "https://registry.npmjs.org/victory-vendor/-/victory-vendor-36.9.2.tgz",
- "integrity": "sha512-PnpQQMuxlwYdocC8fIJqVXvkeViHYzotI+NJrCuav0ZYFoq912ZHBk3mCeuj+5/VpodOjPe1z0Fk2ihgzlXqjQ==",
- "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": "4.5.14",
- "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.14.tgz",
- "integrity": "sha512-+v57oAaoYNnO3hIu5Z/tJRZjq5aHM2zDve9YZ8HngVHbhk66RStobhb1sqPMIPEleV6cNKYK4eGrAbE9Ulbl2g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "esbuild": "^0.18.10",
- "postcss": "^8.4.27",
- "rollup": "^3.27.1"
- },
- "bin": {
- "vite": "bin/vite.js"
- },
- "engines": {
- "node": "^14.18.0 || >=16.0.0"
- },
- "funding": {
- "url": "https://github.com/vitejs/vite?sponsor=1"
- },
- "optionalDependencies": {
- "fsevents": "~2.3.2"
- },
- "peerDependencies": {
- "@types/node": ">= 14",
- "less": "*",
- "lightningcss": "^1.21.0",
- "sass": "*",
- "stylus": "*",
- "sugarss": "*",
- "terser": "^5.4.0"
- },
- "peerDependenciesMeta": {
- "@types/node": {
- "optional": true
- },
- "less": {
- "optional": true
- },
- "lightningcss": {
- "optional": true
- },
- "sass": {
- "optional": true
- },
- "stylus": {
- "optional": true
- },
- "sugarss": {
- "optional": true
- },
- "terser": {
- "optional": true
- }
- }
- },
- "node_modules/vite-node": {
- "version": "0.34.6",
- "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-0.34.6.tgz",
- "integrity": "sha512-nlBMJ9x6n7/Amaz6F3zJ97EBwR2FkzhBRxF5e+jE6LA3yi6Wtc2lyTij1OnDMIr34v5g/tVQtsVAzhT0jc5ygA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "cac": "^6.7.14",
- "debug": "^4.3.4",
- "mlly": "^1.4.0",
- "pathe": "^1.1.1",
- "picocolors": "^1.0.0",
- "vite": "^3.0.0 || ^4.0.0 || ^5.0.0-0"
- },
- "bin": {
- "vite-node": "vite-node.mjs"
- },
- "engines": {
- "node": ">=v14.18.0"
- },
- "funding": {
- "url": "https://opencollective.com/vitest"
- }
- },
- "node_modules/vitest": {
- "version": "0.34.6",
- "resolved": "https://registry.npmjs.org/vitest/-/vitest-0.34.6.tgz",
- "integrity": "sha512-+5CALsOvbNKnS+ZHMXtuUC7nL8/7F1F2DnHGjSsszX8zCjWSSviphCb/NuS9Nzf4Q03KyyDRBAXhF/8lffME4Q==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/chai": "^4.3.5",
- "@types/chai-subset": "^1.3.3",
- "@types/node": "*",
- "@vitest/expect": "0.34.6",
- "@vitest/runner": "0.34.6",
- "@vitest/snapshot": "0.34.6",
- "@vitest/spy": "0.34.6",
- "@vitest/utils": "0.34.6",
- "acorn": "^8.9.0",
- "acorn-walk": "^8.2.0",
- "cac": "^6.7.14",
- "chai": "^4.3.10",
- "debug": "^4.3.4",
- "local-pkg": "^0.4.3",
- "magic-string": "^0.30.1",
- "pathe": "^1.1.1",
- "picocolors": "^1.0.0",
- "std-env": "^3.3.3",
- "strip-literal": "^1.0.1",
- "tinybench": "^2.5.0",
- "tinypool": "^0.7.0",
- "vite": "^3.1.0 || ^4.0.0 || ^5.0.0-0",
- "vite-node": "0.34.6",
- "why-is-node-running": "^2.2.2"
- },
- "bin": {
- "vitest": "vitest.mjs"
- },
- "engines": {
- "node": ">=v14.18.0"
- },
- "funding": {
- "url": "https://opencollective.com/vitest"
- },
- "peerDependencies": {
- "@edge-runtime/vm": "*",
- "@vitest/browser": "*",
- "@vitest/ui": "*",
- "happy-dom": "*",
- "jsdom": "*",
- "playwright": "*",
- "safaridriver": "*",
- "webdriverio": "*"
- },
- "peerDependenciesMeta": {
- "@edge-runtime/vm": {
- "optional": true
- },
- "@vitest/browser": {
- "optional": true
- },
- "@vitest/ui": {
- "optional": true
- },
- "happy-dom": {
- "optional": true
- },
- "jsdom": {
- "optional": true
- },
- "playwright": {
- "optional": true
- },
- "safaridriver": {
- "optional": true
- },
- "webdriverio": {
- "optional": true
- }
- }
- },
- "node_modules/vitest/node_modules/@jest/schemas": {
- "version": "29.6.3",
- "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz",
- "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@sinclair/typebox": "^0.27.8"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/vitest/node_modules/@sinclair/typebox": {
- "version": "0.27.8",
- "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz",
- "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/vitest/node_modules/@vitest/utils": {
- "version": "0.34.6",
- "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-0.34.6.tgz",
- "integrity": "sha512-IG5aDD8S6zlvloDsnzHw0Ut5xczlF+kv2BOTo+iXfPr54Yhi5qbVOgGB1hZaVq4iJ4C/MZ2J0y15IlsV/ZcI0A==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "diff-sequences": "^29.4.3",
- "loupe": "^2.3.6",
- "pretty-format": "^29.5.0"
- },
- "funding": {
- "url": "https://opencollective.com/vitest"
- }
- },
- "node_modules/vitest/node_modules/ansi-styles": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
- "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/vitest/node_modules/pretty-format": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz",
- "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/schemas": "^29.6.3",
- "ansi-styles": "^5.0.0",
- "react-is": "^18.0.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/vitest/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==",
- "dev": true,
- "license": "MIT"
- },
- "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/which-boxed-primitive": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz",
- "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "is-bigint": "^1.1.0",
- "is-boolean-object": "^1.2.1",
- "is-number-object": "^1.1.1",
- "is-string": "^1.1.1",
- "is-symbol": "^1.1.1"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/which-collection": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz",
- "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "is-map": "^2.0.3",
- "is-set": "^2.0.3",
- "is-weakmap": "^2.0.2",
- "is-weakset": "^2.0.3"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/which-typed-array": {
- "version": "1.1.19",
- "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz",
- "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "available-typed-arrays": "^1.0.7",
- "call-bind": "^1.0.8",
- "call-bound": "^1.0.4",
- "for-each": "^0.3.5",
- "get-proto": "^1.0.1",
- "gopd": "^1.2.0",
- "has-tostringtag": "^1.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/why-is-node-running": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz",
- "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "siginfo": "^2.0.0",
- "stackback": "0.0.2"
- },
- "bin": {
- "why-is-node-running": "cli.js"
- },
- "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/wrap-ansi": {
- "version": "8.1.0",
- "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
- "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ansi-styles": "^6.1.0",
- "string-width": "^5.0.1",
- "strip-ansi": "^7.0.1"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
- }
- },
- "node_modules/wrap-ansi-cjs": {
- "name": "wrap-ansi",
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
- "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ansi-styles": "^4.0.0",
- "string-width": "^4.1.0",
- "strip-ansi": "^6.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
- }
- },
- "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
- "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/wrap-ansi-cjs/node_modules/string-width": {
- "version": "4.2.3",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
- "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "emoji-regex": "^8.0.0",
- "is-fullwidth-code-point": "^3.0.0",
- "strip-ansi": "^6.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/wrap-ansi/node_modules/ansi-regex": {
- "version": "6.1.0",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz",
- "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-regex?sponsor=1"
- }
- },
- "node_modules/wrap-ansi/node_modules/ansi-styles": {
- "version": "6.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
- "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/wrap-ansi/node_modules/strip-ansi": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
- "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ansi-regex": "^6.0.1"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/chalk/strip-ansi?sponsor=1"
- }
- },
- "node_modules/wrappy": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
- "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
- "dev": true,
- "license": "ISC"
- },
- "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/yaml": {
- "version": "2.8.1",
- "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.1.tgz",
- "integrity": "sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==",
- "dev": true,
- "license": "ISC",
- "bin": {
- "yaml": "bin.mjs"
- },
- "engines": {
- "node": ">= 14.6"
- }
- },
- "node_modules/yocto-queue": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
- "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/zod": {
- "version": "3.25.76",
- "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
- "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
- "license": "MIT",
- "funding": {
- "url": "https://github.com/sponsors/colinhacks"
- }
- }
- }
-}
diff --git a/fdev-ffrontend/package.json b/fdev-ffrontend/package.json
deleted file mode 100644
index 76b7241c..00000000
--- a/fdev-ffrontend/package.json
+++ /dev/null
@@ -1,75 +0,0 @@
-{
- "name": "pania-frontend",
- "version": "1.0.0",
- "description": "AI-powered bakery demand forecasting platform for Madrid",
- "type": "module",
- "scripts": {
- "dev": "vite",
- "build": "tsc && vite build",
- "preview": "vite preview",
- "test": "vitest",
- "test:ui": "vitest --ui",
- "test:coverage": "vitest --coverage",
- "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
- "lint:fix": "eslint . --ext ts,tsx --fix"
- },
- "dependencies": {
- "@hookform/resolvers": "^3.3.1",
- "@reduxjs/toolkit": "^1.9.5",
- "@stripe/react-stripe-js": "^3.9.0",
- "@stripe/stripe-js": "^7.8.0",
- "clsx": "^2.0.0",
- "date-fns": "^2.30.0",
- "date-fns-tz": "^2.0.0",
- "i18next": "^23.4.4",
- "i18next-browser-languagedetector": "^7.1.0",
- "lucide-react": "^0.263.1",
- "react": "^18.2.0",
- "react-dom": "^18.2.0",
- "react-hook-form": "^7.45.4",
- "react-hot-toast": "^2.4.1",
- "react-i18next": "^13.1.2",
- "react-redux": "^8.1.2",
- "react-router-dom": "^6.15.0",
- "recharts": "^2.8.0",
- "tailwind-merge": "^1.14.0",
- "zod": "^3.22.2"
- },
- "devDependencies": {
- "@tailwindcss/forms": "^0.5.4",
- "@tailwindcss/typography": "^0.5.9",
- "@testing-library/jest-dom": "^5.17.0",
- "@testing-library/react": "^13.4.0",
- "@testing-library/user-event": "^14.4.3",
- "@types/react": "^18.2.15",
- "@types/react-dom": "^18.2.7",
- "@typescript-eslint/eslint-plugin": "^6.0.0",
- "@typescript-eslint/parser": "^6.0.0",
- "@vitejs/plugin-react": "^4.0.3",
- "@vitest/ui": "^0.34.1",
- "autoprefixer": "^10.4.14",
- "eslint": "^8.45.0",
- "eslint-plugin-react-hooks": "^4.6.0",
- "eslint-plugin-react-refresh": "^0.4.3",
- "postcss": "^8.4.27",
- "tailwindcss": "^3.3.0",
- "typescript": "^5.0.2",
- "vite": "^4.4.5",
- "vitest": "^0.34.1"
- },
- "keywords": [
- "bakery",
- "forecasting",
- "ai",
- "madrid",
- "react",
- "typescript",
- "tailwind"
- ],
- "repository": {
- "type": "git",
- "url": "https://github.com/pania-es/frontend"
- },
- "author": "PanIA Team",
- "license": "MIT"
-}
diff --git a/fdev-ffrontend/postcss.config.js b/fdev-ffrontend/postcss.config.js
deleted file mode 100644
index e99ebc2c..00000000
--- a/fdev-ffrontend/postcss.config.js
+++ /dev/null
@@ -1,6 +0,0 @@
-export default {
- plugins: {
- tailwindcss: {},
- autoprefixer: {},
- },
-}
\ No newline at end of file
diff --git a/fdev-ffrontend/src/App.tsx b/fdev-ffrontend/src/App.tsx
deleted file mode 100644
index 5ccda2ad..00000000
--- a/fdev-ffrontend/src/App.tsx
+++ /dev/null
@@ -1,67 +0,0 @@
-import React, { useEffect } from 'react';
-import { RouterProvider } from 'react-router-dom';
-import { Provider } from 'react-redux';
-import { Toaster } from 'react-hot-toast';
-import { router } from './router';
-import { store } from './store';
-import ErrorBoundary from './components/ErrorBoundary';
-import { useAuth } from './hooks/useAuth';
-
-// i18n
-import './i18n';
-
-// Global styles
-import './styles/globals.css';
-
-const AppContent: React.FC = () => {
- const { initializeAuth } = useAuth();
-
- useEffect(() => {
- initializeAuth();
- }, [initializeAuth]);
-
- return (
-
-
-
-
- {/* Global Toast Notifications */}
-
-
-
- );
-};
-
-const App: React.FC = () => {
- return (
-
-
-
- );
-};
-
-export default App;
\ No newline at end of file
diff --git a/fdev-ffrontend/src/api/README.md b/fdev-ffrontend/src/api/README.md
deleted file mode 100644
index 45a6e599..00000000
--- a/fdev-ffrontend/src/api/README.md
+++ /dev/null
@@ -1,85 +0,0 @@
-frontend/src/api/
-├── client/ # HTTP client configuration
-│ ├── index.ts # Main API client
-│ ├── config.ts # Client configuration
-│ ├── interceptors.ts # Request/response interceptors
-│ └── types.ts # Client-specific types
-├── services/ # Service-specific API calls
-│ ├── index.ts # Export all services
-│ ├── auth.service.ts # Authentication operations
-│ ├── tenant.service.ts # Tenant management
-│ ├── data.service.ts # Data operations
-│ ├── training.service.ts # ML training operations
-│ ├── forecasting.service.ts # Forecasting operations
-│ └── notification.service.ts # Notification operations
-├── types/ # TypeScript definitions
-│ ├── index.ts # Re-export all types
-│ ├── common.ts # Common API types
-│ ├── auth.ts # Authentication types
-│ ├── tenant.ts # Tenant types
-│ ├── data.ts # Data types
-│ ├── training.ts # Training types
-│ ├── forecasting.ts # Forecasting types
-│ └── notification.ts # Notification types
-├── hooks/ # React hooks for API calls
-│ ├── index.ts # Export all hooks
-│ ├── useAuth.ts # Authentication hooks
-│ ├── useTenant.ts # Tenant hooks
-│ ├── useData.ts # Data hooks
-│ ├── useTraining.ts # Training hooks
-│ ├── useForecast.ts # Forecasting hooks
-│ └── useNotification.ts # Notification hooks
-├── utils/ # API utilities
-│ ├── index.ts # Export utilities
-│ ├── response.ts # Response handling
-│ ├── error.ts # Error handling
-│ ├── validation.ts # Request validation
-│ └── transform.ts # Data transformation
-├── websocket/ # WebSocket management
-│ ├── index.ts # WebSocket exports
-│ ├── manager.ts # WebSocket manager
-│ ├── types.ts # WebSocket types
-│ └── hooks.ts # WebSocket hooks
-└── index.ts # Main API exports
-```
-
-## 🎯 Key Improvements
-
-### 1. **Modern Architecture Patterns**
-- **Service Layer Pattern**: Clean separation of concerns
-- **Repository Pattern**: Consistent data access layer
-- **Factory Pattern**: Flexible service instantiation
-- **Observer Pattern**: Event-driven updates
-
-### 2. **Type Safety**
-- **Strict TypeScript**: Full type coverage
-- **Schema Validation**: Runtime type checking
-- **Generic Types**: Reusable type definitions
-- **Union Types**: Precise API responses
-
-### 3. **Error Handling**
-- **Centralized Error Management**: Consistent error handling
-- **Error Recovery**: Automatic retry mechanisms
-- **User-Friendly Messages**: Localized error messages
-- **Error Boundaries**: Component-level error isolation
-
-### 4. **Performance Optimization**
-- **Request Caching**: Intelligent cache management
-- **Request Deduplication**: Prevent duplicate calls
-- **Optimistic Updates**: Immediate UI feedback
-- **Background Sync**: Offline-first approach
-
-### 5. **Developer Experience**
-- **Auto-completion**: Full IntelliSense support
-- **Type-safe Hooks**: React hooks with types
-- **Error Prevention**: Compile-time error detection
-- **Documentation**: Comprehensive JSDoc comments
-
-## 🚀 Implementation Benefits
-
-1. **Maintainability**: Modular structure for easy updates
-2. **Scalability**: Easy to add new services and endpoints
-3. **Testability**: Isolated services for unit testing
-4. **Reusability**: Shared utilities and types
-5. **Type Safety**: Prevent runtime errors
-6. **Developer Productivity**: IntelliSense and auto-completion
\ No newline at end of file
diff --git a/fdev-ffrontend/src/api/client/config.ts b/fdev-ffrontend/src/api/client/config.ts
deleted file mode 100644
index 0b4b9c8f..00000000
--- a/fdev-ffrontend/src/api/client/config.ts
+++ /dev/null
@@ -1,142 +0,0 @@
-// frontend/src/api/client/config.ts
-/**
- * API Client Configuration
- * Centralized configuration for all API clients
- */
-
-export interface ApiConfig {
- baseURL: string;
- timeout: number;
- retries: number;
- retryDelay: number;
- enableLogging: boolean;
- enableCaching: boolean;
- cacheTimeout: number;
-}
-
-export interface ServiceEndpoints {
- auth: string;
- tenant: string;
- data: string;
- training: string;
- forecasting: string;
- notification: string;
-}
-
-// Environment-based configuration
-const getEnvironmentConfig = (): ApiConfig => {
- // Use import.meta.env instead of process.env for Vite
- const isDevelopment = import.meta.env.DEV;
- const isProduction = import.meta.env.PROD;
-
- return {
- baseURL: import.meta.env.VITE_API_URL || 'http://localhost:8000/api/v1',
- timeout: parseInt(import.meta.env.VITE_API_TIMEOUT || '30000'),
- retries: parseInt(import.meta.env.VITE_API_RETRIES || '3'),
- retryDelay: parseInt(import.meta.env.VITE_API_RETRY_DELAY || '1000'),
- enableLogging: isDevelopment || import.meta.env.VITE_API_LOGGING === 'true',
- enableCaching: import.meta.env.VITE_API_CACHING !== 'false',
- cacheTimeout: parseInt(import.meta.env.VITE_API_CACHE_TIMEOUT || '300000'), // 5 minutes
- };
-};
-
-export const apiConfig: ApiConfig = getEnvironmentConfig();
-
-// Service endpoint configuration
-export const serviceEndpoints: ServiceEndpoints = {
- auth: '/auth',
- tenant: '/tenants',
- data: '/tenants', // Data operations are tenant-scoped
- training: '/tenants', // Training operations are tenant-scoped
- forecasting: '/tenants', // Forecasting operations are tenant-scoped
- notification: '/tenants', // Notification operations are tenant-scoped
-};
-
-// HTTP status codes
-export const HttpStatus = {
- OK: 200,
- CREATED: 201,
- NO_CONTENT: 204,
- BAD_REQUEST: 400,
- UNAUTHORIZED: 401,
- FORBIDDEN: 403,
- NOT_FOUND: 404,
- CONFLICT: 409,
- UNPROCESSABLE_ENTITY: 422,
- INTERNAL_SERVER_ERROR: 500,
- BAD_GATEWAY: 502,
- SERVICE_UNAVAILABLE: 503,
-} as const;
-
-// Request timeout configuration
-export const RequestTimeouts = {
- SHORT: 5000, // 5 seconds - for quick operations
- MEDIUM: 15000, // 15 seconds - for normal operations
- LONG: 60000, // 1 minute - for file uploads
- EXTENDED: 300000, // 5 minutes - for training operations
-} as const;
-
-// Cache configuration
-export interface CacheConfig {
- defaultTTL: number;
- maxSize: number;
- strategies: {
- user: number;
- tenant: number;
- data: number;
- forecast: number;
- };
-}
-
-export const cacheConfig: CacheConfig = {
- defaultTTL: 300000, // 5 minutes
- maxSize: 100, // Maximum cached items
- strategies: {
- user: 600000, // 10 minutes
- tenant: 1800000, // 30 minutes
- data: 300000, // 5 minutes
- forecast: 600000, // 10 minutes
- },
-};
-
-// Retry configuration
-export interface RetryConfig {
- attempts: number;
- delay: number;
- backoff: number;
- retryCondition: (error: any) => boolean;
-}
-
-export const retryConfig: RetryConfig = {
- attempts: 3,
- delay: 1000,
- backoff: 2, // Exponential backoff multiplier
- retryCondition: (error: any) => {
- // Retry on network errors and specific HTTP status codes
- if (!error.response) return true; // Network error
- const status = error.response.status;
- return status >= 500 || status === 408 || status === 429;
- },
-};
-
-// API versioning
-export const ApiVersion = {
- V1: 'v1',
- CURRENT: 'v1',
-} as const;
-
-export interface FeatureFlags {
- enableWebSockets: boolean;
- enableOfflineMode: boolean;
- enableOptimisticUpdates: boolean;
- enableRequestDeduplication: boolean;
- enableMetrics: boolean;
-}
-
-export const featureFlags: FeatureFlags = {
- enableWebSockets: import.meta.env.VITE_ENABLE_WEBSOCKETS === 'true',
- enableOfflineMode: import.meta.env.VITE_ENABLE_OFFLINE === 'true',
- enableOptimisticUpdates: import.meta.env.VITE_ENABLE_OPTIMISTIC_UPDATES !== 'false',
- enableRequestDeduplication: import.meta.env.VITE_ENABLE_DEDUPLICATION !== 'false',
- enableMetrics: import.meta.env.VITE_ENABLE_METRICS === 'true',
-};
diff --git a/fdev-ffrontend/src/api/client/index.ts b/fdev-ffrontend/src/api/client/index.ts
deleted file mode 100644
index 23959b2b..00000000
--- a/fdev-ffrontend/src/api/client/index.ts
+++ /dev/null
@@ -1,578 +0,0 @@
-// frontend/src/api/client/index.ts
-/**
- * Enhanced API Client with modern features
- * Supports caching, retries, optimistic updates, and more
- */
-
-import {
- ApiResponse,
- ApiError,
- RequestConfig,
- UploadConfig,
- UploadProgress,
- RequestInterceptor,
- ResponseInterceptor,
- CacheEntry,
- RequestMetrics,
-} from './types';
-import { apiConfig, retryConfig, cacheConfig, featureFlags } from './config';
-
-export class ApiClient {
- private baseURL: string;
- private cache = new Map();
- private pendingRequests = new Map>();
- private requestInterceptors: RequestInterceptor[] = [];
- private responseInterceptors: ResponseInterceptor[] = [];
- private metrics: RequestMetrics[] = [];
-
-constructor(baseURL?: string) {
- this.baseURL = baseURL || apiConfig.baseURL;
- // ✅ CRITICAL FIX: Remove trailing slash
- this.baseURL = this.baseURL.replace(/\/+$/, '');
- console.log('🔧 API Client initialized with baseURL:', this.baseURL);
-}
-
-private buildURL(endpoint: string): string {
- // Remove leading slash from endpoint if present to avoid double slashes
- const cleanEndpoint = endpoint.startsWith('/') ? endpoint : `/${endpoint}`;
- const fullURL = `${this.baseURL}${cleanEndpoint}`;
-
- // ✅ DEBUG: Log URL construction
- console.log('🔗 Building URL:', {
- baseURL: this.baseURL,
- endpoint: cleanEndpoint,
- fullURL: fullURL
- });
-
- return fullURL;
- }
-
- /**
- * Add request interceptor
- */
- addRequestInterceptor(interceptor: RequestInterceptor): void {
- this.requestInterceptors.push(interceptor);
- }
-
- /**
- * Add response interceptor
- */
- addResponseInterceptor(interceptor: ResponseInterceptor): void {
- this.responseInterceptors.push(interceptor);
- }
-
- /**
- * Generate cache key for request
- */
- private getCacheKey(url: string, config?: RequestConfig): string {
- const method = config?.method || 'GET';
- const params = config?.params ? JSON.stringify(config.params) : '';
- return `${method}:${url}:${params}`;
- }
-
- /**
- * Check if response is cached and valid
- */
- private getCachedResponse(key: string): T | null {
- if (!featureFlags.enableRequestDeduplication && !apiConfig.enableCaching) {
- return null;
- }
-
- const cached = this.cache.get(key);
- if (!cached) return null;
-
- const now = Date.now();
- if (now - cached.timestamp > cached.ttl) {
- this.cache.delete(key);
- return null;
- }
-
- return cached.data;
- }
-
- /**
- * Cache response data
- */
- private setCachedResponse(key: string, data: T, ttl?: number): void {
- if (!apiConfig.enableCaching) return;
-
- const cacheTTL = ttl || cacheConfig.defaultTTL;
- this.cache.set(key, {
- data,
- timestamp: Date.now(),
- ttl: cacheTTL,
- key,
- });
-
- // Cleanup old cache entries if cache is full
- if (this.cache.size > cacheConfig.maxSize) {
- const oldestKey = this.cache.keys().next().value;
- this.cache.delete(oldestKey);
- }
- }
-
- /**
- * Apply request interceptors
- */
- private async applyRequestInterceptors(config: RequestConfig): Promise {
- let modifiedConfig = { ...config };
-
- for (const interceptor of this.requestInterceptors) {
- if (interceptor.onRequest) {
- try {
- modifiedConfig = await interceptor.onRequest(modifiedConfig);
- } catch (error) {
- if (interceptor.onRequestError) {
- await interceptor.onRequestError(error);
- }
- throw error;
- }
- }
- }
-
- return modifiedConfig;
- }
-
- /**
- * Apply response interceptors
- */
- private async applyResponseInterceptors(response: ApiResponse): Promise> {
- let modifiedResponse = { ...response };
-
- for (const interceptor of this.responseInterceptors) {
- if (interceptor.onResponse) {
- try {
- modifiedResponse = await interceptor.onResponse(modifiedResponse);
- } catch (error) {
- if (interceptor.onResponseError) {
- await interceptor.onResponseError(error);
- }
- throw error;
- }
- }
- }
-
- return modifiedResponse;
- }
-
- /**
- * Retry failed requests with exponential backoff
- */
- private async retryRequest(
- requestFn: () => Promise,
- attempts: number = retryConfig.attempts
- ): Promise {
- try {
- return await requestFn();
- } catch (error) {
- if (attempts <= 0 || !retryConfig.retryCondition(error)) {
- throw error;
- }
-
- const delay = retryConfig.delay * Math.pow(retryConfig.backoff, retryConfig.attempts - attempts);
- await new Promise(resolve => setTimeout(resolve, delay));
-
- return this.retryRequest(requestFn, attempts - 1);
- }
- }
-
- /**
- * Record request metrics
- */
- private recordMetrics(metrics: Partial): void {
- if (!featureFlags.enableMetrics) return;
-
- const completeMetrics: RequestMetrics = {
- url: '',
- method: 'GET',
- duration: 0,
- status: 0,
- size: 0,
- timestamp: Date.now(),
- cached: false,
- retries: 0,
- ...metrics,
- };
-
- this.metrics.push(completeMetrics);
-
- // Keep only recent metrics (last 1000 requests)
- if (this.metrics.length > 1000) {
- this.metrics = this.metrics.slice(-1000);
- }
- }
-
- /**
- * Core request method with all features
- */
- async request(endpoint: string, config: RequestConfig = {}): Promise {
- const startTime = Date.now();
- const url = this.buildURL(endpoint);
- const method = config.method || 'GET';
-
- console.log('🚀 Making API request:', {
- method,
- endpoint,
- url,
- config
- });
-
- // Apply request interceptors
- const modifiedConfig = await this.applyRequestInterceptors(config);
-
- // Generate cache key
- const cacheKey = this.getCacheKey(endpoint, modifiedConfig);
-
- // Check cache for GET requests
- if (method === 'GET' && (config.cache !== false)) {
- const cached = this.getCachedResponse(cacheKey);
- if (cached) {
- this.recordMetrics({
- url: endpoint,
- method,
- duration: Date.now() - startTime,
- status: 200,
- cached: true,
- });
- return cached;
- }
- }
-
- // Request deduplication for concurrent requests
- if (featureFlags.enableRequestDeduplication && method === 'GET') {
- const pendingRequest = this.pendingRequests.get(cacheKey);
- if (pendingRequest) {
- return pendingRequest;
- }
- }
-
- // Create request promise
- const requestPromise = this.retryRequest(async () => {
- const headers: Record = {
- 'Content-Type': 'application/json',
- ...modifiedConfig.headers,
- };
-
- const fetchConfig: RequestInit = {
- method,
- headers,
- signal: AbortSignal.timeout(modifiedConfig.timeout || apiConfig.timeout),
- };
-
- // Add body for non-GET requests
- if (method !== 'GET' && modifiedConfig.body) {
- if (modifiedConfig.body instanceof FormData) {
- // Remove Content-Type for FormData (let browser set it with boundary)
- delete headers['Content-Type'];
- fetchConfig.body = modifiedConfig.body;
- } else {
- fetchConfig.body = typeof modifiedConfig.body === 'string'
- ? modifiedConfig.body
- : JSON.stringify(modifiedConfig.body);
- }
- }
-
- // Add query parameters
- const urlWithParams = new URL(url);
- if (modifiedConfig.params) {
- Object.entries(modifiedConfig.params).forEach(([key, value]) => {
- if (value !== undefined && value !== null) {
- urlWithParams.searchParams.append(key, String(value));
- }
- });
- }
-
- const response = await fetch(urlWithParams.toString(), fetchConfig);
-
- if (!response.ok) {
- const errorText = await response.text();
- let errorData: ApiError;
-
- try {
- errorData = JSON.parse(errorText);
- } catch {
- errorData = {
- message: `HTTP ${response.status}: ${response.statusText}`,
- detail: errorText,
- code: `HTTP_${response.status}`,
- };
- }
-
- const error = new Error(errorData.message || 'Request failed');
- (error as any).response = { status: response.status, data: errorData };
- throw error;
- }
-
- const responseData = await response.json();
- console.log('🔍 Raw responseData from fetch:', responseData);
-
- // Apply response interceptors
- const processedResponse = await this.applyResponseInterceptors(responseData);
- console.log('🔍 processedResponse after interceptors:', processedResponse);
-
- return processedResponse;
- });
-
- // Store pending request for deduplication
- if (featureFlags.enableRequestDeduplication && method === 'GET') {
- this.pendingRequests.set(cacheKey, requestPromise);
- }
-
- try {
- const result = await requestPromise;
-
- // Cache successful GET responses
- if (method === 'GET' && config.cache !== false) {
- this.setCachedResponse(cacheKey, result, config.cacheTTL);
- }
-
- // Record metrics
- this.recordMetrics({
- url: endpoint,
- method,
- duration: Date.now() - startTime,
- status: 200,
- size: JSON.stringify(result).length,
- });
-
- // Handle both wrapped and unwrapped responses
- // If result has a 'data' property, return it; otherwise return the result itself
- console.log('🔍 Final result before return:', result);
- console.log('🔍 Result has data property?', result && typeof result === 'object' && 'data' in result);
-
- if (result && typeof result === 'object' && 'data' in result) {
- console.log('🔍 Returning result.data:', result.data);
- return result.data as T;
- }
- console.log('🔍 Returning raw result:', result);
- return result as T;
- } catch (error) {
- // Record error metrics
- this.recordMetrics({
- url: endpoint,
- method,
- duration: Date.now() - startTime,
- status: (error as any).response?.status || 0,
- });
-
- throw error;
- } finally {
- // Clean up pending request
- if (featureFlags.enableRequestDeduplication && method === 'GET') {
- this.pendingRequests.delete(cacheKey);
- }
- }
- }
-
- /**
- * Convenience methods for HTTP verbs
- */
- async get(endpoint: string, config?: RequestConfig): Promise {
- return this.request(endpoint, { ...config, method: 'GET' });
- }
-
- async post(endpoint: string, data?: any, config?: RequestConfig): Promise {
- return this.request(endpoint, {
- ...config,
- method: 'POST',
- body: data
- });
- }
-
- async put(endpoint: string, data?: any, config?: RequestConfig): Promise {
- return this.request(endpoint, {
- ...config,
- method: 'PUT',
- body: data
- });
- }
-
- async patch(endpoint: string, data?: any, config?: RequestConfig): Promise {
- return this.request(endpoint, {
- ...config,
- method: 'PATCH',
- body: data
- });
- }
-
- async delete(endpoint: string, config?: RequestConfig): Promise {
- return this.request(endpoint, { ...config, method: 'DELETE' });
- }
-
- /**
- * Raw request that returns the Response object for binary data
- */
- async getRaw(endpoint: string, config?: RequestConfig): Promise {
- const url = this.buildURL(endpoint);
- const modifiedConfig = await this.applyRequestInterceptors(config || {});
-
- const headers: Record = {
- ...modifiedConfig.headers,
- };
-
- const fetchConfig: RequestInit = {
- method: 'GET',
- headers,
- signal: AbortSignal.timeout(modifiedConfig.timeout || apiConfig.timeout),
- };
-
- // Add query parameters
- const urlWithParams = new URL(url);
- if (modifiedConfig.params) {
- Object.entries(modifiedConfig.params).forEach(([key, value]) => {
- if (value !== undefined && value !== null) {
- urlWithParams.searchParams.append(key, String(value));
- }
- });
- }
-
- const response = await fetch(urlWithParams.toString(), fetchConfig);
-
- if (!response.ok) {
- const errorText = await response.text();
- let errorData: ApiError;
-
- try {
- errorData = JSON.parse(errorText);
- } catch {
- errorData = {
- message: `HTTP ${response.status}: ${response.statusText}`,
- detail: errorText,
- code: `HTTP_${response.status}`,
- };
- }
-
- const error = new Error(errorData.message || 'Request failed');
- (error as any).response = { status: response.status, data: errorData };
- throw error;
- }
-
- return response;
- }
-
- /**
- * File upload with progress tracking
- */
- async upload(
- endpoint: string,
- file: File,
- additionalData?: Record,
- config?: UploadConfig
- ): Promise {
- const formData = new FormData();
- formData.append('file', file);
-
- if (additionalData) {
- Object.entries(additionalData).forEach(([key, value]) => {
- formData.append(key, String(value));
- });
- }
-
- // For file uploads, we need to use XMLHttpRequest for progress tracking
- if (config?.onProgress) {
- return new Promise((resolve, reject) => {
- const xhr = new XMLHttpRequest();
-
- xhr.upload.addEventListener('progress', (event) => {
- if (event.lengthComputable && config.onProgress) {
- const progress: UploadProgress = {
- loaded: event.loaded,
- total: event.total,
- percentage: Math.round((event.loaded / event.total) * 100),
- };
- config.onProgress(progress);
- }
- });
-
- xhr.addEventListener('load', () => {
- if (xhr.status >= 200 && xhr.status < 300) {
- try {
- const result = JSON.parse(xhr.responseText);
- resolve(result);
- } catch {
- resolve(xhr.responseText as any);
- }
- } else {
- reject(new Error(`Upload failed: ${xhr.status} ${xhr.statusText}`));
- }
- });
-
- xhr.addEventListener('error', () => {
- reject(new Error('Upload failed'));
- });
-
- xhr.open('POST', `${this.baseURL}${endpoint}`);
-
- // Add headers (excluding Content-Type for FormData)
- if (config?.headers) {
- Object.entries(config.headers).forEach(([key, value]) => {
- if (key.toLowerCase() !== 'content-type') {
- xhr.setRequestHeader(key, value);
- }
- });
- }
-
- xhr.send(formData);
- });
- }
-
- // Fallback to regular request for uploads without progress
- return this.request(endpoint, {
- ...config,
- method: 'POST',
- body: formData,
- });
- }
-
- /**
- * Clear cache
- */
- clearCache(pattern?: string): void {
- if (pattern) {
- // Clear cache entries matching pattern
- const regex = new RegExp(pattern);
- Array.from(this.cache.keys())
- .filter(key => regex.test(key))
- .forEach(key => this.cache.delete(key));
- } else {
- // Clear all cache
- this.cache.clear();
- }
- }
-
- /**
- * Get client metrics
- */
- getMetrics() {
- if (!featureFlags.enableMetrics) {
- return {
- totalRequests: 0,
- successfulRequests: 0,
- failedRequests: 0,
- averageResponseTime: 0,
- cacheHitRate: 0,
- errorRate: 0,
- };
- }
-
- const total = this.metrics.length;
- const successful = this.metrics.filter(m => m.status >= 200 && m.status < 300).length;
- const cached = this.metrics.filter(m => m.cached).length;
- const averageTime = total > 0
- ? this.metrics.reduce((sum, m) => sum + m.duration, 0) / total
- : 0;
-
- return {
- totalRequests: total,
- successfulRequests: successful,
- failedRequests: total - successful,
- averageResponseTime: Math.round(averageTime),
- cacheHitRate: total > 0 ? Math.round((cached / total) * 100) : 0,
- errorRate: total > 0 ? Math.round(((total - successful) / total) * 100) : 0,
- };
- }
-}
-
-// Default API client instance
-console.log('🔧 Creating default API client...');
-export const apiClient = new ApiClient();
\ No newline at end of file
diff --git a/fdev-ffrontend/src/api/client/interceptors.ts b/fdev-ffrontend/src/api/client/interceptors.ts
deleted file mode 100644
index 59c87a11..00000000
--- a/fdev-ffrontend/src/api/client/interceptors.ts
+++ /dev/null
@@ -1,488 +0,0 @@
-// frontend/src/api/client/interceptors.ts
-/**
- * Request and Response Interceptors
- * Handles authentication, logging, error handling, etc.
- */
-
-import { apiClient } from './index';
-import type { RequestConfig, ApiResponse } from './types';
-import { ApiErrorHandler } from '../utils';
-
-/**
- * Authentication Interceptor
- * Automatically adds authentication headers to requests
- */
-class AuthInterceptor {
- static isTokenExpired(token: string): boolean {
- try {
- const payload = JSON.parse(atob(token.split('.')[1]));
- const currentTime = Math.floor(Date.now() / 1000);
- return payload.exp <= currentTime;
- } catch (error) {
- console.warn('Error parsing token:', error);
- return true; // Treat invalid tokens as expired
- }
- }
-
- static isTokenExpiringSoon(token: string, bufferMinutes: number = 5): boolean {
- try {
- const payload = JSON.parse(atob(token.split('.')[1]));
- const currentTime = Math.floor(Date.now() / 1000);
- const bufferSeconds = bufferMinutes * 60;
- return payload.exp <= (currentTime + bufferSeconds);
- } catch (error) {
- console.warn('Error parsing token for expiration check:', error);
- return true;
- }
- }
-
- static async refreshTokenIfNeeded(): Promise {
- const token = localStorage.getItem('auth_token');
- const refreshToken = localStorage.getItem('refresh_token');
-
- if (!token || !refreshToken) {
- return;
- }
-
- // If token is expiring within 5 minutes, proactively refresh
- if (this.isTokenExpiringSoon(token, 5)) {
- try {
- const baseURL = (apiClient as any).baseURL || window.location.origin;
- const response = await fetch(`${baseURL}/api/v1/auth/refresh`, {
- method: 'POST',
- headers: { 'Content-Type': 'application/json' },
- body: JSON.stringify({ refresh_token: refreshToken }),
- });
-
- if (response.ok) {
- const data = await response.json();
- localStorage.setItem('auth_token', data.access_token);
- if (data.refresh_token) {
- localStorage.setItem('refresh_token', data.refresh_token);
- }
- } else {
- console.warn('Token refresh failed:', response.status);
- }
- } catch (error) {
- console.warn('Token refresh error:', error);
- }
- }
- }
-
- static setup() {
- apiClient.addRequestInterceptor({
- onRequest: async (config: RequestConfig) => {
- // Proactively refresh token if needed
- await this.refreshTokenIfNeeded();
-
- let token = localStorage.getItem('auth_token');
-
- if (token) {
- // Check if token is expired
- if (this.isTokenExpired(token)) {
- console.warn('Token expired, removing from storage');
- localStorage.removeItem('auth_token');
- token = null;
- }
- }
-
- if (token) {
- config.headers = {
- ...config.headers,
- Authorization: `Bearer ${token}`,
- };
- } else {
- console.warn('No valid auth token found - authentication required');
- }
-
- return config;
- },
-
- onRequestError: async (error: any) => {
- console.error('Request interceptor error:', error);
- throw error;
- },
- });
- }
-}
-
-/**
- * Logging Interceptor
- * Logs API requests and responses for debugging
- */
-class LoggingInterceptor {
- static setup() {
- apiClient.addRequestInterceptor({
- onRequest: async (config: RequestConfig) => {
- const requestId = `req_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
-
- console.group(`🚀 API Request [${requestId}]`);
- console.log('Method:', config.method);
- console.log('URL:', config.url);
- console.log('Headers:', config.headers);
- if (config.body && config.method !== 'GET') {
- console.log('Body:', config.body);
- }
- if (config.params) {
- console.log('Params:', config.params);
- }
- console.groupEnd();
-
- // Add request ID to config for response correlation
- config.headers = {
- ...config.headers,
- 'X-Request-ID': requestId,
- };
-
- return config;
- },
- });
-
- apiClient.addResponseInterceptor({
- onResponse: async (response: ApiResponse) => {
- const requestId = response.meta?.requestId || 'unknown';
-
- console.group(`✅ API Response [${requestId}]`);
- console.log('Status:', response.status);
- console.log('Data:', response.data);
- if (response.message) {
- console.log('Message:', response.message);
- }
- console.groupEnd();
-
- return response;
- },
-
- onResponseError: async (error: any) => {
- const requestId = error?.config?.headers?.[`X-Request-ID`] || 'unknown';
-
- console.group(`❌ API Error [${requestId}]`);
- console.error('Status:', error?.response?.status);
- console.error('Error:', ApiErrorHandler.formatError(error));
- console.error('Full Error:', error);
- console.groupEnd();
-
- throw error;
- },
- });
- }
-}
-
-/**
- * Tenant Context Interceptor
- * Automatically adds tenant context to tenant-scoped requests
- */
-class TenantInterceptor {
- private static currentTenantId: string | null = null;
-
- static setCurrentTenant(tenantId: string | null) {
- this.currentTenantId = tenantId;
- }
-
- static getCurrentTenant(): string | null {
- return this.currentTenantId;
- }
-
- static setup() {
- apiClient.addRequestInterceptor({
- onRequest: async (config: RequestConfig) => {
- // Add tenant context to tenant-scoped endpoints
- if (this.currentTenantId && this.isTenantScopedEndpoint(config.url)) {
- config.headers = {
- ...config.headers,
- 'X-Tenant-ID': this.currentTenantId,
- };
- }
-
- return config;
- },
- });
- }
-
- private static isTenantScopedEndpoint(url?: string): boolean {
- if (!url) return false;
- return url.includes('/tenants/') ||
- url.includes('/training/') ||
- url.includes('/forecasts/') ||
- url.includes('/notifications/');
- }
-}
-
-/**
- * Error Recovery Interceptor
- * Handles automatic token refresh and retry logic
- */
-class ErrorRecoveryInterceptor {
- private static isRefreshing = false;
- private static failedQueue: Array<{
- resolve: (token: string) => void;
- reject: (error: any) => void;
- }> = [];
-
- static setup() {
- apiClient.addResponseInterceptor({
- onResponseError: async (error: any) => {
- const originalRequest = error.config;
-
- // Handle 401 errors with token refresh
- if (error?.response?.status === 401 && !originalRequest._retry) {
- if (this.isRefreshing) {
- // Queue the request while refresh is in progress
- return new Promise((resolve, reject) => {
- this.failedQueue.push({ resolve, reject });
- }).then(token => {
- return this.retryRequestWithNewToken(originalRequest, token as string);
- }).catch(err => {
- throw err;
- });
- }
-
- originalRequest._retry = true;
- this.isRefreshing = true;
-
- try {
- const refreshToken = localStorage.getItem('refresh_token');
-
- if (!refreshToken) {
- throw new Error('No refresh token available');
- }
-
- // Use direct fetch to avoid interceptor recursion
- const baseURL = (apiClient as any).baseURL || window.location.origin;
- const response = await fetch(`${baseURL}/api/v1/auth/refresh`, {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify({ refresh_token: refreshToken }),
- });
-
- if (!response.ok) {
- throw new Error(`Token refresh failed: ${response.status}`);
- }
-
- const data = await response.json();
- const newToken = data.access_token;
-
- if (!newToken) {
- throw new Error('No access token received');
- }
-
- localStorage.setItem('auth_token', newToken);
-
- // Update new refresh token if provided
- if (data.refresh_token) {
- localStorage.setItem('refresh_token', data.refresh_token);
- }
-
- // Process failed queue
- this.processQueue(null, newToken);
-
- // Retry original request with new token
- return this.retryRequestWithNewToken(originalRequest, newToken);
-
- } catch (refreshError) {
- console.warn('Token refresh failed:', refreshError);
- this.processQueue(refreshError, null);
-
- // Clear auth data and redirect to login
- localStorage.removeItem('auth_token');
- localStorage.removeItem('refresh_token');
- localStorage.removeItem('user_data');
-
- // Only redirect if we're not already on the login page
- if (typeof window !== 'undefined' && !window.location.pathname.includes('/login')) {
- window.location.href = '/login';
- }
-
- throw refreshError;
- } finally {
- this.isRefreshing = false;
- }
- }
-
- throw error;
- },
- });
- }
-
- private static async retryRequestWithNewToken(originalRequest: any, token: string) {
- try {
- // Use direct fetch instead of apiClient to avoid interceptor recursion
- const url = originalRequest.url || originalRequest.endpoint;
- const method = originalRequest.method || 'GET';
-
- const fetchOptions: RequestInit = {
- method,
- headers: {
- 'Content-Type': 'application/json',
- 'Authorization': `Bearer ${token}`,
- ...originalRequest.headers
- }
- };
-
- // Add body for non-GET requests
- if (method !== 'GET' && originalRequest.body) {
- fetchOptions.body = typeof originalRequest.body === 'string'
- ? originalRequest.body
- : JSON.stringify(originalRequest.body);
- }
-
- // Add query parameters if present
- let fullUrl = url;
- if (originalRequest.params) {
- const urlWithParams = new URL(fullUrl, (apiClient as any).baseURL);
- Object.entries(originalRequest.params).forEach(([key, value]) => {
- if (value !== undefined && value !== null) {
- urlWithParams.searchParams.append(key, String(value));
- }
- });
- fullUrl = urlWithParams.toString();
- }
-
- // Retry request with refreshed token
-
- const response = await fetch(fullUrl, fetchOptions);
-
- if (!response.ok) {
- throw new Error(`Request failed: ${response.status}`);
- }
-
- return await response.json();
- } catch (retryError) {
- console.warn('Request retry failed:', retryError);
- throw retryError;
- }
- }
-
- private static processQueue(error: any, token: string | null) {
- this.failedQueue.forEach(({ resolve, reject }) => {
- if (error) {
- reject(error);
- } else {
- resolve(token!);
- }
- });
-
- this.failedQueue = [];
- }
-}
-
-/**
- * Performance Monitoring Interceptor
- * Tracks API performance metrics
- */
-class PerformanceInterceptor {
- private static metrics: Array<{
- url: string;
- method: string;
- duration: number;
- status: number;
- timestamp: number;
- }> = [];
-
- static setup() {
- apiClient.addRequestInterceptor({
- onRequest: async (config: RequestConfig) => {
- config.metadata = {
- ...config.metadata,
- startTime: Date.now(),
- };
-
- return config;
- },
- });
-
- apiClient.addResponseInterceptor({
- onResponse: async (response: ApiResponse) => {
- const startTime = response.metadata?.startTime;
- if (startTime) {
- const duration = Date.now() - startTime;
- this.recordMetric({
- url: response.metadata?.url || 'unknown',
- method: response.metadata?.method || 'unknown',
- duration,
- status: 200,
- timestamp: Date.now(),
- });
- }
-
- return response;
- },
-
- onResponseError: async (error: any) => {
- const startTime = error.config?.metadata?.startTime;
- if (startTime) {
- const duration = Date.now() - startTime;
- this.recordMetric({
- url: error.config?.url || 'unknown',
- method: error.config?.method || 'unknown',
- duration,
- status: error?.response?.status || 0,
- timestamp: Date.now(),
- });
- }
-
- throw error;
- },
- });
- }
-
- private static recordMetric(metric: any) {
- this.metrics.push(metric);
-
- // Keep only last 1000 metrics
- if (this.metrics.length > 1000) {
- this.metrics = this.metrics.slice(-1000);
- }
- }
-
- static getMetrics() {
- return [...this.metrics];
- }
-
- static getAverageResponseTime(): number {
- if (this.metrics.length === 0) return 0;
-
- const total = this.metrics.reduce((sum, metric) => sum + metric.duration, 0);
- return Math.round(total / this.metrics.length);
- }
-
- static getErrorRate(): number {
- if (this.metrics.length === 0) return 0;
-
- const errorCount = this.metrics.filter(metric => metric.status >= 400).length;
- return Math.round((errorCount / this.metrics.length) * 100);
- }
-}
-
-/**
- * Setup all interceptors
- * IMPORTANT: Order matters! ErrorRecoveryInterceptor must be first to handle token refresh
- */
-export const setupInterceptors = () => {
- // 1. Error recovery first (handles 401 and token refresh)
- ErrorRecoveryInterceptor.setup();
-
- // 2. Authentication (adds Bearer tokens)
- AuthInterceptor.setup();
-
- // 3. Tenant context
- TenantInterceptor.setup();
-
- // 4. Development-only interceptors
- const isDevelopment = true; // Temporarily set to true for development
- if (isDevelopment) {
- LoggingInterceptor.setup();
- PerformanceInterceptor.setup();
- }
-};
-
-// Export interceptor classes for manual setup if needed
-export {
- AuthInterceptor,
- LoggingInterceptor,
- TenantInterceptor,
- ErrorRecoveryInterceptor,
- PerformanceInterceptor,
-};
\ No newline at end of file
diff --git a/fdev-ffrontend/src/api/client/types.ts b/fdev-ffrontend/src/api/client/types.ts
deleted file mode 100644
index 2b54af5f..00000000
--- a/fdev-ffrontend/src/api/client/types.ts
+++ /dev/null
@@ -1,115 +0,0 @@
-// frontend/src/api/client/types.ts
-/**
- * Core API Client Types
- */
-
-export interface RequestConfig {
- method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
- headers?: Record;
- params?: Record;
- body?: any;
- url?: string;
- timeout?: number;
- retries?: number;
- cache?: boolean;
- cacheTTL?: number;
- optimistic?: boolean;
- background?: boolean;
- metadata?: any;
-}
-
-export interface ApiResponse {
- data: T;
- message?: string;
- status: string;
- timestamp?: string;
- metadata?: any;
- meta?: {
- page?: number;
- limit?: number;
- total?: number;
- hasNext?: boolean;
- hasPrev?: boolean;
- requestId?: string;
- };
-}
-
-export interface ApiError {
- message: string;
- detail?: string;
- code?: string;
- field?: string;
- timestamp?: string;
- service?: string;
- requestId?: string;
-}
-
-export interface PaginatedResponse {
- data: T[];
- pagination: {
- page: number;
- limit: number;
- total: number;
- totalPages: number;
- hasNext: boolean;
- hasPrev: boolean;
- };
-}
-
-export interface UploadProgress {
- loaded: number;
- total: number;
- percentage: number;
-}
-
-export interface UploadConfig extends RequestConfig {
- onProgress?: (progress: UploadProgress) => void;
- maxFileSize?: number;
- allowedTypes?: string[];
-}
-
-// Request/Response interceptor types
-export interface RequestInterceptor {
- onRequest?: (config: RequestConfig) => RequestConfig | Promise;
- onRequestError?: (error: any) => any;
-}
-
-export interface ResponseInterceptor {
- onResponse?: (response: ApiResponse) => ApiResponse | Promise>;
- onResponseError?: (error: any) => any;
-}
-
-// Cache types
-export interface CacheEntry {
- data: T;
- timestamp: number;
- ttl: number;
- key: string;
-}
-
-export interface CacheStrategy {
- key: (url: string, params?: any) => string;
- ttl: number;
- enabled: boolean;
-}
-
-// Metrics types
-export interface RequestMetrics {
- url: string;
- method: string;
- duration: number;
- status: number;
- size: number;
- timestamp: number;
- cached: boolean;
- retries: number;
-}
-
-export interface ClientMetrics {
- totalRequests: number;
- successfulRequests: number;
- failedRequests: number;
- averageResponseTime: number;
- cacheHitRate: number;
- errorRate: number;
-}
\ No newline at end of file
diff --git a/fdev-ffrontend/src/api/hooks/index.ts b/fdev-ffrontend/src/api/hooks/index.ts
deleted file mode 100644
index bb855104..00000000
--- a/fdev-ffrontend/src/api/hooks/index.ts
+++ /dev/null
@@ -1,66 +0,0 @@
-// frontend/src/api/hooks/index.ts
-/**
- * Main Hooks Export
- */
-
-export { useAuth, useAuthHeaders } from './useAuth';
-export { useTenant } from './useTenant';
-export { useSales } from './useSales';
-export { useExternal } from './useExternal';
-export { useTraining } from './useTraining';
-export { useForecast } from './useForecast';
-export { useNotification } from './useNotification';
-export { useOnboarding, useOnboardingStep } from './useOnboarding';
-export { useInventory, useInventoryDashboard, useInventoryItem, useInventoryProducts } from './useInventory';
-export { useRecipes, useProduction } from './useRecipes';
-export {
- useCurrentProcurementPlan,
- useProcurementPlanByDate,
- useProcurementPlan,
- useProcurementPlans,
- usePlanRequirements,
- useCriticalRequirements,
- useProcurementDashboard,
- useGenerateProcurementPlan,
- useUpdatePlanStatus,
- useTriggerDailyScheduler,
- useProcurementHealth,
- useProcurementPlanDashboard,
- useProcurementPlanActions
-} from './useProcurement';
-
-// Import hooks for combined usage
-import { useAuth } from './useAuth';
-import { useTenant } from './useTenant';
-import { useSales } from './useSales';
-import { useExternal } from './useExternal';
-import { useTraining } from './useTraining';
-import { useForecast } from './useForecast';
-import { useNotification } from './useNotification';
-import { useOnboarding } from './useOnboarding';
-import { useInventory } from './useInventory';
-
-// Combined hook for common operations
-export const useApiHooks = () => {
- const auth = useAuth();
- const tenant = useTenant();
- const sales = useSales();
- const external = useExternal();
- const training = useTraining({ disablePolling: true }); // Disable polling by default
- const forecast = useForecast();
- const notification = useNotification();
- const onboarding = useOnboarding();
- const inventory = useInventory();
-
- return {
- auth,
- tenant,
- sales,
- external,
- training,
- forecast,
- notification,
- onboarding,
- inventory
- };
-};
\ No newline at end of file
diff --git a/fdev-ffrontend/src/api/hooks/useAuth.ts b/fdev-ffrontend/src/api/hooks/useAuth.ts
deleted file mode 100644
index 6cb6ba15..00000000
--- a/fdev-ffrontend/src/api/hooks/useAuth.ts
+++ /dev/null
@@ -1,205 +0,0 @@
-// frontend/src/api/hooks/useAuth.ts
-/**
- * Authentication Hooks
- * React hooks for authentication operations
- */
-
-import { useState, useEffect, useCallback } from 'react';
-import { authService } from '../services';
-import type {
- LoginRequest,
- LoginResponse,
- RegisterRequest,
- UserResponse,
- PasswordResetRequest,
-} from '../types';
-
-// Token management
-const TOKEN_KEY = 'auth_token';
-const REFRESH_TOKEN_KEY = 'refresh_token';
-const USER_KEY = 'user_data';
-
-export const useAuth = () => {
- const [user, setUser] = useState(null);
- const [isAuthenticated, setIsAuthenticated] = useState(false);
- const [isLoading, setIsLoading] = useState(true);
- const [error, setError] = useState(null);
-
- // Initialize auth state from localStorage
- useEffect(() => {
- const initializeAuth = async () => {
- try {
- const token = localStorage.getItem(TOKEN_KEY);
- const userData = localStorage.getItem(USER_KEY);
-
- if (token && userData) {
- setUser(JSON.parse(userData));
- setIsAuthenticated(true);
-
- // Verify token is still valid
- try {
- const currentUser = await authService.getCurrentUser();
- setUser(currentUser);
- } catch (error) {
- // Token might be expired - let interceptors handle refresh
- // Only logout if refresh also fails (handled by ErrorRecoveryInterceptor)
- console.log('Token verification failed, interceptors will handle refresh if possible');
-
- // Check if we have a refresh token - if not, logout immediately
- const refreshToken = localStorage.getItem(REFRESH_TOKEN_KEY);
- if (!refreshToken) {
- console.log('No refresh token available, logging out');
- logout();
- }
- }
- }
- } catch (error) {
- console.error('Auth initialization error:', error);
- logout();
- } finally {
- setIsLoading(false);
- }
- };
-
- initializeAuth();
- }, []);
-
- const login = useCallback(async (credentials: LoginRequest): Promise => {
- try {
- setIsLoading(true);
- setError(null);
-
- const response = await authService.login(credentials);
-
- // Store tokens and user data
- localStorage.setItem(TOKEN_KEY, response.access_token);
- if (response.refresh_token) {
- localStorage.setItem(REFRESH_TOKEN_KEY, response.refresh_token);
- }
- if (response.user) {
- localStorage.setItem(USER_KEY, JSON.stringify(response.user));
- setUser(response.user);
- }
-
- setIsAuthenticated(true);
- } catch (error) {
- const message = error instanceof Error ? error.message : 'Login failed';
- setError(message);
- throw error;
- } finally {
- setIsLoading(false);
- }
- }, []);
-
- const register = useCallback(async (data: RegisterRequest): Promise => {
- try {
- setIsLoading(true);
- setError(null);
-
- const response = await authService.register(data);
-
- // Auto-login after successful registration
- if (response && response.user) {
- await login({ email: data.email, password: data.password });
- } else {
- // If response doesn't have user property, registration might still be successful
- // Try to login anyway in case the user was created but response format is different
- await login({ email: data.email, password: data.password });
- }
- } catch (error) {
- const message = error instanceof Error ? error.message : 'Registration failed';
- setError(message);
- throw error;
- } finally {
- setIsLoading(false);
- }
- }, [login]);
-
- const logout = useCallback(async (): Promise => {
- try {
- // Call logout endpoint if authenticated
- if (isAuthenticated) {
- await authService.logout();
- }
- } catch (error) {
- console.error('Logout error:', error);
- } finally {
- // Clear local state regardless of API call success
- localStorage.removeItem(TOKEN_KEY);
- localStorage.removeItem(REFRESH_TOKEN_KEY);
- localStorage.removeItem(USER_KEY);
- setUser(null);
- setIsAuthenticated(false);
- setError(null);
- }
- }, [isAuthenticated]);
-
- const updateProfile = useCallback(async (data: Partial): Promise => {
- try {
- setIsLoading(true);
- setError(null);
-
- const updatedUser = await authService.updateProfile(data);
- setUser(updatedUser);
- localStorage.setItem(USER_KEY, JSON.stringify(updatedUser));
- } catch (error) {
- const message = error instanceof Error ? error.message : 'Profile update failed';
- setError(message);
- throw error;
- } finally {
- setIsLoading(false);
- }
- }, []);
-
- const requestPasswordReset = useCallback(async (data: PasswordResetRequest): Promise => {
- try {
- setIsLoading(true);
- setError(null);
- await authService.requestPasswordReset(data);
- } catch (error) {
- const message = error instanceof Error ? error.message : 'Password reset request failed';
- setError(message);
- throw error;
- } finally {
- setIsLoading(false);
- }
- }, []);
-
- const changePassword = useCallback(async (currentPassword: string, newPassword: string): Promise => {
- try {
- setIsLoading(true);
- setError(null);
- await authService.changePassword(currentPassword, newPassword);
- } catch (error) {
- const message = error instanceof Error ? error.message : 'Password change failed';
- setError(message);
- throw error;
- } finally {
- setIsLoading(false);
- }
- }, []);
-
- return {
- user,
- isAuthenticated,
- isLoading,
- error,
- login,
- register,
- logout,
- updateProfile,
- requestPasswordReset,
- changePassword,
- clearError: () => setError(null),
- };
-};
-
-// Hook for getting authentication headers
-export const useAuthHeaders = () => {
- const getAuthHeaders = useCallback(() => {
- const token = localStorage.getItem(TOKEN_KEY);
- return token ? { Authorization: `Bearer ${token}` } : {};
- }, []);
-
- return { getAuthHeaders };
-};
\ No newline at end of file
diff --git a/fdev-ffrontend/src/api/hooks/useExternal.ts b/fdev-ffrontend/src/api/hooks/useExternal.ts
deleted file mode 100644
index c7d72aa3..00000000
--- a/fdev-ffrontend/src/api/hooks/useExternal.ts
+++ /dev/null
@@ -1,238 +0,0 @@
-// frontend/src/api/hooks/useExternal.ts
-/**
- * External Data Management Hooks
- * Handles weather and traffic data operations
- */
-
-import { useState, useCallback } from 'react';
-import { externalService } from '../services/external.service';
-import type { WeatherData, TrafficData, WeatherForecast, HourlyForecast } from '../services/external.service';
-
-export const useExternal = () => {
- const [weatherData, setWeatherData] = useState(null);
- const [trafficData, setTrafficData] = useState(null);
- const [weatherForecast, setWeatherForecast] = useState([]);
- const [hourlyForecast, setHourlyForecast] = useState([]);
- const [trafficForecast, setTrafficForecast] = useState([]);
- const [isLoading, setIsLoading] = useState(false);
- const [error, setError] = useState(null);
-
- /**
- * Get Current Weather
- */
- const getCurrentWeather = useCallback(async (
- tenantId: string,
- lat: number,
- lon: number
- ): Promise => {
- try {
- setIsLoading(true);
- setError(null);
-
- const weather = await externalService.getCurrentWeather(tenantId, lat, lon);
- setWeatherData(weather);
-
- return weather;
- } catch (error) {
- const message = error instanceof Error ? error.message : 'Failed to get weather data';
- setError(message);
- throw error;
- } finally {
- setIsLoading(false);
- }
- }, []);
-
- /**
- * Get Weather Forecast
- */
- const getWeatherForecast = useCallback(async (
- tenantId: string,
- lat: number,
- lon: number,
- days: number = 7
- ): Promise => {
- try {
- setIsLoading(true);
- setError(null);
-
- const forecast = await externalService.getWeatherForecast(tenantId, lat, lon, days);
- setWeatherForecast(forecast);
-
- return forecast;
- } catch (error) {
- const message = error instanceof Error ? error.message : 'Failed to get weather forecast';
- setError(message);
- throw error;
- } finally {
- setIsLoading(false);
- }
- }, []);
-
- /**
- * Get Hourly Weather Forecast
- */
- const getHourlyWeatherForecast = useCallback(async (
- tenantId: string,
- lat: number,
- lon: number,
- hours: number = 48
- ): Promise => {
- try {
- setIsLoading(true);
- setError(null);
-
- const forecast = await externalService.getHourlyWeatherForecast(tenantId, lat, lon, hours);
- setHourlyForecast(forecast);
-
- return forecast;
- } catch (error) {
- const message = error instanceof Error ? error.message : 'Failed to get hourly weather forecast';
- setError(message);
- throw error;
- } finally {
- setIsLoading(false);
- }
- }, []);
-
- /**
- * Get Historical Weather Data
- */
- const getHistoricalWeather = useCallback(async (
- tenantId: string,
- lat: number,
- lon: number,
- startDate: string,
- endDate: string
- ): Promise => {
- try {
- setIsLoading(true);
- setError(null);
-
- const data = await externalService.getHistoricalWeather(tenantId, lat, lon, startDate, endDate);
-
- return data;
- } catch (error) {
- const message = error instanceof Error ? error.message : 'Failed to get historical weather';
- setError(message);
- throw error;
- } finally {
- setIsLoading(false);
- }
- }, []);
-
- /**
- * Get Current Traffic
- */
- const getCurrentTraffic = useCallback(async (
- tenantId: string,
- lat: number,
- lon: number
- ): Promise => {
- try {
- setIsLoading(true);
- setError(null);
-
- const traffic = await externalService.getCurrentTraffic(tenantId, lat, lon);
- setTrafficData(traffic);
-
- return traffic;
- } catch (error) {
- const message = error instanceof Error ? error.message : 'Failed to get traffic data';
- setError(message);
- throw error;
- } finally {
- setIsLoading(false);
- }
- }, []);
-
- /**
- * Get Traffic Forecast
- */
- const getTrafficForecast = useCallback(async (
- tenantId: string,
- lat: number,
- lon: number,
- hours: number = 24
- ): Promise => {
- try {
- setIsLoading(true);
- setError(null);
-
- const forecast = await externalService.getTrafficForecast(tenantId, lat, lon, hours);
- setTrafficForecast(forecast);
-
- return forecast;
- } catch (error) {
- const message = error instanceof Error ? error.message : 'Failed to get traffic forecast';
- setError(message);
- throw error;
- } finally {
- setIsLoading(false);
- }
- }, []);
-
- /**
- * Get Historical Traffic Data
- */
- const getHistoricalTraffic = useCallback(async (
- tenantId: string,
- lat: number,
- lon: number,
- startDate: string,
- endDate: string
- ): Promise => {
- try {
- setIsLoading(true);
- setError(null);
-
- const data = await externalService.getHistoricalTraffic(tenantId, lat, lon, startDate, endDate);
-
- return data;
- } catch (error) {
- const message = error instanceof Error ? error.message : 'Failed to get historical traffic';
- setError(message);
- throw error;
- } finally {
- setIsLoading(false);
- }
- }, []);
-
- /**
- * Test External Services Connectivity
- */
- const testConnectivity = useCallback(async (tenantId: string) => {
- try {
- setIsLoading(true);
- setError(null);
-
- const results = await externalService.testConnectivity(tenantId);
-
- return results;
- } catch (error) {
- const message = error instanceof Error ? error.message : 'Failed to test connectivity';
- setError(message);
- throw error;
- } finally {
- setIsLoading(false);
- }
- }, []);
-
- return {
- weatherData,
- trafficData,
- weatherForecast,
- hourlyForecast,
- trafficForecast,
- isLoading,
- error,
- getCurrentWeather,
- getWeatherForecast,
- getHourlyWeatherForecast,
- getHistoricalWeather,
- getCurrentTraffic,
- getTrafficForecast,
- getHistoricalTraffic,
- testConnectivity,
- clearError: () => setError(null),
- };
-};
\ No newline at end of file
diff --git a/fdev-ffrontend/src/api/hooks/useForecast.ts b/fdev-ffrontend/src/api/hooks/useForecast.ts
deleted file mode 100644
index 2fa628a0..00000000
--- a/fdev-ffrontend/src/api/hooks/useForecast.ts
+++ /dev/null
@@ -1,229 +0,0 @@
-// frontend/src/api/hooks/useForecast.ts
-/**
- * Forecasting Operations Hooks
- */
-
-import { useState, useCallback } from 'react';
-import { forecastingService } from '../services';
-import type {
- SingleForecastRequest,
- BatchForecastRequest,
- ForecastResponse,
- BatchForecastResponse,
- ForecastAlert,
- QuickForecast,
-} from '../types';
-
-export const useForecast = () => {
- const [forecasts, setForecasts] = useState([]);
- const [batchForecasts, setBatchForecasts] = useState([]);
- const [quickForecasts, setQuickForecasts] = useState([]);
- const [alerts, setAlerts] = useState([]);
- const [isLoading, setIsLoading] = useState(false);
- const [error, setError] = useState(null);
-
- const createSingleForecast = useCallback(async (
- tenantId: string,
- request: SingleForecastRequest
- ): Promise => {
- try {
- setIsLoading(true);
- setError(null);
-
- const newForecasts = await forecastingService.createSingleForecast(tenantId, request);
- setForecasts(prev => [...newForecasts, ...(prev || [])]);
-
- return newForecasts;
- } catch (error) {
- const message = error instanceof Error ? error.message : 'Failed to create forecast';
- setError(message);
- throw error;
- } finally {
- setIsLoading(false);
- }
- }, []);
-
- const createBatchForecast = useCallback(async (
- tenantId: string,
- request: BatchForecastRequest
- ): Promise => {
- try {
- setIsLoading(true);
- setError(null);
-
- const batchForecast = await forecastingService.createBatchForecast(tenantId, request);
- setBatchForecasts(prev => [batchForecast, ...(prev || [])]);
-
- return batchForecast;
- } catch (error) {
- const message = error instanceof Error ? error.message : 'Failed to create batch forecast';
- setError(message);
- throw error;
- } finally {
- setIsLoading(false);
- }
- }, []);
-
- const getForecasts = useCallback(async (tenantId: string): Promise => {
- try {
- setIsLoading(true);
- setError(null);
-
- const response = await forecastingService.getForecasts(tenantId);
- setForecasts(response.data);
-
- return response.data;
- } catch (error) {
- const message = error instanceof Error ? error.message : 'Failed to get forecasts';
- setError(message);
- throw error;
- } finally {
- setIsLoading(false);
- }
- }, []);
-
- const getBatchForecastStatus = useCallback(async (
- tenantId: string,
- batchId: string
- ): Promise => {
- try {
- const batchForecast = await forecastingService.getBatchForecastStatus(tenantId, batchId);
-
- // Update batch forecast in state
- setBatchForecasts(prev => (prev || []).map(bf =>
- bf.id === batchId ? batchForecast : bf
- ));
-
- return batchForecast;
- } catch (error) {
- const message = error instanceof Error ? error.message : 'Failed to get batch forecast status';
- setError(message);
- throw error;
- }
- }, []);
-
- const getQuickForecasts = useCallback(async (tenantId: string): Promise => {
- try {
- setIsLoading(true);
- setError(null);
-
- const quickForecastData = await forecastingService.getQuickForecasts(tenantId);
- setQuickForecasts(quickForecastData);
-
- return quickForecastData;
- } catch (error) {
- const message = error instanceof Error ? error.message : 'Failed to get quick forecasts';
- setError(message);
- throw error;
- } finally {
- setIsLoading(false);
- }
- }, []);
-
- const getForecastAlerts = useCallback(async (tenantId: string): Promise => {
- try {
- setIsLoading(true);
- setError(null);
-
- const response = await forecastingService.getForecastAlerts(tenantId);
-
- // Handle different response formats
- if (response && 'data' in response && response.data) {
- // Standard paginated format: { data: [...], pagination: {...} }
- setAlerts(response.data);
- return { alerts: response.data, ...response };
- } else if (response && Array.isArray(response)) {
- // Direct array format
- setAlerts(response);
- return { alerts: response };
- } else if (Array.isArray(response)) {
- // Direct array format
- setAlerts(response);
- return { alerts: response };
- } else {
- // Unknown format - return empty
- setAlerts([]);
- return { alerts: [] };
- }
- } catch (error) {
- const message = error instanceof Error ? error.message : 'Failed to get forecast alerts';
- setError(message);
- throw error;
- } finally {
- setIsLoading(false);
- }
- }, []);
-
- const acknowledgeForecastAlert = useCallback(async (
- tenantId: string,
- alertId: string
- ): Promise => {
- try {
- setIsLoading(true);
- setError(null);
-
- const acknowledgedAlert = await forecastingService.acknowledgeForecastAlert(tenantId, alertId);
- setAlerts(prev => (prev || []).map(alert =>
- alert.id === alertId ? acknowledgedAlert : alert
- ));
- } catch (error) {
- const message = error instanceof Error ? error.message : 'Failed to acknowledge alert';
- setError(message);
- throw error;
- } finally {
- setIsLoading(false);
- }
- }, []);
-
- const exportForecasts = useCallback(async (
- tenantId: string,
- format: 'csv' | 'excel' | 'json',
- params?: {
- inventory_product_id?: string; // Primary way to filter by product
- product_name?: string; // For backward compatibility
- start_date?: string;
- end_date?: string;
- }
- ): Promise => {
- try {
- setIsLoading(true);
- setError(null);
-
- const blob = await forecastingService.exportForecasts(tenantId, format, params);
-
- // Create download link
- const url = window.URL.createObjectURL(blob);
- const link = document.createElement('a');
- link.href = url;
- link.download = `forecasts.${format}`;
- document.body.appendChild(link);
- link.click();
- document.body.removeChild(link);
- window.URL.revokeObjectURL(url);
- } catch (error) {
- const message = error instanceof Error ? error.message : 'Export failed';
- setError(message);
- throw error;
- } finally {
- setIsLoading(false);
- }
- }, []);
-
- return {
- forecasts,
- batchForecasts,
- quickForecasts,
- alerts,
- isLoading,
- error,
- createSingleForecast,
- createBatchForecast,
- getForecasts,
- getBatchForecastStatus,
- getQuickForecasts,
- getForecastAlerts,
- acknowledgeForecastAlert,
- exportForecasts,
- clearError: () => setError(null),
- };
-};
diff --git a/fdev-ffrontend/src/api/hooks/useInventory.ts b/fdev-ffrontend/src/api/hooks/useInventory.ts
deleted file mode 100644
index 32919f76..00000000
--- a/fdev-ffrontend/src/api/hooks/useInventory.ts
+++ /dev/null
@@ -1,536 +0,0 @@
-// frontend/src/api/hooks/useInventory.ts
-/**
- * Inventory Management React Hook
- * Provides comprehensive state management for inventory operations
- */
-
-import { useState, useEffect, useCallback } from 'react';
-import toast from 'react-hot-toast';
-
-import {
- inventoryService,
- InventoryItem,
- StockLevel,
- StockMovement,
- InventorySearchParams,
- CreateInventoryItemRequest,
- UpdateInventoryItemRequest,
- StockAdjustmentRequest,
- PaginatedResponse,
- InventoryDashboardData
-} from '../services/inventory.service';
-import type { ProductInfo } from '../types';
-
-import { useTenantId } from '../../hooks/useTenantId';
-
-// ========== HOOK INTERFACES ==========
-
-interface UseInventoryReturn {
- // State
- items: InventoryItem[];
- stockLevels: Record;
- movements: StockMovement[];
- dashboardData: InventoryDashboardData | null;
- isLoading: boolean;
- error: string | null;
- pagination: {
- page: number;
- limit: number;
- total: number;
- totalPages: number;
- };
-
- // Actions
- loadItems: (params?: InventorySearchParams) => Promise;
- loadItem: (itemId: string) => Promise;
- createItem: (data: CreateInventoryItemRequest) => Promise;
- updateItem: (itemId: string, data: UpdateInventoryItemRequest) => Promise;
- deleteItem: (itemId: string) => Promise;
-
- // Stock operations
- loadStockLevels: () => Promise;
- adjustStock: (itemId: string, adjustment: StockAdjustmentRequest) => Promise;
- loadMovements: (params?: any) => Promise;
-
-
- // Dashboard
- loadDashboard: () => Promise;
-
- // Utility
- searchItems: (query: string) => Promise;
- refresh: () => Promise;
- clearError: () => void;
-}
-
-interface UseInventoryDashboardReturn {
- dashboardData: InventoryDashboardData | null;
- isLoading: boolean;
- error: string | null;
- refresh: () => Promise;
-}
-
-interface UseInventoryItemReturn {
- item: InventoryItem | null;
- stockLevel: StockLevel | null;
- recentMovements: StockMovement[];
- isLoading: boolean;
- error: string | null;
- updateItem: (data: UpdateInventoryItemRequest) => Promise;
- adjustStock: (adjustment: StockAdjustmentRequest) => Promise;
- refresh: () => Promise;
-}
-
-// ========== MAIN INVENTORY HOOK ==========
-
-export const useInventory = (autoLoad = true): UseInventoryReturn => {
- const { tenantId } = useTenantId();
-
- // State
- const [items, setItems] = useState([]);
- const [stockLevels, setStockLevels] = useState>({});
- const [movements, setMovements] = useState([]);
- const [dashboardData, setDashboardData] = useState(null);
- const [isLoading, setIsLoading] = useState(false);
- const [error, setError] = useState(null);
- const [pagination, setPagination] = useState({
- page: 1,
- limit: 20,
- total: 0,
- totalPages: 0
- });
-
- // Clear error
- const clearError = useCallback(() => setError(null), []);
-
- // Load inventory items
- const loadItems = useCallback(async (params?: InventorySearchParams) => {
- if (!tenantId) return;
-
- setIsLoading(true);
- setError(null);
-
- try {
- const response = await inventoryService.getInventoryItems(tenantId, params);
- console.log('🔄 useInventory: Loaded items:', response.items);
- setItems(response.items || []); // Ensure it's always an array
- setPagination({
- page: response.page || 1,
- limit: response.limit || 20,
- total: response.total || 0,
- totalPages: response.total_pages || 0
- });
- } catch (err: any) {
- console.error('❌ useInventory: Error loading items:', err);
- const errorMessage = err.response?.data?.detail || err.message || 'Error loading inventory items';
-
- setError(errorMessage);
- setItems([]); // Set empty array on error
-
- // Show appropriate error message
- if (err.response?.status === 401) {
- console.error('❌ useInventory: Authentication failed');
- } else if (err.response?.status === 403) {
- toast.error('No tienes permisos para acceder a este inventario');
- } else {
- toast.error(errorMessage);
- }
- } finally {
- setIsLoading(false);
- }
- }, [tenantId]);
-
- // Load single item
- const loadItem = useCallback(async (itemId: string): Promise => {
- if (!tenantId) return null;
-
- try {
- const item = await inventoryService.getInventoryItem(tenantId, itemId);
-
- // Update in local state if it exists
- setItems(prev => prev.map(i => i.id === itemId ? item : i));
-
- return item;
- } catch (err: any) {
- const errorMessage = err.response?.data?.detail || err.message || 'Error loading item';
- setError(errorMessage);
- return null;
- }
- }, [tenantId]);
-
- // Create item
- const createItem = useCallback(async (data: CreateInventoryItemRequest): Promise => {
- if (!tenantId) return null;
-
- setIsLoading(true);
-
- try {
- const newItem = await inventoryService.createInventoryItem(tenantId, data);
- setItems(prev => [newItem, ...prev]);
- toast.success(`Created ${newItem.name} successfully`);
- return newItem;
- } catch (err: any) {
- const errorMessage = err.response?.data?.detail || err.message || 'Error creating item';
- setError(errorMessage);
- toast.error(errorMessage);
- return null;
- } finally {
- setIsLoading(false);
- }
- }, [tenantId]);
-
- // Update item
- const updateItem = useCallback(async (
- itemId: string,
- data: UpdateInventoryItemRequest
- ): Promise => {
- if (!tenantId) return null;
-
- try {
- const updatedItem = await inventoryService.updateInventoryItem(tenantId, itemId, data);
- setItems(prev => prev.map(i => i.id === itemId ? updatedItem : i));
- toast.success(`Updated ${updatedItem.name} successfully`);
- return updatedItem;
- } catch (err: any) {
- const errorMessage = err.response?.data?.detail || err.message || 'Error updating item';
- setError(errorMessage);
- toast.error(errorMessage);
- return null;
- }
- }, [tenantId]);
-
- // Delete item
- const deleteItem = useCallback(async (itemId: string): Promise => {
- if (!tenantId) return false;
-
- try {
- await inventoryService.deleteInventoryItem(tenantId, itemId);
- setItems(prev => prev.filter(i => i.id !== itemId));
- toast.success('Item deleted successfully');
- return true;
- } catch (err: any) {
- const errorMessage = err.response?.data?.detail || err.message || 'Error deleting item';
- setError(errorMessage);
- toast.error(errorMessage);
- return false;
- }
- }, [tenantId]);
-
- // Load stock levels
- const loadStockLevels = useCallback(async () => {
- if (!tenantId) return;
-
- try {
- const levels = await inventoryService.getAllStockLevels(tenantId);
- const levelMap = levels.reduce((acc, level) => {
- acc[level.item_id] = level;
- return acc;
- }, {} as Record);
- setStockLevels(levelMap);
- } catch (err: any) {
- console.error('Error loading stock levels:', err);
- // Don't show toast error for this as it's not critical for forecast page
- }
- }, [tenantId]);
-
- // Adjust stock
- const adjustStock = useCallback(async (
- itemId: string,
- adjustment: StockAdjustmentRequest
- ): Promise => {
- if (!tenantId) return null;
-
- try {
- const movement = await inventoryService.adjustStock(tenantId, itemId, adjustment);
-
- // Update local movements
- setMovements(prev => [movement, ...prev.slice(0, 49)]); // Keep last 50
-
- // Reload stock level for this item
- const updatedLevel = await inventoryService.getStockLevel(tenantId, itemId);
- setStockLevels(prev => ({ ...prev, [itemId]: updatedLevel }));
-
- toast.success('Stock adjusted successfully');
- return movement;
- } catch (err: any) {
- const errorMessage = err.response?.data?.detail || err.message || 'Error adjusting stock';
- setError(errorMessage);
- toast.error(errorMessage);
- return null;
- }
- }, [tenantId]);
-
- // Load movements
- const loadMovements = useCallback(async (params?: any) => {
- if (!tenantId) return;
-
- try {
- const response = await inventoryService.getStockMovements(tenantId, params);
- setMovements(response.items);
- } catch (err: any) {
- console.error('Error loading movements:', err);
- }
- }, [tenantId]);
-
-
- // Load dashboard
- const loadDashboard = useCallback(async () => {
- if (!tenantId) return;
-
- try {
- const data = await inventoryService.getDashboardData(tenantId);
- setDashboardData(data);
- } catch (err: any) {
- console.error('Error loading dashboard:', err);
- // Don't show toast error for this as it's not critical for forecast page
- }
- }, [tenantId]);
-
- // Search items
- const searchItems = useCallback(async (query: string): Promise => {
- if (!tenantId || !query.trim()) return [];
-
- try {
- return await inventoryService.searchItems(tenantId, query);
- } catch (err: any) {
- console.error('Error searching items:', err);
- return [];
- }
- }, [tenantId]);
-
- // Refresh all data
- const refresh = useCallback(async () => {
- await Promise.all([
- loadItems(),
- loadStockLevels(),
- loadDashboard()
- ]);
- }, [loadItems, loadStockLevels, loadDashboard]);
-
- // Auto-load on mount
- useEffect(() => {
- if (autoLoad && tenantId) {
- refresh();
- }
- }, [autoLoad, tenantId, refresh]);
-
- return {
- // State
- items,
- stockLevels,
- movements,
- dashboardData,
- isLoading,
- error,
- pagination,
-
- // Actions
- loadItems,
- loadItem,
- createItem,
- updateItem,
- deleteItem,
-
- // Stock operations
- loadStockLevels,
- adjustStock,
- loadMovements,
-
- // Dashboard
- loadDashboard,
-
- // Utility
- searchItems,
- refresh,
- clearError
- };
-};
-
-// ========== DASHBOARD HOOK ==========
-
-export const useInventoryDashboard = (): UseInventoryDashboardReturn => {
- const { tenantId } = useTenantId();
- const [dashboardData, setDashboardData] = useState(null);
- const [isLoading, setIsLoading] = useState(false);
- const [error, setError] = useState(null);
-
- const refresh = useCallback(async () => {
- if (!tenantId) return;
-
- setIsLoading(true);
- setError(null);
-
- try {
- const dashboard = await inventoryService.getDashboardData(tenantId);
-
- setDashboardData(dashboard);
- } catch (err: any) {
- const errorMessage = err.response?.data?.detail || err.message || 'Error loading dashboard';
- setError(errorMessage);
- } finally {
- setIsLoading(false);
- }
- }, [tenantId]);
-
- useEffect(() => {
- if (tenantId) {
- refresh();
- }
- }, [tenantId, refresh]);
-
- return {
- dashboardData,
- isLoading,
- error,
- refresh
- };
-};
-
-// ========== SINGLE ITEM HOOK ==========
-
-export const useInventoryItem = (itemId: string): UseInventoryItemReturn => {
- const { tenantId } = useTenantId();
- const [item, setItem] = useState(null);
- const [stockLevel, setStockLevel] = useState(null);
- const [recentMovements, setRecentMovements] = useState([]);
- const [isLoading, setIsLoading] = useState(false);
- const [error, setError] = useState(null);
-
- const refresh = useCallback(async () => {
- if (!tenantId || !itemId) return;
-
- setIsLoading(true);
- setError(null);
-
- try {
- const [itemData, stockData, movementsData] = await Promise.all([
- inventoryService.getInventoryItem(tenantId, itemId),
- inventoryService.getStockLevel(tenantId, itemId),
- inventoryService.getStockMovements(tenantId, { item_id: itemId, limit: 10 })
- ]);
-
- setItem(itemData);
- setStockLevel(stockData);
- setRecentMovements(movementsData.items);
- } catch (err: any) {
- const errorMessage = err.response?.data?.detail || err.message || 'Error loading item';
- setError(errorMessage);
- } finally {
- setIsLoading(false);
- }
- }, [tenantId, itemId]);
-
- const updateItem = useCallback(async (data: UpdateInventoryItemRequest): Promise => {
- if (!tenantId || !itemId) return false;
-
- try {
- const updatedItem = await inventoryService.updateInventoryItem(tenantId, itemId, data);
- setItem(updatedItem);
- toast.success('Item updated successfully');
- return true;
- } catch (err: any) {
- const errorMessage = err.response?.data?.detail || err.message || 'Error updating item';
- setError(errorMessage);
- toast.error(errorMessage);
- return false;
- }
- }, [tenantId, itemId]);
-
- const adjustStock = useCallback(async (adjustment: StockAdjustmentRequest): Promise => {
- if (!tenantId || !itemId) return false;
-
- try {
- const movement = await inventoryService.adjustStock(tenantId, itemId, adjustment);
-
- // Refresh data
- const [updatedStock, updatedMovements] = await Promise.all([
- inventoryService.getStockLevel(tenantId, itemId),
- inventoryService.getStockMovements(tenantId, { item_id: itemId, limit: 10 })
- ]);
-
- setStockLevel(updatedStock);
- setRecentMovements(updatedMovements.items);
-
- toast.success('Stock adjusted successfully');
- return true;
- } catch (err: any) {
- const errorMessage = err.response?.data?.detail || err.message || 'Error adjusting stock';
- setError(errorMessage);
- toast.error(errorMessage);
- return false;
- }
- }, [tenantId, itemId]);
-
- useEffect(() => {
- if (tenantId && itemId) {
- refresh();
- }
- }, [tenantId, itemId, refresh]);
-
- return {
- item,
- stockLevel,
- recentMovements,
- isLoading,
- error,
- updateItem,
- adjustStock,
- refresh
- };
-};
-
-// ========== SIMPLE PRODUCTS HOOK FOR FORECASTING ==========
-
-export const useInventoryProducts = () => {
- const [isLoading, setIsLoading] = useState(false);
- const [error, setError] = useState(null);
-
- /**
- * Get Products List for Forecasting
- */
- const getProductsList = useCallback(async (tenantId: string): Promise => {
- try {
- setIsLoading(true);
- setError(null);
-
- const products = await inventoryService.getProductsList(tenantId);
-
- return products;
- } catch (error) {
- const message = error instanceof Error ? error.message : 'Failed to get products list';
- setError(message);
- throw error;
- } finally {
- setIsLoading(false);
- }
- }, []);
-
- /**
- * Get Product by ID
- */
- const getProductById = useCallback(async (tenantId: string, productId: string): Promise => {
- try {
- setIsLoading(true);
- setError(null);
-
- const product = await inventoryService.getProductById(tenantId, productId);
-
- return product;
- } catch (error) {
- const message = error instanceof Error ? error.message : 'Failed to get product';
- setError(message);
- throw error;
- } finally {
- setIsLoading(false);
- }
- }, []);
-
- return {
- // State
- isLoading,
- error,
-
- // Actions
- getProductsList,
- getProductById,
- };
-};
\ No newline at end of file
diff --git a/fdev-ffrontend/src/api/hooks/useNotification.ts b/fdev-ffrontend/src/api/hooks/useNotification.ts
deleted file mode 100644
index 43b059e7..00000000
--- a/fdev-ffrontend/src/api/hooks/useNotification.ts
+++ /dev/null
@@ -1,151 +0,0 @@
-// frontend/src/api/hooks/useNotification.ts
-/**
- * Notification Operations Hooks
- */
-
-import { useState, useCallback } from 'react';
-import { notificationService } from '../services';
-import type {
- NotificationCreate,
- NotificationResponse,
- NotificationTemplate,
- NotificationStats,
- BulkNotificationRequest,
-} from '../types';
-
-export const useNotification = () => {
- const [notifications, setNotifications] = useState([]);
- const [templates, setTemplates] = useState([]);
- const [stats, setStats] = useState(null);
- const [isLoading, setIsLoading] = useState(false);
- const [error, setError] = useState(null);
-
- const sendNotification = useCallback(async (
- tenantId: string,
- notification: NotificationCreate
- ): Promise => {
- try {
- setIsLoading(true);
- setError(null);
-
- const sentNotification = await notificationService.sendNotification(tenantId, notification);
- setNotifications(prev => [sentNotification, ...prev]);
-
- return sentNotification;
- } catch (error) {
- const message = error instanceof Error ? error.message : 'Failed to send notification';
- setError(message);
- throw error;
- } finally {
- setIsLoading(false);
- }
- }, []);
-
- const sendBulkNotifications = useCallback(async (
- tenantId: string,
- request: BulkNotificationRequest
- ): Promise => {
- try {
- setIsLoading(true);
- setError(null);
-
- await notificationService.sendBulkNotifications(tenantId, request);
- } catch (error) {
- const message = error instanceof Error ? error.message : 'Failed to send bulk notifications';
- setError(message);
- throw error;
- } finally {
- setIsLoading(false);
- }
- }, []);
-
- const getNotifications = useCallback(async (tenantId: string): Promise => {
- try {
- setIsLoading(true);
- setError(null);
-
- const response = await notificationService.getNotifications(tenantId);
- setNotifications(response.data);
-
- return response.data;
- } catch (error) {
- const message = error instanceof Error ? error.message : 'Failed to get notifications';
- setError(message);
- throw error;
- } finally {
- setIsLoading(false);
- }
- }, []);
-
- const getTemplates = useCallback(async (tenantId: string): Promise => {
- try {
- setIsLoading(true);
- setError(null);
-
- const response = await notificationService.getTemplates(tenantId);
- setTemplates(response.data);
-
- return response.data;
- } catch (error) {
- const message = error instanceof Error ? error.message : 'Failed to get templates';
- setError(message);
- throw error;
- } finally {
- setIsLoading(false);
- }
- }, []);
-
- const createTemplate = useCallback(async (
- tenantId: string,
- template: Omit
- ): Promise => {
- try {
- setIsLoading(true);
- setError(null);
-
- const newTemplate = await notificationService.createTemplate(tenantId, template);
- setTemplates(prev => [newTemplate, ...prev]);
-
- return newTemplate;
- } catch (error) {
- const message = error instanceof Error ? error.message : 'Failed to create template';
- setError(message);
- throw error;
- } finally {
- setIsLoading(false);
- }
- }, []);
-
- const getNotificationStats = useCallback(async (tenantId: string): Promise => {
- try {
- setIsLoading(true);
- setError(null);
-
- const notificationStats = await notificationService.getNotificationStats(tenantId);
- setStats(notificationStats);
-
- return notificationStats;
- } catch (error) {
- const message = error instanceof Error ? error.message : 'Failed to get notification stats';
- setError(message);
- throw error;
- } finally {
- setIsLoading(false);
- }
- }, []);
-
- return {
- notifications,
- templates,
- stats,
- isLoading,
- error,
- sendNotification,
- sendBulkNotifications,
- getNotifications,
- getTemplates,
- createTemplate,
- getNotificationStats,
- clearError: () => setError(null),
- };
-};
\ No newline at end of file
diff --git a/fdev-ffrontend/src/api/hooks/useOnboarding.ts b/fdev-ffrontend/src/api/hooks/useOnboarding.ts
deleted file mode 100644
index 492a55bf..00000000
--- a/fdev-ffrontend/src/api/hooks/useOnboarding.ts
+++ /dev/null
@@ -1,194 +0,0 @@
-// frontend/src/api/hooks/useOnboarding.ts
-/**
- * Onboarding Hook
- * React hook for managing user onboarding flow and progress
- */
-
-import { useState, useEffect } from 'react';
-import { onboardingService } from '../services/onboarding.service';
-import type { UserProgress, UpdateStepRequest } from '../services/onboarding.service';
-
-export interface UseOnboardingReturn {
- progress: UserProgress | null;
- isLoading: boolean;
- error: string | null;
- currentStep: string | null;
- nextStep: string | null;
- completionPercentage: number;
- isFullyComplete: boolean;
-
- // Actions
- updateStep: (data: UpdateStepRequest) => Promise;
- completeStep: (stepName: string, data?: Record) => Promise;
- resetStep: (stepName: string) => Promise;
- getNextStep: () => Promise;
- completeOnboarding: () => Promise;
- canAccessStep: (stepName: string) => Promise;
- refreshProgress: () => Promise;
-}
-
-export const useOnboarding = (): UseOnboardingReturn => {
- const [progress, setProgress] = useState(null);
- const [isLoading, setIsLoading] = useState(false);
- const [error, setError] = useState(null);
-
- // Derived state
- const currentStep = progress?.current_step || null;
- const nextStep = progress?.next_step || null;
- const completionPercentage = progress?.completion_percentage || 0;
- const isFullyComplete = progress?.fully_completed || false;
-
- // Load initial progress
- const loadProgress = async () => {
- setIsLoading(true);
- setError(null);
-
- try {
- const userProgress = await onboardingService.getUserProgress();
- setProgress(userProgress);
- } catch (err) {
- const message = err instanceof Error ? err.message : 'Failed to load onboarding progress';
- setError(message);
- console.error('Onboarding progress load error:', err);
- } finally {
- setIsLoading(false);
- }
- };
-
- // Update step
- const updateStep = async (data: UpdateStepRequest) => {
- setIsLoading(true);
- setError(null);
-
- try {
- const updatedProgress = await onboardingService.updateStep(data);
- setProgress(updatedProgress);
- } catch (err) {
- const message = err instanceof Error ? err.message : 'Failed to update step';
- setError(message);
- throw err; // Re-throw so calling component can handle it
- } finally {
- setIsLoading(false);
- }
- };
-
- // Complete step with data
- const completeStep = async (stepName: string, data?: Record) => {
- await updateStep({
- step_name: stepName,
- completed: true,
- data
- });
- };
-
- // Reset step
- const resetStep = async (stepName: string) => {
- await updateStep({
- step_name: stepName,
- completed: false
- });
- };
-
- // Get next step
- const getNextStep = async (): Promise => {
- try {
- const result = await onboardingService.getNextStep();
- return result.step;
- } catch (err) {
- const message = err instanceof Error ? err.message : 'Failed to get next step';
- setError(message);
- throw err;
- }
- };
-
- // Complete entire onboarding
- const completeOnboarding = async () => {
- setIsLoading(true);
- setError(null);
-
- try {
- await onboardingService.completeOnboarding();
- await loadProgress(); // Refresh progress after completion
- } catch (err) {
- const message = err instanceof Error ? err.message : 'Failed to complete onboarding';
- setError(message);
- throw err;
- } finally {
- setIsLoading(false);
- }
- };
-
- // Check if user can access step
- const canAccessStep = async (stepName: string): Promise => {
- try {
- const result = await onboardingService.canAccessStep(stepName);
- return result.can_access;
- } catch (err) {
- console.error('Can access step check failed:', err);
- return false;
- }
- };
-
- // Refresh progress
- const refreshProgress = async () => {
- await loadProgress();
- };
-
- // Load progress on mount
- useEffect(() => {
- loadProgress();
- }, []);
-
- return {
- progress,
- isLoading,
- error,
- currentStep,
- nextStep,
- completionPercentage,
- isFullyComplete,
- updateStep,
- completeStep,
- resetStep,
- getNextStep,
- completeOnboarding,
- canAccessStep,
- refreshProgress,
- };
-};
-
-// Helper hook for specific steps
-export const useOnboardingStep = (stepName: string) => {
- const onboarding = useOnboarding();
-
- const stepStatus = onboarding.progress?.steps.find(
- step => step.step_name === stepName
- );
-
- const isCompleted = stepStatus?.completed || false;
- const stepData = stepStatus?.data || {};
- const completedAt = stepStatus?.completed_at;
-
- const completeThisStep = async (data?: Record) => {
- await onboarding.completeStep(stepName, data);
- };
-
- const resetThisStep = async () => {
- await onboarding.resetStep(stepName);
- };
-
- const canAccessThisStep = async (): Promise => {
- return await onboarding.canAccessStep(stepName);
- };
-
- return {
- ...onboarding,
- stepName,
- isCompleted,
- stepData,
- completedAt,
- completeThisStep,
- resetThisStep,
- canAccessThisStep,
- };
-};
\ No newline at end of file
diff --git a/fdev-ffrontend/src/api/hooks/usePOS.ts b/fdev-ffrontend/src/api/hooks/usePOS.ts
deleted file mode 100644
index 044d968a..00000000
--- a/fdev-ffrontend/src/api/hooks/usePOS.ts
+++ /dev/null
@@ -1,337 +0,0 @@
-// frontend/src/api/hooks/usePOS.ts
-/**
- * React hooks for POS Integration functionality
- */
-
-import { useState, useEffect } from 'react';
-import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
-import {
- posService,
- POSConfiguration,
- CreatePOSConfigurationRequest,
- UpdatePOSConfigurationRequest,
- POSTransaction,
- POSSyncLog,
- POSAnalytics,
- SyncRequest
-} from '../services/pos.service';
-import { useTenantId } from './useTenant';
-
-// ============================================================================
-// CONFIGURATION HOOKS
-// ============================================================================
-
-export const usePOSConfigurations = (params?: {
- pos_system?: string;
- is_active?: boolean;
- limit?: number;
- offset?: number;
-}) => {
- const tenantId = useTenantId();
-
- return useQuery({
- queryKey: ['pos-configurations', tenantId, params],
- queryFn: () => posService.getConfigurations(tenantId, params),
- enabled: !!tenantId,
- staleTime: 5 * 60 * 1000, // 5 minutes
- });
-};
-
-export const usePOSConfiguration = (configId?: string) => {
- const tenantId = useTenantId();
-
- return useQuery({
- queryKey: ['pos-configuration', tenantId, configId],
- queryFn: () => posService.getConfiguration(tenantId, configId!),
- enabled: !!tenantId && !!configId,
- staleTime: 5 * 60 * 1000,
- });
-};
-
-export const useCreatePOSConfiguration = () => {
- const queryClient = useQueryClient();
- const tenantId = useTenantId();
-
- return useMutation({
- mutationFn: (data: CreatePOSConfigurationRequest) =>
- posService.createConfiguration(tenantId, data),
- onSuccess: () => {
- queryClient.invalidateQueries({ queryKey: ['pos-configurations', tenantId] });
- },
- });
-};
-
-export const useUpdatePOSConfiguration = () => {
- const queryClient = useQueryClient();
- const tenantId = useTenantId();
-
- return useMutation({
- mutationFn: ({ configId, data }: { configId: string; data: UpdatePOSConfigurationRequest }) =>
- posService.updateConfiguration(tenantId, configId, data),
- onSuccess: (_, { configId }) => {
- queryClient.invalidateQueries({ queryKey: ['pos-configurations', tenantId] });
- queryClient.invalidateQueries({ queryKey: ['pos-configuration', tenantId, configId] });
- },
- });
-};
-
-export const useDeletePOSConfiguration = () => {
- const queryClient = useQueryClient();
- const tenantId = useTenantId();
-
- return useMutation({
- mutationFn: (configId: string) =>
- posService.deleteConfiguration(tenantId, configId),
- onSuccess: () => {
- queryClient.invalidateQueries({ queryKey: ['pos-configurations', tenantId] });
- },
- });
-};
-
-export const useTestPOSConnection = () => {
- const tenantId = useTenantId();
-
- return useMutation({
- mutationFn: (configId: string) =>
- posService.testConnection(tenantId, configId),
- });
-};
-
-// ============================================================================
-// SYNCHRONIZATION HOOKS
-// ============================================================================
-
-export const useTriggerPOSSync = () => {
- const queryClient = useQueryClient();
- const tenantId = useTenantId();
-
- return useMutation({
- mutationFn: ({ configId, syncRequest }: { configId: string; syncRequest: SyncRequest }) =>
- posService.triggerSync(tenantId, configId, syncRequest),
- onSuccess: (_, { configId }) => {
- queryClient.invalidateQueries({ queryKey: ['pos-sync-status', tenantId, configId] });
- queryClient.invalidateQueries({ queryKey: ['pos-sync-logs', tenantId, configId] });
- },
- });
-};
-
-export const usePOSSyncStatus = (configId?: string, pollingInterval?: number) => {
- const tenantId = useTenantId();
-
- return useQuery({
- queryKey: ['pos-sync-status', tenantId, configId],
- queryFn: () => posService.getSyncStatus(tenantId, configId!),
- enabled: !!tenantId && !!configId,
- refetchInterval: pollingInterval || 30000, // Poll every 30 seconds by default
- staleTime: 10 * 1000, // 10 seconds
- });
-};
-
-export const usePOSSyncLogs = (configId?: string, params?: {
- limit?: number;
- offset?: number;
- status?: string;
- sync_type?: string;
- data_type?: string;
-}) => {
- const tenantId = useTenantId();
-
- return useQuery({
- queryKey: ['pos-sync-logs', tenantId, configId, params],
- queryFn: () => posService.getSyncLogs(tenantId, configId!, params),
- enabled: !!tenantId && !!configId,
- staleTime: 2 * 60 * 1000, // 2 minutes
- });
-};
-
-// ============================================================================
-// TRANSACTION HOOKS
-// ============================================================================
-
-export const usePOSTransactions = (params?: {
- pos_system?: string;
- start_date?: string;
- end_date?: string;
- status?: string;
- is_synced?: boolean;
- limit?: number;
- offset?: number;
-}) => {
- const tenantId = useTenantId();
-
- return useQuery({
- queryKey: ['pos-transactions', tenantId, params],
- queryFn: () => posService.getTransactions(tenantId, params),
- enabled: !!tenantId,
- staleTime: 2 * 60 * 1000, // 2 minutes
- });
-};
-
-export const useSyncSingleTransaction = () => {
- const queryClient = useQueryClient();
- const tenantId = useTenantId();
-
- return useMutation({
- mutationFn: ({ transactionId, force }: { transactionId: string; force?: boolean }) =>
- posService.syncSingleTransaction(tenantId, transactionId, force),
- onSuccess: () => {
- queryClient.invalidateQueries({ queryKey: ['pos-transactions', tenantId] });
- },
- });
-};
-
-export const useResyncFailedTransactions = () => {
- const queryClient = useQueryClient();
- const tenantId = useTenantId();
-
- return useMutation({
- mutationFn: (daysBack: number) =>
- posService.resyncFailedTransactions(tenantId, daysBack),
- onSuccess: () => {
- queryClient.invalidateQueries({ queryKey: ['pos-transactions', tenantId] });
- },
- });
-};
-
-// ============================================================================
-// ANALYTICS HOOKS
-// ============================================================================
-
-export const usePOSAnalytics = (days: number = 30) => {
- const tenantId = useTenantId();
-
- return useQuery({
- queryKey: ['pos-analytics', tenantId, days],
- queryFn: () => posService.getSyncAnalytics(tenantId, days),
- enabled: !!tenantId,
- staleTime: 10 * 60 * 1000, // 10 minutes
- });
-};
-
-// ============================================================================
-// SYSTEM INFO HOOKS
-// ============================================================================
-
-export const useSupportedPOSSystems = () => {
- return useQuery({
- queryKey: ['supported-pos-systems'],
- queryFn: () => posService.getSupportedSystems(),
- staleTime: 60 * 60 * 1000, // 1 hour
- });
-};
-
-export const useWebhookStatus = (posSystem?: string) => {
- return useQuery({
- queryKey: ['webhook-status', posSystem],
- queryFn: () => posService.getWebhookStatus(posSystem!),
- enabled: !!posSystem,
- staleTime: 5 * 60 * 1000, // 5 minutes
- });
-};
-
-// ============================================================================
-// COMPOSITE HOOKS
-// ============================================================================
-
-export const usePOSDashboard = () => {
- const tenantId = useTenantId();
-
- // Get configurations
- const { data: configurationsData, isLoading: configurationsLoading } = usePOSConfigurations();
-
- // Get recent transactions
- const { data: transactionsData, isLoading: transactionsLoading } = usePOSTransactions({
- limit: 10
- });
-
- // Get analytics for last 7 days
- const { data: analyticsData, isLoading: analyticsLoading } = usePOSAnalytics(7);
-
- const isLoading = configurationsLoading || transactionsLoading || analyticsLoading;
-
- return {
- configurations: configurationsData?.configurations || [],
- transactions: transactionsData?.transactions || [],
- analytics: analyticsData,
- isLoading,
- summary: {
- total_configurations: configurationsData?.total || 0,
- active_configurations: configurationsData?.configurations?.filter(c => c.is_active).length || 0,
- connected_configurations: configurationsData?.configurations?.filter(c => c.is_connected).length || 0,
- total_transactions: transactionsData?.total || 0,
- total_revenue: transactionsData?.summary?.total_amount || 0,
- sync_health: analyticsData?.success_rate || 0,
- }
- };
-};
-
-export const usePOSConfigurationManagement = () => {
- const createMutation = useCreatePOSConfiguration();
- const updateMutation = useUpdatePOSConfiguration();
- const deleteMutation = useDeletePOSConfiguration();
- const testConnectionMutation = useTestPOSConnection();
-
- const [selectedConfiguration, setSelectedConfiguration] = useState(null);
- const [isFormOpen, setIsFormOpen] = useState(false);
-
- const handleCreate = async (data: CreatePOSConfigurationRequest) => {
- await createMutation.mutateAsync(data);
- setIsFormOpen(false);
- };
-
- const handleUpdate = async (configId: string, data: UpdatePOSConfigurationRequest) => {
- await updateMutation.mutateAsync({ configId, data });
- setIsFormOpen(false);
- setSelectedConfiguration(null);
- };
-
- const handleDelete = async (configId: string) => {
- await deleteMutation.mutateAsync(configId);
- };
-
- const handleTestConnection = async (configId: string) => {
- return await testConnectionMutation.mutateAsync(configId);
- };
-
- const openCreateForm = () => {
- setSelectedConfiguration(null);
- setIsFormOpen(true);
- };
-
- const openEditForm = (configuration: POSConfiguration) => {
- setSelectedConfiguration(configuration);
- setIsFormOpen(true);
- };
-
- const closeForm = () => {
- setIsFormOpen(false);
- setSelectedConfiguration(null);
- };
-
- return {
- // State
- selectedConfiguration,
- isFormOpen,
-
- // Actions
- handleCreate,
- handleUpdate,
- handleDelete,
- handleTestConnection,
- openCreateForm,
- openEditForm,
- closeForm,
-
- // Loading states
- isCreating: createMutation.isPending,
- isUpdating: updateMutation.isPending,
- isDeleting: deleteMutation.isPending,
- isTesting: testConnectionMutation.isPending,
-
- // Errors
- createError: createMutation.error,
- updateError: updateMutation.error,
- deleteError: deleteMutation.error,
- testError: testConnectionMutation.error,
- };
-};
\ No newline at end of file
diff --git a/fdev-ffrontend/src/api/hooks/useProcurement.ts b/fdev-ffrontend/src/api/hooks/useProcurement.ts
deleted file mode 100644
index 067fd9ec..00000000
--- a/fdev-ffrontend/src/api/hooks/useProcurement.ts
+++ /dev/null
@@ -1,294 +0,0 @@
-// ================================================================
-// frontend/src/api/hooks/useProcurement.ts
-// ================================================================
-/**
- * React hooks for procurement planning functionality
- */
-
-import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
-import { procurementService } from '../services/procurement.service';
-import type {
- ProcurementPlan,
- GeneratePlanRequest,
- GeneratePlanResponse,
- DashboardData,
- ProcurementRequirement,
- PaginatedProcurementPlans
-} from '../types/procurement';
-
-// ================================================================
-// QUERY KEYS
-// ================================================================
-
-export const procurementKeys = {
- all: ['procurement'] as const,
- plans: () => [...procurementKeys.all, 'plans'] as const,
- plan: (id: string) => [...procurementKeys.plans(), id] as const,
- currentPlan: () => [...procurementKeys.plans(), 'current'] as const,
- planByDate: (date: string) => [...procurementKeys.plans(), 'date', date] as const,
- plansList: (filters?: any) => [...procurementKeys.plans(), 'list', filters] as const,
- requirements: () => [...procurementKeys.all, 'requirements'] as const,
- planRequirements: (planId: string) => [...procurementKeys.requirements(), 'plan', planId] as const,
- criticalRequirements: () => [...procurementKeys.requirements(), 'critical'] as const,
- dashboard: () => [...procurementKeys.all, 'dashboard'] as const,
-};
-
-// ================================================================
-// PROCUREMENT PLAN HOOKS
-// ================================================================
-
-/**
- * Hook to fetch the current day's procurement plan
- */
-export function useCurrentProcurementPlan() {
- return useQuery({
- queryKey: procurementKeys.currentPlan(),
- queryFn: () => procurementService.getCurrentPlan(),
- staleTime: 5 * 60 * 1000, // 5 minutes
- refetchInterval: 10 * 60 * 1000, // Refetch every 10 minutes
- });
-}
-
-/**
- * Hook to fetch procurement plan by date
- */
-export function useProcurementPlanByDate(date: string, enabled = true) {
- return useQuery({
- queryKey: procurementKeys.planByDate(date),
- queryFn: () => procurementService.getPlanByDate(date),
- enabled: enabled && !!date,
- staleTime: 30 * 60 * 1000, // 30 minutes for historical data
- });
-}
-
-/**
- * Hook to fetch procurement plan by ID
- */
-export function useProcurementPlan(planId: string, enabled = true) {
- return useQuery({
- queryKey: procurementKeys.plan(planId),
- queryFn: () => procurementService.getPlanById(planId),
- enabled: enabled && !!planId,
- staleTime: 10 * 60 * 1000, // 10 minutes
- });
-}
-
-/**
- * Hook to fetch paginated list of procurement plans
- */
-export function useProcurementPlans(params?: {
- status?: string;
- startDate?: string;
- endDate?: string;
- limit?: number;
- offset?: number;
-}) {
- return useQuery({
- queryKey: procurementKeys.plansList(params),
- queryFn: () => procurementService.listPlans(params),
- staleTime: 5 * 60 * 1000, // 5 minutes
- });
-}
-
-// ================================================================
-// REQUIREMENTS HOOKS
-// ================================================================
-
-/**
- * Hook to fetch requirements for a specific plan
- */
-export function usePlanRequirements(
- planId: string,
- filters?: {
- status?: string;
- priority?: string;
- },
- enabled = true
-) {
- return useQuery({
- queryKey: procurementKeys.planRequirements(planId),
- queryFn: () => procurementService.getPlanRequirements(planId, filters),
- enabled: enabled && !!planId,
- staleTime: 5 * 60 * 1000, // 5 minutes
- });
-}
-
-/**
- * Hook to fetch critical requirements across all plans
- */
-export function useCriticalRequirements() {
- return useQuery({
- queryKey: procurementKeys.criticalRequirements(),
- queryFn: () => procurementService.getCriticalRequirements(),
- staleTime: 2 * 60 * 1000, // 2 minutes for critical data
- refetchInterval: 5 * 60 * 1000, // Refetch every 5 minutes
- });
-}
-
-// ================================================================
-// DASHBOARD HOOKS
-// ================================================================
-
-/**
- * Hook to fetch procurement dashboard data
- */
-export function useProcurementDashboard() {
- return useQuery({
- queryKey: procurementKeys.dashboard(),
- queryFn: () => procurementService.getDashboardData(),
- staleTime: 2 * 60 * 1000, // 2 minutes
- refetchInterval: 5 * 60 * 1000, // Refetch every 5 minutes
- });
-}
-
-// ================================================================
-// MUTATION HOOKS
-// ================================================================
-
-/**
- * Hook to generate a new procurement plan
- */
-export function useGenerateProcurementPlan() {
- const queryClient = useQueryClient();
-
- return useMutation({
- mutationFn: (request: GeneratePlanRequest) =>
- procurementService.generatePlan(request),
- onSuccess: (data: GeneratePlanResponse) => {
- // Invalidate relevant queries
- queryClient.invalidateQueries({ queryKey: procurementKeys.plans() });
- queryClient.invalidateQueries({ queryKey: procurementKeys.dashboard() });
-
- // If plan was generated successfully, update the cache
- if (data.success && data.plan) {
- queryClient.setQueryData(
- procurementKeys.plan(data.plan.id),
- data.plan
- );
-
- // Update current plan cache if this is today's plan
- const today = new Date().toISOString().split('T')[0];
- if (data.plan.plan_date === today) {
- queryClient.setQueryData(
- procurementKeys.currentPlan(),
- data.plan
- );
- }
- }
- },
- });
-}
-
-/**
- * Hook to update procurement plan status
- */
-export function useUpdatePlanStatus() {
- const queryClient = useQueryClient();
-
- return useMutation({
- mutationFn: ({ planId, status }: { planId: string; status: string }) =>
- procurementService.updatePlanStatus(planId, status),
- onSuccess: (updatedPlan: ProcurementPlan) => {
- // Update the specific plan in cache
- queryClient.setQueryData(
- procurementKeys.plan(updatedPlan.id),
- updatedPlan
- );
-
- // Update current plan if this is the current plan
- const today = new Date().toISOString().split('T')[0];
- if (updatedPlan.plan_date === today) {
- queryClient.setQueryData(
- procurementKeys.currentPlan(),
- updatedPlan
- );
- }
-
- // Invalidate lists to ensure they're refreshed
- queryClient.invalidateQueries({ queryKey: procurementKeys.plansList() });
- queryClient.invalidateQueries({ queryKey: procurementKeys.dashboard() });
- },
- });
-}
-
-/**
- * Hook to trigger the daily scheduler manually
- */
-export function useTriggerDailyScheduler() {
- const queryClient = useQueryClient();
-
- return useMutation({
- mutationFn: () => procurementService.triggerDailyScheduler(),
- onSuccess: () => {
- // Invalidate all procurement data
- queryClient.invalidateQueries({ queryKey: procurementKeys.all });
- },
- });
-}
-
-// ================================================================
-// UTILITY HOOKS
-// ================================================================
-
-/**
- * Hook to check procurement service health
- */
-export function useProcurementHealth() {
- return useQuery({
- queryKey: [...procurementKeys.all, 'health'],
- queryFn: () => procurementService.healthCheck(),
- staleTime: 60 * 1000, // 1 minute
- refetchInterval: 5 * 60 * 1000, // Check every 5 minutes
- });
-}
-
-// ================================================================
-// COMBINED HOOKS
-// ================================================================
-
-/**
- * Combined hook for procurement plan dashboard
- * Fetches current plan, dashboard data, and critical requirements
- */
-export function useProcurementPlanDashboard() {
- const currentPlan = useCurrentProcurementPlan();
- const dashboard = useProcurementDashboard();
- const criticalRequirements = useCriticalRequirements();
- const health = useProcurementHealth();
-
- return {
- currentPlan,
- dashboard,
- criticalRequirements,
- health,
- isLoading: currentPlan.isLoading || dashboard.isLoading,
- error: currentPlan.error || dashboard.error || criticalRequirements.error,
- refetchAll: () => {
- currentPlan.refetch();
- dashboard.refetch();
- criticalRequirements.refetch();
- health.refetch();
- },
- };
-}
-
-/**
- * Hook for managing procurement plan lifecycle
- */
-export function useProcurementPlanActions() {
- const generatePlan = useGenerateProcurementPlan();
- const updateStatus = useUpdatePlanStatus();
- const triggerScheduler = useTriggerDailyScheduler();
-
- return {
- generatePlan: generatePlan.mutate,
- updateStatus: updateStatus.mutate,
- triggerScheduler: triggerScheduler.mutate,
- isGenerating: generatePlan.isPending,
- isUpdating: updateStatus.isPending,
- isTriggering: triggerScheduler.isPending,
- generateError: generatePlan.error,
- updateError: updateStatus.error,
- triggerError: triggerScheduler.error,
- };
-}
\ No newline at end of file
diff --git a/fdev-ffrontend/src/api/hooks/useRecipes.ts b/fdev-ffrontend/src/api/hooks/useRecipes.ts
deleted file mode 100644
index 3e3f33b5..00000000
--- a/fdev-ffrontend/src/api/hooks/useRecipes.ts
+++ /dev/null
@@ -1,682 +0,0 @@
-// frontend/src/api/hooks/useRecipes.ts
-/**
- * React hooks for recipe and production management
- */
-
-import { useState, useEffect, useCallback, useMemo } from 'react';
-import { toast } from 'react-hot-toast';
-import {
- RecipesService,
- Recipe,
- RecipeIngredient,
- CreateRecipeRequest,
- UpdateRecipeRequest,
- RecipeSearchParams,
- RecipeFeasibility,
- RecipeStatistics,
- ProductionBatch,
- CreateProductionBatchRequest,
- UpdateProductionBatchRequest,
- ProductionBatchSearchParams,
- ProductionStatistics
-} from '../services/recipes.service';
-import { useTenant } from './useTenant';
-import { useAuth } from './useAuth';
-
-const recipesService = new RecipesService();
-
-// Recipe Management Hook
-export interface UseRecipesReturn {
- // Data
- recipes: Recipe[];
- selectedRecipe: Recipe | null;
- categories: string[];
- statistics: RecipeStatistics | null;
-
- // State
- isLoading: boolean;
- isCreating: boolean;
- isUpdating: boolean;
- isDeleting: boolean;
- error: string | null;
-
- // Pagination
- pagination: {
- page: number;
- limit: number;
- total: number;
- totalPages: number;
- };
-
- // Actions
- loadRecipes: (params?: RecipeSearchParams) => Promise;
- loadRecipe: (recipeId: string) => Promise;
- createRecipe: (data: CreateRecipeRequest) => Promise;
- updateRecipe: (recipeId: string, data: UpdateRecipeRequest) => Promise;
- deleteRecipe: (recipeId: string) => Promise;
- duplicateRecipe: (recipeId: string, newName: string) => Promise;
- activateRecipe: (recipeId: string) => Promise;
- checkFeasibility: (recipeId: string, batchMultiplier?: number) => Promise;
- loadStatistics: () => Promise;
- loadCategories: () => Promise;
- clearError: () => void;
- refresh: () => Promise;
- setPage: (page: number) => void;
-}
-
-export const useRecipes = (autoLoad: boolean = true): UseRecipesReturn => {
- const { currentTenant } = useTenant();
- const { user } = useAuth();
-
- // State
- const [recipes, setRecipes] = useState([]);
- const [selectedRecipe, setSelectedRecipe] = useState(null);
- const [categories, setCategories] = useState([]);
- const [statistics, setStatistics] = useState(null);
- const [isLoading, setIsLoading] = useState(false);
- const [isCreating, setIsCreating] = useState(false);
- const [isUpdating, setIsUpdating] = useState(false);
- const [isDeleting, setIsDeleting] = useState(false);
- const [error, setError] = useState(null);
- const [currentParams, setCurrentParams] = useState({});
- const [pagination, setPagination] = useState({
- page: 1,
- limit: 20,
- total: 0,
- totalPages: 0
- });
-
- // Load recipes
- const loadRecipes = useCallback(async (params: RecipeSearchParams = {}) => {
- if (!currentTenant?.id) return;
-
- setIsLoading(true);
- setError(null);
-
- try {
- const searchParams = {
- ...params,
- limit: pagination.limit,
- offset: (pagination.page - 1) * pagination.limit
- };
-
- const recipesData = await recipesService.getRecipes(currentTenant.id, searchParams);
- setRecipes(recipesData);
- setCurrentParams(params);
-
- // Calculate pagination (assuming we get total count somehow)
- const total = recipesData.length; // This would need to be from a proper paginated response
- setPagination(prev => ({
- ...prev,
- total,
- totalPages: Math.ceil(total / prev.limit)
- }));
-
- } catch (err: any) {
- const errorMessage = err.response?.data?.detail || err.message || 'Error loading recipes';
- setError(errorMessage);
- toast.error(errorMessage);
- } finally {
- setIsLoading(false);
- }
- }, [currentTenant?.id, pagination.page, pagination.limit]);
-
- // Load single recipe
- const loadRecipe = useCallback(async (recipeId: string) => {
- if (!currentTenant?.id) return;
-
- setIsLoading(true);
- setError(null);
-
- try {
- const recipe = await recipesService.getRecipe(currentTenant.id, recipeId);
- setSelectedRecipe(recipe);
- } catch (err: any) {
- const errorMessage = err.response?.data?.detail || err.message || 'Error loading recipe';
- setError(errorMessage);
- toast.error(errorMessage);
- } finally {
- setIsLoading(false);
- }
- }, [currentTenant?.id]);
-
- // Create recipe
- const createRecipe = useCallback(async (data: CreateRecipeRequest): Promise => {
- if (!currentTenant?.id || !user?.id) return null;
-
- setIsCreating(true);
- setError(null);
-
- try {
- const newRecipe = await recipesService.createRecipe(currentTenant.id, user.id, data);
-
- // Add to local state
- setRecipes(prev => [newRecipe, ...prev]);
-
- toast.success('Recipe created successfully');
- return newRecipe;
- } catch (err: any) {
- const errorMessage = err.response?.data?.detail || err.message || 'Error creating recipe';
- setError(errorMessage);
- toast.error(errorMessage);
- return null;
- } finally {
- setIsCreating(false);
- }
- }, [currentTenant?.id, user?.id]);
-
- // Update recipe
- const updateRecipe = useCallback(async (recipeId: string, data: UpdateRecipeRequest): Promise => {
- if (!currentTenant?.id || !user?.id) return null;
-
- setIsUpdating(true);
- setError(null);
-
- try {
- const updatedRecipe = await recipesService.updateRecipe(currentTenant.id, user.id, recipeId, data);
-
- // Update local state
- setRecipes(prev => prev.map(recipe =>
- recipe.id === recipeId ? updatedRecipe : recipe
- ));
-
- if (selectedRecipe?.id === recipeId) {
- setSelectedRecipe(updatedRecipe);
- }
-
- toast.success('Recipe updated successfully');
- return updatedRecipe;
- } catch (err: any) {
- const errorMessage = err.response?.data?.detail || err.message || 'Error updating recipe';
- setError(errorMessage);
- toast.error(errorMessage);
- return null;
- } finally {
- setIsUpdating(false);
- }
- }, [currentTenant?.id, user?.id, selectedRecipe?.id]);
-
- // Delete recipe
- const deleteRecipe = useCallback(async (recipeId: string): Promise => {
- if (!currentTenant?.id) return false;
-
- setIsDeleting(true);
- setError(null);
-
- try {
- await recipesService.deleteRecipe(currentTenant.id, recipeId);
-
- // Remove from local state
- setRecipes(prev => prev.filter(recipe => recipe.id !== recipeId));
-
- if (selectedRecipe?.id === recipeId) {
- setSelectedRecipe(null);
- }
-
- toast.success('Recipe deleted successfully');
- return true;
- } catch (err: any) {
- const errorMessage = err.response?.data?.detail || err.message || 'Error deleting recipe';
- setError(errorMessage);
- toast.error(errorMessage);
- return false;
- } finally {
- setIsDeleting(false);
- }
- }, [currentTenant?.id, selectedRecipe?.id]);
-
- // Duplicate recipe
- const duplicateRecipe = useCallback(async (recipeId: string, newName: string): Promise => {
- if (!currentTenant?.id || !user?.id) return null;
-
- setIsCreating(true);
- setError(null);
-
- try {
- const duplicatedRecipe = await recipesService.duplicateRecipe(currentTenant.id, user.id, recipeId, newName);
-
- // Add to local state
- setRecipes(prev => [duplicatedRecipe, ...prev]);
-
- toast.success('Recipe duplicated successfully');
- return duplicatedRecipe;
- } catch (err: any) {
- const errorMessage = err.response?.data?.detail || err.message || 'Error duplicating recipe';
- setError(errorMessage);
- toast.error(errorMessage);
- return null;
- } finally {
- setIsCreating(false);
- }
- }, [currentTenant?.id, user?.id]);
-
- // Activate recipe
- const activateRecipe = useCallback(async (recipeId: string): Promise => {
- if (!currentTenant?.id || !user?.id) return null;
-
- setIsUpdating(true);
- setError(null);
-
- try {
- const activatedRecipe = await recipesService.activateRecipe(currentTenant.id, user.id, recipeId);
-
- // Update local state
- setRecipes(prev => prev.map(recipe =>
- recipe.id === recipeId ? activatedRecipe : recipe
- ));
-
- if (selectedRecipe?.id === recipeId) {
- setSelectedRecipe(activatedRecipe);
- }
-
- toast.success('Recipe activated successfully');
- return activatedRecipe;
- } catch (err: any) {
- const errorMessage = err.response?.data?.detail || err.message || 'Error activating recipe';
- setError(errorMessage);
- toast.error(errorMessage);
- return null;
- } finally {
- setIsUpdating(false);
- }
- }, [currentTenant?.id, user?.id, selectedRecipe?.id]);
-
- // Check feasibility
- const checkFeasibility = useCallback(async (recipeId: string, batchMultiplier: number = 1.0): Promise => {
- if (!currentTenant?.id) return null;
-
- try {
- const feasibility = await recipesService.checkRecipeFeasibility(currentTenant.id, recipeId, batchMultiplier);
- return feasibility;
- } catch (err: any) {
- const errorMessage = err.response?.data?.detail || err.message || 'Error checking recipe feasibility';
- setError(errorMessage);
- toast.error(errorMessage);
- return null;
- }
- }, [currentTenant?.id]);
-
- // Load statistics
- const loadStatistics = useCallback(async () => {
- if (!currentTenant?.id) return;
-
- try {
- const stats = await recipesService.getRecipeStatistics(currentTenant.id);
- setStatistics(stats);
- } catch (err: any) {
- console.error('Error loading recipe statistics:', err);
- }
- }, [currentTenant?.id]);
-
- // Load categories
- const loadCategories = useCallback(async () => {
- if (!currentTenant?.id) return;
-
- try {
- const cats = await recipesService.getRecipeCategories(currentTenant.id);
- setCategories(cats);
- } catch (err: any) {
- console.error('Error loading recipe categories:', err);
- }
- }, [currentTenant?.id]);
-
- // Clear error
- const clearError = useCallback(() => {
- setError(null);
- }, []);
-
- // Refresh
- const refresh = useCallback(async () => {
- await Promise.all([
- loadRecipes(currentParams),
- loadStatistics(),
- loadCategories()
- ]);
- }, [loadRecipes, currentParams, loadStatistics, loadCategories]);
-
- // Set page
- const setPage = useCallback((page: number) => {
- setPagination(prev => ({ ...prev, page }));
- }, []);
-
- // Auto-load on mount and dependencies change
- useEffect(() => {
- if (autoLoad && currentTenant?.id) {
- refresh();
- }
- }, [autoLoad, currentTenant?.id, pagination.page]);
-
- return {
- // Data
- recipes,
- selectedRecipe,
- categories,
- statistics,
-
- // State
- isLoading,
- isCreating,
- isUpdating,
- isDeleting,
- error,
- pagination,
-
- // Actions
- loadRecipes,
- loadRecipe,
- createRecipe,
- updateRecipe,
- deleteRecipe,
- duplicateRecipe,
- activateRecipe,
- checkFeasibility,
- loadStatistics,
- loadCategories,
- clearError,
- refresh,
- setPage
- };
-};
-
-// Production Management Hook
-export interface UseProductionReturn {
- // Data
- batches: ProductionBatch[];
- selectedBatch: ProductionBatch | null;
- activeBatches: ProductionBatch[];
- statistics: ProductionStatistics | null;
-
- // State
- isLoading: boolean;
- isCreating: boolean;
- isUpdating: boolean;
- isDeleting: boolean;
- error: string | null;
-
- // Actions
- loadBatches: (params?: ProductionBatchSearchParams) => Promise;
- loadBatch: (batchId: string) => Promise;
- loadActiveBatches: () => Promise;
- createBatch: (data: CreateProductionBatchRequest) => Promise;
- updateBatch: (batchId: string, data: UpdateProductionBatchRequest) => Promise;
- deleteBatch: (batchId: string) => Promise;
- startBatch: (batchId: string, data: any) => Promise;
- completeBatch: (batchId: string, data: any) => Promise;
- loadStatistics: (startDate?: string, endDate?: string) => Promise;
- clearError: () => void;
- refresh: () => Promise;
-}
-
-export const useProduction = (autoLoad: boolean = true): UseProductionReturn => {
- const { currentTenant } = useTenant();
- const { user } = useAuth();
-
- // State
- const [batches, setBatches] = useState([]);
- const [selectedBatch, setSelectedBatch] = useState(null);
- const [activeBatches, setActiveBatches] = useState([]);
- const [statistics, setStatistics] = useState(null);
- const [isLoading, setIsLoading] = useState(false);
- const [isCreating, setIsCreating] = useState(false);
- const [isUpdating, setIsUpdating] = useState(false);
- const [isDeleting, setIsDeleting] = useState(false);
- const [error, setError] = useState(null);
-
- // Load batches
- const loadBatches = useCallback(async (params: ProductionBatchSearchParams = {}) => {
- if (!currentTenant?.id) return;
-
- setIsLoading(true);
- setError(null);
-
- try {
- const batchesData = await recipesService.getProductionBatches(currentTenant.id, params);
- setBatches(batchesData);
- } catch (err: any) {
- const errorMessage = err.response?.data?.detail || err.message || 'Error loading production batches';
- setError(errorMessage);
- toast.error(errorMessage);
- } finally {
- setIsLoading(false);
- }
- }, [currentTenant?.id]);
-
- // Load single batch
- const loadBatch = useCallback(async (batchId: string) => {
- if (!currentTenant?.id) return;
-
- setIsLoading(true);
- setError(null);
-
- try {
- const batch = await recipesService.getProductionBatch(currentTenant.id, batchId);
- setSelectedBatch(batch);
- } catch (err: any) {
- const errorMessage = err.response?.data?.detail || err.message || 'Error loading production batch';
- setError(errorMessage);
- toast.error(errorMessage);
- } finally {
- setIsLoading(false);
- }
- }, [currentTenant?.id]);
-
- // Load active batches
- const loadActiveBatches = useCallback(async () => {
- if (!currentTenant?.id) return;
-
- try {
- const activeBatchesData = await recipesService.getActiveProductionBatches(currentTenant.id);
- setActiveBatches(activeBatchesData);
- } catch (err: any) {
- console.error('Error loading active batches:', err);
- }
- }, [currentTenant?.id]);
-
- // Create batch
- const createBatch = useCallback(async (data: CreateProductionBatchRequest): Promise => {
- if (!currentTenant?.id || !user?.id) return null;
-
- setIsCreating(true);
- setError(null);
-
- try {
- const newBatch = await recipesService.createProductionBatch(currentTenant.id, user.id, data);
-
- // Add to local state
- setBatches(prev => [newBatch, ...prev]);
-
- toast.success('Production batch created successfully');
- return newBatch;
- } catch (err: any) {
- const errorMessage = err.response?.data?.detail || err.message || 'Error creating production batch';
- setError(errorMessage);
- toast.error(errorMessage);
- return null;
- } finally {
- setIsCreating(false);
- }
- }, [currentTenant?.id, user?.id]);
-
- // Update batch
- const updateBatch = useCallback(async (batchId: string, data: UpdateProductionBatchRequest): Promise => {
- if (!currentTenant?.id || !user?.id) return null;
-
- setIsUpdating(true);
- setError(null);
-
- try {
- const updatedBatch = await recipesService.updateProductionBatch(currentTenant.id, user.id, batchId, data);
-
- // Update local state
- setBatches(prev => prev.map(batch =>
- batch.id === batchId ? updatedBatch : batch
- ));
-
- if (selectedBatch?.id === batchId) {
- setSelectedBatch(updatedBatch);
- }
-
- toast.success('Production batch updated successfully');
- return updatedBatch;
- } catch (err: any) {
- const errorMessage = err.response?.data?.detail || err.message || 'Error updating production batch';
- setError(errorMessage);
- toast.error(errorMessage);
- return null;
- } finally {
- setIsUpdating(false);
- }
- }, [currentTenant?.id, user?.id, selectedBatch?.id]);
-
- // Delete batch
- const deleteBatch = useCallback(async (batchId: string): Promise => {
- if (!currentTenant?.id) return false;
-
- setIsDeleting(true);
- setError(null);
-
- try {
- await recipesService.deleteProductionBatch(currentTenant.id, batchId);
-
- // Remove from local state
- setBatches(prev => prev.filter(batch => batch.id !== batchId));
-
- if (selectedBatch?.id === batchId) {
- setSelectedBatch(null);
- }
-
- toast.success('Production batch deleted successfully');
- return true;
- } catch (err: any) {
- const errorMessage = err.response?.data?.detail || err.message || 'Error deleting production batch';
- setError(errorMessage);
- toast.error(errorMessage);
- return false;
- } finally {
- setIsDeleting(false);
- }
- }, [currentTenant?.id, selectedBatch?.id]);
-
- // Start batch
- const startBatch = useCallback(async (batchId: string, data: any): Promise => {
- if (!currentTenant?.id || !user?.id) return null;
-
- setIsUpdating(true);
- setError(null);
-
- try {
- const startedBatch = await recipesService.startProductionBatch(currentTenant.id, user.id, batchId, data);
-
- // Update local state
- setBatches(prev => prev.map(batch =>
- batch.id === batchId ? startedBatch : batch
- ));
-
- if (selectedBatch?.id === batchId) {
- setSelectedBatch(startedBatch);
- }
-
- toast.success('Production batch started successfully');
- return startedBatch;
- } catch (err: any) {
- const errorMessage = err.response?.data?.detail || err.message || 'Error starting production batch';
- setError(errorMessage);
- toast.error(errorMessage);
- return null;
- } finally {
- setIsUpdating(false);
- }
- }, [currentTenant?.id, user?.id, selectedBatch?.id]);
-
- // Complete batch
- const completeBatch = useCallback(async (batchId: string, data: any): Promise => {
- if (!currentTenant?.id || !user?.id) return null;
-
- setIsUpdating(true);
- setError(null);
-
- try {
- const completedBatch = await recipesService.completeProductionBatch(currentTenant.id, user.id, batchId, data);
-
- // Update local state
- setBatches(prev => prev.map(batch =>
- batch.id === batchId ? completedBatch : batch
- ));
-
- if (selectedBatch?.id === batchId) {
- setSelectedBatch(completedBatch);
- }
-
- toast.success('Production batch completed successfully');
- return completedBatch;
- } catch (err: any) {
- const errorMessage = err.response?.data?.detail || err.message || 'Error completing production batch';
- setError(errorMessage);
- toast.error(errorMessage);
- return null;
- } finally {
- setIsUpdating(false);
- }
- }, [currentTenant?.id, user?.id, selectedBatch?.id]);
-
- // Load statistics
- const loadStatistics = useCallback(async (startDate?: string, endDate?: string) => {
- if (!currentTenant?.id) return;
-
- try {
- const stats = await recipesService.getProductionStatistics(currentTenant.id, startDate, endDate);
- setStatistics(stats);
- } catch (err: any) {
- console.error('Error loading production statistics:', err);
- }
- }, [currentTenant?.id]);
-
- // Clear error
- const clearError = useCallback(() => {
- setError(null);
- }, []);
-
- // Refresh
- const refresh = useCallback(async () => {
- await Promise.all([
- loadBatches(),
- loadActiveBatches(),
- loadStatistics()
- ]);
- }, [loadBatches, loadActiveBatches, loadStatistics]);
-
- // Auto-load on mount
- useEffect(() => {
- if (autoLoad && currentTenant?.id) {
- refresh();
- }
- }, [autoLoad, currentTenant?.id]);
-
- return {
- // Data
- batches,
- selectedBatch,
- activeBatches,
- statistics,
-
- // State
- isLoading,
- isCreating,
- isUpdating,
- isDeleting,
- error,
-
- // Actions
- loadBatches,
- loadBatch,
- loadActiveBatches,
- createBatch,
- updateBatch,
- deleteBatch,
- startBatch,
- completeBatch,
- loadStatistics,
- clearError,
- refresh
- };
-};
\ No newline at end of file
diff --git a/fdev-ffrontend/src/api/hooks/useSales.ts b/fdev-ffrontend/src/api/hooks/useSales.ts
deleted file mode 100644
index cbfa3fa3..00000000
--- a/fdev-ffrontend/src/api/hooks/useSales.ts
+++ /dev/null
@@ -1,200 +0,0 @@
-// frontend/src/api/hooks/useSales.ts
-/**
- * Sales Data Management Hooks
- */
-
-import { useState, useCallback } from 'react';
-import { salesService } from '../services/sales.service';
-import type {
- SalesData,
- SalesValidationResult,
- SalesDataQuery,
- SalesDataImport,
- SalesImportResult,
- DashboardStats,
- ActivityItem,
-} from '../types';
-
-export const useSales = () => {
- const [salesData, setSalesData] = useState([]);
- const [dashboardStats, setDashboardStats] = useState(null);
- const [recentActivity, setRecentActivity] = useState([]);
- const [isLoading, setIsLoading] = useState(false);
- const [error, setError] = useState(null);
- const [uploadProgress, setUploadProgress] = useState(0);
-
- const uploadSalesHistory = useCallback(async (
- tenantId: string,
- file: File,
- additionalData?: Record
- ): Promise => {
- try {
- setIsLoading(true);
- setError(null);
- setUploadProgress(0);
-
- const result = await salesService.uploadSalesHistory(tenantId, file, {
- ...additionalData,
- onProgress: (progress) => {
- setUploadProgress(progress.percentage);
- },
- });
-
- return result;
- } catch (error) {
- const message = error instanceof Error ? error.message : 'Upload failed';
- setError(message);
- throw error;
- } finally {
- setIsLoading(false);
- setUploadProgress(0);
- }
- }, []);
-
- const validateSalesData = useCallback(async (
- tenantId: string,
- file: File
- ): Promise => {
- try {
- setIsLoading(true);
- setError(null);
-
- const result = await salesService.validateSalesData(tenantId, file);
- return result;
- } catch (error) {
- const message = error instanceof Error ? error.message : 'Validation failed';
- setError(message);
- throw error;
- } finally {
- setIsLoading(false);
- }
- }, []);
-
- const getSalesData = useCallback(async (
- tenantId: string,
- query?: SalesDataQuery
- ): Promise => {
- try {
- setIsLoading(true);
- setError(null);
-
- const response = await salesService.getSalesData(tenantId, query);
- setSalesData(response.data);
-
- return response.data;
- } catch (error) {
- const message = error instanceof Error ? error.message : 'Failed to get sales data';
- setError(message);
- throw error;
- } finally {
- setIsLoading(false);
- }
- }, []);
-
- const getDashboardStats = useCallback(async (tenantId: string): Promise => {
- try {
- setIsLoading(true);
- setError(null);
-
- const stats = await salesService.getDashboardStats(tenantId);
- setDashboardStats(stats);
-
- return stats;
- } catch (error) {
- const message = error instanceof Error ? error.message : 'Failed to get dashboard stats';
- setError(message);
- throw error;
- } finally {
- setIsLoading(false);
- }
- }, []);
-
- const getRecentActivity = useCallback(async (tenantId: string, limit?: number): Promise => {
- try {
- setIsLoading(true);
- setError(null);
-
- const activity = await salesService.getRecentActivity(tenantId, limit);
- setRecentActivity(activity);
-
- return activity;
- } catch (error) {
- const message = error instanceof Error ? error.message : 'Failed to get recent activity';
- setError(message);
- throw error;
- } finally {
- setIsLoading(false);
- }
- }, []);
-
- const exportSalesData = useCallback(async (
- tenantId: string,
- format: 'csv' | 'excel' | 'json',
- query?: SalesDataQuery
- ): Promise => {
- try {
- setIsLoading(true);
- setError(null);
-
- const blob = await salesService.exportSalesData(tenantId, format, query);
-
- // Create download link
- const url = window.URL.createObjectURL(blob);
- const link = document.createElement('a');
- link.href = url;
- link.download = `sales-data.${format}`;
- document.body.appendChild(link);
- link.click();
- document.body.removeChild(link);
- window.URL.revokeObjectURL(url);
- } catch (error) {
- const message = error instanceof Error ? error.message : 'Export failed';
- setError(message);
- throw error;
- } finally {
- setIsLoading(false);
- }
- }, []);
-
-
- /**
- * Get Sales Analytics
- */
- const getSalesAnalytics = useCallback(async (
- tenantId: string,
- startDate?: string,
- endDate?: string
- ) => {
- try {
- setIsLoading(true);
- setError(null);
-
- const analytics = await salesService.getSalesAnalytics(tenantId, startDate, endDate);
-
- return analytics;
- } catch (error) {
- const message = error instanceof Error ? error.message : 'Failed to get sales analytics';
- setError(message);
- throw error;
- } finally {
- setIsLoading(false);
- }
- }, []);
-
- return {
- salesData,
- dashboardStats,
- recentActivity,
- isLoading,
- error,
- uploadProgress,
- uploadSalesHistory,
- validateSalesData,
- getSalesData,
- getDashboardStats,
- getRecentActivity,
- exportSalesData,
- getSalesAnalytics,
- clearError: () => setError(null),
- };
-};
\ No newline at end of file
diff --git a/fdev-ffrontend/src/api/hooks/useSuppliers.ts b/fdev-ffrontend/src/api/hooks/useSuppliers.ts
deleted file mode 100644
index 0d3cdefe..00000000
--- a/fdev-ffrontend/src/api/hooks/useSuppliers.ts
+++ /dev/null
@@ -1,101 +0,0 @@
-// Simplified useSuppliers hook for TypeScript compatibility
-import { useState } from 'react';
-import {
- SupplierSummary,
- CreateSupplierRequest,
- UpdateSupplierRequest,
- SupplierSearchParams,
- SupplierStatistics,
- PurchaseOrder,
- CreatePurchaseOrderRequest,
- PurchaseOrderSearchParams,
- PurchaseOrderStatistics,
- Delivery,
- DeliverySearchParams,
- DeliveryPerformanceStats
-} from '../services/suppliers.service';
-
-export const useSuppliers = () => {
- const [isLoading, setIsLoading] = useState(false);
- const [error, setError] = useState(null);
-
- // Simple stub implementations
- const getSuppliers = async (params?: SupplierSearchParams) => {
- setIsLoading(true);
- try {
- // Mock data for now
- return [];
- } catch (err) {
- setError(err instanceof Error ? err.message : 'Unknown error');
- throw err;
- } finally {
- setIsLoading(false);
- }
- };
-
- const createSupplier = async (data: CreateSupplierRequest) => {
- setIsLoading(true);
- try {
- // Mock implementation
- return { id: '1', ...data } as any;
- } catch (err) {
- setError(err instanceof Error ? err.message : 'Unknown error');
- throw err;
- } finally {
- setIsLoading(false);
- }
- };
-
- const updateSupplier = async (id: string, data: UpdateSupplierRequest) => {
- setIsLoading(true);
- try {
- // Mock implementation
- return { id, ...data } as any;
- } catch (err) {
- setError(err instanceof Error ? err.message : 'Unknown error');
- throw err;
- } finally {
- setIsLoading(false);
- }
- };
-
- // Return all the expected properties/methods
- return {
- suppliers: [],
- isLoading,
- error,
- getSuppliers,
- createSupplier,
- updateSupplier,
- deleteSupplier: async () => {},
- getSupplierStatistics: async () => ({} as SupplierStatistics),
- getActiveSuppliers: async () => [] as SupplierSummary[],
- getTopSuppliers: async () => [] as SupplierSummary[],
- getSuppliersNeedingReview: async () => [] as SupplierSummary[],
- approveSupplier: async () => {},
- // Purchase orders
- getPurchaseOrders: async () => [] as PurchaseOrder[],
- createPurchaseOrder: async () => ({} as PurchaseOrder),
- updatePurchaseOrderStatus: async () => ({} as PurchaseOrder),
- // Deliveries
- getDeliveries: async () => [] as Delivery[],
- getTodaysDeliveries: async () => [] as Delivery[],
- getDeliveryPerformanceStats: async () => ({} as DeliveryPerformanceStats),
- };
-};
-
-// Re-export types
-export type {
- SupplierSummary,
- CreateSupplierRequest,
- UpdateSupplierRequest,
- SupplierSearchParams,
- SupplierStatistics,
- PurchaseOrder,
- CreatePurchaseOrderRequest,
- PurchaseOrderSearchParams,
- PurchaseOrderStatistics,
- Delivery,
- DeliverySearchParams,
- DeliveryPerformanceStats
-};
\ No newline at end of file
diff --git a/fdev-ffrontend/src/api/hooks/useTenant.ts b/fdev-ffrontend/src/api/hooks/useTenant.ts
deleted file mode 100644
index 4cbc87ca..00000000
--- a/fdev-ffrontend/src/api/hooks/useTenant.ts
+++ /dev/null
@@ -1,209 +0,0 @@
-// frontend/src/api/hooks/useTenant.ts
-/**
- * Tenant Management Hooks
- */
-
-import { useState, useCallback } from 'react';
-import { tenantService } from '../services';
-import type {
- TenantInfo,
- TenantCreate,
- TenantUpdate,
- TenantMember,
- InviteUser,
- TenantStats,
-} from '../types';
-
-export const useTenant = () => {
- const [tenants, setTenants] = useState([]);
- const [currentTenant, setCurrentTenant] = useState(null);
- const [members, setMembers] = useState([]);
- const [stats, setStats] = useState(null);
- const [isLoading, setIsLoading] = useState(false);
- const [error, setError] = useState(null);
-
- const createTenant = useCallback(async (data: TenantCreate): Promise => {
- try {
- setIsLoading(true);
- setError(null);
-
- const tenant = await tenantService.createTenant(data);
- setTenants(prev => [...prev, tenant]);
- setCurrentTenant(tenant);
-
- return tenant;
- } catch (error) {
- const message = error instanceof Error ? error.message : 'Failed to create tenant';
- setError(message);
- throw error;
- } finally {
- setIsLoading(false);
- }
- }, []);
-
- const getTenant = useCallback(async (tenantId: string): Promise => {
- try {
- setIsLoading(true);
- setError(null);
-
- const tenant = await tenantService.getTenant(tenantId);
- setCurrentTenant(tenant);
-
- return tenant;
- } catch (error) {
- const message = error instanceof Error ? error.message : 'Failed to get tenant';
- setError(message);
- throw error;
- } finally {
- setIsLoading(false);
- }
- }, []);
-
- const updateTenant = useCallback(async (tenantId: string, data: TenantUpdate): Promise => {
- try {
- setIsLoading(true);
- setError(null);
-
- const updatedTenant = await tenantService.updateTenant(tenantId, data);
- setCurrentTenant(updatedTenant);
- setTenants(prev => prev.map(t => t.id === tenantId ? updatedTenant : t));
-
- return updatedTenant;
- } catch (error) {
- const message = error instanceof Error ? error.message : 'Failed to update tenant';
- setError(message);
- throw error;
- } finally {
- setIsLoading(false);
- }
- }, []);
-
- const getUserTenants = useCallback(async (): Promise => {
- try {
- setIsLoading(true);
- setError(null);
-
- const userTenants = await tenantService.getUserTenants();
- setTenants(userTenants);
-
- return userTenants;
- } catch (error) {
- const message = error instanceof Error ? error.message : 'Failed to get user tenants';
- setError(message);
- throw error;
- } finally {
- setIsLoading(false);
- }
- }, []);
-
- const getTenantMembers = useCallback(async (tenantId: string): Promise => {
- try {
- setIsLoading(true);
- setError(null);
-
- const response = await tenantService.getTenantMembers(tenantId);
- setMembers(response.data);
-
- return response.data;
- } catch (error) {
- const message = error instanceof Error ? error.message : 'Failed to get tenant members';
- setError(message);
- throw error;
- } finally {
- setIsLoading(false);
- }
- }, []);
-
- const inviteUser = useCallback(async (tenantId: string, invitation: InviteUser): Promise => {
- try {
- setIsLoading(true);
- setError(null);
-
- await tenantService.inviteUser(tenantId, invitation);
-
- // Refresh members list
- await getTenantMembers(tenantId);
- } catch (error) {
- const message = error instanceof Error ? error.message : 'Failed to invite user';
- setError(message);
- throw error;
- } finally {
- setIsLoading(false);
- }
- }, [getTenantMembers]);
-
- const removeMember = useCallback(async (tenantId: string, userId: string): Promise => {
- try {
- setIsLoading(true);
- setError(null);
-
- await tenantService.removeMember(tenantId, userId);
- setMembers(prev => prev.filter(m => m.user_id !== userId));
- } catch (error) {
- const message = error instanceof Error ? error.message : 'Failed to remove member';
- setError(message);
- throw error;
- } finally {
- setIsLoading(false);
- }
- }, []);
-
- const updateMemberRole = useCallback(async (tenantId: string, userId: string, role: string): Promise => {
- try {
- setIsLoading(true);
- setError(null);
-
- const updatedMember = await tenantService.updateMemberRole(tenantId, userId, role);
- setMembers(prev => prev.map(m => m.user_id === userId ? updatedMember : m));
- } catch (error) {
- const message = error instanceof Error ? error.message : 'Failed to update member role';
- setError(message);
- throw error;
- } finally {
- setIsLoading(false);
- }
- }, []);
-
- const getTenantStats = useCallback(async (tenantId: string): Promise => {
- try {
- setIsLoading(true);
- setError(null);
-
- const tenantStats = await tenantService.getTenantStats(tenantId);
- setStats(tenantStats);
-
- return tenantStats;
- } catch (error) {
- const message = error instanceof Error ? error.message : 'Failed to get tenant stats';
- setError(message);
- throw error;
- } finally {
- setIsLoading(false);
- }
- }, []);
-
- return {
- tenants,
- currentTenant,
- members,
- stats,
- isLoading,
- error,
- createTenant,
- getTenant,
- updateTenant,
- getUserTenants,
- getTenantMembers,
- inviteUser,
- removeMember,
- updateMemberRole,
- getTenantStats,
- clearError: () => setError(null),
- };
-};
-
-// Hook to get current tenant ID from context or state
-export const useTenantId = () => {
- const { currentTenant } = useTenant();
- return currentTenant?.id || null;
-};
diff --git a/fdev-ffrontend/src/api/hooks/useTraining.ts b/fdev-ffrontend/src/api/hooks/useTraining.ts
deleted file mode 100644
index 49efbd33..00000000
--- a/fdev-ffrontend/src/api/hooks/useTraining.ts
+++ /dev/null
@@ -1,265 +0,0 @@
-// frontend/src/api/hooks/useTraining.ts
-/**
- * Training Operations Hooks
- */
-
-import { useState, useCallback, useEffect } from 'react';
-import { trainingService } from '../services';
-import type {
- TrainingJobRequest,
- TrainingJobResponse,
- ModelInfo,
- ModelTrainingStats,
- SingleProductTrainingRequest,
-} from '../types';
-
-interface UseTrainingOptions {
- disablePolling?: boolean; // New option to disable HTTP status polling
-}
-
-export const useTraining = (options: UseTrainingOptions = {}) => {
-
- const { disablePolling = false } = options;
-
- // Debug logging for option changes
- console.log('🔧 useTraining initialized with options:', { disablePolling, options });
- const [jobs, setJobs] = useState([]);
- const [currentJob, setCurrentJob] = useState(null);
- const [models, setModels] = useState([]);
- const [stats, setStats] = useState(null);
- const [isLoading, setIsLoading] = useState(false);
- const [error, setError] = useState(null);
-
- const startTrainingJob = useCallback(async (
- tenantId: string,
- request: TrainingJobRequest
- ): Promise => {
- try {
- setIsLoading(true);
- setError(null);
-
- const job = await trainingService.startTrainingJob(tenantId, request);
- setCurrentJob(job);
- setJobs(prev => [job, ...prev]);
-
- return job;
- } catch (error) {
- const message = error instanceof Error ? error.message : 'Failed to start training job';
- setError(message);
- throw error;
- } finally {
- setIsLoading(false);
- }
- }, []);
-
- const startSingleProductTraining = useCallback(async (
- tenantId: string,
- request: SingleProductTrainingRequest
- ): Promise => {
- try {
- setIsLoading(true);
- setError(null);
-
- const job = await trainingService.startSingleProductTraining(tenantId, request);
- setCurrentJob(job);
- setJobs(prev => [job, ...prev]);
-
- return job;
- } catch (error) {
- const message = error instanceof Error ? error.message : 'Failed to start product training';
- setError(message);
- throw error;
- } finally {
- setIsLoading(false);
- }
- }, []);
-
- const getTrainingJobStatus = useCallback(async (
- tenantId: string,
- jobId: string
- ): Promise => {
- try {
- const job = await trainingService.getTrainingJobStatus(tenantId, jobId);
-
- // Update job in state
- setJobs(prev => prev.map(j => j.job_id === jobId ? job : j));
- if (currentJob?.job_id === jobId) {
- setCurrentJob(job);
- }
-
- return job;
- } catch (error) {
- const message = error instanceof Error ? error.message : 'Failed to get job status';
- setError(message);
- throw error;
- }
- }, [currentJob]);
-
- const cancelTrainingJob = useCallback(async (
- tenantId: string,
- jobId: string
- ): Promise => {
- try {
- setIsLoading(true);
- setError(null);
-
- await trainingService.cancelTrainingJob(tenantId, jobId);
-
- // Update job status in state
- setJobs(prev => prev.map(j =>
- j.job_id === jobId ? { ...j, status: 'cancelled' } : j
- ));
- if (currentJob?.job_id === jobId) {
- setCurrentJob({ ...currentJob, status: 'cancelled' });
- }
- } catch (error) {
- const message = error instanceof Error ? error.message : 'Failed to cancel job';
- setError(message);
- throw error;
- } finally {
- setIsLoading(false);
- }
- }, [currentJob]);
-
- const getTrainingJobs = useCallback(async (tenantId: string): Promise => {
- try {
- setIsLoading(true);
- setError(null);
-
- const response = await trainingService.getTrainingJobs(tenantId);
- setJobs(response.data);
-
- return response.data;
- } catch (error) {
- const message = error instanceof Error ? error.message : 'Failed to get training jobs';
- setError(message);
- throw error;
- } finally {
- setIsLoading(false);
- }
- }, []);
-
- const getModels = useCallback(async (tenantId: string): Promise => {
- try {
- setIsLoading(true);
- setError(null);
-
- const response = await trainingService.getModels(tenantId);
- setModels(response.data);
-
- return response.data;
- } catch (error) {
- const message = error instanceof Error ? error.message : 'Failed to get models';
- setError(message);
- throw error;
- } finally {
- setIsLoading(false);
- }
- }, []);
-
- const validateTrainingData = useCallback(async (tenantId: string): Promise<{
- is_valid: boolean;
- message: string;
- details?: any;
- }> => {
- try {
- setIsLoading(true);
- setError(null);
-
- const result = await trainingService.validateTrainingData(tenantId);
- return result;
- } catch (error) {
- const message = error instanceof Error ? error.message : 'Data validation failed';
- setError(message);
- throw error;
- } finally {
- setIsLoading(false);
- }
- }, []);
-
- const getTrainingStats = useCallback(async (tenantId: string): Promise => {
- try {
- setIsLoading(true);
- setError(null);
-
- const trainingStats = await trainingService.getTrainingStats(tenantId);
- setStats(trainingStats);
-
- return trainingStats;
- } catch (error) {
- const message = error instanceof Error ? error.message : 'Failed to get training stats';
- setError(message);
- throw error;
- } finally {
- setIsLoading(false);
- }
- }, []);
-
- useEffect(() => {
- // Always check disablePolling first and log for debugging
- console.log('🔍 useTraining polling check:', {
- disablePolling,
- jobsCount: jobs.length,
- runningJobs: jobs.filter(job => job.status === 'running' || job.status === 'pending').length
- });
-
- // STRICT CHECK: Skip polling if disabled - NO EXCEPTIONS
- if (disablePolling === true) {
- console.log('🚫 HTTP status polling STRICTLY DISABLED - using WebSocket instead');
- console.log('🚫 Effect triggered but polling prevented by disablePolling flag');
- return; // Early return - no cleanup needed, no interval creation
- }
-
- const runningJobs = jobs.filter(job => job.status === 'running' || job.status === 'pending');
-
- if (runningJobs.length === 0) {
- console.log('⏸️ No running jobs - skipping polling setup');
- return;
- }
-
- console.log('🔄 Starting HTTP status polling for', runningJobs.length, 'jobs');
-
- const interval = setInterval(async () => {
- // Double-check disablePolling inside interval to prevent race conditions
- if (disablePolling) {
- console.log('🚫 Polling disabled during interval - clearing');
- clearInterval(interval);
- return;
- }
-
- for (const job of runningJobs) {
- try {
- const tenantId = job.tenant_id;
- console.log('📡 HTTP polling job status:', job.job_id);
- await getTrainingJobStatus(tenantId, job.job_id);
- } catch (error) {
- console.error('Failed to refresh job status:', error);
- }
- }
- }, 5000); // Refresh every 5 seconds
-
- return () => {
- console.log('🛑 Stopping HTTP status polling (cleanup)');
- clearInterval(interval);
- };
- }, [jobs, getTrainingJobStatus, disablePolling]);
-
-
- return {
- jobs,
- currentJob,
- models,
- stats,
- isLoading,
- error,
- startTrainingJob,
- startSingleProductTraining,
- getTrainingJobStatus,
- cancelTrainingJob,
- getTrainingJobs,
- getModels,
- validateTrainingData,
- getTrainingStats,
- clearError: () => setError(null),
- };
-};
diff --git a/fdev-ffrontend/src/api/index.ts b/fdev-ffrontend/src/api/index.ts
deleted file mode 100644
index 701c823f..00000000
--- a/fdev-ffrontend/src/api/index.ts
+++ /dev/null
@@ -1,64 +0,0 @@
-// frontend/src/api/index.ts
-/**
- * Main API Export
- * Central entry point for all API functionality
- */
-
-// Export main API client first
-export { apiClient } from './client';
-
-// Export all services
-export {
- authService,
- tenantService,
- salesService,
- externalService,
- trainingService,
- forecastingService,
- notificationService,
- inventoryService,
- api
-} from './services';
-
-// Export all hooks
-export {
- useAuth,
- useAuthHeaders,
- useTenant,
- useSales,
- useExternal,
- useTraining,
- useForecast,
- useNotification,
- useApiHooks,
- useOnboarding,
- useInventory,
- useInventoryProducts
-} from './hooks';
-
-// Export WebSocket functionality
-export {
- WebSocketManager,
- useWebSocket,
- useTrainingWebSocket,
- useForecastWebSocket,
-} from './websocket';
-
-// Export WebSocket types
-export type {
- WebSocketConfig,
- WebSocketMessage,
- WebSocketHandlers,
- WebSocketStatus,
- WebSocketMetrics,
-} from './websocket';
-
-// Export types
-export * from './types';
-
-// Export configuration
-export { apiConfig, serviceEndpoints, featureFlags } from './client/config';
-
-// Setup interceptors on import (move to end to avoid circular deps)
-import { setupInterceptors } from './client/interceptors';
-setupInterceptors();
\ No newline at end of file
diff --git a/fdev-ffrontend/src/api/services/auth.service.ts b/fdev-ffrontend/src/api/services/auth.service.ts
deleted file mode 100644
index dd2a8c2d..00000000
--- a/fdev-ffrontend/src/api/services/auth.service.ts
+++ /dev/null
@@ -1,107 +0,0 @@
-// frontend/src/api/services/auth.service.ts
-/**
- * Authentication Service
- * Handles all authentication-related API calls
- */
-
-import { apiClient } from '../client';
-import { serviceEndpoints } from '../client/config';
-import type {
- LoginRequest,
- LoginResponse,
- RegisterRequest,
- UserResponse,
- PasswordResetRequest,
- PasswordResetResponse,
- PasswordResetConfirmRequest,
- TokenVerification,
- LogoutResponse,
-} from '../types';
-
-export class AuthService {
- private baseEndpoint = serviceEndpoints.auth;
-
- /**
- * User Registration
- */
- async register(data: RegisterRequest): Promise {
- return apiClient.post(`${this.baseEndpoint}/register`, data);
- }
-
- /**
- * User Login
- */
- async login(credentials: LoginRequest): Promise {
- return apiClient.post(`${this.baseEndpoint}/login`, credentials);
- }
-
- /**
- * User Logout
- */
- async logout(): Promise {
- return apiClient.post(`${this.baseEndpoint}/logout`);
- }
-
- /**
- * Get Current User Profile
- */
- async getCurrentUser(): Promise {
- return apiClient.get(`/users/me`);
- }
-
- /**
- * Update User Profile
- */
- async updateProfile(data: Partial): Promise {
- return apiClient.put(`/users/me`, data);
- }
-
- /**
- * Verify Token
- */
- async verifyToken(token: string): Promise {
- return apiClient.post(`${this.baseEndpoint}/verify-token`, { token });
- }
-
- /**
- * Refresh Access Token
- */
- async refreshToken(refreshToken: string): Promise {
- return apiClient.post(`${this.baseEndpoint}/refresh`, {
- refresh_token: refreshToken,
- });
- }
-
- /**
- * Request Password Reset
- */
- async requestPasswordReset(data: PasswordResetRequest): Promise {
- return apiClient.post(`${this.baseEndpoint}/password-reset`, data);
- }
-
- /**
- * Confirm Password Reset
- */
- async confirmPasswordReset(data: PasswordResetConfirmRequest): Promise<{ message: string }> {
- return apiClient.post(`${this.baseEndpoint}/password-reset/confirm`, data);
- }
-
- /**
- * Change Password (for authenticated users)
- */
- async changePassword(currentPassword: string, newPassword: string): Promise<{ message: string }> {
- return apiClient.post(`/users/me/change-password`, {
- current_password: currentPassword,
- new_password: newPassword,
- });
- }
-
- /**
- * Delete User Account
- */
- async deleteAccount(): Promise<{ message: string }> {
- return apiClient.delete(`/users/me`);
- }
-}
-
-export const authService = new AuthService();
\ No newline at end of file
diff --git a/fdev-ffrontend/src/api/services/external.service.ts b/fdev-ffrontend/src/api/services/external.service.ts
deleted file mode 100644
index c6756d9a..00000000
--- a/fdev-ffrontend/src/api/services/external.service.ts
+++ /dev/null
@@ -1,296 +0,0 @@
-// frontend/src/api/services/external.service.ts
-/**
- * External Data Service
- * Handles weather and traffic data operations for the external microservice
- */
-
-import { apiClient } from '../client';
-import { RequestTimeouts } from '../client/config';
-
-// Align with backend WeatherDataResponse schema
-export interface WeatherData {
- date: string;
- temperature?: number;
- precipitation?: number;
- humidity?: number;
- wind_speed?: number;
- pressure?: number;
- description?: string;
- source: string;
-}
-
-// Align with backend TrafficDataResponse schema
-export interface TrafficData {
- date: string;
- traffic_volume?: number;
- pedestrian_count?: number;
- congestion_level?: string;
- average_speed?: number;
- source: string;
-}
-
-export interface WeatherForecast {
- date: string;
- temperature_min: number;
- temperature_max: number;
- temperature_avg: number;
- precipitation: number;
- description: string;
- humidity?: number;
- wind_speed?: number;
-}
-
-export interface HourlyForecast {
- forecast_datetime: string;
- generated_at: string;
- temperature: number;
- precipitation: number;
- humidity: number;
- wind_speed: number;
- description: string;
- source: string;
- hour: number;
-}
-
-export class ExternalService {
- /**
- * Get Current Weather Data
- */
- async getCurrentWeather(
- tenantId: string,
- lat: number,
- lon: number
- ): Promise {
- try {
- // ✅ FIX 1: Correct endpoint path with tenant ID
- const endpoint = `/tenants/${tenantId}/weather/current`;
-
- // ✅ FIX 2: Correct parameter names (latitude/longitude, not lat/lon)
- const response = await apiClient.get(endpoint, {
- params: {
- latitude: lat, // Backend expects 'latitude'
- longitude: lon // Backend expects 'longitude'
- }
- });
-
- console.log('Weather API response:', response);
-
- // Return backend response directly (matches WeatherData interface)
- return response;
-
- } catch (error) {
- console.error('Failed to fetch weather from AEMET API via backend:', error);
- throw new Error(`Weather data unavailable: ${error instanceof Error ? error.message : 'AEMET API connection failed'}`);
- }
- }
-
- /**
- * Get Weather Forecast
- */
- async getWeatherForecast(
- tenantId: string,
- lat: number,
- lon: number,
- days: number = 7
- ): Promise {
- try {
- // Fix: Use POST with JSON body as expected by backend
- const response = await apiClient.post(`/tenants/${tenantId}/weather/forecast`, {
- latitude: lat,
- longitude: lon,
- days: days
- });
-
- // Handle response format
- if (Array.isArray(response)) {
- return response;
- } else if (response && response.forecasts) {
- return response.forecasts;
- } else {
- console.warn('Unexpected weather forecast response format:', response);
- return [];
- }
- } catch (error) {
- console.error('Failed to fetch weather forecast from AEMET API:', error);
- throw new Error(`Weather forecast unavailable: ${error instanceof Error ? error.message : 'AEMET API connection failed'}`);
- }
- }
-
- /**
- * Get Hourly Weather Forecast (NEW)
- */
- async getHourlyWeatherForecast(
- tenantId: string,
- lat: number,
- lon: number,
- hours: number = 48
- ): Promise {
- try {
- console.log(`🕒 Fetching hourly weather forecast from AEMET API for tenant ${tenantId}`, {
- latitude: lat,
- longitude: lon,
- hours: hours
- });
-
- const response = await apiClient.post(`/tenants/${tenantId}/weather/hourly-forecast`, {
- latitude: lat,
- longitude: lon,
- hours: hours
- });
-
- // Handle response format
- if (Array.isArray(response)) {
- return response;
- } else if (response && response.data) {
- return response.data;
- } else {
- console.warn('Unexpected hourly forecast response format:', response);
- return [];
- }
- } catch (error) {
- console.error('Failed to fetch hourly forecast from AEMET API:', error);
- throw new Error(`Hourly forecast unavailable: ${error instanceof Error ? error.message : 'AEMET API connection failed'}`);
- }
- }
-
- /**
- * Get Historical Weather Data
- */
- async getHistoricalWeather(
- tenantId: string,
- lat: number,
- lon: number,
- startDate: string,
- endDate: string
- ): Promise {
- try {
- // Fix: Use POST with JSON body as expected by backend
- const response = await apiClient.post(`/tenants/${tenantId}/weather/historical`, {
- latitude: lat,
- longitude: lon,
- start_date: startDate,
- end_date: endDate
- });
-
- // Return backend response directly (matches WeatherData interface)
- return Array.isArray(response) ? response : response.data || [];
- } catch (error) {
- console.error('Failed to fetch historical weather from AEMET API:', error);
- throw new Error(`Historical weather data unavailable: ${error instanceof Error ? error.message : 'AEMET API connection failed'}`);
- }
- }
-
- /**
- * Get Current Traffic Data
- */
- async getCurrentTraffic(
- tenantId: string,
- lat: number,
- lon: number
- ): Promise {
- try {
- const response = await apiClient.get(`/tenants/${tenantId}/traffic/current`, {
- params: {
- latitude: lat,
- longitude: lon
- }
- });
-
- // Return backend response directly (matches TrafficData interface)
- return response;
- } catch (error) {
- console.error('Failed to fetch traffic data from external API:', error);
- throw new Error(`Traffic data unavailable: ${error instanceof Error ? error.message : 'External API connection failed'}`);
- }
- }
-
- /**
- * Get Traffic Forecast
- */
- async getTrafficForecast(
- tenantId: string,
- lat: number,
- lon: number,
- hours: number = 24
- ): Promise {
- try {
- // Fix: Use POST with JSON body as expected by backend
- const response = await apiClient.post(`/tenants/${tenantId}/traffic/forecast`, {
- latitude: lat,
- longitude: lon,
- hours: hours
- });
-
- // Return backend response directly (matches TrafficData interface)
- return Array.isArray(response) ? response : response.data || [];
- } catch (error) {
- console.error('Failed to fetch traffic forecast from external API:', error);
- throw new Error(`Traffic forecast unavailable: ${error instanceof Error ? error.message : 'External API connection failed'}`);
- }
- }
-
- /**
- * Get Historical Traffic Data
- */
- async getHistoricalTraffic(
- tenantId: string,
- lat: number,
- lon: number,
- startDate: string,
- endDate: string
- ): Promise {
- try {
- // Fix: Use POST with JSON body as expected by backend
- const response = await apiClient.post(`/tenants/${tenantId}/traffic/historical`, {
- latitude: lat,
- longitude: lon,
- start_date: startDate,
- end_date: endDate
- });
-
- // Return backend response directly (matches TrafficData interface)
- return Array.isArray(response) ? response : response.data || [];
- } catch (error) {
- console.error('Failed to fetch historical traffic from external API:', error);
- throw new Error(`Historical traffic data unavailable: ${error instanceof Error ? error.message : 'External API connection failed'}`);
- }
- }
-
- /**
- * Test External Service Connectivity
- */
- async testConnectivity(tenantId: string): Promise<{
- weather: boolean;
- traffic: boolean;
- overall: boolean;
- }> {
- const results = {
- weather: false,
- traffic: false,
- overall: false
- };
-
- try {
- // Test weather service (AEMET API)
- await this.getCurrentWeather(tenantId, 40.4168, -3.7038); // Madrid coordinates
- results.weather = true;
- } catch (error) {
- console.warn('AEMET weather service connectivity test failed:', error);
- results.weather = false;
- }
-
- try {
- // Test traffic service
- await this.getCurrentTraffic(tenantId, 40.4168, -3.7038); // Madrid coordinates
- results.traffic = true;
- } catch (error) {
- console.warn('Traffic service connectivity test failed:', error);
- results.traffic = false;
- }
-
- results.overall = results.weather && results.traffic;
- return results;
- }
-}
-
-export const externalService = new ExternalService();
\ No newline at end of file
diff --git a/fdev-ffrontend/src/api/services/forecasting.service.ts b/fdev-ffrontend/src/api/services/forecasting.service.ts
deleted file mode 100644
index 83ef95f1..00000000
--- a/fdev-ffrontend/src/api/services/forecasting.service.ts
+++ /dev/null
@@ -1,301 +0,0 @@
-// frontend/src/api/services/forecasting.service.ts
-/**
- * Forecasting Service
- * Handles forecast operations and predictions
- */
-
-import { apiClient } from '../client';
-import { RequestTimeouts } from '../client/config';
-import type {
- SingleForecastRequest,
- BatchForecastRequest,
- ForecastResponse,
- BatchForecastResponse,
- ForecastAlert,
- QuickForecast,
- PaginatedResponse,
- BaseQueryParams,
-} from '../types';
-
-export class ForecastingService {
- /**
- * Create Single Product Forecast
- */
- async createSingleForecast(
- tenantId: string,
- request: SingleForecastRequest
- ): Promise {
- console.log('🔮 Creating single forecast:', { tenantId, request });
-
- try {
- // Backend returns single ForecastResponse object
- const response = await apiClient.post(
- `/tenants/${tenantId}/forecasts/single`,
- request,
- {
- timeout: RequestTimeouts.MEDIUM,
- }
- );
-
- console.log('🔮 Forecast API Response:', response);
- console.log('- Type:', typeof response);
- console.log('- Is Array:', Array.isArray(response));
-
- // ✅ FIX: Convert single response to array
- if (response && typeof response === 'object' && !Array.isArray(response)) {
- // Single forecast response - wrap in array
- const forecastArray = [response as ForecastResponse];
- console.log('✅ Converted single forecast to array:', forecastArray);
- return forecastArray;
- } else if (Array.isArray(response)) {
- // Already an array (unexpected but handle gracefully)
- console.log('✅ Response is already an array:', response);
- return response;
- } else {
- console.error('❌ Unexpected response format:', response);
- throw new Error('Invalid forecast response format');
- }
-
- } catch (error) {
- console.error('❌ Forecast API Error:', error);
- throw error;
- }
- }
-
- /**
- * Create Batch Forecast
- */
- async createBatchForecast(
- tenantId: string,
- request: BatchForecastRequest
- ): Promise {
- return apiClient.post(
- `/tenants/${tenantId}/forecasts/batch`,
- request,
- {
- timeout: RequestTimeouts.LONG,
- }
- );
- }
-
- /**
- * Get Forecast by ID
- */
- async getForecast(tenantId: string, forecastId: string): Promise