├── .env
├── .gitignore
├── README.md
├── eslint.config.js
├── index.html
├── package-lock.json
├── package.json
├── script.md
├── src
├── App.tsx
├── fileManager
│ ├── components
│ │ ├── FileManager.tsx
│ │ ├── FileQuickActions.tsx
│ │ ├── FileThumbnail.tsx
│ │ ├── FilesDataGrid.tsx
│ │ └── UploadProgressCard.tsx
│ ├── hooks
│ │ ├── useFileDeleteMutation.ts
│ │ ├── useFileManagerStore.ts
│ │ ├── useFileUploadMutation.ts
│ │ └── useFilesQuery.ts
│ └── types
│ │ ├── ExtendedFile.ts
│ │ └── FileDataGridRow.ts
├── main.tsx
├── shared
│ ├── confirm
│ │ ├── components
│ │ │ └── ConfirmProvider.tsx
│ │ └── hooks
│ │ │ └── useConfirm.ts
│ ├── httpClient.ts
│ ├── theme.ts
│ ├── ui
│ │ ├── BulkActions.tsx
│ │ ├── ThemeToggle.tsx
│ │ └── Topbar.tsx
│ └── utils.ts
└── vite-env.d.ts
├── tsconfig.app.json
├── tsconfig.app.tsbuildinfo
├── tsconfig.json
├── tsconfig.node.json
├── tsconfig.node.tsbuildinfo
└── vite.config.ts
/.env:
--------------------------------------------------------------------------------
1 | VITE_API_URL=http://localhost:3000
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | dist
12 | dist-ssr
13 | *.local
14 |
15 | # Editor directories and files
16 | .vscode/*
17 | !.vscode/extensions.json
18 | .idea
19 | .DS_Store
20 | *.suo
21 | *.ntvs*
22 | *.njsproj
23 | *.sln
24 | *.sw?
25 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # File Manager Frontend Tutorial
2 |
3 | This is a simple React project powered by Vite 5.
4 |
5 | ## Requirements
6 |
7 | - Node.js (version 18 or higher)
8 | - npm (Node Package Manager)
9 |
10 | ## Setup
11 |
12 | 1. Clone the repository to your local machine.
13 | 2. Install the dependencies using npm:
14 |
15 | ```bash
16 | npm install
17 | ```
18 |
19 | ## Running the Project
20 |
21 | To start the development server, run the following command:
22 |
23 | ```bash
24 | npm run dev
25 | ```
26 |
27 | The server will start and your project will be available at the specified port (default: **localhost:5173**).
28 |
--------------------------------------------------------------------------------
/eslint.config.js:
--------------------------------------------------------------------------------
1 | import js from '@eslint/js'
2 | import globals from 'globals'
3 | import reactHooks from 'eslint-plugin-react-hooks'
4 | import reactRefresh from 'eslint-plugin-react-refresh'
5 | import tseslint from 'typescript-eslint'
6 |
7 | export default tseslint.config(
8 | { ignores: ['dist'] },
9 | {
10 | extends: [js.configs.recommended, ...tseslint.configs.recommended],
11 | files: ['**/*.{ts,tsx}'],
12 | languageOptions: {
13 | ecmaVersion: 2020,
14 | globals: globals.browser,
15 | },
16 | plugins: {
17 | 'react-hooks': reactHooks,
18 | 'react-refresh': reactRefresh,
19 | },
20 | rules: {
21 | ...reactHooks.configs.recommended.rules,
22 | 'react-refresh/only-export-components': [
23 | 'warn',
24 | { allowConstantExport: true },
25 | ],
26 | },
27 | },
28 | )
29 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | File manager
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "frontend",
3 | "version": "0.0.0",
4 | "lockfileVersion": 3,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "frontend",
9 | "version": "0.0.0",
10 | "dependencies": {
11 | "@emotion/react": "^11.13.3",
12 | "@emotion/styled": "^11.13.0",
13 | "@formkit/auto-animate": "^0.8.2",
14 | "@mui/icons-material": "^6.1.1",
15 | "@mui/lab": "^6.0.0-beta.10",
16 | "@mui/material": "^6.1.1",
17 | "@mui/x-data-grid": "^7.18.0",
18 | "@tanstack/react-query": "^5.56.2",
19 | "axios": "^1.7.7",
20 | "react": "^18.3.1",
21 | "react-dom": "^18.3.1",
22 | "react-dropzone": "^14.2.3",
23 | "zustand": "^5.0.0-rc.2"
24 | },
25 | "devDependencies": {
26 | "@eslint/js": "^9.9.0",
27 | "@types/node": "^22.7.3",
28 | "@types/react": "^18.3.3",
29 | "@types/react-dom": "^18.3.0",
30 | "@vitejs/plugin-react-swc": "^3.5.0",
31 | "eslint": "^9.9.0",
32 | "eslint-plugin-react-hooks": "^5.1.0-rc.0",
33 | "eslint-plugin-react-refresh": "^0.4.9",
34 | "globals": "^15.9.0",
35 | "path": "^0.12.7",
36 | "typescript": "^5.5.3",
37 | "typescript-eslint": "^8.0.1",
38 | "vite": "^5.4.1"
39 | }
40 | },
41 | "node_modules/@babel/code-frame": {
42 | "version": "7.24.7",
43 | "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz",
44 | "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==",
45 | "dependencies": {
46 | "@babel/highlight": "^7.24.7",
47 | "picocolors": "^1.0.0"
48 | },
49 | "engines": {
50 | "node": ">=6.9.0"
51 | }
52 | },
53 | "node_modules/@babel/generator": {
54 | "version": "7.25.6",
55 | "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.6.tgz",
56 | "integrity": "sha512-VPC82gr1seXOpkjAAKoLhP50vx4vGNlF4msF64dSFq1P8RfB+QAuJWGHPXXPc8QyfVWwwB/TNNU4+ayZmHNbZw==",
57 | "dependencies": {
58 | "@babel/types": "^7.25.6",
59 | "@jridgewell/gen-mapping": "^0.3.5",
60 | "@jridgewell/trace-mapping": "^0.3.25",
61 | "jsesc": "^2.5.1"
62 | },
63 | "engines": {
64 | "node": ">=6.9.0"
65 | }
66 | },
67 | "node_modules/@babel/helper-module-imports": {
68 | "version": "7.24.7",
69 | "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz",
70 | "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==",
71 | "dependencies": {
72 | "@babel/traverse": "^7.24.7",
73 | "@babel/types": "^7.24.7"
74 | },
75 | "engines": {
76 | "node": ">=6.9.0"
77 | }
78 | },
79 | "node_modules/@babel/helper-string-parser": {
80 | "version": "7.24.8",
81 | "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz",
82 | "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==",
83 | "engines": {
84 | "node": ">=6.9.0"
85 | }
86 | },
87 | "node_modules/@babel/helper-validator-identifier": {
88 | "version": "7.24.7",
89 | "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz",
90 | "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==",
91 | "engines": {
92 | "node": ">=6.9.0"
93 | }
94 | },
95 | "node_modules/@babel/highlight": {
96 | "version": "7.24.7",
97 | "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz",
98 | "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==",
99 | "dependencies": {
100 | "@babel/helper-validator-identifier": "^7.24.7",
101 | "chalk": "^2.4.2",
102 | "js-tokens": "^4.0.0",
103 | "picocolors": "^1.0.0"
104 | },
105 | "engines": {
106 | "node": ">=6.9.0"
107 | }
108 | },
109 | "node_modules/@babel/parser": {
110 | "version": "7.25.6",
111 | "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.6.tgz",
112 | "integrity": "sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==",
113 | "dependencies": {
114 | "@babel/types": "^7.25.6"
115 | },
116 | "bin": {
117 | "parser": "bin/babel-parser.js"
118 | },
119 | "engines": {
120 | "node": ">=6.0.0"
121 | }
122 | },
123 | "node_modules/@babel/runtime": {
124 | "version": "7.25.6",
125 | "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.6.tgz",
126 | "integrity": "sha512-VBj9MYyDb9tuLq7yzqjgzt6Q+IBQLrGZfdjOekyEirZPHxXWoTSGUTMrpsfi58Up73d13NfYLv8HT9vmznjzhQ==",
127 | "dependencies": {
128 | "regenerator-runtime": "^0.14.0"
129 | },
130 | "engines": {
131 | "node": ">=6.9.0"
132 | }
133 | },
134 | "node_modules/@babel/template": {
135 | "version": "7.25.0",
136 | "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.0.tgz",
137 | "integrity": "sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==",
138 | "dependencies": {
139 | "@babel/code-frame": "^7.24.7",
140 | "@babel/parser": "^7.25.0",
141 | "@babel/types": "^7.25.0"
142 | },
143 | "engines": {
144 | "node": ">=6.9.0"
145 | }
146 | },
147 | "node_modules/@babel/traverse": {
148 | "version": "7.25.6",
149 | "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.6.tgz",
150 | "integrity": "sha512-9Vrcx5ZW6UwK5tvqsj0nGpp/XzqthkT0dqIc9g1AdtygFToNtTF67XzYS//dm+SAK9cp3B9R4ZO/46p63SCjlQ==",
151 | "dependencies": {
152 | "@babel/code-frame": "^7.24.7",
153 | "@babel/generator": "^7.25.6",
154 | "@babel/parser": "^7.25.6",
155 | "@babel/template": "^7.25.0",
156 | "@babel/types": "^7.25.6",
157 | "debug": "^4.3.1",
158 | "globals": "^11.1.0"
159 | },
160 | "engines": {
161 | "node": ">=6.9.0"
162 | }
163 | },
164 | "node_modules/@babel/traverse/node_modules/globals": {
165 | "version": "11.12.0",
166 | "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
167 | "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
168 | "engines": {
169 | "node": ">=4"
170 | }
171 | },
172 | "node_modules/@babel/types": {
173 | "version": "7.25.6",
174 | "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.6.tgz",
175 | "integrity": "sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==",
176 | "dependencies": {
177 | "@babel/helper-string-parser": "^7.24.8",
178 | "@babel/helper-validator-identifier": "^7.24.7",
179 | "to-fast-properties": "^2.0.0"
180 | },
181 | "engines": {
182 | "node": ">=6.9.0"
183 | }
184 | },
185 | "node_modules/@emotion/babel-plugin": {
186 | "version": "11.12.0",
187 | "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.12.0.tgz",
188 | "integrity": "sha512-y2WQb+oP8Jqvvclh8Q55gLUyb7UFvgv7eJfsj7td5TToBrIUtPay2kMrZi4xjq9qw2vD0ZR5fSho0yqoFgX7Rw==",
189 | "dependencies": {
190 | "@babel/helper-module-imports": "^7.16.7",
191 | "@babel/runtime": "^7.18.3",
192 | "@emotion/hash": "^0.9.2",
193 | "@emotion/memoize": "^0.9.0",
194 | "@emotion/serialize": "^1.2.0",
195 | "babel-plugin-macros": "^3.1.0",
196 | "convert-source-map": "^1.5.0",
197 | "escape-string-regexp": "^4.0.0",
198 | "find-root": "^1.1.0",
199 | "source-map": "^0.5.7",
200 | "stylis": "4.2.0"
201 | }
202 | },
203 | "node_modules/@emotion/cache": {
204 | "version": "11.13.1",
205 | "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.13.1.tgz",
206 | "integrity": "sha512-iqouYkuEblRcXmylXIwwOodiEK5Ifl7JcX7o6V4jI3iW4mLXX3dmt5xwBtIkJiQEXFAI+pC8X0i67yiPkH9Ucw==",
207 | "dependencies": {
208 | "@emotion/memoize": "^0.9.0",
209 | "@emotion/sheet": "^1.4.0",
210 | "@emotion/utils": "^1.4.0",
211 | "@emotion/weak-memoize": "^0.4.0",
212 | "stylis": "4.2.0"
213 | }
214 | },
215 | "node_modules/@emotion/hash": {
216 | "version": "0.9.2",
217 | "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz",
218 | "integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g=="
219 | },
220 | "node_modules/@emotion/is-prop-valid": {
221 | "version": "1.3.1",
222 | "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.3.1.tgz",
223 | "integrity": "sha512-/ACwoqx7XQi9knQs/G0qKvv5teDMhD7bXYns9N/wM8ah8iNb8jZ2uNO0YOgiq2o2poIvVtJS2YALasQuMSQ7Kw==",
224 | "dependencies": {
225 | "@emotion/memoize": "^0.9.0"
226 | }
227 | },
228 | "node_modules/@emotion/memoize": {
229 | "version": "0.9.0",
230 | "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz",
231 | "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ=="
232 | },
233 | "node_modules/@emotion/react": {
234 | "version": "11.13.3",
235 | "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.13.3.tgz",
236 | "integrity": "sha512-lIsdU6JNrmYfJ5EbUCf4xW1ovy5wKQ2CkPRM4xogziOxH1nXxBSjpC9YqbFAP7circxMfYp+6x676BqWcEiixg==",
237 | "dependencies": {
238 | "@babel/runtime": "^7.18.3",
239 | "@emotion/babel-plugin": "^11.12.0",
240 | "@emotion/cache": "^11.13.0",
241 | "@emotion/serialize": "^1.3.1",
242 | "@emotion/use-insertion-effect-with-fallbacks": "^1.1.0",
243 | "@emotion/utils": "^1.4.0",
244 | "@emotion/weak-memoize": "^0.4.0",
245 | "hoist-non-react-statics": "^3.3.1"
246 | },
247 | "peerDependencies": {
248 | "react": ">=16.8.0"
249 | },
250 | "peerDependenciesMeta": {
251 | "@types/react": {
252 | "optional": true
253 | }
254 | }
255 | },
256 | "node_modules/@emotion/serialize": {
257 | "version": "1.3.2",
258 | "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.3.2.tgz",
259 | "integrity": "sha512-grVnMvVPK9yUVE6rkKfAJlYZgo0cu3l9iMC77V7DW6E1DUIrU68pSEXRmFZFOFB1QFo57TncmOcvcbMDWsL4yA==",
260 | "dependencies": {
261 | "@emotion/hash": "^0.9.2",
262 | "@emotion/memoize": "^0.9.0",
263 | "@emotion/unitless": "^0.10.0",
264 | "@emotion/utils": "^1.4.1",
265 | "csstype": "^3.0.2"
266 | }
267 | },
268 | "node_modules/@emotion/sheet": {
269 | "version": "1.4.0",
270 | "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.4.0.tgz",
271 | "integrity": "sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg=="
272 | },
273 | "node_modules/@emotion/styled": {
274 | "version": "11.13.0",
275 | "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.13.0.tgz",
276 | "integrity": "sha512-tkzkY7nQhW/zC4hztlwucpT8QEZ6eUzpXDRhww/Eej4tFfO0FxQYWRyg/c5CCXa4d/f174kqeXYjuQRnhzf6dA==",
277 | "dependencies": {
278 | "@babel/runtime": "^7.18.3",
279 | "@emotion/babel-plugin": "^11.12.0",
280 | "@emotion/is-prop-valid": "^1.3.0",
281 | "@emotion/serialize": "^1.3.0",
282 | "@emotion/use-insertion-effect-with-fallbacks": "^1.1.0",
283 | "@emotion/utils": "^1.4.0"
284 | },
285 | "peerDependencies": {
286 | "@emotion/react": "^11.0.0-rc.0",
287 | "react": ">=16.8.0"
288 | },
289 | "peerDependenciesMeta": {
290 | "@types/react": {
291 | "optional": true
292 | }
293 | }
294 | },
295 | "node_modules/@emotion/unitless": {
296 | "version": "0.10.0",
297 | "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.10.0.tgz",
298 | "integrity": "sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg=="
299 | },
300 | "node_modules/@emotion/use-insertion-effect-with-fallbacks": {
301 | "version": "1.1.0",
302 | "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.1.0.tgz",
303 | "integrity": "sha512-+wBOcIV5snwGgI2ya3u99D7/FJquOIniQT1IKyDsBmEgwvpxMNeS65Oib7OnE2d2aY+3BU4OiH+0Wchf8yk3Hw==",
304 | "peerDependencies": {
305 | "react": ">=16.8.0"
306 | }
307 | },
308 | "node_modules/@emotion/utils": {
309 | "version": "1.4.1",
310 | "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.4.1.tgz",
311 | "integrity": "sha512-BymCXzCG3r72VKJxaYVwOXATqXIZ85cuvg0YOUDxMGNrKc1DJRZk8MgV5wyXRyEayIMd4FuXJIUgTBXvDNW5cA=="
312 | },
313 | "node_modules/@emotion/weak-memoize": {
314 | "version": "0.4.0",
315 | "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz",
316 | "integrity": "sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg=="
317 | },
318 | "node_modules/@esbuild/aix-ppc64": {
319 | "version": "0.21.5",
320 | "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz",
321 | "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==",
322 | "cpu": [
323 | "ppc64"
324 | ],
325 | "dev": true,
326 | "optional": true,
327 | "os": [
328 | "aix"
329 | ],
330 | "engines": {
331 | "node": ">=12"
332 | }
333 | },
334 | "node_modules/@esbuild/android-arm": {
335 | "version": "0.21.5",
336 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz",
337 | "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==",
338 | "cpu": [
339 | "arm"
340 | ],
341 | "dev": true,
342 | "optional": true,
343 | "os": [
344 | "android"
345 | ],
346 | "engines": {
347 | "node": ">=12"
348 | }
349 | },
350 | "node_modules/@esbuild/android-arm64": {
351 | "version": "0.21.5",
352 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz",
353 | "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==",
354 | "cpu": [
355 | "arm64"
356 | ],
357 | "dev": true,
358 | "optional": true,
359 | "os": [
360 | "android"
361 | ],
362 | "engines": {
363 | "node": ">=12"
364 | }
365 | },
366 | "node_modules/@esbuild/android-x64": {
367 | "version": "0.21.5",
368 | "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz",
369 | "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==",
370 | "cpu": [
371 | "x64"
372 | ],
373 | "dev": true,
374 | "optional": true,
375 | "os": [
376 | "android"
377 | ],
378 | "engines": {
379 | "node": ">=12"
380 | }
381 | },
382 | "node_modules/@esbuild/darwin-arm64": {
383 | "version": "0.21.5",
384 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz",
385 | "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==",
386 | "cpu": [
387 | "arm64"
388 | ],
389 | "dev": true,
390 | "optional": true,
391 | "os": [
392 | "darwin"
393 | ],
394 | "engines": {
395 | "node": ">=12"
396 | }
397 | },
398 | "node_modules/@esbuild/darwin-x64": {
399 | "version": "0.21.5",
400 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz",
401 | "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==",
402 | "cpu": [
403 | "x64"
404 | ],
405 | "dev": true,
406 | "optional": true,
407 | "os": [
408 | "darwin"
409 | ],
410 | "engines": {
411 | "node": ">=12"
412 | }
413 | },
414 | "node_modules/@esbuild/freebsd-arm64": {
415 | "version": "0.21.5",
416 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz",
417 | "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==",
418 | "cpu": [
419 | "arm64"
420 | ],
421 | "dev": true,
422 | "optional": true,
423 | "os": [
424 | "freebsd"
425 | ],
426 | "engines": {
427 | "node": ">=12"
428 | }
429 | },
430 | "node_modules/@esbuild/freebsd-x64": {
431 | "version": "0.21.5",
432 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz",
433 | "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==",
434 | "cpu": [
435 | "x64"
436 | ],
437 | "dev": true,
438 | "optional": true,
439 | "os": [
440 | "freebsd"
441 | ],
442 | "engines": {
443 | "node": ">=12"
444 | }
445 | },
446 | "node_modules/@esbuild/linux-arm": {
447 | "version": "0.21.5",
448 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz",
449 | "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==",
450 | "cpu": [
451 | "arm"
452 | ],
453 | "dev": true,
454 | "optional": true,
455 | "os": [
456 | "linux"
457 | ],
458 | "engines": {
459 | "node": ">=12"
460 | }
461 | },
462 | "node_modules/@esbuild/linux-arm64": {
463 | "version": "0.21.5",
464 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz",
465 | "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==",
466 | "cpu": [
467 | "arm64"
468 | ],
469 | "dev": true,
470 | "optional": true,
471 | "os": [
472 | "linux"
473 | ],
474 | "engines": {
475 | "node": ">=12"
476 | }
477 | },
478 | "node_modules/@esbuild/linux-ia32": {
479 | "version": "0.21.5",
480 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz",
481 | "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==",
482 | "cpu": [
483 | "ia32"
484 | ],
485 | "dev": true,
486 | "optional": true,
487 | "os": [
488 | "linux"
489 | ],
490 | "engines": {
491 | "node": ">=12"
492 | }
493 | },
494 | "node_modules/@esbuild/linux-loong64": {
495 | "version": "0.21.5",
496 | "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz",
497 | "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==",
498 | "cpu": [
499 | "loong64"
500 | ],
501 | "dev": true,
502 | "optional": true,
503 | "os": [
504 | "linux"
505 | ],
506 | "engines": {
507 | "node": ">=12"
508 | }
509 | },
510 | "node_modules/@esbuild/linux-mips64el": {
511 | "version": "0.21.5",
512 | "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz",
513 | "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==",
514 | "cpu": [
515 | "mips64el"
516 | ],
517 | "dev": true,
518 | "optional": true,
519 | "os": [
520 | "linux"
521 | ],
522 | "engines": {
523 | "node": ">=12"
524 | }
525 | },
526 | "node_modules/@esbuild/linux-ppc64": {
527 | "version": "0.21.5",
528 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz",
529 | "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==",
530 | "cpu": [
531 | "ppc64"
532 | ],
533 | "dev": true,
534 | "optional": true,
535 | "os": [
536 | "linux"
537 | ],
538 | "engines": {
539 | "node": ">=12"
540 | }
541 | },
542 | "node_modules/@esbuild/linux-riscv64": {
543 | "version": "0.21.5",
544 | "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz",
545 | "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==",
546 | "cpu": [
547 | "riscv64"
548 | ],
549 | "dev": true,
550 | "optional": true,
551 | "os": [
552 | "linux"
553 | ],
554 | "engines": {
555 | "node": ">=12"
556 | }
557 | },
558 | "node_modules/@esbuild/linux-s390x": {
559 | "version": "0.21.5",
560 | "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz",
561 | "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==",
562 | "cpu": [
563 | "s390x"
564 | ],
565 | "dev": true,
566 | "optional": true,
567 | "os": [
568 | "linux"
569 | ],
570 | "engines": {
571 | "node": ">=12"
572 | }
573 | },
574 | "node_modules/@esbuild/linux-x64": {
575 | "version": "0.21.5",
576 | "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz",
577 | "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==",
578 | "cpu": [
579 | "x64"
580 | ],
581 | "dev": true,
582 | "optional": true,
583 | "os": [
584 | "linux"
585 | ],
586 | "engines": {
587 | "node": ">=12"
588 | }
589 | },
590 | "node_modules/@esbuild/netbsd-x64": {
591 | "version": "0.21.5",
592 | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz",
593 | "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==",
594 | "cpu": [
595 | "x64"
596 | ],
597 | "dev": true,
598 | "optional": true,
599 | "os": [
600 | "netbsd"
601 | ],
602 | "engines": {
603 | "node": ">=12"
604 | }
605 | },
606 | "node_modules/@esbuild/openbsd-x64": {
607 | "version": "0.21.5",
608 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz",
609 | "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==",
610 | "cpu": [
611 | "x64"
612 | ],
613 | "dev": true,
614 | "optional": true,
615 | "os": [
616 | "openbsd"
617 | ],
618 | "engines": {
619 | "node": ">=12"
620 | }
621 | },
622 | "node_modules/@esbuild/sunos-x64": {
623 | "version": "0.21.5",
624 | "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz",
625 | "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==",
626 | "cpu": [
627 | "x64"
628 | ],
629 | "dev": true,
630 | "optional": true,
631 | "os": [
632 | "sunos"
633 | ],
634 | "engines": {
635 | "node": ">=12"
636 | }
637 | },
638 | "node_modules/@esbuild/win32-arm64": {
639 | "version": "0.21.5",
640 | "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz",
641 | "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==",
642 | "cpu": [
643 | "arm64"
644 | ],
645 | "dev": true,
646 | "optional": true,
647 | "os": [
648 | "win32"
649 | ],
650 | "engines": {
651 | "node": ">=12"
652 | }
653 | },
654 | "node_modules/@esbuild/win32-ia32": {
655 | "version": "0.21.5",
656 | "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz",
657 | "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==",
658 | "cpu": [
659 | "ia32"
660 | ],
661 | "dev": true,
662 | "optional": true,
663 | "os": [
664 | "win32"
665 | ],
666 | "engines": {
667 | "node": ">=12"
668 | }
669 | },
670 | "node_modules/@esbuild/win32-x64": {
671 | "version": "0.21.5",
672 | "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz",
673 | "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==",
674 | "cpu": [
675 | "x64"
676 | ],
677 | "dev": true,
678 | "optional": true,
679 | "os": [
680 | "win32"
681 | ],
682 | "engines": {
683 | "node": ">=12"
684 | }
685 | },
686 | "node_modules/@eslint-community/eslint-utils": {
687 | "version": "4.4.0",
688 | "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
689 | "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==",
690 | "dev": true,
691 | "dependencies": {
692 | "eslint-visitor-keys": "^3.3.0"
693 | },
694 | "engines": {
695 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
696 | },
697 | "peerDependencies": {
698 | "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
699 | }
700 | },
701 | "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": {
702 | "version": "3.4.3",
703 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
704 | "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
705 | "dev": true,
706 | "engines": {
707 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
708 | },
709 | "funding": {
710 | "url": "https://opencollective.com/eslint"
711 | }
712 | },
713 | "node_modules/@eslint-community/regexpp": {
714 | "version": "4.11.1",
715 | "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.1.tgz",
716 | "integrity": "sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q==",
717 | "dev": true,
718 | "engines": {
719 | "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
720 | }
721 | },
722 | "node_modules/@eslint/config-array": {
723 | "version": "0.18.0",
724 | "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.18.0.tgz",
725 | "integrity": "sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw==",
726 | "dev": true,
727 | "dependencies": {
728 | "@eslint/object-schema": "^2.1.4",
729 | "debug": "^4.3.1",
730 | "minimatch": "^3.1.2"
731 | },
732 | "engines": {
733 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
734 | }
735 | },
736 | "node_modules/@eslint/core": {
737 | "version": "0.6.0",
738 | "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.6.0.tgz",
739 | "integrity": "sha512-8I2Q8ykA4J0x0o7cg67FPVnehcqWTBehu/lmY+bolPFHGjh49YzGBMXTvpqVgEbBdvNCSxj6iFgiIyHzf03lzg==",
740 | "dev": true,
741 | "engines": {
742 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
743 | }
744 | },
745 | "node_modules/@eslint/eslintrc": {
746 | "version": "3.1.0",
747 | "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz",
748 | "integrity": "sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==",
749 | "dev": true,
750 | "dependencies": {
751 | "ajv": "^6.12.4",
752 | "debug": "^4.3.2",
753 | "espree": "^10.0.1",
754 | "globals": "^14.0.0",
755 | "ignore": "^5.2.0",
756 | "import-fresh": "^3.2.1",
757 | "js-yaml": "^4.1.0",
758 | "minimatch": "^3.1.2",
759 | "strip-json-comments": "^3.1.1"
760 | },
761 | "engines": {
762 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
763 | },
764 | "funding": {
765 | "url": "https://opencollective.com/eslint"
766 | }
767 | },
768 | "node_modules/@eslint/eslintrc/node_modules/globals": {
769 | "version": "14.0.0",
770 | "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz",
771 | "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==",
772 | "dev": true,
773 | "engines": {
774 | "node": ">=18"
775 | },
776 | "funding": {
777 | "url": "https://github.com/sponsors/sindresorhus"
778 | }
779 | },
780 | "node_modules/@eslint/js": {
781 | "version": "9.11.1",
782 | "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.11.1.tgz",
783 | "integrity": "sha512-/qu+TWz8WwPWc7/HcIJKi+c+MOm46GdVaSlTTQcaqaL53+GsoA6MxWp5PtTx48qbSP7ylM1Kn7nhvkugfJvRSA==",
784 | "dev": true,
785 | "engines": {
786 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
787 | }
788 | },
789 | "node_modules/@eslint/object-schema": {
790 | "version": "2.1.4",
791 | "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.4.tgz",
792 | "integrity": "sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==",
793 | "dev": true,
794 | "engines": {
795 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
796 | }
797 | },
798 | "node_modules/@eslint/plugin-kit": {
799 | "version": "0.2.0",
800 | "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.0.tgz",
801 | "integrity": "sha512-vH9PiIMMwvhCx31Af3HiGzsVNULDbyVkHXwlemn/B0TFj/00ho3y55efXrUZTfQipxoHC5u4xq6zblww1zm1Ig==",
802 | "dev": true,
803 | "dependencies": {
804 | "levn": "^0.4.1"
805 | },
806 | "engines": {
807 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
808 | }
809 | },
810 | "node_modules/@floating-ui/core": {
811 | "version": "1.6.8",
812 | "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.8.tgz",
813 | "integrity": "sha512-7XJ9cPU+yI2QeLS+FCSlqNFZJq8arvswefkZrYI1yQBbftw6FyrZOxYSh+9S7z7TpeWlRt9zJ5IhM1WIL334jA==",
814 | "dependencies": {
815 | "@floating-ui/utils": "^0.2.8"
816 | }
817 | },
818 | "node_modules/@floating-ui/dom": {
819 | "version": "1.6.11",
820 | "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.11.tgz",
821 | "integrity": "sha512-qkMCxSR24v2vGkhYDo/UzxfJN3D4syqSjyuTFz6C7XcpU1pASPRieNI0Kj5VP3/503mOfYiGY891ugBX1GlABQ==",
822 | "dependencies": {
823 | "@floating-ui/core": "^1.6.0",
824 | "@floating-ui/utils": "^0.2.8"
825 | }
826 | },
827 | "node_modules/@floating-ui/react-dom": {
828 | "version": "2.1.2",
829 | "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.2.tgz",
830 | "integrity": "sha512-06okr5cgPzMNBy+Ycse2A6udMi4bqwW/zgBF/rwjcNqWkyr82Mcg8b0vjX8OJpZFy/FKjJmw6wV7t44kK6kW7A==",
831 | "dependencies": {
832 | "@floating-ui/dom": "^1.0.0"
833 | },
834 | "peerDependencies": {
835 | "react": ">=16.8.0",
836 | "react-dom": ">=16.8.0"
837 | }
838 | },
839 | "node_modules/@floating-ui/utils": {
840 | "version": "0.2.8",
841 | "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.8.tgz",
842 | "integrity": "sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig=="
843 | },
844 | "node_modules/@formkit/auto-animate": {
845 | "version": "0.8.2",
846 | "resolved": "https://registry.npmjs.org/@formkit/auto-animate/-/auto-animate-0.8.2.tgz",
847 | "integrity": "sha512-SwPWfeRa5veb1hOIBMdzI+73te5puUBHmqqaF1Bu7FjvxlYSz/kJcZKSa9Cg60zL0uRNeJL2SbRxV6Jp6Q1nFQ=="
848 | },
849 | "node_modules/@humanwhocodes/module-importer": {
850 | "version": "1.0.1",
851 | "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
852 | "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
853 | "dev": true,
854 | "engines": {
855 | "node": ">=12.22"
856 | },
857 | "funding": {
858 | "type": "github",
859 | "url": "https://github.com/sponsors/nzakas"
860 | }
861 | },
862 | "node_modules/@humanwhocodes/retry": {
863 | "version": "0.3.0",
864 | "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.0.tgz",
865 | "integrity": "sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew==",
866 | "dev": true,
867 | "engines": {
868 | "node": ">=18.18"
869 | },
870 | "funding": {
871 | "type": "github",
872 | "url": "https://github.com/sponsors/nzakas"
873 | }
874 | },
875 | "node_modules/@jridgewell/gen-mapping": {
876 | "version": "0.3.5",
877 | "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz",
878 | "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==",
879 | "dependencies": {
880 | "@jridgewell/set-array": "^1.2.1",
881 | "@jridgewell/sourcemap-codec": "^1.4.10",
882 | "@jridgewell/trace-mapping": "^0.3.24"
883 | },
884 | "engines": {
885 | "node": ">=6.0.0"
886 | }
887 | },
888 | "node_modules/@jridgewell/resolve-uri": {
889 | "version": "3.1.2",
890 | "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
891 | "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
892 | "engines": {
893 | "node": ">=6.0.0"
894 | }
895 | },
896 | "node_modules/@jridgewell/set-array": {
897 | "version": "1.2.1",
898 | "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
899 | "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
900 | "engines": {
901 | "node": ">=6.0.0"
902 | }
903 | },
904 | "node_modules/@jridgewell/sourcemap-codec": {
905 | "version": "1.5.0",
906 | "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
907 | "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ=="
908 | },
909 | "node_modules/@jridgewell/trace-mapping": {
910 | "version": "0.3.25",
911 | "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
912 | "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
913 | "dependencies": {
914 | "@jridgewell/resolve-uri": "^3.1.0",
915 | "@jridgewell/sourcemap-codec": "^1.4.14"
916 | }
917 | },
918 | "node_modules/@mui/base": {
919 | "version": "5.0.0-beta.58",
920 | "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.58.tgz",
921 | "integrity": "sha512-P0E7ZrxOuyYqBvVv9w8k7wm+Xzx/KRu+BGgFcR2htTsGCpJNQJCSUXNUZ50MUmSU9hzqhwbQWNXhV1MBTl6F7A==",
922 | "dependencies": {
923 | "@babel/runtime": "^7.25.0",
924 | "@floating-ui/react-dom": "^2.1.1",
925 | "@mui/types": "^7.2.15",
926 | "@mui/utils": "6.0.0-rc.0",
927 | "@popperjs/core": "^2.11.8",
928 | "clsx": "^2.1.1",
929 | "prop-types": "^15.8.1"
930 | },
931 | "engines": {
932 | "node": ">=14.0.0"
933 | },
934 | "funding": {
935 | "type": "opencollective",
936 | "url": "https://opencollective.com/mui-org"
937 | },
938 | "peerDependencies": {
939 | "@types/react": "^17.0.0 || ^18.0.0",
940 | "react": "^17.0.0 || ^18.0.0",
941 | "react-dom": "^17.0.0 || ^18.0.0"
942 | },
943 | "peerDependenciesMeta": {
944 | "@types/react": {
945 | "optional": true
946 | }
947 | }
948 | },
949 | "node_modules/@mui/base/node_modules/@mui/utils": {
950 | "version": "6.0.0-rc.0",
951 | "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-6.0.0-rc.0.tgz",
952 | "integrity": "sha512-tBp0ILEXDL0bbDDT8PnZOjCqSm5Dfk2N0Z45uzRw+wVl6fVvloC9zw8avl+OdX1Bg3ubs/ttKn8nRNv17bpM5A==",
953 | "dependencies": {
954 | "@babel/runtime": "^7.25.0",
955 | "@mui/types": "^7.2.15",
956 | "@types/prop-types": "^15.7.12",
957 | "clsx": "^2.1.1",
958 | "prop-types": "^15.8.1",
959 | "react-is": "^18.3.1"
960 | },
961 | "engines": {
962 | "node": ">=14.0.0"
963 | },
964 | "funding": {
965 | "type": "opencollective",
966 | "url": "https://opencollective.com/mui-org"
967 | },
968 | "peerDependencies": {
969 | "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0",
970 | "react": "^17.0.0 || ^18.0.0 || ^19.0.0"
971 | },
972 | "peerDependenciesMeta": {
973 | "@types/react": {
974 | "optional": true
975 | }
976 | }
977 | },
978 | "node_modules/@mui/core-downloads-tracker": {
979 | "version": "6.1.1",
980 | "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-6.1.1.tgz",
981 | "integrity": "sha512-VdQC1tPIIcZAnf62L2M1eQif0x2vlKg3YK4kGYbtijSH4niEgI21GnstykW1vQIs+Bc6L+Hua2GATYVjilJ22A==",
982 | "funding": {
983 | "type": "opencollective",
984 | "url": "https://opencollective.com/mui-org"
985 | }
986 | },
987 | "node_modules/@mui/icons-material": {
988 | "version": "6.1.1",
989 | "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-6.1.1.tgz",
990 | "integrity": "sha512-sy/YKwcLPW8VcacNP2uWMYR9xyWuwO9NN9FXuGEU90bRshBXj8pdKk+joe3TCW7oviVS3zXLHlc94wQ0jNsQRQ==",
991 | "dependencies": {
992 | "@babel/runtime": "^7.25.6"
993 | },
994 | "engines": {
995 | "node": ">=14.0.0"
996 | },
997 | "funding": {
998 | "type": "opencollective",
999 | "url": "https://opencollective.com/mui-org"
1000 | },
1001 | "peerDependencies": {
1002 | "@mui/material": "^6.1.1",
1003 | "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0",
1004 | "react": "^17.0.0 || ^18.0.0 || ^19.0.0"
1005 | },
1006 | "peerDependenciesMeta": {
1007 | "@types/react": {
1008 | "optional": true
1009 | }
1010 | }
1011 | },
1012 | "node_modules/@mui/lab": {
1013 | "version": "6.0.0-beta.10",
1014 | "resolved": "https://registry.npmjs.org/@mui/lab/-/lab-6.0.0-beta.10.tgz",
1015 | "integrity": "sha512-eqCBz5SZS8Un9To3UcjH01AxkOOgvme/g0ZstFC8Nz1Kg5/EJMA0ByhKS5AvUMzUKrv0FXMdbuPqbBvF3bVrXg==",
1016 | "dependencies": {
1017 | "@babel/runtime": "^7.25.6",
1018 | "@mui/base": "5.0.0-beta.58",
1019 | "@mui/system": "^6.1.1",
1020 | "@mui/types": "^7.2.17",
1021 | "@mui/utils": "^6.1.1",
1022 | "clsx": "^2.1.1",
1023 | "prop-types": "^15.8.1"
1024 | },
1025 | "engines": {
1026 | "node": ">=14.0.0"
1027 | },
1028 | "funding": {
1029 | "type": "opencollective",
1030 | "url": "https://opencollective.com/mui-org"
1031 | },
1032 | "peerDependencies": {
1033 | "@emotion/react": "^11.5.0",
1034 | "@emotion/styled": "^11.3.0",
1035 | "@mui/material": "^6.1.1",
1036 | "@mui/material-pigment-css": "^6.1.1",
1037 | "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0",
1038 | "react": "^17.0.0 || ^18.0.0 || ^19.0.0",
1039 | "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0"
1040 | },
1041 | "peerDependenciesMeta": {
1042 | "@emotion/react": {
1043 | "optional": true
1044 | },
1045 | "@emotion/styled": {
1046 | "optional": true
1047 | },
1048 | "@mui/material-pigment-css": {
1049 | "optional": true
1050 | },
1051 | "@types/react": {
1052 | "optional": true
1053 | }
1054 | }
1055 | },
1056 | "node_modules/@mui/material": {
1057 | "version": "6.1.1",
1058 | "resolved": "https://registry.npmjs.org/@mui/material/-/material-6.1.1.tgz",
1059 | "integrity": "sha512-b+eULldTqtqTCbN++2BtBWCir/1LwEYw+2mIlOt2GiEUh1EBBw4/wIukGKKNt3xrCZqRA80yLLkV6tF61Lq3cA==",
1060 | "dependencies": {
1061 | "@babel/runtime": "^7.25.6",
1062 | "@mui/core-downloads-tracker": "^6.1.1",
1063 | "@mui/system": "^6.1.1",
1064 | "@mui/types": "^7.2.17",
1065 | "@mui/utils": "^6.1.1",
1066 | "@popperjs/core": "^2.11.8",
1067 | "@types/react-transition-group": "^4.4.11",
1068 | "clsx": "^2.1.1",
1069 | "csstype": "^3.1.3",
1070 | "prop-types": "^15.8.1",
1071 | "react-is": "^18.3.1",
1072 | "react-transition-group": "^4.4.5"
1073 | },
1074 | "engines": {
1075 | "node": ">=14.0.0"
1076 | },
1077 | "funding": {
1078 | "type": "opencollective",
1079 | "url": "https://opencollective.com/mui-org"
1080 | },
1081 | "peerDependencies": {
1082 | "@emotion/react": "^11.5.0",
1083 | "@emotion/styled": "^11.3.0",
1084 | "@mui/material-pigment-css": "^6.1.1",
1085 | "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0",
1086 | "react": "^17.0.0 || ^18.0.0 || ^19.0.0",
1087 | "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0"
1088 | },
1089 | "peerDependenciesMeta": {
1090 | "@emotion/react": {
1091 | "optional": true
1092 | },
1093 | "@emotion/styled": {
1094 | "optional": true
1095 | },
1096 | "@mui/material-pigment-css": {
1097 | "optional": true
1098 | },
1099 | "@types/react": {
1100 | "optional": true
1101 | }
1102 | }
1103 | },
1104 | "node_modules/@mui/private-theming": {
1105 | "version": "6.1.1",
1106 | "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-6.1.1.tgz",
1107 | "integrity": "sha512-JlrjIdhyZUtewtdAuUsvi3ZnO0YS49IW4Mfz19ZWTlQ0sDGga6LNPVwHClWr2/zJK2we2BQx9/i8M32rgKuzrg==",
1108 | "dependencies": {
1109 | "@babel/runtime": "^7.25.6",
1110 | "@mui/utils": "^6.1.1",
1111 | "prop-types": "^15.8.1"
1112 | },
1113 | "engines": {
1114 | "node": ">=14.0.0"
1115 | },
1116 | "funding": {
1117 | "type": "opencollective",
1118 | "url": "https://opencollective.com/mui-org"
1119 | },
1120 | "peerDependencies": {
1121 | "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0",
1122 | "react": "^17.0.0 || ^18.0.0 || ^19.0.0"
1123 | },
1124 | "peerDependenciesMeta": {
1125 | "@types/react": {
1126 | "optional": true
1127 | }
1128 | }
1129 | },
1130 | "node_modules/@mui/styled-engine": {
1131 | "version": "6.1.1",
1132 | "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-6.1.1.tgz",
1133 | "integrity": "sha512-HJyIoMpFb11fnHuRtUILOXgq6vj4LhIlE8maG4SwP/W+E5sa7HFexhnB3vOMT7bKys4UKNxhobC8jwWxYilGsA==",
1134 | "dependencies": {
1135 | "@babel/runtime": "^7.25.6",
1136 | "@emotion/cache": "^11.13.1",
1137 | "@emotion/sheet": "^1.4.0",
1138 | "csstype": "^3.1.3",
1139 | "prop-types": "^15.8.1"
1140 | },
1141 | "engines": {
1142 | "node": ">=14.0.0"
1143 | },
1144 | "funding": {
1145 | "type": "opencollective",
1146 | "url": "https://opencollective.com/mui-org"
1147 | },
1148 | "peerDependencies": {
1149 | "@emotion/react": "^11.4.1",
1150 | "@emotion/styled": "^11.3.0",
1151 | "react": "^17.0.0 || ^18.0.0 || ^19.0.0"
1152 | },
1153 | "peerDependenciesMeta": {
1154 | "@emotion/react": {
1155 | "optional": true
1156 | },
1157 | "@emotion/styled": {
1158 | "optional": true
1159 | }
1160 | }
1161 | },
1162 | "node_modules/@mui/system": {
1163 | "version": "6.1.1",
1164 | "resolved": "https://registry.npmjs.org/@mui/system/-/system-6.1.1.tgz",
1165 | "integrity": "sha512-PaYsCz2tUOcpu3T0okDEsSuP/yCDIj9JZ4Tox1JovRSKIjltHpXPsXZSGr3RiWdtM1MTQMFMCZzu0+CKbyy+Kw==",
1166 | "dependencies": {
1167 | "@babel/runtime": "^7.25.6",
1168 | "@mui/private-theming": "^6.1.1",
1169 | "@mui/styled-engine": "^6.1.1",
1170 | "@mui/types": "^7.2.17",
1171 | "@mui/utils": "^6.1.1",
1172 | "clsx": "^2.1.1",
1173 | "csstype": "^3.1.3",
1174 | "prop-types": "^15.8.1"
1175 | },
1176 | "engines": {
1177 | "node": ">=14.0.0"
1178 | },
1179 | "funding": {
1180 | "type": "opencollective",
1181 | "url": "https://opencollective.com/mui-org"
1182 | },
1183 | "peerDependencies": {
1184 | "@emotion/react": "^11.5.0",
1185 | "@emotion/styled": "^11.3.0",
1186 | "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0",
1187 | "react": "^17.0.0 || ^18.0.0 || ^19.0.0"
1188 | },
1189 | "peerDependenciesMeta": {
1190 | "@emotion/react": {
1191 | "optional": true
1192 | },
1193 | "@emotion/styled": {
1194 | "optional": true
1195 | },
1196 | "@types/react": {
1197 | "optional": true
1198 | }
1199 | }
1200 | },
1201 | "node_modules/@mui/types": {
1202 | "version": "7.2.17",
1203 | "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.17.tgz",
1204 | "integrity": "sha512-oyumoJgB6jDV8JFzRqjBo2daUuHpzDjoO/e3IrRhhHo/FxJlaVhET6mcNrKHUq2E+R+q3ql0qAtvQ4rfWHhAeQ==",
1205 | "peerDependencies": {
1206 | "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0"
1207 | },
1208 | "peerDependenciesMeta": {
1209 | "@types/react": {
1210 | "optional": true
1211 | }
1212 | }
1213 | },
1214 | "node_modules/@mui/utils": {
1215 | "version": "6.1.1",
1216 | "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-6.1.1.tgz",
1217 | "integrity": "sha512-HlRrgdJSPbYDXPpoVMWZV8AE7WcFtAk13rWNWAEVWKSanzBBkymjz3km+Th/Srowsh4pf1fTSP1B0L116wQBYw==",
1218 | "dependencies": {
1219 | "@babel/runtime": "^7.25.6",
1220 | "@mui/types": "^7.2.17",
1221 | "@types/prop-types": "^15.7.12",
1222 | "clsx": "^2.1.1",
1223 | "prop-types": "^15.8.1",
1224 | "react-is": "^18.3.1"
1225 | },
1226 | "engines": {
1227 | "node": ">=14.0.0"
1228 | },
1229 | "funding": {
1230 | "type": "opencollective",
1231 | "url": "https://opencollective.com/mui-org"
1232 | },
1233 | "peerDependencies": {
1234 | "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0",
1235 | "react": "^17.0.0 || ^18.0.0 || ^19.0.0"
1236 | },
1237 | "peerDependenciesMeta": {
1238 | "@types/react": {
1239 | "optional": true
1240 | }
1241 | }
1242 | },
1243 | "node_modules/@mui/x-data-grid": {
1244 | "version": "7.18.0",
1245 | "resolved": "https://registry.npmjs.org/@mui/x-data-grid/-/x-data-grid-7.18.0.tgz",
1246 | "integrity": "sha512-41UjJbRxWk+Yk/lfvaO55Pwo5p+F5s3rOTiHLl53ikCT5GuJ5OCCvik0Bi3c6DzTuUBdrEucae2618rydc2DGw==",
1247 | "dependencies": {
1248 | "@babel/runtime": "^7.25.6",
1249 | "@mui/utils": "^5.16.6",
1250 | "@mui/x-internals": "7.18.0",
1251 | "clsx": "^2.1.1",
1252 | "prop-types": "^15.8.1",
1253 | "reselect": "^5.1.1"
1254 | },
1255 | "engines": {
1256 | "node": ">=14.0.0"
1257 | },
1258 | "funding": {
1259 | "type": "opencollective",
1260 | "url": "https://opencollective.com/mui-org"
1261 | },
1262 | "peerDependencies": {
1263 | "@emotion/react": "^11.9.0",
1264 | "@emotion/styled": "^11.8.1",
1265 | "@mui/material": "^5.15.14 || ^6.0.0",
1266 | "@mui/system": "^5.15.14 || ^6.0.0",
1267 | "react": "^17.0.0 || ^18.0.0",
1268 | "react-dom": "^17.0.0 || ^18.0.0"
1269 | },
1270 | "peerDependenciesMeta": {
1271 | "@emotion/react": {
1272 | "optional": true
1273 | },
1274 | "@emotion/styled": {
1275 | "optional": true
1276 | }
1277 | }
1278 | },
1279 | "node_modules/@mui/x-data-grid/node_modules/@mui/utils": {
1280 | "version": "5.16.6",
1281 | "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.16.6.tgz",
1282 | "integrity": "sha512-tWiQqlhxAt3KENNiSRL+DIn9H5xNVK6Jjf70x3PnfQPz1MPBdh7yyIcAyVBT9xiw7hP3SomRhPR7hzBMBCjqEA==",
1283 | "dependencies": {
1284 | "@babel/runtime": "^7.23.9",
1285 | "@mui/types": "^7.2.15",
1286 | "@types/prop-types": "^15.7.12",
1287 | "clsx": "^2.1.1",
1288 | "prop-types": "^15.8.1",
1289 | "react-is": "^18.3.1"
1290 | },
1291 | "engines": {
1292 | "node": ">=12.0.0"
1293 | },
1294 | "funding": {
1295 | "type": "opencollective",
1296 | "url": "https://opencollective.com/mui-org"
1297 | },
1298 | "peerDependencies": {
1299 | "@types/react": "^17.0.0 || ^18.0.0",
1300 | "react": "^17.0.0 || ^18.0.0"
1301 | },
1302 | "peerDependenciesMeta": {
1303 | "@types/react": {
1304 | "optional": true
1305 | }
1306 | }
1307 | },
1308 | "node_modules/@mui/x-internals": {
1309 | "version": "7.18.0",
1310 | "resolved": "https://registry.npmjs.org/@mui/x-internals/-/x-internals-7.18.0.tgz",
1311 | "integrity": "sha512-lzCHOWIR0cAIY1bGrWSprYerahbnH5C31ql/2OWCEjcngL2NAV1M6oKI2Vp4HheqzJ822c60UyWyapvyjSzY/A==",
1312 | "dependencies": {
1313 | "@babel/runtime": "^7.25.6",
1314 | "@mui/utils": "^5.16.6"
1315 | },
1316 | "engines": {
1317 | "node": ">=14.0.0"
1318 | },
1319 | "funding": {
1320 | "type": "opencollective",
1321 | "url": "https://opencollective.com/mui-org"
1322 | },
1323 | "peerDependencies": {
1324 | "react": "^17.0.0 || ^18.0.0"
1325 | }
1326 | },
1327 | "node_modules/@mui/x-internals/node_modules/@mui/utils": {
1328 | "version": "5.16.6",
1329 | "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.16.6.tgz",
1330 | "integrity": "sha512-tWiQqlhxAt3KENNiSRL+DIn9H5xNVK6Jjf70x3PnfQPz1MPBdh7yyIcAyVBT9xiw7hP3SomRhPR7hzBMBCjqEA==",
1331 | "dependencies": {
1332 | "@babel/runtime": "^7.23.9",
1333 | "@mui/types": "^7.2.15",
1334 | "@types/prop-types": "^15.7.12",
1335 | "clsx": "^2.1.1",
1336 | "prop-types": "^15.8.1",
1337 | "react-is": "^18.3.1"
1338 | },
1339 | "engines": {
1340 | "node": ">=12.0.0"
1341 | },
1342 | "funding": {
1343 | "type": "opencollective",
1344 | "url": "https://opencollective.com/mui-org"
1345 | },
1346 | "peerDependencies": {
1347 | "@types/react": "^17.0.0 || ^18.0.0",
1348 | "react": "^17.0.0 || ^18.0.0"
1349 | },
1350 | "peerDependenciesMeta": {
1351 | "@types/react": {
1352 | "optional": true
1353 | }
1354 | }
1355 | },
1356 | "node_modules/@nodelib/fs.scandir": {
1357 | "version": "2.1.5",
1358 | "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
1359 | "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
1360 | "dev": true,
1361 | "dependencies": {
1362 | "@nodelib/fs.stat": "2.0.5",
1363 | "run-parallel": "^1.1.9"
1364 | },
1365 | "engines": {
1366 | "node": ">= 8"
1367 | }
1368 | },
1369 | "node_modules/@nodelib/fs.stat": {
1370 | "version": "2.0.5",
1371 | "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
1372 | "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
1373 | "dev": true,
1374 | "engines": {
1375 | "node": ">= 8"
1376 | }
1377 | },
1378 | "node_modules/@nodelib/fs.walk": {
1379 | "version": "1.2.8",
1380 | "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
1381 | "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
1382 | "dev": true,
1383 | "dependencies": {
1384 | "@nodelib/fs.scandir": "2.1.5",
1385 | "fastq": "^1.6.0"
1386 | },
1387 | "engines": {
1388 | "node": ">= 8"
1389 | }
1390 | },
1391 | "node_modules/@popperjs/core": {
1392 | "version": "2.11.8",
1393 | "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz",
1394 | "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==",
1395 | "funding": {
1396 | "type": "opencollective",
1397 | "url": "https://opencollective.com/popperjs"
1398 | }
1399 | },
1400 | "node_modules/@rollup/rollup-android-arm-eabi": {
1401 | "version": "4.22.5",
1402 | "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.22.5.tgz",
1403 | "integrity": "sha512-SU5cvamg0Eyu/F+kLeMXS7GoahL+OoizlclVFX3l5Ql6yNlywJJ0OuqTzUx0v+aHhPHEB/56CT06GQrRrGNYww==",
1404 | "cpu": [
1405 | "arm"
1406 | ],
1407 | "dev": true,
1408 | "optional": true,
1409 | "os": [
1410 | "android"
1411 | ]
1412 | },
1413 | "node_modules/@rollup/rollup-android-arm64": {
1414 | "version": "4.22.5",
1415 | "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.22.5.tgz",
1416 | "integrity": "sha512-S4pit5BP6E5R5C8S6tgU/drvgjtYW76FBuG6+ibG3tMvlD1h9LHVF9KmlmaUBQ8Obou7hEyS+0w+IR/VtxwNMQ==",
1417 | "cpu": [
1418 | "arm64"
1419 | ],
1420 | "dev": true,
1421 | "optional": true,
1422 | "os": [
1423 | "android"
1424 | ]
1425 | },
1426 | "node_modules/@rollup/rollup-darwin-arm64": {
1427 | "version": "4.22.5",
1428 | "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.22.5.tgz",
1429 | "integrity": "sha512-250ZGg4ipTL0TGvLlfACkIxS9+KLtIbn7BCZjsZj88zSg2Lvu3Xdw6dhAhfe/FjjXPVNCtcSp+WZjVsD3a/Zlw==",
1430 | "cpu": [
1431 | "arm64"
1432 | ],
1433 | "dev": true,
1434 | "optional": true,
1435 | "os": [
1436 | "darwin"
1437 | ]
1438 | },
1439 | "node_modules/@rollup/rollup-darwin-x64": {
1440 | "version": "4.22.5",
1441 | "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.22.5.tgz",
1442 | "integrity": "sha512-D8brJEFg5D+QxFcW6jYANu+Rr9SlKtTenmsX5hOSzNYVrK5oLAEMTUgKWYJP+wdKyCdeSwnapLsn+OVRFycuQg==",
1443 | "cpu": [
1444 | "x64"
1445 | ],
1446 | "dev": true,
1447 | "optional": true,
1448 | "os": [
1449 | "darwin"
1450 | ]
1451 | },
1452 | "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
1453 | "version": "4.22.5",
1454 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.22.5.tgz",
1455 | "integrity": "sha512-PNqXYmdNFyWNg0ma5LdY8wP+eQfdvyaBAojAXgO7/gs0Q/6TQJVXAXe8gwW9URjbS0YAammur0fynYGiWsKlXw==",
1456 | "cpu": [
1457 | "arm"
1458 | ],
1459 | "dev": true,
1460 | "optional": true,
1461 | "os": [
1462 | "linux"
1463 | ]
1464 | },
1465 | "node_modules/@rollup/rollup-linux-arm-musleabihf": {
1466 | "version": "4.22.5",
1467 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.22.5.tgz",
1468 | "integrity": "sha512-kSSCZOKz3HqlrEuwKd9TYv7vxPYD77vHSUvM2y0YaTGnFc8AdI5TTQRrM1yIp3tXCKrSL9A7JLoILjtad5t8pQ==",
1469 | "cpu": [
1470 | "arm"
1471 | ],
1472 | "dev": true,
1473 | "optional": true,
1474 | "os": [
1475 | "linux"
1476 | ]
1477 | },
1478 | "node_modules/@rollup/rollup-linux-arm64-gnu": {
1479 | "version": "4.22.5",
1480 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.22.5.tgz",
1481 | "integrity": "sha512-oTXQeJHRbOnwRnRffb6bmqmUugz0glXaPyspp4gbQOPVApdpRrY/j7KP3lr7M8kTfQTyrBUzFjj5EuHAhqH4/w==",
1482 | "cpu": [
1483 | "arm64"
1484 | ],
1485 | "dev": true,
1486 | "optional": true,
1487 | "os": [
1488 | "linux"
1489 | ]
1490 | },
1491 | "node_modules/@rollup/rollup-linux-arm64-musl": {
1492 | "version": "4.22.5",
1493 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.22.5.tgz",
1494 | "integrity": "sha512-qnOTIIs6tIGFKCHdhYitgC2XQ2X25InIbZFor5wh+mALH84qnFHvc+vmWUpyX97B0hNvwNUL4B+MB8vJvH65Fw==",
1495 | "cpu": [
1496 | "arm64"
1497 | ],
1498 | "dev": true,
1499 | "optional": true,
1500 | "os": [
1501 | "linux"
1502 | ]
1503 | },
1504 | "node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
1505 | "version": "4.22.5",
1506 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.22.5.tgz",
1507 | "integrity": "sha512-TMYu+DUdNlgBXING13rHSfUc3Ky5nLPbWs4bFnT+R6Vu3OvXkTkixvvBKk8uO4MT5Ab6lC3U7x8S8El2q5o56w==",
1508 | "cpu": [
1509 | "ppc64"
1510 | ],
1511 | "dev": true,
1512 | "optional": true,
1513 | "os": [
1514 | "linux"
1515 | ]
1516 | },
1517 | "node_modules/@rollup/rollup-linux-riscv64-gnu": {
1518 | "version": "4.22.5",
1519 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.22.5.tgz",
1520 | "integrity": "sha512-PTQq1Kz22ZRvuhr3uURH+U/Q/a0pbxJoICGSprNLAoBEkyD3Sh9qP5I0Asn0y0wejXQBbsVMRZRxlbGFD9OK4A==",
1521 | "cpu": [
1522 | "riscv64"
1523 | ],
1524 | "dev": true,
1525 | "optional": true,
1526 | "os": [
1527 | "linux"
1528 | ]
1529 | },
1530 | "node_modules/@rollup/rollup-linux-s390x-gnu": {
1531 | "version": "4.22.5",
1532 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.22.5.tgz",
1533 | "integrity": "sha512-bR5nCojtpuMss6TDEmf/jnBnzlo+6n1UhgwqUvRoe4VIotC7FG1IKkyJbwsT7JDsF2jxR+NTnuOwiGv0hLyDoQ==",
1534 | "cpu": [
1535 | "s390x"
1536 | ],
1537 | "dev": true,
1538 | "optional": true,
1539 | "os": [
1540 | "linux"
1541 | ]
1542 | },
1543 | "node_modules/@rollup/rollup-linux-x64-gnu": {
1544 | "version": "4.22.5",
1545 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.22.5.tgz",
1546 | "integrity": "sha512-N0jPPhHjGShcB9/XXZQWuWBKZQnC1F36Ce3sDqWpujsGjDz/CQtOL9LgTrJ+rJC8MJeesMWrMWVLKKNR/tMOCA==",
1547 | "cpu": [
1548 | "x64"
1549 | ],
1550 | "dev": true,
1551 | "optional": true,
1552 | "os": [
1553 | "linux"
1554 | ]
1555 | },
1556 | "node_modules/@rollup/rollup-linux-x64-musl": {
1557 | "version": "4.22.5",
1558 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.22.5.tgz",
1559 | "integrity": "sha512-uBa2e28ohzNNwjr6Uxm4XyaA1M/8aTgfF2T7UIlElLaeXkgpmIJ2EitVNQxjO9xLLLy60YqAgKn/AqSpCUkE9g==",
1560 | "cpu": [
1561 | "x64"
1562 | ],
1563 | "dev": true,
1564 | "optional": true,
1565 | "os": [
1566 | "linux"
1567 | ]
1568 | },
1569 | "node_modules/@rollup/rollup-win32-arm64-msvc": {
1570 | "version": "4.22.5",
1571 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.22.5.tgz",
1572 | "integrity": "sha512-RXT8S1HP8AFN/Kr3tg4fuYrNxZ/pZf1HemC5Tsddc6HzgGnJm0+Lh5rAHJkDuW3StI0ynNXukidROMXYl6ew8w==",
1573 | "cpu": [
1574 | "arm64"
1575 | ],
1576 | "dev": true,
1577 | "optional": true,
1578 | "os": [
1579 | "win32"
1580 | ]
1581 | },
1582 | "node_modules/@rollup/rollup-win32-ia32-msvc": {
1583 | "version": "4.22.5",
1584 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.22.5.tgz",
1585 | "integrity": "sha512-ElTYOh50InL8kzyUD6XsnPit7jYCKrphmddKAe1/Ytt74apOxDq5YEcbsiKs0fR3vff3jEneMM+3I7jbqaMyBg==",
1586 | "cpu": [
1587 | "ia32"
1588 | ],
1589 | "dev": true,
1590 | "optional": true,
1591 | "os": [
1592 | "win32"
1593 | ]
1594 | },
1595 | "node_modules/@rollup/rollup-win32-x64-msvc": {
1596 | "version": "4.22.5",
1597 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.22.5.tgz",
1598 | "integrity": "sha512-+lvL/4mQxSV8MukpkKyyvfwhH266COcWlXE/1qxwN08ajovta3459zrjLghYMgDerlzNwLAcFpvU+WWE5y6nAQ==",
1599 | "cpu": [
1600 | "x64"
1601 | ],
1602 | "dev": true,
1603 | "optional": true,
1604 | "os": [
1605 | "win32"
1606 | ]
1607 | },
1608 | "node_modules/@swc/core": {
1609 | "version": "1.7.26",
1610 | "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.7.26.tgz",
1611 | "integrity": "sha512-f5uYFf+TmMQyYIoxkn/evWhNGuUzC730dFwAKGwBVHHVoPyak1/GvJUm6i1SKl+2Hrj9oN0i3WSoWWZ4pgI8lw==",
1612 | "dev": true,
1613 | "hasInstallScript": true,
1614 | "dependencies": {
1615 | "@swc/counter": "^0.1.3",
1616 | "@swc/types": "^0.1.12"
1617 | },
1618 | "engines": {
1619 | "node": ">=10"
1620 | },
1621 | "funding": {
1622 | "type": "opencollective",
1623 | "url": "https://opencollective.com/swc"
1624 | },
1625 | "optionalDependencies": {
1626 | "@swc/core-darwin-arm64": "1.7.26",
1627 | "@swc/core-darwin-x64": "1.7.26",
1628 | "@swc/core-linux-arm-gnueabihf": "1.7.26",
1629 | "@swc/core-linux-arm64-gnu": "1.7.26",
1630 | "@swc/core-linux-arm64-musl": "1.7.26",
1631 | "@swc/core-linux-x64-gnu": "1.7.26",
1632 | "@swc/core-linux-x64-musl": "1.7.26",
1633 | "@swc/core-win32-arm64-msvc": "1.7.26",
1634 | "@swc/core-win32-ia32-msvc": "1.7.26",
1635 | "@swc/core-win32-x64-msvc": "1.7.26"
1636 | },
1637 | "peerDependencies": {
1638 | "@swc/helpers": "*"
1639 | },
1640 | "peerDependenciesMeta": {
1641 | "@swc/helpers": {
1642 | "optional": true
1643 | }
1644 | }
1645 | },
1646 | "node_modules/@swc/core-darwin-arm64": {
1647 | "version": "1.7.26",
1648 | "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.7.26.tgz",
1649 | "integrity": "sha512-FF3CRYTg6a7ZVW4yT9mesxoVVZTrcSWtmZhxKCYJX9brH4CS/7PRPjAKNk6kzWgWuRoglP7hkjQcd6EpMcZEAw==",
1650 | "cpu": [
1651 | "arm64"
1652 | ],
1653 | "dev": true,
1654 | "optional": true,
1655 | "os": [
1656 | "darwin"
1657 | ],
1658 | "engines": {
1659 | "node": ">=10"
1660 | }
1661 | },
1662 | "node_modules/@swc/core-darwin-x64": {
1663 | "version": "1.7.26",
1664 | "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.7.26.tgz",
1665 | "integrity": "sha512-az3cibZdsay2HNKmc4bjf62QVukuiMRh5sfM5kHR/JMTrLyS6vSw7Ihs3UTkZjUxkLTT8ro54LI6sV6sUQUbLQ==",
1666 | "cpu": [
1667 | "x64"
1668 | ],
1669 | "dev": true,
1670 | "optional": true,
1671 | "os": [
1672 | "darwin"
1673 | ],
1674 | "engines": {
1675 | "node": ">=10"
1676 | }
1677 | },
1678 | "node_modules/@swc/core-linux-arm-gnueabihf": {
1679 | "version": "1.7.26",
1680 | "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.7.26.tgz",
1681 | "integrity": "sha512-VYPFVJDO5zT5U3RpCdHE5v1gz4mmR8BfHecUZTmD2v1JeFY6fv9KArJUpjrHEEsjK/ucXkQFmJ0jaiWXmpOV9Q==",
1682 | "cpu": [
1683 | "arm"
1684 | ],
1685 | "dev": true,
1686 | "optional": true,
1687 | "os": [
1688 | "linux"
1689 | ],
1690 | "engines": {
1691 | "node": ">=10"
1692 | }
1693 | },
1694 | "node_modules/@swc/core-linux-arm64-gnu": {
1695 | "version": "1.7.26",
1696 | "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.7.26.tgz",
1697 | "integrity": "sha512-YKevOV7abpjcAzXrhsl+W48Z9mZvgoVs2eP5nY+uoMAdP2b3GxC0Df1Co0I90o2lkzO4jYBpTMcZlmUXLdXn+Q==",
1698 | "cpu": [
1699 | "arm64"
1700 | ],
1701 | "dev": true,
1702 | "optional": true,
1703 | "os": [
1704 | "linux"
1705 | ],
1706 | "engines": {
1707 | "node": ">=10"
1708 | }
1709 | },
1710 | "node_modules/@swc/core-linux-arm64-musl": {
1711 | "version": "1.7.26",
1712 | "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.7.26.tgz",
1713 | "integrity": "sha512-3w8iZICMkQQON0uIcvz7+Q1MPOW6hJ4O5ETjA0LSP/tuKqx30hIniCGOgPDnv3UTMruLUnQbtBwVCZTBKR3Rkg==",
1714 | "cpu": [
1715 | "arm64"
1716 | ],
1717 | "dev": true,
1718 | "optional": true,
1719 | "os": [
1720 | "linux"
1721 | ],
1722 | "engines": {
1723 | "node": ">=10"
1724 | }
1725 | },
1726 | "node_modules/@swc/core-linux-x64-gnu": {
1727 | "version": "1.7.26",
1728 | "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.7.26.tgz",
1729 | "integrity": "sha512-c+pp9Zkk2lqb06bNGkR2Looxrs7FtGDMA4/aHjZcCqATgp348hOKH5WPvNLBl+yPrISuWjbKDVn3NgAvfvpH4w==",
1730 | "cpu": [
1731 | "x64"
1732 | ],
1733 | "dev": true,
1734 | "optional": true,
1735 | "os": [
1736 | "linux"
1737 | ],
1738 | "engines": {
1739 | "node": ">=10"
1740 | }
1741 | },
1742 | "node_modules/@swc/core-linux-x64-musl": {
1743 | "version": "1.7.26",
1744 | "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.7.26.tgz",
1745 | "integrity": "sha512-PgtyfHBF6xG87dUSSdTJHwZ3/8vWZfNIXQV2GlwEpslrOkGqy+WaiiyE7Of7z9AvDILfBBBcJvJ/r8u980wAfQ==",
1746 | "cpu": [
1747 | "x64"
1748 | ],
1749 | "dev": true,
1750 | "optional": true,
1751 | "os": [
1752 | "linux"
1753 | ],
1754 | "engines": {
1755 | "node": ">=10"
1756 | }
1757 | },
1758 | "node_modules/@swc/core-win32-arm64-msvc": {
1759 | "version": "1.7.26",
1760 | "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.7.26.tgz",
1761 | "integrity": "sha512-9TNXPIJqFynlAOrRD6tUQjMq7KApSklK3R/tXgIxc7Qx+lWu8hlDQ/kVPLpU7PWvMMwC/3hKBW+p5f+Tms1hmA==",
1762 | "cpu": [
1763 | "arm64"
1764 | ],
1765 | "dev": true,
1766 | "optional": true,
1767 | "os": [
1768 | "win32"
1769 | ],
1770 | "engines": {
1771 | "node": ">=10"
1772 | }
1773 | },
1774 | "node_modules/@swc/core-win32-ia32-msvc": {
1775 | "version": "1.7.26",
1776 | "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.7.26.tgz",
1777 | "integrity": "sha512-9YngxNcG3177GYdsTum4V98Re+TlCeJEP4kEwEg9EagT5s3YejYdKwVAkAsJszzkXuyRDdnHUpYbTrPG6FiXrQ==",
1778 | "cpu": [
1779 | "ia32"
1780 | ],
1781 | "dev": true,
1782 | "optional": true,
1783 | "os": [
1784 | "win32"
1785 | ],
1786 | "engines": {
1787 | "node": ">=10"
1788 | }
1789 | },
1790 | "node_modules/@swc/core-win32-x64-msvc": {
1791 | "version": "1.7.26",
1792 | "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.7.26.tgz",
1793 | "integrity": "sha512-VR+hzg9XqucgLjXxA13MtV5O3C0bK0ywtLIBw/+a+O+Oc6mxFWHtdUeXDbIi5AiPbn0fjgVJMqYnyjGyyX8u0w==",
1794 | "cpu": [
1795 | "x64"
1796 | ],
1797 | "dev": true,
1798 | "optional": true,
1799 | "os": [
1800 | "win32"
1801 | ],
1802 | "engines": {
1803 | "node": ">=10"
1804 | }
1805 | },
1806 | "node_modules/@swc/counter": {
1807 | "version": "0.1.3",
1808 | "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz",
1809 | "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==",
1810 | "dev": true
1811 | },
1812 | "node_modules/@swc/types": {
1813 | "version": "0.1.12",
1814 | "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.12.tgz",
1815 | "integrity": "sha512-wBJA+SdtkbFhHjTMYH+dEH1y4VpfGdAc2Kw/LK09i9bXd/K6j6PkDcFCEzb6iVfZMkPRrl/q0e3toqTAJdkIVA==",
1816 | "dev": true,
1817 | "dependencies": {
1818 | "@swc/counter": "^0.1.3"
1819 | }
1820 | },
1821 | "node_modules/@tanstack/query-core": {
1822 | "version": "5.56.2",
1823 | "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.56.2.tgz",
1824 | "integrity": "sha512-gor0RI3/R5rVV3gXfddh1MM+hgl0Z4G7tj6Xxpq6p2I03NGPaJ8dITY9Gz05zYYb/EJq9vPas/T4wn9EaDPd4Q==",
1825 | "funding": {
1826 | "type": "github",
1827 | "url": "https://github.com/sponsors/tannerlinsley"
1828 | }
1829 | },
1830 | "node_modules/@tanstack/react-query": {
1831 | "version": "5.56.2",
1832 | "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.56.2.tgz",
1833 | "integrity": "sha512-SR0GzHVo6yzhN72pnRhkEFRAHMsUo5ZPzAxfTMvUxFIDVS6W9LYUp6nXW3fcHVdg0ZJl8opSH85jqahvm6DSVg==",
1834 | "dependencies": {
1835 | "@tanstack/query-core": "5.56.2"
1836 | },
1837 | "funding": {
1838 | "type": "github",
1839 | "url": "https://github.com/sponsors/tannerlinsley"
1840 | },
1841 | "peerDependencies": {
1842 | "react": "^18 || ^19"
1843 | }
1844 | },
1845 | "node_modules/@types/estree": {
1846 | "version": "1.0.6",
1847 | "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz",
1848 | "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==",
1849 | "dev": true
1850 | },
1851 | "node_modules/@types/json-schema": {
1852 | "version": "7.0.15",
1853 | "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
1854 | "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
1855 | "dev": true
1856 | },
1857 | "node_modules/@types/node": {
1858 | "version": "22.7.3",
1859 | "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.3.tgz",
1860 | "integrity": "sha512-qXKfhXXqGTyBskvWEzJZPUxSslAiLaB6JGP1ic/XTH9ctGgzdgYguuLP1C601aRTSDNlLb0jbKqXjZ48GNraSA==",
1861 | "dev": true,
1862 | "dependencies": {
1863 | "undici-types": "~6.19.2"
1864 | }
1865 | },
1866 | "node_modules/@types/parse-json": {
1867 | "version": "4.0.2",
1868 | "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz",
1869 | "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw=="
1870 | },
1871 | "node_modules/@types/prop-types": {
1872 | "version": "15.7.13",
1873 | "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.13.tgz",
1874 | "integrity": "sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA=="
1875 | },
1876 | "node_modules/@types/react": {
1877 | "version": "18.3.9",
1878 | "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.9.tgz",
1879 | "integrity": "sha512-+BpAVyTpJkNWWSSnaLBk6ePpHLOGJKnEQNbINNovPWzvEUyAe3e+/d494QdEh71RekM/qV7lw6jzf1HGrJyAtQ==",
1880 | "dependencies": {
1881 | "@types/prop-types": "*",
1882 | "csstype": "^3.0.2"
1883 | }
1884 | },
1885 | "node_modules/@types/react-dom": {
1886 | "version": "18.3.0",
1887 | "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.0.tgz",
1888 | "integrity": "sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==",
1889 | "dev": true,
1890 | "dependencies": {
1891 | "@types/react": "*"
1892 | }
1893 | },
1894 | "node_modules/@types/react-transition-group": {
1895 | "version": "4.4.11",
1896 | "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.11.tgz",
1897 | "integrity": "sha512-RM05tAniPZ5DZPzzNFP+DmrcOdD0efDUxMy3145oljWSl3x9ZV5vhme98gTxFrj2lhXvmGNnUiuDyJgY9IKkNA==",
1898 | "dependencies": {
1899 | "@types/react": "*"
1900 | }
1901 | },
1902 | "node_modules/@typescript-eslint/eslint-plugin": {
1903 | "version": "8.7.0",
1904 | "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.7.0.tgz",
1905 | "integrity": "sha512-RIHOoznhA3CCfSTFiB6kBGLQtB/sox+pJ6jeFu6FxJvqL8qRxq/FfGO/UhsGgQM9oGdXkV4xUgli+dt26biB6A==",
1906 | "dev": true,
1907 | "dependencies": {
1908 | "@eslint-community/regexpp": "^4.10.0",
1909 | "@typescript-eslint/scope-manager": "8.7.0",
1910 | "@typescript-eslint/type-utils": "8.7.0",
1911 | "@typescript-eslint/utils": "8.7.0",
1912 | "@typescript-eslint/visitor-keys": "8.7.0",
1913 | "graphemer": "^1.4.0",
1914 | "ignore": "^5.3.1",
1915 | "natural-compare": "^1.4.0",
1916 | "ts-api-utils": "^1.3.0"
1917 | },
1918 | "engines": {
1919 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
1920 | },
1921 | "funding": {
1922 | "type": "opencollective",
1923 | "url": "https://opencollective.com/typescript-eslint"
1924 | },
1925 | "peerDependencies": {
1926 | "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0",
1927 | "eslint": "^8.57.0 || ^9.0.0"
1928 | },
1929 | "peerDependenciesMeta": {
1930 | "typescript": {
1931 | "optional": true
1932 | }
1933 | }
1934 | },
1935 | "node_modules/@typescript-eslint/parser": {
1936 | "version": "8.7.0",
1937 | "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.7.0.tgz",
1938 | "integrity": "sha512-lN0btVpj2unxHlNYLI//BQ7nzbMJYBVQX5+pbNXvGYazdlgYonMn4AhhHifQ+J4fGRYA/m1DjaQjx+fDetqBOQ==",
1939 | "dev": true,
1940 | "dependencies": {
1941 | "@typescript-eslint/scope-manager": "8.7.0",
1942 | "@typescript-eslint/types": "8.7.0",
1943 | "@typescript-eslint/typescript-estree": "8.7.0",
1944 | "@typescript-eslint/visitor-keys": "8.7.0",
1945 | "debug": "^4.3.4"
1946 | },
1947 | "engines": {
1948 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
1949 | },
1950 | "funding": {
1951 | "type": "opencollective",
1952 | "url": "https://opencollective.com/typescript-eslint"
1953 | },
1954 | "peerDependencies": {
1955 | "eslint": "^8.57.0 || ^9.0.0"
1956 | },
1957 | "peerDependenciesMeta": {
1958 | "typescript": {
1959 | "optional": true
1960 | }
1961 | }
1962 | },
1963 | "node_modules/@typescript-eslint/scope-manager": {
1964 | "version": "8.7.0",
1965 | "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.7.0.tgz",
1966 | "integrity": "sha512-87rC0k3ZlDOuz82zzXRtQ7Akv3GKhHs0ti4YcbAJtaomllXoSO8hi7Ix3ccEvCd824dy9aIX+j3d2UMAfCtVpg==",
1967 | "dev": true,
1968 | "dependencies": {
1969 | "@typescript-eslint/types": "8.7.0",
1970 | "@typescript-eslint/visitor-keys": "8.7.0"
1971 | },
1972 | "engines": {
1973 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
1974 | },
1975 | "funding": {
1976 | "type": "opencollective",
1977 | "url": "https://opencollective.com/typescript-eslint"
1978 | }
1979 | },
1980 | "node_modules/@typescript-eslint/type-utils": {
1981 | "version": "8.7.0",
1982 | "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.7.0.tgz",
1983 | "integrity": "sha512-tl0N0Mj3hMSkEYhLkjREp54OSb/FI6qyCzfiiclvJvOqre6hsZTGSnHtmFLDU8TIM62G7ygEa1bI08lcuRwEnQ==",
1984 | "dev": true,
1985 | "dependencies": {
1986 | "@typescript-eslint/typescript-estree": "8.7.0",
1987 | "@typescript-eslint/utils": "8.7.0",
1988 | "debug": "^4.3.4",
1989 | "ts-api-utils": "^1.3.0"
1990 | },
1991 | "engines": {
1992 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
1993 | },
1994 | "funding": {
1995 | "type": "opencollective",
1996 | "url": "https://opencollective.com/typescript-eslint"
1997 | },
1998 | "peerDependenciesMeta": {
1999 | "typescript": {
2000 | "optional": true
2001 | }
2002 | }
2003 | },
2004 | "node_modules/@typescript-eslint/types": {
2005 | "version": "8.7.0",
2006 | "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.7.0.tgz",
2007 | "integrity": "sha512-LLt4BLHFwSfASHSF2K29SZ+ZCsbQOM+LuarPjRUuHm+Qd09hSe3GCeaQbcCr+Mik+0QFRmep/FyZBO6fJ64U3w==",
2008 | "dev": true,
2009 | "engines": {
2010 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
2011 | },
2012 | "funding": {
2013 | "type": "opencollective",
2014 | "url": "https://opencollective.com/typescript-eslint"
2015 | }
2016 | },
2017 | "node_modules/@typescript-eslint/typescript-estree": {
2018 | "version": "8.7.0",
2019 | "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.7.0.tgz",
2020 | "integrity": "sha512-MC8nmcGHsmfAKxwnluTQpNqceniT8SteVwd2voYlmiSWGOtjvGXdPl17dYu2797GVscK30Z04WRM28CrKS9WOg==",
2021 | "dev": true,
2022 | "dependencies": {
2023 | "@typescript-eslint/types": "8.7.0",
2024 | "@typescript-eslint/visitor-keys": "8.7.0",
2025 | "debug": "^4.3.4",
2026 | "fast-glob": "^3.3.2",
2027 | "is-glob": "^4.0.3",
2028 | "minimatch": "^9.0.4",
2029 | "semver": "^7.6.0",
2030 | "ts-api-utils": "^1.3.0"
2031 | },
2032 | "engines": {
2033 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
2034 | },
2035 | "funding": {
2036 | "type": "opencollective",
2037 | "url": "https://opencollective.com/typescript-eslint"
2038 | },
2039 | "peerDependenciesMeta": {
2040 | "typescript": {
2041 | "optional": true
2042 | }
2043 | }
2044 | },
2045 | "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": {
2046 | "version": "2.0.1",
2047 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
2048 | "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
2049 | "dev": true,
2050 | "dependencies": {
2051 | "balanced-match": "^1.0.0"
2052 | }
2053 | },
2054 | "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": {
2055 | "version": "9.0.5",
2056 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
2057 | "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
2058 | "dev": true,
2059 | "dependencies": {
2060 | "brace-expansion": "^2.0.1"
2061 | },
2062 | "engines": {
2063 | "node": ">=16 || 14 >=14.17"
2064 | },
2065 | "funding": {
2066 | "url": "https://github.com/sponsors/isaacs"
2067 | }
2068 | },
2069 | "node_modules/@typescript-eslint/utils": {
2070 | "version": "8.7.0",
2071 | "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.7.0.tgz",
2072 | "integrity": "sha512-ZbdUdwsl2X/s3CiyAu3gOlfQzpbuG3nTWKPoIvAu1pu5r8viiJvv2NPN2AqArL35NCYtw/lrPPfM4gxrMLNLPw==",
2073 | "dev": true,
2074 | "dependencies": {
2075 | "@eslint-community/eslint-utils": "^4.4.0",
2076 | "@typescript-eslint/scope-manager": "8.7.0",
2077 | "@typescript-eslint/types": "8.7.0",
2078 | "@typescript-eslint/typescript-estree": "8.7.0"
2079 | },
2080 | "engines": {
2081 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
2082 | },
2083 | "funding": {
2084 | "type": "opencollective",
2085 | "url": "https://opencollective.com/typescript-eslint"
2086 | },
2087 | "peerDependencies": {
2088 | "eslint": "^8.57.0 || ^9.0.0"
2089 | }
2090 | },
2091 | "node_modules/@typescript-eslint/visitor-keys": {
2092 | "version": "8.7.0",
2093 | "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.7.0.tgz",
2094 | "integrity": "sha512-b1tx0orFCCh/THWPQa2ZwWzvOeyzzp36vkJYOpVg0u8UVOIsfVrnuC9FqAw9gRKn+rG2VmWQ/zDJZzkxUnj/XQ==",
2095 | "dev": true,
2096 | "dependencies": {
2097 | "@typescript-eslint/types": "8.7.0",
2098 | "eslint-visitor-keys": "^3.4.3"
2099 | },
2100 | "engines": {
2101 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
2102 | },
2103 | "funding": {
2104 | "type": "opencollective",
2105 | "url": "https://opencollective.com/typescript-eslint"
2106 | }
2107 | },
2108 | "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": {
2109 | "version": "3.4.3",
2110 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
2111 | "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
2112 | "dev": true,
2113 | "engines": {
2114 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
2115 | },
2116 | "funding": {
2117 | "url": "https://opencollective.com/eslint"
2118 | }
2119 | },
2120 | "node_modules/@vitejs/plugin-react-swc": {
2121 | "version": "3.7.0",
2122 | "resolved": "https://registry.npmjs.org/@vitejs/plugin-react-swc/-/plugin-react-swc-3.7.0.tgz",
2123 | "integrity": "sha512-yrknSb3Dci6svCd/qhHqhFPDSw0QtjumcqdKMoNNzmOl5lMXTTiqzjWtG4Qask2HdvvzaNgSunbQGet8/GrKdA==",
2124 | "dev": true,
2125 | "dependencies": {
2126 | "@swc/core": "^1.5.7"
2127 | },
2128 | "peerDependencies": {
2129 | "vite": "^4 || ^5"
2130 | }
2131 | },
2132 | "node_modules/acorn": {
2133 | "version": "8.12.1",
2134 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz",
2135 | "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==",
2136 | "dev": true,
2137 | "bin": {
2138 | "acorn": "bin/acorn"
2139 | },
2140 | "engines": {
2141 | "node": ">=0.4.0"
2142 | }
2143 | },
2144 | "node_modules/acorn-jsx": {
2145 | "version": "5.3.2",
2146 | "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
2147 | "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
2148 | "dev": true,
2149 | "peerDependencies": {
2150 | "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
2151 | }
2152 | },
2153 | "node_modules/ajv": {
2154 | "version": "6.12.6",
2155 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
2156 | "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
2157 | "dev": true,
2158 | "dependencies": {
2159 | "fast-deep-equal": "^3.1.1",
2160 | "fast-json-stable-stringify": "^2.0.0",
2161 | "json-schema-traverse": "^0.4.1",
2162 | "uri-js": "^4.2.2"
2163 | },
2164 | "funding": {
2165 | "type": "github",
2166 | "url": "https://github.com/sponsors/epoberezkin"
2167 | }
2168 | },
2169 | "node_modules/ansi-regex": {
2170 | "version": "5.0.1",
2171 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
2172 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
2173 | "dev": true,
2174 | "engines": {
2175 | "node": ">=8"
2176 | }
2177 | },
2178 | "node_modules/ansi-styles": {
2179 | "version": "3.2.1",
2180 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
2181 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
2182 | "dependencies": {
2183 | "color-convert": "^1.9.0"
2184 | },
2185 | "engines": {
2186 | "node": ">=4"
2187 | }
2188 | },
2189 | "node_modules/argparse": {
2190 | "version": "2.0.1",
2191 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
2192 | "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
2193 | "dev": true
2194 | },
2195 | "node_modules/asynckit": {
2196 | "version": "0.4.0",
2197 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
2198 | "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
2199 | },
2200 | "node_modules/attr-accept": {
2201 | "version": "2.2.2",
2202 | "resolved": "https://registry.npmjs.org/attr-accept/-/attr-accept-2.2.2.tgz",
2203 | "integrity": "sha512-7prDjvt9HmqiZ0cl5CRjtS84sEyhsHP2coDkaZKRKVfCDo9s7iw7ChVmar78Gu9pC4SoR/28wFu/G5JJhTnqEg==",
2204 | "engines": {
2205 | "node": ">=4"
2206 | }
2207 | },
2208 | "node_modules/axios": {
2209 | "version": "1.7.7",
2210 | "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz",
2211 | "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==",
2212 | "dependencies": {
2213 | "follow-redirects": "^1.15.6",
2214 | "form-data": "^4.0.0",
2215 | "proxy-from-env": "^1.1.0"
2216 | }
2217 | },
2218 | "node_modules/babel-plugin-macros": {
2219 | "version": "3.1.0",
2220 | "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz",
2221 | "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==",
2222 | "dependencies": {
2223 | "@babel/runtime": "^7.12.5",
2224 | "cosmiconfig": "^7.0.0",
2225 | "resolve": "^1.19.0"
2226 | },
2227 | "engines": {
2228 | "node": ">=10",
2229 | "npm": ">=6"
2230 | }
2231 | },
2232 | "node_modules/balanced-match": {
2233 | "version": "1.0.2",
2234 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
2235 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
2236 | "dev": true
2237 | },
2238 | "node_modules/brace-expansion": {
2239 | "version": "1.1.11",
2240 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
2241 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
2242 | "dev": true,
2243 | "dependencies": {
2244 | "balanced-match": "^1.0.0",
2245 | "concat-map": "0.0.1"
2246 | }
2247 | },
2248 | "node_modules/braces": {
2249 | "version": "3.0.3",
2250 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
2251 | "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
2252 | "dev": true,
2253 | "dependencies": {
2254 | "fill-range": "^7.1.1"
2255 | },
2256 | "engines": {
2257 | "node": ">=8"
2258 | }
2259 | },
2260 | "node_modules/callsites": {
2261 | "version": "3.1.0",
2262 | "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
2263 | "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
2264 | "engines": {
2265 | "node": ">=6"
2266 | }
2267 | },
2268 | "node_modules/chalk": {
2269 | "version": "2.4.2",
2270 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
2271 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
2272 | "dependencies": {
2273 | "ansi-styles": "^3.2.1",
2274 | "escape-string-regexp": "^1.0.5",
2275 | "supports-color": "^5.3.0"
2276 | },
2277 | "engines": {
2278 | "node": ">=4"
2279 | }
2280 | },
2281 | "node_modules/chalk/node_modules/escape-string-regexp": {
2282 | "version": "1.0.5",
2283 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
2284 | "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
2285 | "engines": {
2286 | "node": ">=0.8.0"
2287 | }
2288 | },
2289 | "node_modules/clsx": {
2290 | "version": "2.1.1",
2291 | "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz",
2292 | "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==",
2293 | "engines": {
2294 | "node": ">=6"
2295 | }
2296 | },
2297 | "node_modules/color-convert": {
2298 | "version": "1.9.3",
2299 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
2300 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
2301 | "dependencies": {
2302 | "color-name": "1.1.3"
2303 | }
2304 | },
2305 | "node_modules/color-name": {
2306 | "version": "1.1.3",
2307 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
2308 | "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="
2309 | },
2310 | "node_modules/combined-stream": {
2311 | "version": "1.0.8",
2312 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
2313 | "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
2314 | "dependencies": {
2315 | "delayed-stream": "~1.0.0"
2316 | },
2317 | "engines": {
2318 | "node": ">= 0.8"
2319 | }
2320 | },
2321 | "node_modules/concat-map": {
2322 | "version": "0.0.1",
2323 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
2324 | "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
2325 | "dev": true
2326 | },
2327 | "node_modules/convert-source-map": {
2328 | "version": "1.9.0",
2329 | "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz",
2330 | "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A=="
2331 | },
2332 | "node_modules/cosmiconfig": {
2333 | "version": "7.1.0",
2334 | "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz",
2335 | "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==",
2336 | "dependencies": {
2337 | "@types/parse-json": "^4.0.0",
2338 | "import-fresh": "^3.2.1",
2339 | "parse-json": "^5.0.0",
2340 | "path-type": "^4.0.0",
2341 | "yaml": "^1.10.0"
2342 | },
2343 | "engines": {
2344 | "node": ">=10"
2345 | }
2346 | },
2347 | "node_modules/cross-spawn": {
2348 | "version": "7.0.3",
2349 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
2350 | "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
2351 | "dev": true,
2352 | "dependencies": {
2353 | "path-key": "^3.1.0",
2354 | "shebang-command": "^2.0.0",
2355 | "which": "^2.0.1"
2356 | },
2357 | "engines": {
2358 | "node": ">= 8"
2359 | }
2360 | },
2361 | "node_modules/csstype": {
2362 | "version": "3.1.3",
2363 | "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
2364 | "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="
2365 | },
2366 | "node_modules/debug": {
2367 | "version": "4.3.7",
2368 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
2369 | "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
2370 | "dependencies": {
2371 | "ms": "^2.1.3"
2372 | },
2373 | "engines": {
2374 | "node": ">=6.0"
2375 | },
2376 | "peerDependenciesMeta": {
2377 | "supports-color": {
2378 | "optional": true
2379 | }
2380 | }
2381 | },
2382 | "node_modules/deep-is": {
2383 | "version": "0.1.4",
2384 | "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
2385 | "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
2386 | "dev": true
2387 | },
2388 | "node_modules/delayed-stream": {
2389 | "version": "1.0.0",
2390 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
2391 | "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
2392 | "engines": {
2393 | "node": ">=0.4.0"
2394 | }
2395 | },
2396 | "node_modules/dom-helpers": {
2397 | "version": "5.2.1",
2398 | "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz",
2399 | "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==",
2400 | "dependencies": {
2401 | "@babel/runtime": "^7.8.7",
2402 | "csstype": "^3.0.2"
2403 | }
2404 | },
2405 | "node_modules/error-ex": {
2406 | "version": "1.3.2",
2407 | "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
2408 | "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
2409 | "dependencies": {
2410 | "is-arrayish": "^0.2.1"
2411 | }
2412 | },
2413 | "node_modules/esbuild": {
2414 | "version": "0.21.5",
2415 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz",
2416 | "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==",
2417 | "dev": true,
2418 | "hasInstallScript": true,
2419 | "bin": {
2420 | "esbuild": "bin/esbuild"
2421 | },
2422 | "engines": {
2423 | "node": ">=12"
2424 | },
2425 | "optionalDependencies": {
2426 | "@esbuild/aix-ppc64": "0.21.5",
2427 | "@esbuild/android-arm": "0.21.5",
2428 | "@esbuild/android-arm64": "0.21.5",
2429 | "@esbuild/android-x64": "0.21.5",
2430 | "@esbuild/darwin-arm64": "0.21.5",
2431 | "@esbuild/darwin-x64": "0.21.5",
2432 | "@esbuild/freebsd-arm64": "0.21.5",
2433 | "@esbuild/freebsd-x64": "0.21.5",
2434 | "@esbuild/linux-arm": "0.21.5",
2435 | "@esbuild/linux-arm64": "0.21.5",
2436 | "@esbuild/linux-ia32": "0.21.5",
2437 | "@esbuild/linux-loong64": "0.21.5",
2438 | "@esbuild/linux-mips64el": "0.21.5",
2439 | "@esbuild/linux-ppc64": "0.21.5",
2440 | "@esbuild/linux-riscv64": "0.21.5",
2441 | "@esbuild/linux-s390x": "0.21.5",
2442 | "@esbuild/linux-x64": "0.21.5",
2443 | "@esbuild/netbsd-x64": "0.21.5",
2444 | "@esbuild/openbsd-x64": "0.21.5",
2445 | "@esbuild/sunos-x64": "0.21.5",
2446 | "@esbuild/win32-arm64": "0.21.5",
2447 | "@esbuild/win32-ia32": "0.21.5",
2448 | "@esbuild/win32-x64": "0.21.5"
2449 | }
2450 | },
2451 | "node_modules/escape-string-regexp": {
2452 | "version": "4.0.0",
2453 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
2454 | "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
2455 | "engines": {
2456 | "node": ">=10"
2457 | },
2458 | "funding": {
2459 | "url": "https://github.com/sponsors/sindresorhus"
2460 | }
2461 | },
2462 | "node_modules/eslint": {
2463 | "version": "9.11.1",
2464 | "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.11.1.tgz",
2465 | "integrity": "sha512-MobhYKIoAO1s1e4VUrgx1l1Sk2JBR/Gqjjgw8+mfgoLE2xwsHur4gdfTxyTgShrhvdVFTaJSgMiQBl1jv/AWxg==",
2466 | "dev": true,
2467 | "dependencies": {
2468 | "@eslint-community/eslint-utils": "^4.2.0",
2469 | "@eslint-community/regexpp": "^4.11.0",
2470 | "@eslint/config-array": "^0.18.0",
2471 | "@eslint/core": "^0.6.0",
2472 | "@eslint/eslintrc": "^3.1.0",
2473 | "@eslint/js": "9.11.1",
2474 | "@eslint/plugin-kit": "^0.2.0",
2475 | "@humanwhocodes/module-importer": "^1.0.1",
2476 | "@humanwhocodes/retry": "^0.3.0",
2477 | "@nodelib/fs.walk": "^1.2.8",
2478 | "@types/estree": "^1.0.6",
2479 | "@types/json-schema": "^7.0.15",
2480 | "ajv": "^6.12.4",
2481 | "chalk": "^4.0.0",
2482 | "cross-spawn": "^7.0.2",
2483 | "debug": "^4.3.2",
2484 | "escape-string-regexp": "^4.0.0",
2485 | "eslint-scope": "^8.0.2",
2486 | "eslint-visitor-keys": "^4.0.0",
2487 | "espree": "^10.1.0",
2488 | "esquery": "^1.5.0",
2489 | "esutils": "^2.0.2",
2490 | "fast-deep-equal": "^3.1.3",
2491 | "file-entry-cache": "^8.0.0",
2492 | "find-up": "^5.0.0",
2493 | "glob-parent": "^6.0.2",
2494 | "ignore": "^5.2.0",
2495 | "imurmurhash": "^0.1.4",
2496 | "is-glob": "^4.0.0",
2497 | "is-path-inside": "^3.0.3",
2498 | "json-stable-stringify-without-jsonify": "^1.0.1",
2499 | "lodash.merge": "^4.6.2",
2500 | "minimatch": "^3.1.2",
2501 | "natural-compare": "^1.4.0",
2502 | "optionator": "^0.9.3",
2503 | "strip-ansi": "^6.0.1",
2504 | "text-table": "^0.2.0"
2505 | },
2506 | "bin": {
2507 | "eslint": "bin/eslint.js"
2508 | },
2509 | "engines": {
2510 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
2511 | },
2512 | "funding": {
2513 | "url": "https://eslint.org/donate"
2514 | },
2515 | "peerDependencies": {
2516 | "jiti": "*"
2517 | },
2518 | "peerDependenciesMeta": {
2519 | "jiti": {
2520 | "optional": true
2521 | }
2522 | }
2523 | },
2524 | "node_modules/eslint-plugin-react-hooks": {
2525 | "version": "5.1.0-rc-fb9a90fa48-20240614",
2526 | "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.1.0-rc-fb9a90fa48-20240614.tgz",
2527 | "integrity": "sha512-xsiRwaDNF5wWNC4ZHLut+x/YcAxksUd9Rizt7LaEn3bV8VyYRpXnRJQlLOfYaVy9esk4DFP4zPPnoNVjq5Gc0w==",
2528 | "dev": true,
2529 | "engines": {
2530 | "node": ">=10"
2531 | },
2532 | "peerDependencies": {
2533 | "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0"
2534 | }
2535 | },
2536 | "node_modules/eslint-plugin-react-refresh": {
2537 | "version": "0.4.12",
2538 | "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.12.tgz",
2539 | "integrity": "sha512-9neVjoGv20FwYtCP6CB1dzR1vr57ZDNOXst21wd2xJ/cTlM2xLq0GWVlSNTdMn/4BtP6cHYBMCSp1wFBJ9jBsg==",
2540 | "dev": true,
2541 | "peerDependencies": {
2542 | "eslint": ">=7"
2543 | }
2544 | },
2545 | "node_modules/eslint-scope": {
2546 | "version": "8.0.2",
2547 | "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.0.2.tgz",
2548 | "integrity": "sha512-6E4xmrTw5wtxnLA5wYL3WDfhZ/1bUBGOXV0zQvVRDOtrR8D0p6W7fs3JweNYhwRYeGvd/1CKX2se0/2s7Q/nJA==",
2549 | "dev": true,
2550 | "dependencies": {
2551 | "esrecurse": "^4.3.0",
2552 | "estraverse": "^5.2.0"
2553 | },
2554 | "engines": {
2555 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
2556 | },
2557 | "funding": {
2558 | "url": "https://opencollective.com/eslint"
2559 | }
2560 | },
2561 | "node_modules/eslint-visitor-keys": {
2562 | "version": "4.0.0",
2563 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz",
2564 | "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==",
2565 | "dev": true,
2566 | "engines": {
2567 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
2568 | },
2569 | "funding": {
2570 | "url": "https://opencollective.com/eslint"
2571 | }
2572 | },
2573 | "node_modules/eslint/node_modules/ansi-styles": {
2574 | "version": "4.3.0",
2575 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
2576 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
2577 | "dev": true,
2578 | "dependencies": {
2579 | "color-convert": "^2.0.1"
2580 | },
2581 | "engines": {
2582 | "node": ">=8"
2583 | },
2584 | "funding": {
2585 | "url": "https://github.com/chalk/ansi-styles?sponsor=1"
2586 | }
2587 | },
2588 | "node_modules/eslint/node_modules/chalk": {
2589 | "version": "4.1.2",
2590 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
2591 | "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
2592 | "dev": true,
2593 | "dependencies": {
2594 | "ansi-styles": "^4.1.0",
2595 | "supports-color": "^7.1.0"
2596 | },
2597 | "engines": {
2598 | "node": ">=10"
2599 | },
2600 | "funding": {
2601 | "url": "https://github.com/chalk/chalk?sponsor=1"
2602 | }
2603 | },
2604 | "node_modules/eslint/node_modules/color-convert": {
2605 | "version": "2.0.1",
2606 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
2607 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
2608 | "dev": true,
2609 | "dependencies": {
2610 | "color-name": "~1.1.4"
2611 | },
2612 | "engines": {
2613 | "node": ">=7.0.0"
2614 | }
2615 | },
2616 | "node_modules/eslint/node_modules/color-name": {
2617 | "version": "1.1.4",
2618 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
2619 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
2620 | "dev": true
2621 | },
2622 | "node_modules/eslint/node_modules/has-flag": {
2623 | "version": "4.0.0",
2624 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
2625 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
2626 | "dev": true,
2627 | "engines": {
2628 | "node": ">=8"
2629 | }
2630 | },
2631 | "node_modules/eslint/node_modules/supports-color": {
2632 | "version": "7.2.0",
2633 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
2634 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
2635 | "dev": true,
2636 | "dependencies": {
2637 | "has-flag": "^4.0.0"
2638 | },
2639 | "engines": {
2640 | "node": ">=8"
2641 | }
2642 | },
2643 | "node_modules/espree": {
2644 | "version": "10.1.0",
2645 | "resolved": "https://registry.npmjs.org/espree/-/espree-10.1.0.tgz",
2646 | "integrity": "sha512-M1M6CpiE6ffoigIOWYO9UDP8TMUw9kqb21tf+08IgDYjCsOvCuDt4jQcZmoYxx+w7zlKw9/N0KXfto+I8/FrXA==",
2647 | "dev": true,
2648 | "dependencies": {
2649 | "acorn": "^8.12.0",
2650 | "acorn-jsx": "^5.3.2",
2651 | "eslint-visitor-keys": "^4.0.0"
2652 | },
2653 | "engines": {
2654 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
2655 | },
2656 | "funding": {
2657 | "url": "https://opencollective.com/eslint"
2658 | }
2659 | },
2660 | "node_modules/esquery": {
2661 | "version": "1.6.0",
2662 | "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz",
2663 | "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==",
2664 | "dev": true,
2665 | "dependencies": {
2666 | "estraverse": "^5.1.0"
2667 | },
2668 | "engines": {
2669 | "node": ">=0.10"
2670 | }
2671 | },
2672 | "node_modules/esrecurse": {
2673 | "version": "4.3.0",
2674 | "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
2675 | "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
2676 | "dev": true,
2677 | "dependencies": {
2678 | "estraverse": "^5.2.0"
2679 | },
2680 | "engines": {
2681 | "node": ">=4.0"
2682 | }
2683 | },
2684 | "node_modules/estraverse": {
2685 | "version": "5.3.0",
2686 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
2687 | "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
2688 | "dev": true,
2689 | "engines": {
2690 | "node": ">=4.0"
2691 | }
2692 | },
2693 | "node_modules/esutils": {
2694 | "version": "2.0.3",
2695 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
2696 | "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
2697 | "dev": true,
2698 | "engines": {
2699 | "node": ">=0.10.0"
2700 | }
2701 | },
2702 | "node_modules/fast-deep-equal": {
2703 | "version": "3.1.3",
2704 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
2705 | "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
2706 | "dev": true
2707 | },
2708 | "node_modules/fast-glob": {
2709 | "version": "3.3.2",
2710 | "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz",
2711 | "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==",
2712 | "dev": true,
2713 | "dependencies": {
2714 | "@nodelib/fs.stat": "^2.0.2",
2715 | "@nodelib/fs.walk": "^1.2.3",
2716 | "glob-parent": "^5.1.2",
2717 | "merge2": "^1.3.0",
2718 | "micromatch": "^4.0.4"
2719 | },
2720 | "engines": {
2721 | "node": ">=8.6.0"
2722 | }
2723 | },
2724 | "node_modules/fast-glob/node_modules/glob-parent": {
2725 | "version": "5.1.2",
2726 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
2727 | "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
2728 | "dev": true,
2729 | "dependencies": {
2730 | "is-glob": "^4.0.1"
2731 | },
2732 | "engines": {
2733 | "node": ">= 6"
2734 | }
2735 | },
2736 | "node_modules/fast-json-stable-stringify": {
2737 | "version": "2.1.0",
2738 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
2739 | "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
2740 | "dev": true
2741 | },
2742 | "node_modules/fast-levenshtein": {
2743 | "version": "2.0.6",
2744 | "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
2745 | "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
2746 | "dev": true
2747 | },
2748 | "node_modules/fastq": {
2749 | "version": "1.17.1",
2750 | "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz",
2751 | "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==",
2752 | "dev": true,
2753 | "dependencies": {
2754 | "reusify": "^1.0.4"
2755 | }
2756 | },
2757 | "node_modules/file-entry-cache": {
2758 | "version": "8.0.0",
2759 | "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz",
2760 | "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==",
2761 | "dev": true,
2762 | "dependencies": {
2763 | "flat-cache": "^4.0.0"
2764 | },
2765 | "engines": {
2766 | "node": ">=16.0.0"
2767 | }
2768 | },
2769 | "node_modules/file-selector": {
2770 | "version": "0.6.0",
2771 | "resolved": "https://registry.npmjs.org/file-selector/-/file-selector-0.6.0.tgz",
2772 | "integrity": "sha512-QlZ5yJC0VxHxQQsQhXvBaC7VRJ2uaxTf+Tfpu4Z/OcVQJVpZO+DGU0rkoVW5ce2SccxugvpBJoMvUs59iILYdw==",
2773 | "dependencies": {
2774 | "tslib": "^2.4.0"
2775 | },
2776 | "engines": {
2777 | "node": ">= 12"
2778 | }
2779 | },
2780 | "node_modules/fill-range": {
2781 | "version": "7.1.1",
2782 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
2783 | "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
2784 | "dev": true,
2785 | "dependencies": {
2786 | "to-regex-range": "^5.0.1"
2787 | },
2788 | "engines": {
2789 | "node": ">=8"
2790 | }
2791 | },
2792 | "node_modules/find-root": {
2793 | "version": "1.1.0",
2794 | "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz",
2795 | "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng=="
2796 | },
2797 | "node_modules/find-up": {
2798 | "version": "5.0.0",
2799 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
2800 | "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
2801 | "dev": true,
2802 | "dependencies": {
2803 | "locate-path": "^6.0.0",
2804 | "path-exists": "^4.0.0"
2805 | },
2806 | "engines": {
2807 | "node": ">=10"
2808 | },
2809 | "funding": {
2810 | "url": "https://github.com/sponsors/sindresorhus"
2811 | }
2812 | },
2813 | "node_modules/flat-cache": {
2814 | "version": "4.0.1",
2815 | "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz",
2816 | "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==",
2817 | "dev": true,
2818 | "dependencies": {
2819 | "flatted": "^3.2.9",
2820 | "keyv": "^4.5.4"
2821 | },
2822 | "engines": {
2823 | "node": ">=16"
2824 | }
2825 | },
2826 | "node_modules/flatted": {
2827 | "version": "3.3.1",
2828 | "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz",
2829 | "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==",
2830 | "dev": true
2831 | },
2832 | "node_modules/follow-redirects": {
2833 | "version": "1.15.9",
2834 | "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz",
2835 | "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==",
2836 | "funding": [
2837 | {
2838 | "type": "individual",
2839 | "url": "https://github.com/sponsors/RubenVerborgh"
2840 | }
2841 | ],
2842 | "engines": {
2843 | "node": ">=4.0"
2844 | },
2845 | "peerDependenciesMeta": {
2846 | "debug": {
2847 | "optional": true
2848 | }
2849 | }
2850 | },
2851 | "node_modules/form-data": {
2852 | "version": "4.0.0",
2853 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
2854 | "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
2855 | "dependencies": {
2856 | "asynckit": "^0.4.0",
2857 | "combined-stream": "^1.0.8",
2858 | "mime-types": "^2.1.12"
2859 | },
2860 | "engines": {
2861 | "node": ">= 6"
2862 | }
2863 | },
2864 | "node_modules/fsevents": {
2865 | "version": "2.3.3",
2866 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
2867 | "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
2868 | "dev": true,
2869 | "hasInstallScript": true,
2870 | "optional": true,
2871 | "os": [
2872 | "darwin"
2873 | ],
2874 | "engines": {
2875 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
2876 | }
2877 | },
2878 | "node_modules/function-bind": {
2879 | "version": "1.1.2",
2880 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
2881 | "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
2882 | "funding": {
2883 | "url": "https://github.com/sponsors/ljharb"
2884 | }
2885 | },
2886 | "node_modules/glob-parent": {
2887 | "version": "6.0.2",
2888 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
2889 | "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
2890 | "dev": true,
2891 | "dependencies": {
2892 | "is-glob": "^4.0.3"
2893 | },
2894 | "engines": {
2895 | "node": ">=10.13.0"
2896 | }
2897 | },
2898 | "node_modules/globals": {
2899 | "version": "15.9.0",
2900 | "resolved": "https://registry.npmjs.org/globals/-/globals-15.9.0.tgz",
2901 | "integrity": "sha512-SmSKyLLKFbSr6rptvP8izbyxJL4ILwqO9Jg23UA0sDlGlu58V59D1//I3vlc0KJphVdUR7vMjHIplYnzBxorQA==",
2902 | "dev": true,
2903 | "engines": {
2904 | "node": ">=18"
2905 | },
2906 | "funding": {
2907 | "url": "https://github.com/sponsors/sindresorhus"
2908 | }
2909 | },
2910 | "node_modules/graphemer": {
2911 | "version": "1.4.0",
2912 | "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
2913 | "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
2914 | "dev": true
2915 | },
2916 | "node_modules/has-flag": {
2917 | "version": "3.0.0",
2918 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
2919 | "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
2920 | "engines": {
2921 | "node": ">=4"
2922 | }
2923 | },
2924 | "node_modules/hasown": {
2925 | "version": "2.0.2",
2926 | "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
2927 | "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
2928 | "dependencies": {
2929 | "function-bind": "^1.1.2"
2930 | },
2931 | "engines": {
2932 | "node": ">= 0.4"
2933 | }
2934 | },
2935 | "node_modules/hoist-non-react-statics": {
2936 | "version": "3.3.2",
2937 | "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
2938 | "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
2939 | "dependencies": {
2940 | "react-is": "^16.7.0"
2941 | }
2942 | },
2943 | "node_modules/hoist-non-react-statics/node_modules/react-is": {
2944 | "version": "16.13.1",
2945 | "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
2946 | "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
2947 | },
2948 | "node_modules/ignore": {
2949 | "version": "5.3.2",
2950 | "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
2951 | "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
2952 | "dev": true,
2953 | "engines": {
2954 | "node": ">= 4"
2955 | }
2956 | },
2957 | "node_modules/import-fresh": {
2958 | "version": "3.3.0",
2959 | "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
2960 | "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
2961 | "dependencies": {
2962 | "parent-module": "^1.0.0",
2963 | "resolve-from": "^4.0.0"
2964 | },
2965 | "engines": {
2966 | "node": ">=6"
2967 | },
2968 | "funding": {
2969 | "url": "https://github.com/sponsors/sindresorhus"
2970 | }
2971 | },
2972 | "node_modules/imurmurhash": {
2973 | "version": "0.1.4",
2974 | "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
2975 | "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
2976 | "dev": true,
2977 | "engines": {
2978 | "node": ">=0.8.19"
2979 | }
2980 | },
2981 | "node_modules/inherits": {
2982 | "version": "2.0.3",
2983 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
2984 | "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==",
2985 | "dev": true
2986 | },
2987 | "node_modules/is-arrayish": {
2988 | "version": "0.2.1",
2989 | "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
2990 | "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg=="
2991 | },
2992 | "node_modules/is-core-module": {
2993 | "version": "2.15.1",
2994 | "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz",
2995 | "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==",
2996 | "dependencies": {
2997 | "hasown": "^2.0.2"
2998 | },
2999 | "engines": {
3000 | "node": ">= 0.4"
3001 | },
3002 | "funding": {
3003 | "url": "https://github.com/sponsors/ljharb"
3004 | }
3005 | },
3006 | "node_modules/is-extglob": {
3007 | "version": "2.1.1",
3008 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
3009 | "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
3010 | "dev": true,
3011 | "engines": {
3012 | "node": ">=0.10.0"
3013 | }
3014 | },
3015 | "node_modules/is-glob": {
3016 | "version": "4.0.3",
3017 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
3018 | "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
3019 | "dev": true,
3020 | "dependencies": {
3021 | "is-extglob": "^2.1.1"
3022 | },
3023 | "engines": {
3024 | "node": ">=0.10.0"
3025 | }
3026 | },
3027 | "node_modules/is-number": {
3028 | "version": "7.0.0",
3029 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
3030 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
3031 | "dev": true,
3032 | "engines": {
3033 | "node": ">=0.12.0"
3034 | }
3035 | },
3036 | "node_modules/is-path-inside": {
3037 | "version": "3.0.3",
3038 | "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
3039 | "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==",
3040 | "dev": true,
3041 | "engines": {
3042 | "node": ">=8"
3043 | }
3044 | },
3045 | "node_modules/isexe": {
3046 | "version": "2.0.0",
3047 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
3048 | "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
3049 | "dev": true
3050 | },
3051 | "node_modules/js-tokens": {
3052 | "version": "4.0.0",
3053 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
3054 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
3055 | },
3056 | "node_modules/js-yaml": {
3057 | "version": "4.1.0",
3058 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
3059 | "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
3060 | "dev": true,
3061 | "dependencies": {
3062 | "argparse": "^2.0.1"
3063 | },
3064 | "bin": {
3065 | "js-yaml": "bin/js-yaml.js"
3066 | }
3067 | },
3068 | "node_modules/jsesc": {
3069 | "version": "2.5.2",
3070 | "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
3071 | "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
3072 | "bin": {
3073 | "jsesc": "bin/jsesc"
3074 | },
3075 | "engines": {
3076 | "node": ">=4"
3077 | }
3078 | },
3079 | "node_modules/json-buffer": {
3080 | "version": "3.0.1",
3081 | "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
3082 | "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
3083 | "dev": true
3084 | },
3085 | "node_modules/json-parse-even-better-errors": {
3086 | "version": "2.3.1",
3087 | "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
3088 | "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w=="
3089 | },
3090 | "node_modules/json-schema-traverse": {
3091 | "version": "0.4.1",
3092 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
3093 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
3094 | "dev": true
3095 | },
3096 | "node_modules/json-stable-stringify-without-jsonify": {
3097 | "version": "1.0.1",
3098 | "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
3099 | "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
3100 | "dev": true
3101 | },
3102 | "node_modules/keyv": {
3103 | "version": "4.5.4",
3104 | "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
3105 | "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
3106 | "dev": true,
3107 | "dependencies": {
3108 | "json-buffer": "3.0.1"
3109 | }
3110 | },
3111 | "node_modules/levn": {
3112 | "version": "0.4.1",
3113 | "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
3114 | "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
3115 | "dev": true,
3116 | "dependencies": {
3117 | "prelude-ls": "^1.2.1",
3118 | "type-check": "~0.4.0"
3119 | },
3120 | "engines": {
3121 | "node": ">= 0.8.0"
3122 | }
3123 | },
3124 | "node_modules/lines-and-columns": {
3125 | "version": "1.2.4",
3126 | "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
3127 | "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="
3128 | },
3129 | "node_modules/locate-path": {
3130 | "version": "6.0.0",
3131 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
3132 | "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
3133 | "dev": true,
3134 | "dependencies": {
3135 | "p-locate": "^5.0.0"
3136 | },
3137 | "engines": {
3138 | "node": ">=10"
3139 | },
3140 | "funding": {
3141 | "url": "https://github.com/sponsors/sindresorhus"
3142 | }
3143 | },
3144 | "node_modules/lodash.merge": {
3145 | "version": "4.6.2",
3146 | "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
3147 | "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
3148 | "dev": true
3149 | },
3150 | "node_modules/loose-envify": {
3151 | "version": "1.4.0",
3152 | "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
3153 | "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
3154 | "dependencies": {
3155 | "js-tokens": "^3.0.0 || ^4.0.0"
3156 | },
3157 | "bin": {
3158 | "loose-envify": "cli.js"
3159 | }
3160 | },
3161 | "node_modules/merge2": {
3162 | "version": "1.4.1",
3163 | "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
3164 | "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
3165 | "dev": true,
3166 | "engines": {
3167 | "node": ">= 8"
3168 | }
3169 | },
3170 | "node_modules/micromatch": {
3171 | "version": "4.0.8",
3172 | "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
3173 | "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
3174 | "dev": true,
3175 | "dependencies": {
3176 | "braces": "^3.0.3",
3177 | "picomatch": "^2.3.1"
3178 | },
3179 | "engines": {
3180 | "node": ">=8.6"
3181 | }
3182 | },
3183 | "node_modules/mime-db": {
3184 | "version": "1.52.0",
3185 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
3186 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
3187 | "engines": {
3188 | "node": ">= 0.6"
3189 | }
3190 | },
3191 | "node_modules/mime-types": {
3192 | "version": "2.1.35",
3193 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
3194 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
3195 | "dependencies": {
3196 | "mime-db": "1.52.0"
3197 | },
3198 | "engines": {
3199 | "node": ">= 0.6"
3200 | }
3201 | },
3202 | "node_modules/minimatch": {
3203 | "version": "3.1.2",
3204 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
3205 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
3206 | "dev": true,
3207 | "dependencies": {
3208 | "brace-expansion": "^1.1.7"
3209 | },
3210 | "engines": {
3211 | "node": "*"
3212 | }
3213 | },
3214 | "node_modules/ms": {
3215 | "version": "2.1.3",
3216 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
3217 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
3218 | },
3219 | "node_modules/nanoid": {
3220 | "version": "3.3.7",
3221 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
3222 | "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
3223 | "dev": true,
3224 | "funding": [
3225 | {
3226 | "type": "github",
3227 | "url": "https://github.com/sponsors/ai"
3228 | }
3229 | ],
3230 | "bin": {
3231 | "nanoid": "bin/nanoid.cjs"
3232 | },
3233 | "engines": {
3234 | "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
3235 | }
3236 | },
3237 | "node_modules/natural-compare": {
3238 | "version": "1.4.0",
3239 | "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
3240 | "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
3241 | "dev": true
3242 | },
3243 | "node_modules/object-assign": {
3244 | "version": "4.1.1",
3245 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
3246 | "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
3247 | "engines": {
3248 | "node": ">=0.10.0"
3249 | }
3250 | },
3251 | "node_modules/optionator": {
3252 | "version": "0.9.4",
3253 | "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
3254 | "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==",
3255 | "dev": true,
3256 | "dependencies": {
3257 | "deep-is": "^0.1.3",
3258 | "fast-levenshtein": "^2.0.6",
3259 | "levn": "^0.4.1",
3260 | "prelude-ls": "^1.2.1",
3261 | "type-check": "^0.4.0",
3262 | "word-wrap": "^1.2.5"
3263 | },
3264 | "engines": {
3265 | "node": ">= 0.8.0"
3266 | }
3267 | },
3268 | "node_modules/p-limit": {
3269 | "version": "3.1.0",
3270 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
3271 | "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
3272 | "dev": true,
3273 | "dependencies": {
3274 | "yocto-queue": "^0.1.0"
3275 | },
3276 | "engines": {
3277 | "node": ">=10"
3278 | },
3279 | "funding": {
3280 | "url": "https://github.com/sponsors/sindresorhus"
3281 | }
3282 | },
3283 | "node_modules/p-locate": {
3284 | "version": "5.0.0",
3285 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
3286 | "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
3287 | "dev": true,
3288 | "dependencies": {
3289 | "p-limit": "^3.0.2"
3290 | },
3291 | "engines": {
3292 | "node": ">=10"
3293 | },
3294 | "funding": {
3295 | "url": "https://github.com/sponsors/sindresorhus"
3296 | }
3297 | },
3298 | "node_modules/parent-module": {
3299 | "version": "1.0.1",
3300 | "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
3301 | "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
3302 | "dependencies": {
3303 | "callsites": "^3.0.0"
3304 | },
3305 | "engines": {
3306 | "node": ">=6"
3307 | }
3308 | },
3309 | "node_modules/parse-json": {
3310 | "version": "5.2.0",
3311 | "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
3312 | "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
3313 | "dependencies": {
3314 | "@babel/code-frame": "^7.0.0",
3315 | "error-ex": "^1.3.1",
3316 | "json-parse-even-better-errors": "^2.3.0",
3317 | "lines-and-columns": "^1.1.6"
3318 | },
3319 | "engines": {
3320 | "node": ">=8"
3321 | },
3322 | "funding": {
3323 | "url": "https://github.com/sponsors/sindresorhus"
3324 | }
3325 | },
3326 | "node_modules/path": {
3327 | "version": "0.12.7",
3328 | "resolved": "https://registry.npmjs.org/path/-/path-0.12.7.tgz",
3329 | "integrity": "sha512-aXXC6s+1w7otVF9UletFkFcDsJeO7lSZBPUQhtb5O0xJe8LtYhj/GxldoL09bBj9+ZmE2hNoHqQSFMN5fikh4Q==",
3330 | "dev": true,
3331 | "dependencies": {
3332 | "process": "^0.11.1",
3333 | "util": "^0.10.3"
3334 | }
3335 | },
3336 | "node_modules/path-exists": {
3337 | "version": "4.0.0",
3338 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
3339 | "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
3340 | "dev": true,
3341 | "engines": {
3342 | "node": ">=8"
3343 | }
3344 | },
3345 | "node_modules/path-key": {
3346 | "version": "3.1.1",
3347 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
3348 | "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
3349 | "dev": true,
3350 | "engines": {
3351 | "node": ">=8"
3352 | }
3353 | },
3354 | "node_modules/path-parse": {
3355 | "version": "1.0.7",
3356 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
3357 | "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
3358 | },
3359 | "node_modules/path-type": {
3360 | "version": "4.0.0",
3361 | "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
3362 | "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
3363 | "engines": {
3364 | "node": ">=8"
3365 | }
3366 | },
3367 | "node_modules/picocolors": {
3368 | "version": "1.1.0",
3369 | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz",
3370 | "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw=="
3371 | },
3372 | "node_modules/picomatch": {
3373 | "version": "2.3.1",
3374 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
3375 | "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
3376 | "dev": true,
3377 | "engines": {
3378 | "node": ">=8.6"
3379 | },
3380 | "funding": {
3381 | "url": "https://github.com/sponsors/jonschlinkert"
3382 | }
3383 | },
3384 | "node_modules/postcss": {
3385 | "version": "8.4.47",
3386 | "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz",
3387 | "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==",
3388 | "dev": true,
3389 | "funding": [
3390 | {
3391 | "type": "opencollective",
3392 | "url": "https://opencollective.com/postcss/"
3393 | },
3394 | {
3395 | "type": "tidelift",
3396 | "url": "https://tidelift.com/funding/github/npm/postcss"
3397 | },
3398 | {
3399 | "type": "github",
3400 | "url": "https://github.com/sponsors/ai"
3401 | }
3402 | ],
3403 | "dependencies": {
3404 | "nanoid": "^3.3.7",
3405 | "picocolors": "^1.1.0",
3406 | "source-map-js": "^1.2.1"
3407 | },
3408 | "engines": {
3409 | "node": "^10 || ^12 || >=14"
3410 | }
3411 | },
3412 | "node_modules/prelude-ls": {
3413 | "version": "1.2.1",
3414 | "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
3415 | "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
3416 | "dev": true,
3417 | "engines": {
3418 | "node": ">= 0.8.0"
3419 | }
3420 | },
3421 | "node_modules/process": {
3422 | "version": "0.11.10",
3423 | "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
3424 | "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==",
3425 | "dev": true,
3426 | "engines": {
3427 | "node": ">= 0.6.0"
3428 | }
3429 | },
3430 | "node_modules/prop-types": {
3431 | "version": "15.8.1",
3432 | "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
3433 | "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
3434 | "dependencies": {
3435 | "loose-envify": "^1.4.0",
3436 | "object-assign": "^4.1.1",
3437 | "react-is": "^16.13.1"
3438 | }
3439 | },
3440 | "node_modules/prop-types/node_modules/react-is": {
3441 | "version": "16.13.1",
3442 | "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
3443 | "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
3444 | },
3445 | "node_modules/proxy-from-env": {
3446 | "version": "1.1.0",
3447 | "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
3448 | "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
3449 | },
3450 | "node_modules/punycode": {
3451 | "version": "2.3.1",
3452 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
3453 | "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
3454 | "dev": true,
3455 | "engines": {
3456 | "node": ">=6"
3457 | }
3458 | },
3459 | "node_modules/queue-microtask": {
3460 | "version": "1.2.3",
3461 | "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
3462 | "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
3463 | "dev": true,
3464 | "funding": [
3465 | {
3466 | "type": "github",
3467 | "url": "https://github.com/sponsors/feross"
3468 | },
3469 | {
3470 | "type": "patreon",
3471 | "url": "https://www.patreon.com/feross"
3472 | },
3473 | {
3474 | "type": "consulting",
3475 | "url": "https://feross.org/support"
3476 | }
3477 | ]
3478 | },
3479 | "node_modules/react": {
3480 | "version": "18.3.1",
3481 | "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz",
3482 | "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==",
3483 | "dependencies": {
3484 | "loose-envify": "^1.1.0"
3485 | },
3486 | "engines": {
3487 | "node": ">=0.10.0"
3488 | }
3489 | },
3490 | "node_modules/react-dom": {
3491 | "version": "18.3.1",
3492 | "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",
3493 | "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==",
3494 | "dependencies": {
3495 | "loose-envify": "^1.1.0",
3496 | "scheduler": "^0.23.2"
3497 | },
3498 | "peerDependencies": {
3499 | "react": "^18.3.1"
3500 | }
3501 | },
3502 | "node_modules/react-dropzone": {
3503 | "version": "14.2.3",
3504 | "resolved": "https://registry.npmjs.org/react-dropzone/-/react-dropzone-14.2.3.tgz",
3505 | "integrity": "sha512-O3om8I+PkFKbxCukfIR3QAGftYXDZfOE2N1mr/7qebQJHs7U+/RSL/9xomJNpRg9kM5h9soQSdf0Gc7OHF5Fug==",
3506 | "dependencies": {
3507 | "attr-accept": "^2.2.2",
3508 | "file-selector": "^0.6.0",
3509 | "prop-types": "^15.8.1"
3510 | },
3511 | "engines": {
3512 | "node": ">= 10.13"
3513 | },
3514 | "peerDependencies": {
3515 | "react": ">= 16.8 || 18.0.0"
3516 | }
3517 | },
3518 | "node_modules/react-is": {
3519 | "version": "18.3.1",
3520 | "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
3521 | "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg=="
3522 | },
3523 | "node_modules/react-transition-group": {
3524 | "version": "4.4.5",
3525 | "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz",
3526 | "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==",
3527 | "dependencies": {
3528 | "@babel/runtime": "^7.5.5",
3529 | "dom-helpers": "^5.0.1",
3530 | "loose-envify": "^1.4.0",
3531 | "prop-types": "^15.6.2"
3532 | },
3533 | "peerDependencies": {
3534 | "react": ">=16.6.0",
3535 | "react-dom": ">=16.6.0"
3536 | }
3537 | },
3538 | "node_modules/regenerator-runtime": {
3539 | "version": "0.14.1",
3540 | "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
3541 | "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw=="
3542 | },
3543 | "node_modules/reselect": {
3544 | "version": "5.1.1",
3545 | "resolved": "https://registry.npmjs.org/reselect/-/reselect-5.1.1.tgz",
3546 | "integrity": "sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w=="
3547 | },
3548 | "node_modules/resolve": {
3549 | "version": "1.22.8",
3550 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz",
3551 | "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==",
3552 | "dependencies": {
3553 | "is-core-module": "^2.13.0",
3554 | "path-parse": "^1.0.7",
3555 | "supports-preserve-symlinks-flag": "^1.0.0"
3556 | },
3557 | "bin": {
3558 | "resolve": "bin/resolve"
3559 | },
3560 | "funding": {
3561 | "url": "https://github.com/sponsors/ljharb"
3562 | }
3563 | },
3564 | "node_modules/resolve-from": {
3565 | "version": "4.0.0",
3566 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
3567 | "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
3568 | "engines": {
3569 | "node": ">=4"
3570 | }
3571 | },
3572 | "node_modules/reusify": {
3573 | "version": "1.0.4",
3574 | "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
3575 | "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
3576 | "dev": true,
3577 | "engines": {
3578 | "iojs": ">=1.0.0",
3579 | "node": ">=0.10.0"
3580 | }
3581 | },
3582 | "node_modules/rollup": {
3583 | "version": "4.22.5",
3584 | "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.22.5.tgz",
3585 | "integrity": "sha512-WoinX7GeQOFMGznEcWA1WrTQCd/tpEbMkc3nuMs9BT0CPjMdSjPMTVClwWd4pgSQwJdP65SK9mTCNvItlr5o7w==",
3586 | "dev": true,
3587 | "dependencies": {
3588 | "@types/estree": "1.0.6"
3589 | },
3590 | "bin": {
3591 | "rollup": "dist/bin/rollup"
3592 | },
3593 | "engines": {
3594 | "node": ">=18.0.0",
3595 | "npm": ">=8.0.0"
3596 | },
3597 | "optionalDependencies": {
3598 | "@rollup/rollup-android-arm-eabi": "4.22.5",
3599 | "@rollup/rollup-android-arm64": "4.22.5",
3600 | "@rollup/rollup-darwin-arm64": "4.22.5",
3601 | "@rollup/rollup-darwin-x64": "4.22.5",
3602 | "@rollup/rollup-linux-arm-gnueabihf": "4.22.5",
3603 | "@rollup/rollup-linux-arm-musleabihf": "4.22.5",
3604 | "@rollup/rollup-linux-arm64-gnu": "4.22.5",
3605 | "@rollup/rollup-linux-arm64-musl": "4.22.5",
3606 | "@rollup/rollup-linux-powerpc64le-gnu": "4.22.5",
3607 | "@rollup/rollup-linux-riscv64-gnu": "4.22.5",
3608 | "@rollup/rollup-linux-s390x-gnu": "4.22.5",
3609 | "@rollup/rollup-linux-x64-gnu": "4.22.5",
3610 | "@rollup/rollup-linux-x64-musl": "4.22.5",
3611 | "@rollup/rollup-win32-arm64-msvc": "4.22.5",
3612 | "@rollup/rollup-win32-ia32-msvc": "4.22.5",
3613 | "@rollup/rollup-win32-x64-msvc": "4.22.5",
3614 | "fsevents": "~2.3.2"
3615 | }
3616 | },
3617 | "node_modules/run-parallel": {
3618 | "version": "1.2.0",
3619 | "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
3620 | "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
3621 | "dev": true,
3622 | "funding": [
3623 | {
3624 | "type": "github",
3625 | "url": "https://github.com/sponsors/feross"
3626 | },
3627 | {
3628 | "type": "patreon",
3629 | "url": "https://www.patreon.com/feross"
3630 | },
3631 | {
3632 | "type": "consulting",
3633 | "url": "https://feross.org/support"
3634 | }
3635 | ],
3636 | "dependencies": {
3637 | "queue-microtask": "^1.2.2"
3638 | }
3639 | },
3640 | "node_modules/scheduler": {
3641 | "version": "0.23.2",
3642 | "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz",
3643 | "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==",
3644 | "dependencies": {
3645 | "loose-envify": "^1.1.0"
3646 | }
3647 | },
3648 | "node_modules/semver": {
3649 | "version": "7.6.3",
3650 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
3651 | "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
3652 | "dev": true,
3653 | "bin": {
3654 | "semver": "bin/semver.js"
3655 | },
3656 | "engines": {
3657 | "node": ">=10"
3658 | }
3659 | },
3660 | "node_modules/shebang-command": {
3661 | "version": "2.0.0",
3662 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
3663 | "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
3664 | "dev": true,
3665 | "dependencies": {
3666 | "shebang-regex": "^3.0.0"
3667 | },
3668 | "engines": {
3669 | "node": ">=8"
3670 | }
3671 | },
3672 | "node_modules/shebang-regex": {
3673 | "version": "3.0.0",
3674 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
3675 | "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
3676 | "dev": true,
3677 | "engines": {
3678 | "node": ">=8"
3679 | }
3680 | },
3681 | "node_modules/source-map": {
3682 | "version": "0.5.7",
3683 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
3684 | "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==",
3685 | "engines": {
3686 | "node": ">=0.10.0"
3687 | }
3688 | },
3689 | "node_modules/source-map-js": {
3690 | "version": "1.2.1",
3691 | "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
3692 | "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
3693 | "dev": true,
3694 | "engines": {
3695 | "node": ">=0.10.0"
3696 | }
3697 | },
3698 | "node_modules/strip-ansi": {
3699 | "version": "6.0.1",
3700 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
3701 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
3702 | "dev": true,
3703 | "dependencies": {
3704 | "ansi-regex": "^5.0.1"
3705 | },
3706 | "engines": {
3707 | "node": ">=8"
3708 | }
3709 | },
3710 | "node_modules/strip-json-comments": {
3711 | "version": "3.1.1",
3712 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
3713 | "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
3714 | "dev": true,
3715 | "engines": {
3716 | "node": ">=8"
3717 | },
3718 | "funding": {
3719 | "url": "https://github.com/sponsors/sindresorhus"
3720 | }
3721 | },
3722 | "node_modules/stylis": {
3723 | "version": "4.2.0",
3724 | "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz",
3725 | "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw=="
3726 | },
3727 | "node_modules/supports-color": {
3728 | "version": "5.5.0",
3729 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
3730 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
3731 | "dependencies": {
3732 | "has-flag": "^3.0.0"
3733 | },
3734 | "engines": {
3735 | "node": ">=4"
3736 | }
3737 | },
3738 | "node_modules/supports-preserve-symlinks-flag": {
3739 | "version": "1.0.0",
3740 | "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
3741 | "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
3742 | "engines": {
3743 | "node": ">= 0.4"
3744 | },
3745 | "funding": {
3746 | "url": "https://github.com/sponsors/ljharb"
3747 | }
3748 | },
3749 | "node_modules/text-table": {
3750 | "version": "0.2.0",
3751 | "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
3752 | "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
3753 | "dev": true
3754 | },
3755 | "node_modules/to-fast-properties": {
3756 | "version": "2.0.0",
3757 | "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
3758 | "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==",
3759 | "engines": {
3760 | "node": ">=4"
3761 | }
3762 | },
3763 | "node_modules/to-regex-range": {
3764 | "version": "5.0.1",
3765 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
3766 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
3767 | "dev": true,
3768 | "dependencies": {
3769 | "is-number": "^7.0.0"
3770 | },
3771 | "engines": {
3772 | "node": ">=8.0"
3773 | }
3774 | },
3775 | "node_modules/ts-api-utils": {
3776 | "version": "1.3.0",
3777 | "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz",
3778 | "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==",
3779 | "dev": true,
3780 | "engines": {
3781 | "node": ">=16"
3782 | },
3783 | "peerDependencies": {
3784 | "typescript": ">=4.2.0"
3785 | }
3786 | },
3787 | "node_modules/tslib": {
3788 | "version": "2.7.0",
3789 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz",
3790 | "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA=="
3791 | },
3792 | "node_modules/type-check": {
3793 | "version": "0.4.0",
3794 | "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
3795 | "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
3796 | "dev": true,
3797 | "dependencies": {
3798 | "prelude-ls": "^1.2.1"
3799 | },
3800 | "engines": {
3801 | "node": ">= 0.8.0"
3802 | }
3803 | },
3804 | "node_modules/typescript": {
3805 | "version": "5.6.2",
3806 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.2.tgz",
3807 | "integrity": "sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==",
3808 | "dev": true,
3809 | "bin": {
3810 | "tsc": "bin/tsc",
3811 | "tsserver": "bin/tsserver"
3812 | },
3813 | "engines": {
3814 | "node": ">=14.17"
3815 | }
3816 | },
3817 | "node_modules/typescript-eslint": {
3818 | "version": "8.7.0",
3819 | "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.7.0.tgz",
3820 | "integrity": "sha512-nEHbEYJyHwsuf7c3V3RS7Saq+1+la3i0ieR3qP0yjqWSzVmh8Drp47uOl9LjbPANac4S7EFSqvcYIKXUUwIfIQ==",
3821 | "dev": true,
3822 | "dependencies": {
3823 | "@typescript-eslint/eslint-plugin": "8.7.0",
3824 | "@typescript-eslint/parser": "8.7.0",
3825 | "@typescript-eslint/utils": "8.7.0"
3826 | },
3827 | "engines": {
3828 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
3829 | },
3830 | "funding": {
3831 | "type": "opencollective",
3832 | "url": "https://opencollective.com/typescript-eslint"
3833 | },
3834 | "peerDependenciesMeta": {
3835 | "typescript": {
3836 | "optional": true
3837 | }
3838 | }
3839 | },
3840 | "node_modules/undici-types": {
3841 | "version": "6.19.8",
3842 | "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz",
3843 | "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==",
3844 | "dev": true
3845 | },
3846 | "node_modules/uri-js": {
3847 | "version": "4.4.1",
3848 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
3849 | "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
3850 | "dev": true,
3851 | "dependencies": {
3852 | "punycode": "^2.1.0"
3853 | }
3854 | },
3855 | "node_modules/util": {
3856 | "version": "0.10.4",
3857 | "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz",
3858 | "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==",
3859 | "dev": true,
3860 | "dependencies": {
3861 | "inherits": "2.0.3"
3862 | }
3863 | },
3864 | "node_modules/vite": {
3865 | "version": "5.4.8",
3866 | "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.8.tgz",
3867 | "integrity": "sha512-FqrItQ4DT1NC4zCUqMB4c4AZORMKIa0m8/URVCZ77OZ/QSNeJ54bU1vrFADbDsuwfIPcgknRkmqakQcgnL4GiQ==",
3868 | "dev": true,
3869 | "dependencies": {
3870 | "esbuild": "^0.21.3",
3871 | "postcss": "^8.4.43",
3872 | "rollup": "^4.20.0"
3873 | },
3874 | "bin": {
3875 | "vite": "bin/vite.js"
3876 | },
3877 | "engines": {
3878 | "node": "^18.0.0 || >=20.0.0"
3879 | },
3880 | "funding": {
3881 | "url": "https://github.com/vitejs/vite?sponsor=1"
3882 | },
3883 | "optionalDependencies": {
3884 | "fsevents": "~2.3.3"
3885 | },
3886 | "peerDependencies": {
3887 | "@types/node": "^18.0.0 || >=20.0.0",
3888 | "less": "*",
3889 | "lightningcss": "^1.21.0",
3890 | "sass": "*",
3891 | "sass-embedded": "*",
3892 | "stylus": "*",
3893 | "sugarss": "*",
3894 | "terser": "^5.4.0"
3895 | },
3896 | "peerDependenciesMeta": {
3897 | "@types/node": {
3898 | "optional": true
3899 | },
3900 | "less": {
3901 | "optional": true
3902 | },
3903 | "lightningcss": {
3904 | "optional": true
3905 | },
3906 | "sass": {
3907 | "optional": true
3908 | },
3909 | "sass-embedded": {
3910 | "optional": true
3911 | },
3912 | "stylus": {
3913 | "optional": true
3914 | },
3915 | "sugarss": {
3916 | "optional": true
3917 | },
3918 | "terser": {
3919 | "optional": true
3920 | }
3921 | }
3922 | },
3923 | "node_modules/which": {
3924 | "version": "2.0.2",
3925 | "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
3926 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
3927 | "dev": true,
3928 | "dependencies": {
3929 | "isexe": "^2.0.0"
3930 | },
3931 | "bin": {
3932 | "node-which": "bin/node-which"
3933 | },
3934 | "engines": {
3935 | "node": ">= 8"
3936 | }
3937 | },
3938 | "node_modules/word-wrap": {
3939 | "version": "1.2.5",
3940 | "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz",
3941 | "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==",
3942 | "dev": true,
3943 | "engines": {
3944 | "node": ">=0.10.0"
3945 | }
3946 | },
3947 | "node_modules/yaml": {
3948 | "version": "1.10.2",
3949 | "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
3950 | "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==",
3951 | "engines": {
3952 | "node": ">= 6"
3953 | }
3954 | },
3955 | "node_modules/yocto-queue": {
3956 | "version": "0.1.0",
3957 | "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
3958 | "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
3959 | "dev": true,
3960 | "engines": {
3961 | "node": ">=10"
3962 | },
3963 | "funding": {
3964 | "url": "https://github.com/sponsors/sindresorhus"
3965 | }
3966 | },
3967 | "node_modules/zustand": {
3968 | "version": "5.0.0-rc.2",
3969 | "resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.0-rc.2.tgz",
3970 | "integrity": "sha512-o2Nwuvnk8vQBX7CcHL8WfFkZNJdxB/VKeWw0tNglw8p4cypsZ3tRT7rTRTDNeUPFS0qaMBRSKe+fVwL5xpcE3A==",
3971 | "engines": {
3972 | "node": ">=12.20.0"
3973 | },
3974 | "peerDependencies": {
3975 | "@types/react": ">=18.0.0",
3976 | "immer": ">=9.0.6",
3977 | "react": ">=18.0.0",
3978 | "use-sync-external-store": ">=1.2.0"
3979 | },
3980 | "peerDependenciesMeta": {
3981 | "@types/react": {
3982 | "optional": true
3983 | },
3984 | "immer": {
3985 | "optional": true
3986 | },
3987 | "react": {
3988 | "optional": true
3989 | },
3990 | "use-sync-external-store": {
3991 | "optional": true
3992 | }
3993 | }
3994 | }
3995 | }
3996 | }
3997 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "frontend",
3 | "private": true,
4 | "version": "0.0.0",
5 | "type": "module",
6 | "scripts": {
7 | "dev": "vite",
8 | "build": "tsc -b && vite build",
9 | "lint": "eslint .",
10 | "preview": "vite preview"
11 | },
12 | "dependencies": {
13 | "@emotion/react": "^11.13.3",
14 | "@emotion/styled": "^11.13.0",
15 | "@formkit/auto-animate": "^0.8.2",
16 | "@mui/icons-material": "^6.1.1",
17 | "@mui/lab": "^6.0.0-beta.10",
18 | "@mui/material": "^6.1.1",
19 | "@mui/x-data-grid": "^7.18.0",
20 | "@tanstack/react-query": "^5.56.2",
21 | "axios": "^1.7.7",
22 | "react": "^18.3.1",
23 | "react-dom": "^18.3.1",
24 | "react-dropzone": "^14.2.3",
25 | "zustand": "^5.0.0-rc.2"
26 | },
27 | "devDependencies": {
28 | "@eslint/js": "^9.9.0",
29 | "@types/node": "^22.7.3",
30 | "@types/react": "^18.3.3",
31 | "@types/react-dom": "^18.3.0",
32 | "@vitejs/plugin-react-swc": "^3.5.0",
33 | "eslint": "^9.9.0",
34 | "eslint-plugin-react-hooks": "^5.1.0-rc.0",
35 | "eslint-plugin-react-refresh": "^0.4.9",
36 | "globals": "^15.9.0",
37 | "path": "^0.12.7",
38 | "typescript": "^5.5.3",
39 | "typescript-eslint": "^8.0.1",
40 | "vite": "^5.4.1"
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/script.md:
--------------------------------------------------------------------------------
1 | desc:
2 | zustand video
3 | react query video
4 |
5 | first comment on video that do you want to implemnt using nextjs or??
6 |
7 | ---
8 |
9 | intro:
10 |
11 | In this tutorial, you'll learn how to build a file manager in React where users can drag and drop multiple files with smooth animations and real-time upload progress. These files will be uploaded in parallel to a Node.js server running on your localhost. If an upload is interrupted, the progress indicator will turn red.
12 |
13 | Once uploaded, the files will be displayed in a paginated Data Grid fetched from the server. Users can sort by columns, manage, download, or perform bulk actions on multiple files.
14 |
15 | We’ll primarily focus on state management throughout the app, including handling user input for file selection (with type and quantity validation), uploading files in parallel, updating progress, and managing data on the client with caching, mutation, and invalidation.
16 |
17 | So, let’s dive in and get started!
18 |
19 | ---
20 |
21 | If you want to follow along and save time, I've created a starter template for this project. It’s a simple React Vite setup with Material UI and a few other libraries to get us up and running quickly. You can find all the relevant gists and project links in the description below.
22 |
23 | In this React project, we'll be using Material UI, React Query, Zustand, and React Dropzone.
24 |
25 | ```bash
26 | git clone -b starting-template https://github.com/codegenixdev/file-manager-frontend-tutorial.git .
27 | ```
28 |
29 | make sure at least using node 18 for best compatibility
30 |
31 | ```bash
32 | npm i
33 | ```
34 |
35 | open localhost on port 5173
36 |
37 | show what things are installed (insist on dropzone)
38 | review tsconfig.app.json (paths)
39 | review vite.config.ts (paths)
40 | review .env
41 | vite-end.d.ts
42 | inside src, we have app.tsx, main.tsx and shared folder where we put our shared and common components or utilieis here
43 |
44 | main.tsx (show why things are wrapped inside what)
45 | view confirm provider and insist on that this is the best to handle confirms in react and by wrapping your project inside it, you can use it every where in your application with ease where we get to it soon
46 |
47 | App.tsx (our application will go inside this container)
48 | utils, theme and a simple axios httpclient to use it app wide
49 | topbar and theme toggle that we talked before.
50 | BulkActions.tsx where when user select multiple uploaded files, this component will show up and use can do group opertions like delete multiple files which i have implmented this component and you can use it everywhere that you want
51 |
52 | ---
53 |
54 | fileManager/components/FileManager.tsx
55 |
56 | ```tsx FileManager.tsx
57 | export function FileManager() {
58 | return <>file manager>;
59 | }
60 | ```
61 |
62 | import it in app.tsx
63 |
64 | ```tsx filemanager.tsx
65 | export function FileManager() {
66 | return (
67 | <>
68 | Files
69 |
70 | Files and assets that have been uploaded as part of this project.
71 |
72 | ({
74 | backgroundColor: alpha(colors.grey[500], 0.1),
75 | padding: 2,
76 | width: 1,
77 | borderRadius: `${theme.shape.borderRadius}px`,
78 | display: "flex",
79 | flexDirection: "column",
80 | gap: 2,
81 | marginBottom: 3,
82 | })}
83 | >
84 |
85 |
86 |
87 | Click to upload or drag and drop
88 | Max 10GB.
89 |
90 |
91 | >
92 | );
93 | }
94 | ```
95 |
96 | show
97 |
98 | like and subscribe
99 |
100 | ```tsx filemanager.tsx
101 | const { getRootProps, getInputProps } = useDropzone();
102 | ```
103 |
104 | on button base
105 |
106 | ```tsx filemanager.tsx
107 | {...getRootProps()}
108 | ```
109 |
110 | below it
111 |
112 | ```tsx
113 |
114 | ```
115 |
116 | show
117 | thats perfect but how to keep track of what files user has dropped in the upload box or has selected and what to do with them
118 |
119 | ```tsx
120 | function onDrop(acceptedFiles: File[]) {
121 | console.log(acceptedFiles);
122 | }
123 |
124 | const { getRootProps, getInputProps } = useDropzone({
125 | onDrop,
126 | });
127 | ```
128 |
129 | show that is logs
130 |
131 | ```tsx
132 | const { getRootProps, getInputProps } = useDropzone({
133 | onDrop,
134 | // accept: {
135 | // "image/*": [],
136 | // "video/*": [],
137 | // },
138 | maxFiles: 15,
139 | maxSize: 10_000_000_000,
140 | });
141 | ```
142 |
143 | !! try to show some other funcaitonlaity like show error if wrong file or rejected files.
144 |
145 | also there are so many other properties you can read the docs
146 |
147 | now lets continue how to handle and what to do with selected files.
148 | because we want to have access to selected files in many different components and do some operations on them, instead of creating a state here that keeps track of selected files, i prefer to use some state management solutions like react context or zustand. but for simplicity and because zustand is very simple and unopninated, i prefer it here. also i have a full course on it so you can check it out
149 |
150 | ```ts hooks/useFileManagerStore.ts
151 | import { create } from "zustand";
152 |
153 | type FileState = {
154 | files: ExtendedFile[];
155 | };
156 | ```
157 |
158 | ```ts types/extendedFile
159 | export type ExtendedFile = {
160 | file: File;
161 | id: string;
162 | uploadProgress: number;
163 | uploadStatus: "idle" | "pending" | "error" | "success";
164 | };
165 | ```
166 |
167 | ```ts
168 | import { ExtendedFile } from "@/fileManager/types/extendedFile";
169 | import { create } from "zustand";
170 |
171 | type FileState = {
172 | files: ExtendedFile[];
173 | };
174 |
175 | type FileActions = {
176 | appendFiles: (acceptedFiles: File[]) => void;
177 | };
178 |
179 | type FileSlice = FileState & FileActions;
180 |
181 | export const useFileManagerStore = create()((set) => ({
182 | files: [],
183 | appendFiles: (acceptedFiles) =>
184 | set((state) => {
185 | const notDuplicatedNewFiles: ExtendedFile[] = acceptedFiles
186 | .filter((file) => {
187 | const isDuplicate = state.files.some(
188 | (subItem) => subItem.id === `${file.name}${file.size}`
189 | );
190 | return !isDuplicate;
191 | })
192 | .map((file) => ({
193 | file,
194 | id: `${file.name}${file.size}`,
195 | uploadStatus: "idle",
196 | uploadProgress: 0,
197 | }));
198 |
199 | return {
200 | files: [...state.files, ...notDuplicatedNewFiles],
201 | };
202 | }),
203 | }));
204 | ```
205 |
206 | ```tsx
207 | const appendFiles = useFileManagerStore((state) => state.appendFiles);
208 | const files = useFileManagerStore((state) => state.files);
209 |
210 | function onDrop(acceptedFiles: File[]) {
211 | appendFiles(acceptedFiles);
212 | console.log(acceptedFiles);
213 | }
214 | ```
215 |
216 | now show what we want to achieve in final project
217 |
218 | ```tsx before closing button base
219 |
220 | {files.map((file) => (
221 |
222 |
223 |
224 | ))}
225 |
226 | ```
227 |
228 | ```tsx UploadProgressCard
229 | import { FileThumbnail } from "@/fileManager/components/FileThumbnail";
230 | import { useFileManagerStore } from "@/fileManager/hooks/useFileManagerStore";
231 | import { ExtendedFile } from "@/fileManager/types/extendedFile";
232 | import { convertByteToMegabyte } from "@/shared/utils";
233 | import CloseRoundedIcon from "@mui/icons-material/CloseRounded";
234 | import { Card, CardHeader, IconButton, Typography } from "@mui/material";
235 |
236 | import { Box, LinearProgress } from "@mui/material";
237 | import { useCallback } from "react";
238 |
239 | type Props = ExtendedFile;
240 | export function UploadProgressCard({
241 | file,
242 | id,
243 | uploadStatus,
244 | uploadProgress,
245 | }: Props) {
246 | const removeFile = useFileManagerStore((state) => state.removeFile);
247 |
248 | const getStatusColor = useCallback(() => {
249 | switch (uploadStatus) {
250 | case "success":
251 | return "success";
252 | case "error":
253 | return "error";
254 | default:
255 | return "info";
256 | }
257 | }, [uploadStatus]);
258 |
259 | function handleRemove() {
260 | removeFile(id);
261 | }
262 |
263 | return (
264 | e.stopPropagation()}
268 | >
269 |
272 |
273 |
274 | }
275 | avatar={}
276 | title={file.name}
277 | subheader={
278 |
279 |
280 | {convertByteToMegabyte(file.size)}
281 |
282 |
283 |
284 |
285 | ({
287 | height: theme.spacing(1),
288 | borderRadius: theme.shape.borderRadius,
289 | "& .MuiLinearProgress-bar": {
290 | borderRadius: theme.shape.borderRadius,
291 | },
292 | })}
293 | variant="determinate"
294 | color={getStatusColor()}
295 | value={uploadProgress}
296 | aria-label={`Progress: ${uploadProgress ?? 0}%`}
297 | />
298 |
299 | {`${Math.round(
300 | uploadProgress ?? 0
301 | )}%`}
302 |
303 |
304 | }
305 | disableTypography
306 | />
307 |
308 | );
309 | }
310 | ```
311 |
312 | ```tsx FileThumbnail
313 | import AudioFileRoundedIcon from "@mui/icons-material/AudioFileRounded";
314 | import DescriptionRoundedIcon from "@mui/icons-material/DescriptionRounded";
315 | import InsertDriveFileRoundedIcon from "@mui/icons-material/InsertDriveFileRounded";
316 |
317 | import InsertPhotoRoundedIcon from "@mui/icons-material/InsertPhotoRounded";
318 | import SmartDisplayRoundedIcon from "@mui/icons-material/SmartDisplayRounded";
319 |
320 | function getFileType(extension: string) {
321 | switch (extension) {
322 | case "jpg":
323 | case "jpeg":
324 | case "png":
325 | case "gif":
326 | return "image";
327 | case "mp4":
328 | case "mov":
329 | case "avi":
330 | case "mkv":
331 | return "video";
332 | case "mp3":
333 | case "wav":
334 | return "audio";
335 | case "pdf":
336 | case "doc":
337 | case "docx":
338 | case "txt":
339 | return "document";
340 | default:
341 | return "file";
342 | }
343 | }
344 |
345 | type FileThumbnailProps = Pick;
346 |
347 | export function FileThumbnail({ name }: FileThumbnailProps) {
348 | const extension = name.split(".").pop()?.toLowerCase();
349 | const fileType = extension ? getFileType(extension) : "file";
350 |
351 | switch (fileType) {
352 | case "image":
353 | return ;
354 | case "video":
355 | return ;
356 | case "audio":
357 | return ;
358 | case "document":
359 | return ;
360 | default:
361 | return ;
362 | }
363 | }
364 | ```
365 |
366 | now import file upload progress in file manager
367 |
368 | show it
369 |
370 | now implement removeFile
371 |
372 | ```ts
373 | removeFile: (id: string) => void;
374 |
375 | removeFile: (id) =>
376 | set((state) => ({
377 | files: state.files.filter((file) => file.id !== id),
378 | })),
379 | ```
380 |
381 | ```tsx upload card
382 | const removeFile = useFileManagerStore((state) => state.removeFile);
383 | // in avatar
384 |
385 |
386 | ;
387 | ```
388 |
389 | show it that works
390 | disable ripple in button base
391 | to have better animation, we can use this amazing simple library
392 |
393 | ```tsx
394 | const [autoAnimateRef] = useAutoAnimate();
395 |
396 | {files.map((file) => (
397 |
398 |
399 |
400 | ))}
401 | ;
402 | ```
403 |
404 | show animations
405 |
406 | now we need to implement upload logic
407 | we need a simple
408 | i have created a nodejs express server that you can clone it like this
409 |
410 | ```bash
411 | git clone https://github.com/codegenixdev/file-manager-backend-tutorial.git .
412 | npm i
413 | npm run dev
414 | ```
415 |
416 | now it is running on localhost:3000 and uploaded files will be in the upload folder and we can use it in our project
417 | show endpoints in postman
418 |
419 | for simplicity i decided to use react query to communicate with our server and handle queries and mutations to our server in a more professional way. also i have a video on it. if are following along, the react query is installed (show package.json) and just make sure that in main.tsx the whole project is wrapped inside react query provider.
420 |
421 | create useFileUploadMutation.ts
422 |
423 | but before it, because we need to change the upload status and upload progress (show extendedFile) alot during the upload process so we need a way to manage these two properties more easily, so we can easily add two other actions to our store
424 |
425 | ```ts
426 |
427 | updateUploadProgress: (id: string, uploadProgress: number) => void;
428 | updateUploadStatus: (
429 | id: string,
430 | uploadStatus: ExtendedFile["uploadStatus"]
431 | ) => void;
432 |
433 | updateUploadProgress: (id, uploadProgress) =>
434 | set((state) => ({
435 | files: state.files.map((file) =>
436 | file.id === id ? { ...file, uploadProgress } : file
437 | ),
438 | })),
439 |
440 | updateUploadStatus: (id, uploadStatus) =>
441 | set((state) => ({
442 | files: state.files.map((file) =>
443 | file.id === id ? { ...file, uploadStatus } : file
444 | ),
445 | })),
446 |
447 | ```
448 |
449 | ```ts useFileUploadMutation.ts
450 | import { useFileManagerStore } from "@/fileManager/hooks/useFileManagerStore";
451 | import { ExtendedFile } from "@/fileManager/types/extendedFile";
452 | import { httpClient } from "@/shared/httpClient";
453 | import { useMutation } from "@tanstack/react-query";
454 |
455 | export function useFileUploadMutation() {
456 | const updateUploadProgress = useFileManagerStore(
457 | (state) => state.updateUploadProgress
458 | );
459 | const updateUploadStatus = useFileManagerStore(
460 | (state) => state.updateUploadStatus
461 | );
462 | const appendFiles = useFileManagerStore((state) => state.appendFiles);
463 |
464 | return useMutation({
465 | mutationFn: async (files: ExtendedFile[]) => {
466 | const uploadPromises = files.map(async (file) => {
467 | if (file.uploadStatus === "idle") {
468 | updateUploadStatus(file.id, "pending");
469 |
470 | const formData = new FormData();
471 | formData.append("file", file.file);
472 |
473 | return httpClient
474 | .post(`${import.meta.env.VITE_API_URL}/upload`, formData, {
475 | headers: {
476 | "Content-Type": "multipart/form-data",
477 | },
478 | onUploadProgress: (event) => {
479 | if (event.lengthComputable && event.total) {
480 | const percentComplete = Math.round(
481 | (event.loaded / event.total) * 100
482 | );
483 | updateUploadProgress(file.id, percentComplete);
484 | }
485 | },
486 | })
487 | .then(() => {
488 | updateUploadStatus(file.id, "success");
489 | })
490 | .catch(() => {
491 | updateUploadStatus(file.id, "error");
492 | });
493 | }
494 | return Promise.resolve();
495 | });
496 |
497 | await Promise.all(uploadPromises);
498 | },
499 | onMutate: (variables) => {
500 | appendFiles(variables.map((item) => item.file));
501 | },
502 | });
503 | }
504 | ```
505 |
506 | to use it
507 |
508 | ```tsx
509 | const [autoAnimateRef] = useAutoAnimate();
510 |
511 | const fileUploadMutation = useFileUploadMutation();
512 |
513 | function onDrop(acceptedFiles: File[]) {
514 | fileUploadMutation.mutate(
515 | acceptedFiles.map((item) => ({
516 | file: item,
517 | id: `${item.name}${item.size}`,
518 | uploadProgress: 0,
519 | uploadStatus: "idle",
520 | }))
521 | );
522 | }
523 | ```
524 |
525 | now upload a file and show the uploads folder (try a heavy file)
526 |
527 | show it becomes red if upload becomes intruptted
528 |
529 | but i want the file to be removed after a few seconds if uploaded
530 |
531 | ```tsx UploadProgressCard
532 | const [progress, setProgress] = useState(0);
533 |
534 | useEffect(() => {
535 | if (uploadStatus === "success") {
536 | let progressValue = 0;
537 |
538 | const interval = setInterval(() => {
539 | progressValue += 3;
540 | setProgress((prev) => prev + 3);
541 | if (progressValue >= 100) {
542 | removeFile(id);
543 | clearInterval(interval);
544 | }
545 | }, 50);
546 | return () => clearInterval(interval);
547 | }
548 | }, [id, removeFile, uploadStatus]);
549 |
550 |
551 | action={
552 |
553 |
560 |
568 |
569 |
570 |
571 |
572 |
573 | }
574 |
575 | ```
576 |
577 | show it
578 |
579 | now we need to create a query to fetch files from server to show files in a data grid
580 | show final project (upload something and show that data grid updates), show pagination and page size and sorting
581 |
582 | ```ts useFilesQuery.ts
583 | import { GridPaginationModel } from "@mui/x-data-grid";
584 | import { useQuery } from "@tanstack/react-query";
585 |
586 | import { GridSortModel } from "@mui/x-data-grid";
587 | import { FileDataGridRow } from "@/fileManager/types/fileDataGridRow";
588 | import { httpClient } from "@/shared/httpClient";
589 |
590 | export function useFilesQuery({
591 | paginationModel,
592 | sortModel,
593 | }: {
594 | paginationModel: GridPaginationModel;
595 | sortModel: GridSortModel;
596 | }) {
597 | return useQuery({
598 | queryKey: ["files", { paginationModel, sortModel }],
599 | queryFn: async () => {
600 | const sortField =
601 | sortModel.length > 0 ? sortModel[0].field : "dateUploaded";
602 | const sortOrder = sortModel.length > 0 ? sortModel[0].sort : "asc";
603 |
604 | type Response = {
605 | totalFilesCount: number;
606 | files: FileDataGridRow[];
607 | };
608 |
609 | const { data } = await httpClient.get(`/files`, {
610 | params: {
611 | page: paginationModel.page,
612 | pageSize: paginationModel.pageSize,
613 | sortField,
614 | sortOrder,
615 | },
616 | });
617 |
618 | return data;
619 | },
620 | });
621 | }
622 | ```
623 |
624 | ```ts fileDataGridRow
625 | export type FileDataGridRow = {
626 | id: string;
627 | filename: string;
628 | size: number;
629 | dateUploaded: string;
630 | };
631 | ```
632 |
633 | ```ts FilesDataGrid.tsx
634 | import { Stack, Typography } from "@mui/material";
635 |
636 | import { FileThumbnail } from "@/fileManager/components/FileThumbnail";
637 | import { useFilesQuery } from "@/fileManager/hooks/useFilesQuery";
638 | import { FileDataGridRow } from "@/fileManager/types/fileDataGridRow";
639 | import { convertByteToMegabyte } from "@/shared/utils";
640 | import { DataGrid, GridColDef, GridSortModel } from "@mui/x-data-grid";
641 | import { useMemo, useRef, useState } from "react";
642 |
643 | const columns: GridColDef[] = [
644 | {
645 | field: "filename",
646 | headerName: "File Name",
647 | flex: 1,
648 | renderCell: ({ row }) => (
649 |
657 |
658 |
659 | {row.filename}
660 |
661 |
662 | ),
663 | },
664 | {
665 | field: "size",
666 | headerName: "Size",
667 | flex: 1,
668 | valueFormatter: (value) => convertByteToMegabyte(value),
669 | },
670 | {
671 | field: "dateUploaded",
672 | headerName: "Date Uploaded",
673 | flex: 1,
674 | valueFormatter: (value) => new Date(value).toDateString(),
675 | },
676 | ];
677 |
678 | export function FilesDataGrid() {
679 | const [sortModel, setSortModel] = useState([
680 | { field: "dateUploaded", sort: "desc" },
681 | ]);
682 |
683 | const [paginationModel, setPaginationModel] = useState({
684 | page: 0,
685 | pageSize: 10,
686 | });
687 |
688 | const filesQuery = useFilesQuery({ paginationModel, sortModel });
689 | const rowCountRef = useRef(filesQuery.data?.totalFilesCount || 0);
690 |
691 | const rowCount = useMemo(() => {
692 | if (filesQuery.data?.totalFilesCount !== undefined) {
693 | rowCountRef.current = filesQuery.data.totalFilesCount;
694 | }
695 | return rowCountRef.current;
696 | }, [filesQuery.data?.totalFilesCount]);
697 |
698 | return (
699 | <>
700 | ({ height: `calc(100dvh - ${theme.spacing(52)})` })}
702 | rows={filesQuery.data?.files}
703 | columns={columns}
704 | rowCount={rowCount}
705 | loading={filesQuery.isLoading}
706 | pageSizeOptions={[10, 25, 50, 100]}
707 | density="comfortable"
708 | paginationModel={paginationModel}
709 | paginationMode="server"
710 | onPaginationModelChange={setPaginationModel}
711 | onSortModelChange={(newSortModel) => setSortModel(newSortModel)}
712 | />
713 | >
714 | );
715 | }
716 | ```
717 |
718 | import it in filemanager below button base then show it (pagination works and sorting) but when upload something grid wont updated
719 |
720 | ```ts
721 |
722 | onSuccess: async () => {
723 | await queryClient.invalidateQueries({ queryKey: ["files"] });
724 | },
725 | ```
726 |
727 | now when upload, it revalidates
728 |
729 | now show the final quick actions. we want to implement it
730 |
731 | ```ts useFileDeleteMutation
732 | import { httpClient } from "@/shared/httpClient";
733 | import { useMutation, useQueryClient } from "@tanstack/react-query";
734 |
735 | export function useFileDeleteMutation() {
736 | const queryClient = useQueryClient();
737 |
738 | return useMutation({
739 | mutationFn: async (fileIds: string[]) => {
740 | await httpClient.delete(`files`, { data: { fileIds } });
741 | },
742 | onSuccess: async () => {
743 | await queryClient.invalidateQueries({ queryKey: ["files"] });
744 | },
745 | });
746 | }
747 | ```
748 |
749 | ```ts FileQuickActions.tsx
750 | import DeleteForeverRoundedIcon from "@mui/icons-material/DeleteForeverRounded";
751 | import DownloadRoundedIcon from "@mui/icons-material/DownloadRounded";
752 | import MoreVertTwoToneIcon from "@mui/icons-material/MoreVertTwoTone";
753 | import {
754 | Button,
755 | IconButton,
756 | Link,
757 | Popover,
758 | Stack,
759 | Typography,
760 | } from "@mui/material";
761 | import { MouseEvent, useState } from "react";
762 | import { useFileDeleteMutation } from "@/fileManager/hooks/useFileDeleteMutation";
763 | import { FileDataGridRow } from "@/fileManager/types/fileDataGridRow";
764 | import { useConfirm } from "@/shared/confirm/hooks/useConfirm";
765 |
766 | type Props = FileDataGridRow;
767 | export function FileQuickActions({ id, filename }: Props) {
768 | const [anchorEl, setAnchorEl] = useState(null);
769 | const confirm = useConfirm();
770 |
771 | const fileDeleteMutation = useFileDeleteMutation();
772 |
773 | function handleClick(event: MouseEvent) {
774 | setAnchorEl(event.currentTarget);
775 | }
776 |
777 | function handleClose() {
778 | setAnchorEl(null);
779 | }
780 |
781 | function handleRemoveFiles() {
782 | confirm({
783 | handleConfirm: () => {
784 | fileDeleteMutation.mutate([id]);
785 | },
786 | });
787 | }
788 |
789 | return (
790 | <>
791 |
792 |
793 |
794 |
795 |
796 |
801 | }>
802 | {filename}
803 |
804 |
805 |
806 | }
808 | onClick={handleRemoveFiles}
809 | color="error"
810 | >
811 | Delete
812 |
813 |
814 |
815 | >
816 | );
817 | }
818 | ```
819 |
820 | import it in data grid
821 |
822 | ```tsx
823 | {
824 | field: "action",
825 | sortable: false,
826 | pinnable: false,
827 | type: "actions",
828 | renderCell: ({ row }) => ,
829 | },
830 | ```
831 |
832 | show it
833 |
834 | show final project, we want select files then do some actions with them. so first of all we need to select files from our data grid then keep track of selected files specificalyy selected file ids
835 |
836 | ```ts
837 |
838 | selectedFileIds: string[];
839 |
840 | updateSelectedFileIds: (ids: string[]) => void;
841 |
842 | updateSelectedFileIds: (ids) =>
843 | set(() => ({
844 | selectedFileIds: ids,
845 | })),
846 |
847 | ```
848 |
849 | ```tsx datagrid
850 | const confirm = useConfirm();
851 | const fileDeleteMutation = useFileDeleteMutation();
852 |
853 | const selectedFileIds = useFileManagerStore((state) => state.selectedFileIds);
854 | const updateSelectedFileIds = useFileManagerStore(
855 | (state) => state.updateSelectedFileIds
856 | );
857 |
858 | function handleRemoveFiles() {
859 | confirm({
860 | handleConfirm: () => {
861 | fileDeleteMutation.mutate(selectedFileIds, {
862 | onSuccess: () => {
863 | updateSelectedFileIds([]);
864 | },
865 | });
866 | },
867 | });
868 | }
869 |
870 | function handleRowSelectionModelChange(ids: GridRowSelectionModel) {
871 | updateSelectedFileIds(ids.map((id) => id.toString()));
872 | }
873 |
874 | checkboxSelection;
875 | onRowSelectionModelChange = { handleRowSelectionModelChange };
876 | rowSelectionModel = { selectedFileIds };
877 |
878 | ,
882 | actionFn: handleRemoveFiles,
883 | label: "Delete files",
884 | },
885 | ]}
886 | ids={selectedFileIds}
887 | />;
888 | ```
889 |
--------------------------------------------------------------------------------
/src/App.tsx:
--------------------------------------------------------------------------------
1 | import { FileManager } from "@/fileManager/components/FileManager";
2 | import { Topbar } from "@/shared/ui/Topbar";
3 | import { Container } from "@mui/material";
4 |
5 | export function App() {
6 | return (
7 | <>
8 |
9 |
10 |
11 |
12 | >
13 | );
14 | }
15 |
--------------------------------------------------------------------------------
/src/fileManager/components/FileManager.tsx:
--------------------------------------------------------------------------------
1 | import { FilesDataGrid } from "@/fileManager/components/FilesDataGrid";
2 | import { UploadProgressCard } from "@/fileManager/components/UploadProgressCard";
3 | import { useFileManagerStore } from "@/fileManager/hooks/useFileManagerStore";
4 | import { useFileUploadMutation } from "@/fileManager/hooks/useFileUploadMutation";
5 | import { useAutoAnimate } from "@formkit/auto-animate/react";
6 | import FileUploadRoundedIcon from "@mui/icons-material/FileUploadRounded";
7 | import {
8 | alpha,
9 | Box,
10 | ButtonBase,
11 | colors,
12 | Stack,
13 | Typography,
14 | } from "@mui/material";
15 | import { useDropzone } from "react-dropzone";
16 |
17 | export function FileManager() {
18 | const files = useFileManagerStore((state) => state.files);
19 |
20 | const [autoAnimateRef] = useAutoAnimate();
21 |
22 | const fileUploadMutation = useFileUploadMutation();
23 |
24 | function onDrop(acceptedFiles: File[]) {
25 | fileUploadMutation.mutate(
26 | acceptedFiles.map((item) => ({
27 | file: item,
28 | id: `${item.name}${item.size}`,
29 | uploadProgress: 0,
30 | uploadStatus: "idle",
31 | }))
32 | );
33 | }
34 |
35 | const { getRootProps, getInputProps } = useDropzone({
36 | // accept: {
37 | // "image/*": [],
38 | // "video/*": [],
39 | // },
40 | onDrop,
41 | maxFiles: 15,
42 | maxSize: 10_000_000_000,
43 | });
44 |
45 | return (
46 | <>
47 | Files
48 |
49 | Files and assets that have been uploaded as part of this project.
50 |
51 | ({
53 | backgroundColor: alpha(colors.grey[500], 0.1),
54 | padding: 2,
55 | width: 1,
56 | borderRadius: `${theme.shape.borderRadius}px`,
57 | display: "flex",
58 | flexDirection: "column",
59 | gap: 2,
60 | marginBottom: 3,
61 | })}
62 | disableRipple
63 | {...getRootProps()}
64 | >
65 |
66 |
67 |
68 |
69 |
70 | Click to upload or drag and drop
71 | Max 10GB.
72 |
73 |
74 | {files.map((file) => (
75 |
76 |
77 |
78 | ))}
79 |
80 |
81 |
82 | >
83 | );
84 | }
85 |
--------------------------------------------------------------------------------
/src/fileManager/components/FileQuickActions.tsx:
--------------------------------------------------------------------------------
1 | import DeleteForeverRoundedIcon from "@mui/icons-material/DeleteForeverRounded";
2 | import DownloadRoundedIcon from "@mui/icons-material/DownloadRounded";
3 | import MoreVertTwoToneIcon from "@mui/icons-material/MoreVertTwoTone";
4 | import {
5 | Button,
6 | IconButton,
7 | Link,
8 | Popover,
9 | Stack,
10 | Typography,
11 | } from "@mui/material";
12 | import { MouseEvent, useState } from "react";
13 | import { useFileDeleteMutation } from "@/fileManager/hooks/useFileDeleteMutation";
14 | import { FileDataGridRow } from "@/fileManager/types/fileDataGridRow";
15 | import { useConfirm } from "@/shared/confirm/hooks/useConfirm";
16 |
17 | type Props = FileDataGridRow;
18 | export function FileQuickActions({ id, filename }: Props) {
19 | const [anchorEl, setAnchorEl] = useState(null);
20 | const confirm = useConfirm();
21 |
22 | const fileDeleteMutation = useFileDeleteMutation();
23 |
24 | function handleClick(event: MouseEvent) {
25 | setAnchorEl(event.currentTarget);
26 | }
27 |
28 | function handleClose() {
29 | setAnchorEl(null);
30 | }
31 |
32 | function handleRemoveFiles() {
33 | confirm({
34 | handleConfirm: () => {
35 | fileDeleteMutation.mutate([id]);
36 | },
37 | });
38 | }
39 |
40 | return (
41 | <>
42 |
43 |
44 |
45 |
46 |
47 |
52 | }>
53 | {filename}
54 |
55 |
56 |
57 | }
59 | onClick={handleRemoveFiles}
60 | color="error"
61 | >
62 | Delete
63 |
64 |
65 |
66 | >
67 | );
68 | }
69 |
--------------------------------------------------------------------------------
/src/fileManager/components/FileThumbnail.tsx:
--------------------------------------------------------------------------------
1 | import AudioFileRoundedIcon from "@mui/icons-material/AudioFileRounded";
2 | import DescriptionRoundedIcon from "@mui/icons-material/DescriptionRounded";
3 | import InsertDriveFileRoundedIcon from "@mui/icons-material/InsertDriveFileRounded";
4 |
5 | import InsertPhotoRoundedIcon from "@mui/icons-material/InsertPhotoRounded";
6 | import SmartDisplayRoundedIcon from "@mui/icons-material/SmartDisplayRounded";
7 |
8 | function getFileType(extension: string) {
9 | switch (extension) {
10 | case "jpg":
11 | case "jpeg":
12 | case "png":
13 | case "gif":
14 | return "image";
15 | case "mp4":
16 | case "mov":
17 | case "avi":
18 | case "mkv":
19 | return "video";
20 | case "mp3":
21 | case "wav":
22 | return "audio";
23 | case "pdf":
24 | case "doc":
25 | case "docx":
26 | case "txt":
27 | return "document";
28 | default:
29 | return "file";
30 | }
31 | }
32 |
33 | type FileThumbnailProps = Pick;
34 |
35 | export function FileThumbnail({ name }: FileThumbnailProps) {
36 | const extension = name.split(".").pop()?.toLowerCase();
37 | const fileType = extension ? getFileType(extension) : "file";
38 |
39 | switch (fileType) {
40 | case "image":
41 | return ;
42 | case "video":
43 | return ;
44 | case "audio":
45 | return ;
46 | case "document":
47 | return ;
48 | default:
49 | return ;
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/fileManager/components/FilesDataGrid.tsx:
--------------------------------------------------------------------------------
1 | import { Stack, Typography } from "@mui/material";
2 |
3 | import DeleteForeverRoundedIcon from "@mui/icons-material/DeleteForeverRounded";
4 | import {
5 | DataGrid,
6 | GridColDef,
7 | GridRowSelectionModel,
8 | GridSortModel,
9 | } from "@mui/x-data-grid";
10 | import { useMemo, useRef, useState } from "react";
11 | import { FileDataGridRow } from "@/fileManager/types/fileDataGridRow";
12 | import { FileThumbnail } from "@/fileManager/components/FileThumbnail";
13 | import { convertByteToMegabyte } from "@/shared/utils";
14 | import { FileQuickActions } from "@/fileManager/components/FileQuickActions";
15 | import { useFileDeleteMutation } from "@/fileManager/hooks/useFileDeleteMutation";
16 | import { useFileManagerStore } from "@/fileManager/hooks/useFileManagerStore";
17 | import { useFilesQuery } from "@/fileManager/hooks/useFilesQuery";
18 | import { BulkActions } from "@/shared/ui/BulkActions";
19 | import { useConfirm } from "@/shared/confirm/hooks/useConfirm";
20 |
21 | const columns: GridColDef[] = [
22 | {
23 | field: "filename",
24 | headerName: "File Name",
25 | flex: 1,
26 | renderCell: ({ row }) => (
27 |
35 |
36 |
37 | {row.filename}
38 |
39 |
40 | ),
41 | },
42 | {
43 | field: "size",
44 | headerName: "Size",
45 | flex: 1,
46 | valueFormatter: (value) => convertByteToMegabyte(value),
47 | },
48 | {
49 | field: "dateUploaded",
50 | headerName: "Date Uploaded",
51 | flex: 1,
52 | valueFormatter: (value) => new Date(value).toDateString(),
53 | },
54 | {
55 | field: "action",
56 | sortable: false,
57 | pinnable: false,
58 | type: "actions",
59 | renderCell: ({ row }) => ,
60 | },
61 | ];
62 |
63 | export function FilesDataGrid() {
64 | const [sortModel, setSortModel] = useState([
65 | { field: "dateUploaded", sort: "desc" },
66 | ]);
67 | const confirm = useConfirm();
68 |
69 | const fileDeleteMutation = useFileDeleteMutation();
70 |
71 | const selectedFileIds = useFileManagerStore((state) => state.selectedFileIds);
72 | const updateSelectedFileIds = useFileManagerStore(
73 | (state) => state.updateSelectedFileIds
74 | );
75 |
76 | const [paginationModel, setPaginationModel] = useState({
77 | page: 0,
78 | pageSize: 10,
79 | });
80 |
81 | const filesQuery = useFilesQuery({ paginationModel, sortModel });
82 | const rowCountRef = useRef(filesQuery.data?.totalFilesCount || 0);
83 |
84 | const rowCount = useMemo(() => {
85 | if (filesQuery.data?.totalFilesCount !== undefined) {
86 | rowCountRef.current = filesQuery.data.totalFilesCount;
87 | }
88 | return rowCountRef.current;
89 | }, [filesQuery.data?.totalFilesCount]);
90 |
91 | function handleRemoveFiles() {
92 | confirm({
93 | handleConfirm: () => {
94 | fileDeleteMutation.mutate(selectedFileIds, {
95 | onSuccess: () => {
96 | updateSelectedFileIds([]);
97 | },
98 | });
99 | },
100 | });
101 | }
102 |
103 | function handleRowSelectionModelChange(ids: GridRowSelectionModel) {
104 | updateSelectedFileIds(ids.map((id) => id.toString()));
105 | }
106 |
107 | return (
108 | <>
109 | ({ height: `calc(100dvh - ${theme.spacing(52)})` })}
111 | checkboxSelection
112 | onRowSelectionModelChange={handleRowSelectionModelChange}
113 | rowSelectionModel={selectedFileIds}
114 | rows={filesQuery.data?.files}
115 | columns={columns}
116 | rowCount={rowCount}
117 | loading={filesQuery.isLoading}
118 | pageSizeOptions={[10, 25, 50, 100]}
119 | density="comfortable"
120 | paginationModel={paginationModel}
121 | paginationMode="server"
122 | onPaginationModelChange={setPaginationModel}
123 | onSortModelChange={(newSortModel) => setSortModel(newSortModel)}
124 | />
125 | ,
129 | actionFn: handleRemoveFiles,
130 | label: "Delete files",
131 | },
132 | ]}
133 | ids={selectedFileIds}
134 | />
135 | >
136 | );
137 | }
138 |
--------------------------------------------------------------------------------
/src/fileManager/components/UploadProgressCard.tsx:
--------------------------------------------------------------------------------
1 | import { FileThumbnail } from "@/fileManager/components/FileThumbnail";
2 | import { useFileManagerStore } from "@/fileManager/hooks/useFileManagerStore";
3 | import { ExtendedFile } from "@/fileManager/types/extendedFile";
4 | import { convertByteToMegabyte } from "@/shared/utils";
5 | import CloseRoundedIcon from "@mui/icons-material/CloseRounded";
6 | import {
7 | Card,
8 | CardHeader,
9 | CircularProgress,
10 | IconButton,
11 | Stack,
12 | Typography,
13 | } from "@mui/material";
14 |
15 | import { Box, LinearProgress } from "@mui/material";
16 | import { useCallback, useEffect, useState } from "react";
17 |
18 | type Props = ExtendedFile;
19 | export function UploadProgressCard({
20 | file,
21 | id,
22 | uploadStatus,
23 | uploadProgress,
24 | }: Props) {
25 | const removeFile = useFileManagerStore((state) => state.removeFile);
26 |
27 | const [progress, setProgress] = useState(0);
28 |
29 | useEffect(() => {
30 | if (uploadStatus === "success") {
31 | let progressValue = 0;
32 |
33 | const interval = setInterval(() => {
34 | progressValue += 3;
35 | setProgress((prev) => prev + 3);
36 | if (progressValue >= 100) {
37 | removeFile(id);
38 | clearInterval(interval);
39 | }
40 | }, 50);
41 | return () => clearInterval(interval);
42 | }
43 | }, [id, removeFile, uploadStatus]);
44 |
45 | const getStatusColor = useCallback(() => {
46 | switch (uploadStatus) {
47 | case "success":
48 | return "success";
49 | case "error":
50 | return "error";
51 | default:
52 | return "info";
53 | }
54 | }, [uploadStatus]);
55 |
56 | function handleRemove() {
57 | removeFile(id);
58 | }
59 |
60 | return (
61 | e.stopPropagation()}
65 | >
66 |
69 |
76 |
84 |
85 |
86 |
87 |
88 |
89 | }
90 | avatar={}
91 | title={file.name}
92 | subheader={
93 |
94 |
95 | {convertByteToMegabyte(file.size)}
96 |
97 |
98 |
99 |
100 | ({
102 | height: theme.spacing(1),
103 | borderRadius: theme.shape.borderRadius,
104 | "& .MuiLinearProgress-bar": {
105 | borderRadius: theme.shape.borderRadius,
106 | },
107 | })}
108 | variant="determinate"
109 | color={getStatusColor()}
110 | value={uploadProgress}
111 | aria-label={`Progress: ${uploadProgress ?? 0}%`}
112 | />
113 |
114 | {`${Math.round(
115 | uploadProgress ?? 0
116 | )}%`}
117 |
118 |
119 | }
120 | disableTypography
121 | />
122 |
123 | );
124 | }
125 |
--------------------------------------------------------------------------------
/src/fileManager/hooks/useFileDeleteMutation.ts:
--------------------------------------------------------------------------------
1 | import { httpClient } from "@/shared/httpClient";
2 | import { useMutation, useQueryClient } from "@tanstack/react-query";
3 |
4 | export function useFileDeleteMutation() {
5 | const queryClient = useQueryClient();
6 |
7 | return useMutation({
8 | mutationFn: async (fileIds: string[]) => {
9 | await httpClient.delete(`files`, { data: { fileIds } });
10 | },
11 | onSuccess: async () => {
12 | await queryClient.invalidateQueries({ queryKey: ["files"] });
13 | },
14 | });
15 | }
16 |
--------------------------------------------------------------------------------
/src/fileManager/hooks/useFileManagerStore.ts:
--------------------------------------------------------------------------------
1 | import { ExtendedFile } from "@/fileManager/types/extendedFile";
2 | import { create } from "zustand";
3 |
4 | type FileState = {
5 | files: ExtendedFile[];
6 | selectedFileIds: string[];
7 | };
8 |
9 | type FileActions = {
10 | removeFile: (id: string) => void;
11 | appendFiles: (acceptedFiles: File[]) => void;
12 | updateUploadProgress: (id: string, uploadProgress: number) => void;
13 | updateUploadStatus: (
14 | id: string,
15 | uploadStatus: ExtendedFile["uploadStatus"]
16 | ) => void;
17 | updateSelectedFileIds: (ids: string[]) => void;
18 | };
19 |
20 | type FileSlice = FileState & FileActions;
21 |
22 | export const useFileManagerStore = create()((set) => ({
23 | files: [],
24 | selectedFileIds: [],
25 | removeFile: (id) =>
26 | set((state) => ({
27 | files: state.files.filter((file) => file.id !== id),
28 | })),
29 |
30 | appendFiles: (acceptedFiles) =>
31 | set((state) => {
32 | const notDuplicatedNewFiles: ExtendedFile[] = acceptedFiles
33 | .filter((file) => {
34 | const isDuplicate = state.files.some(
35 | (subItem) => subItem.id === `${file.name}${file.size}`
36 | );
37 | return !isDuplicate;
38 | })
39 | .map((file) => ({
40 | file,
41 | id: `${file.name}${file.size}`,
42 | uploadStatus: "idle",
43 | uploadProgress: 0,
44 | }));
45 |
46 | return {
47 | files: [...state.files, ...notDuplicatedNewFiles],
48 | };
49 | }),
50 |
51 | updateUploadProgress: (id, uploadProgress) =>
52 | set((state) => ({
53 | files: state.files.map((file) =>
54 | file.id === id ? { ...file, uploadProgress } : file
55 | ),
56 | })),
57 |
58 | updateUploadStatus: (id, uploadStatus) =>
59 | set((state) => ({
60 | files: state.files.map((file) =>
61 | file.id === id ? { ...file, uploadStatus } : file
62 | ),
63 | })),
64 | updateSelectedFileIds: (ids) =>
65 | set(() => ({
66 | selectedFileIds: ids,
67 | })),
68 | }));
69 |
--------------------------------------------------------------------------------
/src/fileManager/hooks/useFileUploadMutation.ts:
--------------------------------------------------------------------------------
1 | import { useFileManagerStore } from "@/fileManager/hooks/useFileManagerStore";
2 | import { ExtendedFile } from "@/fileManager/types/extendedFile";
3 | import { httpClient } from "@/shared/httpClient";
4 | import { useMutation, useQueryClient } from "@tanstack/react-query";
5 |
6 | export function useFileUploadMutation() {
7 | const updateUploadProgress = useFileManagerStore(
8 | (state) => state.updateUploadProgress
9 | );
10 | const updateUploadStatus = useFileManagerStore(
11 | (state) => state.updateUploadStatus
12 | );
13 | const appendFiles = useFileManagerStore((state) => state.appendFiles);
14 |
15 | const queryClient = useQueryClient();
16 |
17 | return useMutation({
18 | mutationFn: async (files: ExtendedFile[]) => {
19 | const uploadPromises = files.map(async (file) => {
20 | if (file.uploadStatus === "idle") {
21 | updateUploadStatus(file.id, "pending");
22 |
23 | const formData = new FormData();
24 | formData.append("file", file.file);
25 |
26 | return httpClient
27 | .post(`${import.meta.env.VITE_API_URL}/upload`, formData, {
28 | headers: {
29 | "Content-Type": "multipart/form-data",
30 | },
31 | onUploadProgress: (event) => {
32 | if (event.lengthComputable && event.total) {
33 | const percentComplete = Math.round(
34 | (event.loaded / event.total) * 100
35 | );
36 | updateUploadProgress(file.id, percentComplete);
37 | }
38 | },
39 | })
40 | .then(() => {
41 | updateUploadStatus(file.id, "success");
42 | })
43 | .catch(() => {
44 | updateUploadStatus(file.id, "error");
45 | });
46 | }
47 | return Promise.resolve();
48 | });
49 |
50 | await Promise.all(uploadPromises);
51 | },
52 | onMutate: (variables) => {
53 | appendFiles(variables.map((item) => item.file));
54 | },
55 | onSuccess: async () => {
56 | await queryClient.invalidateQueries({ queryKey: ["files"] });
57 | },
58 | });
59 | }
60 |
--------------------------------------------------------------------------------
/src/fileManager/hooks/useFilesQuery.ts:
--------------------------------------------------------------------------------
1 | import { GridPaginationModel } from "@mui/x-data-grid";
2 | import { useQuery } from "@tanstack/react-query";
3 |
4 | import { GridSortModel } from "@mui/x-data-grid";
5 | import { FileDataGridRow } from "@/fileManager/types/fileDataGridRow";
6 | import { httpClient } from "@/shared/httpClient";
7 |
8 | export function useFilesQuery({
9 | paginationModel,
10 | sortModel,
11 | }: {
12 | paginationModel: GridPaginationModel;
13 | sortModel: GridSortModel;
14 | }) {
15 | return useQuery({
16 | queryKey: ["files", { paginationModel, sortModel }],
17 | queryFn: async () => {
18 | const sortField =
19 | sortModel.length > 0 ? sortModel[0].field : "dateUploaded";
20 | const sortOrder = sortModel.length > 0 ? sortModel[0].sort : "asc";
21 |
22 | type Response = {
23 | totalFilesCount: number;
24 | files: FileDataGridRow[];
25 | };
26 |
27 | const { data } = await httpClient.get(`/files`, {
28 | params: {
29 | page: paginationModel.page,
30 | pageSize: paginationModel.pageSize,
31 | sortField,
32 | sortOrder,
33 | },
34 | });
35 |
36 | return data;
37 | },
38 | });
39 | }
40 |
--------------------------------------------------------------------------------
/src/fileManager/types/ExtendedFile.ts:
--------------------------------------------------------------------------------
1 | export type ExtendedFile = {
2 | file: File;
3 | id: string;
4 | uploadProgress: number;
5 | uploadStatus: "idle" | "pending" | "error" | "success";
6 | };
7 |
--------------------------------------------------------------------------------
/src/fileManager/types/FileDataGridRow.ts:
--------------------------------------------------------------------------------
1 | export type FileDataGridRow = {
2 | id: string;
3 | filename: string;
4 | size: number;
5 | dateUploaded: string;
6 | };
7 |
--------------------------------------------------------------------------------
/src/main.tsx:
--------------------------------------------------------------------------------
1 | import { App } from "@/App";
2 | import { ConfirmProvider } from "@/shared/confirm/components/ConfirmProvider";
3 | import { theme } from "@/shared/theme";
4 | import { CssBaseline, ThemeProvider } from "@mui/material";
5 | import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
6 | import { StrictMode } from "react";
7 | import { createRoot } from "react-dom/client";
8 |
9 | const queryClient = new QueryClient();
10 |
11 | createRoot(document.getElementById("root")!).render(
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | );
23 |
--------------------------------------------------------------------------------
/src/shared/confirm/components/ConfirmProvider.tsx:
--------------------------------------------------------------------------------
1 | import { ReactNode, useState } from "react";
2 |
3 | import Button from "@mui/material/Button";
4 | import DialogActions from "@mui/material/DialogActions";
5 | import DialogContent from "@mui/material/DialogContent";
6 | import DialogTitle from "@mui/material/DialogTitle";
7 |
8 | import { Dialog as MuiDialog } from "@mui/material";
9 | import {
10 | ConfirmContext,
11 | ConfirmOptions,
12 | } from "@/shared/confirm/hooks/useConfirm";
13 |
14 | type ConfirmProviderProps = {
15 | children: ReactNode;
16 | };
17 |
18 | export function ConfirmProvider({ children }: ConfirmProviderProps) {
19 | const [open, setOpen] = useState(false);
20 | const [options, setOptions] = useState();
21 |
22 | function confirm(optionsArg: ConfirmOptions) {
23 | return new Promise(() => {
24 | setOptions(optionsArg);
25 | setOpen(true);
26 | });
27 | }
28 |
29 | function handleClose() {
30 | setOpen(false);
31 | }
32 |
33 | function handleConfirm() {
34 | options?.handleConfirm();
35 | handleClose();
36 | }
37 |
38 | return (
39 | <>
40 |
41 | {children}
42 |
43 |
50 | Confirm
51 | Are you sure?
52 |
53 |
54 |
57 |
60 |
61 |
62 | >
63 | );
64 | }
65 |
--------------------------------------------------------------------------------
/src/shared/confirm/hooks/useConfirm.ts:
--------------------------------------------------------------------------------
1 | import { createContext, useContext } from "react";
2 |
3 | type ConfirmOptions = {
4 | handleConfirm: () => void;
5 | };
6 |
7 | type ConfirmContextType = (options: ConfirmOptions) => Promise;
8 |
9 | const ConfirmContext = createContext(undefined);
10 |
11 | function useConfirm() {
12 | const context = useContext(ConfirmContext);
13 |
14 | if (context === undefined) {
15 | throw new Error("useConfirm must be used within a ConfirmProvider");
16 | }
17 | return context;
18 | }
19 |
20 | export { useConfirm, ConfirmContext, type ConfirmOptions };
21 |
--------------------------------------------------------------------------------
/src/shared/httpClient.ts:
--------------------------------------------------------------------------------
1 | import axios from "axios";
2 |
3 | export const httpClient = axios.create({
4 | baseURL: import.meta.env.VITE_API_URL,
5 | headers: {
6 | "Content-Type": "application/json",
7 | },
8 | });
9 |
--------------------------------------------------------------------------------
/src/shared/theme.ts:
--------------------------------------------------------------------------------
1 | import { createTheme } from "@mui/material";
2 |
3 | export const theme = createTheme({
4 | components: {
5 | MuiButton: { styleOverrides: { root: { textTransform: "none" } } },
6 | MuiPopover: { defaultProps: { elevation: 1 } },
7 | MuiCard: { defaultProps: { elevation: 0 } },
8 | },
9 | shape: { borderRadius: 16 },
10 | colorSchemes: {
11 | dark: true,
12 | },
13 | });
14 |
--------------------------------------------------------------------------------
/src/shared/ui/BulkActions.tsx:
--------------------------------------------------------------------------------
1 | import CloseRoundedIcon from "@mui/icons-material/CloseRounded";
2 |
3 | import LayersOutlinedIcon from "@mui/icons-material/LayersOutlined";
4 | import {
5 | Paper,
6 | SpeedDial,
7 | SpeedDialAction,
8 | SpeedDialIcon,
9 | Stack,
10 | SxProps,
11 | Typography,
12 | } from "@mui/material";
13 |
14 | import { ReactNode, useRef } from "react";
15 | import { Transition } from "react-transition-group";
16 |
17 | type Action = {
18 | icon: ReactNode;
19 | label: string;
20 | actionFn: (ids: string[]) => void | Promise;
21 | };
22 |
23 | type Props = {
24 | ids: string[];
25 | actions: Action[];
26 | };
27 | export function BulkActions({ actions, ids }: Props) {
28 | const nodeRef = useRef(null);
29 |
30 | const duration = 300;
31 |
32 | const transitionStyles: { [k: string]: SxProps } = {
33 | entering: { opacity: 1, bottom: 20 },
34 | entered: { opacity: 1, bottom: 20 },
35 | exiting: { opacity: 0, bottom: -10 },
36 | exited: { opacity: 0, bottom: -10 },
37 | };
38 |
39 | return (
40 | 0} timeout={duration}>
41 | {(state) => (
42 |
56 |
57 | {ids.length} Selected items
58 | ({
61 | position: "absolute",
62 | bottom: theme.spacing(1),
63 | right: theme.spacing(2),
64 | ".MuiSpeedDialAction-staticTooltipLabel": {
65 | width: "max-content",
66 | },
67 | })}
68 | icon={
69 | }
71 | openIcon={}
72 | />
73 | }
74 | >
75 | {actions.map((action) => (
76 | action.actionFn(ids)}
81 | key={action.label}
82 | />
83 | ))}
84 |
85 |
86 |
87 | )}
88 |
89 | );
90 | }
91 |
--------------------------------------------------------------------------------
/src/shared/ui/ThemeToggle.tsx:
--------------------------------------------------------------------------------
1 | import ContrastRoundedIcon from "@mui/icons-material/ContrastRounded";
2 | import DarkModeRoundedIcon from "@mui/icons-material/DarkModeRounded";
3 | import LightModeRoundedIcon from "@mui/icons-material/LightModeRounded";
4 | import { MenuItem, Select, useColorScheme } from "@mui/material";
5 |
6 | export function ThemeToggle() {
7 | const { mode, setMode } = useColorScheme();
8 |
9 | if (!mode || !setMode) {
10 | return null;
11 | }
12 |
13 | return (
14 |
35 | );
36 | }
37 |
--------------------------------------------------------------------------------
/src/shared/ui/Topbar.tsx:
--------------------------------------------------------------------------------
1 | import { ThemeToggle } from "@/shared/ui/ThemeToggle";
2 | import { AppBar, Box, Toolbar, Typography } from "@mui/material";
3 |
4 | export function Topbar() {
5 | return (
6 |
7 |
8 |
9 |
10 | File manager
11 |
12 |
13 |
14 |
15 |
16 |
17 | );
18 | }
19 |
--------------------------------------------------------------------------------
/src/shared/utils.ts:
--------------------------------------------------------------------------------
1 | function convertByteToMegabyte(size: number) {
2 | return `${((size ?? 0) / 1000000).toFixed(2)} MB`;
3 | }
4 |
5 | export { convertByteToMegabyte };
6 |
--------------------------------------------------------------------------------
/src/vite-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
3 | interface ImportMetaEnv {
4 | readonly VITE_API_URL: string;
5 | }
6 |
7 | interface ImportMeta {
8 | readonly env: ImportMetaEnv;
9 | }
10 |
--------------------------------------------------------------------------------
/tsconfig.app.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2020",
4 | "useDefineForClassFields": true,
5 | "lib": ["ES2020", "DOM", "DOM.Iterable"],
6 | "module": "ESNext",
7 | "skipLibCheck": true,
8 |
9 | /* Bundler mode */
10 | "moduleResolution": "bundler",
11 | "allowImportingTsExtensions": true,
12 | "isolatedModules": true,
13 | "moduleDetection": "force",
14 | "noEmit": true,
15 | "jsx": "react-jsx",
16 |
17 | /* Linting */
18 | "strict": true,
19 | "noUnusedLocals": true,
20 | "noUnusedParameters": true,
21 | "paths": {
22 | "@/*": ["./src/*"]
23 | },
24 | "noFallthroughCasesInSwitch": true
25 | },
26 | "include": ["src"]
27 | }
28 |
--------------------------------------------------------------------------------
/tsconfig.app.tsbuildinfo:
--------------------------------------------------------------------------------
1 | {"root":["./src/app.tsx","./src/main.tsx","./src/vite-env.d.ts","./src/filemanager/components/filemanager.tsx","./src/filemanager/components/filequickactions.tsx","./src/filemanager/components/filethumbnail.tsx","./src/filemanager/components/filesdatagrid.tsx","./src/filemanager/components/uploadprogresscard.tsx","./src/filemanager/hooks/usefiledeletemutation.ts","./src/filemanager/hooks/usefilemanagerstore.ts","./src/filemanager/hooks/usefileuploadmutation.ts","./src/filemanager/hooks/usefilesquery.ts","./src/filemanager/types/extendedfile.ts","./src/filemanager/types/filedatagridrow.ts","./src/shared/httpclient.ts","./src/shared/theme.ts","./src/shared/utils.ts","./src/shared/confirm/components/confirmprovider.tsx","./src/shared/confirm/hooks/useconfirm.ts","./src/shared/ui/bulkactions.tsx","./src/shared/ui/themetoggle.tsx","./src/shared/ui/topbar.tsx"],"version":"5.6.2"}
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "files": [],
3 | "references": [
4 | { "path": "./tsconfig.app.json" },
5 | { "path": "./tsconfig.node.json" }
6 | ]
7 | }
8 |
--------------------------------------------------------------------------------
/tsconfig.node.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "lib": ["ES2023"],
5 | "module": "ESNext",
6 | "skipLibCheck": true,
7 |
8 | /* Bundler mode */
9 | "moduleResolution": "bundler",
10 | "allowImportingTsExtensions": true,
11 | "isolatedModules": true,
12 | "moduleDetection": "force",
13 | "noEmit": true,
14 |
15 | /* Linting */
16 | "strict": true,
17 | "noUnusedLocals": true,
18 | "noUnusedParameters": true,
19 | "noFallthroughCasesInSwitch": true
20 | },
21 | "include": ["vite.config.ts"]
22 | }
23 |
--------------------------------------------------------------------------------
/tsconfig.node.tsbuildinfo:
--------------------------------------------------------------------------------
1 | {"root":["./vite.config.ts"],"version":"5.6.2"}
--------------------------------------------------------------------------------
/vite.config.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from "vite";
2 | import react from "@vitejs/plugin-react-swc";
3 | import path from "path";
4 |
5 | // https://vitejs.dev/config/
6 | export default defineConfig({
7 | resolve: {
8 | alias: {
9 | "@": path.resolve("./src"),
10 | },
11 | },
12 | plugins: [react()],
13 | });
14 |
--------------------------------------------------------------------------------