From a4c0892741e12c0e2bfb979aad60b1cbf918725c Mon Sep 17 00:00:00 2001 From: kaushik Date: Wed, 10 Jun 2026 18:33:17 +0530 Subject: [PATCH] Initial commit of react-revamp for Auditor Portal --- .gitignore | 24 + README.md | 73 + eslint.config.js | 22 + index.html | 13 + package-lock.json | 3984 +++++++++++++++++ package.json | 40 + public/assets/images/logo/dashboard_logo.png | Bin 0 -> 5234 bytes public/assets/images/logo/side-bar-logo.png | Bin 0 -> 69527 bytes .../master_and_shift_image_not_available.png | Bin 0 -> 5408 bytes .../images/master_image_not_available.png | Bin 0 -> 5575 bytes .../only_master_image_not_available.png | Bin 0 -> 4680 bytes public/favicon.svg | 1 + public/icons.svg | 24 + public/images/SeekRightLogo.png | Bin 0 -> 9702 bytes src/App.css | 184 + src/App.tsx | 70 + src/api/accountService.ts | 19 + src/api/activityFeedsService.ts | 35 + src/api/axiosClient.ts | 55 + src/assets/hero.png | Bin 0 -> 13057 bytes src/assets/react.svg | 1 + src/assets/vite.svg | 1 + src/components/ProtectedRoute.tsx | 24 + src/components/common/TopFilterBar.tsx | 121 + src/components/layout/Header.tsx | 128 + src/components/layout/MainLayout.tsx | 24 + src/index.css | 111 + src/main.tsx | 9 + src/pages/account/DbSelectionDialog.tsx | 59 + src/pages/account/Login.tsx | 163 + src/pages/activity-feeds/AnomalyCard.tsx | 60 + src/pages/activity-feeds/AnomalyList.tsx | 37 + src/pages/activity-feeds/AnomalyTable.tsx | 124 + src/pages/activity-feeds/FeedFilters.tsx | 324 ++ src/pages/activity-feeds/FeedTabs.tsx | 55 + src/pages/activity-feeds/GlobalFeed.tsx | 283 ++ src/pages/activity-feeds/PreviewPanel.tsx | 80 + src/pages/audit-session/AuditSession.tsx | 477 ++ src/pages/dashboard/Dashboard.tsx | 205 + src/store/authStore.ts | 50 + src/store/feedStore.ts | 138 + tsconfig.app.json | 25 + tsconfig.json | 7 + tsconfig.node.json | 24 + vite.config.ts | 21 + 45 files changed, 7095 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 eslint.config.js create mode 100644 index.html create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 public/assets/images/logo/dashboard_logo.png create mode 100644 public/assets/images/logo/side-bar-logo.png create mode 100644 public/assets/images/master_and_shift_image_not_available.png create mode 100644 public/assets/images/master_image_not_available.png create mode 100644 public/assets/images/only_master_image_not_available.png create mode 100644 public/favicon.svg create mode 100644 public/icons.svg create mode 100644 public/images/SeekRightLogo.png create mode 100644 src/App.css create mode 100644 src/App.tsx create mode 100644 src/api/accountService.ts create mode 100644 src/api/activityFeedsService.ts create mode 100644 src/api/axiosClient.ts create mode 100644 src/assets/hero.png create mode 100644 src/assets/react.svg create mode 100644 src/assets/vite.svg create mode 100644 src/components/ProtectedRoute.tsx create mode 100644 src/components/common/TopFilterBar.tsx create mode 100644 src/components/layout/Header.tsx create mode 100644 src/components/layout/MainLayout.tsx create mode 100644 src/index.css create mode 100644 src/main.tsx create mode 100644 src/pages/account/DbSelectionDialog.tsx create mode 100644 src/pages/account/Login.tsx create mode 100644 src/pages/activity-feeds/AnomalyCard.tsx create mode 100644 src/pages/activity-feeds/AnomalyList.tsx create mode 100644 src/pages/activity-feeds/AnomalyTable.tsx create mode 100644 src/pages/activity-feeds/FeedFilters.tsx create mode 100644 src/pages/activity-feeds/FeedTabs.tsx create mode 100644 src/pages/activity-feeds/GlobalFeed.tsx create mode 100644 src/pages/activity-feeds/PreviewPanel.tsx create mode 100644 src/pages/audit-session/AuditSession.tsx create mode 100644 src/pages/dashboard/Dashboard.tsx create mode 100644 src/store/authStore.ts create mode 100644 src/store/feedStore.ts create mode 100644 tsconfig.app.json create mode 100644 tsconfig.json create mode 100644 tsconfig.node.json create mode 100644 vite.config.ts diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a547bf3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/README.md b/README.md new file mode 100644 index 0000000..7dbf7eb --- /dev/null +++ b/README.md @@ -0,0 +1,73 @@ +# React + TypeScript + Vite + +This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. + +Currently, two official plugins are available: + +- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Oxc](https://oxc.rs) +- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) + +## React Compiler + +The React Compiler is not enabled on this template because of its impact on dev & build performances. To add it, see [this documentation](https://react.dev/learn/react-compiler/installation). + +## Expanding the ESLint configuration + +If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules: + +```js +export default defineConfig([ + globalIgnores(['dist']), + { + files: ['**/*.{ts,tsx}'], + extends: [ + // Other configs... + + // Remove tseslint.configs.recommended and replace with this + tseslint.configs.recommendedTypeChecked, + // Alternatively, use this for stricter rules + tseslint.configs.strictTypeChecked, + // Optionally, add this for stylistic rules + tseslint.configs.stylisticTypeChecked, + + // Other configs... + ], + languageOptions: { + parserOptions: { + project: ['./tsconfig.node.json', './tsconfig.app.json'], + tsconfigRootDir: import.meta.dirname, + }, + // other options... + }, + }, +]) +``` + +You can also install [eslint-plugin-react-x](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom) for React-specific lint rules: + +```js +// eslint.config.js +import reactX from 'eslint-plugin-react-x' +import reactDom from 'eslint-plugin-react-dom' + +export default defineConfig([ + globalIgnores(['dist']), + { + files: ['**/*.{ts,tsx}'], + extends: [ + // Other configs... + // Enable lint rules for React + reactX.configs['recommended-typescript'], + // Enable lint rules for React DOM + reactDom.configs.recommended, + ], + languageOptions: { + parserOptions: { + project: ['./tsconfig.node.json', './tsconfig.app.json'], + tsconfigRootDir: import.meta.dirname, + }, + // other options... + }, + }, +]) +``` diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 0000000..ef614d2 --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,22 @@ +import js from '@eslint/js' +import globals from 'globals' +import reactHooks from 'eslint-plugin-react-hooks' +import reactRefresh from 'eslint-plugin-react-refresh' +import tseslint from 'typescript-eslint' +import { defineConfig, globalIgnores } from 'eslint/config' + +export default defineConfig([ + globalIgnores(['dist']), + { + files: ['**/*.{ts,tsx}'], + extends: [ + js.configs.recommended, + tseslint.configs.recommended, + reactHooks.configs.flat.recommended, + reactRefresh.configs.vite, + ], + languageOptions: { + globals: globals.browser, + }, + }, +]) diff --git a/index.html b/index.html new file mode 100644 index 0000000..085e1ff --- /dev/null +++ b/index.html @@ -0,0 +1,13 @@ + + + + + + + react-revamp + + +
+ + + diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..0885e0a --- /dev/null +++ b/package-lock.json @@ -0,0 +1,3984 @@ +{ + "name": "react-revamp", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "react-revamp", + "version": "0.0.0", + "dependencies": { + "@emotion/react": "^11.14.0", + "@emotion/styled": "^11.14.1", + "@mui/icons-material": "^9.1.0", + "@mui/material": "^9.1.0", + "axios": "^1.17.0", + "react": "^19.2.6", + "react-dom": "^19.2.6", + "react-hook-form": "^7.78.0", + "react-router-dom": "^7.17.0", + "socket.io-client": "^4.8.3", + "zod": "^4.4.3", + "zustand": "^5.0.14" + }, + "devDependencies": { + "@eslint/js": "^10.0.1", + "@types/node": "^24.12.3", + "@types/react": "^19.2.14", + "@types/react-dom": "^19.2.3", + "@vitejs/plugin-react": "^6.0.1", + "eslint": "^10.3.0", + "eslint-plugin-react-hooks": "^7.1.1", + "eslint-plugin-react-refresh": "^0.5.2", + "globals": "^17.6.0", + "typescript": "~6.0.2", + "typescript-eslint": "^8.59.2", + "vite": "^8.0.12" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", + "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.29.7", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.7.tgz", + "integrity": "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz", + "integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.7", + "@babel/helper-compilation-targets": "^7.29.7", + "@babel/helper-module-transforms": "^7.29.7", + "@babel/helpers": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/template": "^7.29.7", + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.7.tgz", + "integrity": "sha512-DkXD5OJQaAQIdZ1bt3UZdEnHAn9Imd3IVBdX03UFe+ony9Ojw5pzr9YVKGDY1jt+Gcn/FnGkNf8r+Vj5NOJWtQ==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7", + "@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.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz", + "integrity": "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.29.7", + "@babel/helper-validator-option": "^7.29.7", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz", + "integrity": "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz", + "integrity": "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz", + "integrity": "sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz", + "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", + "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz", + "integrity": "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.7.tgz", + "integrity": "sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.7.tgz", + "integrity": "sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.7" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.7.tgz", + "integrity": "sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz", + "integrity": "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.7.tgz", + "integrity": "sha512-EhlfNQtZ+NK22w5BM61ciuiq1m58ed33Wr1Xan//ZRTy6hgjnwyCffRYwzsGXdASJSUJ1guZILsErh1eQcl+zw==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.7", + "@babel/helper-globals": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.7", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.7.tgz", + "integrity": "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@emnapi/core": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz", + "integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.2.1", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz", + "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", + "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emotion/babel-plugin": { + "version": "11.13.5", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.13.5.tgz", + "integrity": "sha512-pxHCpT2ex+0q+HH91/zsdHkw/lXd468DIN2zvfvLtPKLLMo6gQj7oLObq8PhkrxOZb/gGCq03S3Z7PDhS8pduQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.16.7", + "@babel/runtime": "^7.18.3", + "@emotion/hash": "^0.9.2", + "@emotion/memoize": "^0.9.0", + "@emotion/serialize": "^1.3.3", + "babel-plugin-macros": "^3.1.0", + "convert-source-map": "^1.5.0", + "escape-string-regexp": "^4.0.0", + "find-root": "^1.1.0", + "source-map": "^0.5.7", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/babel-plugin/node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "license": "MIT" + }, + "node_modules/@emotion/cache": { + "version": "11.14.0", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.14.0.tgz", + "integrity": "sha512-L/B1lc/TViYk4DcpGxtAVbx0ZyiKM5ktoIyafGkH6zg/tj+mA+NE//aPYKG0k8kCHSHVJrpLpcAlOBEXQ3SavA==", + "license": "MIT", + "dependencies": { + "@emotion/memoize": "^0.9.0", + "@emotion/sheet": "^1.4.0", + "@emotion/utils": "^1.4.2", + "@emotion/weak-memoize": "^0.4.0", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/hash": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz", + "integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==", + "license": "MIT" + }, + "node_modules/@emotion/is-prop-valid": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.4.0.tgz", + "integrity": "sha512-QgD4fyscGcbbKwJmqNvUMSE02OsHUa+lAWKdEUIJKgqe5IwRSKd7+KhibEWdaKwgjLj0DRSHA9biAIqGBk05lw==", + "license": "MIT", + "dependencies": { + "@emotion/memoize": "^0.9.0" + } + }, + "node_modules/@emotion/memoize": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz", + "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==", + "license": "MIT" + }, + "node_modules/@emotion/react": { + "version": "11.14.0", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.14.0.tgz", + "integrity": "sha512-O000MLDBDdk/EohJPFUqvnp4qnHeYkVP5B0xEG0D/L7cOKP9kefu2DXn8dj74cQfsEzUqh+sr1RzFqiL1o+PpA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.13.5", + "@emotion/cache": "^11.14.0", + "@emotion/serialize": "^1.3.3", + "@emotion/use-insertion-effect-with-fallbacks": "^1.2.0", + "@emotion/utils": "^1.4.2", + "@emotion/weak-memoize": "^0.4.0", + "hoist-non-react-statics": "^3.3.1" + }, + "peerDependencies": { + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/serialize": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.3.3.tgz", + "integrity": "sha512-EISGqt7sSNWHGI76hC7x1CksiXPahbxEOrC5RjmFRJTqLyEK9/9hZvBbiYn70dw4wuwMKiEMCUlR6ZXTSWQqxA==", + "license": "MIT", + "dependencies": { + "@emotion/hash": "^0.9.2", + "@emotion/memoize": "^0.9.0", + "@emotion/unitless": "^0.10.0", + "@emotion/utils": "^1.4.2", + "csstype": "^3.0.2" + } + }, + "node_modules/@emotion/sheet": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.4.0.tgz", + "integrity": "sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==", + "license": "MIT" + }, + "node_modules/@emotion/styled": { + "version": "11.14.1", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.14.1.tgz", + "integrity": "sha512-qEEJt42DuToa3gurlH4Qqc1kVpNq8wO8cJtDzU46TjlzWjDlsVyevtYCRijVq3SrHsROS+gVQ8Fnea108GnKzw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.13.5", + "@emotion/is-prop-valid": "^1.3.0", + "@emotion/serialize": "^1.3.3", + "@emotion/use-insertion-effect-with-fallbacks": "^1.2.0", + "@emotion/utils": "^1.4.2" + }, + "peerDependencies": { + "@emotion/react": "^11.0.0-rc.0", + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/unitless": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.10.0.tgz", + "integrity": "sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==", + "license": "MIT" + }, + "node_modules/@emotion/use-insertion-effect-with-fallbacks": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.2.0.tgz", + "integrity": "sha512-yJMtVdH59sxi/aVJBpk9FQq+OR8ll5GT8oWd57UpeaKEVGab41JWaCFA7FRLoMLloOZF/c/wsPoe+bfGmRKgDg==", + "license": "MIT", + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@emotion/utils": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.4.2.tgz", + "integrity": "sha512-3vLclRofFziIa3J2wDh9jjbkUz9qk5Vi3IZ/FSTKViB0k+ef0fPV7dYrUIugbgupYDx7v9ud/SjrtEP8Y4xLoA==", + "license": "MIT" + }, + "node_modules/@emotion/weak-memoize": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz", + "integrity": "sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==", + "license": "MIT" + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", + "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.23.5", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.23.5.tgz", + "integrity": "sha512-Y3kKLvC1dvTOT+oGlqNQ1XLqK6D1HU2YXPc52NmAlJZbMMWDzGYXMiPRJ8TYD39muD/OTjlZmNJ4ib7dvSrMBA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^3.0.5", + "debug": "^4.3.1", + "minimatch": "^10.2.4" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.6.0.tgz", + "integrity": "sha512-ii6Bw9jJ2zi2cWA2Z+9/QZ/+3DX6kwaV5Q986D/CdP3Lap3w/pgQZ373FV7byY/i7L4IRH/G43I5dz1ClsCbpA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^1.2.1" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/core": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-1.2.1.tgz", + "integrity": "sha512-MwcE1P+AZ4C6DWlpin/OmOA54mmIZ/+xZuJiQd4SyB29oAJjN30UW9wkKNptW2ctp4cEsvhlLY/CsQ1uoHDloQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/js": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-10.0.1.tgz", + "integrity": "sha512-zeR9k5pd4gxjZ0abRoIaxdc7I3nDktoXZk2qOv9gCNWx3mVwEn32VRhyLaRsDiJjTs0xq/T8mfPtyuXu7GWBcA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "eslint": "^10.0.0" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/@eslint/object-schema": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-3.0.5.tgz", + "integrity": "sha512-vqTaUEgxzm+YDSdElad6PiRoX4t8VGDjCtt05zn4nU810UIx/uNEV7/lZJ6KwFThKZOzOxzXy48da+No7HZaMw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.7.2.tgz", + "integrity": "sha512-+CNAzxglkrpNf/kKywqQfk74QjtceuOE7Qm+AF8miRvPF/wmmK5+OJOgVh3AVTT3RP2mH3+FOaxlE5v72owk0A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^1.2.1", + "levn": "^0.4.1" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.2.tgz", + "integrity": "sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/types": "^0.15.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.8", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.8.tgz", + "integrity": "sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.2", + "@humanfs/types": "^0.15.0", + "@humanwhocodes/retry": "^0.4.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/types": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/@humanfs/types/-/types-0.15.0.tgz", + "integrity": "sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@mui/core-downloads-tracker": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-9.1.0.tgz", + "integrity": "sha512-eZiO4x9hufIYiOosniu8RXituaRzUF+IRVxAID0lLwfmkjoleh88PPFmla194zZXp0yhicPjgEvmApI3tAAy2Q==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + } + }, + "node_modules/@mui/icons-material": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-9.1.0.tgz", + "integrity": "sha512-HLrgXtO1Zo1w20fjMrFQ0caCka5CIxWQjydQkd8/DZ6rY2oW+gq5svDlze1meoO03QudNuElMigk4GmAUZU1BQ==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.29.2" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@mui/material": "^9.1.0", + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/material": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-9.1.0.tgz", + "integrity": "sha512-KV3EqUb50g0Mhxiv3pCMX1KpW/M+JGD2lrQelMcjWJ4ABKKU4yotS9G10nvqPRiI9ylZUeIf36UKxTY7jeyfcw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.29.2", + "@mui/core-downloads-tracker": "^9.1.0", + "@mui/system": "^9.1.0", + "@mui/types": "^9.0.0", + "@mui/utils": "^9.1.0", + "@popperjs/core": "^2.11.8", + "@types/react-transition-group": "^4.4.12", + "clsx": "^2.1.1", + "csstype": "^3.2.3", + "prop-types": "^15.8.1", + "react-is": "^19.2.6", + "react-transition-group": "^4.4.5" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@mui/material-pigment-css": "^9.1.0", + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@mui/material-pigment-css": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/private-theming": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-9.1.0.tgz", + "integrity": "sha512-U/5n2BcqAQ6gNehYqjuyRY8pHx5/TmWk2r5kpHJ/8F+YE+QomVXGJXK/ozsIRy760LQkVxWWVFcSa+sIFquV/g==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.29.2", + "@mui/utils": "^9.1.0", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/styled-engine": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-9.1.0.tgz", + "integrity": "sha512-kRplQAga6cQ5uKwJEAh6Mx/NLxnK2Zitas5B1osv1y2MAX97OV/5BTupEBYDbAbTwo4d+t+aDa5CqeGvSpxXgw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.29.2", + "@emotion/cache": "^11.14.0", + "@emotion/serialize": "^1.3.3", + "@emotion/sheet": "^1.4.0", + "csstype": "^3.2.3", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.4.1", + "@emotion/styled": "^11.3.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + } + } + }, + "node_modules/@mui/system": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-9.1.0.tgz", + "integrity": "sha512-zZExEpvOpvE/XuhLN9fABOVngR8KInCRwcEPI7cQBccqen6nkMyZWhiKf3GQ+3WHreAVLqbGYJwUSXGPGHrcmg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.29.2", + "@mui/private-theming": "^9.1.0", + "@mui/styled-engine": "^9.1.0", + "@mui/types": "^9.0.0", + "@mui/utils": "^9.1.0", + "clsx": "^2.1.1", + "csstype": "^3.2.3", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/types": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-9.0.0.tgz", + "integrity": "sha512-i1cuFCAWN44b3AJWO7mh7tuh1sqbQSeVr/94oG0TX5uXivac8XalgE4/6fQZcmGZigzbQ35IXxj/4jLpRIBYZg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.29.2" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/utils": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-9.1.0.tgz", + "integrity": "sha512-ECZGCOdL+CtYrvfBsRx/gb0zSQjXIpAPF6Uk/0EHgGysHnedK1HBfONsOqCOsdPB59rv8S52U/8aVoNlO/c9jQ==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.29.2", + "@mui/types": "^9.0.0", + "@types/prop-types": "^15.7.15", + "clsx": "^2.1.1", + "prop-types": "^15.8.1", + "react-is": "^19.2.6" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.4.tgz", + "integrity": "sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@tybys/wasm-util": "^0.10.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "peerDependencies": { + "@emnapi/core": "^1.7.1", + "@emnapi/runtime": "^1.7.1" + } + }, + "node_modules/@oxc-project/types": { + "version": "0.133.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.133.0.tgz", + "integrity": "sha512-KzkdCd6Uxqnf6l3HOw1xfatAlUURA0g14cvBYFyJ5SaNOQbOUvBr9PKArcPcrNIeRsBdgcUzOGrhKveVpvOIGA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/Boshen" + } + }, + "node_modules/@popperjs/core": { + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, + "node_modules/@rolldown/binding-android-arm64": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.3.tgz", + "integrity": "sha512-454rs7jHngixp/NMxd5srYD57OnzSlZ/eFTETjORQHLwJG1lRtmNOJcBerZlfu4GjKqeq8aCCIQrMdHyhI51Hw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-arm64": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.3.tgz", + "integrity": "sha512-PcAhP+ynjURNyy8SKGl5DQP94aGuB/7JrXJb/t7P+hanXvQVMWzUvRRhBAcg/lNRadBhoUPqSoP4xw5tR/KBEA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-x64": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.3.tgz", + "integrity": "sha512-9YpfeUvSE2RS7wysJ81uOZkXJz7f7Q55H2Gvp3VEw/EsahqDtrphrZ0EwDLK5vvKOzaCrBsjF8JmnMLcUt78Gg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-freebsd-x64": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.3.tgz", + "integrity": "sha512-yB1IlAsSNHncV6SCTL27/MVGR5htvQsoGxIv5KMGXALp+Ll1wYsn+x98M9MW7qa+NdSbvrrY7ANI4wLJ0n1e6g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm-gnueabihf": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.3.tgz", + "integrity": "sha512-Yi30IVAAfLUCy2MseFjbB1jAMDl1VMCAas5StnYp8da9+CKvMd2H2cbEjWcw5NPaPqzvYkVIaF1nNUG+b7u/sw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-gnu": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.3.tgz", + "integrity": "sha512-jsO7R8To+AdlYgUmN5sHSCZbfhtMBkO0WUx8iORQnPcMMdgr7qM2DQmMwgabs3GhNztdmoKkMKQFHD6DTMCIQw==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-musl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.3.tgz", + "integrity": "sha512-VWkUHwWriDciit80wleYwKILoR/KMvxh/IdwS/paX+ZgpuRpCrKLUdadJbc0NpBEiyhpYawsJ73j9aCvOH+f7Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-ppc64-gnu": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.3.tgz", + "integrity": "sha512-5f1laC0SlIR0yDbFCd8acUhvJIag6N3zC5P7oUPN6wX0aOma+uKJ0wBDH5aq7I1PVI2ttTlhJwzwRIBnLiSGEg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-s390x-gnu": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.3.tgz", + "integrity": "sha512-Iq4ko0r4XsgbrF/LunNgHtAGLRRVE2kXonAXQ/MV0mC6jQpMOhW1SvtZja2EhC/kd05++bP78dsqBeIQyYJ6Yg==", + "cpu": [ + "s390x" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-gnu": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.3.tgz", + "integrity": "sha512-B8m6tD5+/N5FeNQFbKlLA/2yVq9ycQP1SeedyEYYKWBNR3ZQbkvIUcNnDNM03lO1l5F2roiiFJGgvoLLyZXtSg==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-musl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.3.tgz", + "integrity": "sha512-pSdpdUJHkuCxun9LE7jvgUB9qsRgaiyNNCX7m/AvHTcq67AiT/Yhoxvw5zPfhrM8k/BfP8ce/hMOpthKDpEUow==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-openharmony-arm64": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.3.tgz", + "integrity": "sha512-OXXS3RKJgX2uLwM+gYyuH5omcH8fL1LJs96pZGgtetVCahON57+d4SJHzTgZiOjxgGkSnpXpOsWuPDGAKAigEg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-wasm32-wasi": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.3.tgz", + "integrity": "sha512-JTtb8BWFynicNSoPrehsCzBtOKjZ6jhMiPFEmOiuXg1Fl8dn2KHQob+GuPSGR0dryQa1PQJbzjF3dqO/whhjLg==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "1.10.0", + "@emnapi/runtime": "1.10.0", + "@napi-rs/wasm-runtime": "^1.1.4" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-arm64-msvc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.3.tgz", + "integrity": "sha512-gEdFFEN70A/jxb2svrWsN3aDL7OUtmvlOy+6fa2jxG8K0wQ1ZbdeLGnidov6Yu5/733dI5ySfzFlQ/cb0bSz1g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-x64-msvc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.3.tgz", + "integrity": "sha512-eXB7CHuaQdqmJcc3koCNtNPmT/bj2gc999kUFgBxG8Ac0NdgXc4rkCHhqrgrhN3zddvvvrgzj1e90SuSfmyIXA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz", + "integrity": "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@socket.io/component-emitter": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz", + "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==", + "license": "MIT" + }, + "node_modules/@tybys/wasm-util": { + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.2.tgz", + "integrity": "sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@types/esrecurse": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@types/esrecurse/-/esrecurse-4.3.1.tgz", + "integrity": "sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", + "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.13.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.13.1.tgz", + "integrity": "sha512-RSpUJGmvsJ1ZeBehQZFhIdpsz+bIpES0nIQXko4Ybq+N+kX6XvOq3Jo+iJ82FWLdblFq85AsMikd3m35jgezYg==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~7.18.0" + } + }, + "node_modules/@types/parse-json": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", + "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==", + "license": "MIT" + }, + "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": "19.2.17", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.17.tgz", + "integrity": "sha512-MXfmqaVPEVgkBT/aY0aGCkRWWtByiYQXo3xdQ8r5RzuFrPiRn8Gar2tQdXSUQ2GKV3bkXckek89V8wQBY2Q/Aw==", + "license": "MIT", + "dependencies": { + "csstype": "^3.2.2" + } + }, + "node_modules/@types/react-dom": { + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz", + "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^19.2.0" + } + }, + "node_modules/@types/react-transition-group": { + "version": "4.4.12", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.12.tgz", + "integrity": "sha512-8TV6R3h2j7a91c+1DXdJi3Syo69zzIZbz7Lg5tORM5LEJG7X/E6a1V3drRyBRZq7/utz7A+c4OgYLiLcYGHG6w==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*" + } + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.61.0.tgz", + "integrity": "sha512-bFNvl9ZczlVb+wR2Akszf3gHfKVj/8WanXaGJ3UstTA7brNKg0cNdk6X1Psu5V7MZ2oQtzZKOEzIUehaoxbDGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.12.2", + "@typescript-eslint/scope-manager": "8.61.0", + "@typescript-eslint/type-utils": "8.61.0", + "@typescript-eslint/utils": "8.61.0", + "@typescript-eslint/visitor-keys": "8.61.0", + "ignore": "^7.0.5", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.61.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.61.0.tgz", + "integrity": "sha512-5B7PfA2e1NQGCnDHd/0lW7W3gvp3d59Ryw54FYO8Uswxo9f6ikw3AZV+Xj/TvpImmpsiYyUqAfhC6kJID1jF6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/scope-manager": "8.61.0", + "@typescript-eslint/types": "8.61.0", + "@typescript-eslint/typescript-estree": "8.61.0", + "@typescript-eslint/visitor-keys": "8.61.0", + "debug": "^4.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/project-service": { + "version": "8.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.61.0.tgz", + "integrity": "sha512-DV42F7MLJO6Rax7SK1yg43tcnEfGUrurSpSxKuVX+a3RCTzBlH3fuxprrOJXKCJGAaw82xXocikJ0uQaqwXgGA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.61.0", + "@typescript-eslint/types": "^8.61.0", + "debug": "^4.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.61.0.tgz", + "integrity": "sha512-IWdXFHFSb6mlC3HPc7QsLDm5zYEbUla6trDEHf32D3/dnuUyXd87plScSNXSbm0/RxMvObpI17sv/EDTGrGZkA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.61.0", + "@typescript-eslint/visitor-keys": "8.61.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.61.0.tgz", + "integrity": "sha512-O5Amvdv9ztMpxpf+vmFULGG78IE6Qwdr3bCGvqwG4nwc9H2qXkOYJJnRbRHyMkQTjv1d03olqwwwzHLMqpFePQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.61.0.tgz", + "integrity": "sha512-TuBiQYIkd97yBfInHCTKVYMbX4kvEmpOEuixIuzCU9p8BGT1SfyyO0d0IfDMbPIHcjn/hWnusUX5e8v5Xg+X8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.61.0", + "@typescript-eslint/typescript-estree": "8.61.0", + "@typescript-eslint/utils": "8.61.0", + "debug": "^4.4.3", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.61.0.tgz", + "integrity": "sha512-9QTQpZ5Iin4CdIodfbDQFSeiSJKidgYJYug1P9CC2xWgUTvlmixViqDZNciMjwLBZyJnG4tGmPl97rVAFb1AJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.61.0.tgz", + "integrity": "sha512-42zatd5qSvvcV1JdDBCLxYRznvP4eIHpPoZXdkPFnAmanA4FuZ5dibSnCBggY8hQnqajPpoGjXFdZ7fIJKQnlA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.61.0", + "@typescript-eslint/tsconfig-utils": "8.61.0", + "@typescript-eslint/types": "8.61.0", + "@typescript-eslint/visitor-keys": "8.61.0", + "debug": "^4.4.3", + "minimatch": "^10.2.2", + "semver": "^7.7.3", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.3.tgz", + "integrity": "sha512-wnilbGyMxzbY7dNOl7jpKbLSjcfeweJWU5j4+u5qW+6/wuGD9KzIGOyZnQVSBM9E7DtWaaH3CyHkppYrKYoxwg==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.61.0.tgz", + "integrity": "sha512-3bzFt7ImFMW/jVYwJamDoe/dMOdFLSC6pom6rRjdh4SZJEYupyMzem8e7vKZLclLfpHjlwSAXOUxtKxGXUiLqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.9.1", + "@typescript-eslint/scope-manager": "8.61.0", + "@typescript-eslint/types": "8.61.0", + "@typescript-eslint/typescript-estree": "8.61.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.61.0.tgz", + "integrity": "sha512-QVLZu3ZPQEE+HICQyAMZ2yLQhxf0meY/wx6Hx14YcTNj13JB3qHlX3lJ02L3fLGHgERRH71kvYDwiXIguT3AjQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.61.0", + "eslint-visitor-keys": "^5.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@vitejs/plugin-react": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-6.0.2.tgz", + "integrity": "sha512-DlSMqo4WhThw4vB8Mpn0Woe9J+Jfq1geJ61AKW0QEgLzGMNwtIMdxbDUzLxcun8W7NbJO0e2Jg/Nxm3cCSVzzg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rolldown/pluginutils": "^1.0.0" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "peerDependencies": { + "@rolldown/plugin-babel": "^0.1.7 || ^0.2.0", + "babel-plugin-react-compiler": "^1.0.0", + "vite": "^8.0.0" + }, + "peerDependenciesMeta": { + "@rolldown/plugin-babel": { + "optional": true + }, + "babel-plugin-react-compiler": { + "optional": true + } + } + }, + "node_modules/acorn": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", + "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/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "license": "MIT", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/ajv": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", + "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/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, + "node_modules/axios": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.17.0.tgz", + "integrity": "sha512-J8SwNxprqqpbfenehxWYXE7CW+wM1BB4w3+N+g+/Wx40xM4rsLrfPmHHxSWIxJLYDgSY/HqlFPIYb2/S3rxafw==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.16.0", + "form-data": "^4.0.5", + "https-proxy-agent": "^5.0.1", + "proxy-from-env": "^2.1.0" + } + }, + "node_modules/babel-plugin-macros": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", + "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.5", + "cosmiconfig": "^7.0.0", + "resolve": "^1.19.0" + }, + "engines": { + "node": ">=10", + "npm": ">=6" + } + }, + "node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/baseline-browser-mapping": { + "version": "2.10.34", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.34.tgz", + "integrity": "sha512-IMDedajPifLnHNY0X9n8hKxRTQ6/eTHwr5bDo04WnuqxyKw6LYtQywCuuqPZwhl3aBXMvQpJov42GLCwRRdQzw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/brace-expansion": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz", + "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/browserslist": { + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.2.tgz", + "integrity": "sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.10.12", + "caniuse-lite": "^1.0.30001782", + "electron-to-chromium": "^1.5.328", + "node-releases": "^2.0.36", + "update-browserslist-db": "^1.2.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001797", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001797.tgz", + "integrity": "sha512-l8xKG+gwAIExZGl9FrF7KUwuOmk6wbEPC9Xoy/RtnWv1XG0Q4LFlagaLpUv3Kiza3W/wm27zy0yWJEieYKAP6w==", + "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/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/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/cookie": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz", + "integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/cosmiconfig": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "license": "MIT", + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/cosmiconfig/node_modules/yaml": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.3.tgz", + "integrity": "sha512-vIYeF1u3CjlhAFekPPAk2h/Kv4T3mAkMox5OymRiJQB0spDP10LHvt+K7G9Ny6NuuMAb25/6n1qyUjAcGNf/AA==", + "license": "ISC", + "engines": { + "node": ">= 6" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "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==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.369", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.369.tgz", + "integrity": "sha512-XM22K9FNaaCOvMMrBn1caIc8v0g6+pKt660ZbfQqUZvfil0hEzr8ZoiY7VcSLGM3L/x3rz5PqZrk+bKOOmVM9w==", + "dev": true, + "license": "ISC" + }, + "node_modules/engine.io-client": { + "version": "6.6.5", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.6.5.tgz", + "integrity": "sha512-QCwxUDULPlXv8F6tqMMKx5dNkTe6OaBYRMPYeXKBlyOoKvAmE0ac6pW7fFhSscJ/5SI7666/U/B+MElbsrJlIg==", + "license": "MIT", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.4.1", + "engine.io-parser": "~5.2.1", + "ws": "~8.20.1", + "xmlhttprequest-ssl": "~2.1.1" + } + }, + "node_modules/engine.io-parser": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz", + "integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/error-ex": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", + "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz", + "integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/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==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.4.1.tgz", + "integrity": "sha512-AyIKhnOBuOAdueD7RB3xB+YeAWScb9jHsJBgH2Hcde8InP5JYhqrRR6iTMHyTEwgENK54Cp44e4v8BwNhsuHuw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.2", + "@eslint/config-array": "^0.23.5", + "@eslint/config-helpers": "^0.6.0", + "@eslint/core": "^1.2.1", + "@eslint/plugin-kit": "^0.7.2", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "ajv": "^6.14.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^9.1.2", + "eslint-visitor-keys": "^5.0.1", + "espree": "^11.2.0", + "esquery": "^1.7.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "minimatch": "^10.2.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-7.1.1.tgz", + "integrity": "sha512-f2I7Gw6JbvCexzIInuSbZpfdQ44D7iqdWX01FKLvrPgqxoE7oMj8clOfto8U6vYiz4yd5oKu39rRSVOe1zRu0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.24.4", + "@babel/parser": "^7.24.4", + "hermes-parser": "^0.25.1", + "zod": "^3.25.0 || ^4.0.0", + "zod-validation-error": "^3.5.0 || ^4.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 || ^10.0.0" + } + }, + "node_modules/eslint-plugin-react-refresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.5.2.tgz", + "integrity": "sha512-hmgTH57GfzoTFjVN0yBwTggnsVUF2tcqi7RJZHqi9lIezSs4eFyAMktA68YD4r5kNw1mxyY4dmkyoFDb3FIqrA==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "eslint": "^9 || ^10" + } + }, + "node_modules/eslint-scope": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-9.1.2.tgz", + "integrity": "sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@types/esrecurse": "^4.3.1", + "@types/estree": "^1.0.8", + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-11.2.0.tgz", + "integrity": "sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.16.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^5.0.1" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", + "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", + "license": "MIT" + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", + "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", + "dev": true, + "license": "ISC" + }, + "node_modules/follow-redirects": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.0.tgz", + "integrity": "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", + "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/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==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "17.6.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-17.6.0.tgz", + "integrity": "sha512-sepffkT8stwnIYbsMBpoCHJuJM5l98FUF2AnE07hfvE0m/qp3R586hw4jF4uadbhvg1ooIdzuu7CsfD2jzCaNA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", + "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hermes-estree": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.25.1.tgz", + "integrity": "sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw==", + "dev": true, + "license": "MIT" + }, + "node_modules/hermes-parser": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.25.1.tgz", + "integrity": "sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "hermes-estree": "0.25.1" + } + }, + "node_modules/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/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "license": "MIT", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "license": "MIT" + }, + "node_modules/is-core-module": { + "version": "2.16.2", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.2.tgz", + "integrity": "sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==", + "license": "MIT", + "dependencies": { + "hasown": "^2.0.3" + }, + "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-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/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/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "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-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lightningcss": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz", + "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.32.0", + "lightningcss-darwin-arm64": "1.32.0", + "lightningcss-darwin-x64": "1.32.0", + "lightningcss-freebsd-x64": "1.32.0", + "lightningcss-linux-arm-gnueabihf": "1.32.0", + "lightningcss-linux-arm64-gnu": "1.32.0", + "lightningcss-linux-arm64-musl": "1.32.0", + "lightningcss-linux-x64-gnu": "1.32.0", + "lightningcss-linux-x64-musl": "1.32.0", + "lightningcss-win32-arm64-msvc": "1.32.0", + "lightningcss-win32-x64-msvc": "1.32.0" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz", + "integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz", + "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz", + "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz", + "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz", + "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz", + "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz", + "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz", + "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz", + "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz", + "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz", + "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "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==", + "license": "MIT" + }, + "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/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.5" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.12", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz", + "integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==", + "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.47", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.47.tgz", + "integrity": "sha512-Uzmd6LXpouKo8EUK68IjH4+E01w/hXyV3R3g/geCJo+rXLNfh1xucB+LOzYEOQPSiUK3h/xZf0cQGcSsmyL2Og==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/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==", + "license": "MIT" + }, + "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==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.15", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.15.tgz", + "integrity": "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==", + "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.12", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/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/proxy-from-env": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz", + "integrity": "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/react": { + "version": "19.2.7", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.7.tgz", + "integrity": "sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "19.2.7", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.7.tgz", + "integrity": "sha512-t0BRVXvbiE/o20Hfw669rLbMCDWtYZLvmJigy2f0MxsXF+71pxhR3xOkspmsO8h3ZlNzyibAmtCa3l4lYKk6gQ==", + "license": "MIT", + "dependencies": { + "scheduler": "^0.27.0" + }, + "peerDependencies": { + "react": "^19.2.7" + } + }, + "node_modules/react-hook-form": { + "version": "7.78.0", + "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.78.0.tgz", + "integrity": "sha512-EEZqc+N23moyzTlz61Pj+JvcXo76ICkpfOZo8JZw+sM4+wLQGh6nI2Ms+PdMOYNluFu0ghlM7B8mCzhRYtJCnA==", + "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-is": { + "version": "19.2.7", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.7.tgz", + "integrity": "sha512-kZFnouyVv7eP/Phmrlo9FK+zcAdriZJvzxXHF1Sl1P377WSGe2G/JxVolhTrB/jeV47lKImhNUsijjHAAbcl/A==", + "license": "MIT" + }, + "node_modules/react-router": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.17.0.tgz", + "integrity": "sha512-FDELK7rTMlCHO5+reyXsPlmfr7N1F91lPHsWYfMEGQm/KQ+F4JFM8jGoeQDmDvdTs93Fw9aSilH+uKRb4/jXvQ==", + "license": "MIT", + "dependencies": { + "cookie": "^1.0.1", + "set-cookie-parser": "^2.6.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + } + } + }, + "node_modules/react-router-dom": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.17.0.tgz", + "integrity": "sha512-fyU2yjGups/hE6Xz0I5ZYbVL8Gx29eCjgpHaRaTaVU+OOAdfRX05KsvyRm0GO8YQwOkhpU3MurW1jyMUJn+zSw==", + "license": "MIT", + "dependencies": { + "react-router": "7.17.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + } + }, + "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/resolve": { + "version": "1.22.12", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.12.tgz", + "integrity": "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "is-core-module": "^2.16.1", + "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==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/rolldown": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.3.tgz", + "integrity": "sha512-i00lAJ2ks1BYr7rjNjKC7BcqAS7nVfiT3QX1SI5aY+AFHblCmaUf9OE9dbdzDvW6dJxbi2ZCZiy9v3CcwOiX3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@oxc-project/types": "=0.133.0", + "@rolldown/pluginutils": "^1.0.0" + }, + "bin": { + "rolldown": "bin/cli.mjs" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "optionalDependencies": { + "@rolldown/binding-android-arm64": "1.0.3", + "@rolldown/binding-darwin-arm64": "1.0.3", + "@rolldown/binding-darwin-x64": "1.0.3", + "@rolldown/binding-freebsd-x64": "1.0.3", + "@rolldown/binding-linux-arm-gnueabihf": "1.0.3", + "@rolldown/binding-linux-arm64-gnu": "1.0.3", + "@rolldown/binding-linux-arm64-musl": "1.0.3", + "@rolldown/binding-linux-ppc64-gnu": "1.0.3", + "@rolldown/binding-linux-s390x-gnu": "1.0.3", + "@rolldown/binding-linux-x64-gnu": "1.0.3", + "@rolldown/binding-linux-x64-musl": "1.0.3", + "@rolldown/binding-openharmony-arm64": "1.0.3", + "@rolldown/binding-wasm32-wasi": "1.0.3", + "@rolldown/binding-win32-arm64-msvc": "1.0.3", + "@rolldown/binding-win32-x64-msvc": "1.0.3" + } + }, + "node_modules/scheduler": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", + "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", + "license": "MIT" + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/set-cookie-parser": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.2.tgz", + "integrity": "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==", + "license": "MIT" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/socket.io-client": { + "version": "4.8.3", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.8.3.tgz", + "integrity": "sha512-uP0bpjWrjQmUt5DTHq9RuoCBdFJF10cdX9X+a368j/Ft0wmaVgxlrjvK3kjvgCODOMMOz9lcaRzxmso0bTWZ/g==", + "license": "MIT", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.4.1", + "engine.io-client": "~6.6.1", + "socket.io-parser": "~4.2.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/socket.io-parser": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.6.tgz", + "integrity": "sha512-asJqbVBDsBCJx0pTqw3WfesSY0iRX+2xzWEWzrpcH7L6fLzrhyF8WPI8UaeM4YCuDfpwA/cgsdugMsmtz8EJeg==", + "license": "MIT", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.4.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "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/stylis": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==", + "license": "MIT" + }, + "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==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/ts-api-utils": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz", + "integrity": "sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD", + "optional": true + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/typescript": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz", + "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/typescript-eslint": { + "version": "8.61.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.61.0.tgz", + "integrity": "sha512-8y31Rd0eGTrDKqhy6vT0HtzhN+YLjQizwX3aA3hPXP/ynSfnrBXcQY5IzsP9/DM7+klX4IUncZZjkchP0z+rUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/eslint-plugin": "8.61.0", + "@typescript-eslint/parser": "8.61.0", + "@typescript-eslint/typescript-estree": "8.61.0", + "@typescript-eslint/utils": "8.61.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/undici-types": { + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz", + "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==", + "dev": true, + "license": "MIT" + }, + "node_modules/update-browserslist-db": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/vite": { + "version": "8.0.16", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.16.tgz", + "integrity": "sha512-h9bXPmJichP5fLmVQo3PyaGSDE2n3aPuomeAlVRm0JLmt4rY6zmPKd59HYI4LNW8oTK7tlTsuC7l/m7awx9Jcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "lightningcss": "^1.32.0", + "picomatch": "^4.0.4", + "postcss": "^8.5.15", + "rolldown": "1.0.3", + "tinyglobby": "^0.2.17" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "@vitejs/devtools": "^0.1.18", + "esbuild": "^0.27.0 || ^0.28.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "@vitejs/devtools": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ws": { + "version": "8.20.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.20.1.tgz", + "integrity": "sha512-It4dO0K5v//JtTXuPkfEOaI3uUN87iYPnqo/ZzqCoG3g8uhA66QUMs/SrM0YK7/NAu+r4LMh/9dq2A7k+rHs+w==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xmlhttprequest-ssl": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.1.2.tgz", + "integrity": "sha512-TEU+nJVUUnA4CYJFLvK5X9AOeH4KvDvhIfm0vV1GaQRtchnG0hgK5p8hw/xjv8cunWYCsiPCSDzObPyhEwq3KQ==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zod": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.4.3.tgz", + "integrity": "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/zod-validation-error": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/zod-validation-error/-/zod-validation-error-4.0.2.tgz", + "integrity": "sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "zod": "^3.25.0 || ^4.0.0" + } + }, + "node_modules/zustand": { + "version": "5.0.14", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.14.tgz", + "integrity": "sha512-/8tAspM5LMPr28b3fwLYrtdj77ECpfZviaP75CMTnwO8ISyaE4GDIG/9rDDYq/cH9D2Xw2A2RXglLInmVBQB/g==", + "license": "MIT", + "engines": { + "node": ">=12.20.0" + }, + "peerDependencies": { + "@types/react": ">=18.0.0", + "immer": ">=9.0.6", + "react": ">=18.0.0", + "use-sync-external-store": ">=1.2.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "immer": { + "optional": true + }, + "react": { + "optional": true + }, + "use-sync-external-store": { + "optional": true + } + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..112b6b9 --- /dev/null +++ b/package.json @@ -0,0 +1,40 @@ +{ + "name": "react-revamp", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "tsc -b && vite build", + "lint": "eslint .", + "preview": "vite preview" + }, + "dependencies": { + "@emotion/react": "^11.14.0", + "@emotion/styled": "^11.14.1", + "@mui/icons-material": "^9.1.0", + "@mui/material": "^9.1.0", + "axios": "^1.17.0", + "react": "^19.2.6", + "react-dom": "^19.2.6", + "react-hook-form": "^7.78.0", + "react-router-dom": "^7.17.0", + "socket.io-client": "^4.8.3", + "zod": "^4.4.3", + "zustand": "^5.0.14" + }, + "devDependencies": { + "@eslint/js": "^10.0.1", + "@types/node": "^24.12.3", + "@types/react": "^19.2.14", + "@types/react-dom": "^19.2.3", + "@vitejs/plugin-react": "^6.0.1", + "eslint": "^10.3.0", + "eslint-plugin-react-hooks": "^7.1.1", + "eslint-plugin-react-refresh": "^0.5.2", + "globals": "^17.6.0", + "typescript": "~6.0.2", + "typescript-eslint": "^8.59.2", + "vite": "^8.0.12" + } +} diff --git a/public/assets/images/logo/dashboard_logo.png b/public/assets/images/logo/dashboard_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..51a7e1bf50bdbfd3842d211e31d62000d3fe5685 GIT binary patch literal 5234 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 F{{c5BPoe+- literal 0 HcmV?d00001 diff --git a/public/assets/images/master_image_not_available.png b/public/assets/images/master_image_not_available.png new file mode 100644 index 0000000000000000000000000000000000000000..b6266564cc19e642d5aec27671182c3bdead7270 GIT binary patch literal 5575 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 literal 0 HcmV?d00001 diff --git a/public/assets/images/only_master_image_not_available.png b/public/assets/images/only_master_image_not_available.png new file mode 100644 index 0000000000000000000000000000000000000000..0bae7c875616553a91b72fbdde43dbdfeb3d8f3a GIT binary patch literal 4680 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 \ No newline at end of file diff --git a/public/icons.svg b/public/icons.svg new file mode 100644 index 0000000..e952219 --- /dev/null +++ b/public/icons.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/images/SeekRightLogo.png b/public/images/SeekRightLogo.png new file mode 100644 index 0000000000000000000000000000000000000000..de78f244c6114302152f60aceabd4ff8b990caaf GIT binary patch literal 9702 zcmYj%Ra6{Z*EAYDxCMv7gS$&`cSz6#_b|A-1|8fXxVsGQFlf-=IzR{x!R?>tUEjsu z7u~)3;;h|AYVWFD(Hd&C z)~MH5w|YFU4@V|k~aJB)SU+i4^gP471C$kkbs97LtXYZneWC{py%rbNN4A4UqNXIeZ!vNd{ z5>ASZ-IG=fWpucSsIjz207%@=;SZ@lX`3S&>!pM%V#gPgrInH7#1KGGxfi_n5H#xI zPc#P8PHG2Ty!+~~m=aM5(BKt;vIt+^7j68m!RAnHRr(0~A^2#?2Ao8I{>S2dK_MiZ zFN4a-$Moc|&#*X1P!&L|@5X_#en@~>2nEgmKS*){oOwNsn{s1#h;ngl0~SfPob7R= zY6!gDXG5Kc(?b;Lr@3gGg3m^kb^<1KVJmGl(7#j~JwQ9te-!E5=@!?2J4W;@GoYz08C zOClvT6`V%b@3%%f5ksO$AX6FeXNvFL%HCAdK~e1cd{foO6-}Y5$t&J$pZu}C{}bDxtRsi=zwJlTdU~!4ZG+qe#}Nl zN-3~!2)q_qd(4~%JoHVD8%NTnd&ARf&89!>g+uOsb3D9+WsN6Tc^!Qc-+LcCQX>E` z^fVD$hg$rx+5ojBH}E+Nx4Q7KsG|@~_W?D@H}+d*S6#lYAD5mNtkOysMyG_lepkM2drN#k0&BohfOI%$)J~*M=%>~TnXj{M4>^wkB@=|96={N@f>F+If z(34i?&OZQ~teJAEGRJhvkxPN|$1E%^?=6;hlcSl0Tz>$-bF|>fjuA$}ksf|ODn-@l z^G@B$nI{HtP3Iwn-Tk2<5rJ!n=kv~N9@WeKdvA4O&OdZYKrlFQG7Vnc@VK^8ydyUF z1EEkGwWKd>@`ZFGj8KEG+I62^;cpj#Xfz~jo2ejZxk#Je>H{qpTEQ&lDR%jAB(>SA zS%|d?A0q4|)W!-AqRV8%0KZH5j!d`=l%PxxPYEo3OalmLjZL`7qTbVjp8~s1hLlkb zREV*(%6oesYih*iuDJ!>l*6Dg-&)9# z0u-FWrqYD97Tx2}%p8*Ffv88dUQK1cNLH0%d-PyHvXvD_7%i5(9x4HTcsUe42-HF% zU~G%jKNV`-{c8>wO*!vvzaKkDCz{5;sd_WEbJZyxI#r5-!ojB{SoAOc?fAoDcArCG z=R~0~^e5qr2sY&1V`|gCJjJut^Xjhe5gjNhHI@`YdK>w2J%Lr;6R_SnO%i^(~k zdtO&w&c*+MyIm)|lVbSVv}lDS6<}c3{%bQW-fE&_q}g~{Mc4AU^G?Qcr9cXf9zuA` zmb%w2+s6Z$+WemXy*hVmeO2u6DxoqAi|vC3-*9-7dfv-$1hIueFma;lObP+SR@d9? zx}6>p0atoZfpMtw?acf@6pc%X5(E%XBC^AbIf{mQZQngoZ7}dMQ*Ja5^AzVYmbr0w z`^6VPzsn7$~|=R8~107$_9R z4qmz^M|}Q(Xkborh-Pu3UNbUgv6HLqTV(7sntrN`7#spxe;v(x9aI0gKjZwkzVaf^ zL2PFmFt*T+89hBdt^a;{@A)TZ=&btxeJ!sGq(w3)+#pLj~#c^x)I-1&`OQWndW8de6mp00es5>sI4`sc^oDVmil?q%@M%l)K z#|tQ?-KRCz0jL}bpgoib-?z)AV)D{;A=~3n4wLeX1&PJKd?d_GmhS%etKDhkjaU_8 znqS4bq!V*W!QlwW5J>6FWJNVO^ zsluYqgU9+4sCag2-|h3eT)W0ZQiQE=Y)9H}Z*ShZEu3&x%u9{t60kf^B(D0d5R2=v z{PUy|bI2SjkjfzX7S75hM;}OMCB74GRZ?EAOXOqhQ(+UGTC8KS2tog%}~(J=|L44z>gzaTxQ;CltO+N zIfEN(kx>_hBlRfo9dKWT%{hq^jj=E*W$$SRieM`#*Xf~^j87xT|9X}Qy=7n((Rb>Z zaJ5B$p*-Tb_L=s(d>qsbAlE5Zc7Hs%zjO9>b9Bd91ubTnMAiO6tKGoKH3j)@=cnCi zsMOT*3gZ6?=Qq?E8&Zum(f|-w*!xUF`jK!&a8t{*Px21R@$?L36wBihlNF~&I_Lh1 zNd-BpO3miHB$B6Y--~|G_aN^GT!F`v8$2+UY%0-1(|bVocT%m8*@V zM1n*&*1_$j^;FMEa^(X>TL23xajVE3#3@jmJdKfjThZ5S)k7xVj*i+(G_w=ulhuwJ zzZ8JHRCm`ZEdRM}-SY?xFR2NUnGt@cFxd#@Vq#0Ug8w~w0Dn+L!93wjeRdo(I(C))gxXl07zM>CpkJKr>YreA{a<}LM8{83+_B5G^Rn@) z@Dq{hO(Rm#Bk2}k)cS4m%scY612tS5EO!+u5qM)Bb2Qb?l9C{BlNTlZ*C<=$BDd_C zg)PGqZP<+^hHCz)82VTY#Vy&kSb(kzUf#!LlHaDGO{Rr@mc(0#+1hPeHvGWR``r5pnTxmyk1z|xQOC~Fw#pYJ5n~-$>5zpTf8CK~ysF+j>;_w^9$c|cM}~Gl zf|T(pRcb()y<6a-&#_9(!z4$TQx5aJLB8#4axBxYHPw8A)8PsUwfCNFQMn%LItKSm zZyrxazp>@XlfVAp{?$$+B!DD8>(G6Imb3!eYG4-SOUchas41^Lj*(yMa@&i9zBAw5 zY??JgsIX-m7(<41Pmvf|(pSaYhn{(z9GhIs=ety1mc1{}Kij+;gI9V3L7A9R^|SjF z;s*!L|Ge%DuVUw~h&jiP6(17IRWj1i&sZ%sH?0U1&47-VT~?f$3xaba*Zg5Ci;htsjP+-(aIlh90&r-fCeymg zdYQE!yTHeA%4tGsUBL$RuJih{LOMt0v?vCKZh@zROe7nCYSlO>;I+-2)yp@G%ESR&V_SYWr}5%S{$iIVR~98 zdU=g70htKrtehU+u(s?K_*lQJOCyQIxA?RJ5PS~Ba1vKJXyy6KAHXn_vi0RANq2?V z=T?Rd?bmwGGT<=fgVXX7q7BMWtLtY=j79CG<>pa;l&h|@+ zYoO;;Ctl|C^~J8m)Fpxg@s2JIhzEV}{J8ZzU(Ee?VdYWyuQM6jK_)9vfl?)ZCxYbt z8M3_d=5cyO#b^d@wlCc$Kfy69{2B`JkA=H;(RI%+{G&dh3q3NYGOz^u-7}u`@^?8) z&7rQ%^;K{~@+>w)_cvc|EBY@F{8;t@HIZeoV=d+jA~1`@=o9eU6$16q<+UD9n!cMz^i!uH2kD8oLyH?9oZ1a z3gQtjr|0fV>xpe#`Mbd;2qCrHVQ4wrb#p@ao=r5eh5*{hgLyYA;C%b9 z_Hs0x|EP&Jt~pKLehCs_BGxGeqzpAVDdEv#T!~+gr>>b;Aeq0@I-zY;v0yq1mY(~0<&0TaTdI|S$nOB|blA?mKRxG=X2mk` zFOgJ%3-_XJ*Ub)8K`VH;t6G-_i@{?&%hCEE*SXrRtk9eTT}N%?+{cDS0sY-pSnA?H zwxF{RO3Xo3cAV05BvtB_6ZFdLcE)wN23O+|QY=-EXf-)B5aW0Ec;dLMB{J4W-m4Zd zFb=SI1}$8CNl!OVv+pnUj%9+7-tqK~`W{Rni#d~Lin~9ZuUqbT0Q$Xdc1!e316_{5hT#2KVbz9VB~#Q_(#Yijy~& z>!6(1oHSfiojeU=j>qgj6ZQMTv+0-+(%}7@zx>_JoJ}p}uPQ9tdRBsY{PsuY_M+)E zh4GHRxacE(*DZ4V*d)DJ;QhbaB19eQP`=r$>xk0~@pudmEx77NC_`3jpJ3 zK(6|v>sV2u>H7nbb*ORJ-S#ge0Toqrx4b12Nxb@6&G_OdMGpz~@*Y|Bv#d)Mx%ljZ zXH~|OSFuAwijF@Kjx$2CdFKF2M*oz7pS~EIwEvP#4p0Q;h}$Y9Hf=5`eIm83sUT3C zhS0U(07idD?jkEcNG7dP17Jc`eEQ~3j5F$~G!sR3)C74vlh8QyQV9HWb5+p;r9h)W z3k7RdjvVkNP7`h^WxlqW)g*&wr+qOimgF$062p<5Bi@zsDW18NXBIYp86CGKd|;Zm z=^(PY%EGONP6nY`if&I}rH5(r|H(z-^PY--E+Dp9%GaG6+8oBc|L)Gk{-dZB$*y+t zstAsjL`8a>*wSiM;sA)T%&@9i=hls6(1D9GNV79wl7VKzgI&G3)!ds`Uzpyq)DFq% zdkP?Ov_tq?(}tOxt-TxN&)RI4(^G|MFXBVpAM^VH_O5mj#!}$y9}9e~oFmOFr*hgA zn*0Kvy`Mqr1rK}`*=+8rb9@lZm=Y~51x{ zJV+|22~JrXlu;#5oE6>;ZT3`a z6>SCY+h($pYdnK;N|DK8D2}1$Sx}~|)NGaKpV(xc3ZL(5d`n|iA83R+z4&J{OkUM! z95oHX(p{Km+UbS5f5P2?jPC{s2Uwu8@0k^14MA?ase=3AP%q@KtshY#QuQ=QezhK{ z@5@&sb3N%5T=z9v@rBcfuT#Hl*n2N_<@CVIh3rsfRd`kRS9C{>vExyT@iL-aPtKTL$N6fcyp&|DmatQ$LaXftG$A78gV^q>u$1H? zrS+(|pu|uI5U}x4G+gv$osDG#K|k^bWs3-@ihOH7`j$p^JUFS4oHGj^s*S2YN|Xai zqJ=@dP~}J>L0Q*NvcF+RD(Nce;PlyNQS-R(vcV(3)xJ%4iVt0ph|h);j_FH+=}9@j z%t4+;s7y3J1yMG!)M1<)*Gy(AEkI#QZluDBLiUM-*Ha0EpGZ#Kd^N6 zxe_ug+DZj-MW_3|*TOI`edMGC%0U%7?Cn(iHR(GCEDynRSBh~IPDyMA%zj*lF`BNc zv5fCC`lz72bF_)BFHP@B4D=~mr6RPJhVTEZKGKb5>-7r7eZZMK-+4Va%C2HU8Xd*; z=Vi{q@8$5hJ?6O8wkWpwXjJ=>Am(5CP3w)bjI@#`&c;M|8 ze|cA4DDTVm#n!g)%B1ma7YRb}lE@h^)_R}9m1Sv=hxu_)VA>-tlgPiHzOl*k`JU)T zWf?&-RC=1be}Qyh1^;=5cbt>1IJohpyHoM!nW)NDy<~hsXUx&)(C`)}RKmUsp_k9- zn{3st`pzvJO@EXGzQI}e^d`8ahR+=~{eh;qK!zj+>&JPEU2 zYejzEk!QvvLxNm3RG|s!#W{{Z{$D8l@>>f?e0W?f2pu85;K{WLhT}8 zrQ8chr^9&~-+&`I{Ts#C>F@bbx!J%?%L&G_oPA>9{ao*LE{*i%9YBWUvZu@d0nrp$ za$1llM``1Ylikc`hzc6}45Rr;^G7m^S#U#jLh=m_4yei=3aN2LD?>Sl=K~EI^R;{? zyp186{Clp`l%3uqJLBMc@i0BiSEi6fcwR-)c=fH&kjn28A>0dW>pXQJ!f~l>r4WYu zCUWBh)60q|Sz;)9q__>21X>Rl*SLc}3MYNYMv(%BaYioHdR_aBn`}G2=y3V-Gg%i(EL(ZBsNpVbzD6Yu{k9VM@>2kPe+5q z^=soqsG_?d*F=`7^K?Ji{Kcl`o$+fYk#Q*ri1*kZ6B*Zs>+@ekf>6=PzR$yUn*63T zmitHTCeD7hbm;v@jYL_0){6}=K+yYVrn}bR_snDdpK@FcwI;oEnk-?Zg(cBO`1f5| zvne$bZ=q9Ff1E@<16}eqpTKge?AdR%u|~h|;k1{rYYt-IdR212Rnd?xR?|y8mjgye zE2rnBbL`2o&i9|!XAVx;$RZiE6CZnOy;Qs;=Pr4~k9GLg>lmzuu-~bs8b$m79QIGl zwWEE=@1|LKTwUaoa=8Z|dWZ zkm?o+%U<1dHzs^z-SpgsG34A#Wsav|XY-db`8>=b%C#;CaBKI0x)HXgraF2>aE9;T zs>-3I35F2>PZaHCj?-H_+8pEv5%?AHkqZRcNgdpP#U{pE4wKt_G7y=Z5yH$;mzD@+ zi_qT;6YdO>%b(DZf1iMZmC0mR&Icu-mqk;TXqUeb&K^yfuGc8?#aFMpeLYl*1DbRB z_jzEwl*hB{mVu#xlsJkMqvwJPn7ZKlEPVYv?&`;Hs-xH%|M|s2Ivdd5vZgu9kKCPb zi&nQTj3UBJn5HS1mKDLw@~E^@f50DQcvZAGBPHkk=xIUqIVp8}yG`IIZta17p_ExAY`krcO(dH!85&&an+G zd2xe}|9RF*y$t?np?bZl`P?MKey;cOU3)uSzw0GgS2#(_e`LkjKK|@K6Z8?TJyk%8;NX!eHh$e5VKurxre2!a@hcd6JIUrjbD| z!Lom|JviZNSMUPwvuop*Rfk5rr`AF1-?2@t841k6*;3ye20yM*v!t4<(TvQy=1#D* z_|U`e0j`oM_tI*;9C8gmPEr=?9q0-G(vQ`*q582)@b8Gb&Lb*c^Txw@^MjNg)P zR@yzkRq0&#$SR;XogKh1W%=~&WkC`BKSOWUGhkhi6)O|P>l!4U z|7!7=V~j@eHzUU^A*b^DM-kpSZn2fqE}_=48C7x|2rl%i6xk4tB^(@b(tln6-n3Uw zSQGCVmvpJFPmvn7LG}*S>g-s}9q8Tj4m_TVMkH2pUPv_pc;&-aLi6vl%@nIG&jh{HBqdSs79xj{RI??V& z>kI$~di*N^4%F1#hFWI>IbCcRQozS?8xxlTIrntizcH5y{V=LXQTeuC(4Zw@S2TPn zGg@9L{z#0zO~hjLBBT`#&---#X1`BG`WSTT_ zKmf2+F!Snx5Cn}7Uv8QGP};|$v7j5IF-S6jT_tt0*u|k~D^e$&{SeB(#4AM6cJxDl z9X&jSk+e^1)@0J^GQsC|#Du5?Lpph0;Rlr&W~N4v#+chL-&T0sC9E|>x&D7IeJMn^ zM+by7Eh~FYoGx?d5LnAtqF^phv+%`&*3OVTbHd6na?BBpQUE{IkshHWB52G365XeG z;P7rvk7I3;OhAQvOy!4x*qZBO=-ti*Hah`2#_Md8Na0#;{Z!-fuuA5d?xIr{J+DT}Lb$rBQFF9m|7KSjF1TIb{ z+YdH%u2EO?bkv{J)?A0QqaajF5gQ??pY+a@K}eh#428+4DIy58O_t#4tu!c(Z|82q zdWGRD0HKHg{_Bd{6fQl+Dd>;f5xR225h~20v1i8B$t6@>Pv4zvW_ZweVE)B&IgbMM zCgzN)E7r-A7*9t^je{Fv4M32hp@yjjiM+<|klRkI38;Tjnt+T5d}IEhiMG(gWpXekUhr(t|9Lh_2rOFaK2l)93zc%v zdHqX8kkf)0Pw){eK=UGy9=-V>7MYR6*@CdiG;c*~te_uS;+jiV245KWK3$2& zBNRIDpyPa31!n1`yDHcwec50#_{#iKA4v(ul2Tk`Q?w>+cYpc-Jyz(tLYVWDQDX@Z z@)XpFJE5P(L}l7%=-$W0~XC)l+7#k&ntPMq5f>XhMZLnP0EuZ8CZLIGOg?! z=AFaRm&H>7tg7k5j}wY1$OyrSIq^t$1CtTWAQYcd7E)7vqBRQ@^>0H{X@flTBGo9c zhHM?P^}TIHk3%!Rw*H)oQ0bk|XEkvR5D(qZ`58Cq>HeG+?d8er*gNeGg7?$tnI$FP zx8sNNlt&ysM|}axvCFLI#EgCz+5Ipfl+J;GOb@;apL&|a96Ik#Mi8&yEZ1$=M!}Wf z`L2mFIm1buZ@KP}8Sd`j&8=_i8y4^!z)r5UMxK1`lZ4fvFIys&#nc_dn9uAE^ZBGc zqANZC5Z)pEQ@P$Qsg5B8g=n$j`9=5H$V-COZA_(@-!f!^k~ff$^_W%m`G(f%HRabM z%bS0qJN`tUGsiO$I%<@b1Q~s1E6bTQkd?&1;7rl&@Ba(IEXXwvsRYR(;~iWvm=kgc foi~K`y`hAu4)$i1G#TX2f9YBIIbW+DF%4A2E1 literal 0 HcmV?d00001 diff --git a/src/App.css b/src/App.css new file mode 100644 index 0000000..f90339d --- /dev/null +++ b/src/App.css @@ -0,0 +1,184 @@ +.counter { + font-size: 16px; + padding: 5px 10px; + border-radius: 5px; + color: var(--accent); + background: var(--accent-bg); + border: 2px solid transparent; + transition: border-color 0.3s; + margin-bottom: 24px; + + &:hover { + border-color: var(--accent-border); + } + &:focus-visible { + outline: 2px solid var(--accent); + outline-offset: 2px; + } +} + +.hero { + position: relative; + + .base, + .framework, + .vite { + inset-inline: 0; + margin: 0 auto; + } + + .base { + width: 170px; + position: relative; + z-index: 0; + } + + .framework, + .vite { + position: absolute; + } + + .framework { + z-index: 1; + top: 34px; + height: 28px; + transform: perspective(2000px) rotateZ(300deg) rotateX(44deg) rotateY(39deg) + scale(1.4); + } + + .vite { + z-index: 0; + top: 107px; + height: 26px; + width: auto; + transform: perspective(2000px) rotateZ(300deg) rotateX(40deg) rotateY(39deg) + scale(0.8); + } +} + +#center { + display: flex; + flex-direction: column; + gap: 25px; + place-content: center; + place-items: center; + flex-grow: 1; + + @media (max-width: 1024px) { + padding: 32px 20px 24px; + gap: 18px; + } +} + +#next-steps { + display: flex; + border-top: 1px solid var(--border); + text-align: left; + + & > div { + flex: 1 1 0; + padding: 32px; + @media (max-width: 1024px) { + padding: 24px 20px; + } + } + + .icon { + margin-bottom: 16px; + width: 22px; + height: 22px; + } + + @media (max-width: 1024px) { + flex-direction: column; + text-align: center; + } +} + +#docs { + border-right: 1px solid var(--border); + + @media (max-width: 1024px) { + border-right: none; + border-bottom: 1px solid var(--border); + } +} + +#next-steps ul { + list-style: none; + padding: 0; + display: flex; + gap: 8px; + margin: 32px 0 0; + + .logo { + height: 18px; + } + + a { + color: var(--text-h); + font-size: 16px; + border-radius: 6px; + background: var(--social-bg); + display: flex; + padding: 6px 12px; + align-items: center; + gap: 8px; + text-decoration: none; + transition: box-shadow 0.3s; + + &:hover { + box-shadow: var(--shadow); + } + .button-icon { + height: 18px; + width: 18px; + } + } + + @media (max-width: 1024px) { + margin-top: 20px; + flex-wrap: wrap; + justify-content: center; + + li { + flex: 1 1 calc(50% - 8px); + } + + a { + width: 100%; + justify-content: center; + box-sizing: border-box; + } + } +} + +#spacer { + height: 88px; + border-top: 1px solid var(--border); + @media (max-width: 1024px) { + height: 48px; + } +} + +.ticks { + position: relative; + width: 100%; + + &::before, + &::after { + content: ''; + position: absolute; + top: -4.5px; + border: 5px solid transparent; + } + + &::before { + left: 0; + border-left-color: var(--border); + } + &::after { + right: 0; + border-right-color: var(--border); + } +} diff --git a/src/App.tsx b/src/App.tsx new file mode 100644 index 0000000..2b86d04 --- /dev/null +++ b/src/App.tsx @@ -0,0 +1,70 @@ +import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom'; +import { ThemeProvider, createTheme } from '@mui/material/styles'; +import { MainLayout } from './components/layout/MainLayout'; +import { ProtectedRoute } from './components/ProtectedRoute'; + +// Creating a base Material-UI theme to replace Nebular's default +const theme = createTheme({ + palette: { + mode: 'dark', + primary: { + main: '#3b82f6', // Matching dashboard blue + }, + background: { + default: '#0b1121', // Dark navy + paper: '#0f172a', // Slightly lighter navy + }, + }, + typography: { + fontFamily: '"Open Sans", sans-serif', + }, + components: { + MuiAppBar: { + styleOverrides: { + root: { + backgroundColor: '#0f172a', + color: '#f8fafc', + backgroundImage: 'none', + } + } + }, + MuiPaper: { + styleOverrides: { + root: { + backgroundImage: 'none', + } + } + } + } +}); + +import { Login } from './pages/account/Login'; +import { Dashboard } from './pages/dashboard/Dashboard'; +import { GlobalFeed } from './pages/activity-feeds/GlobalFeed'; +import { AuditSession } from './pages/audit-session/AuditSession'; + +export default function App() { + return ( + + + + {/* Public Routes */} + } /> + + {/* Protected Routes inside the Main Layout */} + }> + } /> + }> + } /> + } /> + } /> + + + + {/* Catch-all */} + } /> + + + + ); +} diff --git a/src/api/accountService.ts b/src/api/accountService.ts new file mode 100644 index 0000000..b318f10 --- /dev/null +++ b/src/api/accountService.ts @@ -0,0 +1,19 @@ +import { axiosClient } from './axiosClient'; + +export const accountService = { + login: async (username: string, password: string) => { + // Replicating the environment.origin behavior if needed, currently hardcoded + const body = { + username, + password, + origin: "AUDITOR_REMOTE", + }; + const response = await axiosClient.post('/api/dashboard/Master/login', body); + return (response as any).responseData?.[0]?.records?.[0]; // matching the Angular extraction logic + }, + + getOrganizations: async () => { + const response = await axiosClient.get('/api/audit/account/organizations'); + return response; + } +}; diff --git a/src/api/activityFeedsService.ts b/src/api/activityFeedsService.ts new file mode 100644 index 0000000..b55ac19 --- /dev/null +++ b/src/api/activityFeedsService.ts @@ -0,0 +1,35 @@ +import { axiosClient } from './axiosClient'; + +export const activityFeedsService = { + getAssets: async () => { + const response = await axiosClient.get('/api/dashboard/Master/asset_types'); + return response; + }, + + getHistoryDates: async (isRectificationEnabled: boolean) => { + // Requires dbName and siteIds, which should be handled by axios interceptors or passed in + const params = new URLSearchParams({ + isRectificationEnabled: String(isRectificationEnabled) + }); + const response = await axiosClient.get(`/api/audit/anomaly/get_history_dates?${params.toString()}`); + return response; + }, + + getHistory: async (params: any) => { + const queryParams = new URLSearchParams(params); + const response = await axiosClient.get(`/api/audit/anomaly/history?${queryParams.toString()}`); + return response; + }, + + // Mocking update anomaly + updateAuditedAnomaly: async (site_id: string, anomaly_id: string, payload: any) => { + const response = await axiosClient.put(`/api/audit/anomalies/updateAuditedAnomaly/${site_id}/${anomaly_id}`, payload); + return response; + }, + + getOrganizationSites: async (org_id: string) => { + const params = new URLSearchParams({ org_id }); + const response = await axiosClient.get(`/api/dashboard/Master/site?${params.toString()}`); + return response; + } +}; diff --git a/src/api/axiosClient.ts b/src/api/axiosClient.ts new file mode 100644 index 0000000..0f85e3d --- /dev/null +++ b/src/api/axiosClient.ts @@ -0,0 +1,55 @@ +import axios from 'axios'; +import { useAuthStore } from '../store/authStore'; + +// You can move this to an environment variable later +// Base URL is empty because we use specific proxy prefixes in the service calls +const BASE_URL = ''; + +export const axiosClient = axios.create({ + baseURL: BASE_URL, + headers: { + 'Content-Type': 'application/json', + }, +}); + +// Request Interceptor: Attach token if available +axiosClient.interceptors.request.use( + (config) => { + const user = useAuthStore.getState().user; + if (user?.access_token) { + config.headers['x-access-token'] = user.access_token; + } + if (user?.db_name) { + config.params = { ...config.params, dbName: user.db_name }; + } + return config; + }, + (error) => Promise.reject(error) +); + +// Response Interceptor: Global Error Handling (like Angular's HttpService) +axiosClient.interceptors.response.use( + (response) => response.data, + (error) => { + if (!error.response) { + // Network offline or CORS error (status 0 in Angular) + alert('Seems one of the sub-application is offline. Please restart the application again.'); + return Promise.reject(error); + } + + const { status, data } = error.response; + + if (status === 400) { + const message = data?.responseStatus?.responseMessage || data?.errorMessage || 'OOPS! Something wrong has happened. Please refresh the browser and try again.'; + alert(message); + } else if (status === 401) { + console.error('Login issue'); + useAuthStore.getState().logout(); + window.location.href = '/login'; // Redirect to login + } else { + alert('OOPS! Something wrong has happened. Please refresh the browser and try again.'); + } + + return Promise.reject(error); + } +); diff --git a/src/assets/hero.png b/src/assets/hero.png new file mode 100644 index 0000000000000000000000000000000000000000..02251f4b956c55af2d76fd0788124d7eee2b45eb GIT binary patch literal 13057 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 P00000NkvXXu0mjft=yBf literal 0 HcmV?d00001 diff --git a/src/assets/react.svg b/src/assets/react.svg new file mode 100644 index 0000000..6c87de9 --- /dev/null +++ b/src/assets/react.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/vite.svg b/src/assets/vite.svg new file mode 100644 index 0000000..5101b67 --- /dev/null +++ b/src/assets/vite.svg @@ -0,0 +1 @@ +Vite diff --git a/src/components/ProtectedRoute.tsx b/src/components/ProtectedRoute.tsx new file mode 100644 index 0000000..c581693 --- /dev/null +++ b/src/components/ProtectedRoute.tsx @@ -0,0 +1,24 @@ +import { Navigate, Outlet } from 'react-router-dom'; +import { useAuthStore } from '../store/authStore'; + +interface ProtectedRouteProps { + requiredRole?: string; +} + +export const ProtectedRoute = ({ requiredRole }: ProtectedRouteProps) => { + const { isAuthenticated, hasRole } = useAuthStore(); + + if (!isAuthenticated) { + // If user is not authenticated, redirect to login + return ; + } + + if (requiredRole && !hasRole(requiredRole)) { + // If user doesn't have the required role, redirect them or show unauthorized + // For now, redirecting to a default safe page + return ; + } + + // If authenticated and authorized, render the child routes + return ; +}; diff --git a/src/components/common/TopFilterBar.tsx b/src/components/common/TopFilterBar.tsx new file mode 100644 index 0000000..6b7f2c7 --- /dev/null +++ b/src/components/common/TopFilterBar.tsx @@ -0,0 +1,121 @@ +import React, { useState, useEffect, useRef } from 'react'; +import { Box, Button, FormControl, Select, MenuItem } from '@mui/material'; +import FilterListIcon from '@mui/icons-material/FilterList'; +import HistoryIcon from '@mui/icons-material/History'; +import { useFeedStore } from '../../store/feedStore'; +import { FeedFilters } from '../../pages/activity-feeds/FeedFilters'; + +const DEBOUNCE_MS = 600; // wait 600ms after user stops changing before committing to store + +export const TopFilterBar: React.FC = () => { + const { + sites, + selectedSite, setSelectedSite, + auditStatus, setAuditStatus, + setIsFiltersModalOpen + } = useFeedStore(); + + // Local draft values — these do NOT trigger API calls + const [localAuditStatus, setLocalAuditStatus] = useState(auditStatus || 'Auto Audits'); + const [localSiteId, setLocalSiteId] = useState(selectedSite?.site_id || 'All Sites'); + + // Sync local state when store changes externally (e.g., on initial load) + useEffect(() => { + setLocalAuditStatus(auditStatus || 'Auto Audits'); + }, [auditStatus]); + + useEffect(() => { + setLocalSiteId(selectedSite?.site_id || 'All Sites'); + }, [selectedSite?.site_id]); // eslint-disable-line react-hooks/exhaustive-deps + + // Debounced commit for auditStatus + const auditDebounce = useRef | null>(null); + const handleAuditChange = (value: string) => { + setLocalAuditStatus(value); + if (auditDebounce.current) clearTimeout(auditDebounce.current); + auditDebounce.current = setTimeout(() => { + setAuditStatus(value); // triggers API refetch only after user stops + }, DEBOUNCE_MS); + }; + + // Debounced commit for selectedSite + const siteDebounce = useRef | null>(null); + const handleSiteChange = (siteId: string) => { + setLocalSiteId(siteId); + if (siteDebounce.current) clearTimeout(siteDebounce.current); + siteDebounce.current = setTimeout(() => { + const site = siteId === 'All Sites' + ? { site_id: 'All Sites', site_name: 'All Sites' } + : sites.find(s => s.site_id === siteId); + setSelectedSite(site); // triggers API refetch only after user stops + }, DEBOUNCE_MS); + }; + + // Cleanup on unmount + useEffect(() => { + return () => { + if (auditDebounce.current) clearTimeout(auditDebounce.current); + if (siteDebounce.current) clearTimeout(siteDebounce.current); + }; + }, []); + + return ( + <> + + + + + {/* Audit Status — local state, debounced commit */} + + + + + {/* Site — local state, debounced commit */} + + + + + + + + + ); +}; diff --git a/src/components/layout/Header.tsx b/src/components/layout/Header.tsx new file mode 100644 index 0000000..8fba4ca --- /dev/null +++ b/src/components/layout/Header.tsx @@ -0,0 +1,128 @@ +import React, { useState } from 'react'; +import { AppBar, Toolbar, Typography, Box, IconButton, Menu, MenuItem, Button, Select, FormControl } from '@mui/material'; +import MenuIcon from '@mui/icons-material/Menu'; +import AccountCircle from '@mui/icons-material/AccountCircle'; +import FilterListIcon from '@mui/icons-material/FilterList'; +import HistoryIcon from '@mui/icons-material/History'; +import { useAuthStore } from '../../store/authStore'; +import { useFeedStore } from '../../store/feedStore'; +import { useNavigate, useLocation } from 'react-router-dom'; + +interface HeaderProps { + toggleSidebar?: () => void; +} + +export const Header: React.FC = ({ toggleSidebar }) => { + const { user, logout } = useAuthStore(); + const { sites, selectedSite, setSelectedSite, auditStatus, setAuditStatus, setIsFiltersModalOpen } = useFeedStore(); + const navigate = useNavigate(); + const location = useLocation(); + const [anchorEl, setAnchorEl] = useState(null); + + const orgName = user?.org_id || user?.db_name || 'TakeLeep'; // Adjust based on your User model + const showNav = !location.pathname.includes('dashboard'); + const isActivityFeeds = location.pathname.includes('activity-feeds'); + + const handleMenu = (event: React.MouseEvent) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + const handleLogout = () => { + handleClose(); + logout(); + navigate('/login', { replace: true }); + }; + + return ( + theme.zIndex.drawer + 1, boxShadow: 1 }}> + + + + {showNav && toggleSidebar && ( + + + + )} + + Dashboard Logo { e.currentTarget.style.display = 'none'; }} + /> + + + + + + + + + + + + {user && ( +
+ + + Log out + +
+ )} +
+
+
+ ); +}; diff --git a/src/components/layout/MainLayout.tsx b/src/components/layout/MainLayout.tsx new file mode 100644 index 0000000..6ce6b5a --- /dev/null +++ b/src/components/layout/MainLayout.tsx @@ -0,0 +1,24 @@ +import React from 'react'; +import { Box, Toolbar, CssBaseline } from '@mui/material'; +import { Outlet, useLocation } from 'react-router-dom'; +import { Header } from './Header'; + +export const MainLayout: React.FC = () => { + const location = useLocation(); + + return ( + + + +
+ + + {/* Spacer for Header */} + + {/* Child routes get injected here */} + + + + + ); +}; diff --git a/src/index.css b/src/index.css new file mode 100644 index 0000000..5fb3313 --- /dev/null +++ b/src/index.css @@ -0,0 +1,111 @@ +:root { + --text: #6b6375; + --text-h: #08060d; + --bg: #fff; + --border: #e5e4e7; + --code-bg: #f4f3ec; + --accent: #aa3bff; + --accent-bg: rgba(170, 59, 255, 0.1); + --accent-border: rgba(170, 59, 255, 0.5); + --social-bg: rgba(244, 243, 236, 0.5); + --shadow: + rgba(0, 0, 0, 0.1) 0 10px 15px -3px, rgba(0, 0, 0, 0.05) 0 4px 6px -2px; + + --sans: system-ui, 'Segoe UI', Roboto, sans-serif; + --heading: system-ui, 'Segoe UI', Roboto, sans-serif; + --mono: ui-monospace, Consolas, monospace; + + font: 18px/145% var(--sans); + letter-spacing: 0.18px; + color-scheme: light dark; + color: var(--text); + background: var(--bg); + font-synthesis: none; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + + @media (max-width: 1024px) { + font-size: 16px; + } +} + +@media (prefers-color-scheme: dark) { + :root { + --text: #9ca3af; + --text-h: #f3f4f6; + --bg: #16171d; + --border: #2e303a; + --code-bg: #1f2028; + --accent: #c084fc; + --accent-bg: rgba(192, 132, 252, 0.15); + --accent-border: rgba(192, 132, 252, 0.5); + --social-bg: rgba(47, 48, 58, 0.5); + --shadow: + rgba(0, 0, 0, 0.4) 0 10px 15px -3px, rgba(0, 0, 0, 0.25) 0 4px 6px -2px; + } + + #social .button-icon { + filter: invert(1) brightness(2); + } +} + +#root { + width: 1126px; + max-width: 100%; + margin: 0 auto; + text-align: center; + border-inline: 1px solid var(--border); + min-height: 100svh; + display: flex; + flex-direction: column; + box-sizing: border-box; +} + +body { + margin: 0; +} + +h1, +h2 { + font-family: var(--heading); + font-weight: 500; + color: var(--text-h); +} + +h1 { + font-size: 56px; + letter-spacing: -1.68px; + margin: 32px 0; + @media (max-width: 1024px) { + font-size: 36px; + margin: 20px 0; + } +} +h2 { + font-size: 24px; + line-height: 118%; + letter-spacing: -0.24px; + margin: 0 0 8px; + @media (max-width: 1024px) { + font-size: 20px; + } +} +p { + margin: 0; +} + +code, +.counter { + font-family: var(--mono); + display: inline-flex; + border-radius: 4px; + color: var(--text-h); +} + +code { + font-size: 15px; + line-height: 135%; + padding: 4px 8px; + background: var(--code-bg); +} diff --git a/src/main.tsx b/src/main.tsx new file mode 100644 index 0000000..4aff025 --- /dev/null +++ b/src/main.tsx @@ -0,0 +1,9 @@ +import { StrictMode } from 'react' +import { createRoot } from 'react-dom/client' +import App from './App.tsx' + +createRoot(document.getElementById('root')!).render( + + + , +) diff --git a/src/pages/account/DbSelectionDialog.tsx b/src/pages/account/DbSelectionDialog.tsx new file mode 100644 index 0000000..fc72956 --- /dev/null +++ b/src/pages/account/DbSelectionDialog.tsx @@ -0,0 +1,59 @@ +import React, { useEffect, useState } from 'react'; +import { Dialog, DialogTitle, DialogContent, List, ListItem, ListItemButton, ListItemText, CircularProgress, Box } from '@mui/material'; +import { accountService } from '../../api/accountService'; + +interface Organization { + org_name: string; + org_id: string; + db_name: string; +} + +interface DbSelectionDialogProps { + open: boolean; + onClose: (selectedOrg?: Organization) => void; +} + +export const DbSelectionDialog: React.FC = ({ open, onClose }) => { + const [organizations, setOrganizations] = useState([]); + const [loading, setLoading] = useState(false); + + useEffect(() => { + if (open) { + setLoading(true); + accountService.getOrganizations() + .then((res: any) => { + const sorted = res.sort((a: Organization, b: Organization) => + a.org_name.toLowerCase() > b.org_name.toLowerCase() ? 1 : -1 + ); + setOrganizations(sorted); + }) + .catch((err) => { + console.error(err); + }) + .finally(() => setLoading(false)); + } + }, [open]); + + return ( + onClose()} maxWidth="xs" fullWidth> + Select the organization + + {loading ? ( + + + + ) : ( + + {organizations.map((org) => ( + + onClose(org)}> + + + + ))} + + )} + + + ); +}; diff --git a/src/pages/account/Login.tsx b/src/pages/account/Login.tsx new file mode 100644 index 0000000..1ae6165 --- /dev/null +++ b/src/pages/account/Login.tsx @@ -0,0 +1,163 @@ +import React, { useState, useEffect } from 'react'; +import { Box, Button, TextField, Typography, Container, Alert } from '@mui/material'; +import { useNavigate } from 'react-router-dom'; +import { useAuthStore } from '../../store/authStore'; +import { accountService } from '../../api/accountService'; +import { DbSelectionDialog } from './DbSelectionDialog'; + +export const Login: React.FC = () => { + const [username, setUsername] = useState(''); + const [password, setPassword] = useState(''); + const [isInvalid, setIsInvalid] = useState(false); + const [loading, setLoading] = useState(false); + const [dialogOpen, setDialogOpen] = useState(false); + const [tempUserData, setTempUserData] = useState(null); + + const { login, isAuthenticated } = useAuthStore(); + const navigate = useNavigate(); + + // If already logged in, redirect + useEffect(() => { + if (isAuthenticated) { + navigate('/activity-feeds', { replace: true }); + } + }, [isAuthenticated, navigate]); + + const handleLogin = async () => { + setIsInvalid(false); + setLoading(true); + + try { + const userData = await accountService.login(username, password); + + if (!userData) { + setIsInvalid(true); + setLoading(false); + return; + } + + const roles = userData.user_roles ? userData.user_roles.toLowerCase().split(',') : []; + + if (roles.includes('sr_auditor')) { + // Open DB Selection Dialog + setTempUserData(userData); + setDialogOpen(true); + } else if (roles.includes('auditor')) { + // Direct login + login(userData); + navigate('/activity-feeds', { replace: true }); + } else if (roles.includes('video_uploader')) { + // Direct login for dashboard + login(userData); + navigate('/activity-feeds', { replace: true }); + } else { + alert("Your account is not configured to use this website. Please contact your admin for more info."); + } + } catch (error) { + setIsInvalid(true); + } finally { + setLoading(false); + } + }; + + const handleDbSelection = (selectedOrg?: any) => { + setDialogOpen(false); + if (selectedOrg && tempUserData) { + // Merge selected org details into user object + const finalUserData = { + ...tempUserData, + org_id: selectedOrg.org_id, + db_name: selectedOrg.db_name, + selected_org_name: selectedOrg.org_name + }; + login(finalUserData); + navigate('/activity-feeds', { replace: true }); + } + }; + + return ( + + + + {/* Placeholder for Logo */} + + Logo { e.currentTarget.style.display = 'none'; }} /> + + + + setUsername(e.target.value)} + onKeyDown={(e) => e.key === 'Enter' && handleLogin()} + InputProps={{ + sx: { borderRadius: '50px', '& fieldset': { borderColor: '#738ab8' } } + }} + sx={{ + mb: 1, + '& .MuiInputBase-input': { padding: '10px 14px', fontSize: '0.9rem', color: '#333' } + }} + /> + setPassword(e.target.value)} + onKeyDown={(e) => e.key === 'Enter' && handleLogin()} + InputProps={{ + sx: { borderRadius: '50px', '& fieldset': { borderColor: '#738ab8' } } + }} + sx={{ + mt: 1, + mb: 3, + '& .MuiInputBase-input': { padding: '10px 14px', fontSize: '0.9rem', color: '#333' } + }} + /> + + + + + + + + {isInvalid && ( + + Invalid Credentials + + )} + + + + {/* Database Selection Dialog for SR_AUDITOR */} + + + ); +}; diff --git a/src/pages/activity-feeds/AnomalyCard.tsx b/src/pages/activity-feeds/AnomalyCard.tsx new file mode 100644 index 0000000..bab55c2 --- /dev/null +++ b/src/pages/activity-feeds/AnomalyCard.tsx @@ -0,0 +1,60 @@ +import React from 'react'; +import { Card, CardMedia, CardContent, Typography, Box, Slider, Button } from '@mui/material'; + +interface AnomalyCardProps { + anomaly: any; +} + +export const AnomalyCard: React.FC = ({ anomaly }) => { + // Safe extraction of properties based on Angular's data structure + const assetName = anomaly?.Asset?.replace(/_/gi, ' ') || 'Unknown Asset'; + const createdOn = anomaly?.Created_on || 'Unknown Date'; + const confidence = anomaly?.Confidence || 0; + const imageSrc = anomaly?.Frame_Master || '/assets/images/placeholder.jpg'; + const isAudited = anomaly?.IsAudited; + + return ( + + {/* Image Section */} + + + {/* Details Section */} + + + + {assetName} + + + Date: {createdOn} | Chainage: {anomaly?.Chainage || 'N/A'} + + + Confidence: {confidence}% | Status: {isAudited ? 'Audited' : 'Unaudited'} + + + + {/* Sliders and Buttons (Placeholder logic for audit status) */} + + True + + False + + + + + + ); +}; diff --git a/src/pages/activity-feeds/AnomalyList.tsx b/src/pages/activity-feeds/AnomalyList.tsx new file mode 100644 index 0000000..53cb2df --- /dev/null +++ b/src/pages/activity-feeds/AnomalyList.tsx @@ -0,0 +1,37 @@ +import React from 'react'; +import { Box, Typography } from '@mui/material'; +import { useFeedStore } from '../../store/feedStore'; +import { AnomalyCard } from './AnomalyCard'; + +export const AnomalyList: React.FC = () => { + const { tabs, selectedTabIndex } = useFeedStore(); + + if (tabs.length === 0 || selectedTabIndex < 0) { + return Loading feeds...; + } + + const activeTab = tabs[selectedTabIndex]; + const anomalies = activeTab.anomalies || []; + + if (anomalies.length === 0) { + return ( + + + No anomalies found for the selected criteria. + + + ); + } + + return ( + + + Showing {anomalies.length} / {activeTab.totalAnomalyCount} anomalies + + + {anomalies.map((anomaly: any, index: number) => ( + + ))} + + ); +}; diff --git a/src/pages/activity-feeds/AnomalyTable.tsx b/src/pages/activity-feeds/AnomalyTable.tsx new file mode 100644 index 0000000..334b16b --- /dev/null +++ b/src/pages/activity-feeds/AnomalyTable.tsx @@ -0,0 +1,124 @@ +import React from 'react'; +import { Box, Typography, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Paper, Slider, Checkbox } from '@mui/material'; +import { useFeedStore } from '../../store/feedStore'; + +export const AnomalyTable: React.FC = () => { + const { tabs, selectedTabIndex, updateTab } = useFeedStore(); + + if (tabs.length === 0 || selectedTabIndex < 0) { + return Loading feeds...; + } + + const activeTab = tabs[selectedTabIndex]; + const anomalies = activeTab.anomalies || []; + + if (anomalies.length === 0) { + return ( + + + No anomalies found for the selected criteria. + + + ); + } + + const handleRowClick = (index: number) => { + updateTab(selectedTabIndex, { selectedAnomalyIndex: index }); + }; + + const getRowColor = (index: number, _asset: string) => { + // Dark mode colors for table rows + const colors = ['rgba(255, 255, 255, 0.03)', 'rgba(255, 255, 255, 0.0)']; + return colors[index % colors.length]; + }; + + return ( + + + + + #ID + PLAZA + ROAD + DATE + CHAINAGE + LAT/LONG + ANOMALY + SIDE + ANOMALY True/False + FEATURES + COMMENTS + CHECKED + AUTO AUDIT + + + + {anomalies.map((anomaly: any, index: number) => { + const isSelected = activeTab.selectedAnomalyIndex === index; + const assetName = anomaly?.Asset?.replace(/_/gi, ' ') || 'Unknown Asset'; + const rowColor = getRowColor(index, assetName); + + // Parse Position + let latStr = 'N/A'; + let longStr = 'E/A'; + if (anomaly?.Pos) { + const match = String(anomaly.Pos).match(/([NS][0-9.]+)([EW][0-9.]+)/i); + if (match) { + latStr = match[1]; + longStr = match[2]; + } else { + latStr = anomaly.Pos; // Fallback + longStr = ''; + } + } + + return ( + handleRowClick(index)} + sx={{ + bgcolor: isSelected ? 'rgba(59, 130, 246, 0.2)' : rowColor, + cursor: 'pointer', + '&:hover': { bgcolor: 'rgba(255,255,255,0.08)' }, + borderLeft: isSelected ? '4px solid #3b82f6' : '4px solid transparent', + mb: 1, + }} + > + #{anomaly.id || anomaly._id?.substring(0, 7) || 'N/A'} + {anomaly.Plaza || 'N/A'} + {anomaly.road || anomaly.Road || 'N/A'} + {anomaly.Created_on ? new Date(anomaly.Created_on).toLocaleDateString() : 'N/A'} + {anomaly.Chainage || 'N/A'} + + {latStr}
+ {longStr} +
+ {assetName} + {anomaly.Side || 'N/A'} + + + + {anomaly.Features || 'N/A'} + {anomaly.Comments || '-'} + + + + + + +
+ ); + })} +
+
+
+ ); +}; diff --git a/src/pages/activity-feeds/FeedFilters.tsx b/src/pages/activity-feeds/FeedFilters.tsx new file mode 100644 index 0000000..f77bfbf --- /dev/null +++ b/src/pages/activity-feeds/FeedFilters.tsx @@ -0,0 +1,324 @@ +import React, { useState, useMemo, useEffect, useCallback, memo } from 'react'; +import { + Box, TextField, Checkbox, FormControlLabel, Button, Typography, Dialog, + DialogContent, DialogActions, CircularProgress, Divider, InputAdornment, Chip +} from '@mui/material'; +import SearchIcon from '@mui/icons-material/Search'; +import { useFeedStore } from '../../store/feedStore'; +import { activityFeedsService } from '../../api/activityFeedsService'; + +// ── Memoized asset row — only re-renders when ITS OWN checked state changes ── +const AssetRow = memo(({ + assetId, assetName, checked, onToggle +}: { + assetId: number; + assetName: string; + checked: boolean; + onToggle: (id: number) => void; +}) => ( + onToggle(assetId)} + sx={{ color: '#475569', '&.Mui-checked': { color: '#3b82f6' }, py: 0.3 }} + /> + } + label={ + + {assetName.replace(/_/g, ' ')} + + } + /> +)); + +// ── Memoized group header ────────────────────────────────────────────────────── +const GroupHeader = memo(({ + typeName, assetCount, allGroupSelected, someGroupSelected, onToggle +}: { + typeName: string; + assetCount: number; + allGroupSelected: boolean; + someGroupSelected: boolean; + onToggle: () => void; +}) => ( + + } + label={ + + {typeName?.replace(/_/g, ' ')} ({assetCount}) + + } + sx={{ mb: 0.5 }} + /> +)); + +export const FeedFilters: React.FC = () => { + const { + assetTypes, tabs, selectedTabIndex, updateTab, + isFiltersModalOpen, setIsFiltersModalOpen, + selectedAssetIds, setSelectedAssetIds, + filterFromDate, filterTillDate, + filterMinChainage, filterMaxChainage, + setFilterMinChainage, setFilterMaxChainage, + } = useFeedStore(); + + // ── Use a Set (stored in state) for O(1) has() lookups ──────────────────── + // We store a Set but wrap it in an object so React detects the change + const [draftSet, setDraftSet] = useState>(() => new Set(selectedAssetIds)); + const [draftFromDate, setDraftFromDate] = useState(''); + const [draftTillDate, setDraftTillDate] = useState(''); + const [draftMinChainage, setDraftMinChainage] = useState(''); + const [draftMaxChainage, setDraftMaxChainage] = useState(''); + const [assetSearch, setAssetSearch] = useState(''); + const [loading, setLoading] = useState(false); + + // When dialog opens, seed ALL drafts from current store values — not empty strings! + const [prevOpen, setPrevOpen] = useState(false); + if (isFiltersModalOpen && !prevOpen) { + setPrevOpen(true); + setDraftSet(new Set(selectedAssetIds)); + setDraftFromDate(filterFromDate); // ← seeded from store + setDraftTillDate(filterTillDate); // ← seeded from store + setDraftMinChainage(filterMinChainage); // ← seeded from store + setDraftMaxChainage(filterMaxChainage); // ← seeded from store + setAssetSearch(''); + } else if (!isFiltersModalOpen && prevOpen) { + setPrevOpen(false); + } + + const allAssetIds = useMemo( + () => assetTypes.flatMap((t: any) => t.assets.map((a: any) => a.asset_id as number)), + [assetTypes] + ); + + const filteredAssetTypes = useMemo(() => { + if (!assetSearch.trim()) return assetTypes; + const q = assetSearch.toLowerCase(); + return assetTypes + .map((type: any) => ({ + ...type, + assets: type.assets.filter((a: any) => a.asset_name.toLowerCase().includes(q)) + })) + .filter((type: any) => type.assets.length > 0); + }, [assetTypes, assetSearch]); + + const allSelected = allAssetIds.length > 0 && allAssetIds.every(id => draftSet.has(id)); + const someSelected = draftSet.size > 0 && !allSelected; + + // ── Stable callbacks (useCallback so memoized children don't re-render) ─── + const handleToggleAsset = useCallback((assetId: number) => { + setDraftSet(prev => { + const next = new Set(prev); + if (next.has(assetId)) next.delete(assetId); else next.add(assetId); + return next; + }); + }, []); + + const handleToggleAll = useCallback(() => { + setDraftSet(prev => + prev.size === allAssetIds.length ? new Set() : new Set(allAssetIds) + ); + }, [allAssetIds]); + + const makeGroupToggle = useCallback((groupIds: number[]) => () => { + setDraftSet(prev => { + const allIn = groupIds.every(id => prev.has(id)); + const next = new Set(prev); + if (allIn) groupIds.forEach(id => next.delete(id)); + else groupIds.forEach(id => next.add(id)); + return next; + }); + }, []); + + const handleClearAll = useCallback(() => { + setDraftSet(new Set()); + setDraftFromDate(''); + setDraftTillDate(''); + setDraftMinChainage(''); + setDraftMaxChainage(''); + setAssetSearch(''); + }, []); + + // ── Apply — only now do we write to the store ──────────────────────────── + const handleApplyFilter = async () => { + setLoading(true); + try { + const { selectedSite, auditStatus, setFilterFromDate, setFilterTillDate } = useFeedStore.getState(); + const draftAssetArr = Array.from(draftSet); + + // Commit ALL filter state to the global store + setFilterFromDate(draftFromDate); + setFilterTillDate(draftTillDate); + setFilterMinChainage(draftMinChainage); // persist chainage globally + setFilterMaxChainage(draftMaxChainage); // persist chainage globally + setSelectedAssetIds(draftAssetArr); + + if (selectedTabIndex >= 0) { + const activeTab = tabs[selectedTabIndex]; + const siteIdParam = (!selectedSite || selectedSite?.site_id === 'All Sites') + ? '' : String(selectedSite.site_id || ''); + + const historyRes: any = await activityFeedsService.getHistory({ + date: activeTab.date, + fromDate: draftFromDate, + tillDate: draftTillDate, + pageNo: 0, + pageSize: 20, + siteIds: siteIdParam, + assetsIds: draftAssetArr.join(','), + isTrueFalse: auditStatus === 'False Audits' ? 'true' : 'both', + isRectificationEnabled: false, + auto_audit: false, + fromChainage: draftMinChainage, + toChainage: draftMaxChainage, + }); + if (historyRes?.anomalies) { + updateTab(selectedTabIndex, { + anomalies: historyRes.anomalies, + anomaliesCopy: historyRes.anomalies, + totalAnomalyCount: historyRes.count || historyRes.anomalies.length, + filters: { fromDate: draftFromDate, tillDate: draftTillDate, fromChainage: draftMinChainage, toChainage: draftMaxChainage } + }); + } + } + setIsFiltersModalOpen(false); + } catch (err) { + console.error('Filter apply failed', err); + } finally { + setLoading(false); + } + }; + + return ( + setIsFiltersModalOpen(false)} + maxWidth="lg" + fullWidth + // Zero transition — opens instantly + transitionDuration={0} + PaperProps={{ + sx: { + borderRadius: 3, + bgcolor: '#0f172a', + color: '#f8fafc', + border: '1px solid #1e293b', + maxHeight: '90vh' + } + }} + > + + + Filters + {draftSet.size > 0 && ( + 1 ? 's' : ''} selected`} + size="small" color="primary" + onDelete={() => setDraftSet(new Set())} + /> + )} + + + {/* Date & Chainage */} + + + From Date + setDraftFromDate(e.target.value)} + sx={{ bgcolor: 'rgba(255,255,255,0.07)', borderRadius: 1, input: { color: '#f8fafc' }, '& fieldset': { borderColor: '#334155' } }} /> + + + Till Date + setDraftTillDate(e.target.value)} + sx={{ bgcolor: 'rgba(255,255,255,0.07)', borderRadius: 1, input: { color: '#f8fafc' }, '& fieldset': { borderColor: '#334155' } }} /> + + + Chainage + setDraftMinChainage(e.target.value)} + sx={{ width: 90, bgcolor: 'rgba(255,255,255,0.07)', borderRadius: 1, input: { color: '#f8fafc' }, '& fieldset': { borderColor: '#334155' } }} /> + + setDraftMaxChainage(e.target.value)} + sx={{ width: 90, bgcolor: 'rgba(255,255,255,0.07)', borderRadius: 1, input: { color: '#f8fafc' }, '& fieldset': { borderColor: '#334155' } }} /> + + + + + + Assets + + setAssetSearch(e.target.value)} + sx={{ mb: 2, bgcolor: 'rgba(255,255,255,0.05)', borderRadius: 1, input: { color: '#f8fafc' }, '& fieldset': { borderColor: '#334155' } }} + slotProps={{ input: { startAdornment: } }} + /> + + + } + label={Select All ({allAssetIds.length})} + sx={{ mb: 1 }} + /> + + + {filteredAssetTypes.length === 0 ? ( + No assets match your search. + ) : ( + filteredAssetTypes.map((type: any) => { + const groupIds: number[] = type.assets.map((a: any) => a.asset_id); + const allGroupSelected = groupIds.every(id => draftSet.has(id)); + const someGroupSelected = groupIds.some(id => draftSet.has(id)) && !allGroupSelected; + + return ( + + + + {type.assets.map((asset: any) => ( + + ))} + + + ); + }) + )} + + + + + + + + + ); +}; diff --git a/src/pages/activity-feeds/FeedTabs.tsx b/src/pages/activity-feeds/FeedTabs.tsx new file mode 100644 index 0000000..22dce4a --- /dev/null +++ b/src/pages/activity-feeds/FeedTabs.tsx @@ -0,0 +1,55 @@ +import React from 'react'; +import { Tabs, Tab, Box, IconButton } from '@mui/material'; +import CloseIcon from '@mui/icons-material/Close'; +import { useFeedStore } from '../../store/feedStore'; + +export const FeedTabs: React.FC = () => { + const { tabs, selectedTabIndex, setSelectedTabIndex, closeTab } = useFeedStore(); + + const handleChange = (_event: React.SyntheticEvent, newValue: number) => { + setSelectedTabIndex(newValue); + }; + + if (tabs.length === 0) return null; + + return ( + + + {tabs.map((tab, index) => ( + + {tab.date === '' ? 'Unaudited' : tab.date} + {index !== 0 && ( // Don't allow closing the first tab usually + { e.stopPropagation(); closeTab(index); }} sx={{ ml: 1, color: 'inherit', p: 0.5 }}> + + + )} + + } + /> + ))} + + + ); +}; diff --git a/src/pages/activity-feeds/GlobalFeed.tsx b/src/pages/activity-feeds/GlobalFeed.tsx new file mode 100644 index 0000000..517cce3 --- /dev/null +++ b/src/pages/activity-feeds/GlobalFeed.tsx @@ -0,0 +1,283 @@ +import React, { useEffect } from 'react'; +import { Box, Typography, TablePagination, Button, FormControl, Select, MenuItem } from '@mui/material'; +import FilterListIcon from '@mui/icons-material/FilterList'; +import HistoryIcon from '@mui/icons-material/History'; +import { TopFilterBar } from '../../components/common/TopFilterBar'; +import { FeedTabs } from './FeedTabs'; +import { AnomalyTable } from './AnomalyTable'; +import { PreviewPanel } from './PreviewPanel'; +import { useFeedStore } from '../../store/feedStore'; +import { useAuthStore } from '../../store/authStore'; +import { activityFeedsService } from '../../api/activityFeedsService'; +export const GlobalFeed: React.FC = () => { + const { + setAssets, setAssetTypes, addTab, tabs, selectedTabIndex, updateTab, + sites, setSites, selectedSite, setSelectedSite, auditStatus, + isInitialized, setIsInitialized, + lastFetchedFilterKey, setLastFetchedFilterKey + } = useFeedStore(); + const { user } = useAuthStore(); + // Ref to skip the first run of the site/auditStatus effect + const isFirstRender = React.useRef(true); + useEffect(() => { + // Initial Load + const loadInitialData = async () => { + try { + const assetRes: any = await activityFeedsService.getAssets(); + if (assetRes && assetRes.asset_types) { + // Map assets mimicking the Angular logic + let flattenedAssets: any[] = []; + assetRes.asset_types.forEach((type: any) => { + const mapped = type.assets.map((a: any) => ({ + id: a.asset_id, + name: a.asset_name, + asset_type_id: type.type_id + })); + flattenedAssets = [...flattenedAssets, ...mapped]; + }); + setAssets(flattenedAssets); + setAssetTypes(assetRes.asset_types); // store raw grouped data for filters dialog + } + + // Fetch Sites + let defaultSite = null; + if (user?.org_id) { + try { + const sitesRes: any = await activityFeedsService.getOrganizationSites(user.org_id); + let parsedSites: any[] = []; + if (sitesRes?.responseData?.[0]?.records) { + parsedSites = sitesRes.responseData[0].records; + // Handle nested array response [ [ {site1}, {site2} ] ] + if (parsedSites.length === 1 && Array.isArray(parsedSites[0])) { + parsedSites = parsedSites[0]; + } else if (parsedSites.length > 0 && Array.isArray(parsedSites[0])) { + parsedSites = parsedSites.flat(); + } + } else if (Array.isArray(sitesRes)) { + parsedSites = sitesRes; + } else if (sitesRes?.data && Array.isArray(sitesRes.data)) { + parsedSites = sitesRes.data; + } + + if (parsedSites.length > 0) { + // Filter to ensure we only show sites for the currently selected org + parsedSites = parsedSites.filter(site => { + let siteOrgId = site.org_id; + if (siteOrgId === undefined && site.sub_sites && site.sub_sites.length > 0) { + siteOrgId = site.sub_sites[0].org_id; + } + + if (siteOrgId !== undefined && siteOrgId !== null) { + return String(siteOrgId) === String(user.org_id); + } + return true; + }).map(site => { + // Normalize site_id: if missing, aggregate from sub_sites + if (!site.site_id && site.sub_sites && site.sub_sites.length > 0) { + site.site_id = site.sub_sites.map((sub: any) => sub.site_id).filter(Boolean).join(','); + } + return site; + }); + + setSites(parsedSites); + defaultSite = { site_id: 'All Sites', site_name: 'All Sites' }; + setSelectedSite(defaultSite); + } + } catch (siteErr) { + console.error("Failed to fetch sites", siteErr); + } + } + + // Add default Unaudited tab if empty and fetch data + if (useFeedStore.getState().tabs.length === 0) { + addTab({ + date: '', // Unaudited + isRectificationTab: false, + totalAnomalyCount: 0, + anomalies: [], + anomaliesCopy: [], + selectedAnomalyIndex: 0, + filters: {}, + page: 0, + rowsPerPage: 20 + }); + + try { + const historyRes: any = await activityFeedsService.getHistory({ + date: '', + pageNo: 0, + pageSize: 20, + siteIds: defaultSite?.site_id === 'All Sites' ? '' : (defaultSite?.site_id || ''), + isTrueFalse: auditStatus === 'False Audits' ? 'true' : 'both', + auto_audit: false, + isRectificationEnabled: false + }); + if (historyRes && historyRes.anomalies) { + updateTab(0, { + anomalies: historyRes.anomalies, + anomaliesCopy: historyRes.anomalies, + totalAnomalyCount: historyRes.count || historyRes.anomalies.length + }); + } + } catch (historyErr) { + console.error("[GlobalFeed] Failed to load history", historyErr); + } + } + } catch (error) { + console.error("Failed to load initial feed data", error); + } finally { + setIsInitialized(true); // Mark as initialized regardless, to prevent retry loops + } + }; + + // GUARD: Only run initial load once across tab switches + if (useFeedStore.getState().isInitialized) { + return; + } + loadInitialData(); + }, []); // eslint-disable-line react-hooks/exhaustive-deps + + // Fetch data when selectedSite or auditStatus changes + useEffect(() => { + // GUARD: Skip if tabs are not initialized (initial load hasn't finished) + if (useFeedStore.getState().tabs.length === 0) { + return; + } + + // Build a key for the current filter state + const filterKey = `${selectedSite?.site_id ?? ''}|${auditStatus}`; + + // CACHE HIT: This exact filter combo was already fetched — skip re-fetch on remount + if (filterKey === lastFetchedFilterKey) { + return; + } + + const fetchFilteredHistory = async () => { + const state = useFeedStore.getState(); + const currentTabIndex = state.selectedTabIndex > -1 ? state.selectedTabIndex : 0; + const activeTab = state.tabs[currentTabIndex]; + const siteIdParam = (!selectedSite || selectedSite?.site_id === 'All Sites') + ? '' : String(selectedSite.site_id || ''); + + try { + const historyRes: any = await activityFeedsService.getHistory({ + date: activeTab?.date || '', + pageNo: 0, + pageSize: 20, + siteIds: siteIdParam, + isTrueFalse: auditStatus === 'False Audits' ? 'true' : 'both', + auto_audit: false, + isRectificationEnabled: false, + ...(activeTab?.filters || {}) + }); + if (historyRes && historyRes.anomalies) { + useFeedStore.getState().updateTab(currentTabIndex, { + anomalies: historyRes.anomalies, + anomaliesCopy: historyRes.anomalies, + totalAnomalyCount: historyRes.count || historyRes.anomalies.length + }); + setLastFetchedFilterKey(filterKey); // mark this combo as fetched + } + } catch (err) { + console.error('[GlobalFeed] Failed to load history for site/audit status change', err); + } + }; + + fetchFilteredHistory(); + // Use primitive/stable values to avoid spurious re-runs. + // selectedSite?.site_id and auditStatus are both strings/primitives. + }, [selectedSite?.site_id, auditStatus]); // eslint-disable-line react-hooks/exhaustive-deps + + const handlePageChange = async (event: unknown, newPage: number) => { + if (selectedTabIndex < 0 || tabs.length === 0) return; + const activeTab = tabs[selectedTabIndex]; + const allSiteIds = sites.map(s => s.site_id).filter(Boolean).join(','); + const rowsPerPage = activeTab.rowsPerPage || 20; + + try { + const historyRes: any = await activityFeedsService.getHistory({ + date: activeTab?.date || '', + pageNo: newPage * rowsPerPage, + pageSize: rowsPerPage, + siteIds: selectedSite?.site_id === 'All Sites' ? '' : (selectedSite?.site_id || ''), + isTrueFalse: auditStatus === 'False Audits' ? 'true' : 'both', + auto_audit: false, + isRectificationEnabled: false, + ...(activeTab?.filters || {}) + }); + if (historyRes && historyRes.anomalies) { + updateTab(selectedTabIndex, { + anomalies: historyRes.anomalies, + anomaliesCopy: historyRes.anomalies, + totalAnomalyCount: historyRes.count || historyRes.anomalies.length, + page: newPage, + }); + } + } catch (err) { + console.error("Failed to load history for page change", err); + } + }; + + const handleRowsPerPageChange = async (event: React.ChangeEvent) => { + if (selectedTabIndex < 0 || tabs.length === 0) return; + const activeTab = tabs[selectedTabIndex]; + const allSiteIds = sites.map(s => s.site_id).filter(Boolean).join(','); + const newRowsPerPage = parseInt(event.target.value, 10); + const newPage = 0; + + try { + const historyRes: any = await activityFeedsService.getHistory({ + date: activeTab?.date || '', + pageNo: newPage * newRowsPerPage, + pageSize: newRowsPerPage, + siteIds: selectedSite?.site_id === 'All Sites' ? '' : (selectedSite?.site_id || ''), + isTrueFalse: auditStatus === 'False Audits' ? 'true' : 'both', + auto_audit: false, + isRectificationEnabled: false, + ...(activeTab?.filters || {}) + }); + if (historyRes && historyRes.anomalies) { + updateTab(selectedTabIndex, { + anomalies: historyRes.anomalies, + anomaliesCopy: historyRes.anomalies, + totalAnomalyCount: historyRes.count || historyRes.anomalies.length, + page: newPage, + rowsPerPage: newRowsPerPage, + }); + } + } catch (err) { + console.error("Failed to load history for rowsPerPage change", err); + } + }; + + return ( + + + + + + + {/* Left side Table */} + + + + + + + + + + {/* Right side Preview Panel */} + + + + ); +}; diff --git a/src/pages/activity-feeds/PreviewPanel.tsx b/src/pages/activity-feeds/PreviewPanel.tsx new file mode 100644 index 0000000..d3ed11d --- /dev/null +++ b/src/pages/activity-feeds/PreviewPanel.tsx @@ -0,0 +1,80 @@ +import React from 'react'; +import { Box, Typography, Button } from '@mui/material'; +import { useNavigate } from 'react-router-dom'; +import { useFeedStore } from '../../store/feedStore'; + +export const PreviewPanel: React.FC = () => { + const { tabs, selectedTabIndex } = useFeedStore(); + const navigate = useNavigate(); + + if (tabs.length === 0 || selectedTabIndex < 0) return null; + + const activeTab = tabs[selectedTabIndex]; + const anomalies = activeTab.anomalies || []; + const selectedIndex = activeTab.selectedAnomalyIndex || 0; + + const anomaly = anomalies[selectedIndex]; + + if (!anomaly) { + return ( + + No anomaly selected + + ); + } + + const IMAGES_AWS_PREFIX = "https://auditor-master-images.seekright.com/SeekRight/"; + const IMAGES_TEST_AUDIT_PREFIX = "https://dashboard-images.seekright.com/SeekRight/"; + + let masterImageSrc = ''; + if (anomaly.Frame_Master) { + masterImageSrc = IMAGES_AWS_PREFIX + anomaly.Frame_Master; + } else if (!anomaly.Frame_Master && !anomaly.Frame_Test) { + masterImageSrc = '/assets/images/master_and_shift_image_not_available.png'; + } else { + masterImageSrc = '/assets/images/only_master_image_not_available.png'; + } + + let anomalyImageSrc = '/assets/images/placeholder.jpg'; + if (anomaly.Frame_Test) { + anomalyImageSrc = IMAGES_TEST_AUDIT_PREFIX + anomaly.Frame_Test; + } + + return ( + + + + Master + + MASTER IMAGE + + + + + Anomaly + + ANOMALY IMAGE + + + + + + + ); +}; diff --git a/src/pages/audit-session/AuditSession.tsx b/src/pages/audit-session/AuditSession.tsx new file mode 100644 index 0000000..d1b6577 --- /dev/null +++ b/src/pages/audit-session/AuditSession.tsx @@ -0,0 +1,477 @@ +import React, { useState, useEffect, useCallback } from 'react'; +import { Box, Typography, Button, IconButton, Chip } from '@mui/material'; +import { useNavigate, useLocation } from 'react-router-dom'; +import ArrowBackIcon from '@mui/icons-material/ArrowBack'; +import { activityFeedsService } from '../../api/activityFeedsService'; +import { useAuthStore } from '../../store/authStore'; +import { useFeedStore } from '../../store/feedStore'; + +export const AuditSession: React.FC = () => { + const navigate = useNavigate(); + const { user } = useAuthStore(); + const [anomalies, setAnomalies] = useState([]); + const [currentIndex, setCurrentIndex] = useState(0); + const [loading, setLoading] = useState(true); + const [carouselIndex, setCarouselIndex] = useState(0); + + // For the right sidebar state + const [selectedCategory, setSelectedCategory] = useState(null); + const [notes, setNotes] = useState(''); + const [isAnomaly, setIsAnomaly] = useState(null); // true = Anomaly, false = Safe + + const location = useLocation(); + const { tabs, selectedTabIndex } = useFeedStore(); + + useEffect(() => { + const navState = location.state as any; + + if (navState?.useExistingFeed) { + // Use anomalies from the global feed store + const activeTab = tabs[selectedTabIndex]; + if (activeTab && activeTab.anomalies) { + setAnomalies(activeTab.anomalies); + setCurrentIndex(navState.startIndex || 0); + setLoading(false); + } else { + setLoading(false); + } + } else { + // Fetch 50 items for the session (default behavior from Dashboard) + const fetchSessionData = async () => { + try { + setLoading(true); + const res: any = await activityFeedsService.getHistory({ + date: '', + pageNo: 0, + pageSize: 50, + isTrueFalse: 'false', // Fetch unaudited + auto_audit: false, + isRectificationEnabled: false, + }); + if (res && res.anomalies) { + setAnomalies(res.anomalies); + } + } catch (err) { + console.error('Failed to fetch session data', err); + } finally { + setLoading(false); + } + }; + fetchSessionData(); + } + }, [location.state, tabs, selectedTabIndex]); + + const IMAGES_AWS_PREFIX = "https://auditor-master-images.seekright.com/SeekRight/"; + const IMAGES_TEST_AUDIT_PREFIX = "https://dashboard-images.seekright.com/SeekRight/"; + + const currentAnomaly = anomalies[currentIndex]; + + useEffect(() => { + if (currentAnomaly?.images && currentAnomaly.images.length > 0) { + const selectedIdx = currentAnomaly.images.findIndex((img: any) => img.selected); + setCarouselIndex(selectedIdx !== -1 ? selectedIdx : 0); + } else { + setCarouselIndex(0); + } + }, [currentAnomaly]); + + let masterImageSrc = ''; + let anomalyImageSrc = ''; + let latStr = 'N/A'; + let longStr = 'E/A'; + + if (currentAnomaly) { + if (currentAnomaly.Frame_Master) { + masterImageSrc = IMAGES_AWS_PREFIX + currentAnomaly.Frame_Master; + } else if (!currentAnomaly.Frame_Master && !currentAnomaly.Frame_Test) { + masterImageSrc = '/assets/images/master_and_shift_image_not_available.png'; + } else { + masterImageSrc = '/assets/images/only_master_image_not_available.png'; + } + + // Parse Position + if (currentAnomaly.Pos) { + const match = String(currentAnomaly.Pos).match(/([NS][0-9.]+)([EW][0-9.]+)/i); + if (match) { + latStr = match[1]; + longStr = match[2]; + } else { + latStr = currentAnomaly.Pos; // Fallback + longStr = ''; + } + } + } + + const mediaItems: { type: 'image'|'video', url: string }[] = React.useMemo(() => { + if (!currentAnomaly) return []; + const items: { type: 'image'|'video', url: string }[] = []; + + if (currentAnomaly.images && currentAnomaly.images.length > 0) { + currentAnomaly.images.forEach((img: any) => { + items.push({ type: 'image', url: IMAGES_TEST_AUDIT_PREFIX + img.src }); + }); + } else if (currentAnomaly.Frame_Test) { + items.push({ type: 'image', url: IMAGES_TEST_AUDIT_PREFIX + currentAnomaly.Frame_Test }); + } + + if (currentAnomaly.video_url) { + items.push({ type: 'video', url: IMAGES_TEST_AUDIT_PREFIX + currentAnomaly.video_url }); + } + + return items; + }, [currentAnomaly]); + + const handleNext = () => { + if (currentIndex < anomalies.length - 1) { + setCurrentIndex(prev => prev + 1); + // Reset form + setSelectedCategory(null); + setNotes(''); + setIsAnomaly(null); + } else { + // Done with session + const navState = location.state as any; + if (navState?.useExistingFeed) { + navigate('/activity-feeds'); + } else { + navigate('/dashboard'); + } + } + }; + + const handlePrev = () => { + if (currentIndex > 0) { + setCurrentIndex(prev => prev - 1); + // We would ideally preserve form state for previously visited items + } + }; + + const handleSaveAndNext = async () => { + if (!currentAnomaly) return; + + // Placeholder for save logic + // await activityFeedsService.updateAuditedAnomaly(...) + console.log('Saved:', { id: currentAnomaly.anomaly_id, isAnomaly, selectedCategory, notes }); + handleNext(); + }; + + // Keyboard shortcuts + const handleKeyDown = useCallback((e: KeyboardEvent) => { + // Prevent default on shortcuts if focused on inputs? + if (document.activeElement?.tagName === 'TEXTAREA' || document.activeElement?.tagName === 'INPUT') { + return; // Don't trigger shortcuts when typing notes + } + + switch (e.key.toLowerCase()) { + case 'a': + setIsAnomaly(true); + break; + case 's': + setIsAnomaly(false); + break; + case '1': setSelectedCategory(1); break; + case '2': setSelectedCategory(2); break; + case '3': setSelectedCategory(3); break; + case '4': setSelectedCategory(4); break; + case '5': setSelectedCategory(5); break; + case 'enter': + handleSaveAndNext(); + break; + case 'arrowright': + handleSaveAndNext(); + break; + case 'arrowleft': + handlePrev(); + break; + } + }, [currentIndex, anomalies, isAnomaly, selectedCategory, notes]); + + useEffect(() => { + window.addEventListener('keydown', handleKeyDown); + return () => window.removeEventListener('keydown', handleKeyDown); + }, [handleKeyDown]); + + if (loading) { + return Loading session...; + } + + if (anomalies.length === 0) { + return ( + + No unaudited anomalies found to audit. + + + ); + } + + const getSeverityBadge = () => { + // Placeholder badge logic + return ; + }; + + return ( + + + {/* Header */} + + + + + Item {currentIndex + 1} of {anomalies.length} (session) + + {getSeverityBadge()} + + + {user?.first_name} {user?.last_name} + + + + + {/* Main Content Area */} + + + {/* Left Side: Images & Overlay */} + + + {/* Images Row */} + + {/* Previous Image Pane */} + + + MASTER IMAGE + + + {masterImageSrc ? ( + Master + ) : ( + No Master Image + )} + + + + {/* Current Image Pane */} + + + ANOMALY IMAGE + {currentAnomaly?.date_of_audit || currentAnomaly?.Created_on} + + + {mediaItems.length > 0 ? ( + <> + {mediaItems[carouselIndex]?.type === 'video' ? ( + + + + + {/* Bottom Bar: Location Overlay */} + + + + {currentAnomaly?.Plaza || 'Unknown Location'} + + {latStr}, {longStr} • ID #{currentAnomaly?.id || currentAnomaly?.anomaly_id || 'N/A'} + + + + + + {/* Right Side: Sidebar */} + + + {/* Anomaly/Safe Toggle */} + + + ANOMALY? + A / S + + + + + + + + {/* Category */} + + CATEGORY + + {[ + { id: 1, label: 'No Issue', color: '#22c55e' }, + { id: 2, label: 'Minor Crack', color: '#eab308' }, + { id: 3, label: 'Major Crack', color: '#f97316' }, + { id: 4, label: 'Structural Damage', color: '#ef4444' }, + { id: 5, label: 'Needs Investigation', color: '#8b5cf6' }, + ].map(cat => ( + + ))} + + + + {/* Notes */} + + NOTES + setNotes(e.target.value)} + placeholder="Optional observations..." + sx={{ + width: '100%', + flex: 1, + minHeight: 60, + bgcolor: '#0f172a', + border: '1px solid #1e293b', + borderRadius: 2, + color: 'white', + p: 2, + fontFamily: 'inherit', + resize: 'none', + '&:focus': { outline: 'none', borderColor: '#3b82f6' } + }} + /> + + + {/* Actions */} + + + + + + + + + + + {/* Footer Shortcuts */} + div': { display: 'flex', alignItems: 'center', gap: 1, whiteSpace: 'nowrap' } }}> + Keys: + + + Anomaly + + + + Safe + + + + Category + + + + Save & Next + + + + Navigate + + + + Skip + + + + Help + + + + ); +}; diff --git a/src/pages/dashboard/Dashboard.tsx b/src/pages/dashboard/Dashboard.tsx new file mode 100644 index 0000000..db07330 --- /dev/null +++ b/src/pages/dashboard/Dashboard.tsx @@ -0,0 +1,205 @@ +import React, { useEffect, useState } from 'react'; +import { useNavigate } from 'react-router-dom'; +import { Box, Typography, Button, Paper, LinearProgress, Container } from '@mui/material'; +import WarningAmberIcon from '@mui/icons-material/WarningAmber'; +import { activityFeedsService } from '../../api/activityFeedsService'; +import { TopFilterBar } from '../../components/common/TopFilterBar'; +import { useFeedStore } from '../../store/feedStore'; + +export const Dashboard: React.FC = () => { + const { + selectedSite, auditStatus, filterFromDate, filterTillDate, + filterMinChainage, filterMaxChainage, + selectedAssetIds, dashboardCache, setDashboardCache + } = useFeedStore(); + + const navigate = useNavigate(); + + const selectedSiteId = selectedSite?.site_id ?? ''; + const assetIdsKey = selectedAssetIds.join(','); + + // Build a key that uniquely identifies the current filter state + const currentFilterKey = `${selectedSiteId}|${auditStatus}|${filterFromDate}|${filterTillDate}|${assetIdsKey}|${filterMinChainage}|${filterMaxChainage}`; + + // Initialise stats from cache immediately (no flicker on tab switch) + const [stats, setStats] = useState(() => + dashboardCache.stats ?? { total: 0, audited: 0, pending: 0, anomaliesFound: 0 } + ); + // Only show loading spinner if there's no cached result for these filters + const [loading, setLoading] = useState(dashboardCache.stats === null); + + useEffect(() => { + // CACHE HIT: filters unchanged since last fetch — skip API call entirely + if (dashboardCache.stats !== null && currentFilterKey === `${dashboardCache.siteId}|${dashboardCache.auditStatus}|${dashboardCache.fromDate}|${dashboardCache.tillDate}|${dashboardCache.assetIds}|${dashboardCache.minChainage}|${dashboardCache.maxChainage}`) { + setStats(dashboardCache.stats); + setLoading(false); + return; + } + + const fetchStats = async () => { + try { + setLoading(true); + const res: any = await activityFeedsService.getHistory({ + date: '', + pageNo: 0, + pageSize: 200, + sortByDateAsc: false, + isRectificationEnabled: false, + isTrueFalse: auditStatus === 'False Audits' ? 'true' : 'both', + auto_audit: false, + siteIds: (!selectedSiteId || selectedSiteId === 'All Sites') ? '' : selectedSiteId, + assetsIds: assetIdsKey, + fromDate: filterFromDate, + tillDate: filterTillDate, + fromChainage: filterMinChainage, + toChainage: filterMaxChainage, + }); + + if (res) { + const anomalies = res.anomalies || []; + const newStats = { + total: res.count || anomalies.length, + audited: anomalies.filter((a: any) => a.IsAudited === 1).length, + pending: anomalies.filter((a: any) => a.IsAudited === 0).length, + anomaliesFound: anomalies.filter((a: any) => a.Audit_status === 1).length, + }; + setStats(newStats); + // Persist to store cache so re-mounting the Dashboard skips this fetch + setDashboardCache({ + siteId: selectedSiteId, + auditStatus, + fromDate: filterFromDate, + tillDate: filterTillDate, + assetIds: assetIdsKey, + minChainage: filterMinChainage, + maxChainage: filterMaxChainage, + stats: newStats, + }); + } + } catch (err) { + console.error('Failed to load dashboard stats', err); + } finally { + setLoading(false); + } + }; + + fetchStats(); + }, [currentFilterKey]); // eslint-disable-line react-hooks/exhaustive-deps + + const progressPercent = stats.total > 0 ? Math.round((stats.audited / stats.total) * 100) : 0; + + return ( + + + + + + {/* Stats Row */} + + {/* Total Items */} + + Total Items + + {loading ? '...' : stats.total.toLocaleString()} + + + + {/* Audited */} + + Audited + + {loading ? '...' : stats.audited.toLocaleString()} + + + + {/* Pending */} + + Pending + + {loading ? '...' : stats.pending.toLocaleString()} + + + + {/* Anomalies Found */} + + Anomalies Found + + {loading ? '...' : stats.anomaliesFound.toLocaleString()} + + + + + {/* Overall Progress */} + + + Overall Progress + {stats.audited} / {stats.total} completed + + + + {progressPercent}% complete + ~{Math.ceil(stats.pending / 50)} sessions remaining at 50/session + + + + {/* Next Session Info */} + + + Next session: 50 items will be queued ({stats.pending} pending total) + + + + {/* Warning Box */} + + + + 181 high-priority items will appear first in the queue + + + + {/* Start Button */} + + + {/* Footer links */} + + Keyboard shortcuts available inside the audit view + Reset demo data + + + + + + ); +}; diff --git a/src/store/authStore.ts b/src/store/authStore.ts new file mode 100644 index 0000000..8afcd31 --- /dev/null +++ b/src/store/authStore.ts @@ -0,0 +1,50 @@ +import { create } from 'zustand'; +import { persist } from 'zustand/middleware'; +import { useFeedStore } from './feedStore'; + +export interface User { + token: string; + access_token: string; + email: string; + username: string; + user_roles: string; + db_name?: string; + org_id?: string; +} + +interface AuthState { + user: User | null; + isAuthenticated: boolean; + login: (user: User) => void; + logout: () => void; + hasRole: (role: string) => boolean; +} + +export const useAuthStore = create()( + persist( + (set, get) => ({ + user: null, + isAuthenticated: false, + login: (user) => { + useFeedStore.getState().resetStore(); + set({ user, isAuthenticated: true }); + }, + logout: () => { + useFeedStore.getState().resetStore(); + set({ user: null, isAuthenticated: false }); + }, + hasRole: (requiredRole: string) => { + const { user } = get(); + if (!user || !user.user_roles) return false; + + const userRoles = user.user_roles.split(',').map(r => r.trim().toLowerCase()); + const neededRoles = requiredRole.split(',').map(r => r.trim().toLowerCase()); + + return neededRoles.some(role => userRoles.includes(role)); + }, + }), + { + name: 'auth-storage', // saves to localStorage by default + } + ) +); diff --git a/src/store/feedStore.ts b/src/store/feedStore.ts new file mode 100644 index 0000000..d441ac7 --- /dev/null +++ b/src/store/feedStore.ts @@ -0,0 +1,138 @@ +import { create } from 'zustand'; + +export interface FeedTab { + date: string; + isRectificationTab: boolean; + totalAnomalyCount: number; + anomalies: any[]; + anomaliesCopy: any[]; + selectedAnomalyIndex: number; + filters: any; + page: number; + rowsPerPage: number; +} + +// Tracks what filter params were last used to fetch dashboard stats +interface DashboardCache { + siteId: string; + auditStatus: string; + fromDate: string; + tillDate: string; + assetIds: string; + minChainage: string; + maxChainage: string; + stats: { + total: number; + audited: number; + pending: number; + anomaliesFound: number; + } | null; +} + +interface FeedState { + tabs: FeedTab[]; + selectedTabIndex: number; + assets: any[]; + assetTypes: any[]; + filterFromDate: string; + filterTillDate: string; + filterMinChainage: string; + filterMaxChainage: string; + selectedAssetIds: number[]; + sites: any[]; + auditStatus: string; + selectedSite: any; + isFiltersModalOpen: boolean; + isInitialized: boolean; + // Cache: last filter key used for the second GlobalFeed effect + lastFetchedFilterKey: string; + // Dashboard stats cache + dashboardCache: DashboardCache; + + // Actions + setTabs: (tabs: FeedTab[]) => void; + setSelectedTabIndex: (index: number) => void; + setAssets: (assets: any[]) => void; + setAssetTypes: (assetTypes: any[]) => void; + setSelectedAssetIds: (ids: number[]) => void; + setSites: (sites: any[]) => void; + setSelectedSite: (site: any) => void; + setAuditStatus: (status: string) => void; + setIsFiltersModalOpen: (isOpen: boolean) => void; + setIsInitialized: (val: boolean) => void; + setLastFetchedFilterKey: (key: string) => void; + setDashboardCache: (cache: DashboardCache) => void; + addTab: (tab: FeedTab) => void; + closeTab: (index: number) => void; + updateTab: (index: number, partialTab: Partial) => void; + setFilterFromDate: (date: string) => void; + setFilterTillDate: (date: string) => void; + setFilterMinChainage: (val: string) => void; + setFilterMaxChainage: (val: string) => void; + resetStore: () => void; +} + +const EMPTY_DASHBOARD_CACHE: DashboardCache = { + siteId: '__unset__', + auditStatus: '__unset__', + fromDate: '__unset__', + tillDate: '__unset__', + assetIds: '__unset__', + minChainage: '__unset__', + maxChainage: '__unset__', + stats: null, +}; + +const initialFeedState = { + tabs: [], + selectedTabIndex: -1, + assets: [], + assetTypes: [], + filterFromDate: '', + filterTillDate: '', + filterMinChainage: '', + filterMaxChainage: '', + selectedAssetIds: [], + selectedSite: null, + sites: [], + auditStatus: 'Auto Audits', + isFiltersModalOpen: false, + isInitialized: false, + lastFetchedFilterKey: '', + dashboardCache: EMPTY_DASHBOARD_CACHE, +}; + +export const useFeedStore = create((set) => ({ + ...initialFeedState, + + resetStore: () => set(initialFeedState), + + setTabs: (tabs) => set({ tabs }), + setSelectedTabIndex: (index) => set({ selectedTabIndex: index }), + setAssets: (assets) => set({ assets }), + setAssetTypes: (assetTypes) => set({ assetTypes }), + setSelectedAssetIds: (selectedAssetIds) => set({ selectedAssetIds }), + setSites: (sites) => set({ sites }), + setSelectedSite: (selectedSite) => set({ selectedSite }), + setAuditStatus: (auditStatus) => set({ auditStatus }), + setIsFiltersModalOpen: (isFiltersModalOpen) => set({ isFiltersModalOpen }), + setIsInitialized: (isInitialized) => set({ isInitialized }), + setLastFetchedFilterKey: (lastFetchedFilterKey) => set({ lastFetchedFilterKey }), + setDashboardCache: (dashboardCache) => set({ dashboardCache }), + setFilterFromDate: (filterFromDate) => set({ filterFromDate }), + setFilterTillDate: (filterTillDate) => set({ filterTillDate }), + setFilterMinChainage: (filterMinChainage) => set({ filterMinChainage }), + setFilterMaxChainage: (filterMaxChainage) => set({ filterMaxChainage }), + addTab: (tab) => set((state) => ({ tabs: [...state.tabs, tab], selectedTabIndex: state.tabs.length })), + closeTab: (index) => set((state) => { + const newTabs = [...state.tabs]; + newTabs.splice(index, 1); + const newIndex = state.selectedTabIndex >= newTabs.length ? newTabs.length - 1 : state.selectedTabIndex; + return { tabs: newTabs, selectedTabIndex: newIndex }; + }), + updateTab: (index, partialTab) => set((state) => { + const newTabs = [...state.tabs]; + newTabs[index] = { ...newTabs[index], ...partialTab }; + return { tabs: newTabs }; + }) +})); diff --git a/tsconfig.app.json b/tsconfig.app.json new file mode 100644 index 0000000..7f42e5f --- /dev/null +++ b/tsconfig.app.json @@ -0,0 +1,25 @@ +{ + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", + "target": "es2023", + "lib": ["ES2023", "DOM"], + "module": "esnext", + "types": ["vite/client"], + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "verbatimModuleSyntax": true, + "moduleDetection": "force", + "noEmit": true, + "jsx": "react-jsx", + + /* Linting */ + "noUnusedLocals": true, + "noUnusedParameters": true, + "erasableSyntaxOnly": true, + "noFallthroughCasesInSwitch": true + }, + "include": ["src"] +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..1ffef60 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,7 @@ +{ + "files": [], + "references": [ + { "path": "./tsconfig.app.json" }, + { "path": "./tsconfig.node.json" } + ] +} diff --git a/tsconfig.node.json b/tsconfig.node.json new file mode 100644 index 0000000..d3c52ea --- /dev/null +++ b/tsconfig.node.json @@ -0,0 +1,24 @@ +{ + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", + "target": "es2023", + "lib": ["ES2023"], + "module": "esnext", + "types": ["node"], + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "verbatimModuleSyntax": true, + "moduleDetection": "force", + "noEmit": true, + + /* Linting */ + "noUnusedLocals": true, + "noUnusedParameters": true, + "erasableSyntaxOnly": true, + "noFallthroughCasesInSwitch": true + }, + "include": ["vite.config.ts"] +} diff --git a/vite.config.ts b/vite.config.ts new file mode 100644 index 0000000..87cb23c --- /dev/null +++ b/vite.config.ts @@ -0,0 +1,21 @@ +import { defineConfig } from 'vite' +import react from '@vitejs/plugin-react' + +// https://vite.dev/config/ +export default defineConfig({ + plugins: [react()], + server: { + proxy: { + '/api/dashboard': { + target: 'https://sr-backend-api.takeleap.in', + changeOrigin: true, + rewrite: (path) => path.replace(/^\/api\/dashboard/, ''), + }, + '/api/audit': { + target: 'https://sr-audit.takeleap.in', + changeOrigin: true, + rewrite: (path) => path.replace(/^\/api\/audit/, ''), + }, + }, + }, +})