diff --git a/.gitignore b/.gitignore index 41669ba273..269f3d1295 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,7 @@ node_modules .DS_Store +.idea +.vscode .env.local .env.development.local .env.test.local diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 9e26dfeeb6..0000000000 --- a/.vscode/settings.json +++ /dev/null @@ -1 +0,0 @@ -{} \ No newline at end of file diff --git a/week1/assets/exercises/chat.png b/week1/assets/exercises/chat.png old mode 100755 new mode 100644 diff --git a/week1/assets/exercises/coin.png b/week1/assets/exercises/coin.png old mode 100755 new mode 100644 diff --git a/week1/assets/exercises/f-delivery.png b/week1/assets/exercises/f-delivery.png old mode 100755 new mode 100644 diff --git a/week3/project/e-commerce/.gitignore b/week3/project/e-commerce/.gitignore new file mode 100644 index 0000000000..a547bf36d8 --- /dev/null +++ b/week3/project/e-commerce/.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/week3/project/e-commerce/README.md b/week3/project/e-commerce/README.md new file mode 100644 index 0000000000..7059a962ad --- /dev/null +++ b/week3/project/e-commerce/README.md @@ -0,0 +1,12 @@ +# React + Vite + +This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. + +Currently, two official plugins are available: + +- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) for Fast Refresh +- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh + +## Expanding the ESLint configuration + +If you are developing a production application, we recommend using TypeScript with type-aware lint rules enabled. Check out the [TS template](https://github.com/vitejs/vite/tree/main/packages/create-vite/template-react-ts) for information on how to integrate TypeScript and [`typescript-eslint`](https://typescript-eslint.io) in your project. diff --git a/week3/project/e-commerce/eslint.config.js b/week3/project/e-commerce/eslint.config.js new file mode 100644 index 0000000000..46c5909b9b --- /dev/null +++ b/week3/project/e-commerce/eslint.config.js @@ -0,0 +1,33 @@ +import js from "@eslint/js"; +import globals from "globals"; +import reactHooks from "eslint-plugin-react-hooks"; +import reactRefresh from "eslint-plugin-react-refresh"; + +export default [ + { ignores: ["dist"] }, + { + files: ["**/*.{js,jsx}"], + languageOptions: { + ecmaVersion: 2020, + globals: globals.browser, + parserOptions: { + ecmaVersion: "latest", + ecmaFeatures: { jsx: true }, + sourceType: "module", + }, + }, + plugins: { + "react-hooks": reactHooks, + "react-refresh": reactRefresh, + }, + rules: { + ...js.configs.recommended.rules, + ...reactHooks.configs.recommended.rules, + "no-unused-vars": ["error", { varsIgnorePattern: "^[A-Z_]" }], + "react-refresh/only-export-components": [ + "warn", + { allowConstantExport: true }, + ], + }, + }, +]; diff --git a/week3/project/e-commerce/index.html b/week3/project/e-commerce/index.html new file mode 100644 index 0000000000..b7db956ac2 --- /dev/null +++ b/week3/project/e-commerce/index.html @@ -0,0 +1,30 @@ + + + + + + + + + + Ecommerce + + +
+ + + diff --git a/week3/project/e-commerce/package.json b/week3/project/e-commerce/package.json new file mode 100644 index 0000000000..263a5cf08c --- /dev/null +++ b/week3/project/e-commerce/package.json @@ -0,0 +1,31 @@ +{ + "name": "e-commerce", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build", + "lint": "eslint .", + "preview": "vite preview", + "prettier": "prettier . --write ." + }, + "dependencies": { + "react": "^19.1.0", + "react-dom": "^19.1.0", + "react-router-dom": "^7.6.2", + "react-spinners": "^0.17.0" + }, + "devDependencies": { + "@eslint/js": "^9.25.0", + "@types/react": "^19.1.2", + "@types/react-dom": "^19.1.2", + "@vitejs/plugin-react": "^4.4.1", + "eslint": "^9.25.0", + "eslint-plugin-react-hooks": "^5.2.0", + "eslint-plugin-react-refresh": "^0.4.19", + "globals": "^16.0.0", + "prettier": "^3.6.2", + "vite": "^6.3.5" + } +} diff --git a/week3/project/e-commerce/pnpm-lock.yaml b/week3/project/e-commerce/pnpm-lock.yaml new file mode 100644 index 0000000000..9317ce0112 --- /dev/null +++ b/week3/project/e-commerce/pnpm-lock.yaml @@ -0,0 +1,2425 @@ +lockfileVersion: "9.0" + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + .: + dependencies: + react: + specifier: ^19.1.0 + version: 19.1.0 + react-dom: + specifier: ^19.1.0 + version: 19.1.0(react@19.1.0) + react-router-dom: + specifier: ^7.6.2 + version: 7.6.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + react-spinners: + specifier: ^0.17.0 + version: 0.17.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + devDependencies: + "@eslint/js": + specifier: ^9.25.0 + version: 9.29.0 + "@types/react": + specifier: ^19.1.2 + version: 19.1.8 + "@types/react-dom": + specifier: ^19.1.2 + version: 19.1.6(@types/react@19.1.8) + "@vitejs/plugin-react": + specifier: ^4.4.1 + version: 4.5.2(vite@6.3.5) + eslint: + specifier: ^9.25.0 + version: 9.29.0 + eslint-plugin-react-hooks: + specifier: ^5.2.0 + version: 5.2.0(eslint@9.29.0) + eslint-plugin-react-refresh: + specifier: ^0.4.19 + version: 0.4.20(eslint@9.29.0) + globals: + specifier: ^16.0.0 + version: 16.2.0 + prettier: + specifier: ^3.6.2 + version: 3.6.2 + vite: + specifier: ^6.3.5 + version: 6.3.5 + +packages: + "@ampproject/remapping@2.3.0": + resolution: + { + integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==, + } + engines: { node: ">=6.0.0" } + + "@babel/code-frame@7.27.1": + resolution: + { + integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==, + } + engines: { node: ">=6.9.0" } + + "@babel/compat-data@7.27.5": + resolution: + { + integrity: sha512-KiRAp/VoJaWkkte84TvUd9qjdbZAdiqyvMxrGl1N6vzFogKmaLgoM3L1kgtLicp2HP5fBJS8JrZKLVIZGVJAVg==, + } + engines: { node: ">=6.9.0" } + + "@babel/core@7.27.4": + resolution: + { + integrity: sha512-bXYxrXFubeYdvB0NhD/NBB3Qi6aZeV20GOWVI47t2dkecCEoneR4NPVcb7abpXDEvejgrUfFtG6vG/zxAKmg+g==, + } + engines: { node: ">=6.9.0" } + + "@babel/generator@7.27.5": + resolution: + { + integrity: sha512-ZGhA37l0e/g2s1Cnzdix0O3aLYm66eF8aufiVteOgnwxgnRP8GoyMj7VWsgWnQbVKXyge7hqrFh2K2TQM6t1Hw==, + } + engines: { node: ">=6.9.0" } + + "@babel/helper-compilation-targets@7.27.2": + resolution: + { + integrity: sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==, + } + engines: { node: ">=6.9.0" } + + "@babel/helper-module-imports@7.27.1": + resolution: + { + integrity: sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==, + } + engines: { node: ">=6.9.0" } + + "@babel/helper-module-transforms@7.27.3": + resolution: + { + integrity: sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg==, + } + engines: { node: ">=6.9.0" } + peerDependencies: + "@babel/core": ^7.0.0 + + "@babel/helper-plugin-utils@7.27.1": + resolution: + { + integrity: sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==, + } + engines: { node: ">=6.9.0" } + + "@babel/helper-string-parser@7.27.1": + resolution: + { + integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==, + } + engines: { node: ">=6.9.0" } + + "@babel/helper-validator-identifier@7.27.1": + resolution: + { + integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==, + } + engines: { node: ">=6.9.0" } + + "@babel/helper-validator-option@7.27.1": + resolution: + { + integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==, + } + engines: { node: ">=6.9.0" } + + "@babel/helpers@7.27.6": + resolution: + { + integrity: sha512-muE8Tt8M22638HU31A3CgfSUciwz1fhATfoVai05aPXGor//CdWDCbnlY1yvBPo07njuVOCNGCSp/GTt12lIug==, + } + engines: { node: ">=6.9.0" } + + "@babel/parser@7.27.5": + resolution: + { + integrity: sha512-OsQd175SxWkGlzbny8J3K8TnnDD0N3lrIUtB92xwyRpzaenGZhxDvxN/JgU00U3CDZNj9tPuDJ5H0WS4Nt3vKg==, + } + engines: { node: ">=6.0.0" } + hasBin: true + + "@babel/plugin-transform-react-jsx-self@7.27.1": + resolution: + { + integrity: sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==, + } + engines: { node: ">=6.9.0" } + peerDependencies: + "@babel/core": ^7.0.0-0 + + "@babel/plugin-transform-react-jsx-source@7.27.1": + resolution: + { + integrity: sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==, + } + engines: { node: ">=6.9.0" } + peerDependencies: + "@babel/core": ^7.0.0-0 + + "@babel/template@7.27.2": + resolution: + { + integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==, + } + engines: { node: ">=6.9.0" } + + "@babel/traverse@7.27.4": + resolution: + { + integrity: sha512-oNcu2QbHqts9BtOWJosOVJapWjBDSxGCpFvikNR5TGDYDQf3JwpIoMzIKrvfoti93cLfPJEG4tH9SPVeyCGgdA==, + } + engines: { node: ">=6.9.0" } + + "@babel/types@7.27.6": + resolution: + { + integrity: sha512-ETyHEk2VHHvl9b9jZP5IHPavHYk57EhanlRRuae9XCpb/j5bDCbPPMOBfCWhnl/7EDJz0jEMCi/RhccCE8r1+Q==, + } + engines: { node: ">=6.9.0" } + + "@esbuild/aix-ppc64@0.25.5": + resolution: + { + integrity: sha512-9o3TMmpmftaCMepOdA5k/yDw8SfInyzWWTjYTFCX3kPSDJMROQTb8jg+h9Cnwnmm1vOzvxN7gIfB5V2ewpjtGA==, + } + engines: { node: ">=18" } + cpu: [ppc64] + os: [aix] + + "@esbuild/android-arm64@0.25.5": + resolution: + { + integrity: sha512-VGzGhj4lJO+TVGV1v8ntCZWJktV7SGCs3Pn1GRWI1SBFtRALoomm8k5E9Pmwg3HOAal2VDc2F9+PM/rEY6oIDg==, + } + engines: { node: ">=18" } + cpu: [arm64] + os: [android] + + "@esbuild/android-arm@0.25.5": + resolution: + { + integrity: sha512-AdJKSPeEHgi7/ZhuIPtcQKr5RQdo6OO2IL87JkianiMYMPbCtot9fxPbrMiBADOWWm3T2si9stAiVsGbTQFkbA==, + } + engines: { node: ">=18" } + cpu: [arm] + os: [android] + + "@esbuild/android-x64@0.25.5": + resolution: + { + integrity: sha512-D2GyJT1kjvO//drbRT3Hib9XPwQeWd9vZoBJn+bu/lVsOZ13cqNdDeqIF/xQ5/VmWvMduP6AmXvylO/PIc2isw==, + } + engines: { node: ">=18" } + cpu: [x64] + os: [android] + + "@esbuild/darwin-arm64@0.25.5": + resolution: + { + integrity: sha512-GtaBgammVvdF7aPIgH2jxMDdivezgFu6iKpmT+48+F8Hhg5J/sfnDieg0aeG/jfSvkYQU2/pceFPDKlqZzwnfQ==, + } + engines: { node: ">=18" } + cpu: [arm64] + os: [darwin] + + "@esbuild/darwin-x64@0.25.5": + resolution: + { + integrity: sha512-1iT4FVL0dJ76/q1wd7XDsXrSW+oLoquptvh4CLR4kITDtqi2e/xwXwdCVH8hVHU43wgJdsq7Gxuzcs6Iq/7bxQ==, + } + engines: { node: ">=18" } + cpu: [x64] + os: [darwin] + + "@esbuild/freebsd-arm64@0.25.5": + resolution: + { + integrity: sha512-nk4tGP3JThz4La38Uy/gzyXtpkPW8zSAmoUhK9xKKXdBCzKODMc2adkB2+8om9BDYugz+uGV7sLmpTYzvmz6Sw==, + } + engines: { node: ">=18" } + cpu: [arm64] + os: [freebsd] + + "@esbuild/freebsd-x64@0.25.5": + resolution: + { + integrity: sha512-PrikaNjiXdR2laW6OIjlbeuCPrPaAl0IwPIaRv+SMV8CiM8i2LqVUHFC1+8eORgWyY7yhQY+2U2fA55mBzReaw==, + } + engines: { node: ">=18" } + cpu: [x64] + os: [freebsd] + + "@esbuild/linux-arm64@0.25.5": + resolution: + { + integrity: sha512-Z9kfb1v6ZlGbWj8EJk9T6czVEjjq2ntSYLY2cw6pAZl4oKtfgQuS4HOq41M/BcoLPzrUbNd+R4BXFyH//nHxVg==, + } + engines: { node: ">=18" } + cpu: [arm64] + os: [linux] + + "@esbuild/linux-arm@0.25.5": + resolution: + { + integrity: sha512-cPzojwW2okgh7ZlRpcBEtsX7WBuqbLrNXqLU89GxWbNt6uIg78ET82qifUy3W6OVww6ZWobWub5oqZOVtwolfw==, + } + engines: { node: ">=18" } + cpu: [arm] + os: [linux] + + "@esbuild/linux-ia32@0.25.5": + resolution: + { + integrity: sha512-sQ7l00M8bSv36GLV95BVAdhJ2QsIbCuCjh/uYrWiMQSUuV+LpXwIqhgJDcvMTj+VsQmqAHL2yYaasENvJ7CDKA==, + } + engines: { node: ">=18" } + cpu: [ia32] + os: [linux] + + "@esbuild/linux-loong64@0.25.5": + resolution: + { + integrity: sha512-0ur7ae16hDUC4OL5iEnDb0tZHDxYmuQyhKhsPBV8f99f6Z9KQM02g33f93rNH5A30agMS46u2HP6qTdEt6Q1kg==, + } + engines: { node: ">=18" } + cpu: [loong64] + os: [linux] + + "@esbuild/linux-mips64el@0.25.5": + resolution: + { + integrity: sha512-kB/66P1OsHO5zLz0i6X0RxlQ+3cu0mkxS3TKFvkb5lin6uwZ/ttOkP3Z8lfR9mJOBk14ZwZ9182SIIWFGNmqmg==, + } + engines: { node: ">=18" } + cpu: [mips64el] + os: [linux] + + "@esbuild/linux-ppc64@0.25.5": + resolution: + { + integrity: sha512-UZCmJ7r9X2fe2D6jBmkLBMQetXPXIsZjQJCjgwpVDz+YMcS6oFR27alkgGv3Oqkv07bxdvw7fyB71/olceJhkQ==, + } + engines: { node: ">=18" } + cpu: [ppc64] + os: [linux] + + "@esbuild/linux-riscv64@0.25.5": + resolution: + { + integrity: sha512-kTxwu4mLyeOlsVIFPfQo+fQJAV9mh24xL+y+Bm6ej067sYANjyEw1dNHmvoqxJUCMnkBdKpvOn0Ahql6+4VyeA==, + } + engines: { node: ">=18" } + cpu: [riscv64] + os: [linux] + + "@esbuild/linux-s390x@0.25.5": + resolution: + { + integrity: sha512-K2dSKTKfmdh78uJ3NcWFiqyRrimfdinS5ErLSn3vluHNeHVnBAFWC8a4X5N+7FgVE1EjXS1QDZbpqZBjfrqMTQ==, + } + engines: { node: ">=18" } + cpu: [s390x] + os: [linux] + + "@esbuild/linux-x64@0.25.5": + resolution: + { + integrity: sha512-uhj8N2obKTE6pSZ+aMUbqq+1nXxNjZIIjCjGLfsWvVpy7gKCOL6rsY1MhRh9zLtUtAI7vpgLMK6DxjO8Qm9lJw==, + } + engines: { node: ">=18" } + cpu: [x64] + os: [linux] + + "@esbuild/netbsd-arm64@0.25.5": + resolution: + { + integrity: sha512-pwHtMP9viAy1oHPvgxtOv+OkduK5ugofNTVDilIzBLpoWAM16r7b/mxBvfpuQDpRQFMfuVr5aLcn4yveGvBZvw==, + } + engines: { node: ">=18" } + cpu: [arm64] + os: [netbsd] + + "@esbuild/netbsd-x64@0.25.5": + resolution: + { + integrity: sha512-WOb5fKrvVTRMfWFNCroYWWklbnXH0Q5rZppjq0vQIdlsQKuw6mdSihwSo4RV/YdQ5UCKKvBy7/0ZZYLBZKIbwQ==, + } + engines: { node: ">=18" } + cpu: [x64] + os: [netbsd] + + "@esbuild/openbsd-arm64@0.25.5": + resolution: + { + integrity: sha512-7A208+uQKgTxHd0G0uqZO8UjK2R0DDb4fDmERtARjSHWxqMTye4Erz4zZafx7Di9Cv+lNHYuncAkiGFySoD+Mw==, + } + engines: { node: ">=18" } + cpu: [arm64] + os: [openbsd] + + "@esbuild/openbsd-x64@0.25.5": + resolution: + { + integrity: sha512-G4hE405ErTWraiZ8UiSoesH8DaCsMm0Cay4fsFWOOUcz8b8rC6uCvnagr+gnioEjWn0wC+o1/TAHt+It+MpIMg==, + } + engines: { node: ">=18" } + cpu: [x64] + os: [openbsd] + + "@esbuild/sunos-x64@0.25.5": + resolution: + { + integrity: sha512-l+azKShMy7FxzY0Rj4RCt5VD/q8mG/e+mDivgspo+yL8zW7qEwctQ6YqKX34DTEleFAvCIUviCFX1SDZRSyMQA==, + } + engines: { node: ">=18" } + cpu: [x64] + os: [sunos] + + "@esbuild/win32-arm64@0.25.5": + resolution: + { + integrity: sha512-O2S7SNZzdcFG7eFKgvwUEZ2VG9D/sn/eIiz8XRZ1Q/DO5a3s76Xv0mdBzVM5j5R639lXQmPmSo0iRpHqUUrsxw==, + } + engines: { node: ">=18" } + cpu: [arm64] + os: [win32] + + "@esbuild/win32-ia32@0.25.5": + resolution: + { + integrity: sha512-onOJ02pqs9h1iMJ1PQphR+VZv8qBMQ77Klcsqv9CNW2w6yLqoURLcgERAIurY6QE63bbLuqgP9ATqajFLK5AMQ==, + } + engines: { node: ">=18" } + cpu: [ia32] + os: [win32] + + "@esbuild/win32-x64@0.25.5": + resolution: + { + integrity: sha512-TXv6YnJ8ZMVdX+SXWVBo/0p8LTcrUYngpWjvm91TMjjBQii7Oz11Lw5lbDV5Y0TzuhSJHwiH4hEtC1I42mMS0g==, + } + engines: { node: ">=18" } + cpu: [x64] + os: [win32] + + "@eslint-community/eslint-utils@4.7.0": + resolution: + { + integrity: sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==, + } + engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 } + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + + "@eslint-community/regexpp@4.12.1": + resolution: + { + integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==, + } + engines: { node: ^12.0.0 || ^14.0.0 || >=16.0.0 } + + "@eslint/config-array@0.20.1": + resolution: + { + integrity: sha512-OL0RJzC/CBzli0DrrR31qzj6d6i6Mm3HByuhflhl4LOBiWxN+3i6/t/ZQQNii4tjksXi8r2CRW1wMpWA2ULUEw==, + } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + + "@eslint/config-helpers@0.2.3": + resolution: + { + integrity: sha512-u180qk2Um1le4yf0ruXH3PYFeEZeYC3p/4wCTKrr2U1CmGdzGi3KtY0nuPDH48UJxlKCC5RDzbcbh4X0XlqgHg==, + } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + + "@eslint/core@0.14.0": + resolution: + { + integrity: sha512-qIbV0/JZr7iSDjqAc60IqbLdsj9GDt16xQtWD+B78d/HAlvysGdZZ6rpJHGAc2T0FQx1X6thsSPdnoiGKdNtdg==, + } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + + "@eslint/core@0.15.0": + resolution: + { + integrity: sha512-b7ePw78tEWWkpgZCDYkbqDOP8dmM6qe+AOC6iuJqlq1R/0ahMAeH3qynpnqKFGkMltrp44ohV4ubGyvLX28tzw==, + } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + + "@eslint/eslintrc@3.3.1": + resolution: + { + integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==, + } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + + "@eslint/js@9.29.0": + resolution: + { + integrity: sha512-3PIF4cBw/y+1u2EazflInpV+lYsSG0aByVIQzAgb1m1MhHFSbqTyNqtBKHgWf/9Ykud+DhILS9EGkmekVhbKoQ==, + } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + + "@eslint/object-schema@2.1.6": + resolution: + { + integrity: sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==, + } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + + "@eslint/plugin-kit@0.3.2": + resolution: + { + integrity: sha512-4SaFZCNfJqvk/kenHpI8xvN42DMaoycy4PzKc5otHxRswww1kAt82OlBuwRVLofCACCTZEcla2Ydxv8scMXaTg==, + } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + + "@humanfs/core@0.19.1": + resolution: + { + integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==, + } + engines: { node: ">=18.18.0" } + + "@humanfs/node@0.16.6": + resolution: + { + integrity: sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==, + } + engines: { node: ">=18.18.0" } + + "@humanwhocodes/module-importer@1.0.1": + resolution: + { + integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==, + } + engines: { node: ">=12.22" } + + "@humanwhocodes/retry@0.3.1": + resolution: + { + integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==, + } + engines: { node: ">=18.18" } + + "@humanwhocodes/retry@0.4.3": + resolution: + { + integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==, + } + engines: { node: ">=18.18" } + + "@jridgewell/gen-mapping@0.3.8": + resolution: + { + integrity: sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==, + } + engines: { node: ">=6.0.0" } + + "@jridgewell/resolve-uri@3.1.2": + resolution: + { + integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==, + } + engines: { node: ">=6.0.0" } + + "@jridgewell/set-array@1.2.1": + resolution: + { + integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==, + } + engines: { node: ">=6.0.0" } + + "@jridgewell/sourcemap-codec@1.5.0": + resolution: + { + integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==, + } + + "@jridgewell/trace-mapping@0.3.25": + resolution: + { + integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==, + } + + "@rolldown/pluginutils@1.0.0-beta.11": + resolution: + { + integrity: sha512-L/gAA/hyCSuzTF1ftlzUSI/IKr2POHsv1Dd78GfqkR83KMNuswWD61JxGV2L7nRwBBBSDr6R1gCkdTmoN7W4ag==, + } + + "@rollup/rollup-android-arm-eabi@4.43.0": + resolution: + { + integrity: sha512-Krjy9awJl6rKbruhQDgivNbD1WuLb8xAclM4IR4cN5pHGAs2oIMMQJEiC3IC/9TZJ+QZkmZhlMO/6MBGxPidpw==, + } + cpu: [arm] + os: [android] + + "@rollup/rollup-android-arm64@4.43.0": + resolution: + { + integrity: sha512-ss4YJwRt5I63454Rpj+mXCXicakdFmKnUNxr1dLK+5rv5FJgAxnN7s31a5VchRYxCFWdmnDWKd0wbAdTr0J5EA==, + } + cpu: [arm64] + os: [android] + + "@rollup/rollup-darwin-arm64@4.43.0": + resolution: + { + integrity: sha512-eKoL8ykZ7zz8MjgBenEF2OoTNFAPFz1/lyJ5UmmFSz5jW+7XbH1+MAgCVHy72aG59rbuQLcJeiMrP8qP5d/N0A==, + } + cpu: [arm64] + os: [darwin] + + "@rollup/rollup-darwin-x64@4.43.0": + resolution: + { + integrity: sha512-SYwXJgaBYW33Wi/q4ubN+ldWC4DzQY62S4Ll2dgfr/dbPoF50dlQwEaEHSKrQdSjC6oIe1WgzosoaNoHCdNuMg==, + } + cpu: [x64] + os: [darwin] + + "@rollup/rollup-freebsd-arm64@4.43.0": + resolution: + { + integrity: sha512-SV+U5sSo0yujrjzBF7/YidieK2iF6E7MdF6EbYxNz94lA+R0wKl3SiixGyG/9Klab6uNBIqsN7j4Y/Fya7wAjQ==, + } + cpu: [arm64] + os: [freebsd] + + "@rollup/rollup-freebsd-x64@4.43.0": + resolution: + { + integrity: sha512-J7uCsiV13L/VOeHJBo5SjasKiGxJ0g+nQTrBkAsmQBIdil3KhPnSE9GnRon4ejX1XDdsmK/l30IYLiAaQEO0Cg==, + } + cpu: [x64] + os: [freebsd] + + "@rollup/rollup-linux-arm-gnueabihf@4.43.0": + resolution: + { + integrity: sha512-gTJ/JnnjCMc15uwB10TTATBEhK9meBIY+gXP4s0sHD1zHOaIh4Dmy1X9wup18IiY9tTNk5gJc4yx9ctj/fjrIw==, + } + cpu: [arm] + os: [linux] + + "@rollup/rollup-linux-arm-musleabihf@4.43.0": + resolution: + { + integrity: sha512-ZJ3gZynL1LDSIvRfz0qXtTNs56n5DI2Mq+WACWZ7yGHFUEirHBRt7fyIk0NsCKhmRhn7WAcjgSkSVVxKlPNFFw==, + } + cpu: [arm] + os: [linux] + + "@rollup/rollup-linux-arm64-gnu@4.43.0": + resolution: + { + integrity: sha512-8FnkipasmOOSSlfucGYEu58U8cxEdhziKjPD2FIa0ONVMxvl/hmONtX/7y4vGjdUhjcTHlKlDhw3H9t98fPvyA==, + } + cpu: [arm64] + os: [linux] + + "@rollup/rollup-linux-arm64-musl@4.43.0": + resolution: + { + integrity: sha512-KPPyAdlcIZ6S9C3S2cndXDkV0Bb1OSMsX0Eelr2Bay4EsF9yi9u9uzc9RniK3mcUGCLhWY9oLr6er80P5DE6XA==, + } + cpu: [arm64] + os: [linux] + + "@rollup/rollup-linux-loongarch64-gnu@4.43.0": + resolution: + { + integrity: sha512-HPGDIH0/ZzAZjvtlXj6g+KDQ9ZMHfSP553za7o2Odegb/BEfwJcR0Sw0RLNpQ9nC6Gy8s+3mSS9xjZ0n3rhcYg==, + } + cpu: [loong64] + os: [linux] + + "@rollup/rollup-linux-powerpc64le-gnu@4.43.0": + resolution: + { + integrity: sha512-gEmwbOws4U4GLAJDhhtSPWPXUzDfMRedT3hFMyRAvM9Mrnj+dJIFIeL7otsv2WF3D7GrV0GIewW0y28dOYWkmw==, + } + cpu: [ppc64] + os: [linux] + + "@rollup/rollup-linux-riscv64-gnu@4.43.0": + resolution: + { + integrity: sha512-XXKvo2e+wFtXZF/9xoWohHg+MuRnvO29TI5Hqe9xwN5uN8NKUYy7tXUG3EZAlfchufNCTHNGjEx7uN78KsBo0g==, + } + cpu: [riscv64] + os: [linux] + + "@rollup/rollup-linux-riscv64-musl@4.43.0": + resolution: + { + integrity: sha512-ruf3hPWhjw6uDFsOAzmbNIvlXFXlBQ4nk57Sec8E8rUxs/AI4HD6xmiiasOOx/3QxS2f5eQMKTAwk7KHwpzr/Q==, + } + cpu: [riscv64] + os: [linux] + + "@rollup/rollup-linux-s390x-gnu@4.43.0": + resolution: + { + integrity: sha512-QmNIAqDiEMEvFV15rsSnjoSmO0+eJLoKRD9EAa9rrYNwO/XRCtOGM3A5A0X+wmG+XRrw9Fxdsw+LnyYiZWWcVw==, + } + cpu: [s390x] + os: [linux] + + "@rollup/rollup-linux-x64-gnu@4.43.0": + resolution: + { + integrity: sha512-jAHr/S0iiBtFyzjhOkAics/2SrXE092qyqEg96e90L3t9Op8OTzS6+IX0Fy5wCt2+KqeHAkti+eitV0wvblEoQ==, + } + cpu: [x64] + os: [linux] + + "@rollup/rollup-linux-x64-musl@4.43.0": + resolution: + { + integrity: sha512-3yATWgdeXyuHtBhrLt98w+5fKurdqvs8B53LaoKD7P7H7FKOONLsBVMNl9ghPQZQuYcceV5CDyPfyfGpMWD9mQ==, + } + cpu: [x64] + os: [linux] + + "@rollup/rollup-win32-arm64-msvc@4.43.0": + resolution: + { + integrity: sha512-wVzXp2qDSCOpcBCT5WRWLmpJRIzv23valvcTwMHEobkjippNf+C3ys/+wf07poPkeNix0paTNemB2XrHr2TnGw==, + } + cpu: [arm64] + os: [win32] + + "@rollup/rollup-win32-ia32-msvc@4.43.0": + resolution: + { + integrity: sha512-fYCTEyzf8d+7diCw8b+asvWDCLMjsCEA8alvtAutqJOJp/wL5hs1rWSqJ1vkjgW0L2NB4bsYJrpKkiIPRR9dvw==, + } + cpu: [ia32] + os: [win32] + + "@rollup/rollup-win32-x64-msvc@4.43.0": + resolution: + { + integrity: sha512-SnGhLiE5rlK0ofq8kzuDkM0g7FN1s5VYY+YSMTibP7CqShxCQvqtNxTARS4xX4PFJfHjG0ZQYX9iGzI3FQh5Aw==, + } + cpu: [x64] + os: [win32] + + "@types/babel__core@7.20.5": + resolution: + { + integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==, + } + + "@types/babel__generator@7.27.0": + resolution: + { + integrity: sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==, + } + + "@types/babel__template@7.4.4": + resolution: + { + integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==, + } + + "@types/babel__traverse@7.20.7": + resolution: + { + integrity: sha512-dkO5fhS7+/oos4ciWxyEyjWe48zmG6wbCheo/G2ZnHx4fs3EU6YC6UM8rk56gAjNJ9P3MTH2jo5jb92/K6wbng==, + } + + "@types/estree@1.0.7": + resolution: + { + integrity: sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==, + } + + "@types/estree@1.0.8": + resolution: + { + integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==, + } + + "@types/json-schema@7.0.15": + resolution: + { + integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==, + } + + "@types/react-dom@19.1.6": + resolution: + { + integrity: sha512-4hOiT/dwO8Ko0gV1m/TJZYk3y0KBnY9vzDh7W+DH17b2HFSOGgdj33dhihPeuy3l0q23+4e+hoXHV6hCC4dCXw==, + } + peerDependencies: + "@types/react": ^19.0.0 + + "@types/react@19.1.8": + resolution: + { + integrity: sha512-AwAfQ2Wa5bCx9WP8nZL2uMZWod7J7/JSplxbTmBQ5ms6QpqNYm672H0Vu9ZVKVngQ+ii4R/byguVEUZQyeg44g==, + } + + "@vitejs/plugin-react@4.5.2": + resolution: + { + integrity: sha512-QNVT3/Lxx99nMQWJWF7K4N6apUEuT0KlZA3mx/mVaoGj3smm/8rc8ezz15J1pcbcjDK0V15rpHetVfya08r76Q==, + } + engines: { node: ^14.18.0 || >=16.0.0 } + peerDependencies: + vite: ^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0 + + acorn-jsx@5.3.2: + resolution: + { + integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==, + } + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn@8.15.0: + resolution: + { + integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==, + } + engines: { node: ">=0.4.0" } + hasBin: true + + ajv@6.12.6: + resolution: + { + integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==, + } + + ansi-styles@4.3.0: + resolution: + { + integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==, + } + engines: { node: ">=8" } + + argparse@2.0.1: + resolution: + { + integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==, + } + + balanced-match@1.0.2: + resolution: + { + integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==, + } + + brace-expansion@1.1.12: + resolution: + { + integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==, + } + + browserslist@4.25.0: + resolution: + { + integrity: sha512-PJ8gYKeS5e/whHBh8xrwYK+dAvEj7JXtz6uTucnMRB8OiGTsKccFekoRrjajPBHV8oOY+2tI4uxeceSimKwMFA==, + } + engines: { node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7 } + hasBin: true + + callsites@3.1.0: + resolution: + { + integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==, + } + engines: { node: ">=6" } + + caniuse-lite@1.0.30001723: + resolution: + { + integrity: sha512-1R/elMjtehrFejxwmexeXAtae5UO9iSyFn6G/I806CYC/BLyyBk1EPhrKBkWhy6wM6Xnm47dSJQec+tLJ39WHw==, + } + + chalk@4.1.2: + resolution: + { + integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==, + } + engines: { node: ">=10" } + + color-convert@2.0.1: + resolution: + { + integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==, + } + engines: { node: ">=7.0.0" } + + color-name@1.1.4: + resolution: + { + integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==, + } + + concat-map@0.0.1: + resolution: + { + integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==, + } + + convert-source-map@2.0.0: + resolution: + { + integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==, + } + + cookie@1.0.2: + resolution: + { + integrity: sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==, + } + engines: { node: ">=18" } + + cross-spawn@7.0.6: + resolution: + { + integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==, + } + engines: { node: ">= 8" } + + csstype@3.1.3: + resolution: + { + integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==, + } + + debug@4.4.1: + resolution: + { + integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==, + } + engines: { node: ">=6.0" } + peerDependencies: + supports-color: "*" + peerDependenciesMeta: + supports-color: + optional: true + + deep-is@0.1.4: + resolution: + { + integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==, + } + + electron-to-chromium@1.5.167: + resolution: + { + integrity: sha512-LxcRvnYO5ez2bMOFpbuuVuAI5QNeY1ncVytE/KXaL6ZNfzX1yPlAO0nSOyIHx2fVAuUprMqPs/TdVhUFZy7SIQ==, + } + + esbuild@0.25.5: + resolution: + { + integrity: sha512-P8OtKZRv/5J5hhz0cUAdu/cLuPIKXpQl1R9pZtvmHWQvrAUVd0UNIPT4IB4W3rNOqVO0rlqHmCIbSwxh/c9yUQ==, + } + engines: { node: ">=18" } + hasBin: true + + escalade@3.2.0: + resolution: + { + integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==, + } + engines: { node: ">=6" } + + escape-string-regexp@4.0.0: + resolution: + { + integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==, + } + engines: { node: ">=10" } + + eslint-plugin-react-hooks@5.2.0: + resolution: + { + integrity: sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==, + } + engines: { node: ">=10" } + peerDependencies: + eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 + + eslint-plugin-react-refresh@0.4.20: + resolution: + { + integrity: sha512-XpbHQ2q5gUF8BGOX4dHe+71qoirYMhApEPZ7sfhF/dNnOF1UXnCMGZf79SFTBO7Bz5YEIT4TMieSlJBWhP9WBA==, + } + peerDependencies: + eslint: ">=8.40" + + eslint-scope@8.4.0: + resolution: + { + integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==, + } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + + eslint-visitor-keys@3.4.3: + resolution: + { + integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==, + } + engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 } + + eslint-visitor-keys@4.2.1: + resolution: + { + integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==, + } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + + eslint@9.29.0: + resolution: + { + integrity: sha512-GsGizj2Y1rCWDu6XoEekL3RLilp0voSePurjZIkxL3wlm5o5EC9VpgaP7lrCvjnkuLvzFBQWB3vWB3K5KQTveQ==, + } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + hasBin: true + peerDependencies: + jiti: "*" + peerDependenciesMeta: + jiti: + optional: true + + espree@10.4.0: + resolution: + { + integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==, + } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + + esquery@1.6.0: + resolution: + { + integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==, + } + engines: { node: ">=0.10" } + + esrecurse@4.3.0: + resolution: + { + integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==, + } + engines: { node: ">=4.0" } + + estraverse@5.3.0: + resolution: + { + integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==, + } + engines: { node: ">=4.0" } + + esutils@2.0.3: + resolution: + { + integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==, + } + engines: { node: ">=0.10.0" } + + fast-deep-equal@3.1.3: + resolution: + { + integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==, + } + + fast-json-stable-stringify@2.1.0: + resolution: + { + integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==, + } + + fast-levenshtein@2.0.6: + resolution: + { + integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==, + } + + fdir@6.4.6: + resolution: + { + integrity: sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==, + } + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + file-entry-cache@8.0.0: + resolution: + { + integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==, + } + engines: { node: ">=16.0.0" } + + find-up@5.0.0: + resolution: + { + integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==, + } + engines: { node: ">=10" } + + flat-cache@4.0.1: + resolution: + { + integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==, + } + engines: { node: ">=16" } + + flatted@3.3.3: + resolution: + { + integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==, + } + + fsevents@2.3.3: + resolution: + { + integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==, + } + engines: { node: ^8.16.0 || ^10.6.0 || >=11.0.0 } + os: [darwin] + + gensync@1.0.0-beta.2: + resolution: + { + integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==, + } + engines: { node: ">=6.9.0" } + + glob-parent@6.0.2: + resolution: + { + integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==, + } + engines: { node: ">=10.13.0" } + + globals@11.12.0: + resolution: + { + integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==, + } + engines: { node: ">=4" } + + globals@14.0.0: + resolution: + { + integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==, + } + engines: { node: ">=18" } + + globals@16.2.0: + resolution: + { + integrity: sha512-O+7l9tPdHCU320IigZZPj5zmRCFG9xHmx9cU8FqU2Rp+JN714seHV+2S9+JslCpY4gJwU2vOGox0wzgae/MCEg==, + } + engines: { node: ">=18" } + + has-flag@4.0.0: + resolution: + { + integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==, + } + engines: { node: ">=8" } + + ignore@5.3.2: + resolution: + { + integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==, + } + engines: { node: ">= 4" } + + import-fresh@3.3.1: + resolution: + { + integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==, + } + engines: { node: ">=6" } + + imurmurhash@0.1.4: + resolution: + { + integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==, + } + engines: { node: ">=0.8.19" } + + is-extglob@2.1.1: + resolution: + { + integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==, + } + engines: { node: ">=0.10.0" } + + is-glob@4.0.3: + resolution: + { + integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==, + } + engines: { node: ">=0.10.0" } + + isexe@2.0.0: + resolution: + { + integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==, + } + + js-tokens@4.0.0: + resolution: + { + integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==, + } + + js-yaml@4.1.0: + resolution: + { + integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==, + } + hasBin: true + + jsesc@3.1.0: + resolution: + { + integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==, + } + engines: { node: ">=6" } + hasBin: true + + json-buffer@3.0.1: + resolution: + { + integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==, + } + + json-schema-traverse@0.4.1: + resolution: + { + integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==, + } + + json-stable-stringify-without-jsonify@1.0.1: + resolution: + { + integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==, + } + + json5@2.2.3: + resolution: + { + integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==, + } + engines: { node: ">=6" } + hasBin: true + + keyv@4.5.4: + resolution: + { + integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==, + } + + levn@0.4.1: + resolution: + { + integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==, + } + engines: { node: ">= 0.8.0" } + + locate-path@6.0.0: + resolution: + { + integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==, + } + engines: { node: ">=10" } + + lodash.merge@4.6.2: + resolution: + { + integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==, + } + + lru-cache@5.1.1: + resolution: + { + integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==, + } + + minimatch@3.1.2: + resolution: + { + integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==, + } + + ms@2.1.3: + resolution: + { + integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==, + } + + nanoid@3.3.11: + resolution: + { + integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==, + } + engines: { node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1 } + hasBin: true + + natural-compare@1.4.0: + resolution: + { + integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==, + } + + node-releases@2.0.19: + resolution: + { + integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==, + } + + optionator@0.9.4: + resolution: + { + integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==, + } + engines: { node: ">= 0.8.0" } + + p-limit@3.1.0: + resolution: + { + integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==, + } + engines: { node: ">=10" } + + p-locate@5.0.0: + resolution: + { + integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==, + } + engines: { node: ">=10" } + + parent-module@1.0.1: + resolution: + { + integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==, + } + engines: { node: ">=6" } + + path-exists@4.0.0: + resolution: + { + integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==, + } + engines: { node: ">=8" } + + path-key@3.1.1: + resolution: + { + integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==, + } + engines: { node: ">=8" } + + picocolors@1.1.1: + resolution: + { + integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==, + } + + picomatch@4.0.2: + resolution: + { + integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==, + } + engines: { node: ">=12" } + + postcss@8.5.5: + resolution: + { + integrity: sha512-d/jtm+rdNT8tpXuHY5MMtcbJFBkhXE6593XVR9UoGCH8jSFGci7jGvMGH5RYd5PBJW+00NZQt6gf7CbagJCrhg==, + } + engines: { node: ^10 || ^12 || >=14 } + + prelude-ls@1.2.1: + resolution: + { + integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==, + } + engines: { node: ">= 0.8.0" } + + prettier@3.6.2: + resolution: + { + integrity: sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==, + } + engines: { node: ">=14" } + hasBin: true + + punycode@2.3.1: + resolution: + { + integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==, + } + engines: { node: ">=6" } + + react-dom@19.1.0: + resolution: + { + integrity: sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==, + } + peerDependencies: + react: ^19.1.0 + + react-refresh@0.17.0: + resolution: + { + integrity: sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==, + } + engines: { node: ">=0.10.0" } + + react-router-dom@7.6.2: + resolution: + { + integrity: sha512-Q8zb6VlTbdYKK5JJBLQEN06oTUa/RAbG/oQS1auK1I0TbJOXktqm+QENEVJU6QvWynlXPRBXI3fiOQcSEA78rA==, + } + engines: { node: ">=20.0.0" } + peerDependencies: + react: ">=18" + react-dom: ">=18" + + react-router@7.6.2: + resolution: + { + integrity: sha512-U7Nv3y+bMimgWjhlT5CRdzHPu2/KVmqPwKUCChW8en5P3znxUqwlYFlbmyj8Rgp1SF6zs5X4+77kBVknkg6a0w==, + } + engines: { node: ">=20.0.0" } + peerDependencies: + react: ">=18" + react-dom: ">=18" + peerDependenciesMeta: + react-dom: + optional: true + + react-spinners@0.17.0: + resolution: + { + integrity: sha512-L/8HTylaBmIWwQzIjMq+0vyaRXuoAevzWoD35wKpNTxxtYXWZp+xtgkfD7Y4WItuX0YvdxMPU79+7VhhmbmuTQ==, + } + peerDependencies: + react: ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + react@19.1.0: + resolution: + { + integrity: sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==, + } + engines: { node: ">=0.10.0" } + + resolve-from@4.0.0: + resolution: + { + integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==, + } + engines: { node: ">=4" } + + rollup@4.43.0: + resolution: + { + integrity: sha512-wdN2Kd3Twh8MAEOEJZsuxuLKCsBEo4PVNLK6tQWAn10VhsVewQLzcucMgLolRlhFybGxfclbPeEYBaP6RvUFGg==, + } + engines: { node: ">=18.0.0", npm: ">=8.0.0" } + hasBin: true + + scheduler@0.26.0: + resolution: + { + integrity: sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==, + } + + semver@6.3.1: + resolution: + { + integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==, + } + hasBin: true + + set-cookie-parser@2.7.1: + resolution: + { + integrity: sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==, + } + + shebang-command@2.0.0: + resolution: + { + integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==, + } + engines: { node: ">=8" } + + shebang-regex@3.0.0: + resolution: + { + integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==, + } + engines: { node: ">=8" } + + source-map-js@1.2.1: + resolution: + { + integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==, + } + engines: { node: ">=0.10.0" } + + strip-json-comments@3.1.1: + resolution: + { + integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==, + } + engines: { node: ">=8" } + + supports-color@7.2.0: + resolution: + { + integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==, + } + engines: { node: ">=8" } + + tinyglobby@0.2.14: + resolution: + { + integrity: sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==, + } + engines: { node: ">=12.0.0" } + + type-check@0.4.0: + resolution: + { + integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==, + } + engines: { node: ">= 0.8.0" } + + update-browserslist-db@1.1.3: + resolution: + { + integrity: sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==, + } + hasBin: true + peerDependencies: + browserslist: ">= 4.21.0" + + uri-js@4.4.1: + resolution: + { + integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==, + } + + vite@6.3.5: + resolution: + { + integrity: sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==, + } + engines: { node: ^18.0.0 || ^20.0.0 || >=22.0.0 } + hasBin: true + peerDependencies: + "@types/node": ^18.0.0 || ^20.0.0 || >=22.0.0 + jiti: ">=1.21.0" + less: "*" + lightningcss: ^1.21.0 + sass: "*" + sass-embedded: "*" + stylus: "*" + sugarss: "*" + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + "@types/node": + optional: true + jiti: + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + + which@2.0.2: + resolution: + { + integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==, + } + engines: { node: ">= 8" } + hasBin: true + + word-wrap@1.2.5: + resolution: + { + integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==, + } + engines: { node: ">=0.10.0" } + + yallist@3.1.1: + resolution: + { + integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==, + } + + yocto-queue@0.1.0: + resolution: + { + integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==, + } + engines: { node: ">=10" } + +snapshots: + "@ampproject/remapping@2.3.0": + dependencies: + "@jridgewell/gen-mapping": 0.3.8 + "@jridgewell/trace-mapping": 0.3.25 + + "@babel/code-frame@7.27.1": + dependencies: + "@babel/helper-validator-identifier": 7.27.1 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + "@babel/compat-data@7.27.5": {} + + "@babel/core@7.27.4": + dependencies: + "@ampproject/remapping": 2.3.0 + "@babel/code-frame": 7.27.1 + "@babel/generator": 7.27.5 + "@babel/helper-compilation-targets": 7.27.2 + "@babel/helper-module-transforms": 7.27.3(@babel/core@7.27.4) + "@babel/helpers": 7.27.6 + "@babel/parser": 7.27.5 + "@babel/template": 7.27.2 + "@babel/traverse": 7.27.4 + "@babel/types": 7.27.6 + convert-source-map: 2.0.0 + debug: 4.4.1 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + "@babel/generator@7.27.5": + dependencies: + "@babel/parser": 7.27.5 + "@babel/types": 7.27.6 + "@jridgewell/gen-mapping": 0.3.8 + "@jridgewell/trace-mapping": 0.3.25 + jsesc: 3.1.0 + + "@babel/helper-compilation-targets@7.27.2": + dependencies: + "@babel/compat-data": 7.27.5 + "@babel/helper-validator-option": 7.27.1 + browserslist: 4.25.0 + lru-cache: 5.1.1 + semver: 6.3.1 + + "@babel/helper-module-imports@7.27.1": + dependencies: + "@babel/traverse": 7.27.4 + "@babel/types": 7.27.6 + transitivePeerDependencies: + - supports-color + + "@babel/helper-module-transforms@7.27.3(@babel/core@7.27.4)": + dependencies: + "@babel/core": 7.27.4 + "@babel/helper-module-imports": 7.27.1 + "@babel/helper-validator-identifier": 7.27.1 + "@babel/traverse": 7.27.4 + transitivePeerDependencies: + - supports-color + + "@babel/helper-plugin-utils@7.27.1": {} + + "@babel/helper-string-parser@7.27.1": {} + + "@babel/helper-validator-identifier@7.27.1": {} + + "@babel/helper-validator-option@7.27.1": {} + + "@babel/helpers@7.27.6": + dependencies: + "@babel/template": 7.27.2 + "@babel/types": 7.27.6 + + "@babel/parser@7.27.5": + dependencies: + "@babel/types": 7.27.6 + + "@babel/plugin-transform-react-jsx-self@7.27.1(@babel/core@7.27.4)": + dependencies: + "@babel/core": 7.27.4 + "@babel/helper-plugin-utils": 7.27.1 + + "@babel/plugin-transform-react-jsx-source@7.27.1(@babel/core@7.27.4)": + dependencies: + "@babel/core": 7.27.4 + "@babel/helper-plugin-utils": 7.27.1 + + "@babel/template@7.27.2": + dependencies: + "@babel/code-frame": 7.27.1 + "@babel/parser": 7.27.5 + "@babel/types": 7.27.6 + + "@babel/traverse@7.27.4": + dependencies: + "@babel/code-frame": 7.27.1 + "@babel/generator": 7.27.5 + "@babel/parser": 7.27.5 + "@babel/template": 7.27.2 + "@babel/types": 7.27.6 + debug: 4.4.1 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + + "@babel/types@7.27.6": + dependencies: + "@babel/helper-string-parser": 7.27.1 + "@babel/helper-validator-identifier": 7.27.1 + + "@esbuild/aix-ppc64@0.25.5": + optional: true + + "@esbuild/android-arm64@0.25.5": + optional: true + + "@esbuild/android-arm@0.25.5": + optional: true + + "@esbuild/android-x64@0.25.5": + optional: true + + "@esbuild/darwin-arm64@0.25.5": + optional: true + + "@esbuild/darwin-x64@0.25.5": + optional: true + + "@esbuild/freebsd-arm64@0.25.5": + optional: true + + "@esbuild/freebsd-x64@0.25.5": + optional: true + + "@esbuild/linux-arm64@0.25.5": + optional: true + + "@esbuild/linux-arm@0.25.5": + optional: true + + "@esbuild/linux-ia32@0.25.5": + optional: true + + "@esbuild/linux-loong64@0.25.5": + optional: true + + "@esbuild/linux-mips64el@0.25.5": + optional: true + + "@esbuild/linux-ppc64@0.25.5": + optional: true + + "@esbuild/linux-riscv64@0.25.5": + optional: true + + "@esbuild/linux-s390x@0.25.5": + optional: true + + "@esbuild/linux-x64@0.25.5": + optional: true + + "@esbuild/netbsd-arm64@0.25.5": + optional: true + + "@esbuild/netbsd-x64@0.25.5": + optional: true + + "@esbuild/openbsd-arm64@0.25.5": + optional: true + + "@esbuild/openbsd-x64@0.25.5": + optional: true + + "@esbuild/sunos-x64@0.25.5": + optional: true + + "@esbuild/win32-arm64@0.25.5": + optional: true + + "@esbuild/win32-ia32@0.25.5": + optional: true + + "@esbuild/win32-x64@0.25.5": + optional: true + + "@eslint-community/eslint-utils@4.7.0(eslint@9.29.0)": + dependencies: + eslint: 9.29.0 + eslint-visitor-keys: 3.4.3 + + "@eslint-community/regexpp@4.12.1": {} + + "@eslint/config-array@0.20.1": + dependencies: + "@eslint/object-schema": 2.1.6 + debug: 4.4.1 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + + "@eslint/config-helpers@0.2.3": {} + + "@eslint/core@0.14.0": + dependencies: + "@types/json-schema": 7.0.15 + + "@eslint/core@0.15.0": + dependencies: + "@types/json-schema": 7.0.15 + + "@eslint/eslintrc@3.3.1": + dependencies: + ajv: 6.12.6 + debug: 4.4.1 + espree: 10.4.0 + globals: 14.0.0 + ignore: 5.3.2 + import-fresh: 3.3.1 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + "@eslint/js@9.29.0": {} + + "@eslint/object-schema@2.1.6": {} + + "@eslint/plugin-kit@0.3.2": + dependencies: + "@eslint/core": 0.15.0 + levn: 0.4.1 + + "@humanfs/core@0.19.1": {} + + "@humanfs/node@0.16.6": + dependencies: + "@humanfs/core": 0.19.1 + "@humanwhocodes/retry": 0.3.1 + + "@humanwhocodes/module-importer@1.0.1": {} + + "@humanwhocodes/retry@0.3.1": {} + + "@humanwhocodes/retry@0.4.3": {} + + "@jridgewell/gen-mapping@0.3.8": + dependencies: + "@jridgewell/set-array": 1.2.1 + "@jridgewell/sourcemap-codec": 1.5.0 + "@jridgewell/trace-mapping": 0.3.25 + + "@jridgewell/resolve-uri@3.1.2": {} + + "@jridgewell/set-array@1.2.1": {} + + "@jridgewell/sourcemap-codec@1.5.0": {} + + "@jridgewell/trace-mapping@0.3.25": + dependencies: + "@jridgewell/resolve-uri": 3.1.2 + "@jridgewell/sourcemap-codec": 1.5.0 + + "@rolldown/pluginutils@1.0.0-beta.11": {} + + "@rollup/rollup-android-arm-eabi@4.43.0": + optional: true + + "@rollup/rollup-android-arm64@4.43.0": + optional: true + + "@rollup/rollup-darwin-arm64@4.43.0": + optional: true + + "@rollup/rollup-darwin-x64@4.43.0": + optional: true + + "@rollup/rollup-freebsd-arm64@4.43.0": + optional: true + + "@rollup/rollup-freebsd-x64@4.43.0": + optional: true + + "@rollup/rollup-linux-arm-gnueabihf@4.43.0": + optional: true + + "@rollup/rollup-linux-arm-musleabihf@4.43.0": + optional: true + + "@rollup/rollup-linux-arm64-gnu@4.43.0": + optional: true + + "@rollup/rollup-linux-arm64-musl@4.43.0": + optional: true + + "@rollup/rollup-linux-loongarch64-gnu@4.43.0": + optional: true + + "@rollup/rollup-linux-powerpc64le-gnu@4.43.0": + optional: true + + "@rollup/rollup-linux-riscv64-gnu@4.43.0": + optional: true + + "@rollup/rollup-linux-riscv64-musl@4.43.0": + optional: true + + "@rollup/rollup-linux-s390x-gnu@4.43.0": + optional: true + + "@rollup/rollup-linux-x64-gnu@4.43.0": + optional: true + + "@rollup/rollup-linux-x64-musl@4.43.0": + optional: true + + "@rollup/rollup-win32-arm64-msvc@4.43.0": + optional: true + + "@rollup/rollup-win32-ia32-msvc@4.43.0": + optional: true + + "@rollup/rollup-win32-x64-msvc@4.43.0": + optional: true + + "@types/babel__core@7.20.5": + dependencies: + "@babel/parser": 7.27.5 + "@babel/types": 7.27.6 + "@types/babel__generator": 7.27.0 + "@types/babel__template": 7.4.4 + "@types/babel__traverse": 7.20.7 + + "@types/babel__generator@7.27.0": + dependencies: + "@babel/types": 7.27.6 + + "@types/babel__template@7.4.4": + dependencies: + "@babel/parser": 7.27.5 + "@babel/types": 7.27.6 + + "@types/babel__traverse@7.20.7": + dependencies: + "@babel/types": 7.27.6 + + "@types/estree@1.0.7": {} + + "@types/estree@1.0.8": {} + + "@types/json-schema@7.0.15": {} + + "@types/react-dom@19.1.6(@types/react@19.1.8)": + dependencies: + "@types/react": 19.1.8 + + "@types/react@19.1.8": + dependencies: + csstype: 3.1.3 + + "@vitejs/plugin-react@4.5.2(vite@6.3.5)": + dependencies: + "@babel/core": 7.27.4 + "@babel/plugin-transform-react-jsx-self": 7.27.1(@babel/core@7.27.4) + "@babel/plugin-transform-react-jsx-source": 7.27.1(@babel/core@7.27.4) + "@rolldown/pluginutils": 1.0.0-beta.11 + "@types/babel__core": 7.20.5 + react-refresh: 0.17.0 + vite: 6.3.5 + transitivePeerDependencies: + - supports-color + + acorn-jsx@5.3.2(acorn@8.15.0): + dependencies: + acorn: 8.15.0 + + acorn@8.15.0: {} + + ajv@6.12.6: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + argparse@2.0.1: {} + + balanced-match@1.0.2: {} + + brace-expansion@1.1.12: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + browserslist@4.25.0: + dependencies: + caniuse-lite: 1.0.30001723 + electron-to-chromium: 1.5.167 + node-releases: 2.0.19 + update-browserslist-db: 1.1.3(browserslist@4.25.0) + + callsites@3.1.0: {} + + caniuse-lite@1.0.30001723: {} + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + concat-map@0.0.1: {} + + convert-source-map@2.0.0: {} + + cookie@1.0.2: {} + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + csstype@3.1.3: {} + + debug@4.4.1: + dependencies: + ms: 2.1.3 + + deep-is@0.1.4: {} + + electron-to-chromium@1.5.167: {} + + esbuild@0.25.5: + optionalDependencies: + "@esbuild/aix-ppc64": 0.25.5 + "@esbuild/android-arm": 0.25.5 + "@esbuild/android-arm64": 0.25.5 + "@esbuild/android-x64": 0.25.5 + "@esbuild/darwin-arm64": 0.25.5 + "@esbuild/darwin-x64": 0.25.5 + "@esbuild/freebsd-arm64": 0.25.5 + "@esbuild/freebsd-x64": 0.25.5 + "@esbuild/linux-arm": 0.25.5 + "@esbuild/linux-arm64": 0.25.5 + "@esbuild/linux-ia32": 0.25.5 + "@esbuild/linux-loong64": 0.25.5 + "@esbuild/linux-mips64el": 0.25.5 + "@esbuild/linux-ppc64": 0.25.5 + "@esbuild/linux-riscv64": 0.25.5 + "@esbuild/linux-s390x": 0.25.5 + "@esbuild/linux-x64": 0.25.5 + "@esbuild/netbsd-arm64": 0.25.5 + "@esbuild/netbsd-x64": 0.25.5 + "@esbuild/openbsd-arm64": 0.25.5 + "@esbuild/openbsd-x64": 0.25.5 + "@esbuild/sunos-x64": 0.25.5 + "@esbuild/win32-arm64": 0.25.5 + "@esbuild/win32-ia32": 0.25.5 + "@esbuild/win32-x64": 0.25.5 + + escalade@3.2.0: {} + + escape-string-regexp@4.0.0: {} + + eslint-plugin-react-hooks@5.2.0(eslint@9.29.0): + dependencies: + eslint: 9.29.0 + + eslint-plugin-react-refresh@0.4.20(eslint@9.29.0): + dependencies: + eslint: 9.29.0 + + eslint-scope@8.4.0: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-visitor-keys@3.4.3: {} + + eslint-visitor-keys@4.2.1: {} + + eslint@9.29.0: + dependencies: + "@eslint-community/eslint-utils": 4.7.0(eslint@9.29.0) + "@eslint-community/regexpp": 4.12.1 + "@eslint/config-array": 0.20.1 + "@eslint/config-helpers": 0.2.3 + "@eslint/core": 0.14.0 + "@eslint/eslintrc": 3.3.1 + "@eslint/js": 9.29.0 + "@eslint/plugin-kit": 0.3.2 + "@humanfs/node": 0.16.6 + "@humanwhocodes/module-importer": 1.0.1 + "@humanwhocodes/retry": 0.4.3 + "@types/estree": 1.0.8 + "@types/json-schema": 7.0.15 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.6 + debug: 4.4.1 + escape-string-regexp: 4.0.0 + eslint-scope: 8.4.0 + eslint-visitor-keys: 4.2.1 + espree: 10.4.0 + esquery: 1.6.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 8.0.0 + find-up: 5.0.0 + glob-parent: 6.0.2 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + json-stable-stringify-without-jsonify: 1.0.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.4 + transitivePeerDependencies: + - supports-color + + espree@10.4.0: + dependencies: + acorn: 8.15.0 + acorn-jsx: 5.3.2(acorn@8.15.0) + eslint-visitor-keys: 4.2.1 + + esquery@1.6.0: + dependencies: + estraverse: 5.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@5.3.0: {} + + esutils@2.0.3: {} + + fast-deep-equal@3.1.3: {} + + fast-json-stable-stringify@2.1.0: {} + + fast-levenshtein@2.0.6: {} + + fdir@6.4.6(picomatch@4.0.2): + optionalDependencies: + picomatch: 4.0.2 + + file-entry-cache@8.0.0: + dependencies: + flat-cache: 4.0.1 + + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + flat-cache@4.0.1: + dependencies: + flatted: 3.3.3 + keyv: 4.5.4 + + flatted@3.3.3: {} + + fsevents@2.3.3: + optional: true + + gensync@1.0.0-beta.2: {} + + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + + globals@11.12.0: {} + + globals@14.0.0: {} + + globals@16.2.0: {} + + has-flag@4.0.0: {} + + ignore@5.3.2: {} + + import-fresh@3.3.1: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + imurmurhash@0.1.4: {} + + is-extglob@2.1.1: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + isexe@2.0.0: {} + + js-tokens@4.0.0: {} + + js-yaml@4.1.0: + dependencies: + argparse: 2.0.1 + + jsesc@3.1.0: {} + + json-buffer@3.0.1: {} + + json-schema-traverse@0.4.1: {} + + json-stable-stringify-without-jsonify@1.0.1: {} + + json5@2.2.3: {} + + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + + levn@0.4.1: + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + lodash.merge@4.6.2: {} + + lru-cache@5.1.1: + dependencies: + yallist: 3.1.1 + + minimatch@3.1.2: + dependencies: + brace-expansion: 1.1.12 + + ms@2.1.3: {} + + nanoid@3.3.11: {} + + natural-compare@1.4.0: {} + + node-releases@2.0.19: {} + + optionator@0.9.4: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.5 + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + + path-exists@4.0.0: {} + + path-key@3.1.1: {} + + picocolors@1.1.1: {} + + picomatch@4.0.2: {} + + postcss@8.5.5: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + prelude-ls@1.2.1: {} + + prettier@3.6.2: {} + + punycode@2.3.1: {} + + react-dom@19.1.0(react@19.1.0): + dependencies: + react: 19.1.0 + scheduler: 0.26.0 + + react-refresh@0.17.0: {} + + react-router-dom@7.6.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0): + dependencies: + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + react-router: 7.6.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + + react-router@7.6.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0): + dependencies: + cookie: 1.0.2 + react: 19.1.0 + set-cookie-parser: 2.7.1 + optionalDependencies: + react-dom: 19.1.0(react@19.1.0) + + react-spinners@0.17.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0): + dependencies: + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + + react@19.1.0: {} + + resolve-from@4.0.0: {} + + rollup@4.43.0: + dependencies: + "@types/estree": 1.0.7 + optionalDependencies: + "@rollup/rollup-android-arm-eabi": 4.43.0 + "@rollup/rollup-android-arm64": 4.43.0 + "@rollup/rollup-darwin-arm64": 4.43.0 + "@rollup/rollup-darwin-x64": 4.43.0 + "@rollup/rollup-freebsd-arm64": 4.43.0 + "@rollup/rollup-freebsd-x64": 4.43.0 + "@rollup/rollup-linux-arm-gnueabihf": 4.43.0 + "@rollup/rollup-linux-arm-musleabihf": 4.43.0 + "@rollup/rollup-linux-arm64-gnu": 4.43.0 + "@rollup/rollup-linux-arm64-musl": 4.43.0 + "@rollup/rollup-linux-loongarch64-gnu": 4.43.0 + "@rollup/rollup-linux-powerpc64le-gnu": 4.43.0 + "@rollup/rollup-linux-riscv64-gnu": 4.43.0 + "@rollup/rollup-linux-riscv64-musl": 4.43.0 + "@rollup/rollup-linux-s390x-gnu": 4.43.0 + "@rollup/rollup-linux-x64-gnu": 4.43.0 + "@rollup/rollup-linux-x64-musl": 4.43.0 + "@rollup/rollup-win32-arm64-msvc": 4.43.0 + "@rollup/rollup-win32-ia32-msvc": 4.43.0 + "@rollup/rollup-win32-x64-msvc": 4.43.0 + fsevents: 2.3.3 + + scheduler@0.26.0: {} + + semver@6.3.1: {} + + set-cookie-parser@2.7.1: {} + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + source-map-js@1.2.1: {} + + strip-json-comments@3.1.1: {} + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + tinyglobby@0.2.14: + dependencies: + fdir: 6.4.6(picomatch@4.0.2) + picomatch: 4.0.2 + + type-check@0.4.0: + dependencies: + prelude-ls: 1.2.1 + + update-browserslist-db@1.1.3(browserslist@4.25.0): + dependencies: + browserslist: 4.25.0 + escalade: 3.2.0 + picocolors: 1.1.1 + + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + + vite@6.3.5: + dependencies: + esbuild: 0.25.5 + fdir: 6.4.6(picomatch@4.0.2) + picomatch: 4.0.2 + postcss: 8.5.5 + rollup: 4.43.0 + tinyglobby: 0.2.14 + optionalDependencies: + fsevents: 2.3.3 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + word-wrap@1.2.5: {} + + yallist@3.1.1: {} + + yocto-queue@0.1.0: {} diff --git a/week3/project/e-commerce/public/favicon/android-chrome-192x192.png b/week3/project/e-commerce/public/favicon/android-chrome-192x192.png new file mode 100644 index 0000000000..c3532e8995 Binary files /dev/null and b/week3/project/e-commerce/public/favicon/android-chrome-192x192.png differ diff --git a/week3/project/e-commerce/public/favicon/android-chrome-512x512.png b/week3/project/e-commerce/public/favicon/android-chrome-512x512.png new file mode 100644 index 0000000000..7ba4f2477c Binary files /dev/null and b/week3/project/e-commerce/public/favicon/android-chrome-512x512.png differ diff --git a/week3/project/e-commerce/public/favicon/apple-touch-icon.png b/week3/project/e-commerce/public/favicon/apple-touch-icon.png new file mode 100644 index 0000000000..96a39062fc Binary files /dev/null and b/week3/project/e-commerce/public/favicon/apple-touch-icon.png differ diff --git a/week3/project/e-commerce/public/favicon/favicon-16x16.png b/week3/project/e-commerce/public/favicon/favicon-16x16.png new file mode 100644 index 0000000000..dd5e5171a6 Binary files /dev/null and b/week3/project/e-commerce/public/favicon/favicon-16x16.png differ diff --git a/week3/project/e-commerce/public/favicon/favicon-32x32.png b/week3/project/e-commerce/public/favicon/favicon-32x32.png new file mode 100644 index 0000000000..3d888b1fb5 Binary files /dev/null and b/week3/project/e-commerce/public/favicon/favicon-32x32.png differ diff --git a/week3/project/e-commerce/public/favicon/favicon.ico b/week3/project/e-commerce/public/favicon/favicon.ico new file mode 100644 index 0000000000..7260fc58f4 Binary files /dev/null and b/week3/project/e-commerce/public/favicon/favicon.ico differ diff --git a/week3/project/e-commerce/public/favicon/site.webmanifest b/week3/project/e-commerce/public/favicon/site.webmanifest new file mode 100644 index 0000000000..fa99de77db --- /dev/null +++ b/week3/project/e-commerce/public/favicon/site.webmanifest @@ -0,0 +1,19 @@ +{ + "name": "", + "short_name": "", + "icons": [ + { + "src": "/android-chrome-192x192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "/android-chrome-512x512.png", + "sizes": "512x512", + "type": "image/png" + } + ], + "theme_color": "#ffffff", + "background_color": "#ffffff", + "display": "standalone" +} diff --git a/week3/project/assets/heart-regular.svg b/week3/project/e-commerce/src/assets/heart-regular.svg similarity index 100% rename from week3/project/assets/heart-regular.svg rename to week3/project/e-commerce/src/assets/heart-regular.svg diff --git a/week3/project/assets/heart-solid.svg b/week3/project/e-commerce/src/assets/heart-solid.svg similarity index 100% rename from week3/project/assets/heart-solid.svg rename to week3/project/e-commerce/src/assets/heart-solid.svg diff --git a/week3/project/e-commerce/src/components/Categories/Categories.jsx b/week3/project/e-commerce/src/components/Categories/Categories.jsx new file mode 100644 index 0000000000..7c18d2794f --- /dev/null +++ b/week3/project/e-commerce/src/components/Categories/Categories.jsx @@ -0,0 +1,34 @@ +import style from "./categories.module.css"; +import Error from "../Error/Error.jsx"; +import useFetch from "../../hooks/useFetch.js"; +import Loading from "../Loading.jsx"; + +function Categories({ selectedCategory, setCategory }) { + const url = "https://fakestoreapi.com/products/categories"; + const { data, loading, error } = useFetch(url); + + if (error) return ; + if (!data || loading) return ; + + return ( +
+
    + {data.map((category) => ( +
  • { + selectedCategory === category + ? setCategory(null) + : setCategory(category); + }} + > + {category} +
  • + ))} +
+
+ ); +} + +export default Categories; diff --git a/week3/project/e-commerce/src/components/Categories/categories.module.css b/week3/project/e-commerce/src/components/Categories/categories.module.css new file mode 100644 index 0000000000..831b7f78cb --- /dev/null +++ b/week3/project/e-commerce/src/components/Categories/categories.module.css @@ -0,0 +1,21 @@ +.categoriesList { + list-style: none; + text-align: center; +} +.categoryLi { + display: inline-block; + cursor: pointer; + padding: 1rem; + margin: 0.5rem; + border-radius: 5px; + border: 1px solid var(--primary); +} +.categoryLi:hover { + background: var(--primary); + color: var(--background); +} +.active { + background: var(--secondary); + color: var(--background); + border: 1px solid transparent; +} diff --git a/week3/project/e-commerce/src/components/Error/Error.jsx b/week3/project/e-commerce/src/components/Error/Error.jsx new file mode 100644 index 0000000000..eba35d6c10 --- /dev/null +++ b/week3/project/e-commerce/src/components/Error/Error.jsx @@ -0,0 +1,14 @@ +import style from "./error.module.css"; + +function Error({ error }) { + return ( +
+
+

ERROR:

+

{error}

+
+
+ ); +} + +export default Error; diff --git a/week3/project/e-commerce/src/components/Error/error.module.css b/week3/project/e-commerce/src/components/Error/error.module.css new file mode 100644 index 0000000000..d20b3b7bc0 --- /dev/null +++ b/week3/project/e-commerce/src/components/Error/error.module.css @@ -0,0 +1,10 @@ +.errorContainer { + background: var(--secondary); + color: var(--background); + padding: 3rem; + border-radius: 5px; +} +.header { + margin-bottom: 4rem; + border-bottom: 1px solid var(--background); +} diff --git a/week3/project/e-commerce/src/components/Loading.jsx b/week3/project/e-commerce/src/components/Loading.jsx new file mode 100644 index 0000000000..c52680eb3a --- /dev/null +++ b/week3/project/e-commerce/src/components/Loading.jsx @@ -0,0 +1,12 @@ +import { ScaleLoader } from "react-spinners"; + +function Loading() { + return ( +
+

Loading...

+ +
+ ); +} + +export default Loading; diff --git a/week3/project/e-commerce/src/components/Navbar.jsx b/week3/project/e-commerce/src/components/Navbar.jsx new file mode 100644 index 0000000000..c763dc613d --- /dev/null +++ b/week3/project/e-commerce/src/components/Navbar.jsx @@ -0,0 +1,21 @@ +import { Link } from "react-router-dom"; + +function Navbar() { + return ( + + ); +} + +export default Navbar; diff --git a/week3/project/e-commerce/src/components/ProductCard/ProductCard.jsx b/week3/project/e-commerce/src/components/ProductCard/ProductCard.jsx new file mode 100644 index 0000000000..a12c2724b4 --- /dev/null +++ b/week3/project/e-commerce/src/components/ProductCard/ProductCard.jsx @@ -0,0 +1,17 @@ +import style from "./productPage.module.css"; + +function ProductCard({ product }) { + const { title, image, price, description } = product; + + return ( +
+ {title} +
+

{price} EUR

+

{description}

+
+
+ ); +} + +export default ProductCard; diff --git a/week3/project/e-commerce/src/components/ProductCard/productPage.module.css b/week3/project/e-commerce/src/components/ProductCard/productPage.module.css new file mode 100644 index 0000000000..8011d45caf --- /dev/null +++ b/week3/project/e-commerce/src/components/ProductCard/productPage.module.css @@ -0,0 +1,45 @@ +.productCard { + display: flex; + justify-content: space-evenly; + padding: 1rem; + margin-top: 3rem; + max-width: 100vw; +} +.image { + width: 50vw; + max-width: 70rem; + max-height: 60vh; + height: auto; + object-fit: contain; + display: block; +} +.productInfo { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + padding: 1rem; + max-width: 70rem; +} +.price { + background: var(--primary); + color: var(--background); + padding: 1rem; + border-radius: 5px; + margin: 3rem; +} + +@media (max-width: 800px) { + .productCard { + flex-direction: column; + } + h3 { + font-size: 2rem; + } + .productCard { + align-items: center; + } + .image { + max-width: 100%; + } +} diff --git a/week3/project/e-commerce/src/components/ProductList.jsx b/week3/project/e-commerce/src/components/ProductList.jsx new file mode 100644 index 0000000000..460bba4fa9 --- /dev/null +++ b/week3/project/e-commerce/src/components/ProductList.jsx @@ -0,0 +1,13 @@ +import Product from "./Products/Product.jsx"; + +function ProductList({ products }) { + return ( + + ); +} + +export default ProductList; diff --git a/week3/project/e-commerce/src/components/Products/Product.jsx b/week3/project/e-commerce/src/components/Products/Product.jsx new file mode 100644 index 0000000000..e8e85d840f --- /dev/null +++ b/week3/project/e-commerce/src/components/Products/Product.jsx @@ -0,0 +1,36 @@ +import style from "./products.module.css"; +import heartRegular from "../../assets/heart-regular.svg"; +import heartSolid from "../../assets/heart-solid.svg"; +import { Link } from "react-router-dom"; +import { useContext } from "react"; +import { FavouriteContext } from "../../context/favouriteContext.jsx"; + +function Product({ id, image, title }) { + const { favourite, setFavourite } = useContext(FavouriteContext); + + const heart = favourite.includes(id) ? heartSolid : heartRegular; + + const changeFavourite = () => + setFavourite( + favourite.includes(id) + ? favourite.filter((favID) => favID !== id) + : [...favourite, id], + ); + + return ( +
  • + heart + + {title} + {title} + +
  • + ); +} + +export default Product; diff --git a/week3/project/e-commerce/src/components/Products/Products.jsx b/week3/project/e-commerce/src/components/Products/Products.jsx new file mode 100644 index 0000000000..08e53b24cb --- /dev/null +++ b/week3/project/e-commerce/src/components/Products/Products.jsx @@ -0,0 +1,24 @@ +import style from "./products.module.css"; +import Product from "./Product.jsx"; +import Loading from "../Loading.jsx"; +import Error from "../Error/Error.jsx"; +import ProductList from "../ProductList.jsx"; +import useFetch from "../../hooks/useFetch.js"; + +function Products({ selectedCategory }) { + const url = !selectedCategory + ? "https://fakestoreapi.com/products" + : `https://fakestoreapi.com/products/category/${selectedCategory}`; + const { data, loading, error } = useFetch(url); + + if (error) return ; + if (!data || loading) return ; + + return ( +
    + +
    + ); +} + +export default Products; diff --git a/week3/project/e-commerce/src/components/Products/products.module.css b/week3/project/e-commerce/src/components/Products/products.module.css new file mode 100644 index 0000000000..7988fabb67 --- /dev/null +++ b/week3/project/e-commerce/src/components/Products/products.module.css @@ -0,0 +1,29 @@ +.products { + margin-top: 5rem; +} +.product { + display: flex; + flex-wrap: wrap; + width: 100%; + max-width: 40rem; + padding: 1rem; + cursor: pointer; + border: 1px solid rgba(55, 55, 55, 0.15); + border-radius: 5px; +} +.product:hover { + border-radius: 5px; + box-shadow: 0 0 10px rgba(55, 55, 55, 0.5); +} +.image { + width: 100%; + aspect-ratio: 3 / 4; + object-fit: contain; + display: block; + max-height: 50rem; +} +.favorite { + position: absolute; + cursor: pointer; + width: 2.2rem; +} diff --git a/week3/project/e-commerce/src/context/favouriteContext.jsx b/week3/project/e-commerce/src/context/favouriteContext.jsx new file mode 100644 index 0000000000..2e6afc95a4 --- /dev/null +++ b/week3/project/e-commerce/src/context/favouriteContext.jsx @@ -0,0 +1,13 @@ +import { createContext, useState } from "react"; + +export const FavouriteContext = createContext([]); + +export default function FavouriteContextProvider({ children }) { + const [favourite, setFavourite] = useState([]); + + return ( + + {children} + + ); +} diff --git a/week3/project/e-commerce/src/context/statusContext.jsx b/week3/project/e-commerce/src/context/statusContext.jsx new file mode 100644 index 0000000000..a463d4cdca --- /dev/null +++ b/week3/project/e-commerce/src/context/statusContext.jsx @@ -0,0 +1,14 @@ +import { createContext, useState } from "react"; + +export const StatusContext = createContext([]); + +export default function StatusContextProvider({ children }) { + const [loading, setLoading] = useState(false); + const [error, setError] = useState(null); + + return ( + + {children} + + ); +} diff --git a/week3/project/e-commerce/src/hooks/useFetch.js b/week3/project/e-commerce/src/hooks/useFetch.js new file mode 100644 index 0000000000..eaca160dd8 --- /dev/null +++ b/week3/project/e-commerce/src/hooks/useFetch.js @@ -0,0 +1,35 @@ +import { useContext, useEffect, useState } from "react"; +import { StatusContext } from "../context/statusContext.jsx"; + +function useFetch(url) { + const [data, setData] = useState(null); + const { loading, setLoading, error, setError } = useContext(StatusContext); + + useEffect(() => { + setData(null); + setError(null); + setLoading(false); + + setLoading(true); + const fetchData = async () => { + try { + const response = await fetch(url); + if (!response.ok) { + const error = response.statusText || `Error: ${response.status}`; + return setError(error); + } + setData(await response.json()); + } catch (e) { + setError(e.message); + } finally { + setLoading(false); + } + }; + + fetchData(); + }, [url, setLoading, setError]); + + return { data, loading, error }; +} + +export default useFetch; diff --git a/week3/project/e-commerce/src/hooks/useFetchMany.js b/week3/project/e-commerce/src/hooks/useFetchMany.js new file mode 100644 index 0000000000..e860ae25af --- /dev/null +++ b/week3/project/e-commerce/src/hooks/useFetchMany.js @@ -0,0 +1,40 @@ +import { useContext, useEffect, useState } from "react"; +import { StatusContext } from "../context/statusContext.jsx"; + +function useFetchMany(url, array) { + const [data, setData] = useState(null); + const { loading, setLoading, error, setError } = useContext(StatusContext); + + useEffect(() => { + setData(null); + setError(null); + setLoading(false); + + if (!array || array.length === 0) { + setData([]); + return; + } + + setLoading(true); + + const fetchData = async () => { + try { + const productPromises = array.map((id) => fetch(url + id)); + const results = await Promise.all(productPromises); + const promisesArray = results.map((result) => result.json()); + const resultsArray = await Promise.all(promisesArray); + setData(resultsArray); + } catch (e) { + setError(e.message); + } finally { + setLoading(false); + } + }; + + fetchData(); + }, [array, setLoading, setError, url]); + + return { data, loading, error }; +} + +export default useFetchMany; diff --git a/week3/project/e-commerce/src/index.css b/week3/project/e-commerce/src/index.css new file mode 100644 index 0000000000..6613870c3f --- /dev/null +++ b/week3/project/e-commerce/src/index.css @@ -0,0 +1,132 @@ +:root { + --background: #fff; + --primary: #373737; + --secondary: #df473b; +} +html { + font-size: 62.5%; +} +body { + font-family: sans-serif; + background: var(--background); + color: var(--primary); +} +* { + box-sizing: border-box; + margin: 0; + padding: 0; +} +h1 { + font-size: 4.6rem; +} +h3 { + font-size: 3.2rem; +} +li { + font-size: 2.4rem; +} +span, +p { + font-size: 2rem; +} +a { + text-decoration: none; + color: var(--primary); +} +button { + cursor: pointer; + border: none; + background: var(--primary); + color: var(--background); + padding: 0.5rem 1rem; + border-radius: 5px; + margin: 0.5rem; + font-size: 2.1rem; +} +#root { + padding: 1rem; +} + +/* Navbar */ + +.navbar { + display: flex; + justify-content: space-between; + align-items: center; + padding: 2rem; + border-bottom: 1px solid var(--primary); +} +.logo { + font-size: 3.2rem; + border: 1px solid var(--primary); + padding: 0.5rem 2rem; + border-radius: 45px; + cursor: pointer; +} + +/* Title */ + +.title { + text-align: center; + margin: 2rem; +} + +/* Products */ + +.productsList { + list-style: none; + display: grid; + grid-template-columns: repeat(auto-fit, minmax(30rem, 1fr)); + gap: 2rem; +} + +/* ProductPage */ + +.productPage { + display: flex; + flex-direction: column; + padding: 1rem; +} + +/* Loading and error */ + +.loading { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; +} +.error { + position: fixed; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: 1000; + padding: 5rem; +} +.error { + background: var(--background); +} + +/* Media Query */ + +@media (max-width: 800px) { + h1 { + font-size: 3rem; + } + p { + font-size: 1.6rem; + } + .logo { + font-size: 2.4rem; + } + button { + font-size: 1.6rem; + padding: 0.5rem 1rem; + } +} diff --git a/week3/project/e-commerce/src/main.jsx b/week3/project/e-commerce/src/main.jsx new file mode 100644 index 0000000000..66e6e04456 --- /dev/null +++ b/week3/project/e-commerce/src/main.jsx @@ -0,0 +1,27 @@ +import { StrictMode } from "react"; +import { createRoot } from "react-dom/client"; +import { BrowserRouter, Route, Routes } from "react-router-dom"; +import "./index.css"; +import Home from "./pages/Home.jsx"; +import ProductPage from "./pages/ProductPage.jsx"; +import FavouritesPage from "./pages/FavouritesPage.jsx"; +import StatusContextProvider from "./context/statusContext.jsx"; +import FavouriteContextProvider from "./context/favouriteContext.jsx"; +import Navbar from "./components/Navbar.jsx"; + +createRoot(document.getElementById("root")).render( + + + + + + + } /> + } /> + } /> + + + + + , +); diff --git a/week3/project/e-commerce/src/pages/FavouritesPage.jsx b/week3/project/e-commerce/src/pages/FavouritesPage.jsx new file mode 100644 index 0000000000..45fb5ba943 --- /dev/null +++ b/week3/project/e-commerce/src/pages/FavouritesPage.jsx @@ -0,0 +1,27 @@ +import { useContext } from "react"; +import Error from "../components/Error/Error.jsx"; +import Loading from "../components/Loading.jsx"; +import Product from "../components/Products/Product.jsx"; +import { FavouriteContext } from "../context/favouriteContext.jsx"; +import useFetchMany from "../hooks/useFetchMany.js"; +import ProductList from "../components/ProductList.jsx"; + +function FavouritesPage() { + const { favourite } = useContext(FavouriteContext); + + const url = "https://fakestoreapi.com/products/"; + const { data, loading, error } = useFetchMany(url, favourite); + + if (error) return ; + if (!data || loading) return ; + + return ( +
    +

    Favourites

    + {data.length === 0 &&

    You have no favourites

    } + +
    + ); +} + +export default FavouritesPage; diff --git a/week3/project/e-commerce/src/pages/Home.jsx b/week3/project/e-commerce/src/pages/Home.jsx new file mode 100644 index 0000000000..0c49858b7c --- /dev/null +++ b/week3/project/e-commerce/src/pages/Home.jsx @@ -0,0 +1,20 @@ +import Categories from "../components/Categories/Categories.jsx"; +import Products from "../components/Products/Products.jsx"; +import { useState } from "react"; + +function Home() { + const [selectedCategory, setCategory] = useState(null); + + return ( + <> +

    Products

    + + + + ); +} + +export default Home; diff --git a/week3/project/e-commerce/src/pages/ProductPage.jsx b/week3/project/e-commerce/src/pages/ProductPage.jsx new file mode 100644 index 0000000000..f606d029d5 --- /dev/null +++ b/week3/project/e-commerce/src/pages/ProductPage.jsx @@ -0,0 +1,25 @@ +import { useParams } from "react-router-dom"; +import Loading from "../components/Loading.jsx"; +import Error from "../components/Error/Error.jsx"; +import ProductCard from "../components/ProductCard/ProductCard.jsx"; +import style from "../components/ProductCard/productPage.module.css"; +import useFetch from "../hooks/useFetch.js"; + +function ProductPage() { + const { id } = useParams(); + + const url = `https://fakestoreapi.com/products/${id}`; + const { data, loading, error } = useFetch(url); + + if (error) return ; + if (loading || !data) return ; + + return ( +
    +

    {data.title}

    + +
    + ); +} + +export default ProductPage; diff --git a/week3/project/e-commerce/vite.config.js b/week3/project/e-commerce/vite.config.js new file mode 100644 index 0000000000..0e43ae8def --- /dev/null +++ b/week3/project/e-commerce/vite.config.js @@ -0,0 +1,7 @@ +import { defineConfig } from "vite"; +import react from "@vitejs/plugin-react"; + +// https://vite.dev/config/ +export default defineConfig({ + plugins: [react()], +});