diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..b4e3016
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,13 @@
+# Editor configuration, see http://editorconfig.org
+root = true
+
+[*]
+charset = utf-8
+indent_style = space
+indent_size = 2
+insert_final_newline = true
+trim_trailing_whitespace = true
+
+[*.md]
+max_line_length = off
+trim_trailing_whitespace = false
\ No newline at end of file
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
new file mode 100644
index 0000000..da4b55f
--- /dev/null
+++ b/.github/pull_request_template.md
@@ -0,0 +1,33 @@
+# Pull Request Template
+
+## What's Changed
+
+- **In 1 sentence**: What this PR does (e.g., "Adds login state management with Zustand")
+- **Fixed issues**: `Fixes #123` or `Related to #321`
+
+### Type of Change
+
+- [ ] New feature
+- [ ] Bug fix
+- [ ] Refactoring
+- [ ] Other (describe)
+
+### Testing
+
+**How to check**:
+
+1. Step 1 (e.g., "Try logging in with invalid credentials")
+2. Step 2 (e.g., "Verify cart updates when adding items")
+
+**Tested on**:
+
+- [ ] Desktop (Chrome)
+- [ ] Mobile (Safari)
+
+### Screenshots (if UI changed)
+
+### Need to Know
+
+- Any breaking changes?
+- Dependencies added (`zod`, `zustand`, etc.)
+- Questions
diff --git a/.gitignore b/.gitignore
index 1170717..cafae85 100644
--- a/.gitignore
+++ b/.gitignore
@@ -134,3 +134,17 @@ dist
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.*
+
+# Vitest
+.vitest-cache/
+.vitest/
+test-results.xml
+
+# IDE
+.idea/
+.vscode/
+*.swp
+*.swo
+
+# macOS
+.DS_Store
\ No newline at end of file
diff --git a/.husky/commit-msg b/.husky/commit-msg
new file mode 100644
index 0000000..34eed8b
--- /dev/null
+++ b/.husky/commit-msg
@@ -0,0 +1 @@
+npx --no -- commitlint --edit $1
\ No newline at end of file
diff --git a/.husky/pre-commit b/.husky/pre-commit
new file mode 100644
index 0000000..1524ad6
--- /dev/null
+++ b/.husky/pre-commit
@@ -0,0 +1 @@
+npx --no -- lint-staged
diff --git a/.husky/pre-push b/.husky/pre-push
new file mode 100644
index 0000000..cf22276
--- /dev/null
+++ b/.husky/pre-push
@@ -0,0 +1,4 @@
+echo 'Running test...'
+echo 'If there are no tests, you need to write them'
+
+npm test
diff --git a/.prettierrc b/.prettierrc
new file mode 100644
index 0000000..09cb630
--- /dev/null
+++ b/.prettierrc
@@ -0,0 +1,7 @@
+{
+ "semi": true,
+ "singleQuote": true,
+ "trailingComma": "all",
+ "printWidth": 80,
+ "tabWidth": 2
+ }
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
deleted file mode 100644
index ecf8ba8..0000000
--- a/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2025 aleksei
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/README.md b/README.md
index d416b84..80e32c4 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,72 @@
-# eCommerce-Application
\ No newline at end of file
+# Wine not? - Modern Wine E-Commerce
+
+## About Us
+
+**Wine not?** brings you premium wines from around the world with:
+
+- Handpicked wines from top vineyards
+- Easy browsing and cart management
+- Fast nationwide delivery
+- Secure registration and checkout
+- Exclusive deals for regular customers
+
+Discover your next favorite bottle in just a few clicks!
+
+## Technology Stack
+
+### Core
+
+- **Frontend**:
React + TypeScript
+- **Routing**:
React Router
+- **State**:
Zustand +
Zod
+- **Data**:
SWR (Data fetching)
+- **UI**:
Mantine + Framer Motion
+
+### Tooling
+
+- **Bundler**:
Vite
+- **Testing**:
Vitest + Testing Library
+- **Linting**: ESLint + Prettier + Husky
+
+## Quick Start
+
+> [!NOTE]
+> To get started with the development:
+>
+> 1. Clone the repository using `git clone https://github.com/maiano/eCommerce-Application.git`.
+> 2. Install dependencies using `npm install`.
+> 3. Run the development server using `npm run dev`.
+> 4. Build the project using `npm run build`.
+
+
+ Scripts
+
+- `build`: Create production build.
+
+- `ci:format`: Check code formatting.
+
+- `dev`: Start development server.
+
+- `format`: Format code with Prettier.
+
+- `lint`: Check for linting errors.
+
+- `lint:fix`: Fix linting errors.
+
+- `prepare`: Sets up Husky.
+
+- `preview`: Preview production build.
+
+- `test`: Run all tests.
+
+- `coverage`: Generate test coverage report.
+
+
+
+## Project Team
+
+The following contributors have worked on this project:
+
+- **Victoria** - Developer | Designer - [GitHub](https://github.com/blk-thorn)
+- **Anna** - Developer | Project manager - [GitHub](https://github.com/ann-sm)
+- **Aleksei** - Developer | Team Lead- [GitHub](https://github.com/maiano)
diff --git a/commitlint.config.js b/commitlint.config.js
new file mode 100644
index 0000000..6aee53e
--- /dev/null
+++ b/commitlint.config.js
@@ -0,0 +1,27 @@
+export default {
+ extends: ['@commitlint/config-conventional'],
+ rules: {
+ 'scope-case': [2, 'always', 'lower-case'],
+ 'subject-empty': [2, 'never'],
+ 'subject-full-stop': [2, 'never', '.'],
+ 'type-case': [2, 'always', 'lower-case'],
+ 'type-empty': [2, 'never'],
+ 'type-enum': [
+ 2,
+ 'always',
+ [
+ 'build',
+ 'ci',
+ 'chore',
+ 'docs',
+ 'feat',
+ 'fix',
+ 'refactor',
+ 'revert',
+ 'style',
+ 'test',
+ 'init',
+ ],
+ ],
+ },
+};
diff --git a/eslint.config.js b/eslint.config.js
new file mode 100644
index 0000000..ec34a87
--- /dev/null
+++ b/eslint.config.js
@@ -0,0 +1,89 @@
+import js from '@eslint/js';
+import globals from 'globals';
+import reactHooks from 'eslint-plugin-react-hooks';
+import reactRefresh from 'eslint-plugin-react-refresh';
+import tsPlugin from '@typescript-eslint/eslint-plugin';
+import tsParser from '@typescript-eslint/parser';
+import importPlugin from 'eslint-plugin-import';
+import jsxA11y from 'eslint-plugin-jsx-a11y';
+
+export default [
+ // Base
+ {
+ ignores: ['dist/**', '**/*.d.ts', 'node_modules', 'vite.http-config.ts'],
+ },
+
+ // JS
+ {
+ files: ['**/*.js'],
+ languageOptions: {
+ ecmaVersion: 2022,
+ sourceType: 'module',
+ globals: {
+ ...globals.browser,
+ },
+ },
+ rules: {
+ ...js.configs.recommended.rules,
+ },
+ },
+
+ // TS
+ {
+ files: ['src/**/*.{ts,tsx}'],
+ languageOptions: {
+ parser: tsParser,
+ parserOptions: {
+ project: './tsconfig.app.json',
+ tsconfigRootDir: import.meta.dirname,
+ ecmaFeatures: {
+ jsx: true,
+ },
+ ecmaVersion: 2022,
+ sourceType: 'module',
+ },
+ globals: {
+ ...globals.browser,
+ },
+ },
+ plugins: {
+ '@typescript-eslint': tsPlugin,
+ import: importPlugin,
+ 'react-hooks': reactHooks,
+ 'react-refresh': reactRefresh,
+ 'jsx-a11y': jsxA11y,
+ },
+ rules: {
+ ...tsPlugin.configs.recommended.rules,
+ ...reactHooks.configs.recommended.rules,
+ 'react-refresh/only-export-components': 'warn',
+ 'import/order': [
+ 'warn',
+ {
+ groups: [
+ 'builtin',
+ 'external',
+ 'internal',
+ 'parent',
+ 'sibling',
+ 'index',
+ ],
+ alphabetize: { order: 'asc', caseInsensitive: true },
+ },
+ ],
+ '@typescript-eslint/no-unused-vars': 'warn',
+ '@typescript-eslint/no-explicit-any': 'error',
+ '@typescript-eslint/no-non-null-assertion': 'error',
+ '@typescript-eslint/no-unsafe-argument': 'error',
+ '@typescript-eslint/no-unsafe-assignment': 'error',
+ '@typescript-eslint/no-unsafe-call': 'error',
+ '@typescript-eslint/no-unsafe-member-access': 'error',
+ '@typescript-eslint/no-unsafe-return': 'error',
+
+ 'jsx-a11y/alt-text': 'warn',
+ 'jsx-a11y/anchor-is-valid': 'warn',
+ 'jsx-a11y/aria-props': 'warn',
+ 'jsx-a11y/click-events-have-key-events': 'warn',
+ },
+ },
+];
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..2ac827e
--- /dev/null
+++ b/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Wine not?
+
+
+
+
+
+
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 0000000..11508b5
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,10343 @@
+{
+ "name": "ecommerce-application",
+ "version": "0.0.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "ecommerce-application",
+ "version": "0.0.0",
+ "dependencies": {
+ "@commercetools/platform-sdk": "^8.8.0",
+ "@commercetools/sdk-client-v2": "^3.0.0",
+ "@hookform/resolvers": "^5.0.1",
+ "@mantine/carousel": "^7.17.5",
+ "@mantine/core": "^7.17.5",
+ "@mantine/dates": "^7.17.5",
+ "@mantine/form": "^7.17.5",
+ "@mantine/hooks": "^7.17.5",
+ "@mantine/notifications": "^7.17.5",
+ "framer-motion": "^12.9.2",
+ "react": "^19.0.0",
+ "react-dom": "^19.0.0",
+ "react-hook-form": "^7.56.1",
+ "react-router-dom": "^7.6.0",
+ "swr": "^2.3.3",
+ "zod": "^3.24.3",
+ "zustand": "^5.0.3"
+ },
+ "devDependencies": {
+ "@commitlint/cli": "^19.8.0",
+ "@commitlint/config-conventional": "^19.8.0",
+ "@eslint/js": "^9.22.0",
+ "@testing-library/jest-dom": "^6.6.3",
+ "@testing-library/react": "^16.3.0",
+ "@testing-library/user-event": "^14.6.1",
+ "@types/isomorphic-fetch": "^0.0.39",
+ "@types/node": "^22.15.2",
+ "@types/react": "^19.0.10",
+ "@types/react-dom": "^19.0.4",
+ "@typescript-eslint/eslint-plugin": "^8.31.0",
+ "@typescript-eslint/parser": "^8.31.0",
+ "@vitejs/plugin-react": "^4.3.4",
+ "@vitest/coverage-v8": "^3.1.2",
+ "eslint": "^9.22.0",
+ "eslint-config-prettier": "^10.1.2",
+ "eslint-import-resolver-typescript": "^4.3.4",
+ "eslint-plugin-import": "^2.31.0",
+ "eslint-plugin-jsx-a11y": "^6.10.2",
+ "eslint-plugin-prettier": "^5.2.6",
+ "eslint-plugin-react-hooks": "^5.2.0",
+ "eslint-plugin-react-refresh": "^0.4.19",
+ "globals": "^16.0.0",
+ "husky": "^9.1.7",
+ "isomorphic-fetch": "^3.0.0",
+ "jsdom": "^26.1.0",
+ "lint-staged": "^15.5.1",
+ "node-fetch": "^3.3.2",
+ "prettier": "^3.5.3",
+ "typescript": "~5.7.2",
+ "typescript-eslint": "^8.26.1",
+ "vite": "^6.3.1",
+ "vitest": "^3.1.2"
+ }
+ },
+ "node_modules/@adobe/css-tools": {
+ "version": "4.4.2",
+ "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.2.tgz",
+ "integrity": "sha512-baYZExFpsdkBNuvGKTKWCwKH57HRZLVtycZS05WTQNVOiXVSeAki3nU35zlRbToeMW8aHlJfyS+1C4BOv27q0A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@ampproject/remapping": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
+ "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@asamuzakjp/css-color": {
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-3.1.5.tgz",
+ "integrity": "sha512-w7AmVyTTiU41fNLsFDf+gA2Dwtbx2EJtn2pbJNAGSRAg50loXy1uLXA3hEpD8+eydcomTurw09tq5/AyceCaGg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@csstools/css-calc": "^2.1.3",
+ "@csstools/css-color-parser": "^3.0.9",
+ "@csstools/css-parser-algorithms": "^3.0.4",
+ "@csstools/css-tokenizer": "^3.0.3",
+ "lru-cache": "^10.4.3"
+ }
+ },
+ "node_modules/@asamuzakjp/css-color/node_modules/lru-cache": {
+ "version": "10.4.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
+ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/@babel/code-frame": {
+ "version": "7.26.2",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz",
+ "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.25.9",
+ "js-tokens": "^4.0.0",
+ "picocolors": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/compat-data": {
+ "version": "7.26.8",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.8.tgz",
+ "integrity": "sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/core": {
+ "version": "7.26.10",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.10.tgz",
+ "integrity": "sha512-vMqyb7XCDMPvJFFOaT9kxtiRh42GwlZEg1/uIgtZshS5a/8OaduUfCi7kynKgc3Tw/6Uo2D+db9qBttghhmxwQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@ampproject/remapping": "^2.2.0",
+ "@babel/code-frame": "^7.26.2",
+ "@babel/generator": "^7.26.10",
+ "@babel/helper-compilation-targets": "^7.26.5",
+ "@babel/helper-module-transforms": "^7.26.0",
+ "@babel/helpers": "^7.26.10",
+ "@babel/parser": "^7.26.10",
+ "@babel/template": "^7.26.9",
+ "@babel/traverse": "^7.26.10",
+ "@babel/types": "^7.26.10",
+ "convert-source-map": "^2.0.0",
+ "debug": "^4.1.0",
+ "gensync": "^1.0.0-beta.2",
+ "json5": "^2.2.3",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/babel"
+ }
+ },
+ "node_modules/@babel/core/node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/@babel/generator": {
+ "version": "7.27.0",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.27.0.tgz",
+ "integrity": "sha512-VybsKvpiN1gU1sdMZIp7FcqphVVKEwcuj02x73uvcHE0PTihx1nlBcowYWhDwjpoAXRv43+gDzyggGnn1XZhVw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.27.0",
+ "@babel/types": "^7.27.0",
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.25",
+ "jsesc": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-compilation-targets": {
+ "version": "7.27.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.0.tgz",
+ "integrity": "sha512-LVk7fbXml0H2xH34dFzKQ7TDZ2G4/rVTOrq9V+icbbadjbVxxeFeDsNHv2SrZeWoA+6ZiTyWYWtScEIW07EAcA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/compat-data": "^7.26.8",
+ "@babel/helper-validator-option": "^7.25.9",
+ "browserslist": "^4.24.0",
+ "lru-cache": "^5.1.1",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-compilation-targets/node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/@babel/helper-module-imports": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz",
+ "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/traverse": "^7.25.9",
+ "@babel/types": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-transforms": {
+ "version": "7.26.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz",
+ "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-module-imports": "^7.25.9",
+ "@babel/helper-validator-identifier": "^7.25.9",
+ "@babel/traverse": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-plugin-utils": {
+ "version": "7.26.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.26.5.tgz",
+ "integrity": "sha512-RS+jZcRdZdRFzMyr+wcsaqOmld1/EqTghfaBGQQd/WnRdzdlvSZ//kF7U8VQTxf1ynZ4cjUcYgjVGx13ewNPMg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-string-parser": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz",
+ "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-identifier": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz",
+ "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-option": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz",
+ "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helpers": {
+ "version": "7.27.0",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.27.0.tgz",
+ "integrity": "sha512-U5eyP/CTFPuNE3qk+WZMxFkp/4zUzdceQlfzf7DdGdhp+Fezd7HD+i8Y24ZuTMKX3wQBld449jijbGq6OdGNQg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/template": "^7.27.0",
+ "@babel/types": "^7.27.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/parser": {
+ "version": "7.27.0",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.0.tgz",
+ "integrity": "sha512-iaepho73/2Pz7w2eMS0Q5f83+0RKI7i4xmiYeBmDzfRVbQtTOG7Ts0S4HzJVsTMGI9keU8rNfuZr8DKfSt7Yyg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.27.0"
+ },
+ "bin": {
+ "parser": "bin/babel-parser.js"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-react-jsx-self": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.25.9.tgz",
+ "integrity": "sha512-y8quW6p0WHkEhmErnfe58r7x0A70uKphQm8Sp8cV7tjNQwK56sNVK0M73LK3WuYmsuyrftut4xAkjjgU0twaMg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-react-jsx-source": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.25.9.tgz",
+ "integrity": "sha512-+iqjT8xmXhhYv4/uiYd8FNQsraMFZIfxVSqxxVSZP0WbbSAWvBXAul0m/zu+7Vv4O/3WtApy9pmaTMiumEZgfg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/runtime": {
+ "version": "7.27.0",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.0.tgz",
+ "integrity": "sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw==",
+ "license": "MIT",
+ "dependencies": {
+ "regenerator-runtime": "^0.14.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/template": {
+ "version": "7.27.0",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.0.tgz",
+ "integrity": "sha512-2ncevenBqXI6qRMukPlXwHKHchC7RyMuu4xv5JBXRfOGVcTy1mXCD12qrp7Jsoxll1EV3+9sE4GugBVRjT2jFA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.26.2",
+ "@babel/parser": "^7.27.0",
+ "@babel/types": "^7.27.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/traverse": {
+ "version": "7.27.0",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.27.0.tgz",
+ "integrity": "sha512-19lYZFzYVQkkHkl4Cy4WrAVcqBkgvV2YM2TU3xG6DIwO7O3ecbDPfW3yM3bjAGcqcQHi+CCtjMR3dIEHxsd6bA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.26.2",
+ "@babel/generator": "^7.27.0",
+ "@babel/parser": "^7.27.0",
+ "@babel/template": "^7.27.0",
+ "@babel/types": "^7.27.0",
+ "debug": "^4.3.1",
+ "globals": "^11.1.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/traverse/node_modules/globals": {
+ "version": "11.12.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
+ "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@babel/types": {
+ "version": "7.27.0",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.0.tgz",
+ "integrity": "sha512-H45s8fVLYjbhFH62dIJ3WtmJ6RSPt/3DRO0ZcT2SUiYiQyz3BLVb9ADEnLl91m74aQPS3AzzeajZHYOalWe3bg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-string-parser": "^7.25.9",
+ "@babel/helper-validator-identifier": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@bcoe/v8-coverage": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-1.0.2.tgz",
+ "integrity": "sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@commercetools/platform-sdk": {
+ "version": "8.8.0",
+ "resolved": "https://registry.npmjs.org/@commercetools/platform-sdk/-/platform-sdk-8.8.0.tgz",
+ "integrity": "sha512-fHXx4e/4vU8VEofUhIUSo0jjjOqjPy2RsZGDlEahd60ZCTPOMTtyRq6JExQoBtAucBO++8CKCaEdWAp1hZJkOQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@commercetools/ts-client": "^3.2.1"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@commercetools/sdk-client-v2": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@commercetools/sdk-client-v2/-/sdk-client-v2-3.0.0.tgz",
+ "integrity": "sha512-AU0qyd41lv3l7X/e17mwRbtqGUMCJrCP25/ca3CMGvLGYGLx8zFu5zUYggOyEMTkViwG3NlY83zTTG0/YoUo8Q==",
+ "license": "MIT",
+ "dependencies": {
+ "buffer": "^6.0.3"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@commercetools/ts-client": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/@commercetools/ts-client/-/ts-client-3.3.0.tgz",
+ "integrity": "sha512-qqbtvIVcvDS3xd1kUYfYoMUhGLPcY4TCP2WzTvrEHEs/MhrZqUhZUKcblxxY5/d8pROARlbl+XrYnKdFaZxO3g==",
+ "license": "MIT",
+ "dependencies": {
+ "buffer": "^6.0.3"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@commitlint/cli": {
+ "version": "19.8.0",
+ "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-19.8.0.tgz",
+ "integrity": "sha512-t/fCrLVu+Ru01h0DtlgHZXbHV2Y8gKocTR5elDOqIRUzQd0/6hpt2VIWOj9b3NDo7y4/gfxeR2zRtXq/qO6iUg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@commitlint/format": "^19.8.0",
+ "@commitlint/lint": "^19.8.0",
+ "@commitlint/load": "^19.8.0",
+ "@commitlint/read": "^19.8.0",
+ "@commitlint/types": "^19.8.0",
+ "tinyexec": "^0.3.0",
+ "yargs": "^17.0.0"
+ },
+ "bin": {
+ "commitlint": "cli.js"
+ },
+ "engines": {
+ "node": ">=v18"
+ }
+ },
+ "node_modules/@commitlint/config-conventional": {
+ "version": "19.8.0",
+ "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-19.8.0.tgz",
+ "integrity": "sha512-9I2kKJwcAPwMoAj38hwqFXG0CzS2Kj+SAByPUQ0SlHTfb7VUhYVmo7G2w2tBrqmOf7PFd6MpZ/a1GQJo8na8kw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@commitlint/types": "^19.8.0",
+ "conventional-changelog-conventionalcommits": "^7.0.2"
+ },
+ "engines": {
+ "node": ">=v18"
+ }
+ },
+ "node_modules/@commitlint/config-validator": {
+ "version": "19.8.0",
+ "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-19.8.0.tgz",
+ "integrity": "sha512-+r5ZvD/0hQC3w5VOHJhGcCooiAVdynFlCe2d6I9dU+PvXdV3O+fU4vipVg+6hyLbQUuCH82mz3HnT/cBQTYYuA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@commitlint/types": "^19.8.0",
+ "ajv": "^8.11.0"
+ },
+ "engines": {
+ "node": ">=v18"
+ }
+ },
+ "node_modules/@commitlint/config-validator/node_modules/ajv": {
+ "version": "8.17.1",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
+ "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.3",
+ "fast-uri": "^3.0.1",
+ "json-schema-traverse": "^1.0.0",
+ "require-from-string": "^2.0.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/@commitlint/config-validator/node_modules/json-schema-traverse": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@commitlint/ensure": {
+ "version": "19.8.0",
+ "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-19.8.0.tgz",
+ "integrity": "sha512-kNiNU4/bhEQ/wutI1tp1pVW1mQ0QbAjfPRo5v8SaxoVV+ARhkB8Wjg3BSseNYECPzWWfg/WDqQGIfV1RaBFQZg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@commitlint/types": "^19.8.0",
+ "lodash.camelcase": "^4.3.0",
+ "lodash.kebabcase": "^4.1.1",
+ "lodash.snakecase": "^4.1.1",
+ "lodash.startcase": "^4.4.0",
+ "lodash.upperfirst": "^4.3.1"
+ },
+ "engines": {
+ "node": ">=v18"
+ }
+ },
+ "node_modules/@commitlint/execute-rule": {
+ "version": "19.8.0",
+ "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-19.8.0.tgz",
+ "integrity": "sha512-fuLeI+EZ9x2v/+TXKAjplBJWI9CNrHnyi5nvUQGQt4WRkww/d95oVRsc9ajpt4xFrFmqMZkd/xBQHZDvALIY7A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=v18"
+ }
+ },
+ "node_modules/@commitlint/format": {
+ "version": "19.8.0",
+ "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-19.8.0.tgz",
+ "integrity": "sha512-EOpA8IERpQstxwp/WGnDArA7S+wlZDeTeKi98WMOvaDLKbjptuHWdOYYr790iO7kTCif/z971PKPI2PkWMfOxg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@commitlint/types": "^19.8.0",
+ "chalk": "^5.3.0"
+ },
+ "engines": {
+ "node": ">=v18"
+ }
+ },
+ "node_modules/@commitlint/format/node_modules/chalk": {
+ "version": "5.4.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz",
+ "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.17.0 || ^14.13 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/@commitlint/is-ignored": {
+ "version": "19.8.0",
+ "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-19.8.0.tgz",
+ "integrity": "sha512-L2Jv9yUg/I+jF3zikOV0rdiHUul9X3a/oU5HIXhAJLE2+TXTnEBfqYP9G5yMw/Yb40SnR764g4fyDK6WR2xtpw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@commitlint/types": "^19.8.0",
+ "semver": "^7.6.0"
+ },
+ "engines": {
+ "node": ">=v18"
+ }
+ },
+ "node_modules/@commitlint/lint": {
+ "version": "19.8.0",
+ "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-19.8.0.tgz",
+ "integrity": "sha512-+/NZKyWKSf39FeNpqhfMebmaLa1P90i1Nrb1SrA7oSU5GNN/lksA4z6+ZTnsft01YfhRZSYMbgGsARXvkr/VLQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@commitlint/is-ignored": "^19.8.0",
+ "@commitlint/parse": "^19.8.0",
+ "@commitlint/rules": "^19.8.0",
+ "@commitlint/types": "^19.8.0"
+ },
+ "engines": {
+ "node": ">=v18"
+ }
+ },
+ "node_modules/@commitlint/load": {
+ "version": "19.8.0",
+ "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-19.8.0.tgz",
+ "integrity": "sha512-4rvmm3ff81Sfb+mcWT5WKlyOa+Hd33WSbirTVUer0wjS1Hv/Hzr07Uv1ULIV9DkimZKNyOwXn593c+h8lsDQPQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@commitlint/config-validator": "^19.8.0",
+ "@commitlint/execute-rule": "^19.8.0",
+ "@commitlint/resolve-extends": "^19.8.0",
+ "@commitlint/types": "^19.8.0",
+ "chalk": "^5.3.0",
+ "cosmiconfig": "^9.0.0",
+ "cosmiconfig-typescript-loader": "^6.1.0",
+ "lodash.isplainobject": "^4.0.6",
+ "lodash.merge": "^4.6.2",
+ "lodash.uniq": "^4.5.0"
+ },
+ "engines": {
+ "node": ">=v18"
+ }
+ },
+ "node_modules/@commitlint/load/node_modules/chalk": {
+ "version": "5.4.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz",
+ "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.17.0 || ^14.13 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/@commitlint/message": {
+ "version": "19.8.0",
+ "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-19.8.0.tgz",
+ "integrity": "sha512-qs/5Vi9bYjf+ZV40bvdCyBn5DvbuelhR6qewLE8Bh476F7KnNyLfdM/ETJ4cp96WgeeHo6tesA2TMXS0sh5X4A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=v18"
+ }
+ },
+ "node_modules/@commitlint/parse": {
+ "version": "19.8.0",
+ "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-19.8.0.tgz",
+ "integrity": "sha512-YNIKAc4EXvNeAvyeEnzgvm1VyAe0/b3Wax7pjJSwXuhqIQ1/t2hD3OYRXb6D5/GffIvaX82RbjD+nWtMZCLL7Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@commitlint/types": "^19.8.0",
+ "conventional-changelog-angular": "^7.0.0",
+ "conventional-commits-parser": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=v18"
+ }
+ },
+ "node_modules/@commitlint/read": {
+ "version": "19.8.0",
+ "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-19.8.0.tgz",
+ "integrity": "sha512-6ywxOGYajcxK1y1MfzrOnwsXO6nnErna88gRWEl3qqOOP8MDu/DTeRkGLXBFIZuRZ7mm5yyxU5BmeUvMpNte5w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@commitlint/top-level": "^19.8.0",
+ "@commitlint/types": "^19.8.0",
+ "git-raw-commits": "^4.0.0",
+ "minimist": "^1.2.8",
+ "tinyexec": "^0.3.0"
+ },
+ "engines": {
+ "node": ">=v18"
+ }
+ },
+ "node_modules/@commitlint/resolve-extends": {
+ "version": "19.8.0",
+ "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-19.8.0.tgz",
+ "integrity": "sha512-CLanRQwuG2LPfFVvrkTrBR/L/DMy3+ETsgBqW1OvRxmzp/bbVJW0Xw23LnnExgYcsaFtos967lul1CsbsnJlzQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@commitlint/config-validator": "^19.8.0",
+ "@commitlint/types": "^19.8.0",
+ "global-directory": "^4.0.1",
+ "import-meta-resolve": "^4.0.0",
+ "lodash.mergewith": "^4.6.2",
+ "resolve-from": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=v18"
+ }
+ },
+ "node_modules/@commitlint/resolve-extends/node_modules/resolve-from": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
+ "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@commitlint/rules": {
+ "version": "19.8.0",
+ "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-19.8.0.tgz",
+ "integrity": "sha512-IZ5IE90h6DSWNuNK/cwjABLAKdy8tP8OgGVGbXe1noBEX5hSsu00uRlLu6JuruiXjWJz2dZc+YSw3H0UZyl/mA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@commitlint/ensure": "^19.8.0",
+ "@commitlint/message": "^19.8.0",
+ "@commitlint/to-lines": "^19.8.0",
+ "@commitlint/types": "^19.8.0"
+ },
+ "engines": {
+ "node": ">=v18"
+ }
+ },
+ "node_modules/@commitlint/to-lines": {
+ "version": "19.8.0",
+ "resolved": "https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-19.8.0.tgz",
+ "integrity": "sha512-3CKLUw41Cur8VMjh16y8LcsOaKbmQjAKCWlXx6B0vOUREplp6em9uIVhI8Cv934qiwkbi2+uv+mVZPnXJi1o9A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=v18"
+ }
+ },
+ "node_modules/@commitlint/top-level": {
+ "version": "19.8.0",
+ "resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-19.8.0.tgz",
+ "integrity": "sha512-Rphgoc/omYZisoNkcfaBRPQr4myZEHhLPx2/vTXNLjiCw4RgfPR1wEgUpJ9OOmDCiv5ZyIExhprNLhteqH4FuQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "find-up": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=v18"
+ }
+ },
+ "node_modules/@commitlint/top-level/node_modules/find-up": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-7.0.0.tgz",
+ "integrity": "sha512-YyZM99iHrqLKjmt4LJDj58KI+fYyufRLBSYcqycxf//KpBk9FoewoGX0450m9nB44qrZnovzC2oeP5hUibxc/g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "locate-path": "^7.2.0",
+ "path-exists": "^5.0.0",
+ "unicorn-magic": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@commitlint/top-level/node_modules/locate-path": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz",
+ "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-locate": "^6.0.0"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@commitlint/top-level/node_modules/p-limit": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz",
+ "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "yocto-queue": "^1.0.0"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@commitlint/top-level/node_modules/p-locate": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz",
+ "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-limit": "^4.0.0"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@commitlint/top-level/node_modules/path-exists": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz",
+ "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ }
+ },
+ "node_modules/@commitlint/top-level/node_modules/yocto-queue": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.2.1.tgz",
+ "integrity": "sha512-AyeEbWOu/TAXdxlV9wmGcR0+yh2j3vYPGOECcIj2S7MkrLyC7ne+oye2BKTItt0ii2PHk4cDy+95+LshzbXnGg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.20"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@commitlint/types": {
+ "version": "19.8.0",
+ "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-19.8.0.tgz",
+ "integrity": "sha512-LRjP623jPyf3Poyfb0ohMj8I3ORyBDOwXAgxxVPbSD0unJuW2mJWeiRfaQinjtccMqC5Wy1HOMfa4btKjbNxbg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/conventional-commits-parser": "^5.0.0",
+ "chalk": "^5.3.0"
+ },
+ "engines": {
+ "node": ">=v18"
+ }
+ },
+ "node_modules/@commitlint/types/node_modules/chalk": {
+ "version": "5.4.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz",
+ "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.17.0 || ^14.13 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/@csstools/color-helpers": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.0.2.tgz",
+ "integrity": "sha512-JqWH1vsgdGcw2RR6VliXXdA0/59LttzlU8UlRT/iUUsEeWfYq8I+K0yhihEUTTHLRm1EXvpsCx3083EU15ecsA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@csstools/css-calc": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.3.tgz",
+ "integrity": "sha512-XBG3talrhid44BY1x3MHzUx/aTG8+x/Zi57M4aTKK9RFB4aLlF3TTSzfzn8nWVHWL3FgAXAxmupmDd6VWww+pw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "@csstools/css-parser-algorithms": "^3.0.4",
+ "@csstools/css-tokenizer": "^3.0.3"
+ }
+ },
+ "node_modules/@csstools/css-color-parser": {
+ "version": "3.0.9",
+ "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.0.9.tgz",
+ "integrity": "sha512-wILs5Zk7BU86UArYBJTPy/FMPPKVKHMj1ycCEyf3VUptol0JNRLFU/BZsJ4aiIHJEbSLiizzRrw8Pc1uAEDrXw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@csstools/color-helpers": "^5.0.2",
+ "@csstools/css-calc": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "@csstools/css-parser-algorithms": "^3.0.4",
+ "@csstools/css-tokenizer": "^3.0.3"
+ }
+ },
+ "node_modules/@csstools/css-parser-algorithms": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.4.tgz",
+ "integrity": "sha512-Up7rBoV77rv29d3uKHUIVubz1BTcgyUK72IvCQAbfbMv584xHcGKCKbWh7i8hPrRJ7qU4Y8IO3IY9m+iTB7P3A==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "@csstools/css-tokenizer": "^3.0.3"
+ }
+ },
+ "node_modules/@csstools/css-tokenizer": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.3.tgz",
+ "integrity": "sha512-UJnjoFsmxfKUdNYdWgOB0mWUypuLvAfQPH1+pyvRJs6euowbFkFC6P13w1l8mJyi3vxYMxc9kld5jZEGRQs6bw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@emnapi/core": {
+ "version": "1.4.3",
+ "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.4.3.tgz",
+ "integrity": "sha512-4m62DuCE07lw01soJwPiBGC0nAww0Q+RY70VZ+n49yDIO13yyinhbWCeNnaob0lakDtWQzSdtNWzJeOJt2ma+g==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@emnapi/wasi-threads": "1.0.2",
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@emnapi/runtime": {
+ "version": "1.4.3",
+ "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.4.3.tgz",
+ "integrity": "sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@emnapi/wasi-threads": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.0.2.tgz",
+ "integrity": "sha512-5n3nTJblwRi8LlXkJ9eBzu+kZR8Yxcc7ubakyQTFzPMtIhFpUBRbsnc2Dv88IZDIbCDlBiWrknhB4Lsz7mg6BA==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@esbuild/aix-ppc64": {
+ "version": "0.25.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.3.tgz",
+ "integrity": "sha512-W8bFfPA8DowP8l//sxjJLSLkD8iEjMc7cBVyP+u4cEv9sM7mdUCkgsj+t0n/BWPFtv7WWCN5Yzj0N6FJNUUqBQ==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "aix"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-arm": {
+ "version": "0.25.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.3.tgz",
+ "integrity": "sha512-PuwVXbnP87Tcff5I9ngV0lmiSu40xw1At6i3GsU77U7cjDDB4s0X2cyFuBiDa1SBk9DnvWwnGvVaGBqoFWPb7A==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-arm64": {
+ "version": "0.25.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.3.tgz",
+ "integrity": "sha512-XelR6MzjlZuBM4f5z2IQHK6LkK34Cvv6Rj2EntER3lwCBFdg6h2lKbtRjpTTsdEjD/WSe1q8UyPBXP1x3i/wYQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-x64": {
+ "version": "0.25.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.3.tgz",
+ "integrity": "sha512-ogtTpYHT/g1GWS/zKM0cc/tIebFjm1F9Aw1boQ2Y0eUQ+J89d0jFY//s9ei9jVIlkYi8AfOjiixcLJSGNSOAdQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/darwin-arm64": {
+ "version": "0.25.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.3.tgz",
+ "integrity": "sha512-eESK5yfPNTqpAmDfFWNsOhmIOaQA59tAcF/EfYvo5/QWQCzXn5iUSOnqt3ra3UdzBv073ykTtmeLJZGt3HhA+w==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/darwin-x64": {
+ "version": "0.25.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.3.tgz",
+ "integrity": "sha512-Kd8glo7sIZtwOLcPbW0yLpKmBNWMANZhrC1r6K++uDR2zyzb6AeOYtI6udbtabmQpFaxJ8uduXMAo1gs5ozz8A==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.25.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.3.tgz",
+ "integrity": "sha512-EJiyS70BYybOBpJth3M0KLOus0n+RRMKTYzhYhFeMwp7e/RaajXvP+BWlmEXNk6uk+KAu46j/kaQzr6au+JcIw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/freebsd-x64": {
+ "version": "0.25.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.3.tgz",
+ "integrity": "sha512-Q+wSjaLpGxYf7zC0kL0nDlhsfuFkoN+EXrx2KSB33RhinWzejOd6AvgmP5JbkgXKmjhmpfgKZq24pneodYqE8Q==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-arm": {
+ "version": "0.25.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.3.tgz",
+ "integrity": "sha512-dUOVmAUzuHy2ZOKIHIKHCm58HKzFqd+puLaS424h6I85GlSDRZIA5ycBixb3mFgM0Jdh+ZOSB6KptX30DD8YOQ==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-arm64": {
+ "version": "0.25.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.3.tgz",
+ "integrity": "sha512-xCUgnNYhRD5bb1C1nqrDV1PfkwgbswTTBRbAd8aH5PhYzikdf/ddtsYyMXFfGSsb/6t6QaPSzxtbfAZr9uox4A==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-ia32": {
+ "version": "0.25.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.3.tgz",
+ "integrity": "sha512-yplPOpczHOO4jTYKmuYuANI3WhvIPSVANGcNUeMlxH4twz/TeXuzEP41tGKNGWJjuMhotpGabeFYGAOU2ummBw==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-loong64": {
+ "version": "0.25.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.3.tgz",
+ "integrity": "sha512-P4BLP5/fjyihmXCELRGrLd793q/lBtKMQl8ARGpDxgzgIKJDRJ/u4r1A/HgpBpKpKZelGct2PGI4T+axcedf6g==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-mips64el": {
+ "version": "0.25.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.3.tgz",
+ "integrity": "sha512-eRAOV2ODpu6P5divMEMa26RRqb2yUoYsuQQOuFUexUoQndm4MdpXXDBbUoKIc0iPa4aCO7gIhtnYomkn2x+bag==",
+ "cpu": [
+ "mips64el"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-ppc64": {
+ "version": "0.25.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.3.tgz",
+ "integrity": "sha512-ZC4jV2p7VbzTlnl8nZKLcBkfzIf4Yad1SJM4ZMKYnJqZFD4rTI+pBG65u8ev4jk3/MPwY9DvGn50wi3uhdaghg==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-riscv64": {
+ "version": "0.25.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.3.tgz",
+ "integrity": "sha512-LDDODcFzNtECTrUUbVCs6j9/bDVqy7DDRsuIXJg6so+mFksgwG7ZVnTruYi5V+z3eE5y+BJZw7VvUadkbfg7QA==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-s390x": {
+ "version": "0.25.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.3.tgz",
+ "integrity": "sha512-s+w/NOY2k0yC2p9SLen+ymflgcpRkvwwa02fqmAwhBRI3SC12uiS10edHHXlVWwfAagYSY5UpmT/zISXPMW3tQ==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-x64": {
+ "version": "0.25.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.3.tgz",
+ "integrity": "sha512-nQHDz4pXjSDC6UfOE1Fw9Q8d6GCAd9KdvMZpfVGWSJztYCarRgSDfOVBY5xwhQXseiyxapkiSJi/5/ja8mRFFA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/netbsd-arm64": {
+ "version": "0.25.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.3.tgz",
+ "integrity": "sha512-1QaLtOWq0mzK6tzzp0jRN3eccmN3hezey7mhLnzC6oNlJoUJz4nym5ZD7mDnS/LZQgkrhEbEiTn515lPeLpgWA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/netbsd-x64": {
+ "version": "0.25.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.3.tgz",
+ "integrity": "sha512-i5Hm68HXHdgv8wkrt+10Bc50zM0/eonPb/a/OFVfB6Qvpiirco5gBA5bz7S2SHuU+Y4LWn/zehzNX14Sp4r27g==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openbsd-arm64": {
+ "version": "0.25.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.3.tgz",
+ "integrity": "sha512-zGAVApJEYTbOC6H/3QBr2mq3upG/LBEXr85/pTtKiv2IXcgKV0RT0QA/hSXZqSvLEpXeIxah7LczB4lkiYhTAQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openbsd-x64": {
+ "version": "0.25.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.3.tgz",
+ "integrity": "sha512-fpqctI45NnCIDKBH5AXQBsD0NDPbEFczK98hk/aa6HJxbl+UtLkJV2+Bvy5hLSLk3LHmqt0NTkKNso1A9y1a4w==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/sunos-x64": {
+ "version": "0.25.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.3.tgz",
+ "integrity": "sha512-ROJhm7d8bk9dMCUZjkS8fgzsPAZEjtRJqCAmVgB0gMrvG7hfmPmz9k1rwO4jSiblFjYmNvbECL9uhaPzONMfgA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-arm64": {
+ "version": "0.25.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.3.tgz",
+ "integrity": "sha512-YWcow8peiHpNBiIXHwaswPnAXLsLVygFwCB3A7Bh5jRkIBFWHGmNQ48AlX4xDvQNoMZlPYzjVOQDYEzWCqufMQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-ia32": {
+ "version": "0.25.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.3.tgz",
+ "integrity": "sha512-qspTZOIGoXVS4DpNqUYUs9UxVb04khS1Degaw/MnfMe7goQ3lTfQ13Vw4qY/Nj0979BGvMRpAYbs/BAxEvU8ew==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-x64": {
+ "version": "0.25.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.3.tgz",
+ "integrity": "sha512-ICgUR+kPimx0vvRzf+N/7L7tVSQeE3BYY+NhHRHXS1kBuPO7z2+7ea2HbhDyZdTephgvNvKrlDDKUexuCVBVvg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@eslint-community/eslint-utils": {
+ "version": "4.6.1",
+ "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.6.1.tgz",
+ "integrity": "sha512-KTsJMmobmbrFLe3LDh0PC2FXpcSYJt/MLjlkh/9LEnmKYLSYmT/0EW9JWANjeoemiuZrmogti0tW5Ch+qNUYDw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "eslint-visitor-keys": "^3.4.3"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
+ }
+ },
+ "node_modules/@eslint-community/regexpp": {
+ "version": "4.12.1",
+ "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz",
+ "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
+ }
+ },
+ "node_modules/@eslint/config-array": {
+ "version": "0.20.0",
+ "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.20.0.tgz",
+ "integrity": "sha512-fxlS1kkIjx8+vy2SjuCB94q3htSNrufYTXubwiBFeaQHbH6Ipi43gFJq2zCMt6PHhImH3Xmr0NksKDvchWlpQQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@eslint/object-schema": "^2.1.6",
+ "debug": "^4.3.1",
+ "minimatch": "^3.1.2"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/config-array/node_modules/brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/@eslint/config-array/node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/@eslint/config-helpers": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.2.1.tgz",
+ "integrity": "sha512-RI17tsD2frtDu/3dmI7QRrD4bedNKPM08ziRYaC5AhkGrzIAJelm9kJU1TznK+apx6V+cqRz8tfpEeG3oIyjxw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/core": {
+ "version": "0.13.0",
+ "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.13.0.tgz",
+ "integrity": "sha512-yfkgDw1KR66rkT5A8ci4irzDysN7FRpq3ttJolR88OqQikAWqwA8j5VZyas+vjyBNFIJ7MfybJ9plMILI2UrCw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@types/json-schema": "^7.0.15"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/eslintrc": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz",
+ "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ajv": "^6.12.4",
+ "debug": "^4.3.2",
+ "espree": "^10.0.1",
+ "globals": "^14.0.0",
+ "ignore": "^5.2.0",
+ "import-fresh": "^3.2.1",
+ "js-yaml": "^4.1.0",
+ "minimatch": "^3.1.2",
+ "strip-json-comments": "^3.1.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/@eslint/eslintrc/node_modules/brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/@eslint/eslintrc/node_modules/globals": {
+ "version": "14.0.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz",
+ "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@eslint/eslintrc/node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/@eslint/js": {
+ "version": "9.25.1",
+ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.25.1.tgz",
+ "integrity": "sha512-dEIwmjntEx8u3Uvv+kr3PDeeArL8Hw07H9kyYxCjnM9pBjfEhk6uLXSchxxzgiwtRhhzVzqmUSDFBOi1TuZ7qg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/object-schema": {
+ "version": "2.1.6",
+ "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz",
+ "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/plugin-kit": {
+ "version": "0.2.8",
+ "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.8.tgz",
+ "integrity": "sha512-ZAoA40rNMPwSm+AeHpCq8STiNAwzWLJuP8Xv4CHIc9wv/PSuExjMrmjfYNj682vW0OOiZ1HKxzvjQr9XZIisQA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@eslint/core": "^0.13.0",
+ "levn": "^0.4.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@floating-ui/core": {
+ "version": "1.6.9",
+ "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.9.tgz",
+ "integrity": "sha512-uMXCuQ3BItDUbAMhIXw7UPXRfAlOAvZzdK9BWpE60MCn+Svt3aLn9jsPTi/WNGlRUu2uI0v5S7JiIUsbsvh3fw==",
+ "license": "MIT",
+ "dependencies": {
+ "@floating-ui/utils": "^0.2.9"
+ }
+ },
+ "node_modules/@floating-ui/dom": {
+ "version": "1.6.13",
+ "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.13.tgz",
+ "integrity": "sha512-umqzocjDgNRGTuO7Q8CU32dkHkECqI8ZdMZ5Swb6QAM0t5rnlrN3lGo1hdpscRd3WS8T6DKYK4ephgIH9iRh3w==",
+ "license": "MIT",
+ "dependencies": {
+ "@floating-ui/core": "^1.6.0",
+ "@floating-ui/utils": "^0.2.9"
+ }
+ },
+ "node_modules/@floating-ui/react": {
+ "version": "0.26.28",
+ "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.26.28.tgz",
+ "integrity": "sha512-yORQuuAtVpiRjpMhdc0wJj06b9JFjrYF4qp96j++v2NBpbi6SEGF7donUJ3TMieerQ6qVkAv1tgr7L4r5roTqw==",
+ "license": "MIT",
+ "dependencies": {
+ "@floating-ui/react-dom": "^2.1.2",
+ "@floating-ui/utils": "^0.2.8",
+ "tabbable": "^6.0.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.8.0",
+ "react-dom": ">=16.8.0"
+ }
+ },
+ "node_modules/@floating-ui/react-dom": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.2.tgz",
+ "integrity": "sha512-06okr5cgPzMNBy+Ycse2A6udMi4bqwW/zgBF/rwjcNqWkyr82Mcg8b0vjX8OJpZFy/FKjJmw6wV7t44kK6kW7A==",
+ "license": "MIT",
+ "dependencies": {
+ "@floating-ui/dom": "^1.0.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.8.0",
+ "react-dom": ">=16.8.0"
+ }
+ },
+ "node_modules/@floating-ui/utils": {
+ "version": "0.2.9",
+ "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.9.tgz",
+ "integrity": "sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==",
+ "license": "MIT"
+ },
+ "node_modules/@hookform/resolvers": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/@hookform/resolvers/-/resolvers-5.0.1.tgz",
+ "integrity": "sha512-u/+Jp83luQNx9AdyW2fIPGY6Y7NG68eN2ZW8FOJYL+M0i4s49+refdJdOp/A9n9HFQtQs3HIDHQvX3ZET2o7YA==",
+ "license": "MIT",
+ "dependencies": {
+ "@standard-schema/utils": "^0.3.0"
+ },
+ "peerDependencies": {
+ "react-hook-form": "^7.55.0"
+ }
+ },
+ "node_modules/@humanfs/core": {
+ "version": "0.19.1",
+ "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz",
+ "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=18.18.0"
+ }
+ },
+ "node_modules/@humanfs/node": {
+ "version": "0.16.6",
+ "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz",
+ "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@humanfs/core": "^0.19.1",
+ "@humanwhocodes/retry": "^0.3.0"
+ },
+ "engines": {
+ "node": ">=18.18.0"
+ }
+ },
+ "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz",
+ "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=18.18"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
+ }
+ },
+ "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.2",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.2.tgz",
+ "integrity": "sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=18.18"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
+ }
+ },
+ "node_modules/@isaacs/cliui": {
+ "version": "8.0.2",
+ "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
+ "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "string-width": "^5.1.2",
+ "string-width-cjs": "npm:string-width@^4.2.0",
+ "strip-ansi": "^7.0.1",
+ "strip-ansi-cjs": "npm:strip-ansi@^6.0.1",
+ "wrap-ansi": "^8.1.0",
+ "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@isaacs/cliui/node_modules/ansi-styles": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
+ "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/@isaacs/cliui/node_modules/string-width": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
+ "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "eastasianwidth": "^0.2.0",
+ "emoji-regex": "^9.2.2",
+ "strip-ansi": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@isaacs/cliui/node_modules/wrap-ansi": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
+ "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^6.1.0",
+ "string-width": "^5.0.1",
+ "strip-ansi": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/@istanbuljs/schema": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz",
+ "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@jridgewell/gen-mapping": {
+ "version": "0.3.8",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz",
+ "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/set-array": "^1.2.1",
+ "@jridgewell/sourcemap-codec": "^1.4.10",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "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/set-array": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
+ "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
+ "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.25",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
+ "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/resolve-uri": "^3.1.0",
+ "@jridgewell/sourcemap-codec": "^1.4.14"
+ }
+ },
+ "node_modules/@mantine/carousel": {
+ "version": "7.17.5",
+ "resolved": "https://registry.npmjs.org/@mantine/carousel/-/carousel-7.17.5.tgz",
+ "integrity": "sha512-hyBLyZNoXdXn6/JzLqJ9dmRXp/6TXYRO3QpwHBmyDPoF/oeW+qDlsVyk2RWjWwWehkfKuR2tkDV6bv7ykMlDOA==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@mantine/core": "7.17.5",
+ "@mantine/hooks": "7.17.5",
+ "embla-carousel-react": ">=7.0.0",
+ "react": "^18.x || ^19.x",
+ "react-dom": "^18.x || ^19.x"
+ }
+ },
+ "node_modules/@mantine/core": {
+ "version": "7.17.5",
+ "resolved": "https://registry.npmjs.org/@mantine/core/-/core-7.17.5.tgz",
+ "integrity": "sha512-66g/lr281cDPfucjtPw8gFo/yNS9G5iSKqysvPGuDpUBG2bEw8FsJMIsU0bMXtravToIpa3vJRrFUuPndPGnpQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@floating-ui/react": "^0.26.28",
+ "clsx": "^2.1.1",
+ "react-number-format": "^5.4.3",
+ "react-remove-scroll": "^2.6.2",
+ "react-textarea-autosize": "8.5.9",
+ "type-fest": "^4.27.0"
+ },
+ "peerDependencies": {
+ "@mantine/hooks": "7.17.5",
+ "react": "^18.x || ^19.x",
+ "react-dom": "^18.x || ^19.x"
+ }
+ },
+ "node_modules/@mantine/dates": {
+ "version": "7.17.5",
+ "resolved": "https://registry.npmjs.org/@mantine/dates/-/dates-7.17.5.tgz",
+ "integrity": "sha512-8/Qjjb9159rQhxtuHLukNfo3/AEGl7SVSRESN8MkfyP8MCQ7mgm9wqvMADb/9Q75boUA0HIN2pewlzlcd31MHQ==",
+ "license": "MIT",
+ "dependencies": {
+ "clsx": "^2.1.1"
+ },
+ "peerDependencies": {
+ "@mantine/core": "7.17.5",
+ "@mantine/hooks": "7.17.5",
+ "dayjs": ">=1.0.0",
+ "react": "^18.x || ^19.x",
+ "react-dom": "^18.x || ^19.x"
+ }
+ },
+ "node_modules/@mantine/form": {
+ "version": "7.17.5",
+ "resolved": "https://registry.npmjs.org/@mantine/form/-/form-7.17.5.tgz",
+ "integrity": "sha512-24xkjs8486uOoevymHx2xgZ69j8mM9EG01LMOOMmEHV2k+0HwrCvwPL/2ISCnzWfHZBSwrq9ZTw7KZ6HPnU0nQ==",
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.3",
+ "klona": "^2.0.6"
+ },
+ "peerDependencies": {
+ "react": "^18.x || ^19.x"
+ }
+ },
+ "node_modules/@mantine/hooks": {
+ "version": "7.17.5",
+ "resolved": "https://registry.npmjs.org/@mantine/hooks/-/hooks-7.17.5.tgz",
+ "integrity": "sha512-Q/3AHI1fjl+W7xQ3jEoMmSoTxLqxMI2gPfxIjd73OPmRpPenYWR1zk/diirXXm2t7JOrAbmpA3/O1gzmgqzc/Q==",
+ "license": "MIT",
+ "peerDependencies": {
+ "react": "^18.x || ^19.x"
+ }
+ },
+ "node_modules/@mantine/notifications": {
+ "version": "7.17.5",
+ "resolved": "https://registry.npmjs.org/@mantine/notifications/-/notifications-7.17.5.tgz",
+ "integrity": "sha512-dLbrSm7ct97fb0Yv8ImVj9mVNkjnD/xkDCP1PANt/shM9xDh0TguqQTvborb+8Wxh1g+RtWVML/an5rVsHbKmg==",
+ "license": "MIT",
+ "dependencies": {
+ "@mantine/store": "7.17.5",
+ "react-transition-group": "4.4.5"
+ },
+ "peerDependencies": {
+ "@mantine/core": "7.17.5",
+ "@mantine/hooks": "7.17.5",
+ "react": "^18.x || ^19.x",
+ "react-dom": "^18.x || ^19.x"
+ }
+ },
+ "node_modules/@mantine/store": {
+ "version": "7.17.5",
+ "resolved": "https://registry.npmjs.org/@mantine/store/-/store-7.17.5.tgz",
+ "integrity": "sha512-HQzy4rBlUFyw+39TgiAV+TGuQivMWYeQlnMctKJlaxwVY5ZTdF2IpJ/JZcjkGrmrZvBwUQ8IOMFvt2eZc20P1Q==",
+ "license": "MIT",
+ "peerDependencies": {
+ "react": "^18.x || ^19.x"
+ }
+ },
+ "node_modules/@napi-rs/wasm-runtime": {
+ "version": "0.2.9",
+ "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.9.tgz",
+ "integrity": "sha512-OKRBiajrrxB9ATokgEQoG87Z25c67pCpYcCwmXYX8PBftC9pBfN18gnm/fh1wurSLEKIAt+QRFLFCQISrb66Jg==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@emnapi/core": "^1.4.0",
+ "@emnapi/runtime": "^1.4.0",
+ "@tybys/wasm-util": "^0.9.0"
+ }
+ },
+ "node_modules/@nodelib/fs.scandir": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
+ "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.stat": "2.0.5",
+ "run-parallel": "^1.1.9"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.stat": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
+ "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.walk": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+ "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.scandir": "2.1.5",
+ "fastq": "^1.6.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@pkgjs/parseargs": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
+ "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/@pkgr/core": {
+ "version": "0.2.4",
+ "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.4.tgz",
+ "integrity": "sha512-ROFF39F6ZrnzSUEmQQZUar0Jt4xVoP9WnDRdWwF4NNcXs3xBTLgBUDoOwW141y1jP+S8nahIbdxbFC7IShw9Iw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.20.0 || ^14.18.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/pkgr"
+ }
+ },
+ "node_modules/@rollup/rollup-android-arm-eabi": {
+ "version": "4.40.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.40.0.tgz",
+ "integrity": "sha512-+Fbls/diZ0RDerhE8kyC6hjADCXA1K4yVNlH0EYfd2XjyH0UGgzaQ8MlT0pCXAThfxv3QUAczHaL+qSv1E4/Cg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-android-arm64": {
+ "version": "4.40.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.40.0.tgz",
+ "integrity": "sha512-PPA6aEEsTPRz+/4xxAmaoWDqh67N7wFbgFUJGMnanCFs0TV99M0M8QhhaSCks+n6EbQoFvLQgYOGXxlMGQe/6w==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-arm64": {
+ "version": "4.40.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.40.0.tgz",
+ "integrity": "sha512-GwYOcOakYHdfnjjKwqpTGgn5a6cUX7+Ra2HeNj/GdXvO2VJOOXCiYYlRFU4CubFM67EhbmzLOmACKEfvp3J1kQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-x64": {
+ "version": "4.40.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.40.0.tgz",
+ "integrity": "sha512-CoLEGJ+2eheqD9KBSxmma6ld01czS52Iw0e2qMZNpPDlf7Z9mj8xmMemxEucinev4LgHalDPczMyxzbq+Q+EtA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-freebsd-arm64": {
+ "version": "4.40.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.40.0.tgz",
+ "integrity": "sha512-r7yGiS4HN/kibvESzmrOB/PxKMhPTlz+FcGvoUIKYoTyGd5toHp48g1uZy1o1xQvybwwpqpe010JrcGG2s5nkg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-freebsd-x64": {
+ "version": "4.40.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.40.0.tgz",
+ "integrity": "sha512-mVDxzlf0oLzV3oZOr0SMJ0lSDd3xC4CmnWJ8Val8isp9jRGl5Dq//LLDSPFrasS7pSm6m5xAcKaw3sHXhBjoRw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
+ "version": "4.40.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.40.0.tgz",
+ "integrity": "sha512-y/qUMOpJxBMy8xCXD++jeu8t7kzjlOCkoxxajL58G62PJGBZVl/Gwpm7JK9+YvlB701rcQTzjUZ1JgUoPTnoQA==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-musleabihf": {
+ "version": "4.40.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.40.0.tgz",
+ "integrity": "sha512-GoCsPibtVdJFPv/BOIvBKO/XmwZLwaNWdyD8TKlXuqp0veo2sHE+A/vpMQ5iSArRUz/uaoj4h5S6Pn0+PdhRjg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-gnu": {
+ "version": "4.40.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.40.0.tgz",
+ "integrity": "sha512-L5ZLphTjjAD9leJzSLI7rr8fNqJMlGDKlazW2tX4IUF9P7R5TMQPElpH82Q7eNIDQnQlAyiNVfRPfP2vM5Avvg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-musl": {
+ "version": "4.40.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.40.0.tgz",
+ "integrity": "sha512-ATZvCRGCDtv1Y4gpDIXsS+wfFeFuLwVxyUBSLawjgXK2tRE6fnsQEkE4csQQYWlBlsFztRzCnBvWVfcae/1qxQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-loongarch64-gnu": {
+ "version": "4.40.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.40.0.tgz",
+ "integrity": "sha512-wG9e2XtIhd++QugU5MD9i7OnpaVb08ji3P1y/hNbxrQ3sYEelKJOq1UJ5dXczeo6Hj2rfDEL5GdtkMSVLa/AOg==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
+ "version": "4.40.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.40.0.tgz",
+ "integrity": "sha512-vgXfWmj0f3jAUvC7TZSU/m/cOE558ILWDzS7jBhiCAFpY2WEBn5jqgbqvmzlMjtp8KlLcBlXVD2mkTSEQE6Ixw==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-gnu": {
+ "version": "4.40.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.40.0.tgz",
+ "integrity": "sha512-uJkYTugqtPZBS3Z136arevt/FsKTF/J9dEMTX/cwR7lsAW4bShzI2R0pJVw+hcBTWF4dxVckYh72Hk3/hWNKvA==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-musl": {
+ "version": "4.40.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.40.0.tgz",
+ "integrity": "sha512-rKmSj6EXQRnhSkE22+WvrqOqRtk733x3p5sWpZilhmjnkHkpeCgWsFFo0dGnUGeA+OZjRl3+VYq+HyCOEuwcxQ==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-s390x-gnu": {
+ "version": "4.40.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.40.0.tgz",
+ "integrity": "sha512-SpnYlAfKPOoVsQqmTFJ0usx0z84bzGOS9anAC0AZ3rdSo3snecihbhFTlJZ8XMwzqAcodjFU4+/SM311dqE5Sw==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-gnu": {
+ "version": "4.40.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.40.0.tgz",
+ "integrity": "sha512-RcDGMtqF9EFN8i2RYN2W+64CdHruJ5rPqrlYw+cgM3uOVPSsnAQps7cpjXe9be/yDp8UC7VLoCoKC8J3Kn2FkQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-musl": {
+ "version": "4.40.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.40.0.tgz",
+ "integrity": "sha512-HZvjpiUmSNx5zFgwtQAV1GaGazT2RWvqeDi0hV+AtC8unqqDSsaFjPxfsO6qPtKRRg25SisACWnJ37Yio8ttaw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-arm64-msvc": {
+ "version": "4.40.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.40.0.tgz",
+ "integrity": "sha512-UtZQQI5k/b8d7d3i9AZmA/t+Q4tk3hOC0tMOMSq2GlMYOfxbesxG4mJSeDp0EHs30N9bsfwUvs3zF4v/RzOeTQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-ia32-msvc": {
+ "version": "4.40.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.40.0.tgz",
+ "integrity": "sha512-+m03kvI2f5syIqHXCZLPVYplP8pQch9JHyXKZ3AGMKlg8dCyr2PKHjwRLiW53LTrN/Nc3EqHOKxUxzoSPdKddA==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-x64-msvc": {
+ "version": "4.40.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.40.0.tgz",
+ "integrity": "sha512-lpPE1cLfP5oPzVjKMx10pgBmKELQnFJXHgvtHCtuJWOv8MxqdEIMNtgHgBFf7Ea2/7EuVwa9fodWUfXAlXZLZQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rtsao/scc": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz",
+ "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@standard-schema/utils": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/@standard-schema/utils/-/utils-0.3.0.tgz",
+ "integrity": "sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==",
+ "license": "MIT"
+ },
+ "node_modules/@testing-library/dom": {
+ "version": "10.4.0",
+ "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.0.tgz",
+ "integrity": "sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.10.4",
+ "@babel/runtime": "^7.12.5",
+ "@types/aria-query": "^5.0.1",
+ "aria-query": "5.3.0",
+ "chalk": "^4.1.0",
+ "dom-accessibility-api": "^0.5.9",
+ "lz-string": "^1.5.0",
+ "pretty-format": "^27.0.2"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@testing-library/dom/node_modules/aria-query": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz",
+ "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "peer": true,
+ "dependencies": {
+ "dequal": "^2.0.3"
+ }
+ },
+ "node_modules/@testing-library/jest-dom": {
+ "version": "6.6.3",
+ "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.6.3.tgz",
+ "integrity": "sha512-IteBhl4XqYNkM54f4ejhLRJiZNqcSCoXUOG2CPK7qbD322KjQozM4kHQOfkG2oln9b9HTYqs+Sae8vBATubxxA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@adobe/css-tools": "^4.4.0",
+ "aria-query": "^5.0.0",
+ "chalk": "^3.0.0",
+ "css.escape": "^1.5.1",
+ "dom-accessibility-api": "^0.6.3",
+ "lodash": "^4.17.21",
+ "redent": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=14",
+ "npm": ">=6",
+ "yarn": ">=1"
+ }
+ },
+ "node_modules/@testing-library/jest-dom/node_modules/chalk": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+ "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@testing-library/jest-dom/node_modules/dom-accessibility-api": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz",
+ "integrity": "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@testing-library/react": {
+ "version": "16.3.0",
+ "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-16.3.0.tgz",
+ "integrity": "sha512-kFSyxiEDwv1WLl2fgsq6pPBbw5aWKrsY2/noi1Id0TK0UParSF62oFQFGHXIyaG4pp2tEub/Zlel+fjjZILDsw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.12.5"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "@testing-library/dom": "^10.0.0",
+ "@types/react": "^18.0.0 || ^19.0.0",
+ "@types/react-dom": "^18.0.0 || ^19.0.0",
+ "react": "^18.0.0 || ^19.0.0",
+ "react-dom": "^18.0.0 || ^19.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@testing-library/user-event": {
+ "version": "14.6.1",
+ "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.6.1.tgz",
+ "integrity": "sha512-vq7fv0rnt+QTXgPxr5Hjc210p6YKq2kmdziLgnsZGgLJ9e6VAShx1pACLuRjd/AS/sr7phAR58OIIpf0LlmQNw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12",
+ "npm": ">=6"
+ },
+ "peerDependencies": {
+ "@testing-library/dom": ">=7.21.4"
+ }
+ },
+ "node_modules/@tybys/wasm-util": {
+ "version": "0.9.0",
+ "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.9.0.tgz",
+ "integrity": "sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@types/aria-query": {
+ "version": "5.0.4",
+ "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz",
+ "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/@types/babel__core": {
+ "version": "7.20.5",
+ "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
+ "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.20.7",
+ "@babel/types": "^7.20.7",
+ "@types/babel__generator": "*",
+ "@types/babel__template": "*",
+ "@types/babel__traverse": "*"
+ }
+ },
+ "node_modules/@types/babel__generator": {
+ "version": "7.27.0",
+ "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz",
+ "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.0.0"
+ }
+ },
+ "node_modules/@types/babel__template": {
+ "version": "7.4.4",
+ "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz",
+ "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.1.0",
+ "@babel/types": "^7.0.0"
+ }
+ },
+ "node_modules/@types/babel__traverse": {
+ "version": "7.20.7",
+ "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.7.tgz",
+ "integrity": "sha512-dkO5fhS7+/oos4ciWxyEyjWe48zmG6wbCheo/G2ZnHx4fs3EU6YC6UM8rk56gAjNJ9P3MTH2jo5jb92/K6wbng==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.20.7"
+ }
+ },
+ "node_modules/@types/conventional-commits-parser": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/@types/conventional-commits-parser/-/conventional-commits-parser-5.0.1.tgz",
+ "integrity": "sha512-7uz5EHdzz2TqoMfV7ee61Egf5y6NkcO4FB/1iCCQnbeiI1F3xzv3vK5dBCXUCLQgGYS+mUeigK1iKQzvED+QnQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/estree": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz",
+ "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/isomorphic-fetch": {
+ "version": "0.0.39",
+ "resolved": "https://registry.npmjs.org/@types/isomorphic-fetch/-/isomorphic-fetch-0.0.39.tgz",
+ "integrity": "sha512-I0gou/ZdA1vMG7t7gMzL7VYu2xAKU78rW9U1l10MI0nn77pEHq3tQqHQ8hMmXdMpBlkxZOorjI4sO594Z3kKJw==",
+ "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/json5": {
+ "version": "0.0.29",
+ "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
+ "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/node": {
+ "version": "22.15.2",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.2.tgz",
+ "integrity": "sha512-uKXqKN9beGoMdBfcaTY1ecwz6ctxuJAcUlwE55938g0ZJ8lRxwAZqRz2AJ4pzpt5dHdTPMB863UZ0ESiFUcP7A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "undici-types": "~6.21.0"
+ }
+ },
+ "node_modules/@types/react": {
+ "version": "19.1.2",
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.2.tgz",
+ "integrity": "sha512-oxLPMytKchWGbnQM9O7D67uPa9paTNxO7jVoNMXgkkErULBPhPARCfkKL9ytcIJJRGjbsVwW4ugJzyFFvm/Tiw==",
+ "devOptional": true,
+ "license": "MIT",
+ "dependencies": {
+ "csstype": "^3.0.2"
+ }
+ },
+ "node_modules/@types/react-dom": {
+ "version": "19.1.2",
+ "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.1.2.tgz",
+ "integrity": "sha512-XGJkWF41Qq305SKWEILa1O8vzhb3aOo3ogBlSmiqNko/WmRb6QIaweuZCXjKygVDXpzXb5wyxKTSOsmkuqj+Qw==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "^19.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/eslint-plugin": {
+ "version": "8.31.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.31.0.tgz",
+ "integrity": "sha512-evaQJZ/J/S4wisevDvC1KFZkPzRetH8kYZbkgcTRyql3mcKsf+ZFDV1BVWUGTCAW5pQHoqn5gK5b8kn7ou9aFQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/regexpp": "^4.10.0",
+ "@typescript-eslint/scope-manager": "8.31.0",
+ "@typescript-eslint/type-utils": "8.31.0",
+ "@typescript-eslint/utils": "8.31.0",
+ "@typescript-eslint/visitor-keys": "8.31.0",
+ "graphemer": "^1.4.0",
+ "ignore": "^5.3.1",
+ "natural-compare": "^1.4.0",
+ "ts-api-utils": "^2.0.1"
+ },
+ "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.0.0 || ^8.0.0-alpha.0",
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <5.9.0"
+ }
+ },
+ "node_modules/@typescript-eslint/parser": {
+ "version": "8.31.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.31.0.tgz",
+ "integrity": "sha512-67kYYShjBR0jNI5vsf/c3WG4u+zDnCTHTPqVMQguffaWWFs7artgwKmfwdifl+r6XyM5LYLas/dInj2T0SgJyw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/scope-manager": "8.31.0",
+ "@typescript-eslint/types": "8.31.0",
+ "@typescript-eslint/typescript-estree": "8.31.0",
+ "@typescript-eslint/visitor-keys": "8.31.0",
+ "debug": "^4.3.4"
+ },
+ "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",
+ "typescript": ">=4.8.4 <5.9.0"
+ }
+ },
+ "node_modules/@typescript-eslint/scope-manager": {
+ "version": "8.31.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.31.0.tgz",
+ "integrity": "sha512-knO8UyF78Nt8O/B64i7TlGXod69ko7z6vJD9uhSlm0qkAbGeRUSudcm0+K/4CrRjrpiHfBCjMWlc08Vav1xwcw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/types": "8.31.0",
+ "@typescript-eslint/visitor-keys": "8.31.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/type-utils": {
+ "version": "8.31.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.31.0.tgz",
+ "integrity": "sha512-DJ1N1GdjI7IS7uRlzJuEDCgDQix3ZVYVtgeWEyhyn4iaoitpMBX6Ndd488mXSx0xah/cONAkEaYyylDyAeHMHg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/typescript-estree": "8.31.0",
+ "@typescript-eslint/utils": "8.31.0",
+ "debug": "^4.3.4",
+ "ts-api-utils": "^2.0.1"
+ },
+ "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",
+ "typescript": ">=4.8.4 <5.9.0"
+ }
+ },
+ "node_modules/@typescript-eslint/types": {
+ "version": "8.31.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.31.0.tgz",
+ "integrity": "sha512-Ch8oSjVyYyJxPQk8pMiP2FFGYatqXQfQIaMp+TpuuLlDachRWpUAeEu1u9B/v/8LToehUIWyiKcA/w5hUFRKuQ==",
+ "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.31.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.31.0.tgz",
+ "integrity": "sha512-xLmgn4Yl46xi6aDSZ9KkyfhhtnYI15/CvHbpOy/eR5NWhK/BK8wc709KKwhAR0m4ZKRP7h07bm4BWUYOCuRpQQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/types": "8.31.0",
+ "@typescript-eslint/visitor-keys": "8.31.0",
+ "debug": "^4.3.4",
+ "fast-glob": "^3.3.2",
+ "is-glob": "^4.0.3",
+ "minimatch": "^9.0.4",
+ "semver": "^7.6.0",
+ "ts-api-utils": "^2.0.1"
+ },
+ "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 <5.9.0"
+ }
+ },
+ "node_modules/@typescript-eslint/utils": {
+ "version": "8.31.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.31.0.tgz",
+ "integrity": "sha512-qi6uPLt9cjTFxAb1zGNgTob4x9ur7xC6mHQJ8GwEzGMGE9tYniublmJaowOJ9V2jUzxrltTPfdG2nKlWsq0+Ww==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.4.0",
+ "@typescript-eslint/scope-manager": "8.31.0",
+ "@typescript-eslint/types": "8.31.0",
+ "@typescript-eslint/typescript-estree": "8.31.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",
+ "typescript": ">=4.8.4 <5.9.0"
+ }
+ },
+ "node_modules/@typescript-eslint/visitor-keys": {
+ "version": "8.31.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.31.0.tgz",
+ "integrity": "sha512-QcGHmlRHWOl93o64ZUMNewCdwKGU6WItOU52H0djgNmn1EOrhVudrDzXz4OycCRSCPwFCDrE2iIt5vmuUdHxuQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/types": "8.31.0",
+ "eslint-visitor-keys": "^4.2.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz",
+ "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/@unrs/resolver-binding-darwin-arm64": {
+ "version": "1.7.2",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.7.2.tgz",
+ "integrity": "sha512-vxtBno4xvowwNmO/ASL0Y45TpHqmNkAaDtz4Jqb+clmcVSSl8XCG/PNFFkGsXXXS6AMjP+ja/TtNCFFa1QwLRg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-darwin-x64": {
+ "version": "1.7.2",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.7.2.tgz",
+ "integrity": "sha512-qhVa8ozu92C23Hsmv0BF4+5Dyyd5STT1FolV4whNgbY6mj3kA0qsrGPe35zNR3wAN7eFict3s4Rc2dDTPBTuFQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-freebsd-x64": {
+ "version": "1.7.2",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.7.2.tgz",
+ "integrity": "sha512-zKKdm2uMXqLFX6Ac7K5ElnnG5VIXbDlFWzg4WJ8CGUedJryM5A3cTgHuGMw1+P5ziV8CRhnSEgOnurTI4vpHpg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-linux-arm-gnueabihf": {
+ "version": "1.7.2",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.7.2.tgz",
+ "integrity": "sha512-8N1z1TbPnHH+iDS/42GJ0bMPLiGK+cUqOhNbMKtWJ4oFGzqSJk/zoXFzcQkgtI63qMcUI7wW1tq2usZQSb2jxw==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-linux-arm-musleabihf": {
+ "version": "1.7.2",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.7.2.tgz",
+ "integrity": "sha512-tjYzI9LcAXR9MYd9rO45m1s0B/6bJNuZ6jeOxo1pq1K6OBuRMMmfyvJYval3s9FPPGmrldYA3mi4gWDlWuTFGA==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-linux-arm64-gnu": {
+ "version": "1.7.2",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.7.2.tgz",
+ "integrity": "sha512-jon9M7DKRLGZ9VYSkFMflvNqu9hDtOCEnO2QAryFWgT6o6AXU8du56V7YqnaLKr6rAbZBWYsYpikF226v423QA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-linux-arm64-musl": {
+ "version": "1.7.2",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.7.2.tgz",
+ "integrity": "sha512-c8Cg4/h+kQ63pL43wBNaVMmOjXI/X62wQmru51qjfTvI7kmCy5uHTJvK/9LrF0G8Jdx8r34d019P1DVJmhXQpA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-linux-ppc64-gnu": {
+ "version": "1.7.2",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.7.2.tgz",
+ "integrity": "sha512-A+lcwRFyrjeJmv3JJvhz5NbcCkLQL6Mk16kHTNm6/aGNc4FwPHPE4DR9DwuCvCnVHvF5IAd9U4VIs/VvVir5lg==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-linux-riscv64-gnu": {
+ "version": "1.7.2",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.7.2.tgz",
+ "integrity": "sha512-hQQ4TJQrSQW8JlPm7tRpXN8OCNP9ez7PajJNjRD1ZTHQAy685OYqPrKjfaMw/8LiHCt8AZ74rfUVHP9vn0N69Q==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-linux-riscv64-musl": {
+ "version": "1.7.2",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.7.2.tgz",
+ "integrity": "sha512-NoAGbiqrxtY8kVooZ24i70CjLDlUFI7nDj3I9y54U94p+3kPxwd2L692YsdLa+cqQ0VoqMWoehDFp21PKRUoIQ==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-linux-s390x-gnu": {
+ "version": "1.7.2",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.7.2.tgz",
+ "integrity": "sha512-KaZByo8xuQZbUhhreBTW+yUnOIHUsv04P8lKjQ5otiGoSJ17ISGYArc+4vKdLEpGaLbemGzr4ZeUbYQQsLWFjA==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-linux-x64-gnu": {
+ "version": "1.7.2",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.7.2.tgz",
+ "integrity": "sha512-dEidzJDubxxhUCBJ/SHSMJD/9q7JkyfBMT77Px1npl4xpg9t0POLvnWywSk66BgZS/b2Hy9Y1yFaoMTFJUe9yg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-linux-x64-musl": {
+ "version": "1.7.2",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.7.2.tgz",
+ "integrity": "sha512-RvP+Ux3wDjmnZDT4XWFfNBRVG0fMsc+yVzNFUqOflnDfZ9OYujv6nkh+GOr+watwrW4wdp6ASfG/e7bkDradsw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-wasm32-wasi": {
+ "version": "1.7.2",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.7.2.tgz",
+ "integrity": "sha512-y797JBmO9IsvXVRCKDXOxjyAE4+CcZpla2GSoBQ33TVb3ILXuFnMrbR/QQZoauBYeOFuu4w3ifWLw52sdHGz6g==",
+ "cpu": [
+ "wasm32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@napi-rs/wasm-runtime": "^0.2.9"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/@unrs/resolver-binding-win32-arm64-msvc": {
+ "version": "1.7.2",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.7.2.tgz",
+ "integrity": "sha512-gtYTh4/VREVSLA+gHrfbWxaMO/00y+34htY7XpioBTy56YN2eBjkPrY1ML1Zys89X3RJDKVaogzwxlM1qU7egg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-win32-ia32-msvc": {
+ "version": "1.7.2",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.7.2.tgz",
+ "integrity": "sha512-Ywv20XHvHTDRQs12jd3MY8X5C8KLjDbg/jyaal/QLKx3fAShhJyD4blEANInsjxW3P7isHx1Blt56iUDDJO3jg==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-win32-x64-msvc": {
+ "version": "1.7.2",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.7.2.tgz",
+ "integrity": "sha512-friS8NEQfHaDbkThxopGk+LuE5v3iY0StruifjQEt7SLbA46OnfgMO15sOTkbpJkol6RB+1l1TYPXh0sCddpvA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@vitejs/plugin-react": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.4.1.tgz",
+ "integrity": "sha512-IpEm5ZmeXAP/osiBXVVP5KjFMzbWOonMs0NaQQl+xYnUAcq4oHUBsF2+p4MgKWG4YMmFYJU8A6sxRPuowllm6w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/core": "^7.26.10",
+ "@babel/plugin-transform-react-jsx-self": "^7.25.9",
+ "@babel/plugin-transform-react-jsx-source": "^7.25.9",
+ "@types/babel__core": "^7.20.5",
+ "react-refresh": "^0.17.0"
+ },
+ "engines": {
+ "node": "^14.18.0 || >=16.0.0"
+ },
+ "peerDependencies": {
+ "vite": "^4.2.0 || ^5.0.0 || ^6.0.0"
+ }
+ },
+ "node_modules/@vitest/coverage-v8": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-3.1.2.tgz",
+ "integrity": "sha512-XDdaDOeaTMAMYW7N63AqoK32sYUWbXnTkC6tEbVcu3RlU1bB9of32T+PGf8KZvxqLNqeXhafDFqCkwpf2+dyaQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@ampproject/remapping": "^2.3.0",
+ "@bcoe/v8-coverage": "^1.0.2",
+ "debug": "^4.4.0",
+ "istanbul-lib-coverage": "^3.2.2",
+ "istanbul-lib-report": "^3.0.1",
+ "istanbul-lib-source-maps": "^5.0.6",
+ "istanbul-reports": "^3.1.7",
+ "magic-string": "^0.30.17",
+ "magicast": "^0.3.5",
+ "std-env": "^3.9.0",
+ "test-exclude": "^7.0.1",
+ "tinyrainbow": "^2.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ },
+ "peerDependencies": {
+ "@vitest/browser": "3.1.2",
+ "vitest": "3.1.2"
+ },
+ "peerDependenciesMeta": {
+ "@vitest/browser": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@vitest/expect": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.1.2.tgz",
+ "integrity": "sha512-O8hJgr+zREopCAqWl3uCVaOdqJwZ9qaDwUP7vy3Xigad0phZe9APxKhPcDNqYYi0rX5oMvwJMSCAXY2afqeTSA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vitest/spy": "3.1.2",
+ "@vitest/utils": "3.1.2",
+ "chai": "^5.2.0",
+ "tinyrainbow": "^2.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vitest/mocker": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.1.2.tgz",
+ "integrity": "sha512-kOtd6K2lc7SQ0mBqYv/wdGedlqPdM/B38paPY+OwJ1XiNi44w3Fpog82UfOibmHaV9Wod18A09I9SCKLyDMqgw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vitest/spy": "3.1.2",
+ "estree-walker": "^3.0.3",
+ "magic-string": "^0.30.17"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ },
+ "peerDependencies": {
+ "msw": "^2.4.9",
+ "vite": "^5.0.0 || ^6.0.0"
+ },
+ "peerDependenciesMeta": {
+ "msw": {
+ "optional": true
+ },
+ "vite": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@vitest/pretty-format": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.1.2.tgz",
+ "integrity": "sha512-R0xAiHuWeDjTSB3kQ3OQpT8Rx3yhdOAIm/JM4axXxnG7Q/fS8XUwggv/A4xzbQA+drYRjzkMnpYnOGAc4oeq8w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "tinyrainbow": "^2.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vitest/runner": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.1.2.tgz",
+ "integrity": "sha512-bhLib9l4xb4sUMPXnThbnhX2Yi8OutBMA8Yahxa7yavQsFDtwY/jrUZwpKp2XH9DhRFJIeytlyGpXCqZ65nR+g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vitest/utils": "3.1.2",
+ "pathe": "^2.0.3"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vitest/snapshot": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.1.2.tgz",
+ "integrity": "sha512-Q1qkpazSF/p4ApZg1vfZSQ5Yw6OCQxVMVrLjslbLFA1hMDrT2uxtqMaw8Tc/jy5DLka1sNs1Y7rBcftMiaSH/Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vitest/pretty-format": "3.1.2",
+ "magic-string": "^0.30.17",
+ "pathe": "^2.0.3"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vitest/spy": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.1.2.tgz",
+ "integrity": "sha512-OEc5fSXMws6sHVe4kOFyDSj/+4MSwst0ib4un0DlcYgQvRuYQ0+M2HyqGaauUMnjq87tmUaMNDxKQx7wNfVqPA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "tinyspy": "^3.0.2"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vitest/utils": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.1.2.tgz",
+ "integrity": "sha512-5GGd0ytZ7BH3H6JTj9Kw7Prn1Nbg0wZVrIvou+UWxm54d+WoXXgAgjFJ8wn3LdagWLFSEfpPeyYrByZaGEZHLg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vitest/pretty-format": "3.1.2",
+ "loupe": "^3.1.3",
+ "tinyrainbow": "^2.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/acorn": {
+ "version": "8.14.1",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz",
+ "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/acorn-jsx": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
+ "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ }
+ },
+ "node_modules/agent-base": {
+ "version": "7.1.3",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz",
+ "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/ajv": {
+ "version": "6.12.6",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/ansi-escapes": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.0.0.tgz",
+ "integrity": "sha512-GdYO7a61mR0fOlAsvC9/rIHf7L96sBc6dEWzeOu+KAea5bZyQRPIpojrVoI4AXGJS/ycu/fBTdLrUkA4ODrvjw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "environment": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/ansi-regex": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz",
+ "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+ }
+ },
+ "node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/argparse": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+ "dev": true,
+ "license": "Python-2.0"
+ },
+ "node_modules/aria-query": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz",
+ "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/array-buffer-byte-length": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz",
+ "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "is-array-buffer": "^3.0.5"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array-ify": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz",
+ "integrity": "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/array-includes": {
+ "version": "3.1.8",
+ "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz",
+ "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.2",
+ "es-object-atoms": "^1.0.0",
+ "get-intrinsic": "^1.2.4",
+ "is-string": "^1.0.7"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array.prototype.findlastindex": {
+ "version": "1.2.6",
+ "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.6.tgz",
+ "integrity": "sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.4",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.9",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.1.1",
+ "es-shim-unscopables": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array.prototype.flat": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz",
+ "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.5",
+ "es-shim-unscopables": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array.prototype.flatmap": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz",
+ "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.5",
+ "es-shim-unscopables": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/arraybuffer.prototype.slice": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz",
+ "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "array-buffer-byte-length": "^1.0.1",
+ "call-bind": "^1.0.8",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.5",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.6",
+ "is-array-buffer": "^3.0.4"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/assertion-error": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz",
+ "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/ast-types-flow": {
+ "version": "0.0.8",
+ "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz",
+ "integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/async-function": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz",
+ "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/available-typed-arrays": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz",
+ "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "possible-typed-array-names": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/axe-core": {
+ "version": "4.10.3",
+ "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.10.3.tgz",
+ "integrity": "sha512-Xm7bpRXnDSX2YE2YFfBk2FnF0ep6tmG7xPh8iHee8MIcrgq762Nkce856dYtJYLkuIoYZvGfTs/PbZhideTcEg==",
+ "dev": true,
+ "license": "MPL-2.0",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/axobject-query": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz",
+ "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/base64-js": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
+ "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/brace-expansion": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+ "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/braces": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
+ "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fill-range": "^7.1.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/browserslist": {
+ "version": "4.24.4",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz",
+ "integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "caniuse-lite": "^1.0.30001688",
+ "electron-to-chromium": "^1.5.73",
+ "node-releases": "^2.0.19",
+ "update-browserslist-db": "^1.1.1"
+ },
+ "bin": {
+ "browserslist": "cli.js"
+ },
+ "engines": {
+ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+ }
+ },
+ "node_modules/buffer": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
+ "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "base64-js": "^1.3.1",
+ "ieee754": "^1.2.1"
+ }
+ },
+ "node_modules/cac": {
+ "version": "6.7.14",
+ "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz",
+ "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/call-bind": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz",
+ "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.0",
+ "es-define-property": "^1.0.0",
+ "get-intrinsic": "^1.2.4",
+ "set-function-length": "^1.2.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/call-bind-apply-helpers": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
+ "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/call-bound": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
+ "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.2",
+ "get-intrinsic": "^1.3.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/caniuse-lite": {
+ "version": "1.0.30001715",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001715.tgz",
+ "integrity": "sha512-7ptkFGMm2OAOgvZpwgA4yjQ5SQbrNVGdRjzH0pBdy1Fasvcr+KAeECmbCAECzTuDuoX0FCY8KzUxjf9+9kfZEw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "CC-BY-4.0"
+ },
+ "node_modules/chai": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/chai/-/chai-5.2.0.tgz",
+ "integrity": "sha512-mCuXncKXk5iCLhfhwTc0izo0gtEmpz5CtG2y8GiOINBlMVS6v8TMRc5TaLWKS6692m9+dVVfzgeVxR5UxWHTYw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "assertion-error": "^2.0.1",
+ "check-error": "^2.1.1",
+ "deep-eql": "^5.0.1",
+ "loupe": "^3.1.0",
+ "pathval": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/check-error": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz",
+ "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 16"
+ }
+ },
+ "node_modules/cli-cursor": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz",
+ "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "restore-cursor": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/cli-truncate": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-4.0.0.tgz",
+ "integrity": "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "slice-ansi": "^5.0.0",
+ "string-width": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/cliui": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
+ "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.1",
+ "wrap-ansi": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/cliui/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cliui/node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/cliui/node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cliui/node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cliui/node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cliui/node_modules/wrap-ansi": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/clsx": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz",
+ "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/colorette": {
+ "version": "2.0.20",
+ "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz",
+ "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/commander": {
+ "version": "13.1.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-13.1.0.tgz",
+ "integrity": "sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/compare-func": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz",
+ "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "array-ify": "^1.0.0",
+ "dot-prop": "^5.1.0"
+ }
+ },
+ "node_modules/concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/conventional-changelog-angular": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-7.0.0.tgz",
+ "integrity": "sha512-ROjNchA9LgfNMTTFSIWPzebCwOGFdgkEq45EnvvrmSLvCtAw0HSmrCs7/ty+wAeYUZyNay0YMUNYFTRL72PkBQ==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "compare-func": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/conventional-changelog-conventionalcommits": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-7.0.2.tgz",
+ "integrity": "sha512-NKXYmMR/Hr1DevQegFB4MwfM5Vv0m4UIxKZTTYuD98lpTknaZlSRrDOG4X7wIXpGkfsYxZTghUN+Qq+T0YQI7w==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "compare-func": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/conventional-commits-parser": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-5.0.0.tgz",
+ "integrity": "sha512-ZPMl0ZJbw74iS9LuX9YIAiW8pfM5p3yh2o/NbXHbkFuZzY5jvdi5jFycEOkmBW5H5I7nA+D6f3UcsCLP2vvSEA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-text-path": "^2.0.0",
+ "JSONStream": "^1.3.5",
+ "meow": "^12.0.1",
+ "split2": "^4.0.0"
+ },
+ "bin": {
+ "conventional-commits-parser": "cli.mjs"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "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.0.2",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz",
+ "integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/cosmiconfig": {
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz",
+ "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "env-paths": "^2.2.1",
+ "import-fresh": "^3.3.0",
+ "js-yaml": "^4.1.0",
+ "parse-json": "^5.2.0"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/d-fischer"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.9.5"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/cosmiconfig-typescript-loader": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-6.1.0.tgz",
+ "integrity": "sha512-tJ1w35ZRUiM5FeTzT7DtYWAFFv37ZLqSRkGi2oeCK1gPhvaWjkAtfXvLmvE1pRfxxp9aQo6ba/Pvg1dKj05D4g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "jiti": "^2.4.1"
+ },
+ "engines": {
+ "node": ">=v18"
+ },
+ "peerDependencies": {
+ "@types/node": "*",
+ "cosmiconfig": ">=9",
+ "typescript": ">=5"
+ }
+ },
+ "node_modules/cross-spawn": {
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/css.escape": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz",
+ "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/cssstyle": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.3.1.tgz",
+ "integrity": "sha512-ZgW+Jgdd7i52AaLYCriF8Mxqft0gD/R9i9wi6RWBhs1pqdPEzPjym7rvRKi397WmQFf3SlyUsszhw+VVCbx79Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@asamuzakjp/css-color": "^3.1.2",
+ "rrweb-cssom": "^0.8.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/csstype": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
+ "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
+ "license": "MIT"
+ },
+ "node_modules/damerau-levenshtein": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz",
+ "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==",
+ "dev": true,
+ "license": "BSD-2-Clause"
+ },
+ "node_modules/dargs": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/dargs/-/dargs-8.1.0.tgz",
+ "integrity": "sha512-wAV9QHOsNbwnWdNW2FYvE1P56wtgSbM+3SZcdGiWQILwVjACCXDCI3Ai8QlCjMDB8YK5zySiXZYBiwGmNY3lnw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/data-uri-to-buffer": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz",
+ "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 12"
+ }
+ },
+ "node_modules/data-urls": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz",
+ "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "whatwg-mimetype": "^4.0.0",
+ "whatwg-url": "^14.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/data-view-buffer": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz",
+ "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "es-errors": "^1.3.0",
+ "is-data-view": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/data-view-byte-length": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz",
+ "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "es-errors": "^1.3.0",
+ "is-data-view": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/inspect-js"
+ }
+ },
+ "node_modules/data-view-byte-offset": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz",
+ "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "is-data-view": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/dayjs": {
+ "version": "1.11.13",
+ "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz",
+ "integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==",
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/debug": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
+ "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/decimal.js": {
+ "version": "10.5.0",
+ "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.5.0.tgz",
+ "integrity": "sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/deep-eql": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz",
+ "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/deep-is": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
+ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/define-data-property": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
+ "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-define-property": "^1.0.0",
+ "es-errors": "^1.3.0",
+ "gopd": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/define-properties": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz",
+ "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-data-property": "^1.0.1",
+ "has-property-descriptors": "^1.0.0",
+ "object-keys": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/dequal": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
+ "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/detect-node-es": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz",
+ "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==",
+ "license": "MIT"
+ },
+ "node_modules/doctrine": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
+ "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "esutils": "^2.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/dom-accessibility-api": {
+ "version": "0.5.16",
+ "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz",
+ "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/dom-helpers": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz",
+ "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.8.7",
+ "csstype": "^3.0.2"
+ }
+ },
+ "node_modules/dot-prop": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz",
+ "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-obj": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/dunder-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
+ "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "gopd": "^1.2.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/eastasianwidth": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
+ "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/electron-to-chromium": {
+ "version": "1.5.143",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.143.tgz",
+ "integrity": "sha512-QqklJMOFBMqe46k8iIOwA9l2hz57V2OKMmP5eSWcUvwx+mASAsbU+wkF1pHjn9ZVSBPrsYWr4/W/95y5SwYg2g==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/embla-carousel-react": {
+ "version": "8.6.0",
+ "resolved": "https://registry.npmjs.org/embla-carousel-react/-/embla-carousel-react-8.6.0.tgz",
+ "integrity": "sha512-0/PjqU7geVmo6F734pmPqpyHqiM99olvyecY7zdweCw+6tKEXnrE90pBiBbMMU8s5tICemzpQ3hi5EpxzGW+JA==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "embla-carousel": "8.6.0",
+ "embla-carousel-reactive-utils": "8.6.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.1 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"
+ }
+ },
+ "node_modules/embla-carousel-react/node_modules/embla-carousel": {
+ "version": "8.6.0",
+ "resolved": "https://registry.npmjs.org/embla-carousel/-/embla-carousel-8.6.0.tgz",
+ "integrity": "sha512-SjWyZBHJPbqxHOzckOfo8lHisEaJWmwd23XppYFYVh10bU66/Pn5tkVkbkCMZVdbUE5eTCI2nD8OyIP4Z+uwkA==",
+ "peer": true
+ },
+ "node_modules/embla-carousel-react/node_modules/embla-carousel-reactive-utils": {
+ "version": "8.6.0",
+ "resolved": "https://registry.npmjs.org/embla-carousel-reactive-utils/-/embla-carousel-reactive-utils-8.6.0.tgz",
+ "integrity": "sha512-fMVUDUEx0/uIEDM0Mz3dHznDhfX+znCCDCeIophYb1QGVM7YThSWX+wz11zlYwWFOr74b4QLGg0hrGPJeG2s4A==",
+ "peer": true,
+ "peerDependencies": {
+ "embla-carousel": "8.6.0"
+ }
+ },
+ "node_modules/emoji-regex": {
+ "version": "9.2.2",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
+ "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/entities": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.0.tgz",
+ "integrity": "sha512-aKstq2TDOndCn4diEyp9Uq/Flu2i1GlLkc6XIDQSDMuaFE3OPW5OphLCyQ5SpSJZTb4reN+kTcYru5yIfXoRPw==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.12"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/env-paths": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz",
+ "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/environment": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz",
+ "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/error-ex": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
+ "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-arrayish": "^0.2.1"
+ }
+ },
+ "node_modules/es-abstract": {
+ "version": "1.23.9",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.9.tgz",
+ "integrity": "sha512-py07lI0wjxAC/DcfK1S6G7iANonniZwTISvdPzk9hzeH0IZIshbuuFxLIU96OyF89Yb9hiqWn8M/bY83KY5vzA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "array-buffer-byte-length": "^1.0.2",
+ "arraybuffer.prototype.slice": "^1.0.4",
+ "available-typed-arrays": "^1.0.7",
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.3",
+ "data-view-buffer": "^1.0.2",
+ "data-view-byte-length": "^1.0.2",
+ "data-view-byte-offset": "^1.0.1",
+ "es-define-property": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.0.0",
+ "es-set-tostringtag": "^2.1.0",
+ "es-to-primitive": "^1.3.0",
+ "function.prototype.name": "^1.1.8",
+ "get-intrinsic": "^1.2.7",
+ "get-proto": "^1.0.0",
+ "get-symbol-description": "^1.1.0",
+ "globalthis": "^1.0.4",
+ "gopd": "^1.2.0",
+ "has-property-descriptors": "^1.0.2",
+ "has-proto": "^1.2.0",
+ "has-symbols": "^1.1.0",
+ "hasown": "^2.0.2",
+ "internal-slot": "^1.1.0",
+ "is-array-buffer": "^3.0.5",
+ "is-callable": "^1.2.7",
+ "is-data-view": "^1.0.2",
+ "is-regex": "^1.2.1",
+ "is-shared-array-buffer": "^1.0.4",
+ "is-string": "^1.1.1",
+ "is-typed-array": "^1.1.15",
+ "is-weakref": "^1.1.0",
+ "math-intrinsics": "^1.1.0",
+ "object-inspect": "^1.13.3",
+ "object-keys": "^1.1.1",
+ "object.assign": "^4.1.7",
+ "own-keys": "^1.0.1",
+ "regexp.prototype.flags": "^1.5.3",
+ "safe-array-concat": "^1.1.3",
+ "safe-push-apply": "^1.0.0",
+ "safe-regex-test": "^1.1.0",
+ "set-proto": "^1.0.0",
+ "string.prototype.trim": "^1.2.10",
+ "string.prototype.trimend": "^1.0.9",
+ "string.prototype.trimstart": "^1.0.8",
+ "typed-array-buffer": "^1.0.3",
+ "typed-array-byte-length": "^1.0.3",
+ "typed-array-byte-offset": "^1.0.4",
+ "typed-array-length": "^1.0.7",
+ "unbox-primitive": "^1.1.0",
+ "which-typed-array": "^1.1.18"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/es-define-property": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
+ "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-errors": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
+ "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-module-lexer": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz",
+ "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/es-object-atoms": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
+ "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-set-tostringtag": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
+ "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.6",
+ "has-tostringtag": "^1.0.2",
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-shim-unscopables": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz",
+ "integrity": "sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-to-primitive": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz",
+ "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-callable": "^1.2.7",
+ "is-date-object": "^1.0.5",
+ "is-symbol": "^1.0.4"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/esbuild": {
+ "version": "0.25.3",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.3.tgz",
+ "integrity": "sha512-qKA6Pvai73+M2FtftpNKRxJ78GIjmFXFxd/1DVBqGo/qNhLSfv+G12n9pNoWdytJC8U00TrViOwpjT0zgqQS8Q==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "optionalDependencies": {
+ "@esbuild/aix-ppc64": "0.25.3",
+ "@esbuild/android-arm": "0.25.3",
+ "@esbuild/android-arm64": "0.25.3",
+ "@esbuild/android-x64": "0.25.3",
+ "@esbuild/darwin-arm64": "0.25.3",
+ "@esbuild/darwin-x64": "0.25.3",
+ "@esbuild/freebsd-arm64": "0.25.3",
+ "@esbuild/freebsd-x64": "0.25.3",
+ "@esbuild/linux-arm": "0.25.3",
+ "@esbuild/linux-arm64": "0.25.3",
+ "@esbuild/linux-ia32": "0.25.3",
+ "@esbuild/linux-loong64": "0.25.3",
+ "@esbuild/linux-mips64el": "0.25.3",
+ "@esbuild/linux-ppc64": "0.25.3",
+ "@esbuild/linux-riscv64": "0.25.3",
+ "@esbuild/linux-s390x": "0.25.3",
+ "@esbuild/linux-x64": "0.25.3",
+ "@esbuild/netbsd-arm64": "0.25.3",
+ "@esbuild/netbsd-x64": "0.25.3",
+ "@esbuild/openbsd-arm64": "0.25.3",
+ "@esbuild/openbsd-x64": "0.25.3",
+ "@esbuild/sunos-x64": "0.25.3",
+ "@esbuild/win32-arm64": "0.25.3",
+ "@esbuild/win32-ia32": "0.25.3",
+ "@esbuild/win32-x64": "0.25.3"
+ }
+ },
+ "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": "9.25.1",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.25.1.tgz",
+ "integrity": "sha512-E6Mtz9oGQWDCpV12319d59n4tx9zOTXSTmc8BLVxBx+G/0RdM5MvEEJLU9c0+aleoePYYgVTOsRblx433qmhWQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.2.0",
+ "@eslint-community/regexpp": "^4.12.1",
+ "@eslint/config-array": "^0.20.0",
+ "@eslint/config-helpers": "^0.2.1",
+ "@eslint/core": "^0.13.0",
+ "@eslint/eslintrc": "^3.3.1",
+ "@eslint/js": "9.25.1",
+ "@eslint/plugin-kit": "^0.2.8",
+ "@humanfs/node": "^0.16.6",
+ "@humanwhocodes/module-importer": "^1.0.1",
+ "@humanwhocodes/retry": "^0.4.2",
+ "@types/estree": "^1.0.6",
+ "@types/json-schema": "^7.0.15",
+ "ajv": "^6.12.4",
+ "chalk": "^4.0.0",
+ "cross-spawn": "^7.0.6",
+ "debug": "^4.3.2",
+ "escape-string-regexp": "^4.0.0",
+ "eslint-scope": "^8.3.0",
+ "eslint-visitor-keys": "^4.2.0",
+ "espree": "^10.3.0",
+ "esquery": "^1.5.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",
+ "lodash.merge": "^4.6.2",
+ "minimatch": "^3.1.2",
+ "natural-compare": "^1.4.0",
+ "optionator": "^0.9.3"
+ },
+ "bin": {
+ "eslint": "bin/eslint.js"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://eslint.org/donate"
+ },
+ "peerDependencies": {
+ "jiti": "*"
+ },
+ "peerDependenciesMeta": {
+ "jiti": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/eslint-config-prettier": {
+ "version": "10.1.2",
+ "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.1.2.tgz",
+ "integrity": "sha512-Epgp/EofAUeEpIdZkW60MHKvPyru1ruQJxPL+WIycnaPApuseK0Zpkrh/FwL9oIpQvIhJwV7ptOy0DWUjTlCiA==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "eslint-config-prettier": "bin/cli.js"
+ },
+ "peerDependencies": {
+ "eslint": ">=7.0.0"
+ }
+ },
+ "node_modules/eslint-import-resolver-node": {
+ "version": "0.3.9",
+ "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz",
+ "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^3.2.7",
+ "is-core-module": "^2.13.0",
+ "resolve": "^1.22.4"
+ }
+ },
+ "node_modules/eslint-import-resolver-node/node_modules/debug": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+ "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.1"
+ }
+ },
+ "node_modules/eslint-import-resolver-typescript": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-4.3.4.tgz",
+ "integrity": "sha512-buzw5z5VtiQMysYLH9iW9BV04YyZebsw+gPi+c4FCjfS9i6COYOrEWw9t3m3wA9PFBfqcBCqWf32qrXLbwafDw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "debug": "^4.4.0",
+ "get-tsconfig": "^4.10.0",
+ "is-bun-module": "^2.0.0",
+ "stable-hash": "^0.0.5",
+ "tinyglobby": "^0.2.13",
+ "unrs-resolver": "^1.6.3"
+ },
+ "engines": {
+ "node": "^16.17.0 || >=18.6.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint-import-resolver-typescript"
+ },
+ "peerDependencies": {
+ "eslint": "*",
+ "eslint-plugin-import": "*",
+ "eslint-plugin-import-x": "*"
+ },
+ "peerDependenciesMeta": {
+ "eslint-plugin-import": {
+ "optional": true
+ },
+ "eslint-plugin-import-x": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/eslint-module-utils": {
+ "version": "2.12.0",
+ "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.0.tgz",
+ "integrity": "sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^3.2.7"
+ },
+ "engines": {
+ "node": ">=4"
+ },
+ "peerDependenciesMeta": {
+ "eslint": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/eslint-module-utils/node_modules/debug": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+ "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.1"
+ }
+ },
+ "node_modules/eslint-plugin-import": {
+ "version": "2.31.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.31.0.tgz",
+ "integrity": "sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@rtsao/scc": "^1.1.0",
+ "array-includes": "^3.1.8",
+ "array.prototype.findlastindex": "^1.2.5",
+ "array.prototype.flat": "^1.3.2",
+ "array.prototype.flatmap": "^1.3.2",
+ "debug": "^3.2.7",
+ "doctrine": "^2.1.0",
+ "eslint-import-resolver-node": "^0.3.9",
+ "eslint-module-utils": "^2.12.0",
+ "hasown": "^2.0.2",
+ "is-core-module": "^2.15.1",
+ "is-glob": "^4.0.3",
+ "minimatch": "^3.1.2",
+ "object.fromentries": "^2.0.8",
+ "object.groupby": "^1.0.3",
+ "object.values": "^1.2.0",
+ "semver": "^6.3.1",
+ "string.prototype.trimend": "^1.0.8",
+ "tsconfig-paths": "^3.15.0"
+ },
+ "engines": {
+ "node": ">=4"
+ },
+ "peerDependencies": {
+ "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9"
+ }
+ },
+ "node_modules/eslint-plugin-import/node_modules/brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/eslint-plugin-import/node_modules/debug": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+ "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.1"
+ }
+ },
+ "node_modules/eslint-plugin-import/node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/eslint-plugin-import/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/eslint-plugin-jsx-a11y": {
+ "version": "6.10.2",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.10.2.tgz",
+ "integrity": "sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "aria-query": "^5.3.2",
+ "array-includes": "^3.1.8",
+ "array.prototype.flatmap": "^1.3.2",
+ "ast-types-flow": "^0.0.8",
+ "axe-core": "^4.10.0",
+ "axobject-query": "^4.1.0",
+ "damerau-levenshtein": "^1.0.8",
+ "emoji-regex": "^9.2.2",
+ "hasown": "^2.0.2",
+ "jsx-ast-utils": "^3.3.5",
+ "language-tags": "^1.0.9",
+ "minimatch": "^3.1.2",
+ "object.fromentries": "^2.0.8",
+ "safe-regex-test": "^1.0.3",
+ "string.prototype.includes": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=4.0"
+ },
+ "peerDependencies": {
+ "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9"
+ }
+ },
+ "node_modules/eslint-plugin-jsx-a11y/node_modules/brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/eslint-plugin-jsx-a11y/node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/eslint-plugin-prettier": {
+ "version": "5.2.6",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.2.6.tgz",
+ "integrity": "sha512-mUcf7QG2Tjk7H055Jk0lGBjbgDnfrvqjhXh9t2xLMSCjZVcw9Rb1V6sVNXO0th3jgeO7zllWPTNRil3JW94TnQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prettier-linter-helpers": "^1.0.0",
+ "synckit": "^0.11.0"
+ },
+ "engines": {
+ "node": "^14.18.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint-plugin-prettier"
+ },
+ "peerDependencies": {
+ "@types/eslint": ">=8.0.0",
+ "eslint": ">=8.0.0",
+ "eslint-config-prettier": ">= 7.0.0 <10.0.0 || >=10.1.0",
+ "prettier": ">=3.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/eslint": {
+ "optional": true
+ },
+ "eslint-config-prettier": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/eslint-plugin-react-hooks": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.2.0.tgz",
+ "integrity": "sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0"
+ }
+ },
+ "node_modules/eslint-plugin-react-refresh": {
+ "version": "0.4.20",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.20.tgz",
+ "integrity": "sha512-XpbHQ2q5gUF8BGOX4dHe+71qoirYMhApEPZ7sfhF/dNnOF1UXnCMGZf79SFTBO7Bz5YEIT4TMieSlJBWhP9WBA==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "eslint": ">=8.40"
+ }
+ },
+ "node_modules/eslint-scope": {
+ "version": "8.3.0",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.3.0.tgz",
+ "integrity": "sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "esrecurse": "^4.3.0",
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint-visitor-keys": {
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
+ "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint/node_modules/brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/eslint/node_modules/eslint-visitor-keys": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz",
+ "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint/node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/espree": {
+ "version": "10.3.0",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz",
+ "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "acorn": "^8.14.0",
+ "acorn-jsx": "^5.3.2",
+ "eslint-visitor-keys": "^4.2.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/espree/node_modules/eslint-visitor-keys": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz",
+ "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/esquery": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz",
+ "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "estraverse": "^5.1.0"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/esrecurse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
+ "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/estraverse": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/estree-walker": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz",
+ "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "^1.0.0"
+ }
+ },
+ "node_modules/esutils": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/eventemitter3": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz",
+ "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/execa": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz",
+ "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cross-spawn": "^7.0.3",
+ "get-stream": "^8.0.1",
+ "human-signals": "^5.0.0",
+ "is-stream": "^3.0.0",
+ "merge-stream": "^2.0.0",
+ "npm-run-path": "^5.1.0",
+ "onetime": "^6.0.0",
+ "signal-exit": "^4.1.0",
+ "strip-final-newline": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=16.17"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/execa?sponsor=1"
+ }
+ },
+ "node_modules/expect-type": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.2.1.tgz",
+ "integrity": "sha512-/kP8CAwxzLVEeFrMm4kMmy4CCDlpipyA7MYLVrdJIkV0fYF0UaigQHRsxHiuY/GEea+bh4KSv3TIlgr+2UL6bw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
+ "node_modules/fast-deep-equal": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+ "license": "MIT"
+ },
+ "node_modules/fast-diff": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz",
+ "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==",
+ "dev": true,
+ "license": "Apache-2.0"
+ },
+ "node_modules/fast-glob": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
+ "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.stat": "^2.0.2",
+ "@nodelib/fs.walk": "^1.2.3",
+ "glob-parent": "^5.1.2",
+ "merge2": "^1.3.0",
+ "micromatch": "^4.0.8"
+ },
+ "engines": {
+ "node": ">=8.6.0"
+ }
+ },
+ "node_modules/fast-glob/node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/fast-json-stable-stringify": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fast-levenshtein": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fast-uri": {
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz",
+ "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fastify"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/fastify"
+ }
+ ],
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/fastq": {
+ "version": "1.19.1",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz",
+ "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "reusify": "^1.0.4"
+ }
+ },
+ "node_modules/fetch-blob": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz",
+ "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/jimmywarting"
+ },
+ {
+ "type": "paypal",
+ "url": "https://paypal.me/jimmywarting"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "node-domexception": "^1.0.0",
+ "web-streams-polyfill": "^3.0.3"
+ },
+ "engines": {
+ "node": "^12.20 || >= 14.13"
+ }
+ },
+ "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/fill-range": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
+ "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/find-up": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
+ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "locate-path": "^6.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/flat-cache": {
+ "version": "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.3.3",
+ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz",
+ "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/for-each": {
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz",
+ "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-callable": "^1.2.7"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/foreground-child": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz",
+ "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "cross-spawn": "^7.0.6",
+ "signal-exit": "^4.0.1"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/formdata-polyfill": {
+ "version": "4.0.10",
+ "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz",
+ "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fetch-blob": "^3.1.2"
+ },
+ "engines": {
+ "node": ">=12.20.0"
+ }
+ },
+ "node_modules/framer-motion": {
+ "version": "12.9.2",
+ "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.9.2.tgz",
+ "integrity": "sha512-R0O3Jdqbfwywpm45obP+8sTgafmdEcUoShQTAV+rB5pi+Y1Px/FYL5qLLRe5tPtBdN1J4jos7M+xN2VV2oEAbQ==",
+ "license": "MIT",
+ "dependencies": {
+ "motion-dom": "^12.9.1",
+ "motion-utils": "^12.8.3",
+ "tslib": "^2.4.0"
+ },
+ "peerDependencies": {
+ "@emotion/is-prop-valid": "*",
+ "react": "^18.0.0 || ^19.0.0",
+ "react-dom": "^18.0.0 || ^19.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@emotion/is-prop-valid": {
+ "optional": true
+ },
+ "react": {
+ "optional": true
+ },
+ "react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/function-bind": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/function.prototype.name": {
+ "version": "1.1.8",
+ "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz",
+ "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.3",
+ "define-properties": "^1.2.1",
+ "functions-have-names": "^1.2.3",
+ "hasown": "^2.0.2",
+ "is-callable": "^1.2.7"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/functions-have-names": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz",
+ "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/gensync": {
+ "version": "1.0.0-beta.2",
+ "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
+ "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/get-caller-file": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": "6.* || 8.* || >= 10.*"
+ }
+ },
+ "node_modules/get-east-asian-width": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.3.0.tgz",
+ "integrity": "sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/get-intrinsic": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
+ "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.2",
+ "es-define-property": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.1.1",
+ "function-bind": "^1.1.2",
+ "get-proto": "^1.0.1",
+ "gopd": "^1.2.0",
+ "has-symbols": "^1.1.0",
+ "hasown": "^2.0.2",
+ "math-intrinsics": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/get-nonce": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz",
+ "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/get-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
+ "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "dunder-proto": "^1.0.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/get-stream": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz",
+ "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/get-symbol-description": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz",
+ "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.6"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/get-tsconfig": {
+ "version": "4.10.0",
+ "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.10.0.tgz",
+ "integrity": "sha512-kGzZ3LWWQcGIAmg6iWvXn0ei6WDtV26wzHRMwDSzmAbcXrTEXxHy6IehI6/4eT6VRKyMP1eF1VqwrVUmE/LR7A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "resolve-pkg-maps": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1"
+ }
+ },
+ "node_modules/git-raw-commits": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-4.0.0.tgz",
+ "integrity": "sha512-ICsMM1Wk8xSGMowkOmPrzo2Fgmfo4bMHLNX6ytHjajRJUqvHOw/TFapQ+QG75c3X/tTDDhOSRPGC52dDbNM8FQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "dargs": "^8.0.0",
+ "meow": "^12.0.1",
+ "split2": "^4.0.0"
+ },
+ "bin": {
+ "git-raw-commits": "cli.mjs"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/glob": {
+ "version": "10.4.5",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
+ "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "foreground-child": "^3.1.0",
+ "jackspeak": "^3.1.2",
+ "minimatch": "^9.0.4",
+ "minipass": "^7.1.2",
+ "package-json-from-dist": "^1.0.0",
+ "path-scurry": "^1.11.1"
+ },
+ "bin": {
+ "glob": "dist/esm/bin.mjs"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/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/global-directory": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/global-directory/-/global-directory-4.0.1.tgz",
+ "integrity": "sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ini": "4.1.1"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/globals": {
+ "version": "16.0.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-16.0.0.tgz",
+ "integrity": "sha512-iInW14XItCXET01CQFqudPOWP2jYMl7T+QRQT+UNcR/iQncN/F0UNpgd76iFkBPgNQb4+X3LV9tLJYzwh+Gl3A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/globalthis": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz",
+ "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-properties": "^1.2.1",
+ "gopd": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/gopd": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
+ "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/graphemer": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
+ "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/has-bigints": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz",
+ "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/has-property-descriptors": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
+ "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-define-property": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-proto": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz",
+ "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "dunder-proto": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-symbols": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
+ "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-tostringtag": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
+ "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-symbols": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/hasown": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
+ "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/html-encoding-sniffer": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz",
+ "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "whatwg-encoding": "^3.1.1"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/html-escaper": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
+ "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/http-proxy-agent": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz",
+ "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "agent-base": "^7.1.0",
+ "debug": "^4.3.4"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/https-proxy-agent": {
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz",
+ "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "agent-base": "^7.1.2",
+ "debug": "4"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/human-signals": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz",
+ "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=16.17.0"
+ }
+ },
+ "node_modules/husky": {
+ "version": "9.1.7",
+ "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.7.tgz",
+ "integrity": "sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "husky": "bin.js"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/typicode"
+ }
+ },
+ "node_modules/iconv-lite": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
+ "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ieee754": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
+ "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/ignore": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
+ "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/import-fresh": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
+ "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "parent-module": "^1.0.0",
+ "resolve-from": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/import-meta-resolve": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.1.0.tgz",
+ "integrity": "sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8.19"
+ }
+ },
+ "node_modules/indent-string": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
+ "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ini": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.1.tgz",
+ "integrity": "sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/internal-slot": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz",
+ "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "hasown": "^2.0.2",
+ "side-channel": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/is-array-buffer": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz",
+ "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.3",
+ "get-intrinsic": "^1.2.6"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-arrayish": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+ "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/is-async-function": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz",
+ "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "async-function": "^1.0.0",
+ "call-bound": "^1.0.3",
+ "get-proto": "^1.0.1",
+ "has-tostringtag": "^1.0.2",
+ "safe-regex-test": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-bigint": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz",
+ "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-bigints": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-boolean-object": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz",
+ "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-bun-module": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-bun-module/-/is-bun-module-2.0.0.tgz",
+ "integrity": "sha512-gNCGbnnnnFAUGKeZ9PdbyeGYJqewpmc2aKHUEMO5nQPWU9lOmv7jcmQIv+qHD8fXW6W7qfuCwX4rY9LNRjXrkQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "semver": "^7.7.1"
+ }
+ },
+ "node_modules/is-callable": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
+ "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-core-module": {
+ "version": "2.16.1",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
+ "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-data-view": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz",
+ "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "get-intrinsic": "^1.2.6",
+ "is-typed-array": "^1.1.13"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-date-object": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz",
+ "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-finalizationregistry": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz",
+ "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-fullwidth-code-point": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz",
+ "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-generator-function": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.0.tgz",
+ "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "get-proto": "^1.0.0",
+ "has-tostringtag": "^1.0.2",
+ "safe-regex-test": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-map": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz",
+ "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "node_modules/is-number-object": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz",
+ "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-obj": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz",
+ "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-potential-custom-element-name": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz",
+ "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/is-regex": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz",
+ "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "gopd": "^1.2.0",
+ "has-tostringtag": "^1.0.2",
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-set": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz",
+ "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-shared-array-buffer": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz",
+ "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-stream": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz",
+ "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-string": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz",
+ "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-symbol": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz",
+ "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "has-symbols": "^1.1.0",
+ "safe-regex-test": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-text-path": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-2.0.0.tgz",
+ "integrity": "sha512-+oDTluR6WEjdXEJMnC2z6A4FRwFoYuvShVVEGsS7ewc0UTi2QtAKMDJuL4BDEVt+5T7MjFo12RP8ghOM75oKJw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "text-extensions": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-typed-array": {
+ "version": "1.1.15",
+ "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz",
+ "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "which-typed-array": "^1.1.16"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-weakmap": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz",
+ "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-weakref": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz",
+ "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-weakset": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz",
+ "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "get-intrinsic": "^1.2.6"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/isarray": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
+ "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/isomorphic-fetch": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz",
+ "integrity": "sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "node-fetch": "^2.6.1",
+ "whatwg-fetch": "^3.4.1"
+ }
+ },
+ "node_modules/isomorphic-fetch/node_modules/node-fetch": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
+ "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "whatwg-url": "^5.0.0"
+ },
+ "engines": {
+ "node": "4.x || >=6.0.0"
+ },
+ "peerDependencies": {
+ "encoding": "^0.1.0"
+ },
+ "peerDependenciesMeta": {
+ "encoding": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/isomorphic-fetch/node_modules/tr46": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
+ "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/isomorphic-fetch/node_modules/webidl-conversions": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
+ "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
+ "dev": true,
+ "license": "BSD-2-Clause"
+ },
+ "node_modules/isomorphic-fetch/node_modules/whatwg-url": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
+ "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "tr46": "~0.0.3",
+ "webidl-conversions": "^3.0.0"
+ }
+ },
+ "node_modules/istanbul-lib-coverage": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz",
+ "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/istanbul-lib-report": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz",
+ "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "istanbul-lib-coverage": "^3.0.0",
+ "make-dir": "^4.0.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/istanbul-lib-source-maps": {
+ "version": "5.0.6",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-5.0.6.tgz",
+ "integrity": "sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@jridgewell/trace-mapping": "^0.3.23",
+ "debug": "^4.1.1",
+ "istanbul-lib-coverage": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/istanbul-reports": {
+ "version": "3.1.7",
+ "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz",
+ "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "html-escaper": "^2.0.0",
+ "istanbul-lib-report": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/jackspeak": {
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
+ "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "@isaacs/cliui": "^8.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ },
+ "optionalDependencies": {
+ "@pkgjs/parseargs": "^0.11.0"
+ }
+ },
+ "node_modules/jiti": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz",
+ "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "jiti": "lib/jiti-cli.mjs"
+ }
+ },
+ "node_modules/js-tokens": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+ "license": "MIT"
+ },
+ "node_modules/js-yaml": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
+ "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "argparse": "^2.0.1"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/jsdom": {
+ "version": "26.1.0",
+ "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-26.1.0.tgz",
+ "integrity": "sha512-Cvc9WUhxSMEo4McES3P7oK3QaXldCfNWp7pl2NNeiIFlCoLr3kfq9kb1fxftiwk1FLV7CvpvDfonxtzUDeSOPg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cssstyle": "^4.2.1",
+ "data-urls": "^5.0.0",
+ "decimal.js": "^10.5.0",
+ "html-encoding-sniffer": "^4.0.0",
+ "http-proxy-agent": "^7.0.2",
+ "https-proxy-agent": "^7.0.6",
+ "is-potential-custom-element-name": "^1.0.1",
+ "nwsapi": "^2.2.16",
+ "parse5": "^7.2.1",
+ "rrweb-cssom": "^0.8.0",
+ "saxes": "^6.0.0",
+ "symbol-tree": "^3.2.4",
+ "tough-cookie": "^5.1.1",
+ "w3c-xmlserializer": "^5.0.0",
+ "webidl-conversions": "^7.0.0",
+ "whatwg-encoding": "^3.1.1",
+ "whatwg-mimetype": "^4.0.0",
+ "whatwg-url": "^14.1.1",
+ "ws": "^8.18.0",
+ "xml-name-validator": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "canvas": "^3.0.0"
+ },
+ "peerDependenciesMeta": {
+ "canvas": {
+ "optional": true
+ }
+ }
+ },
+ "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-parse-even-better-errors": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
+ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
+ "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/jsonparse": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz",
+ "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==",
+ "dev": true,
+ "engines": [
+ "node >= 0.2.0"
+ ],
+ "license": "MIT"
+ },
+ "node_modules/JSONStream": {
+ "version": "1.3.5",
+ "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz",
+ "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==",
+ "dev": true,
+ "license": "(MIT OR Apache-2.0)",
+ "dependencies": {
+ "jsonparse": "^1.2.0",
+ "through": ">=2.2.7 <3"
+ },
+ "bin": {
+ "JSONStream": "bin.js"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/jsx-ast-utils": {
+ "version": "3.3.5",
+ "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz",
+ "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "array-includes": "^3.1.6",
+ "array.prototype.flat": "^1.3.1",
+ "object.assign": "^4.1.4",
+ "object.values": "^1.1.6"
+ },
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "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/klona": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.6.tgz",
+ "integrity": "sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/language-subtag-registry": {
+ "version": "0.3.23",
+ "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz",
+ "integrity": "sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==",
+ "dev": true,
+ "license": "CC0-1.0"
+ },
+ "node_modules/language-tags": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.9.tgz",
+ "integrity": "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "language-subtag-registry": "^0.3.20"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/levn": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
+ "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prelude-ls": "^1.2.1",
+ "type-check": "~0.4.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/lilconfig": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz",
+ "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antonk52"
+ }
+ },
+ "node_modules/lines-and-columns": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
+ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lint-staged": {
+ "version": "15.5.1",
+ "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-15.5.1.tgz",
+ "integrity": "sha512-6m7u8mue4Xn6wK6gZvSCQwBvMBR36xfY24nF5bMTf2MHDYG6S3yhJuOgdYVw99hsjyDt2d4z168b3naI8+NWtQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "chalk": "^5.4.1",
+ "commander": "^13.1.0",
+ "debug": "^4.4.0",
+ "execa": "^8.0.1",
+ "lilconfig": "^3.1.3",
+ "listr2": "^8.2.5",
+ "micromatch": "^4.0.8",
+ "pidtree": "^0.6.0",
+ "string-argv": "^0.3.2",
+ "yaml": "^2.7.0"
+ },
+ "bin": {
+ "lint-staged": "bin/lint-staged.js"
+ },
+ "engines": {
+ "node": ">=18.12.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/lint-staged"
+ }
+ },
+ "node_modules/lint-staged/node_modules/chalk": {
+ "version": "5.4.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz",
+ "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.17.0 || ^14.13 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/listr2": {
+ "version": "8.3.2",
+ "resolved": "https://registry.npmjs.org/listr2/-/listr2-8.3.2.tgz",
+ "integrity": "sha512-vsBzcU4oE+v0lj4FhVLzr9dBTv4/fHIa57l+GCwovP8MoFNZJTOhGU8PXd4v2VJCbECAaijBiHntiekFMLvo0g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cli-truncate": "^4.0.0",
+ "colorette": "^2.0.20",
+ "eventemitter3": "^5.0.1",
+ "log-update": "^6.1.0",
+ "rfdc": "^1.4.1",
+ "wrap-ansi": "^9.0.0"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/locate-path": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
+ "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-locate": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/lodash": {
+ "version": "4.17.21",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lodash.camelcase": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
+ "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lodash.isplainobject": {
+ "version": "4.0.6",
+ "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
+ "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lodash.kebabcase": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz",
+ "integrity": "sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lodash.merge": {
+ "version": "4.6.2",
+ "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
+ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lodash.mergewith": {
+ "version": "4.6.2",
+ "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz",
+ "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lodash.snakecase": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz",
+ "integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lodash.startcase": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/lodash.startcase/-/lodash.startcase-4.4.0.tgz",
+ "integrity": "sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lodash.uniq": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz",
+ "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lodash.upperfirst": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz",
+ "integrity": "sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/log-update": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.1.0.tgz",
+ "integrity": "sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-escapes": "^7.0.0",
+ "cli-cursor": "^5.0.0",
+ "slice-ansi": "^7.1.0",
+ "strip-ansi": "^7.1.0",
+ "wrap-ansi": "^9.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/log-update/node_modules/ansi-styles": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
+ "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/log-update/node_modules/is-fullwidth-code-point": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.0.0.tgz",
+ "integrity": "sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "get-east-asian-width": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/log-update/node_modules/slice-ansi": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.0.tgz",
+ "integrity": "sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^6.2.1",
+ "is-fullwidth-code-point": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/slice-ansi?sponsor=1"
+ }
+ },
+ "node_modules/loose-envify": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
+ "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
+ "license": "MIT",
+ "dependencies": {
+ "js-tokens": "^3.0.0 || ^4.0.0"
+ },
+ "bin": {
+ "loose-envify": "cli.js"
+ }
+ },
+ "node_modules/loupe": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.3.tgz",
+ "integrity": "sha512-kkIp7XSkP78ZxJEsSxW3712C6teJVoeHHwgo9zJ380de7IYyJ2ISlxojcH2pC5OFLewESmnRi/+XCDIEEVyoug==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "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/lz-string": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz",
+ "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "bin": {
+ "lz-string": "bin/bin.js"
+ }
+ },
+ "node_modules/magic-string": {
+ "version": "0.30.17",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz",
+ "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.5.0"
+ }
+ },
+ "node_modules/magicast": {
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.3.5.tgz",
+ "integrity": "sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.25.4",
+ "@babel/types": "^7.25.4",
+ "source-map-js": "^1.2.0"
+ }
+ },
+ "node_modules/make-dir": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz",
+ "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "semver": "^7.5.3"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/math-intrinsics": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
+ "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/meow": {
+ "version": "12.1.1",
+ "resolved": "https://registry.npmjs.org/meow/-/meow-12.1.1.tgz",
+ "integrity": "sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=16.10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/merge-stream": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
+ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/merge2": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/micromatch": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
+ "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "braces": "^3.0.3",
+ "picomatch": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/mimic-fn": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz",
+ "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/mimic-function": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz",
+ "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/min-indent": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz",
+ "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/minimatch": {
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+ "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/minimist": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
+ "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/minipass": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
+ "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ }
+ },
+ "node_modules/motion-dom": {
+ "version": "12.9.1",
+ "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.9.1.tgz",
+ "integrity": "sha512-xqXEwRLDYDTzOgXobSoWtytRtGlf7zdkRfFbrrdP7eojaGQZ5Go4OOKtgnx7uF8sAkfr1ZjMvbCJSCIT2h6fkQ==",
+ "license": "MIT",
+ "dependencies": {
+ "motion-utils": "^12.8.3"
+ }
+ },
+ "node_modules/motion-utils": {
+ "version": "12.8.3",
+ "resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-12.8.3.tgz",
+ "integrity": "sha512-GYVauZEbca8/zOhEiYOY9/uJeedYQld6co/GJFKOy//0c/4lDqk0zB549sBYqqV2iMuX+uHrY1E5zd8A2L+1Lw==",
+ "license": "MIT"
+ },
+ "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.11",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
+ "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
+ },
+ "engines": {
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ }
+ },
+ "node_modules/napi-postinstall": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.2.2.tgz",
+ "integrity": "sha512-Wy1VI/hpKHwy1MsnFxHCJxqFwmmxD0RA/EKPL7e6mfbsY01phM2SZyJnRdU0bLvhu0Quby1DCcAZti3ghdl4/A==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "napi-postinstall": "lib/cli.js"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.18.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/napi-postinstall"
+ }
+ },
+ "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-domexception": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
+ "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==",
+ "deprecated": "Use your platform's native DOMException instead",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/jimmywarting"
+ },
+ {
+ "type": "github",
+ "url": "https://paypal.me/jimmywarting"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=10.5.0"
+ }
+ },
+ "node_modules/node-fetch": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz",
+ "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "data-uri-to-buffer": "^4.0.0",
+ "fetch-blob": "^3.1.4",
+ "formdata-polyfill": "^4.0.10"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/node-fetch"
+ }
+ },
+ "node_modules/node-releases": {
+ "version": "2.0.19",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz",
+ "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/npm-run-path": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz",
+ "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-key": "^4.0.0"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/npm-run-path/node_modules/path-key": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz",
+ "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/nwsapi": {
+ "version": "2.2.20",
+ "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.20.tgz",
+ "integrity": "sha512-/ieB+mDe4MrrKMT8z+mQL8klXydZWGR5Dowt4RAGKbJ3kIGEx3X4ljUo+6V73IXtUPWgfOlU5B9MlGxFO5T+cA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/object-inspect": {
+ "version": "1.13.4",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
+ "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object-keys": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
+ "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/object.assign": {
+ "version": "4.1.7",
+ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz",
+ "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.3",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.0.0",
+ "has-symbols": "^1.1.0",
+ "object-keys": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object.fromentries": {
+ "version": "2.0.8",
+ "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz",
+ "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.2",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object.groupby": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz",
+ "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/object.values": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz",
+ "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.3",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/onetime": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz",
+ "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mimic-fn": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "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/own-keys": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz",
+ "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "get-intrinsic": "^1.2.6",
+ "object-keys": "^1.1.1",
+ "safe-push-apply": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/p-limit": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "yocto-queue": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-locate": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
+ "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-limit": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/package-json-from-dist": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz",
+ "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==",
+ "dev": true,
+ "license": "BlueOak-1.0.0"
+ },
+ "node_modules/parent-module": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
+ "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "callsites": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/parse-json": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
+ "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.0.0",
+ "error-ex": "^1.3.1",
+ "json-parse-even-better-errors": "^2.3.0",
+ "lines-and-columns": "^1.1.6"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/parse5": {
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz",
+ "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "entities": "^6.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/inikulin/parse5?sponsor=1"
+ }
+ },
+ "node_modules/path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-parse": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/path-scurry": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
+ "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "lru-cache": "^10.2.0",
+ "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/path-scurry/node_modules/lru-cache": {
+ "version": "10.4.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
+ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/pathe": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz",
+ "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/pathval": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.0.tgz",
+ "integrity": "sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 14.16"
+ }
+ },
+ "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": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/pidtree": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.6.0.tgz",
+ "integrity": "sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "pidtree": "bin/pidtree.js"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/possible-typed-array-names": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz",
+ "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/postcss": {
+ "version": "8.5.3",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz",
+ "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==",
+ "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.8",
+ "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/prettier": {
+ "version": "3.5.3",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.3.tgz",
+ "integrity": "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "prettier": "bin/prettier.cjs"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/prettier/prettier?sponsor=1"
+ }
+ },
+ "node_modules/prettier-linter-helpers": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz",
+ "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-diff": "^1.1.2"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/pretty-format": {
+ "version": "27.5.1",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz",
+ "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "ansi-regex": "^5.0.1",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^17.0.1"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/pretty-format/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/pretty-format/node_modules/ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/pretty-format/node_modules/react-is": {
+ "version": "17.0.2",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
+ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/prop-types": {
+ "version": "15.8.1",
+ "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
+ "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
+ "license": "MIT",
+ "dependencies": {
+ "loose-envify": "^1.4.0",
+ "object-assign": "^4.1.1",
+ "react-is": "^16.13.1"
+ }
+ },
+ "node_modules/punycode": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
+ "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/queue-microtask": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
+ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/react": {
+ "version": "19.1.0",
+ "resolved": "https://registry.npmjs.org/react/-/react-19.1.0.tgz",
+ "integrity": "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/react-dom": {
+ "version": "19.1.0",
+ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz",
+ "integrity": "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==",
+ "license": "MIT",
+ "dependencies": {
+ "scheduler": "^0.26.0"
+ },
+ "peerDependencies": {
+ "react": "^19.1.0"
+ }
+ },
+ "node_modules/react-hook-form": {
+ "version": "7.56.1",
+ "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.56.1.tgz",
+ "integrity": "sha512-qWAVokhSpshhcEuQDSANHx3jiAEFzu2HAaaQIzi/r9FNPm1ioAvuJSD4EuZzWd7Al7nTRKcKPnBKO7sRn+zavQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/react-hook-form"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17 || ^18 || ^19"
+ }
+ },
+ "node_modules/react-is": {
+ "version": "16.13.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
+ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
+ "license": "MIT"
+ },
+ "node_modules/react-number-format": {
+ "version": "5.4.4",
+ "resolved": "https://registry.npmjs.org/react-number-format/-/react-number-format-5.4.4.tgz",
+ "integrity": "sha512-wOmoNZoOpvMminhifQYiYSTCLUDOiUbBunrMrMjA+dV52sY+vck1S4UhR6PkgnoCquvvMSeJjErXZ4qSaWCliA==",
+ "license": "MIT",
+ "peerDependencies": {
+ "react": "^0.14 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
+ "react-dom": "^0.14 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
+ }
+ },
+ "node_modules/react-refresh": {
+ "version": "0.17.0",
+ "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz",
+ "integrity": "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/react-remove-scroll": {
+ "version": "2.6.3",
+ "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.6.3.tgz",
+ "integrity": "sha512-pnAi91oOk8g8ABQKGF5/M9qxmmOPxaAnopyTHYfqYEwJhyFrbbBtHuSgtKEoH0jpcxx5o3hXqH1mNd9/Oi+8iQ==",
+ "license": "MIT",
+ "dependencies": {
+ "react-remove-scroll-bar": "^2.3.7",
+ "react-style-singleton": "^2.2.3",
+ "tslib": "^2.1.0",
+ "use-callback-ref": "^1.3.3",
+ "use-sidecar": "^1.1.3"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/react-remove-scroll-bar": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.8.tgz",
+ "integrity": "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==",
+ "license": "MIT",
+ "dependencies": {
+ "react-style-singleton": "^2.2.2",
+ "tslib": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/react-router": {
+ "version": "7.6.0",
+ "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.6.0.tgz",
+ "integrity": "sha512-GGufuHIVCJDbnIAXP3P9Sxzq3UUsddG3rrI3ut1q6m0FI6vxVBF3JoPQ38+W/blslLH4a5Yutp8drkEpXoddGQ==",
+ "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.6.0",
+ "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.6.0.tgz",
+ "integrity": "sha512-DYgm6RDEuKdopSyGOWZGtDfSm7Aofb8CCzgkliTjtu/eDuB0gcsv6qdFhhi8HdtmA+KHkt5MfZ5K2PdzjugYsA==",
+ "license": "MIT",
+ "dependencies": {
+ "react-router": "7.6.0"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ },
+ "peerDependencies": {
+ "react": ">=18",
+ "react-dom": ">=18"
+ }
+ },
+ "node_modules/react-style-singleton": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.3.tgz",
+ "integrity": "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==",
+ "license": "MIT",
+ "dependencies": {
+ "get-nonce": "^1.0.0",
+ "tslib": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/react-textarea-autosize": {
+ "version": "8.5.9",
+ "resolved": "https://registry.npmjs.org/react-textarea-autosize/-/react-textarea-autosize-8.5.9.tgz",
+ "integrity": "sha512-U1DGlIQN5AwgjTyOEnI1oCcMuEr1pv1qOtklB2l4nyMGbHzWrI0eFsYK0zos2YWqAolJyG0IWJaqWmWj5ETh0A==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.20.13",
+ "use-composed-ref": "^1.3.0",
+ "use-latest": "^1.2.1"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
+ }
+ },
+ "node_modules/react-transition-group": {
+ "version": "4.4.5",
+ "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz",
+ "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@babel/runtime": "^7.5.5",
+ "dom-helpers": "^5.0.1",
+ "loose-envify": "^1.4.0",
+ "prop-types": "^15.6.2"
+ },
+ "peerDependencies": {
+ "react": ">=16.6.0",
+ "react-dom": ">=16.6.0"
+ }
+ },
+ "node_modules/redent": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz",
+ "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "indent-string": "^4.0.0",
+ "strip-indent": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/reflect.getprototypeof": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz",
+ "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.9",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.0.0",
+ "get-intrinsic": "^1.2.7",
+ "get-proto": "^1.0.1",
+ "which-builtin-type": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/regenerator-runtime": {
+ "version": "0.14.1",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
+ "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==",
+ "license": "MIT"
+ },
+ "node_modules/regexp.prototype.flags": {
+ "version": "1.5.4",
+ "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz",
+ "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "define-properties": "^1.2.1",
+ "es-errors": "^1.3.0",
+ "get-proto": "^1.0.1",
+ "gopd": "^1.2.0",
+ "set-function-name": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/require-directory": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+ "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/require-from-string": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
+ "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/resolve": {
+ "version": "1.22.10",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz",
+ "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-core-module": "^2.16.0",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ },
+ "bin": {
+ "resolve": "bin/resolve"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/resolve-from": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/resolve-pkg-maps": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz",
+ "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1"
+ }
+ },
+ "node_modules/restore-cursor": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz",
+ "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "onetime": "^7.0.0",
+ "signal-exit": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/restore-cursor/node_modules/onetime": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz",
+ "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mimic-function": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/reusify": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz",
+ "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "iojs": ">=1.0.0",
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/rfdc": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz",
+ "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/rollup": {
+ "version": "4.40.0",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.40.0.tgz",
+ "integrity": "sha512-Noe455xmA96nnqH5piFtLobsGbCij7Tu+tb3c1vYjNbTkfzGqXqQXG3wJaYXkRZuQ0vEYN4bhwg7QnIrqB5B+w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "1.0.7"
+ },
+ "bin": {
+ "rollup": "dist/bin/rollup"
+ },
+ "engines": {
+ "node": ">=18.0.0",
+ "npm": ">=8.0.0"
+ },
+ "optionalDependencies": {
+ "@rollup/rollup-android-arm-eabi": "4.40.0",
+ "@rollup/rollup-android-arm64": "4.40.0",
+ "@rollup/rollup-darwin-arm64": "4.40.0",
+ "@rollup/rollup-darwin-x64": "4.40.0",
+ "@rollup/rollup-freebsd-arm64": "4.40.0",
+ "@rollup/rollup-freebsd-x64": "4.40.0",
+ "@rollup/rollup-linux-arm-gnueabihf": "4.40.0",
+ "@rollup/rollup-linux-arm-musleabihf": "4.40.0",
+ "@rollup/rollup-linux-arm64-gnu": "4.40.0",
+ "@rollup/rollup-linux-arm64-musl": "4.40.0",
+ "@rollup/rollup-linux-loongarch64-gnu": "4.40.0",
+ "@rollup/rollup-linux-powerpc64le-gnu": "4.40.0",
+ "@rollup/rollup-linux-riscv64-gnu": "4.40.0",
+ "@rollup/rollup-linux-riscv64-musl": "4.40.0",
+ "@rollup/rollup-linux-s390x-gnu": "4.40.0",
+ "@rollup/rollup-linux-x64-gnu": "4.40.0",
+ "@rollup/rollup-linux-x64-musl": "4.40.0",
+ "@rollup/rollup-win32-arm64-msvc": "4.40.0",
+ "@rollup/rollup-win32-ia32-msvc": "4.40.0",
+ "@rollup/rollup-win32-x64-msvc": "4.40.0",
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/rrweb-cssom": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.8.0.tgz",
+ "integrity": "sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/run-parallel": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
+ "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "queue-microtask": "^1.2.2"
+ }
+ },
+ "node_modules/safe-array-concat": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz",
+ "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.2",
+ "get-intrinsic": "^1.2.6",
+ "has-symbols": "^1.1.0",
+ "isarray": "^2.0.5"
+ },
+ "engines": {
+ "node": ">=0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/safe-push-apply": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz",
+ "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "isarray": "^2.0.5"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/safe-regex-test": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz",
+ "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "is-regex": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/saxes": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz",
+ "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "xmlchars": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=v12.22.7"
+ }
+ },
+ "node_modules/scheduler": {
+ "version": "0.26.0",
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz",
+ "integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==",
+ "license": "MIT"
+ },
+ "node_modules/semver": {
+ "version": "7.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz",
+ "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/set-cookie-parser": {
+ "version": "2.7.1",
+ "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz",
+ "integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==",
+ "license": "MIT"
+ },
+ "node_modules/set-function-length": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
+ "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-data-property": "^1.1.4",
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2",
+ "get-intrinsic": "^1.2.4",
+ "gopd": "^1.0.1",
+ "has-property-descriptors": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/set-function-name": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz",
+ "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-data-property": "^1.1.4",
+ "es-errors": "^1.3.0",
+ "functions-have-names": "^1.2.3",
+ "has-property-descriptors": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/set-proto": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz",
+ "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "dunder-proto": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "shebang-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/side-channel": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
+ "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "object-inspect": "^1.13.3",
+ "side-channel-list": "^1.0.0",
+ "side-channel-map": "^1.0.1",
+ "side-channel-weakmap": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-list": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
+ "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "object-inspect": "^1.13.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-map": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
+ "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.5",
+ "object-inspect": "^1.13.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-weakmap": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
+ "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.5",
+ "object-inspect": "^1.13.3",
+ "side-channel-map": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/siginfo": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz",
+ "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/signal-exit": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
+ "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/slice-ansi": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz",
+ "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^6.0.0",
+ "is-fullwidth-code-point": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/slice-ansi?sponsor=1"
+ }
+ },
+ "node_modules/slice-ansi/node_modules/ansi-styles": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
+ "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/source-map-js": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
+ "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/split2": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz",
+ "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">= 10.x"
+ }
+ },
+ "node_modules/stable-hash": {
+ "version": "0.0.5",
+ "resolved": "https://registry.npmjs.org/stable-hash/-/stable-hash-0.0.5.tgz",
+ "integrity": "sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/stackback": {
+ "version": "0.0.2",
+ "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz",
+ "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/std-env": {
+ "version": "3.9.0",
+ "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.9.0.tgz",
+ "integrity": "sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/string-argv": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz",
+ "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.6.19"
+ }
+ },
+ "node_modules/string-width": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz",
+ "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^10.3.0",
+ "get-east-asian-width": "^1.0.0",
+ "strip-ansi": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/string-width-cjs": {
+ "name": "string-width",
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/string-width-cjs/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/string-width-cjs/node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/string-width-cjs/node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/string-width-cjs/node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/string-width/node_modules/emoji-regex": {
+ "version": "10.4.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz",
+ "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/string.prototype.includes": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/string.prototype.includes/-/string.prototype.includes-2.0.1.tgz",
+ "integrity": "sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/string.prototype.trim": {
+ "version": "1.2.10",
+ "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz",
+ "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.2",
+ "define-data-property": "^1.1.4",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.5",
+ "es-object-atoms": "^1.0.0",
+ "has-property-descriptors": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/string.prototype.trimend": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz",
+ "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.2",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/string.prototype.trimstart": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz",
+ "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/strip-ansi": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
+ "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/strip-ansi?sponsor=1"
+ }
+ },
+ "node_modules/strip-ansi-cjs": {
+ "name": "strip-ansi",
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-ansi-cjs/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-bom": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
+ "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/strip-final-newline": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz",
+ "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/strip-indent": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz",
+ "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "min-indent": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-json-comments": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/supports-preserve-symlinks-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/swr": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/swr/-/swr-2.3.3.tgz",
+ "integrity": "sha512-dshNvs3ExOqtZ6kJBaAsabhPdHyeY4P2cKwRCniDVifBMoG/SVI7tfLWqPXriVspf2Rg4tPzXJTnwaihIeFw2A==",
+ "license": "MIT",
+ "dependencies": {
+ "dequal": "^2.0.3",
+ "use-sync-external-store": "^1.4.0"
+ },
+ "peerDependencies": {
+ "react": "^16.11.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
+ }
+ },
+ "node_modules/symbol-tree": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
+ "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/synckit": {
+ "version": "0.11.4",
+ "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.4.tgz",
+ "integrity": "sha512-Q/XQKRaJiLiFIBNN+mndW7S/RHxvwzuZS6ZwmRzUBqJBv/5QIKCEwkBC8GBf8EQJKYnaFs0wOZbKTXBPj8L9oQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@pkgr/core": "^0.2.3",
+ "tslib": "^2.8.1"
+ },
+ "engines": {
+ "node": "^14.18.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/synckit"
+ }
+ },
+ "node_modules/tabbable": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz",
+ "integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==",
+ "license": "MIT"
+ },
+ "node_modules/test-exclude": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-7.0.1.tgz",
+ "integrity": "sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "@istanbuljs/schema": "^0.1.2",
+ "glob": "^10.4.1",
+ "minimatch": "^9.0.4"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/text-extensions": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-2.4.0.tgz",
+ "integrity": "sha512-te/NtwBwfiNRLf9Ijqx3T0nlqZiQ2XrrtBvu+cLL8ZRrGkO0NHTug8MYFKyoSrv/sHTaSKfilUkizV6XhxMJ3g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/through": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
+ "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/tinybench": {
+ "version": "2.9.0",
+ "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz",
+ "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/tinyexec": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz",
+ "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/tinyglobby": {
+ "version": "0.2.13",
+ "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.13.tgz",
+ "integrity": "sha512-mEwzpUgrLySlveBwEVDMKk5B57bhLPYovRfPAXD5gA/98Opn0rCDj3GtLwFvCvH5RK9uPCExUROW5NjDwvqkxw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fdir": "^6.4.4",
+ "picomatch": "^4.0.2"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/SuperchupuDev"
+ }
+ },
+ "node_modules/tinyglobby/node_modules/fdir": {
+ "version": "6.4.4",
+ "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.4.tgz",
+ "integrity": "sha512-1NZP+GK4GfuAv3PqKvxQRDMjdSRZjnkq7KfhlNrCNNlZ0ygQFpebfrnfnq/W7fpUnAv9aGWmY1zKx7FYL3gwhg==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "picomatch": "^3 || ^4"
+ },
+ "peerDependenciesMeta": {
+ "picomatch": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/tinyglobby/node_modules/picomatch": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
+ "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/tinypool": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.0.2.tgz",
+ "integrity": "sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.0.0 || >=20.0.0"
+ }
+ },
+ "node_modules/tinyrainbow": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-2.0.0.tgz",
+ "integrity": "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/tinyspy": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-3.0.2.tgz",
+ "integrity": "sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/tldts": {
+ "version": "6.1.86",
+ "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.86.tgz",
+ "integrity": "sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "tldts-core": "^6.1.86"
+ },
+ "bin": {
+ "tldts": "bin/cli.js"
+ }
+ },
+ "node_modules/tldts-core": {
+ "version": "6.1.86",
+ "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.86.tgz",
+ "integrity": "sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-number": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=8.0"
+ }
+ },
+ "node_modules/tough-cookie": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.1.2.tgz",
+ "integrity": "sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "tldts": "^6.1.32"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/tr46": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.1.tgz",
+ "integrity": "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "punycode": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/ts-api-utils": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz",
+ "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18.12"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.8.4"
+ }
+ },
+ "node_modules/tsconfig-paths": {
+ "version": "3.15.0",
+ "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz",
+ "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/json5": "^0.0.29",
+ "json5": "^1.0.2",
+ "minimist": "^1.2.6",
+ "strip-bom": "^3.0.0"
+ }
+ },
+ "node_modules/tsconfig-paths/node_modules/json5": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
+ "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "minimist": "^1.2.0"
+ },
+ "bin": {
+ "json5": "lib/cli.js"
+ }
+ },
+ "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==",
+ "license": "0BSD"
+ },
+ "node_modules/type-check": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
+ "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prelude-ls": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/type-fest": {
+ "version": "4.40.1",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.40.1.tgz",
+ "integrity": "sha512-9YvLNnORDpI+vghLU/Nf+zSv0kL47KbVJ1o3sKgoTefl6i+zebxbiDQWoe/oWWqPhIgQdRZRT1KA9sCPL810SA==",
+ "license": "(MIT OR CC0-1.0)",
+ "engines": {
+ "node": ">=16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/typed-array-buffer": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz",
+ "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "es-errors": "^1.3.0",
+ "is-typed-array": "^1.1.14"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/typed-array-byte-length": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz",
+ "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "for-each": "^0.3.3",
+ "gopd": "^1.2.0",
+ "has-proto": "^1.2.0",
+ "is-typed-array": "^1.1.14"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/typed-array-byte-offset": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz",
+ "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "available-typed-arrays": "^1.0.7",
+ "call-bind": "^1.0.8",
+ "for-each": "^0.3.3",
+ "gopd": "^1.2.0",
+ "has-proto": "^1.2.0",
+ "is-typed-array": "^1.1.15",
+ "reflect.getprototypeof": "^1.0.9"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/typed-array-length": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz",
+ "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "for-each": "^0.3.3",
+ "gopd": "^1.0.1",
+ "is-typed-array": "^1.1.13",
+ "possible-typed-array-names": "^1.0.0",
+ "reflect.getprototypeof": "^1.0.6"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/typescript": {
+ "version": "5.7.3",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz",
+ "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=14.17"
+ }
+ },
+ "node_modules/typescript-eslint": {
+ "version": "8.31.0",
+ "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.31.0.tgz",
+ "integrity": "sha512-u+93F0sB0An8WEAPtwxVhFby573E8ckdjwUUQUj9QA4v8JAvgtoDdIyYR3XFwFHq2W1KJ1AurwJCO+w+Y1ixyQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/eslint-plugin": "8.31.0",
+ "@typescript-eslint/parser": "8.31.0",
+ "@typescript-eslint/utils": "8.31.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",
+ "typescript": ">=4.8.4 <5.9.0"
+ }
+ },
+ "node_modules/unbox-primitive": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz",
+ "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "has-bigints": "^1.0.2",
+ "has-symbols": "^1.1.0",
+ "which-boxed-primitive": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/undici-types": {
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
+ "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/unicorn-magic": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz",
+ "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/unrs-resolver": {
+ "version": "1.7.2",
+ "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.7.2.tgz",
+ "integrity": "sha512-BBKpaylOW8KbHsu378Zky/dGh4ckT/4NW/0SHRABdqRLcQJ2dAOjDo9g97p04sWflm0kqPqpUatxReNV/dqI5A==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "dependencies": {
+ "napi-postinstall": "^0.2.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/JounQin"
+ },
+ "optionalDependencies": {
+ "@unrs/resolver-binding-darwin-arm64": "1.7.2",
+ "@unrs/resolver-binding-darwin-x64": "1.7.2",
+ "@unrs/resolver-binding-freebsd-x64": "1.7.2",
+ "@unrs/resolver-binding-linux-arm-gnueabihf": "1.7.2",
+ "@unrs/resolver-binding-linux-arm-musleabihf": "1.7.2",
+ "@unrs/resolver-binding-linux-arm64-gnu": "1.7.2",
+ "@unrs/resolver-binding-linux-arm64-musl": "1.7.2",
+ "@unrs/resolver-binding-linux-ppc64-gnu": "1.7.2",
+ "@unrs/resolver-binding-linux-riscv64-gnu": "1.7.2",
+ "@unrs/resolver-binding-linux-riscv64-musl": "1.7.2",
+ "@unrs/resolver-binding-linux-s390x-gnu": "1.7.2",
+ "@unrs/resolver-binding-linux-x64-gnu": "1.7.2",
+ "@unrs/resolver-binding-linux-x64-musl": "1.7.2",
+ "@unrs/resolver-binding-wasm32-wasi": "1.7.2",
+ "@unrs/resolver-binding-win32-arm64-msvc": "1.7.2",
+ "@unrs/resolver-binding-win32-ia32-msvc": "1.7.2",
+ "@unrs/resolver-binding-win32-x64-msvc": "1.7.2"
+ }
+ },
+ "node_modules/update-browserslist-db": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz",
+ "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "escalade": "^3.2.0",
+ "picocolors": "^1.1.1"
+ },
+ "bin": {
+ "update-browserslist-db": "cli.js"
+ },
+ "peerDependencies": {
+ "browserslist": ">= 4.21.0"
+ }
+ },
+ "node_modules/uri-js": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
+ "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "node_modules/use-callback-ref": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.3.tgz",
+ "integrity": "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==",
+ "license": "MIT",
+ "dependencies": {
+ "tslib": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/use-composed-ref": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/use-composed-ref/-/use-composed-ref-1.4.0.tgz",
+ "integrity": "sha512-djviaxuOOh7wkj0paeO1Q/4wMZ8Zrnag5H6yBvzN7AKKe8beOaED9SF5/ByLqsku8NP4zQqsvM2u3ew/tJK8/w==",
+ "license": "MIT",
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/use-isomorphic-layout-effect": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.2.0.tgz",
+ "integrity": "sha512-q6ayo8DWoPZT0VdG4u3D3uxcgONP3Mevx2i2b0434cwWBoL+aelL1DzkXI6w3PhTZzUeR2kaVlZn70iCiseP6w==",
+ "license": "MIT",
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/use-latest": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/use-latest/-/use-latest-1.3.0.tgz",
+ "integrity": "sha512-mhg3xdm9NaM8q+gLT8KryJPnRFOz1/5XPBhmDEVZK1webPzDjrPk7f/mbpeLqTgB9msytYWANxgALOCJKnLvcQ==",
+ "license": "MIT",
+ "dependencies": {
+ "use-isomorphic-layout-effect": "^1.1.1"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/use-sidecar": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.3.tgz",
+ "integrity": "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==",
+ "license": "MIT",
+ "dependencies": {
+ "detect-node-es": "^1.1.0",
+ "tslib": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/use-sync-external-store": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.5.0.tgz",
+ "integrity": "sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A==",
+ "license": "MIT",
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
+ }
+ },
+ "node_modules/vite": {
+ "version": "6.3.3",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-6.3.3.tgz",
+ "integrity": "sha512-5nXH+QsELbFKhsEfWLkHrvgRpTdGJzqOZ+utSdmPTvwHmvU6ITTm3xx+mRusihkcI8GeC7lCDyn3kDtiki9scw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "esbuild": "^0.25.0",
+ "fdir": "^6.4.4",
+ "picomatch": "^4.0.2",
+ "postcss": "^8.5.3",
+ "rollup": "^4.34.9",
+ "tinyglobby": "^0.2.13"
+ },
+ "bin": {
+ "vite": "bin/vite.js"
+ },
+ "engines": {
+ "node": "^18.0.0 || ^20.0.0 || >=22.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/vitejs/vite?sponsor=1"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.3"
+ },
+ "peerDependencies": {
+ "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0",
+ "jiti": ">=1.21.0",
+ "less": "*",
+ "lightningcss": "^1.21.0",
+ "sass": "*",
+ "sass-embedded": "*",
+ "stylus": "*",
+ "sugarss": "*",
+ "terser": "^5.16.0",
+ "tsx": "^4.8.1",
+ "yaml": "^2.4.2"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ },
+ "jiti": {
+ "optional": true
+ },
+ "less": {
+ "optional": true
+ },
+ "lightningcss": {
+ "optional": true
+ },
+ "sass": {
+ "optional": true
+ },
+ "sass-embedded": {
+ "optional": true
+ },
+ "stylus": {
+ "optional": true
+ },
+ "sugarss": {
+ "optional": true
+ },
+ "terser": {
+ "optional": true
+ },
+ "tsx": {
+ "optional": true
+ },
+ "yaml": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vite-node": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.1.2.tgz",
+ "integrity": "sha512-/8iMryv46J3aK13iUXsei5G/A3CUlW4665THCPS+K8xAaqrVWiGB4RfXMQXCLjpK9P2eK//BczrVkn5JLAk6DA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cac": "^6.7.14",
+ "debug": "^4.4.0",
+ "es-module-lexer": "^1.6.0",
+ "pathe": "^2.0.3",
+ "vite": "^5.0.0 || ^6.0.0"
+ },
+ "bin": {
+ "vite-node": "vite-node.mjs"
+ },
+ "engines": {
+ "node": "^18.0.0 || ^20.0.0 || >=22.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/vite/node_modules/fdir": {
+ "version": "6.4.4",
+ "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.4.tgz",
+ "integrity": "sha512-1NZP+GK4GfuAv3PqKvxQRDMjdSRZjnkq7KfhlNrCNNlZ0ygQFpebfrnfnq/W7fpUnAv9aGWmY1zKx7FYL3gwhg==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "picomatch": "^3 || ^4"
+ },
+ "peerDependenciesMeta": {
+ "picomatch": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vite/node_modules/picomatch": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
+ "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/vitest": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.1.2.tgz",
+ "integrity": "sha512-WaxpJe092ID1C0mr+LH9MmNrhfzi8I65EX/NRU/Ld016KqQNRgxSOlGNP1hHN+a/F8L15Mh8klwaF77zR3GeDQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vitest/expect": "3.1.2",
+ "@vitest/mocker": "3.1.2",
+ "@vitest/pretty-format": "^3.1.2",
+ "@vitest/runner": "3.1.2",
+ "@vitest/snapshot": "3.1.2",
+ "@vitest/spy": "3.1.2",
+ "@vitest/utils": "3.1.2",
+ "chai": "^5.2.0",
+ "debug": "^4.4.0",
+ "expect-type": "^1.2.1",
+ "magic-string": "^0.30.17",
+ "pathe": "^2.0.3",
+ "std-env": "^3.9.0",
+ "tinybench": "^2.9.0",
+ "tinyexec": "^0.3.2",
+ "tinyglobby": "^0.2.13",
+ "tinypool": "^1.0.2",
+ "tinyrainbow": "^2.0.0",
+ "vite": "^5.0.0 || ^6.0.0",
+ "vite-node": "3.1.2",
+ "why-is-node-running": "^2.3.0"
+ },
+ "bin": {
+ "vitest": "vitest.mjs"
+ },
+ "engines": {
+ "node": "^18.0.0 || ^20.0.0 || >=22.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ },
+ "peerDependencies": {
+ "@edge-runtime/vm": "*",
+ "@types/debug": "^4.1.12",
+ "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0",
+ "@vitest/browser": "3.1.2",
+ "@vitest/ui": "3.1.2",
+ "happy-dom": "*",
+ "jsdom": "*"
+ },
+ "peerDependenciesMeta": {
+ "@edge-runtime/vm": {
+ "optional": true
+ },
+ "@types/debug": {
+ "optional": true
+ },
+ "@types/node": {
+ "optional": true
+ },
+ "@vitest/browser": {
+ "optional": true
+ },
+ "@vitest/ui": {
+ "optional": true
+ },
+ "happy-dom": {
+ "optional": true
+ },
+ "jsdom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/w3c-xmlserializer": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz",
+ "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "xml-name-validator": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/web-streams-polyfill": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz",
+ "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/webidl-conversions": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
+ "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/whatwg-encoding": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz",
+ "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "iconv-lite": "0.6.3"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/whatwg-fetch": {
+ "version": "3.6.20",
+ "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz",
+ "integrity": "sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/whatwg-mimetype": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz",
+ "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/whatwg-url": {
+ "version": "14.2.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz",
+ "integrity": "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "tr46": "^5.1.0",
+ "webidl-conversions": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/which-boxed-primitive": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz",
+ "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-bigint": "^1.1.0",
+ "is-boolean-object": "^1.2.1",
+ "is-number-object": "^1.1.1",
+ "is-string": "^1.1.1",
+ "is-symbol": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/which-builtin-type": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz",
+ "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "function.prototype.name": "^1.1.6",
+ "has-tostringtag": "^1.0.2",
+ "is-async-function": "^2.0.0",
+ "is-date-object": "^1.1.0",
+ "is-finalizationregistry": "^1.1.0",
+ "is-generator-function": "^1.0.10",
+ "is-regex": "^1.2.1",
+ "is-weakref": "^1.0.2",
+ "isarray": "^2.0.5",
+ "which-boxed-primitive": "^1.1.0",
+ "which-collection": "^1.0.2",
+ "which-typed-array": "^1.1.16"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/which-collection": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz",
+ "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-map": "^2.0.3",
+ "is-set": "^2.0.3",
+ "is-weakmap": "^2.0.2",
+ "is-weakset": "^2.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/which-typed-array": {
+ "version": "1.1.19",
+ "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz",
+ "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "available-typed-arrays": "^1.0.7",
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.4",
+ "for-each": "^0.3.5",
+ "get-proto": "^1.0.1",
+ "gopd": "^1.2.0",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/why-is-node-running": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz",
+ "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "siginfo": "^2.0.0",
+ "stackback": "0.0.2"
+ },
+ "bin": {
+ "why-is-node-running": "cli.js"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/word-wrap": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz",
+ "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/wrap-ansi": {
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz",
+ "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^6.2.1",
+ "string-width": "^7.0.0",
+ "strip-ansi": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi-cjs": {
+ "name": "wrap-ansi",
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/wrap-ansi/node_modules/ansi-styles": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
+ "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/ws": {
+ "version": "8.18.1",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.1.tgz",
+ "integrity": "sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10.0.0"
+ },
+ "peerDependencies": {
+ "bufferutil": "^4.0.1",
+ "utf-8-validate": ">=5.0.2"
+ },
+ "peerDependenciesMeta": {
+ "bufferutil": {
+ "optional": true
+ },
+ "utf-8-validate": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/xml-name-validator": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz",
+ "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/xmlchars": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz",
+ "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/y18n": {
+ "version": "5.0.8",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
+ "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/yallist": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/yaml": {
+ "version": "2.7.1",
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.1.tgz",
+ "integrity": "sha512-10ULxpnOCQXxJvBgxsn9ptjq6uviG/htZKk9veJGhlqn3w/DxQ631zFF+nlQXLwmImeS5amR2dl2U8sg6U9jsQ==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "yaml": "bin.mjs"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/yargs": {
+ "version": "17.7.2",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
+ "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cliui": "^8.0.1",
+ "escalade": "^3.1.1",
+ "get-caller-file": "^2.0.5",
+ "require-directory": "^2.1.1",
+ "string-width": "^4.2.3",
+ "y18n": "^5.0.5",
+ "yargs-parser": "^21.1.1"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/yargs-parser": {
+ "version": "21.1.1",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
+ "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/yargs/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/yargs/node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/yargs/node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/yargs/node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/yargs/node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/yocto-queue": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
+ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/zod": {
+ "version": "3.24.3",
+ "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.3.tgz",
+ "integrity": "sha512-HhY1oqzWCQWuUqvBFnsyrtZRhyPeR7SUGv+C4+MsisMuVfSPx8HpwWqH8tRahSlt6M3PiFAcoeFhZAqIXTxoSg==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/colinhacks"
+ }
+ },
+ "node_modules/zustand": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.3.tgz",
+ "integrity": "sha512-14fwWQtU3pH4dE0dOpdMiWjddcH+QzKIgk1cl8epwSE7yag43k/AD/m4L6+K7DytAOr9gGBe3/EXj9g7cdostg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.20.0"
+ },
+ "peerDependencies": {
+ "@types/react": ">=18.0.0",
+ "immer": ">=9.0.6",
+ "react": ">=18.0.0",
+ "use-sync-external-store": ">=1.2.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "immer": {
+ "optional": true
+ },
+ "react": {
+ "optional": true
+ },
+ "use-sync-external-store": {
+ "optional": true
+ }
+ }
+ }
+ }
+}
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..d83fd6c
--- /dev/null
+++ b/package.json
@@ -0,0 +1,76 @@
+{
+ "name": "ecommerce-application",
+ "private": true,
+ "version": "0.0.0",
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "ci:format": "prettier --check .",
+ "format": "prettier --write .",
+ "build": "vite build",
+ "lint": "eslint ./src",
+ "lint:fix": "eslint --fix --color ./src",
+ "preview": "vite preview",
+ "prepare": "husky",
+ "test": "vitest run",
+ "coverage": "vitest run --coverage"
+ },
+ "dependencies": {
+ "@commercetools/platform-sdk": "^8.8.0",
+ "@commercetools/sdk-client-v2": "^3.0.0",
+ "@hookform/resolvers": "^5.0.1",
+ "@mantine/carousel": "^7.17.5",
+ "@mantine/core": "^7.17.5",
+ "@mantine/dates": "^7.17.5",
+ "@mantine/form": "^7.17.5",
+ "@mantine/hooks": "^7.17.5",
+ "@mantine/notifications": "^7.17.5",
+ "framer-motion": "^12.9.2",
+ "react": "^19.0.0",
+ "react-dom": "^19.0.0",
+ "react-hook-form": "^7.56.1",
+ "react-router-dom": "^7.6.0",
+ "swr": "^2.3.3",
+ "zod": "^3.24.3",
+ "zustand": "^5.0.3"
+ },
+ "devDependencies": {
+ "@commitlint/cli": "^19.8.0",
+ "@commitlint/config-conventional": "^19.8.0",
+ "@eslint/js": "^9.22.0",
+ "@testing-library/jest-dom": "^6.6.3",
+ "@testing-library/react": "^16.3.0",
+ "@testing-library/user-event": "^14.6.1",
+ "@types/isomorphic-fetch": "^0.0.39",
+ "@types/node": "^22.15.2",
+ "@types/react": "^19.0.10",
+ "@types/react-dom": "^19.0.4",
+ "@typescript-eslint/eslint-plugin": "^8.31.0",
+ "@typescript-eslint/parser": "^8.31.0",
+ "@vitejs/plugin-react": "^4.3.4",
+ "@vitest/coverage-v8": "^3.1.2",
+ "eslint": "^9.22.0",
+ "eslint-config-prettier": "^10.1.2",
+ "eslint-import-resolver-typescript": "^4.3.4",
+ "eslint-plugin-import": "^2.31.0",
+ "eslint-plugin-jsx-a11y": "^6.10.2",
+ "eslint-plugin-prettier": "^5.2.6",
+ "eslint-plugin-react-hooks": "^5.2.0",
+ "eslint-plugin-react-refresh": "^0.4.19",
+ "globals": "^16.0.0",
+ "husky": "^9.1.7",
+ "isomorphic-fetch": "^3.0.0",
+ "jsdom": "^26.1.0",
+ "lint-staged": "^15.5.1",
+ "node-fetch": "^3.3.2",
+ "prettier": "^3.5.3",
+ "typescript": "~5.7.2",
+ "typescript-eslint": "^8.26.1",
+ "vite": "^6.3.1",
+ "vitest": "^3.1.2"
+ },
+ "lint-staged": {
+ "*.{json, md, css, scss}": "prettier --list-different --ignore-unknown",
+ "*.{cjs,js,mjs,jsx,ts,tsx}": "eslint"
+ }
+}
diff --git a/public/_redirects b/public/_redirects
new file mode 100644
index 0000000..f824337
--- /dev/null
+++ b/public/_redirects
@@ -0,0 +1 @@
+/* /index.html 200
\ No newline at end of file
diff --git a/public/favicon.ico b/public/favicon.ico
new file mode 100644
index 0000000..7310704
Binary files /dev/null and b/public/favicon.ico differ
diff --git a/src/App.css b/src/App.css
new file mode 100644
index 0000000..8336a82
--- /dev/null
+++ b/src/App.css
@@ -0,0 +1,42 @@
+#root {
+ max-width: 1920px;
+ margin: 0 auto;
+ padding: 2rem;
+ text-align: center;
+}
+
+.logo {
+ height: 6em;
+ padding: 1.5em;
+ will-change: filter;
+ transition: filter 300ms;
+}
+.logo:hover {
+ filter: drop-shadow(0 0 2em #646cffaa);
+}
+.logo.react:hover {
+ filter: drop-shadow(0 0 2em #61dafbaa);
+}
+
+@keyframes logo-spin {
+ from {
+ transform: rotate(0deg);
+ }
+ to {
+ transform: rotate(360deg);
+ }
+}
+
+@media (prefers-reduced-motion: no-preference) {
+ a:nth-of-type(2) .logo {
+ animation: logo-spin infinite 20s linear;
+ }
+}
+
+.card {
+ padding: 2em;
+}
+
+.read-the-docs {
+ color: #888;
+}
diff --git a/src/App.tsx b/src/App.tsx
new file mode 100644
index 0000000..5273a5e
--- /dev/null
+++ b/src/App.tsx
@@ -0,0 +1,10 @@
+import '@mantine/core/styles.css';
+import '@mantine/carousel/styles.css';
+import '@mantine/dates/styles.css';
+import { AppProvider } from '@/app/providers';
+
+function App() {
+ return ;
+}
+
+export default App;
diff --git a/src/app/layouts/AuthLayouts.tsx b/src/app/layouts/AuthLayouts.tsx
new file mode 100644
index 0000000..d4927ae
--- /dev/null
+++ b/src/app/layouts/AuthLayouts.tsx
@@ -0,0 +1,17 @@
+import { AppShell } from '@mantine/core';
+import { Header } from '@/components/Header/Header.tsx';
+import { AnimatedOutlet } from '@/shared/ui/AnimatedOutlet';
+
+export function AuthLayout() {
+ return (
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/src/app/layouts/ErrorLayout.tsx b/src/app/layouts/ErrorLayout.tsx
new file mode 100644
index 0000000..94310dc
--- /dev/null
+++ b/src/app/layouts/ErrorLayout.tsx
@@ -0,0 +1,17 @@
+import { AppShell } from '@mantine/core';
+import { Header } from '@/components/Header/Header';
+import { AnimatedOutlet } from '@/shared/ui/AnimatedOutlet';
+
+export function ErrorLayout() {
+ return (
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/src/app/layouts/MainLayout.tsx b/src/app/layouts/MainLayout.tsx
new file mode 100644
index 0000000..b3e3558
--- /dev/null
+++ b/src/app/layouts/MainLayout.tsx
@@ -0,0 +1,26 @@
+import { AppShell } from '@mantine/core';
+import { Footer } from '@/components/Footer/Footer';
+import { Header } from '@/components/Header/Header';
+import { AnimatedOutlet } from '@/shared/ui/AnimatedOutlet';
+
+export function MainLayout() {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/src/app/providers.tsx b/src/app/providers.tsx
new file mode 100644
index 0000000..6f2df21
--- /dev/null
+++ b/src/app/providers.tsx
@@ -0,0 +1,58 @@
+import '@mantine/notifications/styles.css';
+import { MantineProvider } from '@mantine/core';
+import { Notifications } from '@mantine/notifications';
+import { Suspense, useEffect } from 'react';
+import { RouterProvider } from 'react-router-dom';
+import { router } from '@/app/router';
+import { theme } from '@/app/theme';
+import { useAuthStore } from '@/features/auth/auth-state';
+import { getCart } from '@/shared/hooks/useCartStore';
+import { apiClientManager } from '@/shared/lib/commercetools';
+import { CenterLoader } from '@/shared/ui/CenterLoader';
+import { notifyError } from '@/shared/utils/custom-notifications';
+
+export const AppProvider = () => {
+ const { setPending, setUnauthenticated, setAuthenticated, setClientReady } =
+ useAuthStore();
+
+ useEffect(() => {
+ const initializeApp = async () => {
+ setPending();
+ try {
+ const { authType } = await apiClientManager.init();
+ setClientReady(true);
+
+ await getCart();
+
+ if (authType === 'password') {
+ setAuthenticated();
+ } else {
+ setUnauthenticated();
+ }
+ } catch (err) {
+ notifyError(err, { message: 'Failed to connect to commercetools' });
+ setUnauthenticated();
+ setClientReady(true);
+ }
+ };
+
+ initializeApp();
+ }, [
+ setUnauthenticated,
+ setPending,
+ setAuthenticated,
+ setClientReady,
+ ]);
+
+ return (
+
+
+ }>
+
+
+
+ );
+};
diff --git a/src/app/router.tsx b/src/app/router.tsx
new file mode 100644
index 0000000..eebf8f1
--- /dev/null
+++ b/src/app/router.tsx
@@ -0,0 +1,113 @@
+import { lazy, useEffect } from 'react';
+import {
+ createBrowserRouter,
+ Navigate,
+ Outlet,
+ useNavigate,
+ useLocation,
+} from 'react-router-dom';
+import { AuthLayout } from '@/app/layouts/AuthLayouts';
+import { ErrorLayout } from '@/app/layouts/ErrorLayout';
+import { MainLayout } from '@/app/layouts/MainLayout';
+import { ROUTES } from '@/app/routes';
+import { useAuthStore } from '@/features/auth/auth-state';
+import { HomePage } from '@/pages/HomePage/HomePage';
+import { CenterLoader } from '@/shared/ui/CenterLoader';
+
+const CatalogPage = lazy(() => import('@/pages/CatalogPage/CatalogPage'));
+const ProductPage = lazy(() => import('@/pages/ProductPage/ProductPage'));
+const ProfilePage = lazy(() => import('@/pages/ProfilePage/ProfilePage'));
+const LoginPage = lazy(() => import('@/pages/LoginPage'));
+const RegistrationPage = lazy(
+ () => import('@/pages/RegistrationPage/RegistrationPage'),
+);
+const AboutUsPage = lazy(() => import('@/pages/AboutPage/AboutPage'));
+const NotFoundPage = lazy(() => import('@/pages/NotFoundPage/NotFoundPage'));
+const CartPage = lazy(() => import('@/pages/CartPage/CartPage'));
+
+const RedirectGuard = () => {
+ const navigate = useNavigate();
+ const location = useLocation();
+ const isNeedToRedirect = useAuthStore((state) => state.isNeedToRedirect);
+ const resetRedirect = useAuthStore((state) => state.resetRedirect);
+
+ useEffect(() => {
+ if (isNeedToRedirect) {
+ navigate(ROUTES.HOME);
+ resetRedirect();
+ }
+ }, [isNeedToRedirect, navigate, resetRedirect, location.pathname]);
+
+ return ;
+};
+
+const AuthGuard = () => {
+ const { status } = useAuthStore();
+ console.log('[AuthGuard] status:', status);
+
+ if (status === 'PENDING') {
+ return ;
+ }
+
+ return status === 'AUTHENTICATED' ? (
+
+ ) : (
+
+ );
+};
+
+const PrivateGuard = () => {
+ const { status } = useAuthStore();
+ const location = useLocation();
+ console.log('[PrivateGuard] status:', status);
+
+ if (status === 'PENDING') {
+ return ;
+ }
+
+ return status === 'AUTHENTICATED' ? (
+
+ ) : (
+
+ );
+};
+
+export const router = createBrowserRouter([
+ {
+ element: ,
+ errorElement: ,
+ children: [
+ { path: ROUTES.HOME, element: },
+ {
+ element: ,
+ children: [
+ { path: ROUTES.CATALOG, element: },
+ { path: ROUTES.PRODUCT, element: },
+ { path: ROUTES.CART, element: },
+ { path: ROUTES.ABOUT, element: },
+ {
+ element: ,
+ children: [{ path: ROUTES.PROFILE, element: }],
+ },
+ ],
+ },
+ ],
+ },
+ {
+ element: ,
+ children: [
+ {
+ element: ,
+ children: [
+ { path: ROUTES.LOGIN, element: },
+ { path: ROUTES.REGISTRATION, element: },
+ ],
+ },
+ ],
+ },
+ {
+ path: ROUTES.NOT_FOUND,
+ element: ,
+ children: [{ path: ROUTES.NOT_FOUND, element: }],
+ },
+]);
diff --git a/src/app/routes.tsx b/src/app/routes.tsx
new file mode 100644
index 0000000..9343b5c
--- /dev/null
+++ b/src/app/routes.tsx
@@ -0,0 +1,11 @@
+export const ROUTES = {
+ HOME: '/',
+ LOGIN: '/login',
+ REGISTRATION: '/registration',
+ CATALOG: '/catalog',
+ PRODUCT: '/product/:id',
+ PROFILE: '/profile',
+ CART: '/cart',
+ ABOUT: '/about',
+ NOT_FOUND: '*',
+} as const;
diff --git a/src/app/theme.ts b/src/app/theme.ts
new file mode 100644
index 0000000..f01bccf
--- /dev/null
+++ b/src/app/theme.ts
@@ -0,0 +1,235 @@
+import { createTheme, MantineColorsTuple, rem, Container } from '@mantine/core';
+
+const primaryColors: MantineColorsTuple = [
+ '#f8f9fb', // 0 primary text
+ '#e6e9f2',
+ '#d4d8e9',
+ '#8a9dc0', // 3 secondary text
+ '#6d7fa2',
+ '#516185',
+ '#3a4d6d',
+ '#29374c', // 7 Back
+ '#1d2a36', // 8
+ '#141c24', // 9
+];
+
+const accentColors: MantineColorsTuple = [
+ '#fef9e6',
+ '#fdf0c4',
+ '#fbe79f',
+ '#fade77',
+ '#f4c753', // 4 gold
+ '#e6b945',
+ '#d8ab37',
+ '#ca9d29',
+ '#bc8f1b',
+ '#ae810d',
+];
+
+const darkColors: MantineColorsTuple = [
+ '#f0f4f8',
+ '#d9e2ec',
+ '#bcccdc',
+ '#9fb3c8',
+ '#829ab1',
+ '#32415d', // 5 border
+ '#1d2a36', // 6 cards
+ '#131c24', // 7 background
+ '#0a1018',
+ '#00070f',
+];
+
+const redColors: MantineColorsTuple = [
+ '#ffebee',
+ '#ffcdd2',
+ '#ef9a9a',
+ '#e57373',
+ '#ef5350',
+ '#f44336',
+ '#e53935',
+ '#d32f2f',
+ '#c62828',
+ '#8b0000', // 9 logo
+];
+
+export const theme = createTheme({
+ primaryColor: 'accent',
+ primaryShade: 4,
+ colors: {
+ primary: primaryColors,
+ accent: accentColors,
+ dark: darkColors,
+ red: redColors,
+ },
+ fontFamily: '"Plus Jakarta Sans", "Noto Sans", sans-serif',
+ headings: {
+ fontFamily: '"Plus Jakarta Sans", sans-serif',
+ sizes: {
+ h1: { fontSize: rem(28), lineHeight: '1.25' },
+ h2: { fontSize: rem(24), lineHeight: '1.25' },
+ h3: { fontSize: rem(20), lineHeight: '1.25' },
+ h4: { fontSize: rem(18), lineHeight: '1.25' },
+ },
+ },
+ spacing: {
+ xs: rem(8),
+ sm: rem(12),
+ md: rem(16),
+ lg: rem(24),
+ xl: rem(32),
+ },
+ radius: {
+ xs: rem(4),
+ sm: rem(8),
+ md: rem(12),
+ lg: rem(16),
+ xl: rem(20),
+ },
+ shadows: {
+ sm: '0 1px 3px rgba(0, 0, 0, 0.1)',
+ md: '0 4px 6px rgba(0, 0, 0, 0.1)',
+ lg: '0 10px 15px rgba(0, 0, 0, 0.1)',
+ },
+ components: {
+ AppShell: {
+ styles: {
+ root: {
+ backgroundColor: darkColors[7],
+ },
+ main: {
+ // paddingTop: 0,
+ paddingLeft: 0,
+ paddingRight: 0,
+ },
+ },
+ },
+ Header: {
+ styles: {
+ root: {
+ backgroundColor: darkColors[7],
+ borderBottom: `${rem(1)} solid ${darkColors[5]}`,
+ padding: `${rem(12)} ${rem(24)}`,
+ },
+ },
+ },
+ Footer: {
+ styles: {
+ root: {
+ backgroundColor: darkColors[7],
+ borderTop: `${rem(1)} solid ${darkColors[5]}`,
+ padding: `${rem(20)} ${rem(0)}`,
+ },
+ },
+ },
+ Title: {
+ styles: {
+ root: {
+ color: primaryColors[1],
+ },
+ },
+ },
+ Text: {
+ styles: {
+ root: {
+ color: primaryColors[1],
+ },
+ },
+ },
+ Container: Container.extend({
+ styles: () => ({
+ root: {
+ maxWidth: rem(1920),
+ },
+ }),
+ }),
+ Button: {
+ styles: {
+ root: {
+ transition: 'all 0.3s ease-in-out',
+ },
+ },
+ },
+ Carousel: {
+ styles: {
+ root: {
+ transition: 'all 0.3s ease-in-out',
+ },
+ viewport: {
+ overflowY: 'visible',
+ },
+ slide: {
+ display: 'flex',
+ alignItems: 'center',
+ justifyContent: 'center',
+ },
+ container: {
+ alignItems: 'stretch',
+ },
+ },
+ },
+ Loader: {
+ defaultProps: {
+ type: 'dots',
+ color: accentColors[4],
+ },
+ },
+ Fieldset: {
+ styles: {
+ root: {
+ backgroundColor: darkColors[6],
+ padding: '0 0.5rem',
+ },
+ },
+ },
+ TextInput: {
+ styles: {
+ root: {
+ borderColor: darkColors[6],
+ },
+ },
+ },
+ Paper: {
+ styles: {
+ root: {
+ backgroundColor: darkColors[6],
+ },
+ },
+ },
+ Anchor: {
+ styles: {
+ root: {
+ color: darkColors[2],
+ transition: 'all 0.3s ease-in-out',
+ },
+ },
+ },
+ CloseButton: {
+ styles: {
+ root: {
+ color: darkColors[6],
+ transition: 'all 0.3s ease-in-out',
+ },
+ },
+ },
+ Modal: {
+ styles: {
+ root: {
+ backgroundColor: darkColors[6],
+ },
+ header: {
+ backgroundColor: darkColors[6],
+ },
+ close: {
+ color: darkColors[4],
+ }
+ },
+ },
+ Notification: {
+ styles: {
+ closeButton: {
+ color: darkColors[4],
+ }
+ }
+ }
+ },
+});
diff --git a/src/assets/Aleksei_11.webp b/src/assets/Aleksei_11.webp
new file mode 100644
index 0000000..a5ec5f7
Binary files /dev/null and b/src/assets/Aleksei_11.webp differ
diff --git a/src/assets/Anna_9455.webp b/src/assets/Anna_9455.webp
new file mode 100644
index 0000000..d81563c
Binary files /dev/null and b/src/assets/Anna_9455.webp differ
diff --git a/src/assets/Vika_12.webp b/src/assets/Vika_12.webp
new file mode 100644
index 0000000..cf08c62
Binary files /dev/null and b/src/assets/Vika_12.webp differ
diff --git a/src/assets/avatar_1.png b/src/assets/avatar_1.png
new file mode 100644
index 0000000..1321ba5
Binary files /dev/null and b/src/assets/avatar_1.png differ
diff --git a/src/assets/avatar_2.png b/src/assets/avatar_2.png
new file mode 100644
index 0000000..c6f11c5
Binary files /dev/null and b/src/assets/avatar_2.png differ
diff --git a/src/assets/avatar_3.jpeg b/src/assets/avatar_3.jpeg
new file mode 100644
index 0000000..b212812
Binary files /dev/null and b/src/assets/avatar_3.jpeg differ
diff --git a/src/assets/fallback_1.png b/src/assets/fallback_1.png
new file mode 100644
index 0000000..d8fa35b
Binary files /dev/null and b/src/assets/fallback_1.png differ
diff --git a/src/assets/react.svg b/src/assets/react.svg
new file mode 100644
index 0000000..6c87de9
--- /dev/null
+++ b/src/assets/react.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/rsschool-logo.png b/src/assets/rsschool-logo.png
new file mode 100644
index 0000000..a68bb96
Binary files /dev/null and b/src/assets/rsschool-logo.png differ
diff --git a/src/assets/wine.webp b/src/assets/wine.webp
new file mode 100644
index 0000000..18e2764
Binary files /dev/null and b/src/assets/wine.webp differ
diff --git a/src/components/Card/FeatureCard.tsx b/src/components/Card/FeatureCard.tsx
new file mode 100644
index 0000000..54419d7
--- /dev/null
+++ b/src/components/Card/FeatureCard.tsx
@@ -0,0 +1,19 @@
+import { Card, Title, Text} from '@mantine/core';
+import { FeatureCardProps } from '@/types/types';
+
+
+export function FeatureCard({ feature }: FeatureCardProps) {
+ return (
+
+ {feature.icon}
+
+
+ {feature.title}
+
+
+ {feature.description}
+
+
+
+ )
+}
diff --git a/src/components/Card/ProductCard.tsx b/src/components/Card/ProductCard.tsx
new file mode 100644
index 0000000..1715ce3
--- /dev/null
+++ b/src/components/Card/ProductCard.tsx
@@ -0,0 +1,130 @@
+import { Card, Text, Group, Image, Box, Button } from '@mantine/core';
+import { useEffect } from 'react';
+import { Link, useNavigate } from 'react-router-dom';
+import { ROUTES } from '@/app/routes.tsx';
+import { useImageHandler } from '@/shared/hooks/useImageHandler.ts';
+import { WineCardProps } from '@/types/types';
+
+export function ProductCard({ wine }: WineCardProps) {
+ const navigate = useNavigate();
+ const { handleImageLoad, imgRef, checkImage } = useImageHandler();
+
+ useEffect((): void => {
+ if (imgRef.current) {
+ checkImage(imgRef.current);
+ }
+ }, [wine.image, checkImage]);
+
+ return (
+
+ navigate(ROUTES.PRODUCT.replace(':id', wine.id.toString()))
+ }
+ style={{
+ display: 'flex',
+ width: '100%',
+ height: '100%',
+ maxWidth: 400,
+ flexDirection: 'column',
+ justifyContent: 'space-between',
+ }}
+ >
+
+
+
+
+
+
+
+ {wine.title}
+
+
+
+
+
+
+ {wine.description}
+
+
+
+ ★ {wine.rating}
+
+
+ /5
+
+
+
+
+
+
+ {wine.discountedPrice ? (
+
+
+ ${wine.discountedPrice}
+
+
+ ${wine.price}
+
+
+ ) : (
+
+ ${wine.price}
+
+ )}
+
+
+
+
+ );
+}
diff --git a/src/components/Card/TeamMemberCard.tsx b/src/components/Card/TeamMemberCard.tsx
new file mode 100644
index 0000000..80c7809
--- /dev/null
+++ b/src/components/Card/TeamMemberCard.tsx
@@ -0,0 +1,42 @@
+import { Anchor, Avatar, Card, Group, List, Stack, Text, Title, useMantineTheme } from "@mantine/core";
+import { TeamMemberCardProps } from "@/types/types";
+
+export function TeamMemberCard({ member }: TeamMemberCardProps) {
+ const theme = useMantineTheme();
+
+ return (
+
+
+
+
+ {member.name}
+
+
+ {member.role}
+
+
+
+
+ {member.github.substring(member.github.lastIndexOf('/') + 1)}
+
+
+
+ {member.description}
+
+
+ {member.contributions.map((item, index) => (
+ {item}
+ ))}
+
+
+
+ )
+}
\ No newline at end of file
diff --git a/src/components/CartMessage/CartMessage.tsx b/src/components/CartMessage/CartMessage.tsx
new file mode 100644
index 0000000..3440cc0
--- /dev/null
+++ b/src/components/CartMessage/CartMessage.tsx
@@ -0,0 +1,60 @@
+import { Box, Button, Container, Group, Text, Title, useMantineTheme } from '@mantine/core';
+import { Link } from 'react-router-dom';
+import { ROUTES } from '@/app/routes.tsx';
+import '@/pages/CartPage/CartPage.css'
+
+export function CartMessage() {
+ const theme = useMantineTheme();
+
+ return (
+
+
+
+
+
+ Wine not
+
+
+
+ Your shopping cart is empty
+
+
+ 🛒
+
+
+
+
+ );
+}
diff --git a/src/components/Footer/Footer.tsx b/src/components/Footer/Footer.tsx
new file mode 100644
index 0000000..c201336
--- /dev/null
+++ b/src/components/Footer/Footer.tsx
@@ -0,0 +1,70 @@
+import { Container, Box, Text } from '@mantine/core';
+import { Link } from 'react-router-dom';
+
+export function Footer() {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ©2025 Wine not. All rights reserved.
+
+
+ );
+}
diff --git a/src/components/Header/Header.tsx b/src/components/Header/Header.tsx
new file mode 100644
index 0000000..fe0cda5
--- /dev/null
+++ b/src/components/Header/Header.tsx
@@ -0,0 +1,263 @@
+import {
+ useMantineTheme,
+ Button,
+ Burger,
+ Box,
+ Group,
+ Title,
+ Text,
+ Menu,
+ Anchor,
+ Indicator,
+} from '@mantine/core';
+import { useDisclosure, useClickOutside, useMediaQuery } from '@mantine/hooks';
+import { useEffect } from 'react';
+import { Link, useLocation } from 'react-router-dom';
+import { ROUTES } from '@/app/routes';
+import { useAuthStore } from '@/features/auth/auth-state';
+import { useCartStore } from '@/shared/hooks/useCartStore';
+import { apiClientManager } from '@/shared/lib/commercetools/api-client-manager';
+
+export function Header() {
+ const status = useAuthStore((state) => state.status);
+ const isAuthenticated = status === 'AUTHENTICATED';
+ const location = useLocation();
+
+ const cart = useCartStore((state) => state.cart);
+ const itemCount = cart?.lineItems.length ?? 0;
+
+ const handleLogout = async () => {
+ useAuthStore.getState().setClientReady(false);
+ await apiClientManager.logout();
+ useAuthStore.getState().setClientReady(true);
+ useAuthStore.getState().logout();
+ close();
+ };
+
+ const theme = useMantineTheme();
+ const [opened, { toggle, close }] = useDisclosure();
+ const isLargeScreen = useMediaQuery('(min-width: 768px)');
+
+ useEffect(() => {
+ const scrollbarWidth =
+ window.innerWidth - document.documentElement.clientWidth;
+
+ if (opened) {
+ document.body.classList.add('no-scroll');
+ document.body.style.paddingRight = `${scrollbarWidth}px`;
+ } else {
+ document.body.classList.remove('no-scroll');
+ document.body.style.paddingRight = '';
+ }
+
+ return () => {
+ document.body.classList.remove('no-scroll');
+ document.body.style.paddingRight = '';
+ };
+ }, [opened]);
+
+ useEffect(() => {
+ if (isLargeScreen) close();
+ }, [isLargeScreen, close]);
+
+ useEffect(() => {
+ close();
+ }, [location.pathname, close]);
+
+ useClickOutside(
+ () => opened && close(),
+ ['mousedown', 'touchstart'],
+ [
+ document.querySelector('.header__nav'),
+ document.querySelector('.burger-button'),
+ ].filter((el): el is HTMLElement => el !== null),
+ );
+
+ return (
+
+
+
+
+ Wine not?
+
+
+
+
+
+
+ Main
+
+
+ Catalog
+
+
+ About us
+
+
+ Cart
+
+
+ {opened ? (
+ isAuthenticated ? (
+ <>
+
+ Profile
+
+
+ >
+ ) : (
+ <>
+
+
+ >
+ )
+ ) : null}
+
+ {!opened && (
+ <>
+
+
+
+
+
+ >
+ )}
+
+
+ );
+}
diff --git a/src/components/Slider/Slider.tsx b/src/components/Slider/Slider.tsx
new file mode 100644
index 0000000..4dfe6a3
--- /dev/null
+++ b/src/components/Slider/Slider.tsx
@@ -0,0 +1,46 @@
+import { Carousel } from '@mantine/carousel';
+import { Box, Title } from '@mantine/core';
+import { useAuthStore } from '@/features/auth/auth-state';
+import { CatalogProductCard } from '@/features/catalog/CatalogProductCard';
+import { useFeaturedProducts } from '@/features/catalog/useFeatureProduct';
+import { CenterLoader } from '@/shared/ui/CenterLoader';
+
+export function Slider() {
+ const clientReady = useAuthStore((s) => s.clientReady);
+ const { data, isLoading } = useFeaturedProducts();
+
+ if (!clientReady || isLoading || !data || data.length === 0) {
+ return ;
+ }
+
+ return (
+
+ Featured Selections
+
+ {data.map((wine) => {
+ return (
+
+
+
+ );
+ })}
+
+
+ );
+}
diff --git a/src/features/auth/auth-state.ts b/src/features/auth/auth-state.ts
new file mode 100644
index 0000000..13ab571
--- /dev/null
+++ b/src/features/auth/auth-state.ts
@@ -0,0 +1,43 @@
+import { create } from 'zustand';
+import { persist, createJSONStorage } from 'zustand/middleware';
+
+export type AuthStatus = 'AUTHENTICATED' | 'UNAUTHENTICATED' | 'PENDING';
+
+export type AuthState = {
+ status: AuthStatus;
+ isNeedToRedirect: boolean;
+ setAuthenticated: () => void;
+ logout: () => void;
+ setPending: () => void;
+ resetRedirect: () => void;
+ setUnauthenticated: () => void;
+ clientReady: boolean;
+ setClientReady: (ready: boolean) => void;
+};
+
+export const useAuthStore = create()(
+ persist(
+ (set) => ({
+ status: 'UNAUTHENTICATED',
+ isNeedToRedirect: false,
+ clientReady: false,
+ setClientReady: (ready: boolean) => set({ clientReady: ready }),
+ setAuthenticated: () => set({ status: 'AUTHENTICATED' }),
+ logout: () =>
+ set({
+ status: 'UNAUTHENTICATED',
+ isNeedToRedirect: true,
+ }),
+ setPending: () => set({ status: 'PENDING' }),
+ resetRedirect: () => set({ isNeedToRedirect: false }),
+ setUnauthenticated: () => set({ status: 'UNAUTHENTICATED' }),
+ }),
+ {
+ name: 'auth-store',
+ storage: createJSONStorage(() => localStorage),
+ partialize: (state) => ({
+ status: state.status,
+ }),
+ },
+ ),
+);
diff --git a/src/features/catalog/CatalogProductCard.tsx b/src/features/catalog/CatalogProductCard.tsx
new file mode 100644
index 0000000..861b0fd
--- /dev/null
+++ b/src/features/catalog/CatalogProductCard.tsx
@@ -0,0 +1,189 @@
+import { Card, Text, Group, Image, Box, Button } from '@mantine/core';
+import { generatePath, Link, useNavigate } from 'react-router-dom';
+import { ROUTES } from '@/app/routes.tsx';
+import { ProductCard as WineCard } from '@/shared/schemas/product-card-schema';
+import {
+ addToCart,
+ useCartStore,
+ removeFromCart,
+} from '@/shared/hooks/useCartStore.ts';
+import {
+ notifySuccess,
+ notifyError,
+} from '@/shared/utils/custom-notifications';
+import { useState } from 'react';
+
+type ProductCardProps = {
+ wine: WineCard;
+};
+
+export function CatalogProductCard({ wine }: ProductCardProps) {
+ const navigate = useNavigate();
+
+ const cart = useCartStore((state) => state.cart);
+ const cartItem = cart?.lineItems.find(
+ (item) => item.productId === wine.id && item.variant?.id === 1,
+ );
+
+ const cartCurrency = cart?.totalPrice.currencyCode || 'EUR';
+
+ const formatCurrency = (price: number, currencyCode: string) => {
+ return new Intl.NumberFormat('en-US', {
+ style: 'currency',
+ currency: currencyCode,
+ }).format(price);
+ };
+
+ const [isProcessing, setIsProcessing] = useState(false);
+
+ const handleAddToCart = async (e: React.MouseEvent) => {
+ e.stopPropagation();
+ if (isProcessing) return;
+
+ setIsProcessing(true);
+ try {
+ await addToCart(wine.id);
+ notifySuccess({ message: 'Added to cart', autoClose: 2000 });
+ } catch (error) {
+ notifyError(error, { message: 'Failed adding to cart' });
+ } finally {
+ setIsProcessing(false);
+ }
+ };
+
+ const handleRemove = async (e: React.MouseEvent) => {
+ e.stopPropagation();
+ if (!cartItem || isProcessing) return;
+
+ setIsProcessing(true);
+ try {
+ await removeFromCart(cartItem.id);
+ notifySuccess({ message: 'Product removed', autoClose: 2000 });
+ } catch (error) {
+ notifyError(error, { message: 'Failed to remove' });
+ } finally {
+ setIsProcessing(false);
+ }
+ };
+
+ return (
+ navigate(generatePath(ROUTES.PRODUCT, { id: wine.id }))}
+ style={{
+ display: 'flex',
+ width: '100%',
+ height: '100%',
+ maxWidth: 400,
+ flexDirection: 'column',
+ justifyContent: 'space-between',
+ }}
+ >
+
+
+
+
+
+
+
+ {wine.name}
+
+
+
+
+
+
+ {wine.country}
+
+
+
+ ★ {wine.rating}
+
+
+ /5
+
+
+
+
+
+
+ {typeof wine.discountedPrice === 'number' ? (
+
+
+ {formatCurrency(wine.discountedPrice, cartCurrency)}
+
+
+ {formatCurrency(wine.price, cartCurrency)}
+
+
+ ) : (
+
+ {formatCurrency(wine.price, cartCurrency)}
+
+ )}
+
+ {cartItem ? (
+
+ ) : (
+
+ )}
+
+
+ );
+}
diff --git a/src/features/catalog/ProductCardList.tsx b/src/features/catalog/ProductCardList.tsx
new file mode 100644
index 0000000..db968bc
--- /dev/null
+++ b/src/features/catalog/ProductCardList.tsx
@@ -0,0 +1,24 @@
+import { Grid } from '@mantine/core';
+import { CatalogProductCard } from '@/features/catalog/CatalogProductCard';
+import { ProductCard } from '@/shared/schemas/product-card-schema';
+
+export function ProductCardList({ products }: { products: ProductCard[] }) {
+ return (
+
+ {products.map((product) => (
+
+
+
+ ))}
+
+ );
+}
diff --git a/src/features/catalog/map-product-to-card-util.ts b/src/features/catalog/map-product-to-card-util.ts
new file mode 100644
index 0000000..2dbcafc
--- /dev/null
+++ b/src/features/catalog/map-product-to-card-util.ts
@@ -0,0 +1,43 @@
+import { ProductProjection } from '@commercetools/platform-sdk';
+import { ProductCard } from '@/shared/schemas/product-card-schema';
+
+export function mapProductToCard(product: ProductProjection): ProductCard {
+ const variant = product.masterVariant;
+ const priceInfo = variant.prices?.[0];
+
+ const attributes = Object.fromEntries(
+ (variant.attributes ?? []).map((attr) => [attr.name, attr.value]),
+ );
+
+ const ratingAttribute: unknown = attributes.rating;
+ const rating =
+ typeof ratingAttribute === 'string'
+ ? parseFloat(String(ratingAttribute))
+ : undefined;
+
+ const country =
+ typeof attributes.country === 'string' ? attributes.country : '';
+ const year = typeof attributes.year === 'string' ? attributes.year : '';
+
+ const description =
+ product.description && typeof product.description['en-US'] === 'string'
+ ? product.description['en-US']
+ : undefined;
+
+ return {
+ id: product.id,
+ key: product.key ?? '',
+ name: product.name['en-US'],
+ image: variant.images?.[0]?.url ?? '',
+ price: priceInfo?.value.centAmount ? priceInfo.value.centAmount / 100 : 0,
+ discountedPrice: priceInfo?.discounted?.value.centAmount
+ ? priceInfo.discounted.value.centAmount / 100
+ : undefined,
+ currency: priceInfo?.value.currencyCode ?? 'EUR',
+ rating:
+ rating && !isNaN(rating) ? Math.min(Math.max(rating, 0), 5) : undefined,
+ country,
+ year,
+ description,
+ };
+}
diff --git a/src/features/catalog/sort-map-util.ts b/src/features/catalog/sort-map-util.ts
new file mode 100644
index 0000000..363dc7f
--- /dev/null
+++ b/src/features/catalog/sort-map-util.ts
@@ -0,0 +1,8 @@
+export const sortMap: Record = {
+ price_asc: 'price asc',
+ price_desc: 'price desc',
+ rating_desc: 'variants.attributes.rating desc',
+ rating_asc: 'variants.attributes.rating asc',
+ year_desc: 'variants.attributes.year desc',
+ year_asc: 'variants.attributes.year asc',
+};
diff --git a/src/features/catalog/useCategories.ts b/src/features/catalog/useCategories.ts
new file mode 100644
index 0000000..4f3fcd7
--- /dev/null
+++ b/src/features/catalog/useCategories.ts
@@ -0,0 +1,54 @@
+import { z } from 'zod';
+import { useValidatedSWR } from '@/shared/hooks/custom-use-swr';
+
+const CategorySchema = z.object({
+ id: z.string(),
+ name: z.record(z.string(), z.string()),
+ slug: z.record(z.string(), z.string()),
+});
+
+export type Category = z.infer;
+
+const fallbackCategories: Category[] = [
+ {
+ id: 'fallback-1',
+ slug: { 'en-US': 'red' },
+ name: { 'en-US': 'Red' },
+ },
+ {
+ id: 'fallback-2',
+ slug: { 'en-US': 'white' },
+ name: { 'en-US': 'White' },
+ },
+ {
+ id: 'fallback-3',
+ slug: { 'en-US': 'rose' },
+ name: { 'en-US': 'Rose' },
+ },
+ {
+ id: 'fallback-4',
+ slug: { 'en-US': 'sparkling' },
+ name: { 'en-US': 'Sparkling' },
+ },
+ {
+ id: 'fallback-5',
+ slug: { 'en-US': 'dessert' },
+ name: { 'en-US': 'Dessert' },
+ },
+];
+
+export function useCategories() {
+ return useValidatedSWR(
+ ['categories'],
+ (client) =>
+ client
+ .categories()
+ .get({ queryArgs: { limit: 10 } })
+ .execute()
+ .then((res) => res.body.results),
+ z.array(CategorySchema),
+ {
+ fallbackData: fallbackCategories,
+ },
+ );
+}
diff --git a/src/features/catalog/useFeatureProduct.ts b/src/features/catalog/useFeatureProduct.ts
new file mode 100644
index 0000000..c97d08b
--- /dev/null
+++ b/src/features/catalog/useFeatureProduct.ts
@@ -0,0 +1,19 @@
+import { mapProductToCard } from '@/features/catalog/map-product-to-card-util';
+import { useValidatedSWR } from '@/shared/hooks/custom-use-swr';
+import { ProductCardsSchema } from '@/shared/schemas/product-card-schema';
+
+export function useFeaturedProducts(limit = 12) {
+ return useValidatedSWR(
+ ['featured-products', limit],
+ async (client) => {
+ const response = await client
+ .productProjections()
+ .search()
+ .get({ queryArgs: { limit } })
+ .execute();
+
+ return response.body.results.map(mapProductToCard);
+ },
+ ProductCardsSchema,
+ );
+}
diff --git a/src/features/catalog/useProductCards.ts b/src/features/catalog/useProductCards.ts
new file mode 100644
index 0000000..04417e2
--- /dev/null
+++ b/src/features/catalog/useProductCards.ts
@@ -0,0 +1,59 @@
+import { mapProductToCard } from '@/features/catalog/map-product-to-card-util';
+import { sortMap } from '@/features/catalog/sort-map-util';
+import { useValidatedSWR } from '@/shared/hooks/custom-use-swr';
+import { ProductCardsResponseSchema } from '@/shared/schemas/product-card-schema';
+
+export function useProductCards({
+ categoryIds = [],
+ countries = [],
+ sortBy,
+ page = 1,
+ searchTerm = '',
+}: {
+ categoryIds?: string[];
+ countries?: string[];
+ sortBy?: string;
+ page?: number;
+ searchTerm?: string;
+}) {
+ return useValidatedSWR(
+ ['products', categoryIds, countries, sortBy, page, searchTerm],
+ async (client) => {
+ const filters: string[] = [];
+
+ if (categoryIds.length > 0) {
+ filters.push(
+ `categories.id: ${categoryIds.map((id) => `"${id}"`).join(',')}`,
+ );
+ }
+
+ if (countries.length > 0) {
+ filters.push(
+ `variants.attributes.country: ${countries.map((c) => `"${c}"`).join(',')}`,
+ );
+ }
+
+ const mappedSort = sortBy ? sortMap[sortBy] : undefined;
+
+ const response = await client
+ .productProjections()
+ .search()
+ .get({
+ queryArgs: {
+ limit: 8,
+ offset: (page - 1) * 8,
+ ...(mappedSort ? { sort: [mappedSort] } : {}),
+ ...(filters.length ? { filter: filters } : {}),
+ ...(searchTerm.trim() ? { 'text.en-US': searchTerm.trim() } : {}),
+ },
+ })
+ .execute();
+
+ return {
+ items: response.body.results.map(mapProductToCard),
+ total: response.body.total,
+ };
+ },
+ ProductCardsResponseSchema,
+ );
+}
diff --git a/src/features/login/LoginForm.tsx b/src/features/login/LoginForm.tsx
new file mode 100644
index 0000000..ac51ba0
--- /dev/null
+++ b/src/features/login/LoginForm.tsx
@@ -0,0 +1,56 @@
+import { Button, Group, PasswordInput, Stack, TextInput } from '@mantine/core';
+import { useForm, zodResolver } from '@mantine/form';
+import { useLogin } from '@/features/login/useLogin';
+import { loginSchema } from '@/shared/validation';
+import { LoginFormData } from '@/shared/validation/login-validation';
+
+export function LoginForm() {
+ const form = useForm({
+ initialValues: {
+ email: '',
+ password: '',
+ },
+ validate: zodResolver(loginSchema),
+ validateInputOnBlur: true,
+ });
+
+ const { login } = useLogin();
+
+ const handleSubmit = async (values: LoginFormData) => {
+ console.log('form submitted:', values);
+ await login({ email: values.email, password: values.password });
+ };
+
+ return (
+
+ );
+}
diff --git a/src/features/login/useLogin.ts b/src/features/login/useLogin.ts
new file mode 100644
index 0000000..cadf50a
--- /dev/null
+++ b/src/features/login/useLogin.ts
@@ -0,0 +1,42 @@
+import { MyCustomerSignin } from '@commercetools/platform-sdk';
+import { useAuthStore } from '@/features/auth/auth-state';
+import { useCartStore } from '@/shared/hooks/useCartStore';
+import { apiClientManager } from '@/shared/lib/commercetools/api-client-manager';
+import { getErrorMessage } from '@/shared/utils/api-error-utils';
+import {
+ notifySuccess,
+ notifyError,
+} from '@/shared/utils/custom-notifications';
+
+export function useLogin() {
+ const { setAuthenticated, setPending, setUnauthenticated } = useAuthStore();
+ const { fetchCart } = useCartStore();
+
+ const login = async (credentials: MyCustomerSignin) => {
+ setPending();
+
+ try {
+ const result = await apiClientManager.login(credentials);
+ setAuthenticated();
+
+ await fetchCart();
+ notifySuccess({
+ message: `Welcome back, ${credentials.email}`,
+ });
+
+ return result;
+ } catch (err: unknown) {
+ const message = getErrorMessage(err, 'login');
+
+ notifyError(err as Error, {
+ message,
+ });
+
+ setUnauthenticated();
+ }
+ };
+
+ return {
+ login,
+ };
+}
diff --git a/src/features/product/map-product-to-detail-util.ts b/src/features/product/map-product-to-detail-util.ts
new file mode 100644
index 0000000..bfc0626
--- /dev/null
+++ b/src/features/product/map-product-to-detail-util.ts
@@ -0,0 +1,44 @@
+import { ProductProjection } from '@commercetools/platform-sdk';
+import { ProductDetails } from '@/shared/schemas/product-details-schema';
+
+export function mapProductToDetails(
+ product: ProductProjection,
+): ProductDetails {
+ const variant = product.masterVariant;
+ const priceInfo = variant.prices?.[0];
+
+ const attributesArray = variant.attributes ?? [];
+
+ const attributes = Object.fromEntries(
+ attributesArray.map((attr) => [attr.name, attr.value]),
+ );
+
+ const rating =
+ typeof attributes.rating === 'string'
+ ? parseFloat(attributes.rating)
+ : undefined;
+
+ const country =
+ typeof attributes.country === 'string' ? attributes.country : '';
+
+ const year = typeof attributes.year === 'string' ? attributes.year : '';
+
+ return {
+ id: product.id,
+ key: product.key ?? '',
+ name: product.name['en-US'] ?? '',
+ description: product.description?.['en-US'] ?? '',
+ image: (variant.images ?? []).map((img) => img.url),
+ // images: variant.images?.map((img) => img.url) ?? [],
+ price: priceInfo?.value.centAmount ? priceInfo.value.centAmount / 100 : 0,
+ discountedPrice: priceInfo?.discounted?.value.centAmount
+ ? priceInfo.discounted.value.centAmount / 100
+ : undefined,
+ currency: priceInfo?.value.currencyCode ?? 'EUR',
+ rating:
+ rating && !isNaN(rating) ? Math.min(Math.max(rating, 0), 5) : undefined,
+ country,
+ year,
+ attributes: attributesArray,
+ };
+}
diff --git a/src/features/product/useProductById.ts b/src/features/product/useProductById.ts
new file mode 100644
index 0000000..894c8e6
--- /dev/null
+++ b/src/features/product/useProductById.ts
@@ -0,0 +1,19 @@
+import { mapProductToDetails } from '@/features/product/map-product-to-detail-util';
+import { useValidatedSWR } from '@/shared/hooks/custom-use-swr';
+import { ProductDetailsSchema } from '@/shared/schemas/product-details-schema';
+
+export function useProductById(id: string) {
+ return useValidatedSWR(
+ ['product', id],
+ async (client) => {
+ const response = await client
+ .productProjections()
+ .withId({ ID: id })
+ .get()
+ .execute();
+
+ return mapProductToDetails(response.body);
+ },
+ ProductDetailsSchema,
+ );
+}
diff --git a/src/features/profile/AddressForm.tsx b/src/features/profile/AddressForm.tsx
new file mode 100644
index 0000000..a298e24
--- /dev/null
+++ b/src/features/profile/AddressForm.tsx
@@ -0,0 +1,251 @@
+import { BaseAddress, ClientResponse, Customer } from "@commercetools/platform-sdk";
+import { zodResolver } from "@hookform/resolvers/zod";
+import { Button, Checkbox, Combobox, Grid, Input, InputBase, Stack, Switch, Text, TextInput, Title, useCombobox, useMantineTheme } from "@mantine/core";
+import { JSX, useEffect, useState } from "react";
+import { Controller, SubmitHandler, useForm } from "react-hook-form";
+import { getUserInfo } from "../../shared/utils/get-user-info";
+import { useAuthStore } from "../auth/auth-state";
+import { addAddress, updateAddress } from "./address";
+import { countries } from "@/shared/constants/countries";
+import { getCountryCode } from "@/shared/utils/get-country-code";
+import { AddressFormData, addressSchema } from "@/shared/validation/profile-validation";
+
+export function AddressForm({ onClose, type, address, onUpdate }: { onClose: () => void, type: 'add' | 'edit', address: BaseAddress | null, onUpdate?: () => void}) {
+ const theme = useMantineTheme();
+
+ const {
+ register,
+ handleSubmit,
+ control,
+ watch,
+ trigger,
+ setValue,
+ formState: { errors, isValid },
+ } = useForm({
+ mode: 'onChange',
+ resolver: zodResolver(addressSchema)
+ });
+
+ const status = useAuthStore((state) => state.status);
+ const isAuthenticated = status === 'AUTHENTICATED';
+
+ const [user, setUser] = useState | null>(null);
+
+ useEffect(() => {
+ const getUser = async () => {
+ if (isAuthenticated) {
+ const user = await getUserInfo();
+ if (user) {
+ setUser(user);
+ if (address?.country) {
+ setValue('country', countries[address.country as keyof typeof countries]);
+ setCountryValue(countries[address.country as keyof typeof countries]);
+ trigger('country');
+ }
+ if (address?.city) {
+ setValue('city', address.city);
+ }
+ if (address?.streetName) {
+ setValue('street', address.streetName);
+ }
+ if (address?.postalCode) {
+ setValue('postcode', address.postalCode);
+ }
+ if (address?.id) {
+ if (user.body.shippingAddressIds) {
+ setValue('isShippingAddress', user.body.shippingAddressIds?.includes(address.id ?? ''))
+ }
+ if (user.body.billingAddressIds) {
+ setValue('isBillingAddress', user.body.billingAddressIds?.includes(address.id ?? ''))
+ }
+ if (user.body.defaultShippingAddressId) {
+ setValue('isDefaultShippingAddress', user.body.defaultShippingAddressId === address.id)
+ }
+ if (user.body.defaultBillingAddressId) {
+ setValue('isDefaultBillingAddress', user.body.defaultBillingAddressId === address.id)
+ }
+ }
+ }
+ }
+ };
+ getUser();
+ }, [isAuthenticated, setValue, address, trigger]);
+
+ const countrySelect = useCombobox({
+ onDropdownClose: () => countrySelect.resetSelectedOption(),
+ });
+ const [countryValue, setCountryValue] = useState(null);
+
+ const options = Object.values(countries).map((item) => (
+
+ {item}
+
+ ));
+
+ const onNewAddressSubmit: SubmitHandler = async (data) => {
+ const country = getCountryCode(data.country);
+ await addAddress(country, data.city, data.street, data.postcode, data.isShippingAddress, data.isBillingAddress, data.isDefaultShippingAddress, data.isDefaultBillingAddress);
+ if (onUpdate) {
+ onUpdate();
+ }
+ onClose();
+ };
+
+ const onUpdatedAddressSubmit: SubmitHandler = async (data) => {
+ const country = getCountryCode(data.country);
+ await updateAddress(address?.id, country, data.city, data.street, data.postcode, data.isShippingAddress, data.isBillingAddress, data.isDefaultShippingAddress, data.isDefaultBillingAddress);
+ if (onUpdate) {
+ onUpdate();
+ }
+ onClose();
+ };
+
+ const submit = type === 'add' ? onNewAddressSubmit : onUpdatedAddressSubmit;
+ const titleText = type === 'add' ? 'Add new address' : 'Edit address';
+
+ return(
+ <>
+ {titleText}
+
+ >
+ )
+}
\ No newline at end of file
diff --git a/src/features/profile/ChangePasswordForm.tsx b/src/features/profile/ChangePasswordForm.tsx
new file mode 100644
index 0000000..5f2bdf6
--- /dev/null
+++ b/src/features/profile/ChangePasswordForm.tsx
@@ -0,0 +1,98 @@
+import { zodResolver } from "@hookform/resolvers/zod";
+import { Button, PasswordInput, Text, Title, useMantineTheme } from "@mantine/core";
+import { SubmitHandler, useForm } from "react-hook-form";
+import { useChangePassword } from "./change-password";
+import { PasswordChangeFormData, passwordChangeSchema } from "@/shared/validation/profile-validation";
+
+export function ChangePasswordForm({ onClose }: { onClose: () => void }) {
+ const theme = useMantineTheme();
+
+ const {
+ register,
+ handleSubmit,
+ trigger,
+ formState: { errors, isValid },
+ } = useForm({
+ mode: 'onChange',
+ resolver: zodResolver(passwordChangeSchema)
+ });
+
+ const { changePassword } = useChangePassword();
+
+ const onSubmit: SubmitHandler = async (data) => {
+ await changePassword(data.password, data.newPassword);
+ onClose();
+ };
+
+ return(
+ <>
+ Change password
+
+ >
+ )
+}
\ No newline at end of file
diff --git a/src/features/profile/PersonalInfoForm.tsx b/src/features/profile/PersonalInfoForm.tsx
new file mode 100644
index 0000000..a17ea07
--- /dev/null
+++ b/src/features/profile/PersonalInfoForm.tsx
@@ -0,0 +1,162 @@
+import { ClientResponse, Customer } from "@commercetools/platform-sdk";
+import { zodResolver } from "@hookform/resolvers/zod";
+import { Button, Grid, Stack, Text, TextInput, Title, useMantineTheme } from "@mantine/core";
+import { DateInput } from "@mantine/dates";
+import dayjs from 'dayjs';
+import customParseFormat from 'dayjs/plugin/customParseFormat';
+import { JSX, useEffect, useState } from "react";
+import { Controller, SubmitHandler, useForm } from "react-hook-form";
+import { getUserInfo } from "../../shared/utils/get-user-info";
+import { useAuthStore } from "../auth/auth-state";
+import { updateUserInfo } from "./personal-info";
+import { PersonalInfoFormData, personalInfoSchema } from "@/shared/validation/profile-validation";
+
+export function PersonalInfoForm({ onClose }: { onClose: () => void }) {
+ const theme = useMantineTheme();
+
+ const [calendarValue, setCalendarValue] = useState(null);
+ dayjs.extend(customParseFormat);
+
+ const status = useAuthStore((state) => state.status);
+ const isAuthenticated = status === 'AUTHENTICATED';
+
+ const [user, setUser] = useState | null>(null);
+
+ const {
+ register,
+ handleSubmit,
+ control,
+ trigger,
+ setValue,
+ formState: { errors, isValid },
+ } = useForm({
+ mode: 'onChange',
+ resolver: zodResolver(personalInfoSchema)
+ });
+
+ useEffect(() => {
+ const getUser = async () => {
+ if (isAuthenticated) {
+ const user = await getUserInfo();
+ if (user) {
+ setUser(user);
+ setValue('firstName', user.body.firstName || '', { shouldValidate: true });
+ setValue('lastName', user.body.lastName || '', { shouldValidate: true });
+ setValue('email', user.body.email, { shouldValidate: true }) ;
+ if (user.body.dateOfBirth) {
+ const birthDate = new Date(user.body.dateOfBirth);
+ setCalendarValue(birthDate);
+ setValue('birthDate', birthDate.toLocaleDateString('en-CA'), { shouldValidate: true });
+ }
+ }
+ }
+ };
+ getUser();
+ }, [isAuthenticated, setValue]);
+
+ const onSubmit: SubmitHandler = async (data) => {
+ if (data.birthDate) {
+ await updateUserInfo(data.firstName, data.lastName, data.email, data.birthDate);
+ onClose();
+ }
+ };
+
+ return(
+ <>
+ Edit personal information
+
+ >
+ )
+}
\ No newline at end of file
diff --git a/src/features/profile/address.ts b/src/features/profile/address.ts
new file mode 100644
index 0000000..2bf9862
--- /dev/null
+++ b/src/features/profile/address.ts
@@ -0,0 +1,118 @@
+import { ClientResponse, Customer, MyCustomerAddAddressAction, MyCustomerChangeAddressAction } from "@commercetools/platform-sdk";
+import { getUserInfo } from "../../shared/utils/get-user-info";
+import { apiClientManager } from "@/shared/lib/commercetools"
+import { notifyError, notifySuccess } from "@/shared/utils/custom-notifications";
+import { setAddressActions } from "@/shared/utils/set-address-actions";
+
+export async function deleteAddress(id: string | undefined) {
+ const client = apiClientManager.get();
+ const currentUser = await getUserInfo();
+
+ if (currentUser && client) {
+ try {
+ const response = await client.me().post({
+ body: {
+ version: currentUser.body.version,
+ actions: [
+ {
+ action: 'removeAddress',
+ addressId: id,
+ }
+ ],
+ }
+ }).execute();
+ if (response.statusCode === 200) {
+ notifySuccess({ message: 'Address has been removed' });
+ }
+ return response;
+ } catch (error) {
+ if (error as ClientResponse) {
+ notifyError(error, { message: 'Something went wrong. Try again' })
+ }
+ }
+ }
+}
+
+export async function updateAddress (id: string | undefined, country: string, city: string, street: string, postcode: string, isShipping: boolean, isBilling: boolean, isDefaultShipping: boolean, isDefaultBilling: boolean ) {
+ const client = apiClientManager.get();
+ const currentUser = await getUserInfo();
+
+ const changeAddress: MyCustomerChangeAddressAction = {
+ action: 'changeAddress',
+ addressId: id,
+ address: {
+ country: country,
+ city: city,
+ streetName: street,
+ postalCode: postcode,
+ }
+ }
+
+ const actions = setAddressActions(id, currentUser, isShipping, isBilling, isDefaultShipping, isDefaultBilling);
+ actions.push(changeAddress);
+
+ if (currentUser && client) {
+ try {
+ const response = await client.me().post({
+ body: {
+ version: currentUser.body.version,
+ actions: actions
+ }
+ }).execute();
+ if (response.statusCode === 200) {
+ notifySuccess({ message: 'Address has been updated' });
+ }
+ return response;
+ } catch (error) {
+ if (error as ClientResponse) {
+ notifyError(error, { message: 'Something went wrong. Try again' })
+ }
+ }
+ }
+}
+
+export async function addAddress (country: string, city: string, street: string, postcode: string, isShipping: boolean, isBilling: boolean, isDefaultShipping: boolean, isDefaultBilling: boolean) {
+ const client = apiClientManager.get();
+ const currentUser = await getUserInfo();
+
+ const addAddress: MyCustomerAddAddressAction = {
+ action: 'addAddress',
+ address: {
+ country: country,
+ city: city,
+ streetName: street,
+ postalCode: postcode,
+ }
+ }
+
+ if (currentUser && client) {
+ try {
+ const response = await client.me().post({
+ body: {
+ version: currentUser.body.version,
+ actions: [addAddress],
+ }
+ }).execute();
+ if (response.statusCode === 200) {
+ const currentUser = await getUserInfo();
+ if (currentUser) {
+ const actions = setAddressActions(response.body.addresses.pop()?.id, currentUser, isShipping, isBilling, isDefaultShipping, isDefaultBilling);
+ const res = await client.me().post({
+ body: {
+ version: currentUser.body.version,
+ actions: actions,
+ }
+ }).execute();
+ if (res.statusCode === 200) {
+ notifySuccess({ message: 'Address has been successfully added' });
+ }
+ }
+ }
+ return response;
+ } catch (error) {
+ if (error as ClientResponse) {
+ notifyError(error, { message: 'Something went wrong. Try again' })
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/features/profile/change-password.ts b/src/features/profile/change-password.ts
new file mode 100644
index 0000000..a3fdbdd
--- /dev/null
+++ b/src/features/profile/change-password.ts
@@ -0,0 +1,37 @@
+import { ClientResponse, Customer } from "@commercetools/platform-sdk";
+import { useLogin } from "../login/useLogin";
+import { getUserInfo } from "../../shared/utils/get-user-info";
+import { apiClientManager } from "@/shared/lib/commercetools";
+import { notifyError, notifySuccess } from "@/shared/utils/custom-notifications";
+
+export function useChangePassword () {
+ const { login } = useLogin();
+
+ const changePassword = async(password: string, newPassword: string) => {
+ const client = apiClientManager.get();
+ const currentUser = await getUserInfo();
+
+ if (currentUser && client) {
+ try {
+ const response: ClientResponse = await client.me().password().post({
+ body: {
+ version: currentUser.body.version,
+ currentPassword: password,
+ newPassword: newPassword,
+ }
+ }).execute()
+ if (response.statusCode === 200) {
+ notifySuccess({ message: 'Password has been changed' });
+ apiClientManager.logout();
+ await login({ email: currentUser.body.email, password: newPassword });
+ }
+ return response;
+ } catch (error: unknown) {
+ if ((error as ClientResponse).statusCode === 400) {
+ notifyError(error, { message: 'Current password does not match. Try again' })
+ }
+ }
+ }
+ }
+ return { changePassword };
+}
\ No newline at end of file
diff --git a/src/features/profile/personal-info.ts b/src/features/profile/personal-info.ts
new file mode 100644
index 0000000..42f0adf
--- /dev/null
+++ b/src/features/profile/personal-info.ts
@@ -0,0 +1,45 @@
+import { ClientResponse, Customer } from "@commercetools/platform-sdk";
+import { getUserInfo } from "../../shared/utils/get-user-info";
+import { apiClientManager } from "@/shared/lib/commercetools";
+import { notifyError, notifySuccess } from "@/shared/utils/custom-notifications";
+
+export async function updateUserInfo(firstName: string, lastName: string, email: string, birthDate: string ) {
+ const client = apiClientManager.get();
+ const currentUser = await getUserInfo();
+
+ if (currentUser && client) {
+ try {
+ const response = await client.me().post({
+ body: {
+ version: currentUser.body.version,
+ actions: [
+ {
+ action: 'setFirstName',
+ firstName: firstName,
+ },
+ {
+ action: 'setLastName',
+ lastName: lastName,
+ },
+ {
+ action: 'changeEmail',
+ email: email,
+ },
+ {
+ action: 'setDateOfBirth',
+ dateOfBirth: birthDate,
+ },
+ ],
+ }
+ }).execute();
+ if (response.statusCode === 200) {
+ notifySuccess({ message: 'Personal information has been updated' });
+ }
+ return response;
+ } catch (error) {
+ if (error as ClientResponse) {
+ notifyError(error, { message: 'Something went wrong. Try again' })
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/features/registration/RegistrationForm.tsx b/src/features/registration/RegistrationForm.tsx
new file mode 100644
index 0000000..bb2f3d1
--- /dev/null
+++ b/src/features/registration/RegistrationForm.tsx
@@ -0,0 +1,371 @@
+import { zodResolver } from '@hookform/resolvers/zod';
+import {
+ Fieldset,
+ TextInput,
+ PasswordInput,
+ Combobox,
+ Checkbox,
+ Button,
+ useCombobox,
+ InputBase,
+ Input,
+ Text,
+ Grid,
+ ComboboxStore,
+ Stack,
+ useMantineTheme,
+} from '@mantine/core';
+import { DateInput } from '@mantine/dates';
+import dayjs from 'dayjs';
+import customParseFormat from 'dayjs/plugin/customParseFormat';
+import { JSX, useEffect, useState } from 'react';
+import { useForm, SubmitHandler, Controller } from 'react-hook-form';
+import { useRegistration } from '@/features/registration/useRegistration';
+import { countries } from '@/shared/constants/countries';
+import {
+ RegistrationFormData,
+ registrationSchema,
+} from '@/shared/validation/registration-validation';
+
+export function RegistrationForm() {
+ const theme = useMantineTheme();
+ const {
+ register,
+ handleSubmit,
+ control,
+ watch,
+ trigger,
+ setValue,
+ formState: { errors },
+ } = useForm({
+ mode: 'onBlur',
+ resolver: zodResolver(registrationSchema),
+ });
+
+ const { registerUser } = useRegistration();
+
+ const onSubmit: SubmitHandler = async (data) => {
+ await registerUser(data, sameAddress);
+ };
+
+ // Calendar
+ const [calendarValue, setCalendarValue] = useState(null);
+ dayjs.extend(customParseFormat);
+
+ // Selects
+ const shippingCountrySelect = useCombobox({
+ onDropdownClose: () => {
+ shippingCountrySelect.resetSelectedOption();
+ setTimeout(() => {
+ triggerErrorCheck();
+ }, 200);
+ },
+ });
+
+ const billingCountrySelect = useCombobox({
+ onDropdownClose: () => billingCountrySelect.resetSelectedOption(),
+ });
+
+ const [shippingCountryValue, setShippingCountryValue] = useState<
+ string | null
+ >(null);
+ const [billingCountryValue, setBillingCountryValue] = useState(
+ null,
+ );
+
+ const options = Object.values(countries).map((item) => (
+
+ {item}
+
+ ));
+
+ // Same address checkbox
+ const [sameAddress, setSameAddress] = useState(false);
+ const handleSameAddressChange = (
+ event: React.ChangeEvent,
+ ) => {
+ setSameAddress(event.target.checked);
+ setTimeout(() => {
+ trigger([
+ 'billingAddress.country',
+ 'billingAddress.city',
+ 'billingAddress.street',
+ 'billingAddress.postcode',
+ ]);
+ }, 200);
+ };
+
+ const triggerErrorCheck = () => {
+ if (sameAddress) {
+ trigger([
+ 'billingAddress.country',
+ 'billingAddress.city',
+ 'billingAddress.street',
+ 'billingAddress.postcode',
+ ]);
+ }
+ };
+
+ const shippingFields = watch([
+ 'shippingAddress.country',
+ 'shippingAddress.city',
+ 'shippingAddress.street',
+ 'shippingAddress.postcode',
+ ]);
+
+ useEffect(() => {
+ if (sameAddress) {
+ const [shippingCountry, shippingCity, shippingStreet, shippingPostcode] =
+ shippingFields;
+ if (shippingCountry) {
+ setValue('billingAddress.country', shippingCountry);
+ setBillingCountryValue(shippingCountry);
+ setValue('billingAddress.city', shippingCity);
+ setValue('billingAddress.street', shippingStreet);
+ setValue('billingAddress.postcode', shippingPostcode);
+ }
+ }
+ }, [shippingFields, sameAddress, setValue]);
+
+ // Address
+ const renderCountrySelect = (
+ name: 'shippingAddress.country' | 'billingAddress.country',
+ store: ComboboxStore,
+ value: string | null,
+ addressType: 'shippingAddress' | 'billingAddress',
+ setValue: (value: string) => void,
+ ) => (
+
+ name={name}
+ control={control}
+ render={({ field }): JSX.Element => (
+
+ {
+ field.onChange(value);
+ setValue(value);
+ store.closeDropdown();
+ }}
+ >
+
+ }
+ onClick={() => store.toggleDropdown()}
+ onChange={(event) => setValue(event.currentTarget.value)}
+ rightSectionPointerEvents="none"
+ classNames={{ input: 'form-input' }}
+ className={errors[`${addressType}`]?.country ? 'error' : ''}
+ >
+ {value || Select country}
+
+
+
+ {options}
+
+
+
+ )}
+ />
+ );
+
+ const renderAddressFields = (type: 'shipping' | 'billing') => {
+ const countrySelect =
+ type === 'shipping' ? shippingCountrySelect : billingCountrySelect;
+ const countryValue =
+ type === 'shipping' ? shippingCountryValue : billingCountryValue;
+ const setCountryValue =
+ type === 'shipping' ? setShippingCountryValue : setBillingCountryValue;
+ const isDisabledOnSameAddress = type === 'shipping' ? false : sameAddress;
+
+ return (
+
+ );
+ };
+
+ // Form
+ return (
+
+ );
+}
diff --git a/src/features/registration/useRegistration.ts b/src/features/registration/useRegistration.ts
new file mode 100644
index 0000000..b7f0eb0
--- /dev/null
+++ b/src/features/registration/useRegistration.ts
@@ -0,0 +1,45 @@
+import { useAuthStore } from '@/features/auth/auth-state';
+import { useLogin } from '@/features/login/useLogin';
+import { apiClientManager } from '@/shared/lib/commercetools';
+import { getErrorMessage } from '@/shared/utils/api-error-utils';
+import {
+ notifyError,
+ notifySuccess,
+} from '@/shared/utils/custom-notifications';
+import {
+ createCustomerDraft,
+ getAddressIndexes,
+} from '@/shared/utils/customer-draft-utils';
+import { RegistrationFormData } from '@/shared/validation/registration-validation';
+
+export function useRegistration() {
+ const { setPending } = useAuthStore();
+ const { login } = useLogin();
+
+ const registerUser = async (
+ data: RegistrationFormData,
+ sameAddress: boolean,
+ ) => {
+ setPending();
+
+ try {
+ const draft = createCustomerDraft(data, sameAddress);
+ const addressIndexes = getAddressIndexes(sameAddress);
+
+ const response = await apiClientManager.register(
+ Object.assign(draft, addressIndexes),
+ );
+
+ if (response.statusCode === 201) {
+ notifySuccess({ message: 'Account created successfully' });
+ await login({ email: data.email, password: data.password });
+ }
+ } catch (err: unknown) {
+ const message = getErrorMessage(err, 'registration');
+ notifyError(err, { message });
+ useAuthStore.getState().setUnauthenticated();
+ }
+ };
+
+ return { registerUser };
+}
diff --git a/src/features/sorting/useWineSorting.tsx b/src/features/sorting/useWineSorting.tsx
new file mode 100644
index 0000000..e84aa23
--- /dev/null
+++ b/src/features/sorting/useWineSorting.tsx
@@ -0,0 +1,46 @@
+import { useState, useEffect } from 'react';
+import { Wine } from '@/types/types';
+
+export function useWineSorting(initialWines: Wine[]) {
+ const sortOptions = [
+ { label: 'Price: Low to High', value: 'price_asc' },
+ { label: 'Price: High to Low', value: 'price_desc' },
+ { label: 'Rating: High to Low', value: 'rating_desc' },
+ { label: 'Rating: Low to High', value: 'rating_asc' },
+ { label: 'Year: Newest First', value: 'year_desc' },
+ { label: 'Year: Oldest First', value: 'year_asc' },
+ ];
+ const [sortBy, setSortBy] = useState('price_asc');
+ const [sortedWines, setSortedWines] = useState(initialWines);
+
+ useEffect((): void => {
+ const sorted: Wine[] = [...initialWines].sort(
+ (a: Wine, b: Wine): number => {
+ switch (sortBy) {
+ case 'price_asc':
+ return a.price - b.price;
+ case 'price_desc':
+ return b.price - a.price;
+ case 'rating_desc':
+ return b.rating - a.rating;
+ case 'rating_asc':
+ return a.rating - b.rating;
+ case 'year_desc':
+ return parseInt(b.year) - parseInt(a.year);
+ case 'year_asc':
+ return parseInt(a.year) - parseInt(b.year);
+ default:
+ return 0;
+ }
+ },
+ );
+ setSortedWines(sorted);
+ }, [sortBy, initialWines]);
+
+ return {
+ sortedWines,
+ sortBy,
+ setSortBy,
+ sortOptions,
+ };
+}
diff --git a/src/index.css b/src/index.css
new file mode 100644
index 0000000..3a99d11
--- /dev/null
+++ b/src/index.css
@@ -0,0 +1,453 @@
+*,
+*::before,
+*::after {
+ margin: 0;
+ padding: 0;
+ border: none;
+ box-sizing: border-box;
+ list-style: none;
+ text-decoration: none;
+ list-style: none;
+}
+
+body.no-scroll {
+ overflow: hidden;
+ scrollbar-gutter: stable;
+}
+
+body {
+ font-family: 'Plus Jakarta Sans', 'Noto Sans', sans-serif;
+}
+
+.page {
+ min-height: 100vh;
+ background-color: #131c24;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ /*justify-content: center;*/
+}
+
+.header {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ justify-self: center;
+ white-space: nowrap;
+ border-bottom: 1px solid #29374c;
+ height: 80px;
+ padding: 0 1.5rem;
+}
+
+.header__logo-icon {
+ width: 1.5rem;
+ height: 1.5rem;
+}
+
+.header__logo-text {
+ font-size: 1.5rem !important;
+ padding: 0.75rem 0.2rem;
+ color: #8b0000 !important;
+}
+
+.header__nav {
+ display: flex;
+ align-items: center;
+}
+
+.header__nav-item {
+ color: #f8f9fb;
+ font-size: 0.875rem;
+ font-weight: 500;
+ line-height: normal;
+ text-decoration: none;
+}
+.header__nav-item--cart {
+ display: none;
+}
+
+.burger,
+.burger__line {
+ display: none;
+}
+
+.header__actions {
+ display: flex;
+ gap: 0.5rem;
+}
+
+.header__user-menu {
+ position: relative;
+ display: inline-block;
+}
+
+.header__user-summary {
+ list-style: none;
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+}
+
+.header__user-summary::-webkit-details-marker {
+ display: none;
+}
+
+.header__user-icon {
+ width: 24px;
+ height: 24px;
+ transition: opacity 0.3s ease-in-out;
+}
+
+.header__user-icon:hover {
+ opacity: 0.8;
+}
+
+.header__user-icon {
+ width: 20px;
+ height: 20px;
+ stroke: #f8f9fb;
+}
+
+.header__avatar {
+ width: 2.5rem;
+ height: 2.5rem;
+ border-radius: 9999px;
+ background-size: cover;
+ background-position: center;
+ background-repeat: no-repeat;
+ background-image: url('./assets/avatar_1.png');
+}
+.section-title {
+ color: #f8f9fb;
+ font-size: 1.75rem;
+ font-weight: 700;
+ margin-bottom: 1.5rem !important;
+ text-align: center;
+}
+
+.section-text {
+ color: #8a9dc0;
+ font-size: 1rem;
+ text-align: center;
+ max-width: 800px;
+ margin: 0 auto 2rem;
+}
+
+.button {
+ display: flex;
+ max-width: 480px;
+ cursor: pointer;
+ align-items: center;
+ justify-content: center;
+ overflow: hidden;
+ border-radius: 0.75rem;
+ height: 2.5rem;
+ padding: 0 1rem;
+ font-size: 0.875rem;
+ font-weight: 700;
+ line-height: normal;
+ letter-spacing: 0.015em;
+}
+
+.button--primary,
+.button--primary .mantine-CloseButton-root{
+ background-color: #f4c753;
+ color: #141c24;
+}
+
+.button--primary:hover,
+.button--primary:hover .mantine-CloseButton-root {
+ background-color: #ca9d29;
+ color: #f8f9fb !important;
+}
+
+.button:disabled {
+ background-color: grey !important;
+ opacity: 0.3 !important;
+}
+
+.button:hover:disabled {
+ cursor: not-allowed;
+ background-color: grey !important;
+ opacity: 0.3 !important;
+ color: #141c24 !important;
+}
+
+.button--secondary {
+ /*background-color: #29374c;*/
+ /*border-color: rgba(202, 157, 41, 0.38);*/
+ background-color: #32415D;
+ border-color: #516185;
+ color: #f8f9fb;
+}
+
+.button--remove {
+ background-color: #ff6b6b;
+ color: #1d2a36;
+}
+
+.button--remove:hover {
+ background-color: #ff5252;
+ color: #f8f9fb;
+}
+
+.button--secondary:hover {
+ background-color: #516185;
+ border-color: #516185;
+ color: #e6e9f2;
+}
+
+.burger-button--primary {
+ display: none;
+ background-color: #f4c753;
+ color: #141c24;
+}
+
+.burger-button--secondary {
+ display: none;
+ background-color: #29374c;
+ color: #f8f9fb;
+}
+
+
+
+.button--icon {
+ min-width: 0;
+ padding: 0 0.625rem;
+ gap: 0.5rem;
+}
+
+.button--large {
+ align-self: center;
+ height: 3rem;
+ padding: 0 1.25rem;
+ font-size: 1rem;
+ width: 100%;
+ max-width: 300px;
+}
+
+.button__text {
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+.button__icon {
+ color: #f8f9fb;
+}
+
+.contact-section {
+ padding: 1rem;
+}
+
+.carousel {
+ display: flex;
+ flex-direction: column;
+}
+
+.carousel__container {
+ display: flex;
+ justify-content: center;
+}
+
+.footer {
+ display: flex;
+ justify-content: center;
+ margin-top: 2rem;
+ flex-direction: column;
+}
+
+.footer__links {
+ display: flex;
+ flex-wrap: wrap;
+ align-items: center;
+ justify-content: center;
+ gap: 1.5rem;
+ padding: 1.25rem 1.25rem 1.5rem;
+}
+
+.footer__social {
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: center;
+ gap: 1rem;
+ padding-bottom: 1.5rem;
+}
+
+.social-icon {
+ color: #8a9dc0;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.footer__copyright {
+ color: #8a9dc0;
+ font-size: 1rem;
+ font-weight: 400;
+ line-height: normal;
+ text-align: center;
+ padding-bottom: 2.5rem;
+}
+
+.visually-hidden {
+ position: absolute;
+ width: 1px;
+ height: 1px;
+ padding: 0;
+ margin: -1px;
+ overflow: hidden;
+ clip: rect(0, 0, 0, 0);
+ border: 0;
+}
+
+.wine-title {
+ font-size: clamp(1rem, 0.5795rem + 0.4545vw, 1.125rem);
+ font-weight: 700;
+}
+
+@media (min-width: 380px) and (max-width: 768px) {
+ .header__nav-item {
+ display: none;
+ }
+
+ .burger {
+ display: block;
+ }
+
+ .header__nav {
+ display: flex;
+ position: static;
+ transform: none !important;
+ background: transparent;
+ overflow: visible;
+ justify-content: flex-end !important;
+ }
+
+ .header__nav-item {
+ display: none;
+ }
+
+ .header__nav.open {
+ display: flex;
+ flex-direction: column;
+ position: fixed;
+ top: 0;
+ right: 0;
+ width: 45%;
+ height: 100%;
+ border: 1px solid #32415d;
+ background-color: rgba(29, 42, 54, 0.97);
+ border-radius: 0.5rem;
+ padding: 20px 0;
+ transform: translateX(0);
+ opacity: 1;
+ justify-content: flex-start;
+ align-items: center;
+ z-index: 999;
+ transition: all 0.3s ease-in-out;
+ box-shadow:
+ 0 0 0 100vmax rgba(0, 0, 0, 0.8),
+ 15px 0 30px -10px rgba(0, 0, 0, 0.8);
+ backdrop-filter: blur(2px);
+ justify-content: flex-start !important;
+ }
+
+ .header__nav.open .header__nav-item {
+ display: block;
+ width: 100%;
+ text-align: center;
+ padding: 15px 0;
+ color: #8a9dc0;
+ font-size: 24px;
+ font-weight: 600;
+ line-height: 152%;
+ letter-spacing: 3px;
+ text-transform: uppercase;
+ transition: all 0.3s ease-in-out;
+ }
+
+ .header__nav.open .header__nav-item:hover {
+ background: rgba(0, 0, 0, 0.05);
+ }
+
+ .active {
+ top: 15px;
+ position: fixed;
+ right: 20px;
+ }
+
+ .header__nav.open .button {
+ display: flex;
+ width: 80%;
+ max-width: 280px;
+ margin: 15px auto;
+ justify-content: center;
+ }
+
+ .header__nav.open {
+ padding-top: 5rem;
+ padding-bottom: 20px;
+ }
+
+ .header__nav.open .button--secondary {
+ order: 1;
+ background: rgba(248, 249, 251, 0.1);
+ border: 1px solid #32415d;
+ }
+
+ .header__nav.open .button--primary {
+ order: 2;
+ background: #f4c753;
+ color: #1d2a36;
+ }
+}
+
+@media (max-width: 1223px) {
+ .card {
+ max-width: 400px !important;
+ }
+}
+@media (max-width: 1100px) {
+ .button--large {
+ font-size: 0.870rem;
+ }
+}
+@media (max-width: 1024px) {
+ .feature-card {
+ width: 100% !important;
+ }
+}
+
+@media (max-width: 480px) {
+ .header {
+ padding: 10px !important;
+ }
+
+ .header__logo {
+ gap: 0 !important;
+ }
+
+ .header__nav {
+ width: 50% !important;
+ }
+
+ .carousel__container {
+ grid-template-columns: 1fr;
+ gap: 1rem;
+ justify-items: center;
+ padding: 0 1rem;
+ }
+
+ .card {
+ width: 80% !important;
+ }
+
+ .card__image {
+ height: 250px;
+ }
+
+ .discount-section {
+ padding: 1.5rem 0.5rem;
+ }
+}
diff --git a/src/main.tsx b/src/main.tsx
new file mode 100644
index 0000000..ead2470
--- /dev/null
+++ b/src/main.tsx
@@ -0,0 +1,15 @@
+import React from 'react';
+import ReactDOM from 'react-dom/client';
+import App from './App';
+import './index.css';
+
+const root = document.getElementById('root');
+if (!root) {
+ throw new Error('Root not found');
+}
+
+ReactDOM.createRoot(root).render(
+
+
+ ,
+);
diff --git a/src/pages/AboutPage/AboutPage.css b/src/pages/AboutPage/AboutPage.css
new file mode 100644
index 0000000..f487208
--- /dev/null
+++ b/src/pages/AboutPage/AboutPage.css
@@ -0,0 +1,68 @@
+.about-container {
+ margin-top: 1rem;
+ max-width: 1440px;
+ width: 100%;
+ text-align: center;
+}
+
+.container__dark {
+ background-color: #1d2a36;
+ border: 1px solid #32415d;
+ border-radius: 0.75rem;
+}
+
+.member-card__bio {
+ line-height: 1.6;
+}
+
+.member-card__contribution li {
+ list-style: disc;
+ list-style-position: inside;
+ font-size: 14px;
+ margin-bottom: 8px;
+}
+
+.member-card__contribution li > div {
+ display: inline;
+}
+
+.member-card_github:hover{
+ text-decoration: none;
+}
+
+.member-card_github:hover > div > p {
+ transition: color 0.2s;
+ color: #d4d8e9 !important;
+}
+
+.member-card_github:hover > div > svg {
+ transition: fill 0.2s;
+ fill: #d4d8e9;
+}
+
+.member-card__avatar, .rsschool-logo {
+ max-width: 320px;
+ transition: transform 0.3s ease;
+}
+
+.member-card__avatar:hover, .rsschool-logo:hover {
+ transform: scale(1.1);
+}
+
+.rsschool-description {
+ max-width: 680px;
+ line-height: 1.6;
+}
+
+.team-collaboration-item {
+ flex-direction: row;
+ justify-content: center;
+ align-items: center;
+}
+
+@media (max-width: 1265px) {
+ .team-collaboration-item {
+ flex-direction: column;
+ }
+
+}
\ No newline at end of file
diff --git a/src/pages/AboutPage/AboutPage.tsx b/src/pages/AboutPage/AboutPage.tsx
new file mode 100644
index 0000000..82c2168
--- /dev/null
+++ b/src/pages/AboutPage/AboutPage.tsx
@@ -0,0 +1,216 @@
+import {
+ Anchor,
+ Box,
+ Container,
+ Grid,
+ Group,
+ Image,
+ Stack,
+ Text,
+ Title,
+ useMantineTheme,
+} from '@mantine/core';
+import { motion } from 'framer-motion';
+import logo from '@/assets/rsschool-logo.png';
+import { TeamMemberCard } from '@/components/Card/TeamMemberCard';
+import { team } from '@/shared/constants/team';
+import '@/pages/AboutPage/AboutPage.css';
+
+const cardVariants = {
+ hidden: { opacity: 0, y: 30 },
+ visible: (i: number) => ({
+ opacity: 1,
+ y: 0,
+ transition: {
+ delay: i * 0.1,
+ duration: 0.6,
+ ease: 'easeOut',
+ },
+ }),
+};
+
+export default function AboutPage() {
+ const theme = useMantineTheme();
+ return (
+
+
+
+
+ About Our Winery
+
+
+ At WineShop, we are dedicated to providing an exquisite online wine
+ shopping experience. Our commitment is to quality wines, exceptional
+ service, and innovative selection. Our team ensures we deliver the
+ latest vintages, a seamless purchase process, and unparalleled
+ support. We believe in integrity, innovation, and customer
+ appreciation. Our values drive us to continuously improve our
+ selections and enhance the wine-buying journey.
+
+
+
+
+
+ Meet Our Team:
+
+
+
+ We are the dedicated frontend engineers who architected and built
+ this APP delivering a premium digital shopping experience.
+
+
+ {team.map((member, index) => (
+
+
+
+
+
+ ))}
+
+
+
+ Teamwork collaboration:
+
+
+
+
+
+
+ Kanban board with sprint planning
+
+
+
+
+
+
+
+ 24/7 Discord communication
+
+
+
+
+
+
+
+ Support and help of teammates
+
+
+
+
+
+
+
+ Mutual code reviews on GitHub
+
+
+
+
+
+
+
+ Big thanks to:
+
+
+
+
+
+ RS School offers a unique learning experience as a free,
+ community-based online education initiative. It has been run by
+ the Rolling Scopes community since 2013. Today, over 600
+ developer-volunteers from various countries and companies assist
+ as mentors. We believe in important ideas that guide our mission.
+
+
+
+
+
+ );
+}
diff --git a/src/pages/CartPage/CartPage.css b/src/pages/CartPage/CartPage.css
new file mode 100644
index 0000000..6dddf07
--- /dev/null
+++ b/src/pages/CartPage/CartPage.css
@@ -0,0 +1,254 @@
+.cart-container {
+ width: 100%;
+ max-width: 800px;
+ background-color: #1d2a36;
+ border: 1px solid #32415d;
+ border-radius: 0.75rem;
+ padding: 2rem;
+ display: flex;
+ flex-direction: column;
+ gap: 1.5rem;
+ align-items: center;
+ text-align: center;
+ opacity: 0;
+ animation: fadeIn 1s ease-out forwards;
+}
+
+.cart-title {
+ color: #f8f9fb;
+ font-size: 1.75rem;
+ font-weight: 700;
+ line-height: 1.25;
+ letter-spacing: -0.015em;
+ margin-bottom: 0.5rem;
+}
+
+.cart-content {
+ display: flex;
+ flex-direction: column;
+ gap: 2rem;
+}
+
+.cart-items {
+ flex: 2;
+ display: flex;
+ flex-direction: column;
+ gap: 1rem;
+}
+
+.cart-item {
+ display: flex;
+ align-items: stretch;
+ gap: 1.5rem;
+ padding: 1.5rem;
+ border-radius: 0.75rem;
+ background-color: #1d2a36;
+ border: 1px solid #32415d;
+ position: relative;
+}
+
+.cart-item__image {
+ width: 100px;
+ height: 100px;
+ border-radius: 0.5rem;
+ background-size: cover;
+ background-position: center;
+ flex-shrink: 0;
+}
+
+.cart-item__details {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ gap: 0.5rem;
+}
+
+.cart-item__title {
+ color: #f8f9fb;
+ font-size: 1.125rem;
+ font-weight: 700;
+ line-height: 1.25;
+}
+
+.cart-item__price {
+ color: #f8f9fb;
+ font-size: 1rem;
+ font-weight: 700;
+ margin-top: 0.5rem;
+}
+
+.cart-item__quantity {
+ display: flex;
+ align-items: center;
+ gap: 0.75rem;
+ margin-top: 0.75rem;
+}
+
+.quantity-btn {
+ width: 2rem;
+ height: 2rem;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ border-radius: 0.5rem;
+ background-color: #29374c;
+ color: #f8f9fb;
+ border: none;
+ cursor: pointer;
+ font-size: 1rem;
+ font-weight: 700;
+ transition: background-color 0.2s ease-in-out;
+}
+
+.quantity-btn:hover {
+ background-color: #32415d;
+}
+
+.quantity {
+ color: #f8f9fb;
+ font-size: 1rem;
+ font-weight: 500;
+ min-width: 1.5rem;
+ text-align: center;
+}
+
+.cart-item__remove {
+ position: absolute;
+ top: 1rem;
+ right: 1rem;
+ background: none;
+ border: none;
+ color: #8a9dc0;
+ cursor: pointer;
+ padding: 0.5rem;
+ transition: color 0.2s ease-in-out;
+}
+
+.cart-item__remove:hover {
+ color: #e74c3c;
+}
+
+.cart-summary {
+ flex: 1;
+ padding: 1.5rem;
+ border-radius: 0.75rem;
+ background-color: #1d2a36;
+ border: 1px solid #32415d;
+ display: flex;
+ flex-direction: column;
+ gap: 1rem;
+}
+
+@media (min-width: 1024px) {
+ .cart-summary {
+ position: sticky;
+ top: 1rem;
+ }
+}
+
+.summary-title {
+ color: #f8f9fb;
+ font-size: 1.25rem;
+ font-weight: 700;
+ margin-bottom: 0.5rem;
+}
+
+.summary-row {
+ display: flex;
+ justify-content: space-between;
+ color: #f8f9fb;
+ font-size: 0.875rem;
+ font-weight: 500;
+ padding: 0.5rem 0;
+}
+
+.summary-row:not(:last-child) {
+ border-bottom: 1px solid #32415d;
+}
+
+.summary-row.total {
+ font-weight: 700;
+ font-size: 1.125rem;
+ margin-top: 0.5rem;
+}
+
+.checkout-btn {
+ align-self: center;
+ width: 100%;
+ margin-top: 1.5rem;
+ background-color: #f4c753;
+ color: #141c24;
+ border: none;
+ padding: 1rem;
+ border-radius: 0.5rem;
+ font-size: 1rem;
+ font-weight: 700;
+ cursor: pointer;
+ transition: background-color 0.2s ease-in-out;
+ font-family: "Plus Jakarta Sans", "Noto Sans", sans-serif;
+}
+
+.checkout-btn:hover {
+ background-color: #e6b945;
+}
+
+.empty-cart {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ gap: 1rem;
+ padding: 3rem 1rem;
+ text-align: center;
+}
+
+.empty-cart__icon {
+ color: #8a9dc0;
+ font-size: 3rem;
+}
+
+.empty-cart__text {
+ color: #f8f9fb;
+ font-size: 1.125rem;
+ font-weight: 500;
+}
+
+.modal {
+ display: flex;
+ justify-content: center;
+}
+
+
+@keyframes fadeIn {
+ from {
+ opacity: 0;
+ transform: translateY(10px);
+ }
+ to {
+ opacity: 1;
+ transform: translateY(0);
+ }
+}
+
+.cart-item {
+ animation: fadeIn 0.3s ease-out forwards;
+}
+
+
+@media (max-width: 600px) {
+ .cart-inner {
+ display: flex;
+ flex-direction: column;
+ padding: 0 !important;
+
+ }
+ .cart-column {
+ padding: 0 !important;
+ }
+ .button--cart {
+ min-width: 140px;
+ }
+ .cart-image {
+ max-width: 100% !important;
+ }
+}
diff --git a/src/pages/CartPage/CartPage.tsx b/src/pages/CartPage/CartPage.tsx
new file mode 100644
index 0000000..fe6fa0e
--- /dev/null
+++ b/src/pages/CartPage/CartPage.tsx
@@ -0,0 +1,483 @@
+import {
+ Container,
+ Title,
+ Text,
+ Box,
+ Group,
+ Button,
+ Grid,
+ Image,
+ Stack,
+ NumberInput,
+ ActionIcon,
+ Card,
+ Divider,
+ useMantineTheme,
+ TextInput,
+ Badge,
+ Modal,
+} from '@mantine/core';
+import { Link } from 'react-router-dom';
+import { ROUTES } from '@/app/routes';
+import '@/pages/CartPage/CartPage.css';
+import {
+ useCartStore,
+ removeFromCart,
+ changeQuantity,
+ clearCart,
+ addDiscount,
+ removeDiscount,
+ fetchShippingMethod,
+} from '@/shared/hooks/useCartStore.ts';
+import { CartMessage } from '@/components/CartMessage/CartMessage.tsx';
+import { useEffect, useState } from 'react';
+import { useDisclosure } from '@mantine/hooks';
+
+export default function CartPage() {
+ const cart = useCartStore((state) => state.cart);
+ const cartError = useCartStore((state) => state.error);
+ const shipMethod = useCartStore((state) => state.shippingMethod);
+
+ const theme = useMantineTheme();
+ const cartCurrency = cart?.totalPrice.currencyCode || 'EUR';
+
+ const [opened, { open, close }] = useDisclosure(false);
+ const [promoCode, setPromoCode] = useState('');
+ const [discountError, setDiscountError] = useState('');
+
+ useEffect(() => {
+ if (!shipMethod) {
+ fetchShippingMethod().catch(() => {
+ console.log('Error fetching shipmethod');
+ });
+ }
+ }, [shipMethod]);
+
+ const handleApplyPromo = () => {
+ if (!promoCode.trim()) return;
+
+ addDiscount(promoCode.trim())
+ .then(() => {
+ console.log('Promo code applied');
+ setPromoCode('');
+ setDiscountError('');
+ })
+ .catch(() => {
+ console.log('Failed to apply promo code');
+ setDiscountError(cartError || 'Invalid promo code');
+ });
+ };
+
+ const handleRemovePromo = (discountCodeId: string) => {
+ removeDiscount(discountCodeId)
+ .then(() => {
+ console.log('Discount removed');
+ })
+ .catch(() => {
+ console.log('Failed to remove discount');
+ setDiscountError('Failed to remove discount');
+ });
+ };
+
+ const handleClearCart = () => {
+ const removalPromises = appliedDiscounts.map((dc) =>
+ removeDiscount(dc.discountCode.id),
+ );
+
+ Promise.all(removalPromises)
+ .then(() => clearCart())
+ .then(() => {
+ console.log('Cart cleared');
+ close();
+ })
+ .catch((error) => console.error('Failed to clear cart', error));
+ };
+
+ const handleClearCartClick = (e: React.MouseEvent) => {
+ e.stopPropagation();
+ open();
+ };
+
+ const shippingMethodName = shipMethod?.localizedName;
+ const shippingDescription = shipMethod?.localizedDescription;
+
+ if (!shippingMethodName) return null;
+ if (!shippingDescription) return null;
+
+ const shipName: string = shippingMethodName['en-US'] || '';
+ const shipDescription: string = shippingDescription['en-US'] || '';
+
+ const subtotal =
+ cart?.lineItems.reduce(
+ (sum, item) => sum + (item.price.value.centAmount / 100) * item.quantity,
+ 0,
+ ) || 0;
+
+ const shippingCents =
+ shipMethod?.zoneRates?.[0]?.shippingRates?.[0]?.price?.centAmount ?? 0;
+ const shippingPrice = shippingCents / 100;
+
+ const totalForItems = cart?.totalPrice.centAmount / 100 || subtotal;
+
+ const itemsDiscount = Math.max(0, subtotal - totalForItems);
+
+ const totalWithShipping = totalForItems + (subtotal > 0 ? shippingPrice : 0);
+
+ const totalWithoutDiscount = subtotal + (subtotal > 0 ? shippingPrice : 0);
+
+ const appliedDiscounts =
+ cart?.discountCodes.filter((dc) => dc.state === 'MatchesCart') || [];
+
+ const handleIncrease = (
+ e: React.MouseEvent,
+ lineItemId: string,
+ currentQuantity: number,
+ ) => {
+ e.stopPropagation();
+ changeQuantity(lineItemId, currentQuantity + 1)
+ .then(() => console.log('Quantity increased'))
+ .catch(() => console.log('Failed to increase'));
+ };
+
+ const handleDecrease = (
+ e: React.MouseEvent,
+ lineItemId: string,
+ currentQuantity: number,
+ ) => {
+ e.stopPropagation();
+ if (currentQuantity > 1) {
+ changeQuantity(lineItemId, currentQuantity - 1)
+ .then(() => console.log('Quantity decreased'))
+ .catch(() => console.log('Failed to decrease'));
+ }
+ };
+
+ const handleRemove = (e: React.MouseEvent, lineItemId: string) => {
+ e.stopPropagation();
+ removeFromCart(lineItemId)
+ .then(() => console.log('Product removed'))
+ .catch(() => console.log('Failed to remove'));
+ };
+
+ const formatCurrency = (amount: number, currencyCode: string) => {
+ const normalizedAmount = amount / 100;
+ return new Intl.NumberFormat('en-US', {
+ style: 'currency',
+ currency: currencyCode,
+ }).format(normalizedAmount);
+ };
+
+ const getLocalizedValue = (value: unknown, locale = 'en-US'): string => {
+ if (typeof value === 'string') {
+ return value;
+ }
+ if (value && typeof value === 'object' && value !== null) {
+ if (locale in value) {
+ const localizedValue = (value as Record)[locale];
+ if (typeof localizedValue === 'string') {
+ return localizedValue;
+ }
+ }
+ }
+ return 'No description available';
+ };
+
+ if (!cart || cart.lineItems.length === 0) {
+ return ;
+ }
+
+ return (
+
+
+
+ Your Shopping Cart
+
+
+
+
+
+ {cart.lineItems.map((item) => {
+ const formattedPrice = formatCurrency(
+ item.totalPrice.centAmount,
+ item.totalPrice.currencyCode,
+ );
+ const imageUrl =
+ item.variant.images?.[0]?.url ||
+ '../src/assets/fallback_1.png';
+
+ const itemName = getLocalizedValue(item.name);
+
+ return (
+
+
+
+
+
+
+
+
+
+ {itemName}
+
+
+ {formattedPrice}
+
+
+
+
+
+ handleDecrease(e, item.id, item.quantity)
+ }
+ >
+ –
+
+
+
+ handleIncrease(e, item.id, item.quantity)
+ }
+ >
+ +
+
+
+
+ handleRemove(e, item.id)}
+ color={theme.colors.dark[5]}
+ size="lg"
+ >
+
+
+
+
+
+
+
+ );
+ })}
+
+
+
+
+
+
+
+ Order Summary
+
+
+
+ Products:
+ {cart.lineItems.length}
+
+
+
+ Subtotal:
+
+ {formatCurrency(subtotal * 100, cartCurrency)}
+
+
+
+ {itemsDiscount > 0 && (
+
+ Discount:
+
+ - {formatCurrency(itemsDiscount * 100, cartCurrency)}
+
+
+ )}
+
+
+ Shipping:
+
+ {' '}
+ {formatCurrency(shippingPrice * 100, cartCurrency)} (
+ {shipName})
+
+
+
+
+
+ {shipDescription}
+
+
+
+ {appliedDiscounts.length > 0 ? (
+
+ {appliedDiscounts.map((dc) => (
+
+
+ Promo code applied
+
+
+
+ ))}
+
+ ) : (
+
+
+ setPromoCode(event.currentTarget.value)
+ }
+ error={discountError}
+ style={{ flex: 1 }}
+ />
+
+
+ )}
+
+
+
+
+
+ Total:
+
+
+ {itemsDiscount > 0 ? (
+
+
+ {formatCurrency(totalWithShipping * 100, cartCurrency)}
+
+
+ {formatCurrency(
+ totalWithoutDiscount * 100,
+ cartCurrency,
+ )}
+
+
+ ) : (
+
+ {formatCurrency(totalWithoutDiscount * 100, cartCurrency)}
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Are you sure you want to clear your cart?
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/src/pages/CatalogPage/CatalogPage.css b/src/pages/CatalogPage/CatalogPage.css
new file mode 100644
index 0000000..3804bee
--- /dev/null
+++ b/src/pages/CatalogPage/CatalogPage.css
@@ -0,0 +1,190 @@
+.search-input {
+ width: 70%;
+ border-radius: 0.75rem;
+ margin-bottom: 1rem;
+}
+
+
+.search-input__field {
+ flex: 1;
+ min-width: 0;
+ resize: none;
+ overflow: hidden;
+ color: #f8f9fb;
+ /*background-color: #29374c;*/
+ font-size: 1rem;
+ font-weight: 400;
+ line-height: normal;
+ outline: none;
+ border-radius: 0 0.75rem 0.75rem 0;
+}
+
+.search-input__field::placeholder {
+ color: #8a9dc0;
+}
+
+
+.filters {
+ width: 70%;
+ flex-wrap: wrap;
+ justify-content: space-between;
+ padding: 0.75rem 1rem;
+}
+
+.filter-group {
+ display: flex;
+ /*justify-content: start;*/
+ /*flex-wrap: nowrap;*/
+}
+
+.filter-group__label {
+ color: #f8f9fb;
+ font-size: 1rem;
+ font-weight: 500;
+ line-height: normal;
+ padding-bottom: 0.5rem;
+}
+
+.filter-group__select {
+ display: flex;
+ width: 100%;
+ min-width: 0;
+ flex: 1;
+ resize: none;
+ overflow: hidden;
+ border-radius: 0.75rem;
+ color: #f8f9fb;
+ background-color: #1d2a36;
+ border: 1px solid #32415d;
+ height: 3.5rem;
+ background-image: url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 width=%2724px%27 height=%2724px%27 fill=%27rgb(138,157,192)%27 viewBox=%270 0 256 256%27%3e%3cpath d=%27M181.66,170.34a8,8,0,0,1,0,11.32l-48,48a8,8,0,0,1-11.32,0l-48-48a8,8,0,0,1,11.32-11.32L128,212.69l42.34-42.35A8,8,0,0,1,181.66,170.34Zm-96-84.68L128,43.31l42.34,42.35a8,8,0,0,0,11.32-11.32l-48-48a8,8,0,0,0-11.32,0l-48,48A8,8,0,0,0,85.66,85.66Z%27%3e%3c/path%3e%3c/svg%3e");
+ background-repeat: no-repeat;
+ background-position: right 1rem center;
+ padding: 0.9375rem;
+ font-size: 1rem;
+ font-weight: 400;
+ line-height: normal;
+ outline: none;
+ appearance: none;
+}
+
+.filter-tags {
+ display: flex;
+ gap: 0.75rem;
+ padding: 0.75rem 1rem 0.75rem 0.75rem;
+ flex-wrap: wrap;
+}
+
+.filter-tag {
+ display: flex;
+ height: 2rem;
+ flex-shrink: 0;
+ align-items: center;
+ justify-content: center;
+ gap: 0.5rem;
+ border-radius: 0.75rem;
+ background-color: #29374c;
+ padding: 0 1rem;
+ color: #f8f9fb;
+ font-size: 0.875rem;
+ font-weight: 500;
+ line-height: normal;
+ cursor: pointer;
+}
+
+.product-grid {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
+ gap: 0.75rem;
+ padding: 1rem;
+}
+
+.product-card {
+ background: #1d2a36;
+ border: 1px solid #32415d;
+ border-radius: 0.75rem;
+ overflow: hidden;
+ cursor: pointer;
+ height: 500px !important;
+ justify-content: space-between;
+ transition: all 0.3s ease-in-out;
+ margin: 7px;
+}
+
+.product-card:hover {
+ box-shadow: 0 0 10px 3px #9fb3c8;
+ transform: scale(1.02);
+ background-color: rgba(10, 16, 24, 0.2);
+}
+
+.product-card__price {
+ font-size: 1.2rem;
+ color: #f4c753;
+ margin-right: 1rem;
+}
+
+.product-card__old-price {
+ color: #8a9dc0;
+ text-decoration: line-through;
+}
+
+.product-card__image {
+ max-height: 100vh;
+ max-width: 100vw;
+ object-fit: cover;
+ background-size: cover;
+ background-position: center;
+ background-repeat: no-repeat;
+ border-radius: 0.75rem;
+ background-color: #f8f9fb;
+ cursor: pointer;
+ margin-bottom: 5px;
+}
+
+/*@media (max-width: 769px) {*/
+/* .filter-group {*/
+/* width: 100%*/
+/* }*/
+/*}*/
+
+/*@media (min-width: 380px) and (max-width: 1024px) {*/
+/* .filters {*/
+/* display: flex;*/
+/* flex-direction: column;*/
+/* align-items: center;*/
+/* }*/
+/*}*/
+
+
+
+.product-card__image--1 {
+ background-image: url("../../../src/assets/Castillo Ygay Gran Reserva Especial Blanco 2001-1.jpg");
+}
+
+.product-card__image--2 {
+ background-image: url("../../../src/assets/Montrachet Grand Cru 2010-2.jpg");
+}
+
+.product-card__image--3 {
+ background-image: url("https://images.vivino.com/thumbs/G3MU5UwBQ1eCX5A6CiPivg_pb_x600.png");
+}
+
+.product-card__image--4 {
+ background-image: url("https://cdn.usegalileo.ai/sdxl10/0eea6aee-9921-49ac-bbaa-7def81318f98.png");
+}
+
+.product-card__image--5 {
+ background-image: url("https://cdn.usegalileo.ai/sdxl10/c6ab2f06-0ec1-4d34-bd49-6520fdd63180.png");
+}
+
+.product-card__image--6 {
+ background-image: url("https://cdn.usegalileo.ai/sdxl10/d90f77b3-fdd9-4c18-aac8-5a54b27fe7de.png");
+}
+
+.product-card__image--7 {
+ background-image: url("https://cdn.usegalileo.ai/sdxl10/0f7256d8-8e72-4104-b428-cea3b42e76d9.png");
+}
+
+.product-card__image--8 {
+ background-image: url("https://cdn.usegalileo.ai/sdxl10/9204a299-2794-4f6b-af2a-2fa313afab9c.png");
+}
diff --git a/src/pages/CatalogPage/CatalogPage.tsx b/src/pages/CatalogPage/CatalogPage.tsx
new file mode 100644
index 0000000..49e0274
--- /dev/null
+++ b/src/pages/CatalogPage/CatalogPage.tsx
@@ -0,0 +1,250 @@
+import '@/index.css';
+import './CatalogPage.css';
+import {
+ Container,
+ Box,
+ Button,
+ Stack,
+ Combobox,
+ useCombobox,
+ InputBase,
+ Group,
+ TextInput,
+ Grid,
+ ComboboxStore,
+ Pagination,
+} from '@mantine/core';
+import { useMemo, useState } from 'react';
+import { ProductCardList } from '@/features/catalog/ProductCardList';
+import { useCategories } from '@/features/catalog/useCategories';
+import { useProductCards } from '@/features/catalog/useProductCards';
+import {
+ productSortOptions,
+ ProductSortOption,
+} from '@/shared/constants/sorting';
+import { useDebouncedValue } from '@/shared/hooks/useDebouncedValue';
+import { CategoryButton } from '@/shared/ui/CategoryButton';
+
+export default function CatalogPage() {
+ const { data: categories = [] } = useCategories();
+ const [selectedCategorySlugs, setSelectedCategorySlugs] = useState(
+ [],
+ );
+
+ const [selectedCountries, setSelectedCountries] = useState([]);
+
+ const [page, setPage] = useState(1);
+ const [searchInput, setSearchInput] = useState('');
+ const debouncedSearchTerm = useDebouncedValue(searchInput.toLowerCase());
+
+ const combobox: ComboboxStore = useCombobox({
+ onDropdownClose: (): void => combobox.resetSelectedOption(),
+ });
+
+ const [sortBy, setSortBy] = useState('price_asc');
+
+ const slugToIdMap = useMemo(() => {
+ return categories.reduce(
+ (acc, category) => {
+ const slug = category.slug['en-US'];
+ if (slug) acc[slug] = category.id;
+ return acc;
+ },
+ {} as Record,
+ );
+ }, [categories]);
+
+ const selectedCategoryIds = selectedCategorySlugs
+ .map((slug) => slugToIdMap[slug])
+ .filter(Boolean);
+
+ const toggleCategory = (slug: string) => {
+ setSelectedCategorySlugs((prev) =>
+ prev.includes(slug) ? prev.filter((s) => s !== slug) : [...prev, slug],
+ );
+ setPage(1);
+ };
+
+ const resetCategories = () => {
+ setSelectedCategorySlugs([]);
+ setPage(1);
+ };
+
+ const toggleCountry = (country: string) => {
+ setSelectedCountries((prev) =>
+ prev.includes(country)
+ ? prev.filter((c) => c !== country)
+ : [...prev, country],
+ );
+ setPage(1);
+ };
+
+ const resetCountries = () => {
+ setSelectedCountries([]);
+ setPage(1);
+ };
+
+ const { data, isLoading } = useProductCards({
+ categoryIds: selectedCategoryIds,
+ countries: selectedCountries,
+ sortBy,
+ page,
+ searchTerm: debouncedSearchTerm.length >= 3 ? debouncedSearchTerm : '',
+ });
+
+ const total = data?.total ?? 0;
+ const products = data?.items ?? [];
+
+ return (
+
+
+ {
+ setSearchInput(e.currentTarget.value);
+ setPage(1);
+ }}
+ leftSection={
+
+ }
+ rightSectionPointerEvents="none"
+ />
+
+
+
+
+ {categories?.map((category) => {
+ const slug = category.slug['en-US'];
+ const label = category.name['en-US'].split(' ')[0];
+
+ if (!slug || !label) return null;
+ const selected = selectedCategorySlugs.includes(slug);
+
+ return (
+
+ toggleCategory(slug)}
+ />
+
+ );
+ })}
+
+ {['France', 'Spain', 'Italy'].map((country) => {
+ const selected = selectedCountries.includes(country);
+ return (
+
+ toggleCountry(country)}
+ />
+
+ );
+ })}
+
+
+
+
+
+
+
+ {
+ setSortBy(val as ProductSortOption);
+ combobox.closeDropdown();
+ setPage(1);
+ }}
+ >
+
+ }
+ rightSectionPointerEvents="none"
+ onClick={() => combobox.toggleDropdown()}
+ classNames={{ input: 'form-input' }}
+ aria-label="Sort products by"
+ >
+ {productSortOptions.find((opt) => opt.value === sortBy)?.label}
+
+
+
+
+
+ {productSortOptions.map((option) => (
+
+ {option.label}
+
+ ))}
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/src/pages/HomePage/HomePage.css b/src/pages/HomePage/HomePage.css
new file mode 100644
index 0000000..6fcb280
--- /dev/null
+++ b/src/pages/HomePage/HomePage.css
@@ -0,0 +1,230 @@
+.hero {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ text-align: center;
+ width: 100%;
+ max-width: 1920px;
+ min-height: 600px;
+ border-radius: 0.75rem;
+ padding: 1rem;
+ gap: 1.5rem;
+ background-size: cover;
+ background-position: center;
+ background-repeat: no-repeat;
+ background-image:
+ linear-gradient(rgba(0, 0, 0, 0.1) 0%, rgba(0, 0, 0, 0.4) 100%),
+ url('../../assets/wine.webp');
+}
+
+.hero__title {
+ color: white;
+ font-size: 2.25rem !important;
+ font-weight: 900;
+ line-height: 1.25;
+ letter-spacing: -0.033em;
+}
+
+.hero__subtitle {
+ color: white;
+ font-size: 0.875rem;
+ font-weight: 400;
+ line-height: normal;
+}
+
+.section-title {
+ color: #f8f9fb;
+ font-size: 1.375rem;
+ font-weight: 700;
+ line-height: 1.25;
+ letter-spacing: -0.015em;
+ padding: 1.25rem 1rem 0.75rem;
+}
+
+.card {
+ padding-top: 10px;
+ /* min-width: 280px !important; */
+ max-width: 400px !important;
+ height: 420px !important;
+ background: #1d2a36;
+ border-radius: 0.75rem;
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
+}
+
+.card__image {
+ width: 100%;
+ height: 260px;
+ min-height: 260px;
+ background-size: cover;
+ background-position: center;
+ border-radius: 0.75rem;
+}
+
+.card__content {
+ padding: 1.5rem;
+}
+
+.card__title {
+ color: #f8f9fb;
+ font-size: 1.25rem !important;
+ margin-bottom: 0.5rem;
+}
+
+.card__description {
+ color: #8a9dc0;
+ font-size: 0.875rem;
+ line-height: 1.5;
+}
+
+.card__image--chardonnay {
+ background-image: url('../../assets/wine4.png');
+}
+
+.card__image--pinot {
+ background-image: url('../../assets/wine2.png');
+}
+
+.card__image--cabernet {
+ background-image: url('../../assets/wine1.png');
+}
+
+.card__image--sauvignon {
+ background-image: url('../../assets/wine3.png');
+}
+
+.card__content {
+ display: flex;
+ flex-direction: column;
+}
+
+.card__title {
+ color: #f8f9fb;
+ font-size: 1rem;
+ font-weight: 500;
+ line-height: normal;
+}
+
+.card__description {
+ color: #8a9dc0;
+ font-size: 0.875rem;
+ font-weight: 400;
+ line-height: normal;
+}
+
+.discount {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ background-color: #1d2a36;
+ border-radius: 0.75rem;
+ margin: 2rem 1rem;
+ padding: 2rem 1rem;
+ width: 100%;
+ gap: 1rem;
+}
+
+.discount-title {
+ color: #f4c753;
+ font-size: 1.75rem;
+ font-weight: 700;
+ margin-bottom: 1rem;
+}
+
+.discount-description {
+ color: #f8f9fb;
+ font-size: 1.125rem;
+ line-height: 1.6;
+}
+
+.features {
+ display: flex;
+ flex-direction: column;
+ gap: 2.5rem;
+ padding: 2.5rem 1rem;
+ width: 100%;
+ max-width: 1920px;
+}
+
+.features__header {
+ display: flex;
+ flex-direction: column !important;
+ gap: 1.5rem;
+}
+
+.features__title {
+ color: #f8f9fb;
+ font-size: 2rem;
+ font-weight: 700;
+ line-height: 1.25;
+ letter-spacing: -0.033em;
+ max-width: 720px;
+}
+
+.features__subtitle {
+ color: #f8f9fb;
+ font-size: 1rem;
+ font-weight: 400;
+ line-height: normal;
+ max-width: 720px;
+}
+
+.features__grid {
+ display: flex;
+ justify-content: center !important;
+ width: 100%;
+ max-width: 1920px;
+}
+
+.feature-card {
+ display: flex;
+ border-radius: 0.5rem;
+ border: 1px solid #32415d;
+ background-color: #1d2a36;
+ width: 32%;
+ max-height: 142px;
+}
+
+.feature-card__icon {
+ color: #f8f9fb;
+}
+
+.feature-card__content {
+ gap: 0.25rem;
+ padding: 1rem;
+}
+
+.feature-card__title {
+ color: #f8f9fb;
+ font-size: 1rem;
+ font-weight: 700;
+ line-height: 1.25;
+}
+
+.feature-card__description {
+ align-self: center;
+ color: #8a9dc0;
+ font-size: 0.875rem;
+ font-weight: 400;
+ line-height: normal;
+}
+
+@media (max-width: 768px) {
+ .discount-section {
+ padding: 1.5rem 1.5rem;
+ }
+
+ .discount-title {
+ font-size: 1.5rem;
+ }
+
+ .discount-description {
+ font-size: 1rem;
+ }
+}
+
+@media (max-width: 480px) {
+ .discount-section {
+ padding: 1.5rem 0.5rem;
+ }
+}
diff --git a/src/pages/HomePage/HomePage.test.tsx b/src/pages/HomePage/HomePage.test.tsx
new file mode 100644
index 0000000..52bf280
--- /dev/null
+++ b/src/pages/HomePage/HomePage.test.tsx
@@ -0,0 +1,35 @@
+import { MantineProvider } from '@mantine/core';
+import { render, screen } from '@testing-library/react';
+import { BrowserRouter } from 'react-router-dom';
+import { describe, it, expect, vi } from 'vitest';
+import { theme } from '@/app/theme';
+import { HomePage } from '@/pages/HomePage/HomePage';
+
+const IntersectionObserverMock = vi.fn(() => ({
+ disconnect: vi.fn(),
+ observe: vi.fn(),
+ takeRecords: vi.fn(),
+ unobserve: vi.fn(),
+}));
+
+const ResizeObserverMock = vi.fn(() => ({
+ observe: vi.fn(),
+ unobserve: vi.fn(),
+ disconnect: vi.fn(),
+}));
+
+vi.stubGlobal('IntersectionObserver', IntersectionObserverMock);
+vi.stubGlobal('ResizeObserver', ResizeObserverMock);
+
+describe('HomePage Component', () => {
+ it('renders main title', () => {
+ render(
+
+
+
+
+ ,
+ );
+ expect(screen.getByText(/Explore the Finest Wines/i)).toBeInTheDocument();
+ });
+});
diff --git a/src/pages/HomePage/HomePage.tsx b/src/pages/HomePage/HomePage.tsx
new file mode 100644
index 0000000..66d40f9
--- /dev/null
+++ b/src/pages/HomePage/HomePage.tsx
@@ -0,0 +1,135 @@
+import {
+ Container,
+ Title,
+ Text,
+ Box,
+ Group,
+ Badge,
+ Button,
+} from '@mantine/core';
+import { Link } from 'react-router-dom';
+import '@/pages/HomePage/HomePage.css';
+import { ROUTES } from '@/app/routes';
+import { FeatureCard } from '@/components/Card/FeatureCard.tsx';
+import { Slider } from '@/components/Slider/Slider';
+
+export function HomePage() {
+ const features = [
+ {
+ title: 'Exclusive Selection',
+ description:
+ 'Explore a hand-picked collection of wines from top vineyards',
+ icon: (
+
+ ),
+ },
+ {
+ title: 'Tasting Events',
+ description: 'Join our wine tasting events and discover new flavors',
+ icon: (
+
+ ),
+ },
+ {
+ title: 'Fast Delivery',
+ description: 'Enjoy quick and reliable delivery of your favorite wines',
+ icon: (
+
+ ),
+ },
+ ];
+
+ return (
+
+
+ Explore the Finest Wines
+
+ Discover a curated selection of exceptional wines from renowned
+ vineyards around the globe.
+
+
+
+
+
+
+
+
+ Summer Sale!
+
+
+
+ To get 25% off all products in your cart use code
+
+ SUMMER25
+
+ at checkout.
+
+
+
+
+
+
+
+ Why Choose us?
+
+
+ Experience the art of wine with us. We offer a wide variety of
+ wines, tasting events, and convenient delivery options to enhance
+ your appreciation.
+
+
+
+
+
+ {features.map((feature, index) => (
+
+ ))}
+
+
+
+ );
+}
diff --git a/src/pages/LoginPage.tsx b/src/pages/LoginPage.tsx
new file mode 100644
index 0000000..e732bad
--- /dev/null
+++ b/src/pages/LoginPage.tsx
@@ -0,0 +1,43 @@
+import {
+ Box,
+ Container,
+ Group,
+ Paper,
+ Stack,
+ Text,
+ Title,
+} from '@mantine/core';
+import { Link } from 'react-router-dom';
+import { ROUTES } from '@/app/routes';
+import { LoginForm } from '@/features/login/LoginForm';
+import '@/pages/RegistrationPage/RegistrationPage.css';
+
+export default function LoginPage() {
+ return (
+
+
+
+
+
+ Welcome Back
+
+
+
+
+ Don't have an account?{' '}
+
+ Sign Up
+
+
+
+
+
+
+
+ );
+}
diff --git a/src/pages/NotFoundPage/NotFoundPage.css b/src/pages/NotFoundPage/NotFoundPage.css
new file mode 100644
index 0000000..e4f48a0
--- /dev/null
+++ b/src/pages/NotFoundPage/NotFoundPage.css
@@ -0,0 +1,66 @@
+.not-found-content {
+ width: 100%;
+ max-width: 500px;
+ background-color: #1d2a36;
+ border: 1px solid #32415d;
+ border-radius: 0.75rem;
+ padding: 2rem;
+ display: flex;
+ flex-direction: column;
+ gap: 1.5rem;
+ align-items: center;
+ text-align: center;
+ opacity: 0;
+ animation: fadeIn 1s ease-out forwards;
+}
+
+.not-found-text {
+ display: flex;
+ flex-direction: column !important;
+ gap: 0.75rem;
+ justify-content: center !important;
+}
+
+.not-found-title {
+ color: #f4c753 !important;
+ font-size: 4rem !important;
+ font-weight: 700;
+ line-height: 1.25;
+ margin-bottom: 0.75rem;
+ animation: float 3s ease-in-out infinite;
+}
+
+.not-found-subtitle {
+ color: #f8f9fb;
+ font-size: 1.5rem;
+ font-weight: 700;
+ line-height: 1.25;
+ margin-bottom: 0.5rem;
+}
+
+.not-found-description {
+ color: #8a9dc0;
+ font-size: 1rem;
+ line-height: 1.5;
+ margin-bottom: 1rem;
+}
+
+.button__link {
+ color: #131c24;
+}
+
+@keyframes fadeIn {
+ to {
+ opacity: 1;
+ }
+}
+
+@keyframes float {
+ 0%,
+ 100% {
+ transform: translateY(0);
+ }
+ 50% {
+ transform: translateY(-10px);
+ }
+}
diff --git a/src/pages/NotFoundPage/NotFoundPage.tsx b/src/pages/NotFoundPage/NotFoundPage.tsx
new file mode 100644
index 0000000..096d120
--- /dev/null
+++ b/src/pages/NotFoundPage/NotFoundPage.tsx
@@ -0,0 +1,72 @@
+import {
+ useMantineTheme,
+ Container,
+ Title,
+ Text,
+ Button,
+ Group,
+ Box,
+} from '@mantine/core';
+import { Link } from 'react-router-dom';
+import './NotFoundPage.css';
+import { ROUTES } from '@/app/routes.tsx';
+
+export default function NotFoundPage() {
+ const theme = useMantineTheme();
+ return (
+
+
+
+
+
+ Wine not
+
+
+
+
+
+ 404
+
+
+ Page Not Found
+
+
+ This page is unavailable or under construction.
+
+
+
+
+
+
+ );
+}
diff --git a/src/pages/ProductPage/ProductPage.css b/src/pages/ProductPage/ProductPage.css
new file mode 100644
index 0000000..909cf15
--- /dev/null
+++ b/src/pages/ProductPage/ProductPage.css
@@ -0,0 +1,311 @@
+body.mantine-Modal-body {
+ overflow: hidden;
+}
+
+.mantine-Modal-content {
+ overflow: hidden;
+}
+
+.divider {
+ margin: clamp(1rem, 0.7532rem + 1.039vw, 2rem) auto;
+}
+
+.attribute {
+ background: rgba(138, 157, 192, 0.12);
+ padding: 0.5rem 1rem;
+ border-radius: 4px;
+ text-align: center;
+ font-size: 0.875rem;
+ text-transform: capitalize;
+}
+
+.value {
+ text-align: center;
+ font-size: 0.875rem;
+}
+
+.product-content {
+ display: flex;
+ justify-content: space-between;
+ gap: 40px;
+ width: 85%;
+ padding: 2rem;
+ background: #1d2a36;
+ border: 1px solid #32415d;
+ border-radius: 0.75rem;
+}
+
+.image-section {
+ max-width: 500px;
+ width: 100%;
+}
+
+.details-section {
+ flex: 1;
+ min-width: 300px;
+ width: 100%;
+}
+
+.main-product-image {
+ flex: 1;
+ max-height: 100vh;
+ max-width: 100vw;
+ border-radius: 0.75rem;
+ cursor: pointer;
+ object-fit: cover;
+ background-color: #f8f9fb;
+}
+
+.modal-image {
+ max-height: 80%;
+ max-width: 80%;
+ width: 100%;
+ height: 100vh;
+ cursor: pointer;
+ background-color: #f8f9fb;
+ aspect-ratio: 1/1;
+ object-fit: cover;
+ background-size: cover;
+ background-position: center;
+ background-repeat: no-repeat;
+ border-radius: 0.75rem;
+}
+
+.thumbnails-container {
+ justify-content: center;
+ margin-top: 16px;
+ gap: 1rem;
+}
+
+.thumbnail-item {
+ width: 60px;
+ height: 60px;
+ border-radius: 4px;
+ overflow: hidden;
+ cursor: pointer;
+ border: 2px solid transparent;
+ transition: border-color 0.3s ease;
+}
+
+.thumbnail-image {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+ background-color: #f8f9fb;
+}
+
+.thumbnail-item.active-thumbnail {
+ border-color: #fab005;
+}
+
+.carousel {
+ .carousel-viewport {
+ perspective: 1000px;
+ will-change: transform;
+ border-radius: 0.875rem;
+ }
+
+ .carousel-slide {
+ max-height: 53vh;
+ border-radius: 0.75rem;
+ overflow: hidden;
+ background-color: #f8f9fb;
+ }
+
+ .carousel-container {
+ gap: var(--mantine-spacing-md);
+ }
+}
+
+.slider {
+ display: flex;
+ max-width: 600px;
+ width: 100%;
+}
+
+.carousel-indicator {
+ width: 12px;
+ height: 4px;
+ transition: width 250ms ease;
+ background-color: rgba(0, 0, 0, 0.4);
+}
+
+.carousel-indicator[data-active] {
+ width: 24px;
+ background-color: #fab005;
+}
+
+.modal-container {
+ transition: transform 0.3s ease-in-out;
+ will-change: transform;
+}
+
+.modal-carousel {
+ .mantine-Carousel-indicator {
+ width: 12px;
+ height: 4px;
+ }
+
+ .mantine-Carousel-indicator[data-active] {
+ background-color: #fab005;
+ width: 18px;
+ height: 4px;
+ transition: width 250ms ease;
+ }
+}
+
+.modal-image {
+ max-height: 80%;
+ max-width: 80%;
+ margin: 0 auto;
+ display: block;
+ border-radius: 16px;
+}
+
+.title {
+ font-size: clamp(1.5rem, 1.3766rem + 0.5195vw, 2rem);
+}
+
+.subtitle {
+ font-size: clamp(1.2rem, 1.126rem + 0.3117vw, 1.5rem);
+ line-height: 1.6;
+}
+
+.description {
+ font-size: clamp(1rem, 0.9506rem + 0.2078vw, 1.2rem);
+ line-height: 1.6;
+}
+
+@media (max-width: 1385px) {
+ .product-page {
+ max-width: 100%;
+ }
+ .slider {
+ width: 60%;
+ max-width: 400px;
+ }
+}
+
+@media (max-width: 1280px) {
+ .product-content {
+ gap: 40px;
+ width: 100%;
+ }
+}
+
+@media (max-width: 1024px) {
+ .divider {
+ margin: 1rem auto;
+ }
+}
+
+@media (max-width: 940px) {
+ .product-content {
+ flex-direction: column;
+ align-items: center;
+ gap: 30px;
+ }
+
+ .modal-close-btn {
+ width: 40px;
+ height: 40px;
+ }
+
+ .modal-carousel .mantine-Carousel-control {
+ width: 40px;
+ height: 40px;
+ }
+
+ .details-section {
+ text-align: center;
+ justify-content: center;
+ }
+
+ .price-content {
+ justify-content: center;
+ }
+}
+
+@media (max-width: 900px) {
+ .carousel-control {
+ width: 25px;
+ height: 25px;
+ }
+}
+
+@media (max-width: 768px) {
+ .product-page {
+ flex-direction: column;
+ }
+}
+
+@media (max-width: 600px) {
+ .product-page-container {
+ padding: 0 10px;
+ }
+
+ .carousel-slide {
+ height: 50vh;
+ }
+ .modal-slide {
+ height: 70vh;
+ }
+
+ .thumbnail-item {
+ width: 40px;
+ height: 40px;
+ }
+
+ .modal-close-btn {
+ width: 35px;
+ height: 35px;
+ }
+
+ .modal-carousel {
+ .modal-control {
+ width: 35px;
+ height: 35px;
+ }
+ .modal-indicator {
+ width: 10px;
+ height: 3px;
+ }
+ .modal-indicator[data-active] {
+ width: 18px;
+ }
+ }
+
+}
+
+@media (max-width: 480px) {
+ .carousel-slide,
+ .main-product-image {
+ max-height: 40vh !important;
+ }
+ .modal-slide {
+ height: 65vh;
+ }
+}
+
+@media (max-width: 400px) {
+ .carousel-slide,
+ .main-product-image{
+ max-height: 35vh !important;
+ }
+ .modal-slide {
+ height: 58vh;
+ }
+
+ .thumbnail-item {
+ width: 35px;
+ height: 35px;
+ }
+
+ .product-title {
+ font-size: 1.5rem;
+ }
+
+ .attributes-table {
+ font-size: 0.75rem;
+ }
+}
diff --git a/src/pages/ProductPage/ProductPage.tsx b/src/pages/ProductPage/ProductPage.tsx
new file mode 100644
index 0000000..7a4d3e6
--- /dev/null
+++ b/src/pages/ProductPage/ProductPage.tsx
@@ -0,0 +1,371 @@
+import { Carousel } from '@mantine/carousel';
+import {
+ Box,
+ Text,
+ Group,
+ Image,
+ Button,
+ Table,
+ Title,
+ Container,
+ Badge,
+ Divider,
+ Modal,
+ CloseButton,
+} from '@mantine/core';
+import { useState, useRef, useEffect, RefObject, useMemo } from 'react';
+import { useParams, useNavigate, NavigateFunction } from 'react-router-dom';
+import { ROUTES } from '@/app/routes';
+import { useProductById } from '@/features/product/useProductById';
+import {
+ addToCart,
+ removeFromCart,
+ useCartStore,
+} from '@/shared/hooks/useCartStore.ts';
+import { useImageHandler } from '@/shared/hooks/useImageHandler.ts';
+import { CenterLoader } from '@/shared/ui/CenterLoader';
+import {
+ notifyError,
+ notifySuccess,
+} from '@/shared/utils/custom-notifications';
+import type { ModalEmbla, Wine, WineAttribute } from '@/types/types.tsx';
+import './ProductPage.css';
+
+const TRANSITION_DURATION = 300;
+
+export default function ProductPage() {
+ const { id } = useParams<{ id: string }>();
+
+ const {
+ data: wine,
+ error,
+ isLoading,
+ } = useProductById(id) as {
+ data: Wine | undefined;
+ error: unknown;
+ isLoading: boolean;
+ };
+
+ const navigate: NavigateFunction = useNavigate();
+
+ const mainCarouselRef: RefObject =
+ useRef(null);
+ const modalCarouselRef: RefObject =
+ useRef(null);
+ const [modalOpened, setModalOpened] = useState(false);
+ const [currentImageIndex, setCurrentImageIndex] = useState(0);
+
+ const cart = useCartStore((state) => state.cart);
+ const cartItem = useMemo(() => {
+ if (!wine) return undefined;
+ return cart?.lineItems.find(
+ (item) => item.productId === wine.id && item.variant?.id === 1,
+ );
+ }, [cart, wine]);
+
+ const [isProcessing, setIsProcessing] = useState(false);
+
+ const handleAddToCart = async (e: React.MouseEvent) => {
+ e.stopPropagation();
+ if (isProcessing) return;
+
+ setIsProcessing(true);
+ try {
+ await addToCart(wine.id);
+ notifySuccess({ message: 'Added to cart', autoClose: 2000 });
+ } catch (error) {
+ notifyError(error, { message: 'Failed adding to cart' });
+ } finally {
+ setIsProcessing(false);
+ }
+ };
+
+ const handleRemove = async (e: React.MouseEvent) => {
+ e.stopPropagation();
+ if (!cartItem || isProcessing) return;
+
+ setIsProcessing(true);
+ try {
+ await removeFromCart(cartItem.id);
+ notifySuccess({ message: 'Product removed', autoClose: 2000 });
+ } catch (error) {
+ notifyError(error, { message: 'Failed to remove' });
+ } finally {
+ setIsProcessing(false);
+ }
+ };
+
+ const { handleImageLoad } = useImageHandler();
+
+ useEffect(() => {
+ if (error) {
+ notifyError(error, {
+ message: 'Something went wrong. Please try again later.',
+ });
+ }
+ if (modalOpened && modalCarouselRef.current) {
+ let raf: number;
+ const initCarousel: () => void = (): void => {
+ modalCarouselRef.current?.reInit();
+ modalCarouselRef.current?.scrollTo(currentImageIndex);
+ };
+
+ raf = requestAnimationFrame(initCarousel);
+
+ return (): void => cancelAnimationFrame(raf);
+ }
+ }, [modalOpened, currentImageIndex, error]);
+
+ if (isLoading) return ;
+
+ if (!wine) return null;
+
+ const ratingAttribute: WineAttribute | undefined = wine.attributes.find(
+ (attr: WineAttribute): boolean => attr.name === 'Rating',
+ );
+ const ratingValue: number = ratingAttribute
+ ? parseFloat(ratingAttribute.value)
+ : wine.rating;
+
+ const handleThumbnailClick = (index: number): void => {
+ setCurrentImageIndex(index);
+ mainCarouselRef.current?.scrollTo(index);
+ modalCarouselRef.current?.scrollTo(index);
+ };
+
+ const openModal = (index: number): void => {
+ setCurrentImageIndex(index);
+ setModalOpened(true);
+ };
+
+ return (
+
+
+
+ setCurrentImageIndex(index)}
+ getEmblaApi={(embla: ModalEmbla): ModalEmbla =>
+ (mainCarouselRef.current = embla)
+ }
+ classNames={{
+ viewport: 'carousel-viewport',
+ container: 'carousel-container',
+ slide: 'carousel-slide',
+ }}
+ >
+ {wine.image.map((img: string, index: number) => (
+
+ openModal(index)}
+ onLoad={handleImageLoad}
+ />
+
+ ))}
+
+
+
+ {wine.image.map((_: string, index: number) => (
+ handleThumbnailClick(index)}
+ >
+
+
+ ))}
+
+
+
+
+
+ {wine.name}
+
+
+
+
+
+ Description:
+
+
+ {wine.description}
+
+
+
+
+
+ Price:
+
+
+ {wine.discountedPrice ? (
+ <>
+
+ ${wine.discountedPrice}
+
+
+ ${wine.price}
+
+
+ Save ${(wine.price - wine.discountedPrice).toFixed(2)}
+
+ >
+ ) : (
+
+ ${wine.price}
+
+ )}
+
+
+
+
+
+ Wine Details:
+
+
+
+ {wine.attributes
+ .filter(
+ (attr: WineAttribute): boolean => attr.name !== 'rating',
+ )
+ .map((attr: WineAttribute, index: number) => (
+
+
+ {attr.name}:
+
+
+ {attr.value}
+
+
+ ))}
+
+
+
+ Rating:
+
+
+
+
+ ★ {ratingValue}
+
+
+ /5
+
+
+
+
+
+
+
+
+ {cartItem ? (
+
+ ) : (
+
+ )}
+
+
+
+
+
+ setModalOpened(false)}
+ fullScreen
+ padding={0}
+ withCloseButton={false}
+ transitionProps={{ duration: TRANSITION_DURATION }}
+ >
+ setModalOpened(false)}
+ style={{
+ position: 'fixed',
+ top: 20,
+ right: 20,
+ zIndex: 100,
+ backgroundColor: 'dark.7',
+ color: 'primary.0',
+ }}
+ size="xl"
+ />
+
+ setCurrentImageIndex(index)}
+ getEmblaApi={(embla: ModalEmbla): ModalEmbla =>
+ (modalCarouselRef.current = embla)
+ }
+ style={{
+ backgroundColor: '#131c24',
+ height: '100vh',
+ display: 'flex',
+ alignItems: 'center',
+ }}
+ classNames={{
+ viewport: 'modal-viewport',
+ container: 'modal-container',
+ slide: 'modal-slide',
+ }}
+ >
+ {wine.image.map((img: string, index: number) => (
+
+
+
+ ))}
+
+
+
+ );
+}
diff --git a/src/pages/ProfilePage/ProfilePage.css b/src/pages/ProfilePage/ProfilePage.css
new file mode 100644
index 0000000..8e92005
--- /dev/null
+++ b/src/pages/ProfilePage/ProfilePage.css
@@ -0,0 +1,24 @@
+.profile-container {
+ margin-top: 1rem;
+ max-width: 860px;
+ width: 100%;
+}
+
+.container-dark {
+ background-color: #1d2a36;
+ border: 1px solid #32415d;
+ border-radius: 0.75rem;
+ padding: 2rem;
+}
+
+.address-item {
+ background-color: #131c24;
+ border: 1px solid #32415d;
+ border-radius: 8px;
+ padding: 20px;
+}
+
+.address-text {
+ font-size: 14px;
+ margin-bottom: 4px;
+}
\ No newline at end of file
diff --git a/src/pages/ProfilePage/ProfilePage.tsx b/src/pages/ProfilePage/ProfilePage.tsx
new file mode 100644
index 0000000..d1a2397
--- /dev/null
+++ b/src/pages/ProfilePage/ProfilePage.tsx
@@ -0,0 +1,361 @@
+import {
+ BaseAddress,
+ ClientResponse,
+ Customer,
+} from '@commercetools/platform-sdk';
+import {
+ Avatar,
+ Badge,
+ Box,
+ Button,
+ Container,
+ Grid,
+ Group,
+ Stack,
+ Text,
+ Title,
+ Modal,
+ useMantineTheme,
+ useModalsStack,
+} from '@mantine/core';
+import '@/pages/ProfilePage/ProfilePage.css';
+import { useEffect, useState } from 'react';
+import { useAuthStore } from '@/features/auth/auth-state';
+import { deleteAddress } from '@/features/profile/address';
+import { AddressForm } from '@/features/profile/AddressForm';
+import { ChangePasswordForm } from '@/features/profile/ChangePasswordForm';
+import { PersonalInfoForm } from '@/features/profile/PersonalInfoForm';
+import { countries } from '@/shared/constants/countries';
+import { getUserInfo } from '@/shared/utils/get-user-info';
+
+export default function ProfilePage() {
+ const theme = useMantineTheme();
+
+ const stack = useModalsStack([
+ 'change-password',
+ 'update-info',
+ 'add-address',
+ 'edit-address',
+ 'delete-address',
+ ]);
+
+ const status = useAuthStore((state) => state.status);
+ const isAuthenticated = status === 'AUTHENTICATED';
+
+ const [user, setUser] = useState | null>(null);
+
+ const [selectedAddress, setSelectedAddress] = useState(
+ null,
+ );
+
+ useEffect(() => {
+ const getUser = async () => {
+ if (isAuthenticated) {
+ const user = await getUserInfo();
+ if (user) {
+ setUser(user);
+ }
+ }
+ };
+ getUser();
+ }, [isAuthenticated]);
+
+ return (
+
+
+
+ My Profile
+
+
+
+
+
+
+
+
+ {user?.body.firstName} {user?.body.lastName}
+
+
+
+
+
+
+
+
+
+
+
+ Personal Information
+
+
+
+
+
+
+
+ First Name
+
+ {user?.body.firstName}
+
+
+
+
+
+ Last Name
+
+ {user?.body.lastName}
+
+
+
+
+
+ Email
+
+ {user?.body.email}
+
+
+
+
+
+ Date of Birth
+
+ {user?.body.dateOfBirth}
+
+
+
+
+
+
+ My addresses
+
+ {user?.body.addresses.map((address, index) => (
+
+
+
+ {user.body.shippingAddressIds?.includes(
+ address.id ?? '',
+ ) && (
+
+ {address.id === user.body.defaultShippingAddressId
+ ? 'Default shipping address'
+ : user.body.shippingAddressIds?.includes(
+ address.id ?? '',
+ )
+ ? 'Shipping address'
+ : ''}
+
+ )}
+ {user.body.billingAddressIds?.includes(
+ address.id ?? '',
+ ) && (
+
+ {address.id === user.body.defaultBillingAddressId
+ ? 'Default billing address'
+ : user.body.billingAddressIds?.includes(
+ address.id ?? '',
+ )
+ ? 'Billing address'
+ : ''}
+
+ )}
+
+
+
+ {address.streetName}
+ {address.postalCode}
+ {address.city}
+
+ {countries[address.country as keyof typeof countries]}
+
+
+
+
+
+
+
+
+
+ ))}
+
+
+
+ {/* Change password */}
+
+ {
+ stack.close('change-password');
+ const updatedUser = await getUserInfo();
+ if (updatedUser) {
+ setUser(updatedUser);
+ }
+ }}
+ />
+
+
+ {/* Update user info */}
+
+ {
+ stack.close('update-info');
+ const updatedUser = await getUserInfo();
+ if (updatedUser) {
+ setUser(updatedUser);
+ }
+ }}
+ />
+
+
+ {/* Add address */}
+
+ stack.close('add-address')}
+ type={'add'}
+ address={null}
+ onUpdate={async () => {
+ const updatedUser = await getUserInfo();
+ if (updatedUser) {
+ setUser(updatedUser);
+ }
+ }}
+ />
+
+
+ {/* Edit address */}
+
+ stack.close('edit-address')}
+ type={'edit'}
+ address={selectedAddress}
+ onUpdate={async () => {
+ const updatedUser = await getUserInfo();
+ if (updatedUser) {
+ setUser(updatedUser);
+ }
+ }}
+ />
+
+
+ {/* Delete address */}
+ {
+ stack.close('delete-address');
+ const updatedUser = await getUserInfo();
+ if (updatedUser) {
+ setUser(updatedUser);
+ }
+ }}
+ >
+
+ Are you sure you want to remove this address?
+
+
+ {selectedAddress?.streetName}, {selectedAddress?.city},{' '}
+ {countries[selectedAddress?.country as keyof typeof countries]},{' '}
+ {selectedAddress?.postalCode}
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/src/pages/RegistrationPage/RegistrationPage.css b/src/pages/RegistrationPage/RegistrationPage.css
new file mode 100644
index 0000000..c9d2a5a
--- /dev/null
+++ b/src/pages/RegistrationPage/RegistrationPage.css
@@ -0,0 +1,105 @@
+.auth-container {
+ align-self: center;
+ display: flex;
+ justify-content: center;
+ padding: 1rem;
+}
+
+.auth-form {
+ background-color: #1d2a36;
+ border: 1px solid #32415d;
+ border-radius: 0.75rem;
+ padding: 0 2rem 1rem 2rem;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ max-width: 580px !important;
+}
+
+.auth-title {
+ color: #f8f9fb;
+ font-size: 1.75rem;
+ font-weight: 700;
+ line-height: 1.25;
+ letter-spacing: -0.015em;
+ text-align: center;
+}
+
+.form {
+ display: flex;
+ flex-direction: column;
+ gap: 0.3rem;
+}
+
+.form-label {
+ color: #f8f9fb;
+ font-size: 0.875rem;
+ font-weight: 500;
+ line-height: 1;
+ margin-bottom: 0.2rem;
+}
+
+.form-input, .form-input input {
+ border-radius: 0.5rem;
+ border: 1px solid #32415d !important;
+ background-color: #131c24 !important;
+ color: #f8f9fb;
+ font-size: 0.875rem;
+ font-weight: 400;
+}
+
+.form-input input {
+ border: 0px solid #32415d !important;
+}
+
+.form-input:focus, .form-input input:focus {
+ outline: none;
+ border: 1px solid #f4c753 !important;
+}
+
+.error .form-input {
+ border-color: #c62828 !important;
+}
+
+.error .form-input input:focus {
+ border: 0 solid #c62828 !important;
+}
+
+.form-checkbox {
+ width: 1rem;
+ height: 1rem;
+ accent-color: #f4c753;
+}
+
+.checkbox-group {
+ flex-direction: row;
+ align-items: center;
+ gap: 0.75rem;
+}
+
+.checkbox-label {
+ color: #f8f9fb;
+ font-size: 0.875rem;
+ font-weight: 400;
+}
+
+.auth-button {
+ width: 100%;
+ margin-top: 0.5rem;
+}
+
+.auth-footer {
+ text-align: center;
+ color: #8a9dc0;
+ font-size: 0.875rem;
+}
+
+.auth-link {
+ color: #f4c753;
+ text-decoration: none;
+ font-weight: 500;
+}
+
+.auth-link:hover {
+ text-decoration: underline;
+}
diff --git a/src/pages/RegistrationPage/RegistrationPage.tsx b/src/pages/RegistrationPage/RegistrationPage.tsx
new file mode 100644
index 0000000..cece94b
--- /dev/null
+++ b/src/pages/RegistrationPage/RegistrationPage.tsx
@@ -0,0 +1,27 @@
+import { Title, Text, Container, Group, Box } from '@mantine/core';
+import { Link } from 'react-router-dom';
+import { RegistrationForm } from '@/features/registration/RegistrationForm';
+import '@/pages/RegistrationPage/RegistrationPage.css';
+
+export default function RegistrationPage() {
+ return (
+
+
+
+ Create Account
+
+
+
+
+
+
+ Already have an account?{' '}
+
+ Log in
+
+
+
+
+
+ );
+}
diff --git a/src/shared/constants/countries.ts b/src/shared/constants/countries.ts
new file mode 100644
index 0000000..2a54e28
--- /dev/null
+++ b/src/shared/constants/countries.ts
@@ -0,0 +1,5 @@
+export const countries = {
+ "FR": "France",
+ "IT": "Italy",
+ "ES": "Spain",
+}
\ No newline at end of file
diff --git a/src/shared/constants/sorting.ts b/src/shared/constants/sorting.ts
new file mode 100644
index 0000000..66a3ec1
--- /dev/null
+++ b/src/shared/constants/sorting.ts
@@ -0,0 +1,10 @@
+export const productSortOptions = [
+ { label: 'Price: Low to High', value: 'price_asc' },
+ { label: 'Price: High to Low', value: 'price_desc' },
+ { label: 'Rating: High to Low', value: 'rating_desc' },
+ { label: 'Rating: Low to High', value: 'rating_asc' },
+ { label: 'Year: Newest First', value: 'year_desc' },
+ { label: 'Year: Oldest First', value: 'year_asc' },
+] as const;
+
+export type ProductSortOption = (typeof productSortOptions)[number]['value'];
diff --git a/src/shared/constants/team.ts b/src/shared/constants/team.ts
new file mode 100644
index 0000000..f04adbf
--- /dev/null
+++ b/src/shared/constants/team.ts
@@ -0,0 +1,50 @@
+import aleksei from '@/assets/Aleksei_11.webp';
+import anna from '@/assets/Anna_9455.webp';
+import vika from '@/assets/Vika_12.webp';
+
+export const team = [
+ {
+ avatar: aleksei,
+ name: 'Aleksei Kalimullin',
+ role: 'Lead Sommelier',
+ description: `I am a civil engineer and a chemist by experience and education. Currently passionate about front-end development and deeply interested in functional programming languages ​​and architecture.`,
+ contributions: [
+ 'Repository set up and project configuration',
+ 'Routing implementaion',
+ 'API client setup',
+ 'Login Page',
+ 'Catalog Page',
+ 'Writing tests for the entire project',
+ ],
+ github: 'https://github.com/maiano',
+ },
+ {
+ avatar: vika,
+ name: 'Victoria Ternovaya',
+ role: 'Wine Educator',
+ description: `I hold a degree in Philology, with professional experience as a news editor and 3D visualizer. Since 2024, I've been studying frontend development.`,
+ contributions: [
+ 'Project design',
+ 'CommerceTools project and API client setup',
+ 'Main Page',
+ 'Catalog Page',
+ 'Product Page',
+ 'Cart Page',
+ '404 Page',
+ ],
+ github: 'https://github.com/blk-thorn',
+ },
+ {
+ avatar: anna,
+ name: 'Anna Smirnova',
+ role: 'Junior Wine Specialist',
+ description: `Passionate about the creative, versatile and dynamic nature of frontend development. Always learning and excited for new challenges.`,
+ contributions: [
+ 'Task board set up and management',
+ 'Registration Page',
+ 'User Profile Page',
+ 'About Us Page',
+ ],
+ github: 'https://github.com/ann-sm',
+ },
+];
diff --git a/src/shared/hooks/custom-use-swr.ts b/src/shared/hooks/custom-use-swr.ts
new file mode 100644
index 0000000..0ef0afd
--- /dev/null
+++ b/src/shared/hooks/custom-use-swr.ts
@@ -0,0 +1,38 @@
+import useSWR, { SWRConfiguration } from 'swr';
+import { ZodError, type ZodSchema } from 'zod';
+import { useAuthStore } from '@/features/auth/auth-state';
+import { apiClientManager } from '@/shared/lib/commercetools/api-client-manager';
+import { debug } from '@/shared/utils/debug-log';
+
+export function useValidatedSWR(
+ key: string | [string, ...unknown[]],
+ fetcherFn: (
+ client: ReturnType,
+ ) => Promise,
+ schema: ZodSchema,
+ options?: SWRConfiguration,
+) {
+ const clientReady = useAuthStore((s) => s.clientReady);
+
+ return useSWR(
+ clientReady ? key : null,
+ async () => {
+ try {
+ debug(`fetching data for key: ${JSON.stringify(key)}`);
+ const client = apiClientManager.get();
+ const data = await fetcherFn(client);
+ return schema.parse(data);
+ } catch (error) {
+ debug('validation or fetch failed:', error);
+ throw error;
+ }
+ },
+ {
+ revalidateOnFocus: false,
+ shouldRetryOnError: (error) => {
+ return !(error instanceof ZodError);
+ },
+ ...options,
+ },
+ );
+}
diff --git a/src/shared/hooks/useCartStore.ts b/src/shared/hooks/useCartStore.ts
new file mode 100644
index 0000000..9873940
--- /dev/null
+++ b/src/shared/hooks/useCartStore.ts
@@ -0,0 +1,500 @@
+import {
+ Cart,
+ ClientResponse,
+ CartDraft,
+ CartUpdate,
+} from '@commercetools/platform-sdk';
+import { ShippingMethod } from '@commercetools/platform-sdk';
+import { create } from 'zustand';
+import { persist } from 'zustand/middleware';
+import { apiClientManager } from '@/shared/lib/commercetools/api-client-manager';
+import { debug } from '@/shared/utils/debug-log';
+
+interface CartState {
+ cart: Cart | null;
+ error: string | null;
+ shippingMethod: ShippingMethod | null;
+ createCart: () => Promise>;
+ fetchCart: () => Promise;
+ addLineItem: (
+ productId: string,
+ variantId?: number,
+ quantity?: number,
+ ) => Promise;
+ removeLineItem: (lineItemId: string) => Promise;
+ changeLineItemQuantity: (
+ lineItemId: string,
+ quantity: number,
+ ) => Promise;
+ clearCart: () => Promise;
+ addDiscount: (code: string) => Promise;
+ removeDiscount: (discountCodeId: string) => Promise;
+ fetchShippingMethod: () => Promise;
+}
+
+const CART_STORAGE_KEY = 'wine-not-cart-id';
+const ANONYMOUS_ID_KEY = 'wine-not-anonymous-id';
+
+export const useCartStore = create()(
+ persist(
+ (set, get) => ({
+ cart: null,
+ error: null,
+ shippingMethod: null,
+
+ createCart: async () => {
+ const client = apiClientManager.get();
+ if (!client) throw new Error('Client is not initialized');
+
+ const authType = apiClientManager.getAuthType();
+
+ if (authType === 'password') {
+ const draft: CartDraft = {
+ currency: 'EUR',
+ country: 'FR',
+ lineItems: [],
+ };
+
+ return client.me().carts().post({ body: draft }).execute();
+ } else {
+ const anonymousId =
+ localStorage.getItem(ANONYMOUS_ID_KEY) || crypto.randomUUID();
+ localStorage.setItem(ANONYMOUS_ID_KEY, anonymousId);
+ debug(`Using anonymous ID: ${anonymousId}`);
+
+ const draft: CartDraft = {
+ currency: 'EUR',
+ country: 'FR',
+ lineItems: [],
+ anonymousId,
+ };
+
+ const response = await client
+ .me()
+ .carts()
+ .post({ body: draft })
+ .execute();
+
+ localStorage.setItem(CART_STORAGE_KEY, response.body.id);
+ localStorage.setItem(ANONYMOUS_ID_KEY, response.body.anonymousId);
+
+ debug(
+ `Anonymous cartID: ${response.body.id}, AnonymousID: ${response.body.anonymousId}`,
+ );
+ return response;
+ }
+ },
+
+ fetchCart: async () => {
+ set({ error: null });
+
+ try {
+ const authType = apiClientManager.getAuthType();
+ const client = apiClientManager.get();
+ if (!client) throw new Error('Client is not initialized');
+
+ if (authType === 'password') {
+ try {
+ const response = await client.me().activeCart().get().execute();
+ set({ cart: response.body });
+ debug(`Active cart loaded: ${response.body.id}`);
+ } catch (error: unknown) {
+ const isNotFound =
+ typeof error === 'object' &&
+ error !== null &&
+ (('statusCode' in error &&
+ (error as { statusCode?: number }).statusCode === 404) ||
+ ('response' in error &&
+ (error as { response?: { status?: number } }).response
+ ?.status === 404));
+
+ if (isNotFound) {
+ debug('Active cart not found');
+ const response = await get().createCart();
+ set({ cart: response.body });
+ debug(`New cart created: ${response.body.id}`);
+ } else {
+ throw error;
+ }
+ }
+ } else {
+ const savedCartId = localStorage.getItem(CART_STORAGE_KEY);
+ const savedAnonymousId = localStorage.getItem(ANONYMOUS_ID_KEY);
+
+ if (savedCartId) {
+ try {
+ debug(`Fetching cart by ID: ${savedCartId}`);
+ const client = apiClientManager.get();
+ if (!client) throw new Error('Client is not initialized');
+
+ const response = await client
+ .me()
+ .carts()
+ .withId({ ID: savedCartId })
+ .get()
+ .execute();
+
+ set({ cart: response.body });
+ debug('Anonymous cart loaded');
+
+ if (
+ response.body.anonymousId &&
+ response.body.anonymousId !== savedAnonymousId
+ ) {
+ localStorage.setItem(
+ ANONYMOUS_ID_KEY,
+ response.body.anonymousId,
+ );
+ }
+ return;
+ } catch (error) {
+ debug('No saved cart, removing ID', error);
+ localStorage.removeItem(CART_STORAGE_KEY);
+ localStorage.removeItem(ANONYMOUS_ID_KEY);
+ }
+ }
+
+ debug('Creating new anonymous cart');
+ const response = await get().createCart();
+ set({ cart: response.body });
+ localStorage.setItem(CART_STORAGE_KEY, response.body.id);
+ if (response.body.anonymousId) {
+ localStorage.setItem(ANONYMOUS_ID_KEY, response.body.anonymousId);
+ }
+ }
+ } catch (error) {
+ let errorMessage = 'Unknown error';
+
+ if (
+ error instanceof Object &&
+ 'message' in error &&
+ typeof error.message === 'string'
+ ) {
+ errorMessage = error.message;
+ }
+
+ debug('Cart fetch error:', errorMessage);
+ set({ error: errorMessage });
+ }
+ },
+
+ addLineItem: async (productId, variantId = 1, quantity = 1) => {
+ set({ error: null });
+ try {
+ const client = apiClientManager.get();
+ if (!client) throw new Error('Client is not initialized');
+
+ const { cart } = get();
+ let currentCart = cart;
+
+ if (!currentCart) throw new Error('No cart');
+
+ const updateActions: CartUpdate = {
+ version: currentCart.version,
+ actions: [
+ {
+ action: 'addLineItem',
+ productId,
+ variantId,
+ quantity,
+ },
+ ],
+ };
+
+ const response = await client
+ .carts()
+ .withId({ ID: currentCart.id })
+ .post({ body: updateActions })
+ .execute();
+
+ set({ cart: response.body });
+ debug(`Added product ${productId} to cart`);
+ } catch (error) {
+ let errorMessage = 'Failed to add product';
+
+ if (
+ error instanceof Object &&
+ 'message' in error &&
+ typeof error.message === 'string'
+ ) {
+ errorMessage = error.message;
+ }
+
+ set({ error: errorMessage });
+ debug('Add to cart error:', errorMessage);
+ throw error;
+ }
+ },
+
+ changeLineItemQuantity: async (lineItemId, quantity) => {
+ set({ error: null });
+ try {
+ const client = apiClientManager.get();
+ if (!client) throw new Error('Client is not initialized');
+
+ const { cart } = get();
+ if (!cart) throw new Error('No cart');
+
+ const updateActions: CartUpdate = {
+ version: cart.version,
+ actions: [
+ {
+ action: 'changeLineItemQuantity',
+ lineItemId,
+ quantity,
+ },
+ ],
+ };
+
+ const response = await client
+ .carts()
+ .withId({ ID: cart.id })
+ .post({ body: updateActions })
+ .execute();
+
+ set({ cart: response.body });
+ console.log(`Changed quantity for ${lineItemId} to ${quantity}`);
+ } catch (error) {
+ let errorMessage = 'Failed to change quantity';
+
+ if (
+ error instanceof Object &&
+ 'message' in error &&
+ typeof error.message === 'string'
+ ) {
+ errorMessage = error.message;
+ }
+
+ set({ error: errorMessage });
+ debug('Change quantity error:', errorMessage);
+ throw error;
+ }
+ },
+ removeLineItem: async (lineItemId) => {
+ set({ error: null });
+ try {
+ const client = apiClientManager.get();
+ if (!client) throw new Error('Client is not initialized');
+
+ const { cart } = get();
+ if (!cart) throw new Error('No cart');
+
+ const updateActions: CartUpdate = {
+ version: cart.version,
+ actions: [
+ {
+ action: 'removeLineItem',
+ lineItemId,
+ },
+ ],
+ };
+
+ const response = await client
+ .carts()
+ .withId({ ID: cart.id })
+ .post({ body: updateActions })
+ .execute();
+
+ set({ cart: response.body });
+ debug(`Removed ${lineItemId}`);
+ } catch (error) {
+ let errorMessage = 'Failed to remove product';
+ if (
+ error instanceof Object &&
+ 'message' in error &&
+ typeof error.message === 'string'
+ ) {
+ errorMessage = error.message;
+ }
+ set({ error: errorMessage });
+ debug('Remove error:', errorMessage);
+ throw error;
+ }
+ },
+
+ clearCart: async () => {
+ set({ error: null });
+ try {
+ const client = apiClientManager.get();
+ if (!client) throw new Error('Client is not initialized');
+
+ const { cart } = get();
+ if (!cart || cart.lineItems.length === 0) {
+ debug('Cart is already empty');
+ return;
+ }
+
+ const updateActions: CartUpdate = {
+ version: cart.version,
+ actions: cart.lineItems.map((item) => ({
+ action: 'removeLineItem',
+ lineItemId: item.id,
+ })),
+ };
+
+ const response = await client
+ .carts()
+ .withId({ ID: cart.id })
+ .post({ body: updateActions })
+ .execute();
+
+ set({ cart: response.body });
+ debug('Cart cleared');
+ } catch (error) {
+ let errorMessage = 'Failed to clear cart';
+ if (
+ error instanceof Object &&
+ 'message' in error &&
+ typeof error.message === 'string'
+ ) {
+ errorMessage = error.message;
+ }
+ set({ error: errorMessage });
+ debug('Clear cart error:', errorMessage);
+ throw error;
+ }
+ },
+
+ addDiscount: async (code: string) => {
+ set({ error: null });
+ try {
+ const client = apiClientManager.get();
+ if (!client) throw new Error('Client not initialized');
+
+ const { cart } = get();
+ if (!cart) throw new Error('No cart');
+
+ const updateActions: CartUpdate = {
+ version: cart.version,
+ actions: [
+ {
+ action: 'addDiscountCode',
+ code,
+ },
+ ],
+ };
+
+ const response = await client
+ .carts()
+ .withId({ ID: cart.id })
+ .post({ body: updateActions })
+ .execute();
+
+ set({ cart: response.body });
+ debug(`Discount added: ${code}`);
+
+ console.log(response.body);
+ } catch (error) {
+ let errorMessage = 'Failed to add discount';
+ if (
+ error instanceof Object &&
+ 'message' in error &&
+ typeof error.message === 'string'
+ ) {
+ errorMessage = error.message;
+ }
+ set({ error: errorMessage });
+ debug('Add discount error:', errorMessage);
+ throw error;
+ }
+ },
+
+ removeDiscount: async (discountCodeId: string) => {
+ set({ error: null });
+ try {
+ const client = apiClientManager.get();
+ if (!client) throw new Error('Client not initialized');
+
+ const { cart } = get();
+ if (!cart) throw new Error('No cart');
+
+ const updateActions: CartUpdate = {
+ version: cart.version,
+ actions: [
+ {
+ action: 'removeDiscountCode',
+ discountCode: {
+ typeId: 'discount-code',
+ id: discountCodeId,
+ },
+ },
+ ],
+ };
+
+ const response = await client
+ .carts()
+ .withId({ ID: cart.id })
+ .post({ body: updateActions })
+ .execute();
+
+ set({ cart: response.body });
+ debug(`Discount removed: ${discountCodeId}`);
+ } catch (error) {
+ let errorMessage = 'Failed to remove discount';
+ if (
+ error instanceof Object &&
+ 'message' in error &&
+ typeof error.message === 'string'
+ ) {
+ errorMessage = error.message;
+ }
+ set({ error: errorMessage });
+ debug('Remove discount error:', errorMessage);
+ throw error;
+ }
+ },
+ fetchShippingMethod: async () => {
+ try {
+ const client = apiClientManager.get();
+ if (!client) throw new Error('Client not initialized');
+
+ const response = await client.shippingMethods().get().execute();
+
+ const firstMethod = response.body.results[0] || null;
+ set({ shippingMethod: firstMethod });
+ debug('Shipping method fetched');
+ } catch (error) {
+ let errorMessage = 'Failed to fetch shipping methods';
+ if (
+ error instanceof Object &&
+ 'message' in error &&
+ typeof error.message === 'string'
+ ) {
+ errorMessage = error.message;
+ }
+ debug('Fetch shipping methods error:', errorMessage);
+ set({ shippingMethod: null });
+ }
+ },
+ }),
+ {
+ name: 'cart-storage',
+ partialize: (state) => ({ cart: state.cart }),
+ },
+ ),
+);
+
+export const getCart = () => useCartStore.getState().fetchCart();
+
+export const addToCart = (
+ productId: string,
+ variantId?: number,
+ quantity?: number,
+) => useCartStore.getState().addLineItem(productId, variantId, quantity);
+
+export const changeQuantity = (lineItemId: string, quantity: number) =>
+ useCartStore.getState().changeLineItemQuantity(lineItemId, quantity);
+
+export const removeFromCart = (lineItemId: string) =>
+ useCartStore.getState().removeLineItem(lineItemId);
+
+export const clearCart = () => useCartStore.getState().clearCart();
+
+export const addDiscount = (code: string) =>
+ useCartStore.getState().addDiscount(code);
+
+export const removeDiscount = (discountCodeId: string) =>
+ useCartStore.getState().removeDiscount(discountCodeId);
+
+export const fetchShippingMethod = () =>
+ useCartStore.getState().fetchShippingMethod();
diff --git a/src/shared/hooks/useDebouncedValue.ts b/src/shared/hooks/useDebouncedValue.ts
new file mode 100644
index 0000000..3dad299
--- /dev/null
+++ b/src/shared/hooks/useDebouncedValue.ts
@@ -0,0 +1,12 @@
+import { useState, useEffect } from 'react';
+
+export function useDebouncedValue(value: T, delay = 300): T {
+ const [debounced, setDebounced] = useState(value);
+
+ useEffect(() => {
+ const timeout = setTimeout(() => setDebounced(value), delay);
+ return () => clearTimeout(timeout);
+ }, [value, delay]);
+
+ return debounced;
+}
diff --git a/src/shared/hooks/useImageHandler.ts b/src/shared/hooks/useImageHandler.ts
new file mode 100644
index 0000000..834cf75
--- /dev/null
+++ b/src/shared/hooks/useImageHandler.ts
@@ -0,0 +1,42 @@
+import { SyntheticEvent, useRef } from 'react';
+import type { ApplyStylesFunction, ImageLoadHandler, CheckImageFunction, UseImageHandler} from '@/types/types.tsx'
+
+export const useImageHandler: () => UseImageHandler = (): UseImageHandler => {
+ const imgRef = useRef(null);
+
+ const applyStyles: ApplyStylesFunction = (
+ img: HTMLImageElement
+ ): void => {
+ if (img.naturalHeight > img.naturalWidth * 1.5) {
+ img.style.objectFit = "contain";
+ if (!img.classList.contains('modal-image')) {
+ img.style.maxHeight = '50vh';
+ }
+ }
+ };
+
+ const handleImageLoad: ImageLoadHandler = (
+ e: SyntheticEvent
+ ): void => {
+ if (e.target instanceof HTMLImageElement) {
+ const img: HTMLImageElement = e.target;
+ applyStyles(img);
+ }
+ };
+
+ const checkImage: CheckImageFunction = (
+ img: HTMLImageElement
+ ): void => {
+ if (img.complete) {
+ applyStyles(img);
+ } else {
+ img.onload = (): void => applyStyles(img);
+ }
+ };
+
+ return {
+ handleImageLoad,
+ imgRef,
+ checkImage
+ };
+};
diff --git a/src/shared/lib/commercetools/api-client-manager.ts b/src/shared/lib/commercetools/api-client-manager.ts
new file mode 100644
index 0000000..dea534b
--- /dev/null
+++ b/src/shared/lib/commercetools/api-client-manager.ts
@@ -0,0 +1,179 @@
+import {
+ ClientResponse,
+ CustomerSignInResult,
+ MyCustomerDraft,
+ MyCustomerSignin,
+} from '@commercetools/platform-sdk';
+import { createAnonymousClient } from '@/shared/lib/commercetools/create-anonymous-client';
+import { createPasswordClient } from '@/shared/lib/commercetools/create-password-client';
+import { createRefreshClient } from '@/shared/lib/commercetools/create-refresh-client';
+import {
+ isEmptyToken,
+ makeTokenCache,
+} from '@/shared/lib/commercetools/token-cache';
+import { debug } from '@/shared/utils/debug-log';
+
+type AnonymousApiRoot = ReturnType;
+type PasswordApiRoot = ReturnType;
+type RefreshApiRoot = ReturnType;
+
+type ApiRoot = AnonymousApiRoot | PasswordApiRoot | RefreshApiRoot;
+
+type AuthType = 'anonymous' | 'password' | 'refresh';
+
+type MyExtendedCustomerSignin = MyCustomerSignin & {
+ anonymousId?: string;
+ activeCartSignInMode?:
+ | 'MergeWithExistingCustomerCart'
+ | 'UseAsNewActiveCustomerCart';
+ updateProductData?: boolean;
+};
+
+export const apiClientManager = (() => {
+ let client: ApiRoot | null = null;
+ let authType: AuthType = 'anonymous';
+
+ const passwordTokenCache = makeTokenCache('wine-not-password-token');
+ const anonymousTokenCache = makeTokenCache('wine-not-anonymous-token');
+
+ const get = (): ApiRoot => {
+ if (!client) {
+ throw new Error('client not initialized');
+ }
+ debug(
+ 'token: ',
+ anonymousTokenCache.get().token,
+ passwordTokenCache.get().token,
+ );
+ return client;
+ };
+
+ const init = async (force = false) => {
+ if (client && !force) {
+ return { client, authType };
+ }
+
+ debug('initializing client');
+
+ if (!force) {
+ const restoredClient = restore();
+ if (restoredClient) {
+ debug('Client restored from cache');
+ client = restoredClient.client;
+ authType = restoredClient.authType;
+ return { client, authType };
+ }
+ }
+ debug('creating new anonymous client');
+ client = createAnonymousClient(true);
+ authType = 'anonymous';
+
+ try {
+ await client
+ .categories()
+ .get({ queryArgs: { limit: 1 } })
+ .execute();
+
+ const token = anonymousTokenCache.get();
+ debug('New anonymous token fetched:', token);
+
+ if (token?.token) {
+ anonymousTokenCache.set(token);
+ }
+ } catch (error) {
+ console.error('Anonymous client init failed:', error);
+ }
+ return { client, authType };
+ };
+
+ const register = (
+ body: MyCustomerDraft,
+ ): Promise> => {
+ const draft = {
+ ...body,
+ anonymousCartSignInMode: 'MergeWithExistingCustomerCart',
+ };
+
+ return get().me().signup().post({ body: draft }).execute();
+ };
+
+ const login = async (
+ credentials: MyCustomerSignin,
+ ): Promise> => {
+ const authClient = createPasswordClient(
+ credentials.email,
+ credentials.password,
+ );
+
+ const body: MyExtendedCustomerSignin = {
+ ...credentials,
+ activeCartSignInMode: 'MergeWithExistingCustomerCart',
+ updateProductData: true,
+ };
+
+ return await authClient
+ .me()
+ .login()
+ .post({ body })
+ .execute()
+ .then((response) => {
+ client = authClient;
+ authType = 'password';
+ const token = passwordTokenCache.get();
+ if (token?.token) {
+ passwordTokenCache.set(token);
+ }
+ return response;
+ });
+ };
+
+ const logout = async () => {
+ debug('Logging out...');
+ passwordTokenCache.clear();
+ anonymousTokenCache.clear();
+
+ debug('Creating new anonymous client after logout...');
+
+ await init(true);
+ };
+
+ const restore = (): { client: ApiRoot; authType: AuthType } | null => {
+ const passwordToken = passwordTokenCache.get();
+ if (passwordToken.token && passwordToken.refreshToken) {
+ try {
+ debug('restore pass: ', passwordToken);
+ return {
+ client: createRefreshClient('wine-not-password-token'),
+ authType: 'password',
+ };
+ } catch {
+ passwordTokenCache.clear();
+ }
+ }
+
+ const anonymousToken = anonymousTokenCache.get();
+ if (!isEmptyToken(anonymousToken) && anonymousToken.refreshToken) {
+ try {
+ debug('restore anonymous refresh: ', anonymousToken);
+ return {
+ client: createRefreshClient('wine-not-anonymous-token'),
+ authType: 'anonymous',
+ };
+ } catch {
+ anonymousTokenCache.clear();
+ }
+ }
+
+ debug('no valid sessions');
+ return null;
+ };
+
+ return {
+ get,
+ init,
+ login,
+ register,
+ logout,
+ getAuthType: () => authType,
+ };
+})();
diff --git a/src/shared/lib/commercetools/create-anonymous-client.ts b/src/shared/lib/commercetools/create-anonymous-client.ts
new file mode 100644
index 0000000..c550faf
--- /dev/null
+++ b/src/shared/lib/commercetools/create-anonymous-client.ts
@@ -0,0 +1,62 @@
+import {
+ ByProjectKeyRequestBuilder,
+ createApiBuilderFromCtpClient,
+} from '@commercetools/platform-sdk';
+import {
+ AnonymousAuthMiddlewareOptions,
+ ClientBuilder,
+} from '@commercetools/sdk-client-v2';
+import { env } from './environment';
+import { httpMiddlewareOptions } from './http-config.ts';
+import { anonymousScopes } from '@/shared/lib/commercetools/scopes.ts';
+import { makeTokenCache } from '@/shared/lib/commercetools/token-cache.ts';
+import { debug } from '@/shared/utils/debug-log.ts';
+
+const projectKey = env.VITE_CTP_PROJECT_KEY;
+
+const anonymousTokenCache = makeTokenCache('wine-not-anonymous-token');
+
+export const createAnonymousClient = (
+ force = false,
+): ByProjectKeyRequestBuilder => {
+ if (force) {
+ anonymousTokenCache.clear();
+ debug('anonymousTokenCache cleared with force');
+ }
+
+ const authOptions: AnonymousAuthMiddlewareOptions = {
+ host: env.VITE_CTP_AUTH_URL,
+ projectKey,
+ credentials: {
+ clientId: env.VITE_CTP_CLIENT_ID,
+ clientSecret: env.VITE_CTP_CLIENT_SECRET,
+ },
+ scopes: anonymousScopes,
+ fetch,
+ tokenCache: {
+ get: () => {
+ const token = anonymousTokenCache.get();
+ debug('token-cache:get', token);
+ return token;
+ },
+ set: (token) => {
+ debug('token-cache:set', token);
+ anonymousTokenCache.set(token);
+ return token;
+ },
+ },
+ };
+
+ const ctpClient = new ClientBuilder()
+ .withProjectKey(projectKey)
+ .withAnonymousSessionFlow(authOptions)
+ .withHttpMiddleware(httpMiddlewareOptions)
+ .withLoggerMiddleware()
+ .build();
+
+ return createApiBuilderFromCtpClient(ctpClient).withProjectKey({
+ projectKey,
+ });
+};
+
+export type AnonymousApiRoot = ReturnType;
diff --git a/src/shared/lib/commercetools/create-password-client.ts b/src/shared/lib/commercetools/create-password-client.ts
new file mode 100644
index 0000000..626f040
--- /dev/null
+++ b/src/shared/lib/commercetools/create-password-client.ts
@@ -0,0 +1,49 @@
+import {
+ ByProjectKeyRequestBuilder,
+ createApiBuilderFromCtpClient,
+} from '@commercetools/platform-sdk';
+import {
+ ClientBuilder,
+ PasswordAuthMiddlewareOptions,
+} from '@commercetools/sdk-client-v2';
+import fetch from 'isomorphic-fetch';
+import { env } from './environment';
+import { httpMiddlewareOptions } from './http-config.ts';
+import { customerPasswordFlowScopes } from './scopes.ts';
+import { makeTokenCache } from '@/shared/lib/commercetools/token-cache.ts';
+
+const projectKey = env.VITE_CTP_PROJECT_KEY;
+
+const buildPasswordFlowOptions = (
+ username: string,
+ password: string,
+): PasswordAuthMiddlewareOptions => ({
+ host: env.VITE_CTP_AUTH_URL,
+ projectKey,
+ credentials: {
+ clientId: env.VITE_CTP_CLIENT_ID,
+ clientSecret: env.VITE_CTP_CLIENT_SECRET,
+ user: { username, password },
+ },
+ scopes: customerPasswordFlowScopes,
+ fetch,
+ tokenCache: makeTokenCache('wine-not-password-token'),
+});
+
+export const createPasswordClient = (
+ username: string,
+ password: string,
+): ByProjectKeyRequestBuilder => {
+ const ctpClient = new ClientBuilder()
+ .withProjectKey(projectKey)
+ .withPasswordFlow(buildPasswordFlowOptions(username, password))
+ .withHttpMiddleware(httpMiddlewareOptions)
+ .withLoggerMiddleware()
+ .build();
+
+ return createApiBuilderFromCtpClient(ctpClient).withProjectKey({
+ projectKey,
+ });
+};
+
+export type PasswordApiRoot = ReturnType;
diff --git a/src/shared/lib/commercetools/create-refresh-client.ts b/src/shared/lib/commercetools/create-refresh-client.ts
new file mode 100644
index 0000000..14740f3
--- /dev/null
+++ b/src/shared/lib/commercetools/create-refresh-client.ts
@@ -0,0 +1,53 @@
+import {
+ ByProjectKeyRequestBuilder,
+ createApiBuilderFromCtpClient,
+} from '@commercetools/platform-sdk';
+import {
+ ClientBuilder,
+ RefreshAuthMiddlewareOptions,
+} from '@commercetools/sdk-client-v2';
+import fetch from 'isomorphic-fetch';
+import { env } from './environment';
+import { httpMiddlewareOptions } from './http-config.ts';
+import {
+ makeTokenCache,
+ TokenKey,
+} from '@/shared/lib/commercetools/token-cache.ts';
+
+const projectKey = env.VITE_CTP_PROJECT_KEY;
+
+export const createRefreshClient = (
+ token: TokenKey,
+): ByProjectKeyRequestBuilder | null => {
+ const tokenCache = makeTokenCache(token);
+ const refreshToken = tokenCache.get()?.refreshToken;
+
+ if (!refreshToken) {
+ return null;
+ }
+
+ const buildRefreshAuthMiddlewareOptions: RefreshAuthMiddlewareOptions = {
+ host: env.VITE_CTP_AUTH_URL,
+ projectKey,
+ credentials: {
+ clientId: env.VITE_CTP_CLIENT_ID,
+ clientSecret: env.VITE_CTP_CLIENT_SECRET,
+ },
+ fetch,
+ refreshToken,
+ tokenCache,
+ };
+
+ const ctpClient = new ClientBuilder()
+ .withProjectKey(projectKey)
+ .withHttpMiddleware(httpMiddlewareOptions)
+ .withRefreshTokenFlow(buildRefreshAuthMiddlewareOptions)
+ .withLoggerMiddleware()
+ .build();
+
+ return createApiBuilderFromCtpClient(ctpClient).withProjectKey({
+ projectKey,
+ });
+};
+
+export type RefreshApiRoot = ReturnType;
diff --git a/src/shared/lib/commercetools/environment.ts b/src/shared/lib/commercetools/environment.ts
new file mode 100644
index 0000000..388ce8e
--- /dev/null
+++ b/src/shared/lib/commercetools/environment.ts
@@ -0,0 +1,11 @@
+import { z } from 'zod';
+
+const envSchema = z.object({
+ VITE_CTP_PROJECT_KEY: z.string().min(1),
+ VITE_CTP_CLIENT_ID: z.string().min(1),
+ VITE_CTP_CLIENT_SECRET: z.string().min(1),
+ VITE_CTP_API_URL: z.string().url(),
+ VITE_CTP_AUTH_URL: z.string().url(),
+});
+
+export const env = envSchema.parse(import.meta.env);
diff --git a/src/shared/lib/commercetools/http-config.ts b/src/shared/lib/commercetools/http-config.ts
new file mode 100644
index 0000000..f71a912
--- /dev/null
+++ b/src/shared/lib/commercetools/http-config.ts
@@ -0,0 +1,7 @@
+import fetch from 'isomorphic-fetch';
+import { env } from './environment.ts';
+
+export const httpMiddlewareOptions = {
+ host: env.VITE_CTP_API_URL,
+ fetch: fetch,
+};
diff --git a/src/shared/lib/commercetools/index.ts b/src/shared/lib/commercetools/index.ts
new file mode 100644
index 0000000..ac0490e
--- /dev/null
+++ b/src/shared/lib/commercetools/index.ts
@@ -0,0 +1 @@
+export { apiClientManager } from '@/shared/lib/commercetools/api-client-manager';
diff --git a/src/shared/lib/commercetools/init-api-client.test.ts b/src/shared/lib/commercetools/init-api-client.test.ts
new file mode 100644
index 0000000..cfb485b
--- /dev/null
+++ b/src/shared/lib/commercetools/init-api-client.test.ts
@@ -0,0 +1,27 @@
+import { describe, it, expect, beforeAll } from 'vitest';
+import { apiClientManager } from './api-client-manager';
+
+describe('initApiClient', () => {
+ beforeAll(async () => {
+ await apiClientManager.init();
+ });
+
+ it('initialize client', () => {
+ const client = apiClientManager.get();
+ expect(client).toBeDefined();
+ });
+
+ it('login customer', async () => {
+ await apiClientManager.login({
+ email: 'test-user-1747652756012@example.com',
+ password: 'Qwerty123!',
+ });
+
+ const client = apiClientManager.get();
+
+ const result = await client.me().get().execute();
+
+ expect(result.statusCode).toBe(200);
+ expect(result.body).toHaveProperty('id');
+ });
+});
diff --git a/src/shared/lib/commercetools/registration-api-client.test.ts b/src/shared/lib/commercetools/registration-api-client.test.ts
new file mode 100644
index 0000000..301c197
--- /dev/null
+++ b/src/shared/lib/commercetools/registration-api-client.test.ts
@@ -0,0 +1,111 @@
+import { describe, it, expect, beforeAll, beforeEach } from 'vitest';
+import { apiClientManager } from './api-client-manager';
+
+const runAllTests = process.env.RUN_ALL_TESTS === 'true';
+const describeIf = runAllTests ? describe : describe.skip;
+
+describeIf('Customer registration via apiClientManager', () => {
+ beforeAll(async () => {
+ apiClientManager.init(true);
+ });
+
+ beforeEach(() => {
+ apiClientManager.init(true);
+ });
+
+ it('registers a customer with address and names', async () => {
+ const email = `test-${Date.now()}@example.com`;
+
+ const customerDraft = {
+ email,
+ password: 'Qwerty123!',
+ firstName: 'John',
+ lastName: 'Doe',
+ addresses: [
+ {
+ country: 'DE',
+ streetName: 'Main Street',
+ streetNumber: '123',
+ postalCode: '10115',
+ city: 'Berlin',
+ },
+ ],
+ defaultShippingAddress: 0,
+ defaultBillingAddress: 0,
+ };
+
+ const result = await apiClientManager.register(customerDraft);
+
+ expect(result.statusCode).toBe(201);
+ const customer = result.body.customer;
+
+ expect(customer).toHaveProperty('id');
+ expect(customer.email).toBe(email);
+ expect(customer.firstName).toBe('John');
+ expect(customer.addresses).toHaveLength(1);
+ expect(customer.defaultShippingAddressId).toBeDefined();
+ expect(customer.defaultBillingAddressId).toBeDefined();
+ });
+
+ it('registers a customer with different shipping and billing addresses', async () => {
+ const email = `test-${Date.now()}@example.com`;
+
+ const customerDraft = {
+ email,
+ password: 'Qwerty123!',
+ firstName: 'John',
+ lastName: 'Doe',
+ addresses: [
+ {
+ country: 'DE',
+ streetName: 'Shipping Street',
+ streetNumber: '1',
+ postalCode: '10115',
+ city: 'Berlin',
+ },
+ {
+ country: 'DE',
+ streetName: 'Billing Avenue',
+ streetNumber: '99',
+ postalCode: '10243',
+ city: 'Munich',
+ },
+ ],
+ defaultShippingAddress: 0,
+ defaultBillingAddress: 1,
+ };
+
+ const result = await apiClientManager.register(customerDraft);
+
+ expect(result.statusCode).toBe(201);
+ const customer = result.body.customer;
+
+ expect(customer.email).toBe(email);
+ expect(customer.addresses).toHaveLength(2);
+ expect(customer.defaultShippingAddressId).not.toBe(
+ customer.defaultBillingAddressId,
+ );
+ });
+
+ it('logs in with newly registered customer', async () => {
+ const email = `test-${Date.now()}@example.com`;
+ const password = 'Qwerty123!';
+
+ const customerDraft = {
+ email,
+ password,
+ firstName: 'Maria',
+ lastName: 'Roth',
+ };
+
+ await apiClientManager.register(customerDraft);
+
+ const loginResult = await apiClientManager.login({
+ email,
+ password,
+ });
+
+ expect(loginResult.statusCode).toBe(200);
+ expect(loginResult.body.customer.email).toBe(email);
+ });
+});
diff --git a/src/shared/lib/commercetools/scopes.ts b/src/shared/lib/commercetools/scopes.ts
new file mode 100644
index 0000000..af79b4b
--- /dev/null
+++ b/src/shared/lib/commercetools/scopes.ts
@@ -0,0 +1,24 @@
+export const anonymousScopes = [
+ 'manage_my_profile:ecom-while-true-wine-not',
+ 'view_published_products:ecom-while-true-wine-not',
+ 'view_categories:ecom-while-true-wine-not',
+ 'create_anonymous_token:ecom-while-true-wine-not',
+ 'manage_customers:ecom-while-true-wine-not',
+ 'manage_my_orders:ecom-while-true-wine-not',
+ 'view_orders:ecom-while-true-wine-not',
+ 'manage_orders:ecom-while-true-wine-not'
+];
+
+export const customerPasswordFlowScopes = [
+ 'manage_my_orders:ecom-while-true-wine-not',
+ 'view_orders:ecom-while-true-wine-not',
+ 'view_published_products:ecom-while-true-wine-not',
+ 'manage_my_quote_requests:ecom-while-true-wine-not',
+ 'manage_my_payments:ecom-while-true-wine-not',
+ 'manage_my_quotes:ecom-while-true-wine-not',
+ 'manage_my_profile:ecom-while-true-wine-not',
+ 'view_categories:ecom-while-true-wine-not',
+ 'manage_my_business_units:ecom-while-true-wine-not',
+ 'manage_my_shopping_lists:ecom-while-true-wine-not',
+ 'manage_orders:ecom-while-true-wine-not'
+];
diff --git a/src/shared/lib/commercetools/token-cache.ts b/src/shared/lib/commercetools/token-cache.ts
new file mode 100644
index 0000000..f19cfa3
--- /dev/null
+++ b/src/shared/lib/commercetools/token-cache.ts
@@ -0,0 +1,91 @@
+import { type TokenCache, type TokenStore } from '@commercetools/sdk-client-v2';
+import { z } from 'zod';
+
+export type TokenKey = 'wine-not-anonymous-token' | 'wine-not-password-token';
+
+const TOKEN_THRESHOLD = 300_000;
+const EMPTY_TOKEN: TokenStore = { token: '', expirationTime: 0 };
+
+const TokenSchema = z.object({
+ token: z.string().min(1),
+ refreshToken: z.string().optional(),
+ expirationTime: z.number().positive(),
+});
+
+const validateToken = (raw: string): TokenStore | null => {
+ try {
+ const parsed = TokenSchema.parse(JSON.parse(raw));
+ return parsed.expirationTime > Date.now() + TOKEN_THRESHOLD ? parsed : null;
+ } catch (error) {
+ console.error('Token validation failed:', error);
+ return null;
+ }
+};
+
+const safeStorage = {
+ get: (key: string): string | null => {
+ try {
+ return localStorage.getItem(key);
+ } catch (error) {
+ console.error('LocalStorage access failed:', error);
+ return null;
+ }
+ },
+ set: (key: string, value: string): void => {
+ try {
+ localStorage.setItem(key, value);
+ } catch (error) {
+ console.error('LocalStorage write failed:', error);
+ }
+ },
+ remove: (key: string): void => {
+ try {
+ localStorage.removeItem(key);
+ } catch (error) {
+ console.error('LocalStorage remove failed:', error);
+ }
+ },
+};
+
+export function makeTokenCache(
+ tokenKey: TokenKey,
+): TokenCache & { clear: () => void } {
+ let current: TokenStore = EMPTY_TOKEN;
+
+ return {
+ get: (): TokenStore => {
+ if (current.token && current.expirationTime > Date.now()) {
+ return current;
+ }
+ const raw = safeStorage.get(tokenKey);
+ if (!raw) {
+ current = EMPTY_TOKEN;
+ return EMPTY_TOKEN;
+ }
+
+ const token = validateToken(raw);
+ if (!token) {
+ current = EMPTY_TOKEN;
+ return EMPTY_TOKEN;
+ }
+
+ current = token;
+ return token;
+ },
+
+ set: (newValue: TokenStore): TokenStore => {
+ const token = TokenSchema.parse(newValue);
+ current = token;
+ safeStorage.set(tokenKey, JSON.stringify(current));
+ return current;
+ },
+
+ clear: (): void => {
+ current = EMPTY_TOKEN;
+ safeStorage.remove(tokenKey);
+ },
+ };
+}
+
+export const isEmptyToken = (token: TokenStore): boolean =>
+ token.token === '' || token.expirationTime <= Date.now() + TOKEN_THRESHOLD;
diff --git "a/src/shared/lib/commercetools/token-\321\201ache.test.ts" "b/src/shared/lib/commercetools/token-\321\201ache.test.ts"
new file mode 100644
index 0000000..20c5f65
--- /dev/null
+++ "b/src/shared/lib/commercetools/token-\321\201ache.test.ts"
@@ -0,0 +1,50 @@
+import type { TokenStore } from '@commercetools/sdk-client-v2';
+import { describe, it, expect, beforeEach, vi } from 'vitest';
+import { makeTokenCache } from '@/shared/lib/commercetools/token-cache';
+
+const mockLocalStorage = {
+ store: {} as Record,
+ getItem: vi.fn((key: string) => mockLocalStorage.store[key] || null),
+ setItem: vi.fn((key: string, value: string) => {
+ mockLocalStorage.store[key] = value;
+ }),
+ removeItem: vi.fn((key: string) => {
+ delete mockLocalStorage.store[key];
+ }),
+ clear: vi.fn(() => {
+ mockLocalStorage.store = {};
+ }),
+};
+
+beforeEach(() => {
+ vi.stubGlobal('localStorage', mockLocalStorage);
+ mockLocalStorage.clear();
+});
+
+describe('makeTokenCache', () => {
+ const tokenKey = 'wine-not-anonymous-token';
+
+ it('set token', () => {
+ const cache = makeTokenCache(tokenKey);
+ const testToken: TokenStore = {
+ token: 'test-token',
+ expirationTime: Date.now() + 10_000,
+ };
+
+ cache.set(testToken);
+ expect(cache.get()).toEqual(testToken);
+ });
+
+ it('clear token', () => {
+ const cache = makeTokenCache(tokenKey);
+ const expiredToken: TokenStore = {
+ token: 'expired',
+ expirationTime: Date.now() - 1000,
+ };
+
+ cache.set(expiredToken);
+ cache.clear();
+ expect(cache.get().token).toBe('');
+ expect(mockLocalStorage.removeItem).toHaveBeenCalled();
+ });
+});
diff --git a/src/shared/schemas/product-card-schema.ts b/src/shared/schemas/product-card-schema.ts
new file mode 100644
index 0000000..7c4cf4b
--- /dev/null
+++ b/src/shared/schemas/product-card-schema.ts
@@ -0,0 +1,24 @@
+import { z } from 'zod';
+
+const ProductCardSchema = z.object({
+ id: z.string(),
+ key: z.string(),
+ name: z.string(),
+ description: z.string().optional(),
+ image: z.string().url(),
+ price: z.number(),
+ discountedPrice: z.number().optional(),
+ currency: z.string(),
+ rating: z.number().min(0).max(5).optional(),
+ country: z.string(),
+ year: z.string(),
+});
+
+export type ProductCard = z.infer;
+
+export const ProductCardsSchema = z.array(ProductCardSchema);
+
+export const ProductCardsResponseSchema = z.object({
+ items: z.array(ProductCardSchema),
+ total: z.number(),
+});
diff --git a/src/shared/schemas/product-details-schema.ts b/src/shared/schemas/product-details-schema.ts
new file mode 100644
index 0000000..f02d888
--- /dev/null
+++ b/src/shared/schemas/product-details-schema.ts
@@ -0,0 +1,24 @@
+import { z } from 'zod';
+
+export const ProductDetailsSchema = z.object({
+ id: z.string(),
+ key: z.string(),
+ name: z.string(),
+ description: z.string().optional(),
+ image: z.array(z.string().url()),
+ // images: z.array(z.string().url()),
+ price: z.number(),
+ discountedPrice: z.number().optional(),
+ currency: z.string(),
+ rating: z.number().min(0).max(5).optional(),
+ country: z.string(),
+ year: z.string(),
+ attributes: z.array(
+ z.object({
+ name: z.string(),
+ value: z.union([z.string(), z.number(), z.boolean()]),
+ }),
+ ),
+});
+
+export type ProductDetails = z.infer;
diff --git a/src/shared/ui/AnimatedOutlet.tsx b/src/shared/ui/AnimatedOutlet.tsx
new file mode 100644
index 0000000..8482ef2
--- /dev/null
+++ b/src/shared/ui/AnimatedOutlet.tsx
@@ -0,0 +1,27 @@
+import { AnimatePresence, motion } from 'framer-motion';
+import { useState } from 'react';
+import { useLocation, Outlet } from 'react-router-dom';
+
+export function AnimatedOutlet() {
+ const location = useLocation();
+ const [displayKey, setDisplayKey] = useState(location.pathname);
+
+ return (
+ {
+ setDisplayKey(location.pathname);
+ }}
+ >
+
+
+
+
+ );
+}
diff --git a/src/shared/ui/CategoryButton.tsx b/src/shared/ui/CategoryButton.tsx
new file mode 100644
index 0000000..ff37321
--- /dev/null
+++ b/src/shared/ui/CategoryButton.tsx
@@ -0,0 +1,53 @@
+import { Button, Box } from '@mantine/core';
+
+export function CategoryButton({
+ label,
+ selected,
+ onToggle,
+}: {
+ label: string;
+ selected: boolean;
+ onToggle: () => void;
+}) {
+ return (
+
+ );
+}
diff --git a/src/shared/ui/CenterLoader.tsx b/src/shared/ui/CenterLoader.tsx
new file mode 100644
index 0000000..4f1321a
--- /dev/null
+++ b/src/shared/ui/CenterLoader.tsx
@@ -0,0 +1,40 @@
+import { Loader, Center, Overlay } from '@mantine/core';
+import { useEffect, useState } from 'react';
+
+interface CenterLoaderProps {
+ size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';
+}
+
+export function CenterLoader({ size = 'md' }: CenterLoaderProps) {
+ const [mounted, setMounted] = useState(false);
+
+ useEffect(() => {
+ setMounted(true);
+ return () => setMounted(false);
+ }, []);
+
+ return (
+ <>
+
+
+
+
+ >
+ );
+}
diff --git a/src/shared/ui/Logo.tsx b/src/shared/ui/Logo.tsx
new file mode 100644
index 0000000..347ecf5
--- /dev/null
+++ b/src/shared/ui/Logo.tsx
@@ -0,0 +1,37 @@
+import { Anchor } from '@mantine/core';
+import { Link } from 'react-router-dom';
+import { ROUTES } from '@/app/routes';
+
+export function Logo() {
+ return (
+
+
+
+ );
+}
diff --git a/src/shared/ui/LogoWithTitle.tsx b/src/shared/ui/LogoWithTitle.tsx
new file mode 100644
index 0000000..59b271e
--- /dev/null
+++ b/src/shared/ui/LogoWithTitle.tsx
@@ -0,0 +1,43 @@
+import { Anchor, useMantineTheme } from '@mantine/core';
+import { Title } from '@mantine/core';
+import { Link } from 'react-router-dom';
+import { ROUTES } from '@/app/routes';
+
+export function LogoWithTitle() {
+ const theme = useMantineTheme();
+ return (
+
+
+
+ Wine not
+
+
+ );
+}
diff --git a/src/shared/utils/api-error-utils.ts b/src/shared/utils/api-error-utils.ts
new file mode 100644
index 0000000..4826044
--- /dev/null
+++ b/src/shared/utils/api-error-utils.ts
@@ -0,0 +1,82 @@
+import { HttpErrorType } from '@commercetools/sdk-client-v2';
+
+export interface CommerceToolsError extends HttpErrorType {
+ body?: {
+ statusCode?: number;
+ message?: string;
+ errors?: Array<{
+ code: string;
+ message: string;
+ detailedErrorMessage?: string;
+ field?: string;
+ value?: unknown;
+ duplicateValue?: unknown;
+ }>;
+ };
+}
+
+export function isCommerceToolsError(
+ error: unknown,
+): error is CommerceToolsError {
+ return (
+ typeof error === 'object' &&
+ error !== null &&
+ 'body' in error &&
+ typeof (error as CommerceToolsError).body === 'object'
+ );
+}
+
+export function getErrorMessage(
+ error: unknown,
+ context: 'login' | 'registration' | 'general' = 'general',
+): string {
+ if (!isCommerceToolsError(error)) {
+ return context === 'login'
+ ? 'Invalid email or password'
+ : 'An unexpected error occurred. Please try again later';
+ }
+
+ const statusCode = error.body?.statusCode;
+ const firstError = error.body?.errors?.[0];
+
+ if (context === 'registration') {
+ switch (firstError?.code) {
+ case 'DuplicateField':
+ return `This ${firstError.field} is already in use. Please use a different ${firstError.field}`;
+
+ case 'InvalidJsonInput':
+ return 'Invalid registration data. Please check your input and try again';
+
+ case 'FieldValueNotFound':
+ return `The ${firstError.field} is invalid. Please check and try again`;
+ }
+ }
+
+ switch (statusCode) {
+ case 400:
+ if (context === 'login') {
+ return 'Invalid email or password';
+ }
+ return (
+ firstError?.message || 'Invalid request data. Please check your input'
+ );
+
+ case 401:
+ return 'Authentication failed. Please check your credentials';
+
+ case 403:
+ return 'Access denied. You do not have permission for this action';
+
+ case 409:
+ return 'Conflict occurred. Please try again';
+
+ case 429:
+ return 'Too many requests. Please wait and try again later';
+
+ default:
+ return (
+ firstError?.message ||
+ 'An unexpected error occurred. Please try again later'
+ );
+ }
+}
diff --git a/src/shared/utils/custom-notifications.ts b/src/shared/utils/custom-notifications.ts
new file mode 100644
index 0000000..8d15b79
--- /dev/null
+++ b/src/shared/utils/custom-notifications.ts
@@ -0,0 +1,29 @@
+import { notifications } from '@mantine/notifications';
+
+type NotificationOptions = {
+ title?: string;
+ message: string;
+ autoClose?: number;
+ withCloseButton?: boolean;
+};
+
+export const notifySuccess = (options: NotificationOptions) => {
+ notifications.show({
+ title: options.title,
+ message: options.message,
+ color: 'green',
+ autoClose: options.autoClose ?? 5000,
+ withCloseButton: options.withCloseButton ?? true,
+ });
+};
+
+export const notifyError = (error: unknown, options: NotificationOptions) => {
+ console.error(error);
+ notifications.show({
+ title: options.title,
+ message: options.message,
+ color: 'red',
+ autoClose: options.autoClose ?? 5000,
+ withCloseButton: options.withCloseButton ?? true,
+ });
+};
diff --git a/src/shared/utils/customer-draft-utils.test.ts b/src/shared/utils/customer-draft-utils.test.ts
new file mode 100644
index 0000000..cf1f0be
--- /dev/null
+++ b/src/shared/utils/customer-draft-utils.test.ts
@@ -0,0 +1,56 @@
+import { describe, test, expect } from 'vitest';
+import { createCustomerDraft } from '@/shared/utils/customer-draft-utils';
+import type { RegistrationFormData } from '@/shared/validation/registration-validation';
+
+const mockData: RegistrationFormData = {
+ email: 'test@example.com',
+ password: 'Password123!',
+ firstName: 'John',
+ lastName: 'Doe',
+ birthDate: '1990-01-01',
+ shippingAddress: {
+ country: 'United States',
+ street: 'Main St',
+ city: 'New York',
+ postcode: '10001',
+ isDefaultAddress: true,
+ },
+ billingAddress: {
+ country: 'Germany',
+ street: 'Berliner Str.',
+ city: 'Berlin',
+ postcode: '10115',
+ isDefaultAddress: false,
+ sameAsShipping: false,
+ },
+};
+
+describe('createCustomerDraft', () => {
+ test('creates draft with single address when sameAddress is true', () => {
+ const draft = createCustomerDraft(mockData, true);
+ expect(draft.addresses).toHaveLength(1);
+ expect(draft.defaultShippingAddress).toBe(0);
+ expect(draft.defaultBillingAddress).toBeUndefined();
+ });
+
+ test('creates draft with two addresses when sameAddress is false', () => {
+ const draft = createCustomerDraft(mockData, false);
+ expect(draft.addresses).toHaveLength(2);
+ expect(draft.addresses?.[1].city).toBe('Berlin');
+ });
+
+ test('sets defaultBillingAddress to 0 if sameAddress and isDefaultAddress are true', () => {
+ const draft = createCustomerDraft(
+ {
+ ...mockData,
+ billingAddress: {
+ ...mockData.billingAddress,
+ isDefaultAddress: true,
+ sameAsShipping: true,
+ },
+ },
+ true,
+ );
+ expect(draft.defaultBillingAddress).toBe(0);
+ });
+});
diff --git a/src/shared/utils/customer-draft-utils.ts b/src/shared/utils/customer-draft-utils.ts
new file mode 100644
index 0000000..9eba622
--- /dev/null
+++ b/src/shared/utils/customer-draft-utils.ts
@@ -0,0 +1,49 @@
+import { MyCustomerDraft } from '@commercetools/platform-sdk';
+import { getCountryCode } from '@/shared/utils/get-country-code';
+import { RegistrationFormData } from '@/shared/validation/registration-validation';
+
+export const createCustomerDraft = (
+ data: RegistrationFormData,
+ sameAddress: boolean,
+): MyCustomerDraft => {
+ const addresses = [
+ {
+ country: getCountryCode(data.shippingAddress.country),
+ streetName: data.shippingAddress.street,
+ postalCode: data.shippingAddress.postcode,
+ city: data.shippingAddress.city,
+ },
+ ...(sameAddress
+ ? []
+ : [
+ {
+ country: getCountryCode(data.billingAddress.country),
+ streetName: data.billingAddress.street,
+ postalCode: data.billingAddress.postcode,
+ city: data.billingAddress.city,
+ },
+ ]),
+ ];
+
+ return {
+ email: data.email,
+ password: data.password,
+ firstName: data.firstName,
+ lastName: data.lastName,
+ dateOfBirth: data.birthDate,
+ addresses,
+ defaultShippingAddress: data.shippingAddress.isDefaultAddress
+ ? 0
+ : undefined,
+ defaultBillingAddress: data.billingAddress.isDefaultAddress
+ ? sameAddress
+ ? 0
+ : 1
+ : undefined,
+ };
+};
+
+export const getAddressIndexes = (sameAddress: boolean) => ({
+ shippingAddresses: [0],
+ billingAddresses: sameAddress ? [0] : [1],
+});
diff --git a/src/shared/utils/debug-log.ts b/src/shared/utils/debug-log.ts
new file mode 100644
index 0000000..ea2a50b
--- /dev/null
+++ b/src/shared/utils/debug-log.ts
@@ -0,0 +1,6 @@
+const isDebugMode = import.meta.env.MODE === 'development';
+
+export const debug = (namespace: string, ...args: unknown[]) => {
+ if (!isDebugMode) return;
+ console.log(`[debug:${namespace}]`, ...args);
+};
diff --git a/src/shared/utils/get-country-code.ts b/src/shared/utils/get-country-code.ts
new file mode 100644
index 0000000..a8e37c7
--- /dev/null
+++ b/src/shared/utils/get-country-code.ts
@@ -0,0 +1,9 @@
+import { countries } from "../constants/countries";
+
+export const getCountryCode = (country: string | undefined) => {
+ if (country) {
+ return Object.keys(countries)[Object.values(countries).indexOf(country)];
+ } else {
+ return '';
+ }
+}
\ No newline at end of file
diff --git a/src/shared/utils/get-user-info.ts b/src/shared/utils/get-user-info.ts
new file mode 100644
index 0000000..e740a3c
--- /dev/null
+++ b/src/shared/utils/get-user-info.ts
@@ -0,0 +1,15 @@
+import { apiClientManager } from "@/shared/lib/commercetools";
+
+export const getUserInfo = async() => {
+ try {
+ const client = apiClientManager.get();
+ if (client) {
+ const data = await client.me().get().execute();
+ if (data) {
+ return data;
+ }
+ }
+ } catch (error) {
+ console.error('getUserInfo failed:', error);
+ }
+}
\ No newline at end of file
diff --git a/src/shared/utils/set-address-actions.ts b/src/shared/utils/set-address-actions.ts
new file mode 100644
index 0000000..a1efa76
--- /dev/null
+++ b/src/shared/utils/set-address-actions.ts
@@ -0,0 +1,45 @@
+import { ClientResponse, Customer, MyCustomerUpdateAction } from "@commercetools/platform-sdk";
+
+type Action = 'setDefaultShippingAddress' | 'addShippingAddressId' | 'removeShippingAddressId' | 'setDefaultShippingAddress' | 'setDefaultBillingAddress' | 'addBillingAddressId' | 'removeBillingAddressId' | 'setDefaultBillingAddress';
+
+export const setAddressActions = (id: string | undefined, currentUser: ClientResponse | undefined, isShipping: boolean, isBilling: boolean, isDefaultShipping: boolean, isDefaultBilling: boolean) => {
+ let actions: MyCustomerUpdateAction[] = [];
+
+ const createAddressAction = (action: Action, addressId: string | undefined): MyCustomerUpdateAction => ({
+ action,
+ addressId
+ });
+
+ if (isShipping) {
+ if (isDefaultShipping && id !== currentUser?.body.defaultShippingAddressId) {
+ actions.push(createAddressAction('setDefaultShippingAddress', id));
+ }
+ if (!currentUser?.body.shippingAddressIds?.includes(id ?? '')) {
+ actions.push(createAddressAction('addShippingAddressId', id));
+ }
+ if (id === currentUser?.body.defaultShippingAddressId && !isDefaultShipping) {
+ actions.push(createAddressAction('setDefaultShippingAddress', undefined));
+ }
+ } else {
+ if (currentUser?.body.shippingAddressIds?.includes(id ?? '')) {
+ actions.push(createAddressAction('removeShippingAddressId', id));
+ }
+ }
+
+ if (isBilling) {
+ if (isDefaultBilling && id !== currentUser?.body.defaultBillingAddressId) {
+ actions.push(createAddressAction('setDefaultBillingAddress', id));
+ }
+ if (!currentUser?.body.billingAddressIds?.includes(id ?? '')) {
+ actions.push(createAddressAction('addBillingAddressId', id));
+ }
+ if (id === currentUser?.body.defaultBillingAddressId && !isDefaultBilling) {
+ actions.push(createAddressAction('setDefaultBillingAddress', undefined));
+ }
+ } else {
+ if (currentUser?.body.billingAddressIds?.includes(id ?? '')) {
+ actions.push(createAddressAction('removeBillingAddressId', id));
+ }
+ }
+ return actions;
+}
diff --git a/src/shared/validation/index.ts b/src/shared/validation/index.ts
new file mode 100644
index 0000000..a279e0a
--- /dev/null
+++ b/src/shared/validation/index.ts
@@ -0,0 +1 @@
+export { loginSchema } from '@/shared/validation/login-validation';
diff --git a/src/shared/validation/login-validation.ts b/src/shared/validation/login-validation.ts
new file mode 100644
index 0000000..619e33a
--- /dev/null
+++ b/src/shared/validation/login-validation.ts
@@ -0,0 +1,31 @@
+import { z } from 'zod';
+
+export const email = z
+ .string()
+ .trim()
+ .min(1, 'Email is required')
+ .email('Invalid email format')
+ .refine(
+ (email) => email.split('@')[1]?.includes('.'),
+ 'Email address must contain a domain name (e.g., example.com)',
+ );
+
+export const password = z
+ .string()
+ .min(8, 'Password must be at least 8 characters long')
+ .regex(/[A-Z]/, 'Password must contain at least one uppercase letter (A-Z)')
+ .regex(/[a-z]/, 'Password must contain at least one lowercase letter (a-z)')
+ .regex(/[0-9]/, 'Password must contain at least one digit (0-9)')
+ .regex(
+ /[!@#$%^&*]/,
+ 'Password must contain at least one special character (e.g., !@#$%^&*)',
+ )
+ .refine((pass) => !/\s/.test(pass), 'Password must not contain any spaces')
+ .refine((pass) => !/[<>]/.test(pass), 'Password must not contain < or >');
+
+export const loginSchema = z.object({
+ email,
+ password,
+});
+
+export type LoginFormData = z.infer;
diff --git a/src/shared/validation/login.schema.test.ts b/src/shared/validation/login.schema.test.ts
new file mode 100644
index 0000000..01cb824
--- /dev/null
+++ b/src/shared/validation/login.schema.test.ts
@@ -0,0 +1,38 @@
+import { describe, expect, test } from 'vitest';
+import { loginSchema } from '@/shared/validation';
+
+describe('Email', () => {
+ test('Rejects invalid email', () => {
+ expect(() =>
+ loginSchema.parse({ email: 'invalid', password: '1BestPassword!' }),
+ ).toThrow('Invalid email format');
+ });
+
+ test('Accepts valid email', () => {
+ expect(() =>
+ loginSchema.parse({
+ email: 'valid@example.com',
+ password: '1BestPassword!',
+ }),
+ ).not.toThrow('Invalid email format');
+ });
+});
+
+describe('Password', () => {
+ test('Accepts valid passwords', () => {
+ ['1BestPassword!', 'Qwerty@!1'].forEach((password) => {
+ expect(() =>
+ loginSchema.parse({ email: 'valid@example.com', password }),
+ ).not.toThrow();
+ });
+ });
+
+ test('Rejects passwords with spaces', () => {
+ expect(() =>
+ loginSchema.parse({
+ email: 'valid@example.com',
+ password: ' 1NotBest Password!',
+ }),
+ ).toThrow('Password must not contain any spaces');
+ });
+});
diff --git a/src/shared/validation/profile-validation.ts b/src/shared/validation/profile-validation.ts
new file mode 100644
index 0000000..d3558b6
--- /dev/null
+++ b/src/shared/validation/profile-validation.ts
@@ -0,0 +1,43 @@
+import { z } from 'zod';
+import { email, password } from './login-validation';
+import { birthDate, city, country, firstName, lastName, postcode, street } from './registration-validation';
+
+export const personalInfoSchema = z.object({
+ firstName,
+ lastName,
+ email,
+ birthDate
+})
+
+export type PersonalInfoFormData = z.infer;
+
+const newPassword = password;
+const confirmNewPassword = password
+
+export const passwordChangeSchema = z.object({
+ password,
+ newPassword,
+ confirmNewPassword,
+})
+.refine((data) => data.newPassword === data.confirmNewPassword, { message: 'Passwords do not match', path: ['confirmNewPassword']})
+.refine((data) => data.newPassword !== data.password, { message: 'New password must be different from current password', path: ['newPassword']});
+
+export type PasswordChangeFormData = z.infer;
+
+const isShippingAddress = z.boolean();
+const isBillingAddress = z.boolean();
+const isDefaultShippingAddress = z.boolean();
+const isDefaultBillingAddress = z.boolean();
+
+export const addressSchema = z.object({
+ country,
+ city,
+ street,
+ postcode,
+ isShippingAddress,
+ isDefaultShippingAddress,
+ isBillingAddress,
+ isDefaultBillingAddress,
+})
+
+export type AddressFormData = z.infer;
\ No newline at end of file
diff --git a/src/shared/validation/registration-validation.ts b/src/shared/validation/registration-validation.ts
new file mode 100644
index 0000000..c3f827a
--- /dev/null
+++ b/src/shared/validation/registration-validation.ts
@@ -0,0 +1,103 @@
+import { z } from 'zod';
+import { email, password } from './login-validation';
+
+export const firstName = z
+ .string()
+ .trim()
+ .min(1, 'First name is required')
+ .refine((val) => !/\d/.test(val), 'First name must not contain any numbers')
+ .refine(
+ (val) => !/[^A-Za-z0-9\u0401\u0451\u0410-\u044f\s-]/gu.test(val),
+ 'First name must not contain any special characters',
+ );
+
+export const lastName = z
+ .string()
+ .trim()
+ .min(1, 'Last name is required')
+ .refine((val) => !/\d/.test(val), 'Last name must not contain any numbers')
+ .refine(
+ (val) => !/[^A-Za-z0-9\u0401\u0451\u0410-\u044f\s'-]/gu.test(val),
+ 'Last name must not contain any special characters',
+ );
+
+export const birthDate = z
+ .string()
+ .min(1, 'Date of birth is required')
+ .refine(
+ (val) =>
+ new Date().getTime() >=
+ new Date(
+ new Date(Date.parse(val)).getFullYear() + 18,
+ new Date(Date.parse(val)).getMonth(),
+ new Date(Date.parse(val)).getDate(),
+ ).getTime(),
+ 'You must be at least 18 years old',
+ )
+ .optional()
+ .refine((val) => val !== undefined, 'Date of birth is required');
+
+export const country = z
+ .string()
+ .min(1, 'Country is required')
+ .optional()
+ .refine((val) => val !== undefined, 'Country is required');
+
+export const city = z
+ .string()
+ .trim()
+ .min(1, 'City is required')
+ .refine((val) => !/\d/.test(val), 'City must not contain any numbers')
+ .refine(
+ (val) => !/[^A-Za-z0-9\u0401\u0451\u0410-\u044f\s-]/gu.test(val),
+ 'City must not contain any special characters',
+ );
+
+export const street = z.string().trim().min(1, 'Street is required');
+
+export const postcode = z
+ .string()
+ .trim()
+ .refine(
+ (val) => !/[a-zA-Z]/.test(val),
+ 'Postcode must not contain any letters',
+ )
+ .refine(
+ (val) => !/[^A-Za-z0-9]/.test(val),
+ 'Postcode must not contain any special characters',
+ )
+ .refine((val) => /^\b\d{5}\b/g.test(val), 'Postcode must contain 5 digits');
+
+export const isDefaultAddress = z
+ .boolean();
+
+const shippingAddress = z.object({
+ country,
+ city,
+ street,
+ postcode,
+ isDefaultAddress,
+});
+
+const sameAsShipping = z.boolean();
+
+const billingAddress = z.object({
+ country,
+ city,
+ street,
+ postcode,
+ isDefaultAddress,
+ sameAsShipping,
+});
+
+export const registrationSchema = z.object({
+ email,
+ password,
+ firstName,
+ lastName,
+ birthDate,
+ shippingAddress,
+ billingAddress,
+});
+
+export type RegistrationFormData = z.infer;
\ No newline at end of file
diff --git a/src/test/button-for-test.test.tsx b/src/test/button-for-test.test.tsx
new file mode 100644
index 0000000..e3ab2d4
--- /dev/null
+++ b/src/test/button-for-test.test.tsx
@@ -0,0 +1,9 @@
+import { Button } from '@mantine/core';
+import { screen } from '@testing-library/react';
+import { it, expect } from 'vitest';
+import { customRender } from '@/test';
+
+it('renders hello button', () => {
+ customRender();
+ expect(screen.getByText('Hello')).toBeInTheDocument();
+});
diff --git a/src/test/index.ts b/src/test/index.ts
new file mode 100644
index 0000000..de661d2
--- /dev/null
+++ b/src/test/index.ts
@@ -0,0 +1 @@
+export { customRender } from '@/test/test-utils';
diff --git a/src/test/test-utils.tsx b/src/test/test-utils.tsx
new file mode 100644
index 0000000..b9fdc72
--- /dev/null
+++ b/src/test/test-utils.tsx
@@ -0,0 +1,11 @@
+import { MantineProvider } from '@mantine/core';
+import { render as testingLibraryRender } from '@testing-library/react';
+import { theme } from '@/app/theme';
+
+export function customRender(ui: React.ReactNode) {
+ return testingLibraryRender(<>{ui}>, {
+ wrapper: ({ children }: { children: React.ReactNode }) => (
+ {children}
+ ),
+ });
+}
diff --git a/src/types/types.tsx b/src/types/types.tsx
new file mode 100644
index 0000000..e5179bd
--- /dev/null
+++ b/src/types/types.tsx
@@ -0,0 +1,226 @@
+import { MutableRefObject, ReactElement, SyntheticEvent } from 'react';
+import { password } from '@/shared/validation/login-validation.ts';
+import { string } from 'zod';
+
+export interface Feature {
+ title: string;
+ description: string;
+ icon: ReactElement;
+}
+
+export type Wine = {
+ id: number;
+ title: string;
+ price: number;
+ rating: number;
+ description: string;
+ year: string;
+ discountedPrice?: number;
+ attributes: WineAttribute[];
+ image: string[];
+ name?: string;
+};
+
+export interface WineCardProps {
+ wine: Wine;
+}
+
+export interface FeatureCardProps {
+ feature: Feature;
+}
+
+export type WineAttribute = {
+ name: string;
+ value: string;
+};
+
+export type ApplyStylesFunction = (img: HTMLImageElement) => void;
+
+export type ImageLoadHandler = (
+ e: SyntheticEvent,
+) => void;
+
+export type CheckImageFunction = (img: HTMLImageElement) => void;
+
+export interface UseImageHandler {
+ handleImageLoad: ImageLoadHandler;
+ imgRef: MutableRefObject;
+ checkImage: CheckImageFunction;
+}
+
+export const wines: Wine[] = [
+ {
+ id: 1,
+ title: 'Estate Pinot Noir',
+ price: 140,
+ discountedPrice: 120,
+ rating: 4.8,
+ description: 'Elegant red wine with cherry and earthy tones',
+ year: '2015',
+ attributes: [
+ { name: 'Year', value: '2015' },
+ { name: 'Country', value: 'France' },
+ { name: 'Rating', value: '4.8' },
+ ],
+ image: [
+ '../src/assets/Montrachet Grand Cru 2010-2.jpg',
+ '../src/assets/Ellen Lane Estate Chardonnay 2015-1.jpg',
+ '../src/assets/Corton-Charlemagne Grand Cru N.V-2..jpg',
+ 'https://images.vivino.com/thumbs/G3MU5UwBQ1eCX5A6CiPivg_pb_x600.png',
+ ],
+ },
+ {
+ id: 2,
+ title: 'Sparkling Delight',
+ price: 80,
+ discountedPrice: 60,
+ rating: 4.5,
+ description: 'Festive sparkling wine with fine persistent bubbles',
+ year: '2024',
+ attributes: [
+ { name: 'Year', value: '2024' },
+ { name: 'Country', value: 'Italy' },
+ { name: 'Rating', value: '4.5' },
+ ],
+ image: [
+ 'https://cdn.usegalileo.ai/sdxl10/59a49d75-b7ce-48f0-96d7-d620aefc4e49.png',
+ 'https://cdn.usegalileo.ai/sdxl10/544838f2-4393-4780-ab1e-7bbef36024f9.png',
+ 'https://cdn.usegalileo.ai/sdxl10/b25779ab-c1bf-42c0-8245-bc5f7d576365.png',
+ 'https://cdn.usegalileo.ai/sdxl10/0eea6aee-9921-49ac-bbaa-7def81318f98.png',
+ ],
+ },
+ {
+ id: 3,
+ title: 'Coastal Breeze Sauvignon',
+ price: 200,
+ discountedPrice: 160,
+ rating: 4.7,
+ description: 'Refreshing white wine with tropical fruit accents',
+ year: '2017',
+ attributes: [
+ { name: 'Year', value: '2017' },
+ { name: 'Country', value: 'New Zealand' },
+ { name: 'Rating', value: '4.7' },
+ ],
+ image: [
+ 'https://cdn.usegalileo.ai/sdxl10/b25779ab-c1bf-42c0-8245-bc5f7d576365.png',
+ 'https://cdn.usegalileo.ai/sdxl10/544838f2-4393-4780-ab1e-7bbef36024f9.png',
+ 'https://cdn.usegalileo.ai/sdxl10/59a49d75-b7ce-48f0-96d7-d620aefc4e49.png',
+ 'https://cdn.usegalileo.ai/sdxl10/0eea6aee-9921-49ac-bbaa-7def81318f98.png',
+ ],
+ },
+ {
+ id: 4,
+ title: 'Hillside Blend',
+ price: 100,
+ rating: 5,
+ description: 'Complex blend with blackcurrant and spice flavors',
+ year: '2009',
+ attributes: [
+ { name: 'Year', value: '2009' },
+ { name: 'Country', value: 'Spain' },
+ { name: 'Rating', value: '5' },
+ ],
+ image: [
+ 'https://cdn.usegalileo.ai/sdxl10/0eea6aee-9921-49ac-bbaa-7def81318f98.png',
+ 'https://cdn.usegalileo.ai/sdxl10/544838f2-4393-4780-ab1e-7bbef36024f9.png',
+ 'https://cdn.usegalileo.ai/sdxl10/59a49d75-b7ce-48f0-96d7-d620aefc4e49.png',
+ 'https://cdn.usegalileo.ai/sdxl10/b25779ab-c1bf-42c0-8245-bc5f7d576365.png',
+ ],
+ },
+ {
+ id: 5,
+ title: 'Sunset Rosé',
+ price: 150,
+ rating: 3.9,
+ description: 'Fruity rosé with strawberry undertones',
+ year: '2022',
+ attributes: [
+ { name: 'Year', value: '2022' },
+ { name: 'Country', value: 'France' },
+ { name: 'Rating', value: '3.9' },
+ ],
+ image: [
+ 'https://cdn.usegalileo.ai/sdxl10/c6ab2f06-0ec1-4d34-bd49-6520fdd63180.png',
+ 'https://cdn.usegalileo.ai/sdxl10/d90f77b3-fdd9-4c18-aac8-5a54b27fe7de.png',
+ 'https://cdn.usegalileo.ai/sdxl10/0f7256d8-8e72-4104-b428-cea3b42e76d9.png',
+ 'https://cdn.usegalileo.ai/sdxl10/9204a299-2794-4f6b-af2a-2fa313afab9c.png',
+ ],
+ },
+ {
+ id: 6,
+ title: 'Valley White',
+ price: 60,
+ rating: 4.2,
+ description: 'Crisp white wine with citrus notes',
+ year: '2007',
+ attributes: [
+ { name: 'Year', value: '2007' },
+ { name: 'Country', value: 'Germany' },
+ { name: 'Rating', value: '4.2' },
+ ],
+ image: [
+ 'https://cdn.usegalileo.ai/sdxl10/d90f77b3-fdd9-4c18-aac8-5a54b27fe7de.png',
+ 'https://cdn.usegalileo.ai/sdxl10/c6ab2f06-0ec1-4d34-bd49-6520fdd63180.png',
+ 'https://cdn.usegalileo.ai/sdxl10/0f7256d8-8e72-4104-b428-cea3b42e76d9.png',
+ 'https://cdn.usegalileo.ai/sdxl10/9204a299-2794-4f6b-af2a-2fa313afab9c.png',
+ ],
+ },
+ {
+ id: 7,
+ title: 'Vineyard Reserve',
+ price: 299,
+ discountedPrice: 239,
+ rating: 4.4,
+ description: 'Aged oak barrel red wine',
+ year: '2000',
+ attributes: [
+ { name: 'Year', value: '2000' },
+ { name: 'Country', value: 'Italy' },
+ { name: 'Rating', value: '4.4' },
+ ],
+ image: [
+ 'https://cdn.usegalileo.ai/sdxl10/0f7256d8-8e72-4104-b428-cea3b42e76d9.png',
+ 'https://cdn.usegalileo.ai/sdxl10/c6ab2f06-0ec1-4d34-bd49-6520fdd63180.png',
+ 'https://cdn.usegalileo.ai/sdxl10/d90f77b3-fdd9-4c18-aac8-5a54b27fe7de.png',
+ 'https://cdn.usegalileo.ai/sdxl10/9204a299-2794-4f6b-af2a-2fa313afab9c.png',
+ ],
+ },
+ {
+ id: 8,
+ title: 'Chateau Rouge',
+ price: 120,
+ rating: 5,
+ description: 'Rich red wine with dark berry aromas',
+ year: '2010',
+ attributes: [
+ { name: 'Year', value: '2010' },
+ { name: 'Country', value: 'France' },
+ { name: 'Rating', value: '5' },
+ ],
+ image: [
+ 'https://cdn.usegalileo.ai/sdxl10/9204a299-2794-4f6b-af2a-2fa313afab9c.png',
+ 'https://cdn.usegalileo.ai/sdxl10/c6ab2f06-0ec1-4d34-bd49-6520fdd63180.png',
+ 'https://cdn.usegalileo.ai/sdxl10/d90f77b3-fdd9-4c18-aac8-5a54b27fe7de.png',
+ 'https://cdn.usegalileo.ai/sdxl10/0f7256d8-8e72-4104-b428-cea3b42e76d9.png',
+ ],
+ },
+];
+
+export interface ModalEmbla {
+ scrollTo: (index: number) => void;
+ reInit: () => void;
+}
+
+export interface TeamMember {
+ avatar: string;
+ name: string;
+ role: string;
+ description: string;
+ contributions: string[];
+ github: string,
+}
+
+export interface TeamMemberCardProps {
+ member: TeamMember;
+}
\ No newline at end of file
diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts
new file mode 100644
index 0000000..11f02fe
--- /dev/null
+++ b/src/vite-env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/tsconfig.app.json b/tsconfig.app.json
new file mode 100644
index 0000000..3c5ccce
--- /dev/null
+++ b/tsconfig.app.json
@@ -0,0 +1,31 @@
+{
+ "compilerOptions": {
+ "target": "ES2020",
+ "useDefineForClassFields": true,
+ "lib": ["ES2020", "DOM", "DOM.Iterable"],
+ "module": "ESNext",
+ "skipLibCheck": true,
+ "types": ["@testing-library/jest-dom"],
+
+ /* Bundler mode */
+ "moduleResolution": "bundler",
+ "allowImportingTsExtensions": true,
+ "isolatedModules": true,
+ "moduleDetection": "force",
+ "noEmit": true,
+ "jsx": "react-jsx",
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["./src/*"]
+ },
+
+ /* Linting */
+ "strict": true,
+ "noImplicitAny": true,
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "noFallthroughCasesInSwitch": true,
+ "noUncheckedSideEffectImports": true
+ },
+ "include": ["src"]
+}
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 0000000..1ffef60
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,7 @@
+{
+ "files": [],
+ "references": [
+ { "path": "./tsconfig.app.json" },
+ { "path": "./tsconfig.node.json" }
+ ]
+}
diff --git a/tsconfig.node.json b/tsconfig.node.json
new file mode 100644
index 0000000..342b156
--- /dev/null
+++ b/tsconfig.node.json
@@ -0,0 +1,24 @@
+{
+ "compilerOptions": {
+ "target": "ES2022",
+ "lib": ["ES2023"],
+ "module": "ESNext",
+ "skipLibCheck": true,
+ "types": ["@testing-library/jest-dom"],
+
+ /* Bundler mode */
+ "moduleResolution": "bundler",
+ "allowImportingTsExtensions": true,
+ "isolatedModules": true,
+ "moduleDetection": "force",
+ "noEmit": true,
+
+ /* Linting */
+ "strict": true,
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "noFallthroughCasesInSwitch": true,
+ "noUncheckedSideEffectImports": true
+ },
+ "include": ["vite.config.ts"]
+}
diff --git a/vite.config.ts b/vite.config.ts
new file mode 100644
index 0000000..7b2ced9
--- /dev/null
+++ b/vite.config.ts
@@ -0,0 +1,53 @@
+///
+import { defineConfig } from 'vite';
+import react from '@vitejs/plugin-react';
+import path from 'path';
+
+// https://vite.dev/config/
+export default defineConfig({
+ base: './',
+ build: {
+ outDir: 'dist',
+ },
+ plugins: [react()],
+ resolve: {
+ alias: {
+ '@': path.resolve(__dirname, './src'),
+ },
+ },
+ test: {
+ coverage: {
+ all: false,
+ exclude: [
+ 'src/test/**',
+ '**/types/**',
+ '**/*.d.ts',
+ 'src/**/index.ts',
+ 'src/main.tsx',
+ ],
+ extension: ['.ts', '.tsx'],
+ include: ['src/**/*'],
+ provider: 'v8',
+ reporter: ['text', 'json', 'html'],
+ thresholds: {
+ lines: 80,
+ functions: 70,
+ branches: 60,
+ },
+ },
+ typecheck: {
+ enabled: true,
+ include: ['**/*.test-d.ts'],
+ },
+ css: {
+ modules: { classNameStrategy: 'non-scoped' },
+ },
+ exclude: ['**/node_modules/**', '**/e2e/**'],
+ include: ['**/*.{test,spec}.{ts,tsx}'],
+ environment: 'jsdom',
+ globals: true,
+ maxConcurrency: 4,
+ setupFiles: ['./vitest.setup.mjs'],
+ cache: { dir: './node_modules/.vite/.vitest-cache' },
+ },
+});
diff --git a/vitest.setup.mjs b/vitest.setup.mjs
new file mode 100644
index 0000000..ac096df
--- /dev/null
+++ b/vitest.setup.mjs
@@ -0,0 +1,28 @@
+import '@testing-library/jest-dom/vitest';
+import { vi } from 'vitest';
+
+const { getComputedStyle } = window;
+window.getComputedStyle = (elt) => getComputedStyle(elt);
+window.HTMLElement.prototype.scrollIntoView = () => {};
+
+Object.defineProperty(window, 'matchMedia', {
+ writable: true,
+ value: vi.fn().mockImplementation((query) => ({
+ matches: false,
+ media: query,
+ onchange: null,
+ addListener: vi.fn(),
+ removeListener: vi.fn(),
+ addEventListener: vi.fn(),
+ removeEventListener: vi.fn(),
+ dispatchEvent: vi.fn(),
+ })),
+});
+
+class ResizeObserver {
+ observe() {}
+ unobserve() {}
+ disconnect() {}
+}
+
+window.ResizeObserver = ResizeObserver;