From 64e76d6aee5031c399914d9829ff58f05df6d2d0 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Mon, 11 May 2026 13:55:40 +0000 Subject: [PATCH 1/4] Migrate Angular 9 app to React 19 with Vite and TypeScript - Replace Angular framework with React 19, React Router, Vite, and TypeScript - Migrate all components: Header, Footer, Feed, Item, ItemDetails, Comment, User, Settings, Loader, ErrorMessage - Convert Angular services to React Context (SettingsProvider) and plain async fetch functions - Preserve full SCSS theme system (default, night, amoledblack) with media queries - Maintain all routes: /news, /newest, /show, /ask, /jobs, /item/:id, /user/:id - Preserve localStorage persistence for settings - All lint checks, typecheck, and build pass cleanly Co-Authored-By: Eashan Sinha --- react-app/.gitignore | 24 + react-app/README.md | 73 + react-app/eslint.config.js | 22 + react-app/index.html | 15 + react-app/package-lock.json | 3157 +++++++++++++++++ react-app/package.json | 32 + .../assets/icons/android-chrome-144x144.png | Bin 0 -> 29992 bytes .../assets/icons/android-chrome-192x192.png | Bin 0 -> 5033 bytes .../assets/icons/android-chrome-256x256.png | Bin 0 -> 6756 bytes .../assets/icons/android-chrome-512x512.png | Bin 0 -> 30053 bytes .../assets/icons/apple-touch-icon-120x120.png | Bin 0 -> 2629 bytes .../assets/icons/apple-touch-icon-152x152.png | Bin 0 -> 3304 bytes .../assets/icons/apple-touch-icon-180x180.png | Bin 0 -> 3846 bytes .../assets/icons/apple-touch-icon-60x60.png | Bin 0 -> 1699 bytes .../assets/icons/apple-touch-icon-76x76.png | Bin 0 -> 1993 bytes .../public/assets/icons/apple-touch-icon.png | Bin 0 -> 3846 bytes .../public/assets/icons/browserconfig.xml | 9 + .../public/assets/icons/favicon-16x16.png | Bin 0 -> 694 bytes .../public/assets/icons/favicon-32x32.png | Bin 0 -> 1371 bytes .../public/assets/icons/mstile-150x150.png | Bin 0 -> 3656 bytes .../public/assets/icons/safari-pinned-tab.svg | 1 + react-app/public/assets/images/cog.svg | 1 + .../public/assets/images/logo-header.png | Bin 0 -> 4109 bytes react-app/public/assets/images/logo.svg | 1 + react-app/public/favicon.ico | Bin 0 -> 5430 bytes react-app/public/favicon.svg | 1 + react-app/public/icons.svg | 24 + react-app/src/App.scss | 23 + react-app/src/App.tsx | 61 + react-app/src/assets/hero.png | Bin 0 -> 13057 bytes react-app/src/assets/react.svg | 1 + react-app/src/assets/vite.svg | 1 + react-app/src/components/Comment/Comment.scss | 83 + react-app/src/components/Comment/Comment.tsx | 52 + .../components/ErrorMessage/ErrorMessage.scss | 115 + .../components/ErrorMessage/ErrorMessage.tsx | 25 + react-app/src/components/Feed/Feed.scss | 108 + react-app/src/components/Feed/Feed.tsx | 80 + react-app/src/components/Footer/Footer.scss | 23 + react-app/src/components/Footer/Footer.tsx | 14 + react-app/src/components/Header/Header.scss | 149 + react-app/src/components/Header/Header.tsx | 51 + react-app/src/components/Item/Item.scss | 68 + react-app/src/components/Item/Item.tsx | 79 + .../components/ItemDetails/ItemDetails.scss | 151 + .../components/ItemDetails/ItemDetails.tsx | 141 + react-app/src/components/Loader/Loader.scss | 109 + react-app/src/components/Loader/Loader.tsx | 9 + .../src/components/Settings/Settings.scss | 74 + .../src/components/Settings/Settings.tsx | 99 + react-app/src/components/User/User.scss | 89 + react-app/src/components/User/User.tsx | 55 + react-app/src/main.tsx | 9 + react-app/src/services/SettingsContext.tsx | 76 + react-app/src/services/hackerNewsApi.ts | 41 + react-app/src/services/settingsContextDef.ts | 13 + react-app/src/services/useSettings.ts | 9 + react-app/src/styles/_media.scss | 3 + react-app/src/styles/_theme_variables.scss | 29 + react-app/src/styles/_themes.scss | 234 ++ react-app/src/styles/globals.scss | 16 + react-app/src/types/index.ts | 53 + react-app/src/utils/commentLabel.ts | 6 + react-app/tsconfig.app.json | 25 + react-app/tsconfig.json | 7 + react-app/tsconfig.node.json | 24 + react-app/vite.config.ts | 7 + 67 files changed, 5572 insertions(+) create mode 100644 react-app/.gitignore create mode 100644 react-app/README.md create mode 100644 react-app/eslint.config.js create mode 100644 react-app/index.html create mode 100644 react-app/package-lock.json create mode 100644 react-app/package.json create mode 100644 react-app/public/assets/icons/android-chrome-144x144.png create mode 100644 react-app/public/assets/icons/android-chrome-192x192.png create mode 100644 react-app/public/assets/icons/android-chrome-256x256.png create mode 100644 react-app/public/assets/icons/android-chrome-512x512.png create mode 100644 react-app/public/assets/icons/apple-touch-icon-120x120.png create mode 100644 react-app/public/assets/icons/apple-touch-icon-152x152.png create mode 100644 react-app/public/assets/icons/apple-touch-icon-180x180.png create mode 100644 react-app/public/assets/icons/apple-touch-icon-60x60.png create mode 100644 react-app/public/assets/icons/apple-touch-icon-76x76.png create mode 100644 react-app/public/assets/icons/apple-touch-icon.png create mode 100644 react-app/public/assets/icons/browserconfig.xml create mode 100644 react-app/public/assets/icons/favicon-16x16.png create mode 100644 react-app/public/assets/icons/favicon-32x32.png create mode 100644 react-app/public/assets/icons/mstile-150x150.png create mode 100644 react-app/public/assets/icons/safari-pinned-tab.svg create mode 100755 react-app/public/assets/images/cog.svg create mode 100644 react-app/public/assets/images/logo-header.png create mode 100644 react-app/public/assets/images/logo.svg create mode 100644 react-app/public/favicon.ico create mode 100644 react-app/public/favicon.svg create mode 100644 react-app/public/icons.svg create mode 100644 react-app/src/App.scss create mode 100644 react-app/src/App.tsx create mode 100644 react-app/src/assets/hero.png create mode 100644 react-app/src/assets/react.svg create mode 100644 react-app/src/assets/vite.svg create mode 100644 react-app/src/components/Comment/Comment.scss create mode 100644 react-app/src/components/Comment/Comment.tsx create mode 100644 react-app/src/components/ErrorMessage/ErrorMessage.scss create mode 100644 react-app/src/components/ErrorMessage/ErrorMessage.tsx create mode 100644 react-app/src/components/Feed/Feed.scss create mode 100644 react-app/src/components/Feed/Feed.tsx create mode 100644 react-app/src/components/Footer/Footer.scss create mode 100644 react-app/src/components/Footer/Footer.tsx create mode 100644 react-app/src/components/Header/Header.scss create mode 100644 react-app/src/components/Header/Header.tsx create mode 100644 react-app/src/components/Item/Item.scss create mode 100644 react-app/src/components/Item/Item.tsx create mode 100644 react-app/src/components/ItemDetails/ItemDetails.scss create mode 100644 react-app/src/components/ItemDetails/ItemDetails.tsx create mode 100644 react-app/src/components/Loader/Loader.scss create mode 100644 react-app/src/components/Loader/Loader.tsx create mode 100644 react-app/src/components/Settings/Settings.scss create mode 100644 react-app/src/components/Settings/Settings.tsx create mode 100644 react-app/src/components/User/User.scss create mode 100644 react-app/src/components/User/User.tsx create mode 100644 react-app/src/main.tsx create mode 100644 react-app/src/services/SettingsContext.tsx create mode 100644 react-app/src/services/hackerNewsApi.ts create mode 100644 react-app/src/services/settingsContextDef.ts create mode 100644 react-app/src/services/useSettings.ts create mode 100644 react-app/src/styles/_media.scss create mode 100644 react-app/src/styles/_theme_variables.scss create mode 100644 react-app/src/styles/_themes.scss create mode 100644 react-app/src/styles/globals.scss create mode 100644 react-app/src/types/index.ts create mode 100644 react-app/src/utils/commentLabel.ts create mode 100644 react-app/tsconfig.app.json create mode 100644 react-app/tsconfig.json create mode 100644 react-app/tsconfig.node.json create mode 100644 react-app/vite.config.ts diff --git a/react-app/.gitignore b/react-app/.gitignore new file mode 100644 index 000000000..a547bf36d --- /dev/null +++ b/react-app/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/react-app/README.md b/react-app/README.md new file mode 100644 index 000000000..7dbf7ebf3 --- /dev/null +++ b/react-app/README.md @@ -0,0 +1,73 @@ +# React + TypeScript + Vite + +This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. + +Currently, two official plugins are available: + +- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Oxc](https://oxc.rs) +- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) + +## React Compiler + +The React Compiler is not enabled on this template because of its impact on dev & build performances. To add it, see [this documentation](https://react.dev/learn/react-compiler/installation). + +## Expanding the ESLint configuration + +If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules: + +```js +export default defineConfig([ + globalIgnores(['dist']), + { + files: ['**/*.{ts,tsx}'], + extends: [ + // Other configs... + + // Remove tseslint.configs.recommended and replace with this + tseslint.configs.recommendedTypeChecked, + // Alternatively, use this for stricter rules + tseslint.configs.strictTypeChecked, + // Optionally, add this for stylistic rules + tseslint.configs.stylisticTypeChecked, + + // Other configs... + ], + languageOptions: { + parserOptions: { + project: ['./tsconfig.node.json', './tsconfig.app.json'], + tsconfigRootDir: import.meta.dirname, + }, + // other options... + }, + }, +]) +``` + +You can also install [eslint-plugin-react-x](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom) for React-specific lint rules: + +```js +// eslint.config.js +import reactX from 'eslint-plugin-react-x' +import reactDom from 'eslint-plugin-react-dom' + +export default defineConfig([ + globalIgnores(['dist']), + { + files: ['**/*.{ts,tsx}'], + extends: [ + // Other configs... + // Enable lint rules for React + reactX.configs['recommended-typescript'], + // Enable lint rules for React DOM + reactDom.configs.recommended, + ], + languageOptions: { + parserOptions: { + project: ['./tsconfig.node.json', './tsconfig.app.json'], + tsconfigRootDir: import.meta.dirname, + }, + // other options... + }, + }, +]) +``` diff --git a/react-app/eslint.config.js b/react-app/eslint.config.js new file mode 100644 index 000000000..ef614d25c --- /dev/null +++ b/react-app/eslint.config.js @@ -0,0 +1,22 @@ +import js from '@eslint/js' +import globals from 'globals' +import reactHooks from 'eslint-plugin-react-hooks' +import reactRefresh from 'eslint-plugin-react-refresh' +import tseslint from 'typescript-eslint' +import { defineConfig, globalIgnores } from 'eslint/config' + +export default defineConfig([ + globalIgnores(['dist']), + { + files: ['**/*.{ts,tsx}'], + extends: [ + js.configs.recommended, + tseslint.configs.recommended, + reactHooks.configs.flat.recommended, + reactRefresh.configs.vite, + ], + languageOptions: { + globals: globals.browser, + }, + }, +]) diff --git a/react-app/index.html b/react-app/index.html new file mode 100644 index 000000000..540332b52 --- /dev/null +++ b/react-app/index.html @@ -0,0 +1,15 @@ + + + + + + + React HN + + + + +
+ + + diff --git a/react-app/package-lock.json b/react-app/package-lock.json new file mode 100644 index 000000000..02afade62 --- /dev/null +++ b/react-app/package-lock.json @@ -0,0 +1,3157 @@ +{ + "name": "react-app", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "react-app", + "version": "0.0.0", + "dependencies": { + "react": "^19.2.6", + "react-dom": "^19.2.6", + "react-router-dom": "^7.15.0", + "sass": "^1.99.0" + }, + "devDependencies": { + "@eslint/js": "^10.0.1", + "@types/node": "^24.12.3", + "@types/react": "^19.2.14", + "@types/react-dom": "^19.2.3", + "@vitejs/plugin-react": "^6.0.1", + "eslint": "^10.3.0", + "eslint-plugin-react-hooks": "^7.1.1", + "eslint-plugin-react-refresh": "^0.5.2", + "globals": "^17.6.0", + "typescript": "~6.0.2", + "typescript-eslint": "^8.59.2", + "vite": "^8.0.12" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", + "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.28.5", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.29.3", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.3.tgz", + "integrity": "sha512-LIVqM46zQWZhj17qA8wb4nW/ixr2y1Nw+r1etiAWgRM6U1IqP+LNhL1yg440jYZR72jCWcWbLWzIosH+uP1fqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.0.tgz", + "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-module-transforms": "^7.28.6", + "@babel/helpers": "^7.28.6", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/traverse": "^7.29.0", + "@babel/types": "^7.29.0", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.29.1", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz", + "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.0", + "@babel/types": "^7.29.0", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz", + "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.28.6", + "@babel/helper-validator-option": "^7.27.1", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz", + "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz", + "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.28.6", + "@babel/helper-validator-identifier": "^7.28.5", + "@babel/traverse": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.2.tgz", + "integrity": "sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.28.6", + "@babel/types": "^7.29.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.3.tgz", + "integrity": "sha512-b3ctpQwp+PROvU/cttc4OYl4MzfJUWy6FZg+PMXfzmt/+39iHVF0sDfqay8TQM3JA2EUOyKcFZt75jWriQijsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.0" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/template": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", + "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.28.6", + "@babel/parser": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz", + "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/types": "^7.29.0", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", + "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@emnapi/core": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz", + "integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.2.1", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz", + "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", + "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", + "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.23.5", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.23.5.tgz", + "integrity": "sha512-Y3kKLvC1dvTOT+oGlqNQ1XLqK6D1HU2YXPc52NmAlJZbMMWDzGYXMiPRJ8TYD39muD/OTjlZmNJ4ib7dvSrMBA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^3.0.5", + "debug": "^4.3.1", + "minimatch": "^10.2.4" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.5.5.tgz", + "integrity": "sha512-eIJYKTCECbP/nsKaaruF6LW967mtbQbsw4JTtSVkUQc9MneSkbrgPJAbKl9nWr0ZeowV8BfsarBmPpBzGelA2w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^1.2.1" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/core": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-1.2.1.tgz", + "integrity": "sha512-MwcE1P+AZ4C6DWlpin/OmOA54mmIZ/+xZuJiQd4SyB29oAJjN30UW9wkKNptW2ctp4cEsvhlLY/CsQ1uoHDloQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/js": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-10.0.1.tgz", + "integrity": "sha512-zeR9k5pd4gxjZ0abRoIaxdc7I3nDktoXZk2qOv9gCNWx3mVwEn32VRhyLaRsDiJjTs0xq/T8mfPtyuXu7GWBcA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "eslint": "^10.0.0" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/@eslint/object-schema": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-3.0.5.tgz", + "integrity": "sha512-vqTaUEgxzm+YDSdElad6PiRoX4t8VGDjCtt05zn4nU810UIx/uNEV7/lZJ6KwFThKZOzOxzXy48da+No7HZaMw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.7.1.tgz", + "integrity": "sha512-rZAP3aVgB9ds9KOeUSL+zZ21hPmo8dh6fnIFwRQj5EAZl9gzR7wxYbYXYysAM8CTqGmUGyp2S4kUdV17MnGuWQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^1.2.1", + "levn": "^0.4.1" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.2.tgz", + "integrity": "sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/types": "^0.15.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.8", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.8.tgz", + "integrity": "sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.2", + "@humanfs/types": "^0.15.0", + "@humanwhocodes/retry": "^0.4.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/types": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/@humanfs/types/-/types-0.15.0.tgz", + "integrity": "sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.4.tgz", + "integrity": "sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@tybys/wasm-util": "^0.10.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "peerDependencies": { + "@emnapi/core": "^1.7.1", + "@emnapi/runtime": "^1.7.1" + } + }, + "node_modules/@oxc-project/types": { + "version": "0.129.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.129.0.tgz", + "integrity": "sha512-3oz8m3FGdr2nDXVqmFUw7jolKliC4MoyXYIG2c7gpjBnzUWQpUGIYcXYKxTdTi+N2jusvt610ckTMkxdwHkYEg==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/Boshen" + } + }, + "node_modules/@parcel/watcher": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.6.tgz", + "integrity": "sha512-tmmZ3lQxAe/k/+rNnXQRawJ4NjxO2hqiOLTHvWchtGZULp4RyFeh6aU4XdOYBFe2KE1oShQTv4AblOs2iOrNnQ==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "detect-libc": "^2.0.3", + "is-glob": "^4.0.3", + "node-addon-api": "^7.0.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "@parcel/watcher-android-arm64": "2.5.6", + "@parcel/watcher-darwin-arm64": "2.5.6", + "@parcel/watcher-darwin-x64": "2.5.6", + "@parcel/watcher-freebsd-x64": "2.5.6", + "@parcel/watcher-linux-arm-glibc": "2.5.6", + "@parcel/watcher-linux-arm-musl": "2.5.6", + "@parcel/watcher-linux-arm64-glibc": "2.5.6", + "@parcel/watcher-linux-arm64-musl": "2.5.6", + "@parcel/watcher-linux-x64-glibc": "2.5.6", + "@parcel/watcher-linux-x64-musl": "2.5.6", + "@parcel/watcher-win32-arm64": "2.5.6", + "@parcel/watcher-win32-ia32": "2.5.6", + "@parcel/watcher-win32-x64": "2.5.6" + } + }, + "node_modules/@parcel/watcher-android-arm64": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.6.tgz", + "integrity": "sha512-YQxSS34tPF/6ZG7r/Ih9xy+kP/WwediEUsqmtf0cuCV5TPPKw/PQHRhueUo6JdeFJaqV3pyjm0GdYjZotbRt/A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-arm64": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.6.tgz", + "integrity": "sha512-Z2ZdrnwyXvvvdtRHLmM4knydIdU9adO3D4n/0cVipF3rRiwP+3/sfzpAwA/qKFL6i1ModaabkU7IbpeMBgiVEA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-x64": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.6.tgz", + "integrity": "sha512-HgvOf3W9dhithcwOWX9uDZyn1lW9R+7tPZ4sug+NGrGIo4Rk1hAXLEbcH1TQSqxts0NYXXlOWqVpvS1SFS4fRg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-freebsd-x64": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.6.tgz", + "integrity": "sha512-vJVi8yd/qzJxEKHkeemh7w3YAn6RJCtYlE4HPMoVnCpIXEzSrxErBW5SJBgKLbXU3WdIpkjBTeUNtyBVn8TRng==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-glibc": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.6.tgz", + "integrity": "sha512-9JiYfB6h6BgV50CCfasfLf/uvOcJskMSwcdH1PHH9rvS1IrNy8zad6IUVPVUfmXr+u+Km9IxcfMLzgdOudz9EQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-musl": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.6.tgz", + "integrity": "sha512-Ve3gUCG57nuUUSyjBq/MAM0CzArtuIOxsBdQ+ftz6ho8n7s1i9E1Nmk/xmP323r2YL0SONs1EuwqBp2u1k5fxg==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-glibc": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.6.tgz", + "integrity": "sha512-f2g/DT3NhGPdBmMWYoxixqYr3v/UXcmLOYy16Bx0TM20Tchduwr4EaCbmxh1321TABqPGDpS8D/ggOTaljijOA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-musl": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.6.tgz", + "integrity": "sha512-qb6naMDGlbCwdhLj6hgoVKJl2odL34z2sqkC7Z6kzir8b5W65WYDpLB6R06KabvZdgoHI/zxke4b3zR0wAbDTA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-glibc": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.6.tgz", + "integrity": "sha512-kbT5wvNQlx7NaGjzPFu8nVIW1rWqV780O7ZtkjuWaPUgpv2NMFpjYERVi0UYj1msZNyCzGlaCWEtzc+exjMGbQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-musl": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.6.tgz", + "integrity": "sha512-1JRFeC+h7RdXwldHzTsmdtYR/Ku8SylLgTU/reMuqdVD7CtLwf0VR1FqeprZ0eHQkO0vqsbvFLXUmYm/uNKJBg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-arm64": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.6.tgz", + "integrity": "sha512-3ukyebjc6eGlw9yRt678DxVF7rjXatWiHvTXqphZLvo7aC5NdEgFufVwjFfY51ijYEWpXbqF5jtrK275z52D4Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-ia32": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.6.tgz", + "integrity": "sha512-k35yLp1ZMwwee3Ez/pxBi5cf4AoBKYXj00CZ80jUz5h8prpiaQsiRPKQMxoLstNuqe2vR4RNPEAEcjEFzhEz/g==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-x64": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.6.tgz", + "integrity": "sha512-hbQlYcCq5dlAX9Qx+kFb0FHue6vbjlf0FrNzSKdYK2APUf7tGfGxQCk2ihEREmbR6ZMc0MVAD5RIX/41gpUzTw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@rolldown/binding-android-arm64": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0.tgz", + "integrity": "sha512-TWMZnRLMe63C2Lhyicviu7ZHaU4kxa6PS3rofvc9GmcvptzNN11BcfQ4Sl7MwTOsisQoa2keB/EBdNCAnUo8vA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-arm64": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0.tgz", + "integrity": "sha512-6XcD+8k0gPVItNagEw78/qqcBDwKcwDYS8V2hRmVsfUSIrd8cWe/CBvRDI5toqFyPfj+FJr6t8U6Xj2P2prEew==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-x64": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0.tgz", + "integrity": "sha512-iN/tWVXRQDWvmZlKdceP1Dwug9GDpEymhb9p4xnEe6zvCg5lFmzVljl+1qR1NVx3yfGpr2Na+CuLmv5IU8uzfQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-freebsd-x64": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0.tgz", + "integrity": "sha512-jjQMDvvwSOuhOwMszD/klSOjyWMM3zI64hWTj9KT5x4MxRbZAf+7vLQ6qouRhtsLVFHr3f0ILaJAfgENPiQdAQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm-gnueabihf": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0.tgz", + "integrity": "sha512-d//Dtg2x6/m3mbV64yUGNnDGNZaDGRpDLLNGerHQUVObuNaIQaaDp25yUiqGXtHEXX+NP2d0wAlmKgpYgIAJ2A==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-gnu": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0.tgz", + "integrity": "sha512-n7Ofp0mx+aB2cC+Sdy5YtMnXtY9lchnHbY+3Yt0uq9JsWQExf4f5Whu0tK0R8Jdc9S6RchTHjIFY7uc92puOVQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-musl": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0.tgz", + "integrity": "sha512-EIVjy2cgd7uuMMo94FVkBp7F6DhcZAUwNURkSG3RwUmvAXR6s0ISxM81U+IydcZByPG0pZIHsf1b6kTxoFDgJA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-ppc64-gnu": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.0.tgz", + "integrity": "sha512-JEwwOPcwTLAcpDQlqSmjEmfs63xJnSiUNIGvLcDLUHCWK4XowpS/7c7tUsUH6uT/ct6bMUTdXKfI8967FYj6mg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-s390x-gnu": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.0.tgz", + "integrity": "sha512-0wjCFhLrihtAubnT9iA0N++0pSV0z5Hg7tNGdNJ4RFaINceHadoF+kiFGyY1qSSNVIAZtLotG8Ju1bgDPkjnFA==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-gnu": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0.tgz", + "integrity": "sha512-Dfn7iak9BcMMePxcoJfpSbWqnEyrp/dRF63/8qW/eHBdOZov6x5aShLLEYGYdIeSJ6vMLK/XCVB+lGIxm41bQA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-musl": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0.tgz", + "integrity": "sha512-5/utzzDmD/pD/bmuaUcbTf/sZYy0aztwIVlfpoW1fTjCZ0BaPOMVWGZL1zvgxyi7ZIVYWlxKONHmSbHuiOh8Jw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-openharmony-arm64": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0.tgz", + "integrity": "sha512-ouJs8VcUomfLfpbUECqFMRqdV4x6aeAK3MA4m6vTrJJjKyWTV5KnxZx7Jd9G+GlDaQQxubcba00x16OyJ1meig==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-wasm32-wasi": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0.tgz", + "integrity": "sha512-E+oHKGiDA+lsKMmFtffDDw91EryDT7uJocrIuCHqhm6bCTM6xFK+3gaCkYOHfPwQr0cCNarSM2xaELoQDz9jJg==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "1.10.0", + "@emnapi/runtime": "1.10.0", + "@napi-rs/wasm-runtime": "^1.1.4" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-arm64-msvc": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0.tgz", + "integrity": "sha512-yYK02n8Rngo+gbm1y6G0+7jk1sJ/2Wt7K0me0Y7k/ErBpyf+LJ2gFpqWVTcRV1rUepBlQRmpgWkTQCiiwrK0Ow==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-x64-msvc": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0.tgz", + "integrity": "sha512-14bpChMahXRRXiTwahSl+zzHPW6qQTXtkMuJBFlbo+pqSAews2d4BdCSHfrJ/MBsCZtpmTafsY+1QhBzitcmdg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-rc.7", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.7.tgz", + "integrity": "sha512-qujRfC8sFVInYSPPMLQByRh7zhwkGFS4+tyMQ83srV1qrxL4g8E2tyxVVyxd0+8QeBM1mIk9KbWxkegRr76XzA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tybys/wasm-util": { + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.2.tgz", + "integrity": "sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@types/esrecurse": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@types/esrecurse/-/esrecurse-4.3.1.tgz", + "integrity": "sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "24.12.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.12.3.tgz", + "integrity": "sha512-8oljBDGun9cIsZRJR6fkihn0TSXJI0UDOOhncYaERq6M0JMDoPLxyscwruJcb4GKS6dvK/d8xebYBg27h/duaQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~7.16.0" + } + }, + "node_modules/@types/react": { + "version": "19.2.14", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz", + "integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==", + "dev": true, + "license": "MIT", + "dependencies": { + "csstype": "^3.2.2" + } + }, + "node_modules/@types/react-dom": { + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz", + "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^19.2.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.59.2.tgz", + "integrity": "sha512-j/bwmkBvHUtPNxzuWe5z6BEk3q54YRyGlBXkSsmfoih7zNrBvl5A9A98anlp/7JbyZcWIJ8KXo/3Tq/DjFLtuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.12.2", + "@typescript-eslint/scope-manager": "8.59.2", + "@typescript-eslint/type-utils": "8.59.2", + "@typescript-eslint/utils": "8.59.2", + "@typescript-eslint/visitor-keys": "8.59.2", + "ignore": "^7.0.5", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.59.2", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.59.2.tgz", + "integrity": "sha512-plR3pp6D+SSUn1HM7xvSkx12/DhoHInI2YF35KAcVFNZvlC0gtrWqx7Qq1oH2Ssgi0vlFRCTbP+DZc7B9+TtsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/scope-manager": "8.59.2", + "@typescript-eslint/types": "8.59.2", + "@typescript-eslint/typescript-estree": "8.59.2", + "@typescript-eslint/visitor-keys": "8.59.2", + "debug": "^4.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/project-service": { + "version": "8.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.59.2.tgz", + "integrity": "sha512-+2hqvEkeyf/0FBor67duF0Ll7Ot8jyKzDQOSrxazF/danillRq2DwR9dLptsXpoZQqxE1UisSmoZewrlPas9Vw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.59.2", + "@typescript-eslint/types": "^8.59.2", + "debug": "^4.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.59.2.tgz", + "integrity": "sha512-JzfyEpEtOU89CcFSwyNS3mu4MLvLSXqnmX05+aKBDM+TdR5jzcGOEBwxwGNxrEQ7p/z6kK2WyioCGBf2zZBnvg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.59.2", + "@typescript-eslint/visitor-keys": "8.59.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.59.2.tgz", + "integrity": "sha512-BKK4alN7oi4C/zv4VqHQ+uRU+lTa6JGIZ7s1juw7b3RHo9OfKB+bKX3u0iVZetdsUCBBkSbdWbarJbmN0fTeSw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.59.2.tgz", + "integrity": "sha512-nhqaj1nmTdVVl/BP5omXNRGO38jn5iosis2vbdmupF2txCf8ylWT8lx+JlvMYYVqzGVKtjojUFoQ3JRWK+mfzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.59.2", + "@typescript-eslint/typescript-estree": "8.59.2", + "@typescript-eslint/utils": "8.59.2", + "debug": "^4.4.3", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.59.2.tgz", + "integrity": "sha512-e82GVOE8Ps3E++Egvb6Y3Dw0S10u8NkQ9KXmtRhCWJJ8kDhOJTvtMAWnFL16kB1583goCWXsr0NieKCZMs2/0Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.59.2.tgz", + "integrity": "sha512-o0XPGNwcWw+FIwStOWn+BwBuEmL6QXP0rsvAFg7ET1dey1Nr6Wb1ac8p5HEsK0ygO/6mUxlk+YWQD9xcb/nnXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.59.2", + "@typescript-eslint/tsconfig-utils": "8.59.2", + "@typescript-eslint/types": "8.59.2", + "@typescript-eslint/visitor-keys": "8.59.2", + "debug": "^4.4.3", + "minimatch": "^10.2.2", + "semver": "^7.7.3", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.0.tgz", + "integrity": "sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.59.2.tgz", + "integrity": "sha512-Juw3EinkXqjaffxz6roowvV7GZT/kET5vSKKZT6upl5TXdWkLkYmNPXwDDL2Vkt2DPn0nODIS4egC/0AGxKo/Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.9.1", + "@typescript-eslint/scope-manager": "8.59.2", + "@typescript-eslint/types": "8.59.2", + "@typescript-eslint/typescript-estree": "8.59.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.59.2.tgz", + "integrity": "sha512-NwjLUnGy8/Zfx23fl50tRC8rYaYnM52xNRYFAXvmiil9yh1+K6aRVQMnzW6gQB/1DLgWt977lYQn7C+wtgXZiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.59.2", + "eslint-visitor-keys": "^5.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@vitejs/plugin-react": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-6.0.1.tgz", + "integrity": "sha512-l9X/E3cDb+xY3SWzlG1MOGt2usfEHGMNIaegaUGFsLkb3RCn/k8/TOXBcab+OndDI4TBtktT8/9BwwW8Vi9KUQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rolldown/pluginutils": "1.0.0-rc.7" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "peerDependencies": { + "@rolldown/plugin-babel": "^0.1.7 || ^0.2.0", + "babel-plugin-react-compiler": "^1.0.0", + "vite": "^8.0.0" + }, + "peerDependenciesMeta": { + "@rolldown/plugin-babel": { + "optional": true + }, + "babel-plugin-react-compiler": { + "optional": true + } + } + }, + "node_modules/acorn": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/baseline-browser-mapping": { + "version": "2.10.29", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.29.tgz", + "integrity": "sha512-Asa2krT+XTPZINCS+2QcyS8WTkObE77RwkydwF7h6DmnKqbvlalz93m/dnphUyCa6SWSP51VgtEUf2FN+gelFQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/brace-expansion": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz", + "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/browserslist": { + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.2.tgz", + "integrity": "sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.10.12", + "caniuse-lite": "^1.0.30001782", + "electron-to-chromium": "^1.5.328", + "node-releases": "^2.0.36", + "update-browserslist-db": "^1.2.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001792", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001792.tgz", + "integrity": "sha512-hVLMUZFgR4JJ6ACt1uEESvQN1/dBVqPAKY0hgrV70eN3391K6juAfTjKZLKvOMsx8PxA7gsY1/tLMMTcfFLLpw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/cookie": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz", + "integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "devOptional": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.353", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.353.tgz", + "integrity": "sha512-kOrWphBi8TOZyiJZqsgqIle0lw+tzmnQK83pV9dZUd01Nm2POECSyFQMAuarzZdYqQW7FH9RaYOuaRo3h+bQ3w==", + "dev": true, + "license": "ISC" + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.3.0.tgz", + "integrity": "sha512-XbEXaRva5cF0ZQB8w6MluHA0kZZfV2DuCMJ3ozyEOHLwDpZX2Lmm/7Pp0xdJmI0GL1W05VH5VwIFHEm1Vcw2gw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.2", + "@eslint/config-array": "^0.23.5", + "@eslint/config-helpers": "^0.5.5", + "@eslint/core": "^1.2.1", + "@eslint/plugin-kit": "^0.7.1", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "ajv": "^6.14.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^9.1.2", + "eslint-visitor-keys": "^5.0.1", + "espree": "^11.2.0", + "esquery": "^1.7.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "minimatch": "^10.2.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-7.1.1.tgz", + "integrity": "sha512-f2I7Gw6JbvCexzIInuSbZpfdQ44D7iqdWX01FKLvrPgqxoE7oMj8clOfto8U6vYiz4yd5oKu39rRSVOe1zRu0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.24.4", + "@babel/parser": "^7.24.4", + "hermes-parser": "^0.25.1", + "zod": "^3.25.0 || ^4.0.0", + "zod-validation-error": "^3.5.0 || ^4.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 || ^10.0.0" + } + }, + "node_modules/eslint-plugin-react-refresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.5.2.tgz", + "integrity": "sha512-hmgTH57GfzoTFjVN0yBwTggnsVUF2tcqi7RJZHqi9lIezSs4eFyAMktA68YD4r5kNw1mxyY4dmkyoFDb3FIqrA==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "eslint": "^9 || ^10" + } + }, + "node_modules/eslint-scope": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-9.1.2.tgz", + "integrity": "sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@types/esrecurse": "^4.3.1", + "@types/estree": "^1.0.8", + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-11.2.0.tgz", + "integrity": "sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.16.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^5.0.1" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", + "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", + "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", + "dev": true, + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "17.6.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-17.6.0.tgz", + "integrity": "sha512-sepffkT8stwnIYbsMBpoCHJuJM5l98FUF2AnE07hfvE0m/qp3R586hw4jF4uadbhvg1ooIdzuu7CsfD2jzCaNA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/hermes-estree": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.25.1.tgz", + "integrity": "sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw==", + "dev": true, + "license": "MIT" + }, + "node_modules/hermes-parser": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.25.1.tgz", + "integrity": "sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "hermes-estree": "0.25.1" + } + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/immutable": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.5.tgz", + "integrity": "sha512-t7xcm2siw+hlUM68I+UEOK+z84RzmN59as9DZ7P1l0994DKUWV7UXBMQZVxaoMSRQ+PBZbHCOoBt7a2wxOMt+A==", + "license": "MIT" + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lightningcss": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz", + "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.32.0", + "lightningcss-darwin-arm64": "1.32.0", + "lightningcss-darwin-x64": "1.32.0", + "lightningcss-freebsd-x64": "1.32.0", + "lightningcss-linux-arm-gnueabihf": "1.32.0", + "lightningcss-linux-arm64-gnu": "1.32.0", + "lightningcss-linux-arm64-musl": "1.32.0", + "lightningcss-linux-x64-gnu": "1.32.0", + "lightningcss-linux-x64-musl": "1.32.0", + "lightningcss-win32-arm64-msvc": "1.32.0", + "lightningcss-win32-x64-msvc": "1.32.0" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz", + "integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz", + "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz", + "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz", + "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz", + "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz", + "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz", + "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz", + "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz", + "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz", + "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz", + "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.5" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.12", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz", + "integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-addon-api": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", + "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", + "license": "MIT", + "optional": true + }, + "node_modules/node-releases": { + "version": "2.0.38", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.38.tgz", + "integrity": "sha512-3qT/88Y3FbH/Kx4szpQQ4HzUbVrHPKTLVpVocKiLfoYvw9XSGOX2FmD2d6DrXbVYyAQTF2HeF6My8jmzx7/CRw==", + "dev": true, + "license": "MIT" + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.14.tgz", + "integrity": "sha512-SoSL4+OSEtR99LHFZQiJLkT59C5B1amGO1NzTwj7TT1qCUgUO6hxOvzkOYxD+vMrXBM3XJIKzokoERdqQq/Zmg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/react": { + "version": "19.2.6", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.6.tgz", + "integrity": "sha512-sfWGGfavi0xr8Pg0sVsyHMAOziVYKgPLNrS7ig+ivMNb3wbCBw3KxtflsGBAwD3gYQlE/AEZsTLgToRrSCjb0Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "19.2.6", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.6.tgz", + "integrity": "sha512-0prMI+hvBbPjsWnxDLxlCGyM8PN6UuWjEUCYmZhO67xIV9Xasa/r/vDnq+Xyq4Lo27g8QSbO5YzARu0D1Sps3g==", + "license": "MIT", + "dependencies": { + "scheduler": "^0.27.0" + }, + "peerDependencies": { + "react": "^19.2.6" + } + }, + "node_modules/react-router": { + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.15.0.tgz", + "integrity": "sha512-HW9vYwuM8f4yx66Izy8xfrzCM+SBJluoZcCbww9A1TySax11S5Vgw6fi3ZjMONw9J4gQwngL7PzkyIpJJpJ7RQ==", + "license": "MIT", + "dependencies": { + "cookie": "^1.0.1", + "set-cookie-parser": "^2.6.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + } + } + }, + "node_modules/react-router-dom": { + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.15.0.tgz", + "integrity": "sha512-VcrVg64Fo8nwBvDscajG8gRTLIuTC6N50nb22l2HOOV4PTOHgoGp8mUjy9wLiHYoYTSYI36tUnXZgasSRFZorQ==", + "license": "MIT", + "dependencies": { + "react-router": "7.15.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + } + }, + "node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "license": "MIT", + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/rolldown": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0.tgz", + "integrity": "sha512-yD986aXDESFGS95spT1LAv0jssywP4npMEjmMHyN2/5+eE8qQJUype2AaKkRiLgBgyD0LFlubwAht7VmY8rGoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@oxc-project/types": "=0.129.0", + "@rolldown/pluginutils": "1.0.0" + }, + "bin": { + "rolldown": "bin/cli.mjs" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "optionalDependencies": { + "@rolldown/binding-android-arm64": "1.0.0", + "@rolldown/binding-darwin-arm64": "1.0.0", + "@rolldown/binding-darwin-x64": "1.0.0", + "@rolldown/binding-freebsd-x64": "1.0.0", + "@rolldown/binding-linux-arm-gnueabihf": "1.0.0", + "@rolldown/binding-linux-arm64-gnu": "1.0.0", + "@rolldown/binding-linux-arm64-musl": "1.0.0", + "@rolldown/binding-linux-ppc64-gnu": "1.0.0", + "@rolldown/binding-linux-s390x-gnu": "1.0.0", + "@rolldown/binding-linux-x64-gnu": "1.0.0", + "@rolldown/binding-linux-x64-musl": "1.0.0", + "@rolldown/binding-openharmony-arm64": "1.0.0", + "@rolldown/binding-wasm32-wasi": "1.0.0", + "@rolldown/binding-win32-arm64-msvc": "1.0.0", + "@rolldown/binding-win32-x64-msvc": "1.0.0" + } + }, + "node_modules/rolldown/node_modules/@rolldown/pluginutils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0.tgz", + "integrity": "sha512-aKs/3GSWyV0mrhNmt/96/Z3yczC3yvrzYATCiCXQebBsGyYzjNdUphRVLeJQ67ySKVXRfMxt2lm12pmXvbPFQQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/sass": { + "version": "1.99.0", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.99.0.tgz", + "integrity": "sha512-kgW13M54DUB7IsIRM5LvJkNlpH+WhMpooUcaWGFARkF1Tc82v9mIWkCbCYf+MBvpIUBSeSOTilpZjEPr2VYE6Q==", + "license": "MIT", + "dependencies": { + "chokidar": "^4.0.0", + "immutable": "^5.1.5", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=14.0.0" + }, + "optionalDependencies": { + "@parcel/watcher": "^2.4.1" + } + }, + "node_modules/scheduler": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", + "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", + "license": "MIT" + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/set-cookie-parser": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.2.tgz", + "integrity": "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==", + "license": "MIT" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.16", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.16.tgz", + "integrity": "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/ts-api-utils": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz", + "integrity": "sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD", + "optional": true + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/typescript": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz", + "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/typescript-eslint": { + "version": "8.59.2", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.59.2.tgz", + "integrity": "sha512-pJw051uomb3ZeCzGTpRb8RbEqB5Y4WWet8gl/GcTlU35BSx0PVdZ86/bqkQCyKKuraVQEK7r6kBHQXF+fBhkoQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/eslint-plugin": "8.59.2", + "@typescript-eslint/parser": "8.59.2", + "@typescript-eslint/typescript-estree": "8.59.2", + "@typescript-eslint/utils": "8.59.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/undici-types": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", + "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "dev": true, + "license": "MIT" + }, + "node_modules/update-browserslist-db": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/vite": { + "version": "8.0.12", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.12.tgz", + "integrity": "sha512-w2dDofOWv2QB09ZITZBsvKTVAlYvPR4IAmrY/v0ir9KvLs0xybR7i48wxhM1/oyBWO34wPns+bPGw5ZrZqDpZg==", + "dev": true, + "license": "MIT", + "dependencies": { + "lightningcss": "^1.32.0", + "picomatch": "^4.0.4", + "postcss": "^8.5.14", + "rolldown": "1.0.0", + "tinyglobby": "^0.2.16" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "@vitejs/devtools": "^0.1.18", + "esbuild": "^0.27.0 || ^0.28.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "@vitejs/devtools": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zod": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.4.3.tgz", + "integrity": "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/zod-validation-error": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/zod-validation-error/-/zod-validation-error-4.0.2.tgz", + "integrity": "sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "zod": "^3.25.0 || ^4.0.0" + } + } + } +} diff --git a/react-app/package.json b/react-app/package.json new file mode 100644 index 000000000..76e46e76d --- /dev/null +++ b/react-app/package.json @@ -0,0 +1,32 @@ +{ + "name": "react-app", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "tsc -b && vite build", + "lint": "eslint .", + "preview": "vite preview" + }, + "dependencies": { + "react": "^19.2.6", + "react-dom": "^19.2.6", + "react-router-dom": "^7.15.0", + "sass": "^1.99.0" + }, + "devDependencies": { + "@eslint/js": "^10.0.1", + "@types/node": "^24.12.3", + "@types/react": "^19.2.14", + "@types/react-dom": "^19.2.3", + "@vitejs/plugin-react": "^6.0.1", + "eslint": "^10.3.0", + "eslint-plugin-react-hooks": "^7.1.1", + "eslint-plugin-react-refresh": "^0.5.2", + "globals": "^17.6.0", + "typescript": "~6.0.2", + "typescript-eslint": "^8.59.2", + "vite": "^8.0.12" + } +} diff --git a/react-app/public/assets/icons/android-chrome-144x144.png b/react-app/public/assets/icons/android-chrome-144x144.png new file mode 100644 index 0000000000000000000000000000000000000000..833fcf97ffa8be01d9efa488b6a927f62fb0ebf2 GIT binary patch literal 29992 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
mg~B#bqT^yv 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 literal 0 HcmV?d00001 diff --git a/react-app/public/assets/icons/android-chrome-512x512.png b/react-app/public/assets/icons/android-chrome-512x512.png new file mode 100644 index 0000000000000000000000000000000000000000..5baddb33011b10828e9539a0a7b662993b8b3928 GIT binary patch literal 30053 zcma%iWmHsO)c2VghVGUe0cmOJ7)lzEl9Ch&m6DPiLP}ypLOKLNT0lWS7(}GIq`L$G z>7IxGv)1$RUF+TJtaJCd_v{b%oPGBF?Y-}g*3(rZA!Hx~0FY>?tLOs&y^>oncLl2+}T_O))lrS-zc56j7i<>JS33t(?^V_EL}*WYHJy~Wr`is+|i8K$Bir=(rx z6Fj%IKY5pYzOXp@_b--&2FuQi<>1HiiDLPMR=DnTvU3g7GYwMG4U^WQduq8=tlhk90{-e>Oc6%gBc16YOQ@8D!(`qvsr=XP&?%ToSpr zotKZLX2S9aVY&H7*ty5<@QmIx4(<`eoql$XK{y_kR|I=k414ol!V-VEx%znp#&`rK z_ym6Q@(y$I?OWMmd4)&0_{O>U#^{-*C}^%I=&-!^uyo85cX(!nL`OM!PSiB#7+Eg| z2C($3D@diQM`l-cPyf7d#j@~@a&fQn3Tz@(wybT|hX%25qHX{kqoN-srWnP6|7dAB ze;tLDl$+q<*Op?j{n&aB ztce_Uz83o*U16`Tv1$6pf)v=x1#E@kKMqoCPc^pm9kwhLiyg&c&$0jNvHjUtQG9He z|FxPZ_JQh-mdu{5;TkI)_OZn#JuWuH7JK~{8|R93eld@@jl~{*`1uoiTLeolgeB$f zxy6qarQf@(kCml4ukF2}@-e;B%l*}XUZ38VV*1v$u?JJ%6LjK#O{{F+9FiM4Si!vY zbQIh_{@>9#_Skau@BgwlU9Ho>|FRu9iKqW}Z{+_NEcW#cyIWa{ox%=bzt1OPo9inp zvDm4B`iLVe_8M!Ge)BwMQbp!VPTSxFR=eXrNmA?C({1r7T0Paj0 zDvE}_knL1hO1ltsM8?XmS6^TFKR3Uy>M3}9Kcn*3;+6Z7Dor>+h_zbhOBF*1EoLaa zgOc z-?X=k!PuKUdm%Du(X7Xx(oMq$DNkC7wHEv-iH5(|&TuX_E|rMsGcKLo^z@I@Y%%`A zrhdVIyiUkw&x9fn!_uPa#A?gKPo}c_*524VeA&4dkr5s z(ebdZ%ERHwfu2fk?&nqXbYmqgFFd<`3NfvJo;FQ6B8N1|E9{cgSA@d2bS)ZjDTyai zX&_NBbdpyeBq2eW>#-y}#$S{eT6$sD7qUDT67uj;2> z1--+AQ9I;sG3cyQB^!oZj!e*Y{Nj_G<4_iB9_|h{;yPyqpe*^OpO+xkrh;Hf>?3v zczkOL`P};N_?Sw$&b3e6C)i0WMF&B*a+~T2XMQAy4)6?=;yALZV35~u92#cK$h2q> zeIcH)PH_s?Xm6od2<=hD`3+}P6ee#Lh_U<`@((h7Y9coEYHR2F1=%2T3Z3x^8^x1C z0<@!pmC;4<9|awf7X8C435Cm88(D23ZnxoJ4&aG`?+QQ+J7sx)^hG^5hG%l)WxA+9 z)!UV=*+ke|gCTC^pG~h-;iCvlDE(pR2 z*2U-frojEzHi2Owha%y_UGm5MuG#&UeoxnY9^gf$_a~~0>5rqy-4P^(+dUr?6X5#T z#SDprUz`*dQonkAC7pB<%ZxW$LXD;{6665+h&#r;a$=RR{uk~{*uz6OIx3=(@e@z3 zB-$8{RBVrZpNh4Y) z9wBokV{J#1IafwgrC{j{xD1MnrokTDB1o#kwoKidWbC*)mX)J&JX)-o4C%us+W-${V?kQhp6Qw*M^Mgg3w*_ z`8sz^Jn}brG>v$U&rjvX!fV=&?l?1bcIhS%pP286=5B{oPMZYdv>-W1 zxxypw*^@78ZqJ_ak55d@yV`D}I%3KOG+c>X{$>%N)E8(ftyXK~d zuzpm=IaCant5j_xd-8ye=G)}0a57N|?FVPXC3U+VW6mTlhuUA|ZoM9VX3GTCO3pcS z(M!houmhA->qp|Kic)TZoS@kuh}{_pe!EfXBEQ-_7vf6fUeU1pfx0%)IBnX}7pzfxi#3zU0&h(>}IGZ36i=8SI{3`R*=jP)*oqg~8MKWoVNTgW;#sg0ipym(TRsTu*BHln;4ezBWb8<-7NX<&? z4iL@3Z;kG(E`ztMfyE(YrRqE zG4=Z{N|RfJv2k(mpT!J#4GpBMQZJr!KdM8cpbYrv`?x$;E1ND=V&V*OZ>EdSM;V!Y zdS{y0@t+mZ3{5-hAfUzV0AQo$`C>vs{>2|tVNP^>STlFTT}=6-V8wXDUC4K%5Bi(; zf0eg8s5y5{PfRFCNl5r)|Lc`usvlfN8*)%W4CBz$`7{l-)k_AWA+3rWFcbBstcRni zCZm3sJ={m`=i9s4*S~%VS}AQP=t@Xyv(R5`Gci(!8ixlxv!z7BMHFS@pOgRU)$>ZN z;|sAic2AKQB%#6yIegrP{ej9FQLvf(Bk#34LVq4;-L;ZN#{`{hfFxZ-YXKD3^B?9c z(MUdT5+o~#NJr4*SZ)hsTWa5{ZRUu<(neQvYL3*to!`Z1DwlXv+Xz+a2%@?_yC3<^D5SEALa5_0@ z8W1DL`K_=AHeonJ{$8=(6pCEWrOibxoK*x6Sa1s;8AAQiXE3&sJTlm}U~Nq&>N|Nr ze}-EeYlWqTwK8c^&;=j~LIs9+EQ>8I!*n~_(NTsHx1E)UjA`iDC{egFFWX`b_YT*2 z`{hyM^@x3#!Me>>bv9YVM%znN0V@>D>D1%>2*CNMKeWysg73ayHj(`2Z8>gkW2W#9%yOcJB;`Lm+~+Wt(eS!P za@=^?>0g-KkXqXn*z5`1@Q{vH@sGl=5|OMe^|=&v;8Phkh0?$uIrY*QmQ?MfQJUu! zmCN3(>*P`7czV=xFXq@jy^r~!eZ_la`g=B68JBE%ywo80)MlT6;kvL;>Zv6#;VE|6 zJN=EbcYeuAC7WB8AAR~=K=2%DA>QWIrdDL>WoP%Lu$V2?qWw_I=aKY=X2PGXtn#bH zNY)GO)a=-69P_$a3Jde;iB9atE1-f(AT|AX1!EH&zEKlH#=ilF8#}+Q8vL|u;NwOH z2Ix}Jq-I?6mfpV^X`=y+|C|Oc>PHQWYZ(m*t#`EGDuoFxJhS%45tl@ zEzu8H*zC;0-z3$5y;4I}K# zQ@VJUD^G8e(9zs|_`JdCM`dQ29E3aYcWi=~sl$m&T$D^S>4s>FsZqfQc7pHBgJ%%gk-es3{EQ1f z(%GMrIhmQEt+2)Hnjdp^G=?wdTQTYQID4g}Y%FOQ!TU`yk@)(;+b|#2oSm;GoC~a- zZ8L*65P-ewr+n`z;^g|$zih8Kq^8cRIym0@tKW7HPT}@?K^Sal;F>RlArhYPR!H&i zjV0YN<$a%-@OxvWzjaO{R;t3t1*EK)RKV!vP@V z5K<<0Q+LW?4<*)J5{p9h+pkKEbUgudoru+^T2+WqM97?s(kzv%6Q<+v3I62rAUz?(N^JD`}m0L z@Oi6g{5N54bg=^~EvxiZGW+zj;O^C+#A}R#bd2iN0qM^m-$qIT;}Qrpw0>#pIy_8J zDG&McE_DtZ`hMnU%OE;?8QIKH-eS?CVGTj9ZSzp^Y^#eHBnko+i;NN zn_W(&j03k7bs$0Hh{Y-m`@DI$ny|1nla_j?JYc2JA<`q(vwP1yZRXUg<~JbK8JJRi z&VI(QHSV4`zHKdqj)3>MIwc6uQ^^w*FNYc|i#8o7?;5aeN-D3OBeu25G%edQhh z_=B*O9-5LelUxO-UO-JKP3uW#b+tbtx0h&vvq0|4dpg5p%zfOIFg!gxaw7Tjg2=M0 zSKUN%tE*J?!;tTIsL=i{j}gdzcmMD$?Zn76i`i&=P0N=;-wU_> zkUQ^YZ3Nyr zok-WUwXBNjAkrh-UT?59+T^klw780^w7mZ8Ls^=!Mla$e`ZR)ow{eaz51T{q?%`W^qiPM9eRbqvM7{nAY2=E=Ev8gNtf~OY#MPiJQ84R z-(B-7aiK#)LltPlB(CIxMHEdHL)$&c-#j8GsF?b-$ocakCCi8Pd7GJ~c%C6FjrH`x z?ibmooSnnLxn}k+wT(`jONClK)Gz7c<-IN~@^OOyUO)u+`8m3UHvak~4c`;BOk-5y zU`Uv|{xkF;uEXodz8JSE4P6pKmUc!{$ja!i<>)#u%zNJZG$24Fxba>mF4d>`iDq_u zGPM%HNKRH?YpR#ZuBd(RST5nK&me8$q|FE0|3K>+-djH-AJ*CRu)4}?{9Cg3v4`t# za&B*#!}$UOc?j|ZqV@4}1zu_C{#?aB5~ioOW*)M--v3hlx}a#(R#ElTB8#y(wNz3x zqvGGY#>y)Ff5$cs&&qOiThcy9h<)!*KBchEQbJ{xQS0qy#JFdVqjN=3uM4)G^tnA4 zvu{^Dj8C8|KDe52{bv`Z2Af^xd~~wH1p6HM&Ln}OD*VYEaFGs{{8Ttk-%FQn(TI#5`?$G(|<>>pRWYqED60q+4cs4tyW>tPh@{0Rx zG`ZaCi`eS3zkl1pW{Bt3_w^Qhs-EfV+nxNicF!t8c3-?>s!k+Ma>j^rN8F~hyTHUv zHVj8+-Q_sTMSdOceK423kJ~;SnOu%}V$~AO5OjX7NFN}nA&3(-A}u(VbD8U;C|kWh z>oZ9B=*J@~*W0b)`S-nuG=g+fY$^{DtO|~37q)|6HGDfG3%<;Ab#bCjmD1_FH2!mP z`+)DQ6&}uScld=DjHP86jTc0ua08>>6MW*U*K$pNA?PhZYqYZBRR7Brx#o)8Xu&%1 zxg0FK5WqaQm6U86SN}7DXM$|JEBlQXx;pey@K0+9q{)TAPHKlSd)D`xBTsMn?{~m7 z;u5O0oLb59{7~1nnXH`5IYF+|+K-_?D!~%7nGA3|QhGAvdx?Cxys0RsJ|wVAJXoRI z(E!RWiuPAE9gGUcwu3dbVkF-kbb$Bs?|$qU_>F#5l~UZM+Usv^b)OMEKi@k3n4TEA z|2@5>H}i6-L|H9iS?X!S&$!)$$5+N7nOT19phyMGQi5EGzDt2xxJ%K?HNjxHp)V$* z^>~nK(E~!>(gc=AwHzG@(mpx5+$g+tAWbg zzRVw1?wHCwYWvOVX|lLOq={l7$PHsaX4K5!gAx zo{Nc#==;!s{rb8b8>ZWef6olUfvm=-puo`7#{v^Z6Mtz*a5{Shr~GCnT*U`QCMV<| zqtv-u_~3MjjioAPZf=kk^40SCcLD<{CYa{aL!9CL`&X2R1supu;HOVSzn!mbC~;8x zb~x*Ue%+t1F$`k(iYe{> z-(Tv5aFk*S^#}(A5qLxSZ>N3g?)q!BVgz&}BNYRuyQKyQi*8a)! z=$Ieh%MkRqa)M4S(Q%<55mTtkSZuc^(i9pt^l@@{sp%!duh!sF*+4<@BXr0=Q5_(+ zFikUgcD69swb(Q8a$k(!uSdqfYzq3Ds5 zI_LU={Wb#5hAbh+jJuaVUC|EusMvO=Y9_QCuVZRQcEytwBHN<*S{(g|VDGBzvk4JI zq-LLxF&e~P6Xg0RM-j@ikm5aO=6YHevtLtNfNBc;<#2u*DGlFS!S&U|IW@fzhz8T= zY{+!5Q=|^bxeU;KhVwf<1jGi#V8kHJx458=x{$ulTs|9w@8{lN3~ys%E;bvNxd5f=iL3}lMAV)WyKElpG2)-vB3*?LbGSdG*Lu>n>NEE9r0u`y##ir+=fjn-bh?0XO ze2oT^>Azadi>`k=oX5V^uO=Eylgo@`AACJ#QzxPOKz5*~dt8Jx$mP{hNAtl`3sRDg zwm5^Vkj$OdjYkPuT>Y!grVMFm<`3rrE9-(u88OObK?InO5u|__jW6Ws)42UA`?fL+ zBI0onEYO(X0JKN6Z3kc@e70iNqT0KIq+a9WkD7&^v>i1{5PuWo%zm*D>Ugst;G5#i z*SwGEC8B4hrs>9=jKu3PThIJ2`kbH}KS>Y!PNP4jzomO+nwE}_PRlxJDp?zme|nyG zP2kp=K}Z2`=vk!RrGD~K^__e3b}^-SQ)bP6yu=P#aG#;A zuAe#RXqKTXdcDGRv&DSA8o5^#_~_DPaO>MTumAP$;LYJfkEk&T2(4$ZXlEm(F@DwQ z$@;hS)b{nv(wS>JY>q&Bs8tcwGIz99C}Hl=-ERxrrrDZV6rvg1Wl_;NUd?`FCyt9=d;ni}UVp#~n( zg2jy9dX4n7<1)ZqI8(o-VLLDQnhqQeu%c*AvQ3=W!LdKkXz*l#Kzspk6LJOTFceQD z1a(pkM}`O_$0G=#M7Y+yNo}I#c&NzXqCdAA#TeVZ$d|5vubx=9mm)zKx+WD^iD(XY zp&ht4vK(4CdI|IDP?r!CZUXZ`?_%95+Pcn|d=ZT9M?bn%}&6e>tSLC>uLePc8Gw0QEW+_HOnfRP&H76dk@ zXlfezkf^pj{0lT9))Ep8pJm-)&Wrt&RAT=fHV6h;ATYv1U*tQ&5C$uGQi5h@W^@a(Hkw^VkKX{7eGh;RsGDh5Wylq#2_O|P8PwP&u{!HOh zl>!E1z4E!PRx5;~Ap0i(d(yi&u2L@glYgr1bL)Csd(&y#+v5-3l2dPgsdwoGKPc~F?1ax{26>eW|0HqBS}l*)OOKGvY* z)2A}S9vGzB#Qd@AUFgF*8P*7>T;PI_PLI~ zzyIqo9M1(JtDS;~>GaCZS`SlmbF}=F!rvM$J=3%r%Ig!nP&Xz+|Bhquccs8Yf}`G& zxFILA*51tNEEn?1l~J~81yk=dQCo4iPg_Rc_d0!AjsVM7*?fG?=$fe8ocCv?OG0O? z>m57@zP*Xo;(8fOmOR`t@!-4Pc`tUr%KXJ5nVwDI)OU15SkmD@u;|%!*sl~z1$V!# z?WYHjg)5TY>7j={$1~qnq;xcfrQUfpck*^|T;Cbs%G1{TQ)(>oGU$5L+_f^h&N$YD z4jKhH`B6kC$TJ{=6MjB~Mn|6vm~?0CLQnO=SRqJaU_t7)K6_FIN4EBdy!-mxudIn< z_ZSbH%I$q77=fS$93X%g_|COJQBnX0g2~EYkx>ULm5R#Vy6@$wfXNc1DLVdVR}Tzj z;A%<;!pqq>@0!V01h^>zVy1?dBUk0)fPASbTV*NiWolSrks(>G3V+tE2DhQwPzWZs zs!x=EAM`G2csc@(ft$eK2i-RibW)UFO~7!9|08M$rbhIsOy*h#5Ls@biT)Xx3I{x7 z&j3mqjHf|T5 zy{$4*z!6iOB~$S1XdWt5#(iuQg-gZ*2QT?eI6~Lo6JjFogN*^CqDWfS8;)B(R)5aA zR`nClyYKripE%EFiUkCZ@6U+<>nyy%h=WNy}7i)mj-BcDqH zV#Qos%pHChi17m4JJS;nnC^LXVy<69h4u%DFPRMKY@aGX=_i8Vz(56veRB;C_~CfY zQ?Cc^@1|cbuv-@O`Vv{fC}0-4Ac~^Y7UTFHAn|>TY#8)B+-9gIX1;cB2{EHmXtDM< zm`^_Cmv@o+5EC+hOS1-qld;dDbVY$U1DP^4o%D@>FpLvSW z2IL~lC_Qmt>3=l#Na1Yd%Y=NFT4kWe@%H3{ksnfjHhW@UHT;-BFkK@Ho5@b@@9S0u zp$5A7w+Trlc!>7!=^w?XVxaem1J=XM%~JcysgW z!MOA7{P8MOUfti+q344|EdEr3 zT`57yOam;Zf_XkL`#Yb>XXj*V4KpF9{UuvKujdgkGS5<+KKmR3CjFp+qw3#YS8Gq} z_s|ukjtPgHUcQ}5*A<%CUfm7eAi$^@LlNTl2*!3aRQ*ti%gYc{n*dmVP+CU%#QTum z$5$pTmb=R!$|RG*pd1_UVfbsj<)4ZNG37x{bC>DqXL@mpA%=68s2#hiE@!eKcv(+_ z^!l}pREw@~+nwOJJ=u zJ$0y_7a4raLi337kW*?K9xzT2S})Pm@N#QF;o6o9C>gp5){_IX(#($?fd6NcDP-gQ zNR_{YrfJkq^*sJRSp$X-os;HhsZ_mdND^EyquFtb>VBbWl3r28ga##anqI@PHIwYm zcIS|$rqg`4K%%!Vs+ioOid7hsa|?(W4j}dd7*Hk$JGl2>`acPFwk?kJCi=9$_3^^_ z%*iX`P!N@SHfAd0r%IzgeP7kUu7E;KWC~wKnr)20TiU-M&IXz* zdb-^46;^fKzoqpi4q~=RVSOHjXu>t-@Pq9I^wKSDS)^$!m~}fmjcGKr-yi9I{}kW- zb}DB$qf6_-U0rR`@_2-?=7R&8VLa8!dQRyVF+{hVexX~LC~?d(Kh?af=mTQ#S$a~B zz)iF*kQBO3zhzVtn7PRwx?&Q^#Rt4d?waIa>c1+F8{Izi;W+vp5T4?8R~{fn>!S5@ zy1%3$S?}SPWpJ5{fBV}}5C>FLZ@WQ&wh_clyl0J!=)n`9{)ZJ35H{btxhX(`a?Fq- z5)~t40LSoT0OVuXySo6B=`xh0+TkG|vJ2@k_ToSU2sPoF{eh^|+#t0k`0rad z`Rqb^2ZIIAgxRW|SU&`pSKL78RVeqslaH*_&X0)^FF!)bZ-cLsM8FGY-u-}^7;nQ$ zo4kHyaHzzrsOv)Q2h8mo*h@R3MG1=E#YJ5c1Dq|G%O$Pk`2t#r9XJBuyQ6M&cP*m6 z7mm1S0tXOl4=rYhb-(js=wHBXqv#=Mf*n28kHzPQqHY_c&iL3Gzi1rkN@KYExOEJvqMH-YO<=o z0kLpfW^b^tBnk9h=n|7B{GOvJ;~rBSgT-=p!>p+`!bgVLkv!?0%w%Kw~u4n6$pR%n930vPnbnji>%qUc0B=7Y68l&Y zPt7WDtAw|x$CVTGwfh1(JAwFhv2PZE@_&qkv&!>Wk>>rx24}Myh}0r=t8s#>R$5Q z3QwznOOKiWC5MBmFg!rf#kEm=&fVG z7MJ@Awd17+xO5VW5i%M1?y6CCPppw&NC=fIN?c-ggrSJ1cnj=XfE*q&PJo?w4cvTO z!Sh`_w{N~&=?4YA6qu@?oF{hED=i zztrV~e$6F?KVxQQE__uj6a?(V^I+E7rmAY6eoSURPwa7ppi?0EmE-ChJe`9H*7?*t zzV63**y}~BuN;Nl!IW2sl0?sv7pkf%VDuL`U>}8jCq6>DKRg3lKTTMWCSc{;x4%WY z$x2ikD8)BcPX6&cNt!%5U7QX)O!Ts5?zv@cX%$c2BjKIZr5yRZb>FjV1e}%R4H{E znwgxAB>ph}`s8e1DY{@J{V{dY;@Go-U)!r8k#)^4J-;cIe;q!n!^2RC0^(Yl$B^lq z`FrdPfW_D5VH1BAr5H_Y;PsmXZ?BWlu}rxiQf6KR;JuN;wEQO>_^I}%ngX2hmc%u=VCSK@81*kHV0Q!;N0vqWYGVnRp7NQ3OlgTbjpsJa%FPa|UX0+#N-t~#|1H|~C!ELqs zo6HW24S6RoW@O;+Yd&O3)7;NzMpf_V0p~5S@#h;;fC+5@=+<`U0fY3KkSASh=8sTA zkAo_3mvQ7vvY$Ro{@5u`4a^uBzziO_81WMb_b{gtn=eljJe~<9m^0nzmSsXbt9W?~ zNAn>a!8Le<(vOB&8{atNkt{D7O>>e~lG5n!v`2(wl<`u4!6?|E*~E6lx4B8>o&ZN4 zu=hd;L@x${ODRcXAXy;e&~lXVNg+qly8viUVOK@1kfy~3Da!v!z(cTbbVbg9>dgbb zfez+^qg=_nPo$C(%?6;>2GROt+2!pgG`?hyc`FmAs!5bV)ou7GqyIQ8k_`t#r3GrE zYiu;P1v%pxg~6Sc=_A$)+E#i_se97rP8E0oGDF;Tx&T5H#0>&L7(hW8)P$em;U5_X#<2DC@q3N6 zS>plHRqONV_$0xwN8lrn1ossoRWFi1_6O|`MII;o#-o=B@|Y2GgCZf?Ndbn3@b_)J z7)X(Rnm;3GzEuy!;Hlr2$1Kq3q0YeeQ1kWjRDUfhu{EH0KSXGcixR|aE5VRjfrM4T z;e-I!t92yj3i<_iBex);g%4AP=)>V%wSkbsK*J&cM0*g=I!ZJGh^k0FjP9Zhe! za|($8dt1#eG#Fff0edLk0T36bqJQ#YqM@W@?&}ByTNQIO>~YeH00N3ExuSQ;0pnfn z8$~8VrBZ-*_en9nzZpedUS}}UxSj29;P7_ML*0Oh@_&)92os1Nr_f6|BA^Lx92k2I zFc(*>e6zfUcciI-1*B;rAUgLppclcx#n=k}Fu=S!xnBqdStXahtiQrVDcUXN<1V21 zML;Go6s3c+sp@h}h$;VP8=~%9NN3l$4Ae#?;>yz=7Y^3 zgC*vNL~!l$d{L@4JtH$nxD8f3G`X6fosoDz3r zaIysw64YZ!I1=PmJ24I6(C95muuZjSeWksH=29wK5}H$ z1s_M|2)$;Xg-L=c!8>V5Q2`n4&PhMsZ=`80bH>Fnpk8lLS9@mhq)fMUiH1PHdykj( zkHCXviqu9;*i~2%T%9C?fJs#z)oyEWry^kW`@r~h&=2Mz=$A=tjsvdzT>UBae zZvHodE{{J0;sZ4$(gTesut12;oBHN)>_2e5b3&DGfNDfSj4P>%dd7QnJ}`hNs1QgR z;zeOU$joe0YK+m!fCYRKloiAc@V5cv0UJM^knN^;?6+Y>R!z{=a26UKMGLqI%!vK% zd~ZMkJc<%X#sbVUs8lpmkIAh`4_3b92Qb-rIwYTfuN-O*Y-fsYO|*PJ5CDj7KJX`$ z#x_lWE44)k-3L=4LKakp-24U|=#Iobq^Gs+`*;LUij2mP;rs8PCbbo#8xT~(f|dNy z3?0$3jbcq#+42@4T8#+Rfd{AvfQS;nFvK%O(&e%JCe)gK>%*)I0pK=km=KVBh!VEr zx(bj!j3|3Ur>y)vexMmeVF_U&1}-$Hdk=PH*y_S@LGGw13=d(!g1K!WhiZ+Wws!ba zc9M^4O?()kJzYb0lM4W!9m!5qaDnp)bXf~xQhHU>sQ<+JgkTwj_uw#ygyUjX)0yuA zBqm(r&NCkf7-T^6B(yh!flmF_OCIq4MBVFE$&~ZMk>lt3aG}8;k0Hg8LnU5+1ME9o zcljY8|MNctgv`a9y3&Ndr@&VDPOnUL2ZDtLZ2LVTih+%u=ikU#pTO}`2xba&J^Ln` zx%|MdI6UCZA3I>4ne8;(Zmpi=!;z(E8AOA5d3Jw-68~V-^I=MeAtVOJ@J6{~z$rec zCvqiC@OABc?9S-TAHJ4*bP2&M0F@cW<2k?BDz>+Av>S>6uBhxc%V;zy~k>WF}<$ zI|tW-Smxk~U6znO#b=r?ZDFX$T$%UWWQa!|hqS2e^C832--fktY7_t=rJ*FX$;Pd2 zC?B8i%?dV`@40CZHdyTMn!R_hXDeyMm5-2O2aw-FXf`itvJJFigX#v6nW%V)0tMNI65dZ4*!798XO?>ILE;BNSm{OR5%HoB+BRu86ggxqiJ916;#2bx)Bau5Z5&J`@X&_?8Qce&X}=fC<^zc<0T6VC zR`kI*8ag=l5ci!DS)?Cn^J9(o6O3-~sMV)bQef|!7jvqy7ww0Bgb2LKJRFL#o^U`u zz|5RjzPY&N0r}7j&7P`pyEQh*vX(0q@{@4kYM|vDRB=+?hp0L_CHZT_AqaCPX#2Ap?UZL$ z-0dX6f)^{Gwn{@ftFvHa_<<%4ifyILTKGc&^d3rtr>|NzKz9KJm3-MN6;6nWiLJ|P zZb0f=l-;OU8ySk6(E6Suk=3h{HZ|`DER0{Eu^CPN=M~@I$WIo3@OU*#x5q3DY@WhJ zW4pq?{v>g`HM zIyf<#Ih@9M2M0CF^oJIMhpGS>FIF=L=KbA_G!8+P%ufZAs^?j;BL9pjY0-FlGXjJ+ z`{%2qP6GBei;#f6O|LU)t@pw0CVrV)F82qkUI9V=e5bba@C30p(Ev_zd2B?R)ji+HZtXtzI+b@y#2`FmbtlJp%9adOUhjKcMz`K~dR9<80-md4 zVqZ;Xo8a2eTJ`0b=vc4ZB#hitZ%rWx=Aq?f`T1h*RrXoh9eZ%_ip829kS0}_zDr6nOgA($GsBGt3IX*d zTLdtq2+jUIa^@59z{ihHytX7lC^&vX;Q2p){!D`2?6rFh(LJoPx%V3|@QGh<_8vCR?^AFO^n*oYMEb0CvgWK`ah3c2w; z<|?=1XP@JD!txYKWf~03->2*A;v+wg{gwAs0)Rh590JIch%xQ!3bc?tOsJQT&Fs&O z(-Qm`7yaV(X?8g|wLyu)w$ChBvJSt7Mt?s>S$cp&qX>`>d}eL76*e!fX=x0@Y531l zZv4k-3L9-aIf^u;O z!jL?v^)~1v$dul_x?821Y2zt7hJ&k3w9a}{cndDVdX5|}12O*9)zwW+mxvJP$_UgL zXXvn}jH;6W*m2(J_1z1jn~P0NyTzRF$(j-*1@MBD<4+Yk(&0s6!DZgbk8A-d?grM@ z4xR3=pWI#jLr5=bBf=m5YP&Da_QvYa+X7F`SB^kdUJ$b-O7_eWySsPU9LZ1UDE;uS zb900YxrE@CdNmn9I%Okv?c7L)61D)Swea5eXY|^H`MuK3-gxgI2no@yIy}_XyFozC zjcV~dZM*}&t5&6O`SEMfQN}-j$m9@`e+9Y_pnK{ys4fQ5}1SEZx$U&_<;CzXP*=gLJ zt~MhEdtW5bVl+%wG=sGA;uJjii!Fe5sKF zA}J}t6eR=!K^o-HEg&kWG}37xN)8D{S_SEl?(TZ`d-v~l&b3|7bMEK9KeY?~Whx?Y zuL3wKzfiC9=xGW%{8JLHLvV_s@H3?u^bBDQA@59^li&WOi$UyWhP_B!Ieag(TFU;g z__839yOa4u5vJ0s%#dCw?=9HS%4lY{fy7~igyK5Y>9bi$R2EtScath1A%QBbnd=Xy zs|!`xGIt_k#2>BJYHN5Wm>Esf`;|f;194-WnNdJ41mH^zY2+R&MuE!>OrUQr&3A-F z0|o1MRP8`wGqvY6Z{Dc;Zi> z1Ft(;CnvDa+c95R=8^mnj_4-uIXz8g1%DF}&fnyZf2u zTGYdPlzdOTn+>z~YSiE;lDjJ%8%CvpYby&r=}uLNVuo)BZcZFg%slw7F%bL@hSOCS z!S1{a^;SW$J&fwLOW_y)3xLFPOyESU`e z9M2?(y*`H{2aGug-%492{ob>yKlC{A^99++@(5tXt5kJ9!+WZGZ6ue|PM23&_<_Z$ zKLo0N%ZM(3_zY{Qz5XMLHmPC%STr#lLGw--{;D*~;NH+QJUrnlqn<*BBvENO=rYJr zs;A6CV~aq!;JKC9b1R;V;C0bc`Qn_MYNr>^qI1e|D0qn-DG@Y(su}k{>g!mmi4vG* zz=ua8@K`9lP=5(=<+`8)ef|Sd{YWC1n;Z))uDTvtUPk&19-v#N?q#TR#vk< z#}3kH0C^H0Q#L0|5AU1s9&PglwoEhR^O-@BrQM~!0YtBS|mTe4z27) z3H25c;~(B~k|zP=YP1D<0m03+Uiahy-c1Q?*?5HsAzu>i0kbmSxsHHT4-&xqhj@cT5d2hoNgurTKUh&yA147`FR9bxXUNLP1rXUo zzl4R08jU&$%f}35n-|M?mH=FlnD4~d?QF5Mf5n_25O&NAQ$GYAS!lyZ2=f{Nz(c2! zmBXCiOW=>l*}jiTp#Q-;$uUU6`}E@3?PGwzem9|q7oZ;ys*-@WI{dgBo@hwd1DHTcH|Z5bqt|U)`ns!`_o|Q_o^=#IBS9z*TNge6THe zjhF(MIS4=W2J7>+K(4dmX0dMlY%qHBlmg(0K<3!{yA1Ut9>oCQ>%V74%WeT!_?thB z0lqDWB>GR{*)I(VLvYRKAy*@(tGD0QIrAYw7Y`-S0=S(zg@SV3v>*8(eoGinM;=QG zx?WdFAdoQ57K9+~&qrtz%M!qw+omoZW`)HG1KlcBwmb;18wv;%)2Awtd-J=(Dc>iX zk}|Rc!mMqzWYP|ty(coPBM_2hQ!HMXs1&-Wq%3ZvinL30)dSUQh0mc-E*-9 zPKwFyQwZaYLtMU1Wl5rwUz*u~7it!1qQ6!1J6i{S{ zj|d5m<0GSoiSaqT9@-_=smoS`10M%qPT;%sF_>SkK8zH6Ze5t&G({VFhaSqyZP0eu zB@r@afCn)EAIe!fdMfNv`AE6vU*iKQjNx9}z)dbPx^{Oo{`AV0q2t|u`JAweE;HhP z$L?i@E(C5~1EL)MtbcQPYrPRRc>D=5)r7DauOgI?G}+)zHhGEYw@v;aREV1$n4_R* zYlxDh&NOA{m)B?EGK6mg34sKk2p|Jf){xD0P-Z|vHdV>Vy{!lf8bW&YLU6OaQ7QRP zl}FKsne~*T7;&G_ zIEw@jyKf*@{W%FyKpuovm|L8@As&g3LST&?89~zB&Yv>1q8Gk7UcSVO>{I|Nugz-< z6i?c64-cO>Vi+n2cCbEG0L+a5z%Dq*u`}A4no74qG{V@=1bm3&q3J)-F$d!Fwz_zx8;BjiKS}W`V*sv9im;y2isMd~8J}0m=2%ATW}a zBkLL&T2*LvbDkB@lXj&YoW4r%>(L{y4j^6y@FpSv9N3iZqibwck?zLM26F|#_->~h;F1wjF?!H*-DFWa804~?BE zNrIy%Wej*+-T}Y)F3Q~&Us2y_|jom?DN%%u$gLluvOlS%BIsm60BPX|&b^eW! z{^-7sfS4_rqeVi$7z6PFfIB|D{8nq$`-~@aPy(XIRt`Q~Xgpc`^gQ?(8v!9SID)dn zkysW^!g6w3acwjQf%|=n`TCEU@JxIpcur3)09ARc2kaCG;75FIpd`(s@BkQUeE|2k?U-xxypC$9zBqj8G9?u{{tt7ImcOOhc zMt}vlm{zUsuT3)pZ$dlL{@pVd$WW*ZfWZvU`KJ<8_rM|E7XfmCKB2-8XbMySvMCV* z>aXeXq-YiZO%&*`eOo8)`42g?O46eee2b=t1neuec@uBV5~8l=e*!_|>w<+5x@fF7o}qM9*iTZ^)$C7tN`;r{*w~eKSWH znJLY?pS8pUH#dy`x2Pf;PKzhB`-~reb!q5{YW|^xX=6O#J7>YvT+ev{;oB@>ScbHla zRXI$y*YC2&MonOi!R!!>3RT4N$p|KSAw1!_y{}6EZlk{V&^z$wpFa0(I$sK4%bhl2 z{1-z6N8RCa>qZl0|B&j6W>zH6c8cQDMVy*ro2`lPz7xRWyPqcpfqh>PPYLAz$0Ohg zNScOz_Hfx%BV`b~#%e)(+nmi`H%)oU*x2f0wPdeFyrm@p_em&YwgYEWMt=%~&c5D; zh<_M=rC1KI%z+vH++4jGQV{NhgnoQ3y+-@U^I}hCpPRWWes8Q6QKo*q)gsok1_^)u zb(I3nl+i$gM??hD;7dxXDDL$B)hkbiwJbltKw`QuJSNP6_#?ojD*Pm>c>MEu_cp|Z zzgKp-a-)qc7-zBDM_}7k6WWJ7=9%5Yhi?L~LIL~3qX2 zs-w7CRBlBh{!@#O^_suLAva7&yDLm%(Ia{=EIPi|;M;%UbAua=LBSK5k4#F(*0ZQd zk(d%mB2Pr~HwX~HkNcSl)Ii`@LcJHzpEx6M-IuKeQ}PQi$H&v6^Lc(uWdBBj9(p55n!D-umHgZ5Z!30w_At>F6-49q@42!)h zPXA3djdge4#`_A9k8L(LY69?=97jus0Oo)kSvOPzW(TfSA6f73oZTS@xCY@QMy=PG z=4Rg8CnS@Wi5D)9?gR;IKppX~yNOCj*v%8+kk)CunlA-fst!wh^^reo{ALP`!cyA^yoLt8!jjr`0P#?$p#a@WtMp zm7|$rleHwWSDlvN*X|S3>HN$P^+ji!^_98_&rc;K(wpQzghWI>6zKey=xy6T;xL@I zDJy2Xu0W8H48%ZKG%1|G8GRw2LDzV%Z9Y*soiSD7F*_Q>vyi?Gn}0O=f%;X{;~-+f zmNEZaQ|PmIF!^P~ldtc%GTqs&x6MX)?v_Wu_u?C}uGSoiQBTK%Ya5j0jTeQ^q`#6Le7L0f9!UbKTU} zS7eNNlTkn9K>-iVyZwv>Q)}tPfsGfu5|{GBveNmbEmE`g2`v~gX}f=x9k>I zN;+O*6Dyos`0MTu=d*2uW^nAwQIg=wE(kUG&!GRnz{544M)F^gRBZMxLxz%hx!<^6 zzO$M+2)B8=yr&h^7`r7cf?GHUP~@x^Wqm#c7c0pY#MOxL3Vj1g#-eFy^`|F~KhhqD@LNZX`*M+ecV}Gf4c;82;0E@$GPS@952C4bQpPErSY|rC zZicayYhl{F)>!??fBB-xLOn6AGWgfsM^PD`!=W#JPn(6qF<{sKA#)0| zJMkTe=`)~v6+`u8A*D5&f_yf-#`_H|n1%Rv+it7bh)3F~W5~62KR@~XSGPrqzgdiy zI-+X&PDu^pd9VZ&?dU{_d}MKLtF^-#I-HSTFr@*mbddHgugFk#1n)n;|K?uJHOTR^ zFdltguOAF2I1+|-EU01~@^e2_@w0x8Tey79nBpP7y^6&Sf|u2vuC$AVhgK59{3ncg6boLSb*T}TT`{6kKHC4+>UBg1dm$suc4rv8)T z1p;eGtpRE)SU#mlgXAUYjZELwGMX0MFNjU7>CKJIA{vDIMF&3@;se!o75@cE zseRiz+abb1iZE_n4o<4E!S|>x5_v#)3>wb`x)pXx_ym6|f$IQ6_X#+KA_@=^i$SnN zp)&T58sOd_j$`a~W3%d_fv*t3znx@RKpE3!Fd$K+W#5mN_uJxlOPJ(tv=QM4iHikD zK$HVSiUCf}gq5Ot6WqlM@cqaa0KW7$@s2JhR`TF(-@Ymb>C``{jDuYN;a1W{Xk9;% z`!3K_zwYwYSBY0mPn-El?1?@X+<6CAbjkG+SgNA8GK*0Ly#he>?rmzN`E%#WDg`2G zsAz=|h8aNk^MYD1^BZ4tIR^FIad^=*9TF1blp!_>Ni~;W3w61diOqTY7^Vb<_n!fN zT2*mHzy&Pm49|-gBtr=8nqOYOY2o92kj5@`VXQ&S%d270;l!TJhlW|1YylAmjFJTs zaqmuz&N*R#imLA{sC*;$Mi3ZwY~Ik~2x8%FAvT)7N?j$5hPwlmV6~e7!WW{k(qXkb zz&ITVEUuku^ZjZy$z3XoriNd!?rg~P|uiT^o_A=10GPV%~zw|<>ywaf{gc~M! z-}+)M63Z*{A4qoRg`y=IOUACvz=yu=Mj_bZ4x;6+aAGz*MXRNg8J~-mwO5WtG?U&0V(2 zSU)^;X^jk}-uo$MI>kk2`n$l0O6;FRpA7N9#Lt23$em{}$enhnqlfvNIxKP^Sm!59DG*joGpdh|KZ%p<@?I~At z%*@cukr^$uFJqQJ3}Eg!omF|&KU$Af1Gn6_0GOH&xbDho+{FM32g^-IzBd&H+;2$m zx~~L!`bdY;Iu>J!?OZR-KNCI_Fv$Z~?{SWq=&VOta&r1ET+%f#^D1Y^(<^4Fh&xXv9 zs=`Q}6XFxeM*^{If2*Q_r89zRdW2MnV~-f%z<8WbaQoebL}m*RB`_7)u_F8JYny9E#>k0BfVQ4 zJ%*n)e2dPKdmBGbe*W1X0aGvPyeG9z4<7q zsJt$kCqruwf?hP#*w3ABS8AK^jHDiz+V-Cq&6_7L@^!v-yV!J6w{li8uX2m{`Ze_0 zRY93>43Hoei)C%165?2FlH*2LBweL$CM!F#84# z2eX|KP;``@&9yOU4!|rBvAIO7$Ku!8VQRh`v?lR*qZdJ_AZA>;t!Zl*0%Y$cu{J=Y zbt_5oW#ockkm0_A7rl*HW>78!`#{*S`+)U%=1&u*g!Xrs3Ge~~Ho+Odt}+7kr!evs zCG5Zqt_TFcNec)LnCFriaQ}5g!5-@e{&cvwPBn9b&F4qpYU{NN;zAowVOK<)9}?D3 z70i61TivM##){WSDS!fmZ$Y21&R7lAyJm+=l3#S0RDSgz6!0a;S>u(LUJzPBux!Vb zJ%cxt<;<3Jx@Va5u0#Zh3nvEgSUUFyUWSrekKL#Br$WYvuF9m5!)6!9A-9pE`hF0t{O*r_!b89aG;4ZNTQGbJ3<=D`qldSXW`yFxhSvGU_2ut`u* zipg*b! zdH?5g{LE1p5>DL{z?!zqBc`@IDM=-XBD()OseL~{U8fEpB$j(a#!z_lb9cX|;HLAh z+XV^ezGaMy+eF61ZNH|8+iq({z4|`qGY;cOep63qv)96Fru)XG#E;ONDa!*_j@ys8 z0Qi>)P`YJKC*CLGiAwvY3QEgO8>_wk=WD^ID}}`j%AO{4#;&NQ;I*5w;=@w8FJwWR zIt`=$*-Ma{K&{wDCGms9qYH{EGqZJ;#fYJ`l=agzwGL!4!hhe?Ph(QCIp3=Da(0#?!G7w zxF00$A%T1}ZoMKg8B@CA?kbR9#o*ij@)kMZZuQ)mS7Et)vU5+QM(O^??&+efTSMNn z_dhBrPLvk>77#?m9Xps+yuL1vi2D)%{}O%_HSTxu1(w(PXQ*UO>WXS%lcx`N~D5`h%^|6qQwNnptQzEL?xY{pP)VnxJk$AgPDAxZ>kcM8qnQSGCbmW zRGG@gUYpX!cG_FZGc)zr)|||-To6@zB6E1?3|b~ zZd!M6JSKI;=fTFh3hfdh{}ZcsNL<)6^B?7X3+#5uDv=_&Yzeyc1 zwKCoDaXnJOl-jSMy$VXXVlXZfWWIXZM-6bV1(bn$*=9@IaPIKFhv7RS-Jvl z+MEW>?Mc5SB%0Xo4U5zS=?tER+smd3NdWb4Y+kVlxDnXDITC?|wtVbh6-?FPvsT zkTWHS_dGpstTV)d-4*%m+w@9wLQjE4B$5cG;_-xgMFoy?C>Xs^(FpMD!gu$F@I%6z z{eI*_=`$%_YFhB2%MCWby^jH4jBwLan&8VMS&pNJvu|)92?-2|m-jfMzCaiT6%Z}6 zokPBQcF%tC9Ib}P&Zqk3-oyR$|1V>#lKe9-m0-~GQlPe1m74nxUEfH->%Rf<^dfrPtLvHQF>nIO^=bVH7WT@lL_PMP2D@3BS>%OivZfg)ksChhpO4 zfb;y7!V*-H2WZN=TpF~7W_2!EpEw>>a>$)Hnw)Ec7CN3`DQ9ueWp9+6^ed`4o|d@_uj2ujFR0eN#Hb{5@2Sh zsJ>Lmcm=(F^`B%#Abt}L)5M}q%#fOIi3l^@disoAu{vz5{n9Z4ppTqV$dvkL>tew#`3Knf_ zkOmphlRCOn(bz~@I?|SU!}I0BMGo6F*zmf5=r=yYVbiCCZ1G7~4wmLWW)@G3V8Z6* z0jF}xir~vdkbueee=X+fSr>$#s3!sF`=0cjoLs6Azw`A!s1o&$D34F|aY<+!35+s5 zrxDCm5eQWnbbfU!>tgymaeQHl_R5rSQkLlYc?h@RpkfYNw&rs)tIqE+)Zkw%_;O0o zLeXecSl&=v{Mg@Pe!BG6N$`cwc=3yRY~RNJGRB`&FdI$PFaLV^kb_ZYxusvit;$N1 z2%t5x^K{>7B7wXFN`Ir#V{H^F44Au`Nj@Zm}v;Ht-1K|8*@~2-g_LrQCgB; zol&vEMA0SWo8qln(_;IrgQKM!8@_>gryuTZD7gmrLr4qm`v9j8MMPwW(_VV{(amb) ziLKJ#P1VwV5nh7rw+$&Vfkxr|tJU$wZ^F=?jC zchT$`tO)&_Mhj7-2f^opakR}+!LH;qxus`XnN*G1qUOb~KTCgr*y>IwXY^Dd4?XfD zM;ayXB0M-idi(^k-2l3hV!X24-8@(iE4GWZOXvr`AR5CeQVK)mvyHFQne>fv)mw0 z+XjK(*T&Ax)tAO>Uj^7+NYDw1{1=U2GokwHcuzI=6_g1Cy@rMkG-?)jUitNWek zI29ueg5vkgw1g}xj6;LHij`ky=(=nW-{F2mUn-xQ+b% z_HUL3OqD|6&^v?~8Q?NMP~RZ#jCwh+VP4G#OecV1HcBFR`e4*}j+il|W$T$)i=Kku_Hi-`H{-_Ol=z@`D zf5c3C?WC=1%&M5Sm22fVX7gQ2b5MThmu49bP6QD|Aw$jP*(o6A0N_rp9X~r#rQqBk zqobK)=?R1MDDI@ONh6nkJdToK%*LgATB2F%vDxgg;MVa8R(JT*$TRVxZNZMH&B|cL z%n<%K#BI0HRqu?^3d!xJT&CykEp`@Sbj>r9qt|PK^-W9kL>tMeW6b(VLU>~l0Yo8@ z%MU+(Ei4r5N@Q+f7j#0P6SFi_xX+RCdqJn=pvD$EP-Oi~2#YZ^efd&WHrr@%Ym>wZ z(XLZ6)gl>e`(uS@=VNZfNL^X!la0;&g^p(Rs<(OqjbhDm)21KCD-H~!U~cz$K3GL* zUSKA( zSTklN9erG((O^V38g@laHR(Q_lpjckq7E4bu=JyHbCb-*NVfVlNc<9%CGA92j4z(rDD|suFbmn<#eN)gzw|WYn?v|f0X=_t%W1b?`hQ<|aZH@6IV$%IC3m7dLgX|!+4&$Bz%rChl$@Tz%cnRCsIa%QoZddc)mR3H+ay zcWmj7&L7b|w|#$Th9aP;WQ-!1%}nl-CdPQzVvBATy?t15P>%m!COH2_sVm>9@jQ}4@(7SAucJ1F&+?T znQ*3Y!gsE+H1KVDWpsCqN%imbK6zf2PNL^A8V^i^ZaAYoSw3idENA|gJ4}j4d}?e2 zyEdYI$0l>OwI9DbUSuU6>u@Kji@(UV#v0WS-;1^gNiO8uWS{$h28H4Q?dQp;_EVnY zMd$kcFCQOjAC2y38VeX|ze>^Jjf6o7X*36QC}$7Br)Xolucxflza8;)NB4J@>kCOA zbN`cI=dUS5h+lE2Nl0|$ZF3tjTbK(GG2tk zEk0P%;p|JRctzpVwxy|6fKRMdk@`=@#k2hR#Kwb1r>9qH&pejaF8VZtKXRIt*sri< zb8@otX9*V_e3(aX3MmK}IUYu0PpVsH?E>rVBggI#e>kKGjw9G~i0GX^_Qll)kOt6D zxDvj|=Sh+T|?C)rgL$+|B)C#lc&DB0K5 zBck^9QyVG2ke1*7%*F*eluUk&2FG)Ai|W-Gq`3A~e3eEuqq=D_E))Hdc|05q`T~BX z6LLBBI{sEazIFb6@I;4ONcX+iv~&E+x^W?LdE^p_CXSvZZ-Hx)tF`xEr{%-rOFlkr zm4`HAcG^A5&_hhUJ`tzJcSRad8L}q(SJrKAuG+99?(p`^eODF8kA_P4(2U*MR(7Fq>2Co!q9^ zrFe(i$Ei&oVJx3QnSZj}gD{b-(>gBn`yqF4_NC?P=%6xjGaO`6`l zTv=jzr>Wwm!O@L(!LNvB>4^(i(_Gzc(Bs(*Zq0%LMDo%^FxPh`R;|t8d(zirDr9>H zrK;UTZq(QsC*&6yXlLA8B*{|Yg2|MIrXA-m-QA5Q-FzT)h}W_els;m<$hCiH7k$%T zw=CG~cAHBiZofNRf5H2ph^otydq!weIF4_6l`JtespfB6eTL|=E<<)ueu2TOrMm(w zBQffdSMLg(I3+5N3w9|Ys@jrS%DrORa2tzjYx$4P*<@!9Pd^Q5n!zcW7;SOYSgDYl z>ey{jI{R^{K@4+Q651gXd7lJut$BJWVV7m^{QjyTh8{KUHNb!>f3WM`u~xEOI`DV= zVRf71)$AKDUW>?uNl8Sea*g%#3GQaz{5u%4H>ps6Mhl3B)v)a!b)KNaf&w1oR+oQQ ziwt8yO!dD%AZcgh{j;~H{N8DL!#gkVN{?%B@{^MYPnLUE5VweICmU}~x(w!UV%^Z6 zumu!+&r(m+H@I5FE=Wsfu4O#9^RjD#rrGw#sQ3U<18t%S3-rHSelX6l*+OlX){6nX z%8k3WV1o;}<`z0qH$S~*EO027Fe-i*YlCXQ8e5VD(0ueyS}l|`WbG~^-wgUx6W}<+ znEf-0-qy2h)4*uS$LhdV7nO3t&mFaJUnN#eebaXX|2~=^(|Z5DPbgZYE2mvo`xWZ=^?fwo+%IZHH;XQEa4bf$6;>nV=G_dfkm$Tu$1 zkIF+!5sSfjp{^<(!Tx8Sx@)5E!=e#2%~WRQD`T8r;w%WG3l}k%+!#B*J2|xI*hOL& zOmxu`_3~4X`Oh=Yl~YA>>t^+&OkPQi>t$nwgsdO}>m33}&hW=R%Hb2}nkEav$K=Tg zf8=m&Rg;p>puAZR!oO<-*k}@^t^JE)PaRXM=Sh^A9t!02zimELd?5K408psg|j?0L}yPi!}YncqarO@C|%=jm}G6Q*R1ZoeUJ13X&E;6mZ|9^)(DQ&raY}YBsvcz zvu56j2&7S=Ixd&_wdQaVsOhjNK-21kTBQ+%h582bYUDzvv#QCcPLoX*KW5$Z|8MK` z;9iy+>FL=&!esX1ukBA_o&T&nYF3PcZroPcr?I@N$e!Ra*2|$r5NlsJtShnlAv|qk z&!zwD8CY`l8ltE`OKHq4uD8CLOMGWs?G65X@^ERQR#4G$+>Y|LByQ?x=|& zP=;aItezUI_R+`E~EWbuYoSIEw)FhO_5q|PVsd8{pn38$(`|3YCJG)KqcaPRxvfLOf6>ik1 zWKsW)zeGnqz-|F$u)P)flFZ$ed-Q~5@gRX_tx1iIL(t(by>9!-oO!Rgl{!H6u_82} zWehiwucJav7{IVn5ug8f9$gu zP698HdXyF9nGWQqPD@7!NmM5O*I4hfk@(r>5np4I$Wu-a+m1=ei#$B~(#zDJ%eSkN zf6N@NG@T`yy`5ON5teEES9~K6%cB``TOu>#wW6SXkwiWSP zubOdM2j*4hd!#iNE|mT{cj2#uex)k6G5-Ng^TojQ+V_Q2;BKZT*x_bqTJxU2;mqL` zv+g~PgnLECUoXNw_3f2a@aqaVWvw`P3=dPB87tvEn%B7Md|o$AvIr0&Y@aFoZYy_u RoCydo9Zh|W3N>8l{{d*_(P;nx literal 0 HcmV?d00001 diff --git a/react-app/public/assets/icons/apple-touch-icon-120x120.png b/react-app/public/assets/icons/apple-touch-icon-120x120.png new file mode 100644 index 0000000000000000000000000000000000000000..e5b71708cef98a9cefe018f9bb7027b057e331ec GIT binary patch literal 2629 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 literal 0 HcmV?d00001 diff --git a/react-app/public/assets/icons/apple-touch-icon-152x152.png b/react-app/public/assets/icons/apple-touch-icon-152x152.png new file mode 100644 index 0000000000000000000000000000000000000000..cb316f56ac9ace3deee6195a062f82766609ab73 GIT binary patch literal 3304 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 m<(AieZ&O!Yb=6f@U4H>fl$@Z$Iq`M?0000g)gi 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 IM6N<$f*L6ZVE_OC literal 0 HcmV?d00001 diff --git a/react-app/public/assets/icons/apple-touch-icon-60x60.png b/react-app/public/assets/icons/apple-touch-icon-60x60.png new file mode 100644 index 0000000000000000000000000000000000000000..7b588a9cdbf967c6d44a2a8c66de09e196be5bf5 GIT binary patch literal 1699 zcmV;U23+}xP)DBoG5;to)hR6h{P_O=|Nk*I|4L8)K}FX#Isg9t)FLPUEj0f# zIsaZ_|NQ*_Qdj>qIsNhR)+{g6A|?Iz_tPIE{P6JqI6nU*EdKiX|MvF%?(YBc^4mj3 z-9C@$!blK;24|LExb+}+kGE8%Qz|Ni~#i-r2<=+q=7?W?T+ zPE-Ex>(?X+kdyyvV(OEX|L^bmDPH`>n6xVPyT&)cW%B{Z(7?EHc?UJ^uau|H8ZNsHxaML;XEM z|LW@dzrgtA<^TKp|0gZ~!NULa^!?}F|5!}ZASCl6DgJ72_0Q1p$H?xWq4Fs%{QLX< z>*4?T_W$?u|LpAHR8HJKI{(wp?Uj-KmYMy4gywg4|F5q5;M)Jh!~ctp?2?Z8?Cjxi zbMz%F|42;#M@0QnSO4+r;9FhSEiC^sIMpvQ|Ni>@OHkx(YyR2V<$i(MM@#;amDD9F z;(mebm6zvoY5$_7@~)=kW@7)js`I)@REJ=v#a~X z$Mwm|_Qt>eSX||1Vfo+S?2n57TwLL3YX9`>|Mm3$k&XYjs{f3T^SHMEx2gZ7pWIzv z+)q*eEHK_zTI6qS^T5FQ)z;M|D(r}U|F^3D@$mig^zf;w_|wk)Xl&IZC;y?O@0N@I zL^}7tvi+#4{_*hLQ&r$nP5F?F_|H{Gt&d~6`!206e|9NHMWoPcV zx#x9m_{hroadqjUr1-+M+BY%yy1V;iXz-qw_2A*uBq`Q4IQCIh|8{QpmYMuTOz*_S z|B8p}va|Wh%jlt^_v`EYW^3e+koDo=@`Z>Cysx$Z00U=9L_t(|UhURHxFbsdhT&?) z&Y^AFwlTDA+qP}nxVCNEwz0U$Io)08=}B_e^F2?N?;?MtIt{RH*EgwfYnbW($kfDy z5`A0FqKb>2dQ;_$nOQo99~n(kIg8d0d)j>({@&ymEAPmGDT<;gW7CLTZu!ua8*M=x z!$a)!ti#8Kx|nF^w4nw;LM-_9k50z=D@l8=gnfF8Q$qYWg+!|lr95*r2sdpCUkZC6wh$6 z9l_c)5O5Y)n;OO3c1H>MPSqgTScl;x1H^aU6U;LV}62=P<}T<@Q!zn3^}^(MV6iP@`S+{zJXt^ka`?% z8K)1vKKA}0n>EuXQ1_0G48U-42Zl{kaD4Z;d7b#m7|jMViK%#irJc+xV6Z8f#A~|) zyhe`1wJ}|IdSo7feX9xFTZiMy^7%hH@z~>IJ|S^?EP+=VFnk|axMv}7;xDq#lY>R{ zA@Bh`jy2t;%}8|)_RXcyharZy87-`pLGhD!4C)$8Gb?SGW+24yn34R4D&g0&0fAT9 z2^_Lt0Z&?dkib+0Akvoc3OFE*z-)IJt`YI&&Z9!`_-uSI-}eF8F$;=6%zsHWKfiqL zsnci7i_f0>61^D4VKRJS33??}Du!oNs<`M3nxZl?DD+CMPM6{4APLW`RSC^~-rQ9H zd>FuEh9zc+c)$x;UP3=SD3qJFOu{MtG8}Fbad_!dVz2s$g#rn$GC_s^N;t;w>s?ZB zT!W3LWydUk95DT0Z~4I-mUY^-nR2Xs+s(gN^*cab!E$#ny>w1GkY`FN>dCmkwEBUM z6<&)PKK;zf+zPX~pU(!0wS4upg;B&k;=kP7( literal 0 HcmV?d00001 diff --git a/react-app/public/assets/icons/apple-touch-icon-76x76.png b/react-app/public/assets/icons/apple-touch-icon-76x76.png new file mode 100644 index 0000000000000000000000000000000000000000..22094f6e1c6c2118c487b17298069bc955f1d2e9 GIT binary patch literal 1993 zcmV;)2R8VLP){{JmB)F&$c_4U&t zCD}Yc`}z6*GC1v)mi_SX-(Fz%&(Hnz^#3(G;Ad(7d3^u&_U@pf;ACg_*xCO?O8+b~ z|4B~TKtuod`2FVQIp#|2IAS>FU}=Nbaw&{?*j~ zJVM<{O#l7;{j9FmEH2kDGW{qo-X|*mCoTW_`uOPS`tkAoc6$G>u>L|w>zSMXEi(WA z{{AU2;3g{nGBe&uL)Q&#up=l0*<`0wxka&_^>$NwxY*e)&OdVJniSl=lv{gRaV%*6lC(D>2N;V?4( z!^Hn3EdJcv|5aPlAtdwB(*K{L|4K&xL_YprWB-Yb_R7oub9ejP-T&|8{-vn@@$cMH zROo?!{Z?H6j*0*C>*HKg*D^HyWN7b~jQsca{BU*u{QUhYG1Da}|CEXFyS)GE>-o>e z|I^CpjgS81+4kY$|GB&Jtflq2uJx*x+)hycb8zc^bN~AF|KQ>M=HLE)g4Zf4|NQ#Y zBPa39&HJ;p?0s$gxS`%8DgR7T)+Z>}DJSHDh5VM8{xmq>S6bRgO#L}O?YzAD_V(LU zSNmdS=9roJ^z`?|$M~qL=4xaAT3+sxhyL#7_`k6Bz`6O+%;r~G=Vn#^w65@}qT_3B z{Mp+4_V)iwJpXK8=xts9i+JjGW8OnK_p+MgRzv#o^58Q!|CpQTY+d4Sa?>9o=X-ePQ&!zl zRR2y(|Cp2i&&l(ml>aq2@Tsc*xVQhx#pI>eMd_)l z__@0O+soKEJo`{p^4Qt;k(2n;)&GQj|7mXjucG>fiTAItqm(Bd000DpNkl9j~N5gt0j19#YZ@%F02$P;o zWYoB5d{E?MG>7D|!Eq6pj3bYq_(uZ75*wpES>oLA7!u1(P*4($u{}o;OIFYZjj{70 zvC$4zV=1diEY!_vEVYxw?(v0IV#)v?5{qdOV5$s$X-91Ni3AurlSN`qQv{g*je>3; z!s~RROn^COlUQI5A5-Ld+IaH1pO>r6gM*ZOY_OWdG{Xegr(o=7yoP^;3jtpXv3x)^ zOCiKO3c_%sQjE!Ea|ul6MOj?3R)}?s!FExxNNH^RlLRKmYep;@#-{7B?%yg@K|Lly z`ujv8rI^Ab6KE_xfx=2AP127W{r=>lVo7P4SS%|mEvF~5^P#aBd62;1cR$Aasxp3` z`Da1pO*h|CE=s+%>JD2HLvyNWta=`asUDcQ#$S~&A3R)8`3P9B(00+tr(d8k=htY= zb+LJ@aLG07O&WV^DUB^%W*!5>%Tt+HjfTc*qx!&RFO;(|aXv?5Tpb%5W5mD`=42`1 zfPv*|X{@59q-2!=t8Z9a=EA^!ngAF@M$=g4y2i#02CT8F{stBnyOD+MYN9dF(9lq5 zz&39ITW_N=v@MH;1s$ca`c>Pv-)X?^+L5%OYA21k--`+2@kn3`?rUzI--DIzE=*!z z!D<#}pToc&>RpY^d$$0L?V)`;$)^Ug3jxeRqlFlp{LHh@LDlnzUsP1SbodYwy}b36S4G{} zO1x&RY-~mz`PlC2l3u%X6%`*leoTMoas8E;%-fZXMKnPI!+$8fqmbAMycyKiVyvS% z16OI=+uQH(G39!Wjj28OSX9e6+`Dt$Gq%kUV|dM|xF|jrXv52uS0EpguQr99G*VK< z2kSoMw^qlnh}$Rea!FFsMK;^gL*9#&_+A-t0?3pO*v?kDk#P zu*57=Sfrb!Z;tz&+f89Xi~XQQ7_$3(xhYH&bTZEZ3`qtbum`5IclqKh>>q~Y?&r<} zvvKFY`Suj-8$+@S-?ww1uekOfE^1*Pm@f8Gs|NHZuC?xG1vG;pyP99rpug3&{n}&_ zLz3W5dtgcG-|#mfz>wVe++_|}7I*o|GB=1ZeD2j8u%hgP7abrUL%K7UHfn%%X{xWz z(_&0%cLJZgHC#lUzrui-*mn!RiN6xyigZz`H{SOFWPc^+?9dBwc;5#Um;HBsTP^s{ bcfEfA%Vtu$eB;+100000NkvXXu0mjf%o|-k literal 0 HcmV?d00001 diff --git a/react-app/public/assets/icons/apple-touch-icon.png b/react-app/public/assets/icons/apple-touch-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..9b8d8d0da36f3f4834c8ebd2d1d7ba6ee36a82cf GIT binary patch literal 3846 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 IM6N<$f*L6ZVE_OC literal 0 HcmV?d00001 diff --git a/react-app/public/assets/icons/browserconfig.xml b/react-app/public/assets/icons/browserconfig.xml new file mode 100644 index 000000000..daef18b07 --- /dev/null +++ b/react-app/public/assets/icons/browserconfig.xml @@ -0,0 +1,9 @@ + + + + + + #b92b27 + + + diff --git a/react-app/public/assets/icons/favicon-16x16.png b/react-app/public/assets/icons/favicon-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..110da42ea2659e34108caa6a19b68ca009654a22 GIT binary patch literal 694 zcmV;n0!jUeP)RN?y+s#PS*DBOuD=9t@&$~-tDP#ZoH87 zUauTs`1s4+nQfe#W?4sXu&FB)pN(4E-`eZsW4g|r`o^)&V!-?%&5u8B!|>#Br2k(? z?oP)0oima6KbPZ_yI!Qj(rSj{#()!t6mtQ_`?x#fFc&xp6%j^ZA>vd%0f={KR&IuZ2vtoCdLK$^jxyFhADTh*!Vus!MEAbxBV zv5pl=M>DF{I0Diej0)-L%IiPc#8{xc-w6$R4S}ObpaRvfnETtg@Jz9e}4!bEl>;& z59lNz`{zFZL@QBoG_V>FN`w~@_WZ*CvE-~T=}o0++*SHh%gt2}(b=_h?X cU**6ibIKnlOlX*}hyVZp07*qoM6N<$f?Tjl$p8QV literal 0 HcmV?d00001 diff --git a/react-app/public/assets/icons/favicon-32x32.png b/react-app/public/assets/icons/favicon-32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..903146b7bc7719f79899f7df2e6d81e95af34abf GIT binary patch literal 1371 zcmV-h1*H0kP)^%FBIAX z5Xv8dAA;8+0Q>hmSYOG);g=DNQ>xfaFpktLIh|1>fOC^3{Si%D3s5V%B{YWZ5X)~t zAoT?UvjZ?hFm|5k7Qwi~B065IS1$ysSO1w60696o_cU((B@)vcBGkAX64hmY052mb z13`rd*8mKC%Yj3#+(xnKS^d^$44+?NAOhovSoQn|A?)A$0LwSuv#C-D zyIMD&V!!l2sX2ORg~20Yffj98Rn)vSt~70q%PhKBr!MSbNreDTW7v?O3BBg1#;i`K ze>!Or;4TDq?*jJhE+_AvU3j{CC!XxyQBKc~9YTrQ0e83=mTx(%K5*$x^@9MV(MfTv z1|)!KGl04C0iiS?u^c4&ej$>=!4ty96Tl`AfqqHu*jN->a^a2)X9wW&JWl-vB^CE<9;zcr<4Qd`}+YQf4~kA2++VuM~iupj|4@ zcXl4|zaYTH0R#T!Rq2kC>uU@!YZ`zu+?zDES^y;bs~S+Q6#LZr71g?dvpK--EhxKr znNmOi^i63X_v1#lc2xq{6zXY=W>orcAmB1)Q41j~% zfnnu6KmhmW&cgL}t$?CuRo?(lSmaDfN@M^OC1)j2F{%_`!(yOMCm>W$Fz_TL;^D+m zWIz;ZH7LqCgzIgZR0?3@iyzR`!~pO#Y!>RT1rIANLXv6{pAhFRaTOh|)lfse(D+Hw*v(zb)07=d;cPTrsPH z1If1>hO8vE*)Tl1SA|pY<9bbhC^AIM@`fnxzsr$~-o8a7wOUQ)cGLr^9LpbN)eSG! z8rS(m@@H=iAdpz?1pr8w73+R!uxq8ib6I3DzR3X@_0c^ zOx+y+9{G-zQ|4w&TMczipMPZ|0Gr?0uML*dvE#?@YddBb^;t?r1S!GW0zI^_HqCK002ovPDHLkV1m80er*5% literal 0 HcmV?d00001 diff --git a/react-app/public/assets/icons/mstile-150x150.png b/react-app/public/assets/icons/mstile-150x150.png new file mode 100644 index 0000000000000000000000000000000000000000..63ed11d6b21007676dbb19175a474ec53d2665d0 GIT binary patch literal 3656 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 \ No newline at end of file diff --git a/react-app/public/assets/images/cog.svg b/react-app/public/assets/images/cog.svg new file mode 100755 index 000000000..3e270d2b7 --- /dev/null +++ b/react-app/public/assets/images/cog.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/react-app/public/assets/images/logo-header.png b/react-app/public/assets/images/logo-header.png new file mode 100644 index 0000000000000000000000000000000000000000..8e7a2bdc45678c29aaad257d63b12e9fd4f8c454 GIT binary patch literal 4109 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 LNkvXXu0mjfOh?KC literal 0 HcmV?d00001 diff --git a/react-app/public/assets/images/logo.svg b/react-app/public/assets/images/logo.svg new file mode 100644 index 000000000..f88f9e31d --- /dev/null +++ b/react-app/public/assets/images/logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/react-app/public/favicon.ico b/react-app/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..8081c7ceaf2be08bf59010158c586170d9d2d517 GIT binary patch literal 5430 zcmc(je{54#6vvCoAI3i*G5%$U7!sA3wtMZ$fH6V9C`=eXGJb@R1%(I_{vnZtpD{6n z5Pl{DmxzBDbrB>}`90e12m8T*36WoeDLA&SD_hw{H^wM!cl_RWcVA!I+x87ee975; z@4kD^=bYPn&pmG@(+JZ`rqQEKxW<}RzhW}I!|ulN=fmjVi@x{p$cC`)5$a!)X&U+blKNvN5tg=uLvuLnuqRM;Yc*swiexsoh#XPNu{9F#c`G zQLe{yWA(Y6(;>y|-efAy11k<09(@Oo1B2@0`PtZSkqK&${ zgEY}`W@t{%?9u5rF?}Y7OL{338l*JY#P!%MVQY@oqnItpZ}?s z!r?*kwuR{A@jg2Chlf0^{q*>8n5Ir~YWf*wmsh7B5&EpHfd5@xVaj&gqsdui^spyL zB|kUoblGoO7G(MuKTfa9?pGH0@QP^b#!lM1yHWLh*2iq#`C1TdrnO-d#?Oh@XV2HK zKA{`eo{--^K&MW66Lgsktfvn#cCAc*(}qsfhrvOjMGLE?`dHVipu1J3Kgr%g?cNa8 z)pkmC8DGH~fG+dlrp(5^-QBeEvkOvv#q7MBVLtm2oD^$lJZx--_=K&Ttd=-krx(Bb zcEoKJda@S!%%@`P-##$>*u%T*mh+QjV@)Qa=Mk1?#zLk+M4tIt%}wagT{5J%!tXAE;r{@=bb%nNVxvI+C+$t?!VJ@0d@HIyMJTI{vEw0Ul ze(ha!e&qANbTL1ZneNl45t=#Ot??C0MHjjgY8%*mGisN|S6%g3;Hlx#fMNcL<87MW zZ>6moo1YD?P!fJ#Jb(4)_cc50X5n0KoDYfdPoL^iV`k&o{LPyaoqMqk92wVM#_O0l z09$(A-D+gVIlq4TA&{1T@BsUH`Bm=r#l$Z51J-U&F32+hfUP-iLo=jg7Xmy+WLq6_tWv&`wDlz#`&)Jp~iQf zZP)tu>}pIIJKuw+$&t}GQuqMd%Z>0?t%&BM&Wo^4P^Y z)c6h^f2R>X8*}q|bblAF?@;%?2>$y+cMQbN{X$)^R>vtNq_5AB|0N5U*d^T?X9{xQnJYeU{ zoZL#obI;~Pp95f1`%X3D$Mh*4^?O?IT~7HqlWguezmg?Ybq|7>qQ(@pPHbE9V?f|( z+0xo!#m@Np9PljsyxBY-UA*{U*la#8Wz2sO|48_-5t8%_!n?S$zlGe+NA%?vmxjS- zHE5O3ZarU=X}$7>;Okp(UWXJxI%G_J-@IH;%5#Rt$(WUX?6*Ux!IRd$dLP6+SmPn= z8zjm4jGjN772R{FGkXwcNv8GBcZI#@Y2m{RNF_w8(Z%^A*!bS*!}s6sh*NnURytky humW;*g7R+&|Ledvc- \ No newline at end of file diff --git a/react-app/public/icons.svg b/react-app/public/icons.svg new file mode 100644 index 000000000..e9522193d --- /dev/null +++ b/react-app/public/icons.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/react-app/src/App.scss b/react-app/src/App.scss new file mode 100644 index 000000000..cae300712 --- /dev/null +++ b/react-app/src/App.scss @@ -0,0 +1,23 @@ +@use "./styles/media" as *; + +.body-cover { + width: 100%; + z-index: 0; + position: fixed; + height: 100%; +} + +.wrapper { + position: relative; + width: 85%; + min-height: 80px; + margin: 0 auto; + font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif; + font-size: 15px; + height: 100%; + line-height: 1.3; + + @media #{$mobile-only} { + width: 100%; + } +} diff --git a/react-app/src/App.tsx b/react-app/src/App.tsx new file mode 100644 index 000000000..25291604e --- /dev/null +++ b/react-app/src/App.tsx @@ -0,0 +1,61 @@ +import { BrowserRouter, Routes, Route, Navigate, useParams } from 'react-router-dom'; +import { SettingsProvider } from './services/SettingsContext'; +import { useSettings } from './services/useSettings'; +import Header from './components/Header/Header'; +import Footer from './components/Footer/Footer'; +import Feed from './components/Feed/Feed'; +import ItemDetails from './components/ItemDetails/ItemDetails'; +import UserProfile from './components/User/User'; +import './styles/globals.scss'; +import './App.scss'; + +function FeedRoute({ feedType }: { feedType: string }) { + const { page } = useParams<{ page: string }>(); + const pageNum = page ? parseInt(page, 10) : 1; + return ; +} + +function ItemRoute() { + const { id } = useParams<{ id: string }>(); + const itemId = id ? parseInt(id, 10) : 0; + return ; +} + +function UserRoute() { + const { id } = useParams<{ id: string }>(); + return ; +} + +function AppShell() { + const { settings } = useSettings(); + + return ( +
+
+
+
+ + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + +
+
+
+ ); +} + +export default function App() { + return ( + + + + + + ); +} diff --git a/react-app/src/assets/hero.png b/react-app/src/assets/hero.png new file mode 100644 index 0000000000000000000000000000000000000000..02251f4b956c55af2d76fd0788124d7eee2b45eb GIT binary patch literal 13057 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 P00000NkvXXu0mjft=yBf literal 0 HcmV?d00001 diff --git a/react-app/src/assets/react.svg b/react-app/src/assets/react.svg new file mode 100644 index 000000000..6c87de9bb --- /dev/null +++ b/react-app/src/assets/react.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/react-app/src/assets/vite.svg b/react-app/src/assets/vite.svg new file mode 100644 index 000000000..5101b674d --- /dev/null +++ b/react-app/src/assets/vite.svg @@ -0,0 +1 @@ +Vite diff --git a/react-app/src/components/Comment/Comment.scss b/react-app/src/components/Comment/Comment.scss new file mode 100644 index 000000000..72dfb3268 --- /dev/null +++ b/react-app/src/components/Comment/Comment.scss @@ -0,0 +1,83 @@ +@use "../../styles/media" as *; +@use "../../styles/theme_variables" as *; + +.comment-tree a { + font-weight: bold; + text-decoration: none; + &:hover { + text-decoration: underline; + } +} + +.meta { + font-size: 13px; + color: #696969; + font-weight: bold; + letter-spacing: 0.5px; + margin-bottom: 8px; + a { + text-decoration: none; + + &:hover { + text-decoration: underline; + } + } + .time { + padding-left: 5px; + } +} + +@media #{$mobile-only} { + .meta { + font-size: 14px; + margin-bottom: 10px; + .time { + padding: 0; + float: right; + } + } +} + +.meta-collapse { + margin-bottom: 20px; +} + +.deleted-meta { + font-size: 12px; + font-weight: bold; + letter-spacing: 0.5px; + margin: 30px 0; + a { + text-decoration: none; + } +} + +.collapse { + font-size: 13px; + letter-spacing: 2px; + cursor: pointer; +} + +.comment-tree { + margin-left: 24px; +} + +@media #{$tablet-only} { + .comment-tree { + margin-left: 8px; + } +} + +.comment-text { + font-size: 15px; + margin-top: 0; + margin-bottom: 20px; + word-wrap: break-word; + line-height: 1.5em; +} + +.subtree { + margin-left: 0; + padding: 0; + list-style-type: none; +} diff --git a/react-app/src/components/Comment/Comment.tsx b/react-app/src/components/Comment/Comment.tsx new file mode 100644 index 000000000..26bbdaee4 --- /dev/null +++ b/react-app/src/components/Comment/Comment.tsx @@ -0,0 +1,52 @@ +import { useState } from 'react'; +import { Link } from 'react-router-dom'; +import type { Comment as CommentType } from '../../types'; +import './Comment.scss'; + +interface CommentProps { + comment: CommentType; +} + +export default function Comment({ comment }: CommentProps) { + const [collapsed, setCollapsed] = useState(false); + + if (comment.deleted) { + return ( +
+
+ [deleted] | Comment Deleted +
+
+ ); + } + + return ( +
+
+ setCollapsed(!collapsed)}> + [{collapsed ? '+' : '-'}] + {' '} + {comment.user} + {comment.time_ago} +
+
+ {!collapsed && ( +
+

+

    + {comment.comments && + comment.comments.map((sub) => ( +
  • + +
  • + ))} +
+
+ )} +
+
+ ); +} diff --git a/react-app/src/components/ErrorMessage/ErrorMessage.scss b/react-app/src/components/ErrorMessage/ErrorMessage.scss new file mode 100644 index 000000000..b8bc6fbc3 --- /dev/null +++ b/react-app/src/components/ErrorMessage/ErrorMessage.scss @@ -0,0 +1,115 @@ +@use "../../styles/media" as *; +@use "../../styles/theme_variables" as *; + +.error-section { + height: 300px; + margin: 200px; + + @media #{$mobile-only} { + height: 0; + display: block; + position: relative; + margin: 30vh 0; + } + + p { + text-align: center; + padding: 0 25px; + + &.strong { + margin-top: 25px; + font-weight: bold; + } + } + + .skull { + width: $skull-size; + height: $skull-size; + position: relative; + top: 0; + left: 0; + right: 0; + bottom: 0; + margin: auto; + + .head { + width: 100%; + height: 75%; + border-radius: 15% / 20%; + position: absolute; + top: 0; + left: 0; + &:before, &:after { + content: ""; + position: absolute; + border-radius: 50%; + width: 20%; + height: 30%; + bottom: 10%; + } + &:before { + left: 10%; + } + &:after { + right: 10%; + } + .crack { + width: 10%; + height: 10%; + position: absolute; + top: 0; + right: 25%; + transform: skew(-15deg); + + &:before { + content: ""; + position: absolute; + top: 100%; + left: calc($skull-size / 15); + border-right: calc($skull-size / 20) solid transparent; + border-left: calc($skull-size / 40) solid transparent; + } + } + } + .mouth { + width: 40%; + height: 25%; + position: absolute; + top: 75%; + left: 30%; + border-radius: 0 0 calc($skull-size / 10) calc($skull-size / 10); + &:before { + content: ""; + position: absolute; + width: 15%; + height: 50%; + border-radius: 50% / 30%; + left: 42.5%; + top: -25%; + } + .teeth { + position: absolute; + bottom: 0; + left: 45%; + width: 10%; + height: 50%; + margin-bottom: -5%; + border-radius: 50% / 20%; + + &:before, &:after { + content: ""; + position: absolute; + width: 100%; + height: 100%; + border-radius: 50% / 20%; + } + &:before { + left: -250%; + } + &:after { + right: -250%; + } + } + } + } +} diff --git a/react-app/src/components/ErrorMessage/ErrorMessage.tsx b/react-app/src/components/ErrorMessage/ErrorMessage.tsx new file mode 100644 index 000000000..02e297f35 --- /dev/null +++ b/react-app/src/components/ErrorMessage/ErrorMessage.tsx @@ -0,0 +1,25 @@ +import './ErrorMessage.scss'; + +interface ErrorMessageProps { + message: string; +} + +export default function ErrorMessage({ message }: ErrorMessageProps) { + return ( +
+
+
+
+
+
+
+
+
+

{message}

+

+ If you are offline viewing, you'll need to visit this page with a network + connection first before it can work offline. +

+
+ ); +} diff --git a/react-app/src/components/Feed/Feed.scss b/react-app/src/components/Feed/Feed.scss new file mode 100644 index 000000000..abf42d39b --- /dev/null +++ b/react-app/src/components/Feed/Feed.scss @@ -0,0 +1,108 @@ +@use "../../styles/media" as *; +@use "../../styles/theme_variables" as *; + +a { + text-decoration: none; + font-weight: bold; + + &:hover { + text-decoration: underline; + }; +} + +ol { + padding: 0 40px; + margin: 0; + + @media #{$mobile-only} { + box-sizing: border-box; + list-style: none; + padding: 0 10px; + } + + li { + position: relative; + -webkit-transition: background-color .2s ease; + transition: background-color .2s ease; + } +} + +.list-margin { + @media #{$mobile-only} { + margin-top: 55px; + } +} + +.main-content { + position: relative; + width: 100%; + min-height: 100vh; + -webkit-transition: opacity .2s ease; + transition: opacity .2s ease; + box-sizing: border-box; + padding: 8px 0; + z-index: 0; +} + +.post { + padding: 10px 0 10px 5px; + transition: background-color 0.2s ease; + border-bottom: 1px solid #CECECB; + + .itemNum { + color: #696969; + position: absolute; + width: 30px; + text-align: right; + left: 0; + top: 4px; + } +} + +.item-block { + display: block; +} + + +.nav { + padding: 10px 40px; + margin-top: 10px; + font-size: 17px; + + a { + @media #{$mobile-only} { + text-decoration: none; + } + } + + @media #{$mobile-only} { + margin: 20px 0; + text-align: center; + padding: 10px 80px; + height: 20px; + } + + .prev { + padding-right: 20px; + + @media #{$mobile-only} { + float: left; + padding-right: 0; + } + } + + .more { + @media #{$mobile-only} { + float: right; + } + } +} + +.job-header { + font-size: 15px; + padding: 0 40px 10px; + + @media #{$mobile-only} { + padding: 60px 15px 25px 15px; + } +} diff --git a/react-app/src/components/Feed/Feed.tsx b/react-app/src/components/Feed/Feed.tsx new file mode 100644 index 000000000..3263484bb --- /dev/null +++ b/react-app/src/components/Feed/Feed.tsx @@ -0,0 +1,80 @@ +import { useEffect, useState } from 'react'; +import { Link } from 'react-router-dom'; +import { fetchFeed } from '../../services/hackerNewsApi'; +import Loader from '../Loader/Loader'; +import ErrorMessage from '../ErrorMessage/ErrorMessage'; +import Item from '../Item/Item'; +import type { Story } from '../../types'; +import './Feed.scss'; + +interface FeedProps { + feedType: string; + pageNum: number; +} + +export default function Feed({ feedType, pageNum }: FeedProps) { + const [items, setItems] = useState(null); + const [errorMessage, setErrorMessage] = useState(''); + + useEffect(() => { + let cancelled = false; + fetchFeed(feedType, pageNum) + .then((data) => { + if (!cancelled) { + setItems(data); + window.scrollTo(0, 0); + } + }) + .catch(() => { + if (!cancelled) { + setErrorMessage(`Could not load ${feedType} stories.`); + } + }); + return () => { cancelled = true; }; + }, [feedType, pageNum]); + + const listStart = (pageNum - 1) * 30 + 1; + + return ( +
+ {!items && !errorMessage && } + {!items && errorMessage && } + + {items && ( +
+ {feedType === 'jobs' && ( +

+ These are jobs at startups that were funded by Y Combinator. You can also + get a job at a YC startup through{' '} + Triplebyte. +

+ )} + {feedType !== 'new' && ( +
    + {items.map((item) => ( +
  1. + +
  2. + ))} +
+ )} +
+ {listStart !== 1 && ( + + ‹ Prev + + )} + {items.length === 30 && ( + + More › + + )} +
+
+ )} +
+ ); +} diff --git a/react-app/src/components/Footer/Footer.scss b/react-app/src/components/Footer/Footer.scss new file mode 100644 index 000000000..a00f67538 --- /dev/null +++ b/react-app/src/components/Footer/Footer.scss @@ -0,0 +1,23 @@ +@use "../../styles/media" as *; +@use "../../styles/theme_variables" as *; + +#footer { + position: relative; + padding: 10px; + height: 60px; + letter-spacing: 0.7px; + text-align: center; + + a { + font-weight: bold; + text-decoration: none; + + &:hover { + text-decoration: underline; + } + } + + @media #{$mobile-only} { + display: none; + } +} diff --git a/react-app/src/components/Footer/Footer.tsx b/react-app/src/components/Footer/Footer.tsx new file mode 100644 index 000000000..1c2e5cdbd --- /dev/null +++ b/react-app/src/components/Footer/Footer.tsx @@ -0,0 +1,14 @@ +import './Footer.scss'; + +export default function Footer() { + return ( + + ); +} diff --git a/react-app/src/components/Header/Header.scss b/react-app/src/components/Header/Header.scss new file mode 100644 index 000000000..6d9dde074 --- /dev/null +++ b/react-app/src/components/Header/Header.scss @@ -0,0 +1,149 @@ +@use "../../styles/media" as *; +@use "../../styles/theme_variables" as *; + +#header { + color: #fff; + padding: 6px 0; + line-height: 18px; + vertical-align: middle; + position: relative; + z-index: 1; + width: 100%; + + @media #{$mobile-only} { + height: 50px; + position: fixed; + top: 0; + } + + a { + display: inline; + } +} + +.home-link { + width: 50px; + height: 66px; +} + +.logo-inner { + width: 32px; + position: absolute; + left: 17px; + top: 18px; + z-index: -1; + height: 32px; + border-radius: 50%; + + @media #{$mobile-only} { + left: 16px; + top: 12px; + } +} + +.logo { + width: 50px; + padding: 3px 8px 0; + + @media #{$mobile-only} { + width: 45px; + padding: 0 0 0 10px; + } +} + +h1 { + font-weight: normal; + display: inline-block; + vertical-align:middle; + margin: 0; + font-size: 16px; + + a { + color: #fff; + text-decoration: none; + } +} + +.name { + margin-right: 30px; + margin-bottom: 2px; + + @media #{$mobile-only} { + display: none; + } +} + +.header-text { + position: absolute; + width: inherit; + height: 20px; + left: 10px; + top: 27px; + z-index: -1; + + @media #{$mobile-only} { + top: 22px; + } +} + +.left { + position: absolute; + left: 60px; + font-size: 16px; + + @media #{$mobile-only} { + width: 100%; + left: 0; + } +} + +.header-nav { + display: inline-block; + margin-left: 20px; + + @media #{$mobile-only} { + margin-left: 60px; + } + + a { + color: hsla(0,0%,100%,.9); + text-decoration: none; + margin: 0 5px; + letter-spacing: 1.8px; + + &:hover { + color: #fff; + } + } + + .active { + color: #fff; + } +} + +.info { + position: absolute; + top: 0; + right: 20px; + height: 100%; + + @media #{$mobile-only} { + right: 10px; + } + + img { + opacity: 0.8; + width: 25px; + margin-top: 21.5px; + display: block; + + &:hover { + opacity: 1; + cursor: pointer; + } + + @media #{$mobile-only} { + margin-top: 15px; + } + } +} diff --git a/react-app/src/components/Header/Header.tsx b/react-app/src/components/Header/Header.tsx new file mode 100644 index 000000000..e2135bbd9 --- /dev/null +++ b/react-app/src/components/Header/Header.tsx @@ -0,0 +1,51 @@ +import { NavLink } from 'react-router-dom'; +import { useSettings } from '../../services/useSettings'; +import Settings from '../Settings/Settings'; +import './Header.scss'; + +export default function Header() { + const { settings, toggleSettings } = useSettings(); + + const scrollTop = () => window.scrollTo(0, 0); + + return ( +
+ + {settings.showSettings && } +
+ ); +} diff --git a/react-app/src/components/Item/Item.scss b/react-app/src/components/Item/Item.scss new file mode 100644 index 000000000..01024b9ba --- /dev/null +++ b/react-app/src/components/Item/Item.scss @@ -0,0 +1,68 @@ +@use "../../styles/media" as *; +@use "../../styles/theme_variables" as *; + +p { + margin: 2px 0; + + @media #{$mobile-only} { + margin-bottom: 5px; + margin-top: 0; + } + } + + a { + cursor: pointer; + text-decoration: none; + } + + .title { + font-size: 16px; + font-family: Verdana, Geneva, sans-serif; + } + + .subtext-laptop { + font-size: 12px; + font-weight: bold; + letter-spacing: 0.5px; + + a { + &:hover { + text-decoration: underline; + }; + } + @media #{$mobile-only} { + display: none; + } + } + + .subtext-palm { + font-size: 13px; + font-weight: bold; + letter-spacing: 0.5px; + + a { + &:hover { + text-decoration: underline; + }; + } + + .details { + margin-top: 5px; + + .right { + float: right; + } + } + @media #{$laptop-only} { + display: none; + } + } + + .domain { + color: #696969; + letter-spacing: 0.5px; + } + + .item-details { + padding: 10px; + } diff --git a/react-app/src/components/Item/Item.tsx b/react-app/src/components/Item/Item.tsx new file mode 100644 index 000000000..5db210bdf --- /dev/null +++ b/react-app/src/components/Item/Item.tsx @@ -0,0 +1,79 @@ +import { Link } from 'react-router-dom'; +import { useSettings } from '../../services/useSettings'; +import { commentLabel } from '../../utils/commentLabel'; +import type { Story } from '../../types'; +import './Item.scss'; + +interface ItemProps { + item: Story; +} + +export default function Item({ item }: ItemProps) { + const { settings } = useSettings(); + const hasUrl = item.url && item.url.indexOf('http') === 0; + + return ( +
+ {hasUrl ? ( +

+ + {item.title} + + {item.domain && ({item.domain})} +

+ ) : ( +

+ + {item.title} + +

+ )} +
+ {item.type !== 'job' && ( +
+ + {item.user} + + {item.points} ★ +
+ )} +
+ {item.time_ago}{' '} + {item.type !== 'job' && ( + + {' '} + • {commentLabel(item.comments_count)} + + )} +
+
+
+ {item.type !== 'job' && ( + + {item.points} points by{' '} + {item.user} + + )} + + {item.time_ago} + {item.type !== 'job' && ( + + {' '} + | {commentLabel(item.comments_count)} + + )} + +
+
+ ); +} diff --git a/react-app/src/components/ItemDetails/ItemDetails.scss b/react-app/src/components/ItemDetails/ItemDetails.scss new file mode 100644 index 000000000..34f891920 --- /dev/null +++ b/react-app/src/components/ItemDetails/ItemDetails.scss @@ -0,0 +1,151 @@ +@use "../../styles/media" as *; +@use "../../styles/theme_variables" as *; + +.main-content { + position: relative; + width: 100%; + min-height: 100vh; + -webkit-transition: opacity .2s ease; + transition: opacity .2s ease; + box-sizing: border-box; + padding: 8px 0; + z-index: 0; +} + +.item { + box-sizing: border-box; + padding: 10px 40px 0 40px; + z-index: 0; +} + +@media #{$tablet-only} { + .item { + padding: 10px 20px 0 40px; + } +} + +@media #{$mobile-only} { + .item { + box-sizing: border-box; + padding: 110px 15px 0 15px; + } +} + +.head-margin { + margin-bottom: 15px; +} + +p { + margin: 2px 0; +} + +.subject { + word-wrap: break-word; + margin-top: 20px; +} + +a { + cursor: pointer; + text-decoration: none; +} + +@media #{$mobile-only} { + .laptop { + display: none; + } +} + +@media #{$laptop-only} { + .mobile { + display: none; + } +} + +.title { + font-size: 16px; + font-family: Verdana, Geneva, sans-serif; +} + +.title-block { + text-align: center; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + margin: 0 75px; +} + +@media #{$mobile-only} { + .title { + font-size: 15px; + } + .back-button { + position: absolute; + top: 52%; + width: 0.6rem; + height: 0.6rem; + background: transparent; + box-shadow: 0 0 0 lightgray; + transition: all 200ms ease; + left: 4%; + transform: translate3d(0, -50%, 0) rotate(-135deg); + } +} + +.subtext { + font-size: 12px; + font-weight: bold; + letter-spacing: 0.5px; +} + +.domain { + letter-spacing: 0.5px; +} + +.subtext a { + &:hover { + text-decoration: underline; + } +} + +.item-details { + padding: 10px; +} + +.item-header { + padding-bottom: 10px; +} + +@media #{$mobile-only} { + .item-header { + padding: 10px 0 10px 0; + position: fixed; + width: 100%; + left: 0; + top: 62px; + } +} + +.pollResults { + margin-bottom: 1em; +} + +.pollContent { + * { + padding-bottom: 0; + margin-bottom: -1em; + margin-top: 1em; + } + .pollBar { + height: 10px; + margin-bottom: 1em; + } +} + +ul { + list-style-type: none; + padding: 10px 0; +} + +li { + display: list-item; +} diff --git a/react-app/src/components/ItemDetails/ItemDetails.tsx b/react-app/src/components/ItemDetails/ItemDetails.tsx new file mode 100644 index 000000000..a398b6421 --- /dev/null +++ b/react-app/src/components/ItemDetails/ItemDetails.tsx @@ -0,0 +1,141 @@ +import { useEffect, useState } from 'react'; +import { Link, useNavigate } from 'react-router-dom'; +import { fetchItemContent } from '../../services/hackerNewsApi'; +import { useSettings } from '../../services/useSettings'; +import { commentLabel } from '../../utils/commentLabel'; +import Loader from '../Loader/Loader'; +import ErrorMessage from '../ErrorMessage/ErrorMessage'; +import Comment from '../Comment/Comment'; +import type { Story } from '../../types'; +import './ItemDetails.scss'; + +interface ItemDetailsProps { + itemId: number; +} + +export default function ItemDetails({ itemId }: ItemDetailsProps) { + const navigate = useNavigate(); + const { settings } = useSettings(); + const [item, setItem] = useState(null); + const [errorMessage, setErrorMessage] = useState(''); + + useEffect(() => { + let cancelled = false; + fetchItemContent(itemId) + .then((data) => { if (!cancelled) setItem(data); }) + .catch(() => { if (!cancelled) setErrorMessage('Could not load item comments.'); }); + window.scrollTo(0, 0); + return () => { cancelled = true; }; + }, [itemId]); + + const goBack = () => navigate(-1); + const hasUrl = item ? item.url && item.url.indexOf('http') === 0 : false; + + return ( +
+ {!item && !errorMessage && } + {!item && errorMessage && } + + {item && ( +
+
+

+ + {hasUrl ? ( + + {item.title} + + ) : ( + + {item.title} + + )} +

+
+
0 || item.type === 'job' ? ' item-header' : '' + }${item.content ? ' head-margin' : ''}`} + > + {hasUrl ? ( +

+ + {item.title} + + {item.domain && ({item.domain})} +

+ ) : ( +

+ + {item.title} + +

+ )} +
+ {item.type !== 'job' && ( + + {item.points} points by{' '} + {item.user} + + )} + + {item.time_ago} + {item.type !== 'job' && ( + + {' '} + |{' '} + + {commentLabel(item.comments_count)} + + + )} + +
+
+ {item.type === 'poll' && item.poll && ( +
+ {item.poll.map((pollResult, idx) => ( +
+
+
{pollResult.points} points
+
+
+ ))} +
+ )} + {item.content && ( +

+ )} +

    + {item.comments && + item.comments.map((comment) => ( +
  • + +
  • + ))} +
+
+ )} +
+ ); +} diff --git a/react-app/src/components/Loader/Loader.scss b/react-app/src/components/Loader/Loader.scss new file mode 100644 index 000000000..16bf98ecd --- /dev/null +++ b/react-app/src/components/Loader/Loader.scss @@ -0,0 +1,109 @@ +@use "../../styles/media" as *; +@use "../../styles/theme_variables" as *; + +.loader { + -webkit-animation: load1 1s infinite ease-in-out; + animation: load1 1s infinite ease-in-out; + width: 1em; + height: 4em; + &:before, &:after { + -webkit-animation: load1 1s infinite ease-in-out; + animation: load1 1s infinite ease-in-out; + width: 1em; + height: 4em; + } + &:before, &:after { + position: absolute; + top: 0; + content: ''; + } + &:before { + left: -1.5em; + -webkit-animation-delay: -0.32s; + animation-delay: -0.32s; + } +} + +.loading-section { + height: 70px; + margin: 40px 0 40px 40px; + + @media #{$mobile-only} { + display: block; + position: relative; + margin: 45vh 0; + } +} + +.loader { + text-indent: -9999em; + margin: 20px 20px; + position: relative; + font-size: 11px; + -webkit-transform: translateZ(0); + -ms-transform: translateZ(0); + transform: translateZ(0); + -webkit-animation-delay: -0.16s; + animation-delay: -0.16s; + &:after { + left: 1.5em; + } + + @media #{$mobile-only} { + margin: 20px auto; + } +} + +@-webkit-keyframes load1 { + 0%, + 80%, + 100% { + box-shadow: 0 0; + height: 2em; + } + 40% { + box-shadow: 0 -2em; + height: 3em; + } +} + +@keyframes load1 { + 0%, + 80%, + 100% { + box-shadow: 0 0; + height: 2em; + } + 40% { + box-shadow: 0 -2em; + height: 3em; + } +} + +@media #{$mobile-only} { + @-webkit-keyframes load1 { + 0%, + 80%, + 100% { + box-shadow: 0 0; + height: 4em; + } + 40% { + box-shadow: 0 -2em; + height: 5em; + } + } + + @keyframes load1 { + 0%, + 80%, + 100% { + box-shadow: 0 0; + height: 3em; + } + 40% { + box-shadow: 0 -2em; + height: 4em; + } + } +} diff --git a/react-app/src/components/Loader/Loader.tsx b/react-app/src/components/Loader/Loader.tsx new file mode 100644 index 000000000..05ca5a18d --- /dev/null +++ b/react-app/src/components/Loader/Loader.tsx @@ -0,0 +1,9 @@ +import './Loader.scss'; + +export default function Loader() { + return ( +
+
Loading...
+
+ ); +} diff --git a/react-app/src/components/Settings/Settings.scss b/react-app/src/components/Settings/Settings.scss new file mode 100644 index 000000000..56f491574 --- /dev/null +++ b/react-app/src/components/Settings/Settings.scss @@ -0,0 +1,74 @@ +@use "../../styles/media" as *; +@use "../../styles/theme_variables" as *; + +.overlay { + position: fixed; + top: 0; + bottom: 0; + left: 0; + right: 0; + background: rgba(0, 0, 0, 0.7); + opacity: 1; + z-index: 1; +} + +.popup { + margin: 70px auto; + padding: 30px; + border-radius: 5px; + width: 30%; + position: relative; + h1 { + margin-top: 0; + margin-bottom: 0px; + color: #fff; + text-align: center; + letter-spacing: 1px; + } + h2 { + padding-top: 10px; + } + hr { + width: 40%; + margin-bottom: 20px; + } + .close { + position: absolute; + top: 12px; + right: 20px; + font-size: 30px; + font-weight: bold; + text-decoration: none; + color: rgba(255,255,255,0.8); + &:hover { + color: #fff; + cursor: pointer; + } + } + .content { + max-height: 30%; + color: #fff; + letter-spacing: 1px; + overflow: auto; + } + input[type=number] { + display: block; + width: 80%; + height: 20px; + margin-bottom: 15px; + border-radius: 5px; + padding: 2px; + } +} + +.control-section { + margin-bottom: 15px; + padding-bottom: 15px; + border-bottom: 1px solid white; +} + +@media screen and (max-width: 700px) { + .box, .popup { + width: 70%; + } +} diff --git a/react-app/src/components/Settings/Settings.tsx b/react-app/src/components/Settings/Settings.tsx new file mode 100644 index 000000000..752b76cc9 --- /dev/null +++ b/react-app/src/components/Settings/Settings.tsx @@ -0,0 +1,99 @@ +import { useSettings } from '../../services/useSettings'; +import './Settings.scss'; + +export default function Settings() { + const { settings, toggleOpenLinksInNewTab, setTheme, setFont, setSpacing } = useSettings(); + + const closeSettings = useSettings().toggleSettings; + + return ( +
+
+

Settings

+
+ + × + +
+
+

Links

+ {' '} + Open links in a new tab +
+
+
+

Select a theme

+
+ +
+
+ +
+
+ +
+
+
+

Change Font

+
+ +
+
+ +
+
+
+
+
+
+ ); +} diff --git a/react-app/src/components/User/User.scss b/react-app/src/components/User/User.scss new file mode 100644 index 000000000..b40bc15cc --- /dev/null +++ b/react-app/src/components/User/User.scss @@ -0,0 +1,89 @@ +@use "../../styles/media" as *; +@use "../../styles/theme_variables" as *; + +.profile pre { + white-space: pre-wrap; +} + +.profile { + padding: 30px; +} + +@media #{$mobile-only} { + .profile { + padding: 110px 15px 0 15px; + } + .title-block { + font-size: 15px; + text-align: center; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + margin: 0 75px; + } + .back-button { + position: absolute; + top: 52%; + width: 0.6rem; + height: 0.6rem; + background: transparent; + box-shadow: 0 0 0 lightgray; + transition: all 200ms ease; + left: 4%; + transform: translate3d(0, -50%, 0) rotate(-135deg); + } + .item-header { + padding-bottom: 10px; + background-color: #fff; + padding: 10px 0 10px 0; + position: fixed; + width: 100%; + left: 0; + top: 62px; + height: 20px; + } +} + +@media #{$laptop-only} { + .mobile { + display: none; + } +} + +.main-details { + .name { + font-weight: bold; + font-size: 32px; + letter-spacing: 2px; + } + .age { + font-weight: bold; + color: #696969; + padding-bottom: 0; + } + .right { + float: right; + font-weight: bold; + font-size: 32px; + letter-spacing: 2px; + } +} + +@media #{$mobile-only} { + .main-details { + margin-top: 20px; + .name { + font-size: 18px; + } + } +} + +@media #{$mobile-only} { + .main-details .right { + font-size: 18px; + } +} + +.other-details { + word-wrap: break-word; +} diff --git a/react-app/src/components/User/User.tsx b/react-app/src/components/User/User.tsx new file mode 100644 index 000000000..fcd0474b3 --- /dev/null +++ b/react-app/src/components/User/User.tsx @@ -0,0 +1,55 @@ +import { useEffect, useState } from 'react'; +import { useNavigate } from 'react-router-dom'; +import { fetchUser } from '../../services/hackerNewsApi'; +import Loader from '../Loader/Loader'; +import ErrorMessage from '../ErrorMessage/ErrorMessage'; +import type { User as UserType } from '../../types'; +import './User.scss'; + +interface UserProfileProps { + userId: string; +} + +export default function UserProfile({ userId }: UserProfileProps) { + const navigate = useNavigate(); + const [user, setUser] = useState(null); + const [errorMessage, setErrorMessage] = useState(''); + + useEffect(() => { + let cancelled = false; + fetchUser(userId) + .then((data) => { if (!cancelled) setUser(data); }) + .catch(() => { if (!cancelled) setErrorMessage(`Could not load user ${userId}.`); }); + return () => { cancelled = true; }; + }, [userId]); + + const goBack = () => navigate(-1); + + return ( + <> + {!user && !errorMessage && } + {!user && errorMessage && } + + {user && ( +
+
+

+ + Profile: {user.id} +

+
+
+ {user.id} + {user.karma} ★ +

Created {user.created}

+
+ {user.about && ( +
+

+

+ )} +
+ )} + + ); +} diff --git a/react-app/src/main.tsx b/react-app/src/main.tsx new file mode 100644 index 000000000..4aff0256e --- /dev/null +++ b/react-app/src/main.tsx @@ -0,0 +1,9 @@ +import { StrictMode } from 'react' +import { createRoot } from 'react-dom/client' +import App from './App.tsx' + +createRoot(document.getElementById('root')!).render( + + + , +) diff --git a/react-app/src/services/SettingsContext.tsx b/react-app/src/services/SettingsContext.tsx new file mode 100644 index 000000000..cd564a4e8 --- /dev/null +++ b/react-app/src/services/SettingsContext.tsx @@ -0,0 +1,76 @@ +import { useState, useEffect, useCallback, type ReactNode } from 'react'; +import type { Settings } from '../types'; +import { SettingsContext } from './settingsContextDef'; + +function getInitialSettings(): Settings { + return { + showSettings: false, + openLinkInNewTab: localStorage.getItem('openLinkInNewTab') + ? JSON.parse(localStorage.getItem('openLinkInNewTab')!) + : false, + theme: 'default', + titleFontSize: localStorage.getItem('titleFontSize') ?? '16', + listSpacing: localStorage.getItem('listSpacing') ?? '0', + }; +} + +function getInitialTheme(): string { + const saved = localStorage.getItem('theme'); + if (saved) return saved; + return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'night' : 'default'; +} + +export function SettingsProvider({ children }: { children: ReactNode }) { + const [settings, setSettings] = useState(() => { + const s = getInitialSettings(); + s.theme = getInitialTheme(); + return s; + }); + + const handleColorSchemeChange = useCallback((e: MediaQueryListEvent) => { + const theme = e.matches ? 'night' : 'default'; + setSettings(prev => ({ ...prev, theme })); + localStorage.setItem('theme', theme); + }, []); + + useEffect(() => { + const mql = window.matchMedia('(prefers-color-scheme: dark)'); + mql.addEventListener('change', handleColorSchemeChange); + return () => mql.removeEventListener('change', handleColorSchemeChange); + }, [handleColorSchemeChange]); + + const toggleSettings = useCallback(() => { + setSettings(prev => ({ ...prev, showSettings: !prev.showSettings })); + }, []); + + const toggleOpenLinksInNewTab = useCallback(() => { + setSettings(prev => { + const next = !prev.openLinkInNewTab; + localStorage.setItem('openLinkInNewTab', JSON.stringify(next)); + return { ...prev, openLinkInNewTab: next }; + }); + }, []); + + const setTheme = useCallback((theme: string) => { + setSettings(prev => ({ ...prev, theme })); + localStorage.setItem('theme', theme); + }, []); + + const setFont = useCallback((fontSize: string) => { + setSettings(prev => ({ ...prev, titleFontSize: fontSize })); + localStorage.setItem('titleFontSize', fontSize); + }, []); + + const setSpacing = useCallback((listSpace: string) => { + setSettings(prev => ({ ...prev, listSpacing: listSpace })); + localStorage.setItem('listSpacing', listSpace); + }, []); + + return ( + + {children} + + ); +} diff --git a/react-app/src/services/hackerNewsApi.ts b/react-app/src/services/hackerNewsApi.ts new file mode 100644 index 000000000..12652b786 --- /dev/null +++ b/react-app/src/services/hackerNewsApi.ts @@ -0,0 +1,41 @@ +import type { Story, User, PollResult } from '../types'; + +const BASE_URL = 'https://node-hnapi.herokuapp.com'; + +async function fetchJson(url: string): Promise { + const res = await fetch(url); + if (!res.ok) { + throw new Error(`HTTP error: ${res.status}`); + } + return res.json(); +} + +export async function fetchFeed(feedType: string, page: number): Promise { + return fetchJson(`${BASE_URL}/${feedType}?page=${page}`); +} + +export async function fetchItemContent(id: number): Promise { + const story = await fetchJson(`${BASE_URL}/item/${id}`); + if (story.type === 'poll' && story.poll) { + const numberOfPollOptions = story.poll.length; + story.poll_votes_count = 0; + const pollPromises = []; + for (let i = 1; i <= numberOfPollOptions; i++) { + pollPromises.push(fetchPollContent(story.id + i)); + } + const pollResults = await Promise.all(pollPromises); + pollResults.forEach((result, idx) => { + story.poll[idx] = result; + story.poll_votes_count += result.points; + }); + } + return story; +} + +export async function fetchPollContent(id: number): Promise { + return fetchJson(`${BASE_URL}/item/${id}`); +} + +export async function fetchUser(id: string): Promise { + return fetchJson(`${BASE_URL}/user/${id}`); +} diff --git a/react-app/src/services/settingsContextDef.ts b/react-app/src/services/settingsContextDef.ts new file mode 100644 index 000000000..7f8249758 --- /dev/null +++ b/react-app/src/services/settingsContextDef.ts @@ -0,0 +1,13 @@ +import { createContext } from 'react'; +import type { Settings } from '../types'; + +export interface SettingsContextValue { + settings: Settings; + toggleSettings: () => void; + toggleOpenLinksInNewTab: () => void; + setTheme: (theme: string) => void; + setFont: (fontSize: string) => void; + setSpacing: (listSpace: string) => void; +} + +export const SettingsContext = createContext(null); diff --git a/react-app/src/services/useSettings.ts b/react-app/src/services/useSettings.ts new file mode 100644 index 000000000..d0be7a7a2 --- /dev/null +++ b/react-app/src/services/useSettings.ts @@ -0,0 +1,9 @@ +import { useContext } from 'react'; +import { SettingsContext } from './settingsContextDef'; +import type { SettingsContextValue } from './settingsContextDef'; + +export function useSettings(): SettingsContextValue { + const ctx = useContext(SettingsContext); + if (!ctx) throw new Error('useSettings must be used within SettingsProvider'); + return ctx; +} diff --git a/react-app/src/styles/_media.scss b/react-app/src/styles/_media.scss new file mode 100644 index 000000000..b04b71a92 --- /dev/null +++ b/react-app/src/styles/_media.scss @@ -0,0 +1,3 @@ +$mobile-only: "only screen and (max-width : 768px)"; +$laptop-only: "only screen and (min-width : 769px)"; +$tablet-only: "only screen and (max-width : 1024px)"; diff --git a/react-app/src/styles/_theme_variables.scss b/react-app/src/styles/_theme_variables.scss new file mode 100644 index 000000000..32759093e --- /dev/null +++ b/react-app/src/styles/_theme_variables.scss @@ -0,0 +1,29 @@ +$skull-size: 200px; + +// Day theme colors +$theme-day-body-background-color: #fff; +$theme-day-wrapper-background-color: #f5f5f5; +$theme-day-wrapper-mobile-background-color: #fff; +$theme-day-text-color: #000; +$theme-day-subtext-color: #696969; +$theme-day-secondary-color: #b92b27; +$theme-day-header-background-color: $theme-day-secondary-color; +$theme-day-logo-inner: #fff; +$theme-day-border: 2px solid #b92b27; + +// Night theme colors +$theme-night-body-background-color: #37474F; +$theme-night-wrapper-background-color: #263238; +$theme-night-wrapper-mobile-background-color: $theme-night-wrapper-background-color; +$theme-night-text-color: rgba(255, 255, 255, 0.7); +$theme-night-subtext-color: #999; +$theme-night-secondary-color: #00c0ff; +$theme-night-header-background-color: #263238; +$theme-night-logo-inner: $theme-night-header-background-color; +$theme-night-border: 2px solid #00c0ff; + +// Black theme colors +$theme-amoledblack-body-background-color: #000; +$theme-amoledblack-text-color: rgba(255, 255, 255, 0.75); +$theme-amoledblack-subtext-color: rgba(255, 255, 255, 0.5); +$theme-amoledblack-secondary-color: rgba(255, 255, 255, 0.6); diff --git a/react-app/src/styles/_themes.scss b/react-app/src/styles/_themes.scss new file mode 100644 index 000000000..bc6dc2f6f --- /dev/null +++ b/react-app/src/styles/_themes.scss @@ -0,0 +1,234 @@ +@use "sass:color"; +@use "media" as *; +@use "theme_variables" as *; + +@mixin theme( + $name, + $body-background-color, + $wrapper-background-color, + $wrapper-mobile-background-color, + $wrapper-color, + $item-a-color, + $item-a-visited-color, + $header-background-color, + $subtext-color, + $secondary-link-color, + $logo-inner-color, + $border +) { + .#{$name} { + .body-cover { + background: $body-background-color; + + @media #{$mobile-only} { + background: $wrapper-mobile-background-color; + } + } + + .wrapper { + background: $wrapper-background-color; + color: $wrapper-color; + + @media #{$mobile-only} { + background: $wrapper-mobile-background-color; + } + + a { + color: $item-a-color; + + &:visited { + color: $item-a-visited-color; + } + } + + #header { + background: $header-background-color; + border-bottom: $border; + } + + .logo-inner { + background: $logo-inner-color; + } + + .nav { + a { + color: $secondary-link-color; + + @media #{$mobile-only} { + color: $secondary-link-color; + } + } + } + + #footer { + border-top: $border; + + a { + color: $secondary-link-color; + } + } + + .subtext, .subtext-palm, .subtext-laptop, .domain, .meta, .deleted-meta{ + color: $subtext-color; + + a { + color: $secondary-link-color; + } + } + + .popup { + background: $header-background-color; + } + + .item-header { + border-bottom: $border; + + @media #{$mobile-only} { + background: $wrapper-mobile-background-color; + } + } + + .pollContent { + .pollBar { + background: $secondary-link-color; + } + } + + .loader { + color: $secondary-link-color; + background: $secondary-link-color; + + &:before, &:after { + background: $secondary-link-color; + } + } + + .job-header { + @media #{$mobile-only} { + border-bottom: $border; + } + } + + .back-button { + @media #{$mobile-only} { + border-top: .3rem solid $secondary-link-color; + border-right: .3rem solid $secondary-link-color; + } + } + + .error-section { + .skull { + .head { + background-color: $secondary-link-color; + + &:before, &:after { + background-color: $wrapper-background-color; + + @media #{$mobile-only} { + background-color: $wrapper-mobile-background-color; + } + } + + .crack { + background-color: $wrapper-background-color; + + @media #{$mobile-only} { + background-color: $wrapper-mobile-background-color; + } + + &:before { + border-top: calc($skull-size / 8) solid $wrapper-background-color; + + @media #{$mobile-only} { + border-top: calc($skull-size / 8) solid $wrapper-mobile-background-color; + } + } + } + } + + .mouth { + background-color: $secondary-link-color; + + &:before { + background-color: $wrapper-background-color; + + @media #{$mobile-only} { + background-color: $wrapper-mobile-background-color; + } + } + } + + .teeth { + background-color: $wrapper-background-color; + + @media #{$mobile-only} { + background-color: $wrapper-mobile-background-color; + } + + &:before, &:after { + background-color: $wrapper-background-color; + + @media #{$mobile-only} { + background-color: $wrapper-mobile-background-color; + } + } + } + } + } + + .main-details { + .name { + color: $secondary-link-color; + } + .right { + color: $secondary-link-color; + } + } + } + } +} + +@include theme( + default, + $theme-day-body-background-color, + $theme-day-wrapper-background-color, + $theme-day-wrapper-mobile-background-color, + $theme-day-text-color, + $theme-day-text-color, + $theme-day-subtext-color, + $theme-day-header-background-color, + $theme-day-subtext-color, + $theme-day-secondary-color, + $theme-day-logo-inner, + $theme-day-border +); + +@include theme( + night, + $theme-night-body-background-color, + $theme-night-wrapper-background-color, + $theme-night-wrapper-mobile-background-color, + $theme-night-text-color, + $theme-night-text-color, + $theme-night-subtext-color, + $theme-night-header-background-color, + $theme-night-subtext-color, + $theme-night-secondary-color, + $theme-night-logo-inner, + $theme-night-border +); + +@include theme( + amoledblack, + $theme-amoledblack-body-background-color, + $theme-amoledblack-body-background-color, + $theme-amoledblack-body-background-color, + $theme-amoledblack-text-color, + $theme-amoledblack-text-color, + color.adjust($theme-amoledblack-text-color, $lightness: -33%), + $theme-amoledblack-body-background-color, + $theme-amoledblack-subtext-color, + $theme-amoledblack-secondary-color, + $theme-amoledblack-body-background-color, + $theme-amoledblack-secondary-color +); diff --git a/react-app/src/styles/globals.scss b/react-app/src/styles/globals.scss new file mode 100644 index 000000000..6e9fd40de --- /dev/null +++ b/react-app/src/styles/globals.scss @@ -0,0 +1,16 @@ +@use "themes"; + +html { + height: 100%; + width: 100%; +} + +body { + margin: 0; + height: 100%; + width: 100%; +} + +pre { + white-space: pre-wrap; +} diff --git a/react-app/src/types/index.ts b/react-app/src/types/index.ts new file mode 100644 index 000000000..e0c2c4cd4 --- /dev/null +++ b/react-app/src/types/index.ts @@ -0,0 +1,53 @@ +export type FeedType = 'poll' | 'story' | 'job'; + +export interface Comment { + id: number; + level: number; + user: string; + time: number; + time_ago: string; + content: string; + deleted: boolean; + comments: Comment[]; +} + +export interface PollResult { + points: number; + content: string; +} + +export interface Story { + id: number; + title: string; + points: number; + user: string; + time: number; + time_ago: string; + type: FeedType; + url: string; + domain: string; + comments: Comment[]; + comments_count: number; + content: string; + poll: PollResult[]; + poll_votes_count: number; + deleted: boolean; + dead: boolean; +} + +export interface User { + id: string; + crated_time: number; + created: string; + karma: number; + avg: number; + about: string; +} + +export interface Settings { + showSettings: boolean; + openLinkInNewTab: boolean; + theme: string; + titleFontSize: string; + listSpacing: string; +} diff --git a/react-app/src/utils/commentLabel.ts b/react-app/src/utils/commentLabel.ts new file mode 100644 index 000000000..cb07a9cb3 --- /dev/null +++ b/react-app/src/utils/commentLabel.ts @@ -0,0 +1,6 @@ +export function commentLabel(count: number): string { + if (count > 0) { + return count === 1 ? '1 comment' : `${count} comments`; + } + return 'discuss'; +} diff --git a/react-app/tsconfig.app.json b/react-app/tsconfig.app.json new file mode 100644 index 000000000..7f42e5f7c --- /dev/null +++ b/react-app/tsconfig.app.json @@ -0,0 +1,25 @@ +{ + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", + "target": "es2023", + "lib": ["ES2023", "DOM"], + "module": "esnext", + "types": ["vite/client"], + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "verbatimModuleSyntax": true, + "moduleDetection": "force", + "noEmit": true, + "jsx": "react-jsx", + + /* Linting */ + "noUnusedLocals": true, + "noUnusedParameters": true, + "erasableSyntaxOnly": true, + "noFallthroughCasesInSwitch": true + }, + "include": ["src"] +} diff --git a/react-app/tsconfig.json b/react-app/tsconfig.json new file mode 100644 index 000000000..1ffef600d --- /dev/null +++ b/react-app/tsconfig.json @@ -0,0 +1,7 @@ +{ + "files": [], + "references": [ + { "path": "./tsconfig.app.json" }, + { "path": "./tsconfig.node.json" } + ] +} diff --git a/react-app/tsconfig.node.json b/react-app/tsconfig.node.json new file mode 100644 index 000000000..d3c52ea64 --- /dev/null +++ b/react-app/tsconfig.node.json @@ -0,0 +1,24 @@ +{ + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", + "target": "es2023", + "lib": ["ES2023"], + "module": "esnext", + "types": ["node"], + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "verbatimModuleSyntax": true, + "moduleDetection": "force", + "noEmit": true, + + /* Linting */ + "noUnusedLocals": true, + "noUnusedParameters": true, + "erasableSyntaxOnly": true, + "noFallthroughCasesInSwitch": true + }, + "include": ["vite.config.ts"] +} diff --git a/react-app/vite.config.ts b/react-app/vite.config.ts new file mode 100644 index 000000000..8b0f57b91 --- /dev/null +++ b/react-app/vite.config.ts @@ -0,0 +1,7 @@ +import { defineConfig } from 'vite' +import react from '@vitejs/plugin-react' + +// https://vite.dev/config/ +export default defineConfig({ + plugins: [react()], +}) From 6dfe88c749aad23d7eadcc3c3493db49f3c2444b Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Mon, 11 May 2026 14:05:19 +0000 Subject: [PATCH 2/4] fix: AMOLED border shorthand and poll bar division by zero Co-Authored-By: Eashan Sinha --- react-app/src/components/ItemDetails/ItemDetails.tsx | 4 +++- react-app/src/styles/_theme_variables.scss | 1 + react-app/src/styles/_themes.scss | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/react-app/src/components/ItemDetails/ItemDetails.tsx b/react-app/src/components/ItemDetails/ItemDetails.tsx index a398b6421..73eb607a3 100644 --- a/react-app/src/components/ItemDetails/ItemDetails.tsx +++ b/react-app/src/components/ItemDetails/ItemDetails.tsx @@ -112,7 +112,9 @@ export default function ItemDetails({ itemId }: ItemDetailsProps) { className="pollBar" style={{ width: `${ - (pollResult.points / item.poll_votes_count) * 100 + item.poll_votes_count > 0 + ? (pollResult.points / item.poll_votes_count) * 100 + : 0 }%`, }} /> diff --git a/react-app/src/styles/_theme_variables.scss b/react-app/src/styles/_theme_variables.scss index 32759093e..2ee86cc51 100644 --- a/react-app/src/styles/_theme_variables.scss +++ b/react-app/src/styles/_theme_variables.scss @@ -27,3 +27,4 @@ $theme-amoledblack-body-background-color: #000; $theme-amoledblack-text-color: rgba(255, 255, 255, 0.75); $theme-amoledblack-subtext-color: rgba(255, 255, 255, 0.5); $theme-amoledblack-secondary-color: rgba(255, 255, 255, 0.6); +$theme-amoledblack-border: 2px solid rgba(255, 255, 255, 0.6); diff --git a/react-app/src/styles/_themes.scss b/react-app/src/styles/_themes.scss index bc6dc2f6f..b8c2406f5 100644 --- a/react-app/src/styles/_themes.scss +++ b/react-app/src/styles/_themes.scss @@ -230,5 +230,5 @@ $theme-amoledblack-subtext-color, $theme-amoledblack-secondary-color, $theme-amoledblack-body-background-color, - $theme-amoledblack-secondary-color + $theme-amoledblack-border ); From 8292ee0c531aef284c3c61d4f808be50ef219c7b Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Mon, 11 May 2026 14:11:20 +0000 Subject: [PATCH 3/4] fix: correct feedType check and prevent OS theme override of user choice Co-Authored-By: Eashan Sinha --- react-app/src/components/Feed/Feed.tsx | 2 +- react-app/src/services/SettingsContext.tsx | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/react-app/src/components/Feed/Feed.tsx b/react-app/src/components/Feed/Feed.tsx index 3263484bb..a52a2a7e4 100644 --- a/react-app/src/components/Feed/Feed.tsx +++ b/react-app/src/components/Feed/Feed.tsx @@ -49,7 +49,7 @@ export default function Feed({ feedType, pageNum }: FeedProps) { Triplebyte.

)} - {feedType !== 'new' && ( + {feedType !== 'newest' && (
    localStorage.getItem('theme') !== null); const handleColorSchemeChange = useCallback((e: MediaQueryListEvent) => { + if (userSetTheme) return; const theme = e.matches ? 'night' : 'default'; setSettings(prev => ({ ...prev, theme })); - localStorage.setItem('theme', theme); - }, []); + }, [userSetTheme]); useEffect(() => { const mql = window.matchMedia('(prefers-color-scheme: dark)'); @@ -54,6 +55,7 @@ export function SettingsProvider({ children }: { children: ReactNode }) { const setTheme = useCallback((theme: string) => { setSettings(prev => ({ ...prev, theme })); localStorage.setItem('theme', theme); + setUserSetTheme(true); }, []); const setFont = useCallback((fontSize: string) => { From c020053c0940b34ef889da385a978cbfb684393b Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Mon, 11 May 2026 14:16:18 +0000 Subject: [PATCH 4/4] fix: remove dead feedType condition that hid newest feed items Co-Authored-By: Eashan Sinha --- react-app/src/components/Feed/Feed.tsx | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/react-app/src/components/Feed/Feed.tsx b/react-app/src/components/Feed/Feed.tsx index a52a2a7e4..35aa0a3f2 100644 --- a/react-app/src/components/Feed/Feed.tsx +++ b/react-app/src/components/Feed/Feed.tsx @@ -49,18 +49,16 @@ export default function Feed({ feedType, pageNum }: FeedProps) { Triplebyte.

    )} - {feedType !== 'newest' && ( -
      - {items.map((item) => ( -
    1. - -
    2. - ))} -
    - )} +
      + {items.map((item) => ( +
    1. + +
    2. + ))} +
    {listStart !== 1 && (