diff --git a/.github/ISSUE_TEMPLATE/bug-report-template.md b/.github/ISSUE_TEMPLATE/bug-report-template.md
new file mode 100644
index 0000000..379b238
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug-report-template.md
@@ -0,0 +1,32 @@
+---
+name: ๐ Bug Report template
+about: ํ๋ก์ ํธ์์ ๋ฐ์ํ ๋ฒ๊ทธ์ ๋ํด์ ์์ฑํฉ๋๋ค.
+title: "[FIX]"
+labels: ""
+assignees: ""
+---
+
+## ๐ Bug Description
+
+
+
+## โ
Expected Behavior
+
+
+
+## ๐ Reproduce
+
+
+
+## ๐ผ๏ธ Screenshots
+
+
+
+## ๐งฉ Additional Context
+
+
diff --git a/.github/ISSUE_TEMPLATE/issue-template.md b/.github/ISSUE_TEMPLATE/issue-template.md
new file mode 100644
index 0000000..73d3821
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/issue-template.md
@@ -0,0 +1,18 @@
+---
+name: ๐ค Issue template
+about: ๊ฐ๋ฐํด์ผ ํ๋ ๊ธฐ๋ฅ์ ๋ํ์ฌ ์์ฑํฉ๋๋ค.
+title: "[DEV]"
+labels: ""
+assignees: ""
+---
+
+## Summary
+
+
+
+## To-do
+
+
+
+- []
+- []
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 0000000..bb4e6fb
--- /dev/null
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,15 @@
+## ๐ ๊ด๋ จ ์ด์
+
+
+
+## โจ ์์ฝ
+
+
+
+## ๐ ์์
๋ด์ฉ
+
+
+
+## ๐ ๋ ํผ๋ฐ์ค (๋๋ ์๋ก ์๊ฒ ๋ ๋ด์ฉ) ํน์ ๊ถ๊ธํ ์
+
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 0000000..d72d68c
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,31 @@
+name: React CI/CD
+
+on:
+ pull_request:
+ branches: [main, develop] # ์คํ ์์
+
+jobs:
+ build-and-test:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v4
+
+ - name: Setup Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version: 20
+ cache: 'npm' # ์บ์ฑ ์ถ๊ฐ: ๋น๋ ์๋ ํฅ์
+ cache-dependency-path: './Mine/package-lock.json'
+
+ - name: Install dependencies
+ run: npm ci
+ working-directory: ./Mine
+
+ - name: Lint check
+ run: npm run lint --if-present
+ working-directory: ./Mine
+
+ - name: Build project
+ run: npm run build
+ working-directory: ./Mine
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..2653ec2
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,30 @@
+.env
+.env*
+
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+lerna-debug.log*
+
+node_modules
+dist
+dist-ssr
+*.local
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+.DS_Store
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+.vercel
+.vite/
diff --git a/.prettierignore b/.prettierignore
new file mode 100644
index 0000000..c50753c
--- /dev/null
+++ b/.prettierignore
@@ -0,0 +1,2 @@
+*.json
+pnpm-lock.yaml
\ No newline at end of file
diff --git a/.prettierrc b/.prettierrc
new file mode 100644
index 0000000..f771fd8
--- /dev/null
+++ b/.prettierrc
@@ -0,0 +1,8 @@
+{
+ "endOfLine": "lf",
+ "trailingComma": "es5",
+ "tabWidth": 4,
+ "semi": false,
+ "singleQuote": true,
+ "printWidth": 120
+}
diff --git a/Mine/README.md b/Mine/README.md
new file mode 100644
index 0000000..4dcad1f
--- /dev/null
+++ b/Mine/README.md
@@ -0,0 +1,73 @@
+# React + TypeScript + Vite
+
+This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
+
+Currently, two official plugins are available:
+
+- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) (or [oxc](https://oxc.rs) when used in [rolldown-vite](https://vite.dev/guide/rolldown)) for Fast Refresh
+- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
+
+## React Compiler
+
+The React Compiler is currently not compatible with SWC. See [this issue](https://github.com/vitejs/vite-plugin-react/issues/428) for tracking the progress.
+
+## Expanding the ESLint configuration
+
+If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules:
+
+```js
+export default defineConfig([
+ globalIgnores(['dist']),
+ {
+ files: ['**/*.{ts,tsx}'],
+ extends: [
+ // Other configs...
+
+ // Remove tseslint.configs.recommended and replace with this
+ tseslint.configs.recommendedTypeChecked,
+ // Alternatively, use this for stricter rules
+ tseslint.configs.strictTypeChecked,
+ // Optionally, add this for stylistic rules
+ tseslint.configs.stylisticTypeChecked,
+
+ // Other configs...
+ ],
+ languageOptions: {
+ parserOptions: {
+ project: ['./tsconfig.node.json', './tsconfig.app.json'],
+ tsconfigRootDir: import.meta.dirname,
+ },
+ // other options...
+ },
+ },
+])
+```
+
+You can also install [eslint-plugin-react-x](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom) for React-specific lint rules:
+
+```js
+// eslint.config.js
+import reactX from 'eslint-plugin-react-x'
+import reactDom from 'eslint-plugin-react-dom'
+
+export default defineConfig([
+ globalIgnores(['dist']),
+ {
+ files: ['**/*.{ts,tsx}'],
+ extends: [
+ // Other configs...
+ // Enable lint rules for React
+ reactX.configs['recommended-typescript'],
+ // Enable lint rules for React DOM
+ reactDom.configs.recommended,
+ ],
+ languageOptions: {
+ parserOptions: {
+ project: ['./tsconfig.node.json', './tsconfig.app.json'],
+ tsconfigRootDir: import.meta.dirname,
+ },
+ // other options...
+ },
+ },
+])
+```
diff --git a/Mine/eslint.config.js b/Mine/eslint.config.js
new file mode 100644
index 0000000..96401d5
--- /dev/null
+++ b/Mine/eslint.config.js
@@ -0,0 +1,26 @@
+import js from '@eslint/js'
+import globals from 'globals'
+import reactHooks from 'eslint-plugin-react-hooks'
+import reactRefresh from 'eslint-plugin-react-refresh'
+import tseslint from 'typescript-eslint'
+
+export default tseslint.config(
+ { ignores: ['dist', '.vite//**'] },
+ {
+ extends: [js.configs.recommended, ...tseslint.configs.recommended],
+ files: ['**/*.{ts,tsx}'],
+ languageOptions: {
+ ecmaVersion: 2020,
+ globals: globals.browser,
+ },
+ // ์๋ฌ์ ํต์ฌ: plugins๋ฅผ ๊ฐ์ฒด๋ก ์ ์ํ๊ณ , ๊ท์น(rules)์ ์ง์ ์ฃผ์
ํด์ผ ํฉ๋๋ค.
+ plugins: {
+ 'react-hooks': reactHooks,
+ 'react-refresh': reactRefresh,
+ },
+ rules: {
+ ...reactHooks.configs.recommended.rules,
+ 'react-refresh/only-export-components': ['warn', { allowConstantExport: true }],
+ },
+ }
+)
diff --git a/Mine/index.html b/Mine/index.html
new file mode 100644
index 0000000..c92fe3c
--- /dev/null
+++ b/Mine/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ mine
+
+
+
+
+
+
diff --git a/Mine/package-lock.json b/Mine/package-lock.json
new file mode 100644
index 0000000..b54e6ca
--- /dev/null
+++ b/Mine/package-lock.json
@@ -0,0 +1,6169 @@
+{
+ "name": "mine",
+ "version": "0.0.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "mine",
+ "version": "0.0.0",
+ "dependencies": {
+ "@tailwindcss/vite": "^4.1.17",
+ "@tanstack/react-query": "^5.90.19",
+ "axios": "^1.13.2",
+ "html-react-parser": "^5.2.16",
+ "react": "^18.2.0",
+ "react-dom": "^18.2.0",
+ "react-router-dom": "^6.30.2",
+ "tailwindcss": "^4.1.17",
+ "zustand": "^5.0.10"
+ },
+ "devDependencies": {
+ "@eslint/js": "^9.39.1",
+ "@types/node": "^24.10.0",
+ "@types/react": "^18.3.27",
+ "@types/react-dom": "^18.3.7",
+ "@vitejs/plugin-react-swc": "^4.2.1",
+ "eslint": "^9.39.1",
+ "eslint-plugin-jsx-a11y": "^6.10.2",
+ "eslint-plugin-react-hooks": "^7.0.1",
+ "eslint-plugin-react-refresh": "^0.4.24",
+ "globals": "^16.5.0",
+ "prettier": "^3.6.2",
+ "typescript": "~5.9.3",
+ "typescript-eslint": "^8.46.3",
+ "vite": "^7.2.2",
+ "vite-plugin-svgr": "^4.5.0"
+ }
+ },
+ "node_modules/@babel/code-frame": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz",
+ "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.27.1",
+ "js-tokens": "^4.0.0",
+ "picocolors": "^1.1.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/compat-data": {
+ "version": "7.28.5",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.5.tgz",
+ "integrity": "sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/core": {
+ "version": "7.28.5",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.5.tgz",
+ "integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.27.1",
+ "@babel/generator": "^7.28.5",
+ "@babel/helper-compilation-targets": "^7.27.2",
+ "@babel/helper-module-transforms": "^7.28.3",
+ "@babel/helpers": "^7.28.4",
+ "@babel/parser": "^7.28.5",
+ "@babel/template": "^7.27.2",
+ "@babel/traverse": "^7.28.5",
+ "@babel/types": "^7.28.5",
+ "@jridgewell/remapping": "^2.3.5",
+ "convert-source-map": "^2.0.0",
+ "debug": "^4.1.0",
+ "gensync": "^1.0.0-beta.2",
+ "json5": "^2.2.3",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/babel"
+ }
+ },
+ "node_modules/@babel/generator": {
+ "version": "7.28.5",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.5.tgz",
+ "integrity": "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/parser": "^7.28.5",
+ "@babel/types": "^7.28.5",
+ "@jridgewell/gen-mapping": "^0.3.12",
+ "@jridgewell/trace-mapping": "^0.3.28",
+ "jsesc": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-compilation-targets": {
+ "version": "7.27.2",
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz",
+ "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/compat-data": "^7.27.2",
+ "@babel/helper-validator-option": "^7.27.1",
+ "browserslist": "^4.24.0",
+ "lru-cache": "^5.1.1",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-globals": {
+ "version": "7.28.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz",
+ "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-imports": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz",
+ "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==",
+ "dev": true,
+ "dependencies": {
+ "@babel/traverse": "^7.27.1",
+ "@babel/types": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-transforms": {
+ "version": "7.28.3",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz",
+ "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-module-imports": "^7.27.1",
+ "@babel/helper-validator-identifier": "^7.27.1",
+ "@babel/traverse": "^7.28.3"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-string-parser": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
+ "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-identifier": {
+ "version": "7.28.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz",
+ "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-option": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz",
+ "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helpers": {
+ "version": "7.28.4",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz",
+ "integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==",
+ "dev": true,
+ "dependencies": {
+ "@babel/template": "^7.27.2",
+ "@babel/types": "^7.28.4"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/parser": {
+ "version": "7.28.5",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz",
+ "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.28.5"
+ },
+ "bin": {
+ "parser": "bin/babel-parser.js"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/template": {
+ "version": "7.27.2",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz",
+ "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.27.1",
+ "@babel/parser": "^7.27.2",
+ "@babel/types": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/traverse": {
+ "version": "7.28.5",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.5.tgz",
+ "integrity": "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.27.1",
+ "@babel/generator": "^7.28.5",
+ "@babel/helper-globals": "^7.28.0",
+ "@babel/parser": "^7.28.5",
+ "@babel/template": "^7.27.2",
+ "@babel/types": "^7.28.5",
+ "debug": "^4.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/types": {
+ "version": "7.28.5",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz",
+ "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-string-parser": "^7.27.1",
+ "@babel/helper-validator-identifier": "^7.28.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@esbuild/aix-ppc64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.2.tgz",
+ "integrity": "sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==",
+ "cpu": [
+ "ppc64"
+ ],
+ "optional": true,
+ "os": [
+ "aix"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-arm": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.2.tgz",
+ "integrity": "sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==",
+ "cpu": [
+ "arm"
+ ],
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-arm64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.2.tgz",
+ "integrity": "sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-x64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.2.tgz",
+ "integrity": "sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/darwin-arm64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.2.tgz",
+ "integrity": "sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/darwin-x64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.2.tgz",
+ "integrity": "sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.2.tgz",
+ "integrity": "sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/freebsd-x64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.2.tgz",
+ "integrity": "sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-arm": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.2.tgz",
+ "integrity": "sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==",
+ "cpu": [
+ "arm"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-arm64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.2.tgz",
+ "integrity": "sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-ia32": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.2.tgz",
+ "integrity": "sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==",
+ "cpu": [
+ "ia32"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-loong64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.2.tgz",
+ "integrity": "sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==",
+ "cpu": [
+ "loong64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-mips64el": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.2.tgz",
+ "integrity": "sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==",
+ "cpu": [
+ "mips64el"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-ppc64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.2.tgz",
+ "integrity": "sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==",
+ "cpu": [
+ "ppc64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-riscv64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.2.tgz",
+ "integrity": "sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==",
+ "cpu": [
+ "riscv64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-s390x": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.2.tgz",
+ "integrity": "sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==",
+ "cpu": [
+ "s390x"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-x64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.2.tgz",
+ "integrity": "sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/netbsd-arm64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.2.tgz",
+ "integrity": "sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/netbsd-x64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.2.tgz",
+ "integrity": "sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openbsd-arm64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.2.tgz",
+ "integrity": "sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openbsd-x64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.2.tgz",
+ "integrity": "sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openharmony-arm64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.2.tgz",
+ "integrity": "sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "openharmony"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/sunos-x64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.2.tgz",
+ "integrity": "sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-arm64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.2.tgz",
+ "integrity": "sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-ia32": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.2.tgz",
+ "integrity": "sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==",
+ "cpu": [
+ "ia32"
+ ],
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-x64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.2.tgz",
+ "integrity": "sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@eslint-community/eslint-utils": {
+ "version": "4.9.1",
+ "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz",
+ "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==",
+ "dev": true,
+ "dependencies": {
+ "eslint-visitor-keys": "^3.4.3"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
+ }
+ },
+ "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": {
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
+ "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
+ "dev": true,
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/@eslint-community/regexpp": {
+ "version": "4.12.2",
+ "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz",
+ "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==",
+ "dev": true,
+ "engines": {
+ "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
+ }
+ },
+ "node_modules/@eslint/config-array": {
+ "version": "0.21.1",
+ "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz",
+ "integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==",
+ "dev": true,
+ "dependencies": {
+ "@eslint/object-schema": "^2.1.7",
+ "debug": "^4.3.1",
+ "minimatch": "^3.1.2"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/config-helpers": {
+ "version": "0.4.2",
+ "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz",
+ "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==",
+ "dev": true,
+ "dependencies": {
+ "@eslint/core": "^0.17.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/core": {
+ "version": "0.17.0",
+ "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz",
+ "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==",
+ "dev": true,
+ "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.3",
+ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.3.tgz",
+ "integrity": "sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ==",
+ "dev": true,
+ "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.1",
+ "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/globals": {
+ "version": "14.0.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz",
+ "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@eslint/js": {
+ "version": "9.39.2",
+ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.2.tgz",
+ "integrity": "sha512-q1mjIoW1VX4IvSocvM/vbTiveKC4k9eLrajNEuSsmjymSDEbpGddtpfOoN7YGAqBK3NG+uqo8ia4PDTt8buCYA==",
+ "dev": true,
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://eslint.org/donate"
+ }
+ },
+ "node_modules/@eslint/object-schema": {
+ "version": "2.1.7",
+ "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz",
+ "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==",
+ "dev": true,
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/plugin-kit": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz",
+ "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==",
+ "dev": true,
+ "dependencies": {
+ "@eslint/core": "^0.17.0",
+ "levn": "^0.4.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.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,
+ "engines": {
+ "node": ">=18.18.0"
+ }
+ },
+ "node_modules/@humanfs/node": {
+ "version": "0.16.7",
+ "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz",
+ "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==",
+ "dev": true,
+ "dependencies": {
+ "@humanfs/core": "^0.19.1",
+ "@humanwhocodes/retry": "^0.4.0"
+ },
+ "engines": {
+ "node": ">=18.18.0"
+ }
+ },
+ "node_modules/@humanwhocodes/module-importer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
+ "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
+ "dev": true,
+ "engines": {
+ "node": ">=12.22"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
+ }
+ },
+ "node_modules/@humanwhocodes/retry": {
+ "version": "0.4.3",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz",
+ "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=18.18"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
+ }
+ },
+ "node_modules/@jridgewell/gen-mapping": {
+ "version": "0.3.13",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
+ "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.5.0",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ }
+ },
+ "node_modules/@jridgewell/remapping": {
+ "version": "2.3.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz",
+ "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==",
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ }
+ },
+ "node_modules/@jridgewell/resolve-uri": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
+ "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.5.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
+ "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="
+ },
+ "node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.31",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
+ "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
+ "dependencies": {
+ "@jridgewell/resolve-uri": "^3.1.0",
+ "@jridgewell/sourcemap-codec": "^1.4.14"
+ }
+ },
+ "node_modules/@remix-run/router": {
+ "version": "1.23.2",
+ "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.23.2.tgz",
+ "integrity": "sha512-Ic6m2U/rMjTkhERIa/0ZtXJP17QUi2CbWE7cqx4J58M8aA3QTfW+2UlQ4psvTX9IO1RfNVhK3pcpdjej7L+t2w==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/@rolldown/pluginutils": {
+ "version": "1.0.0-beta.47",
+ "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.47.tgz",
+ "integrity": "sha512-8QagwMH3kNCuzD8EWL8R2YPW5e4OrHNSAHRFDdmFqEwEaD/KcNKjVoumo+gP2vW5eKB2UPbM6vTYiGZX0ixLnw==",
+ "dev": true
+ },
+ "node_modules/@rollup/pluginutils": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.3.0.tgz",
+ "integrity": "sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==",
+ "dev": true,
+ "dependencies": {
+ "@types/estree": "^1.0.0",
+ "estree-walker": "^2.0.2",
+ "picomatch": "^4.0.2"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0"
+ },
+ "peerDependenciesMeta": {
+ "rollup": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@rollup/rollup-android-arm-eabi": {
+ "version": "4.54.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.54.0.tgz",
+ "integrity": "sha512-OywsdRHrFvCdvsewAInDKCNyR3laPA2mc9bRYJ6LBp5IyvF3fvXbbNR0bSzHlZVFtn6E0xw2oZlyjg4rKCVcng==",
+ "cpu": [
+ "arm"
+ ],
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-android-arm64": {
+ "version": "4.54.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.54.0.tgz",
+ "integrity": "sha512-Skx39Uv+u7H224Af+bDgNinitlmHyQX1K/atIA32JP3JQw6hVODX5tkbi2zof/E69M1qH2UoN3Xdxgs90mmNYw==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-arm64": {
+ "version": "4.54.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.54.0.tgz",
+ "integrity": "sha512-k43D4qta/+6Fq+nCDhhv9yP2HdeKeP56QrUUTW7E6PhZP1US6NDqpJj4MY0jBHlJivVJD5P8NxrjuobZBJTCRw==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-x64": {
+ "version": "4.54.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.54.0.tgz",
+ "integrity": "sha512-cOo7biqwkpawslEfox5Vs8/qj83M/aZCSSNIWpVzfU2CYHa2G3P1UN5WF01RdTHSgCkri7XOlTdtk17BezlV3A==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-freebsd-arm64": {
+ "version": "4.54.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.54.0.tgz",
+ "integrity": "sha512-miSvuFkmvFbgJ1BevMa4CPCFt5MPGw094knM64W9I0giUIMMmRYcGW/JWZDriaw/k1kOBtsWh1z6nIFV1vPNtA==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-freebsd-x64": {
+ "version": "4.54.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.54.0.tgz",
+ "integrity": "sha512-KGXIs55+b/ZfZsq9aR026tmr/+7tq6VG6MsnrvF4H8VhwflTIuYh+LFUlIsRdQSgrgmtM3fVATzEAj4hBQlaqQ==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
+ "version": "4.54.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.54.0.tgz",
+ "integrity": "sha512-EHMUcDwhtdRGlXZsGSIuXSYwD5kOT9NVnx9sqzYiwAc91wfYOE1g1djOEDseZJKKqtHAHGwnGPQu3kytmfaXLQ==",
+ "cpu": [
+ "arm"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-musleabihf": {
+ "version": "4.54.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.54.0.tgz",
+ "integrity": "sha512-+pBrqEjaakN2ySv5RVrj/qLytYhPKEUwk+e3SFU5jTLHIcAtqh2rLrd/OkbNuHJpsBgxsD8ccJt5ga/SeG0JmA==",
+ "cpu": [
+ "arm"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-gnu": {
+ "version": "4.54.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.54.0.tgz",
+ "integrity": "sha512-NSqc7rE9wuUaRBsBp5ckQ5CVz5aIRKCwsoa6WMF7G01sX3/qHUw/z4pv+D+ahL1EIKy6Enpcnz1RY8pf7bjwng==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-musl": {
+ "version": "4.54.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.54.0.tgz",
+ "integrity": "sha512-gr5vDbg3Bakga5kbdpqx81m2n9IX8M6gIMlQQIXiLTNeQW6CucvuInJ91EuCJ/JYvc+rcLLsDFcfAD1K7fMofg==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-loong64-gnu": {
+ "version": "4.54.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.54.0.tgz",
+ "integrity": "sha512-gsrtB1NA3ZYj2vq0Rzkylo9ylCtW/PhpLEivlgWe0bpgtX5+9j9EZa0wtZiCjgu6zmSeZWyI/e2YRX1URozpIw==",
+ "cpu": [
+ "loong64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-ppc64-gnu": {
+ "version": "4.54.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.54.0.tgz",
+ "integrity": "sha512-y3qNOfTBStmFNq+t4s7Tmc9hW2ENtPg8FeUD/VShI7rKxNW7O4fFeaYbMsd3tpFlIg1Q8IapFgy7Q9i2BqeBvA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-gnu": {
+ "version": "4.54.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.54.0.tgz",
+ "integrity": "sha512-89sepv7h2lIVPsFma8iwmccN7Yjjtgz0Rj/Ou6fEqg3HDhpCa+Et+YSufy27i6b0Wav69Qv4WBNl3Rs6pwhebQ==",
+ "cpu": [
+ "riscv64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-musl": {
+ "version": "4.54.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.54.0.tgz",
+ "integrity": "sha512-ZcU77ieh0M2Q8Ur7D5X7KvK+UxbXeDHwiOt/CPSBTI1fBmeDMivW0dPkdqkT4rOgDjrDDBUed9x4EgraIKoR2A==",
+ "cpu": [
+ "riscv64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-s390x-gnu": {
+ "version": "4.54.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.54.0.tgz",
+ "integrity": "sha512-2AdWy5RdDF5+4YfG/YesGDDtbyJlC9LHmL6rZw6FurBJ5n4vFGupsOBGfwMRjBYH7qRQowT8D/U4LoSvVwOhSQ==",
+ "cpu": [
+ "s390x"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-gnu": {
+ "version": "4.54.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.54.0.tgz",
+ "integrity": "sha512-WGt5J8Ij/rvyqpFexxk3ffKqqbLf9AqrTBbWDk7ApGUzaIs6V+s2s84kAxklFwmMF/vBNGrVdYgbblCOFFezMQ==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-musl": {
+ "version": "4.54.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.54.0.tgz",
+ "integrity": "sha512-JzQmb38ATzHjxlPHuTH6tE7ojnMKM2kYNzt44LO/jJi8BpceEC8QuXYA908n8r3CNuG/B3BV8VR3Hi1rYtmPiw==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-openharmony-arm64": {
+ "version": "4.54.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.54.0.tgz",
+ "integrity": "sha512-huT3fd0iC7jigGh7n3q/+lfPcXxBi+om/Rs3yiFxjvSxbSB6aohDFXbWvlspaqjeOh+hx7DDHS+5Es5qRkWkZg==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "openharmony"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-arm64-msvc": {
+ "version": "4.54.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.54.0.tgz",
+ "integrity": "sha512-c2V0W1bsKIKfbLMBu/WGBz6Yci8nJ/ZJdheE0EwB73N3MvHYKiKGs3mVilX4Gs70eGeDaMqEob25Tw2Gb9Nqyw==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-ia32-msvc": {
+ "version": "4.54.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.54.0.tgz",
+ "integrity": "sha512-woEHgqQqDCkAzrDhvDipnSirm5vxUXtSKDYTVpZG3nUdW/VVB5VdCYA2iReSj/u3yCZzXID4kuKG7OynPnB3WQ==",
+ "cpu": [
+ "ia32"
+ ],
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-x64-gnu": {
+ "version": "4.54.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.54.0.tgz",
+ "integrity": "sha512-dzAc53LOuFvHwbCEOS0rPbXp6SIhAf2txMP5p6mGyOXXw5mWY8NGGbPMPrs4P1WItkfApDathBj/NzMLUZ9rtQ==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-x64-msvc": {
+ "version": "4.54.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.54.0.tgz",
+ "integrity": "sha512-hYT5d3YNdSh3mbCU1gwQyPgQd3T2ne0A3KG8KSBdav5TiBg6eInVmV+TeR5uHufiIgSFg0XsOWGW5/RhNcSvPg==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@svgr/babel-plugin-add-jsx-attribute": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-8.0.0.tgz",
+ "integrity": "sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g==",
+ "dev": true,
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/gregberge"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@svgr/babel-plugin-remove-jsx-attribute": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-8.0.0.tgz",
+ "integrity": "sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA==",
+ "dev": true,
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/gregberge"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@svgr/babel-plugin-remove-jsx-empty-expression": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-8.0.0.tgz",
+ "integrity": "sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA==",
+ "dev": true,
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/gregberge"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@svgr/babel-plugin-replace-jsx-attribute-value": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-8.0.0.tgz",
+ "integrity": "sha512-KVQ+PtIjb1BuYT3ht8M5KbzWBhdAjjUPdlMtpuw/VjT8coTrItWX6Qafl9+ji831JaJcu6PJNKCV0bp01lBNzQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/gregberge"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@svgr/babel-plugin-svg-dynamic-title": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-8.0.0.tgz",
+ "integrity": "sha512-omNiKqwjNmOQJ2v6ge4SErBbkooV2aAWwaPFs2vUY7p7GhVkzRkJ00kILXQvRhA6miHnNpXv7MRnnSjdRjK8og==",
+ "dev": true,
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/gregberge"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@svgr/babel-plugin-svg-em-dimensions": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-8.0.0.tgz",
+ "integrity": "sha512-mURHYnu6Iw3UBTbhGwE/vsngtCIbHE43xCRK7kCw4t01xyGqb2Pd+WXekRRoFOBIY29ZoOhUCTEweDMdrjfi9g==",
+ "dev": true,
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/gregberge"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@svgr/babel-plugin-transform-react-native-svg": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-8.1.0.tgz",
+ "integrity": "sha512-Tx8T58CHo+7nwJ+EhUwx3LfdNSG9R2OKfaIXXs5soiy5HtgoAEkDay9LIimLOcG8dJQH1wPZp/cnAv6S9CrR1Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/gregberge"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@svgr/babel-plugin-transform-svg-component": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-8.0.0.tgz",
+ "integrity": "sha512-DFx8xa3cZXTdb/k3kfPeaixecQLgKh5NVBMwD0AQxOzcZawK4oo1Jh9LbrcACUivsCA7TLG8eeWgrDXjTMhRmw==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/gregberge"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@svgr/babel-preset": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-8.1.0.tgz",
+ "integrity": "sha512-7EYDbHE7MxHpv4sxvnVPngw5fuR6pw79SkcrILHJ/iMpuKySNCl5W1qcwPEpU+LgyRXOaAFgH0KhwD18wwg6ug==",
+ "dev": true,
+ "dependencies": {
+ "@svgr/babel-plugin-add-jsx-attribute": "8.0.0",
+ "@svgr/babel-plugin-remove-jsx-attribute": "8.0.0",
+ "@svgr/babel-plugin-remove-jsx-empty-expression": "8.0.0",
+ "@svgr/babel-plugin-replace-jsx-attribute-value": "8.0.0",
+ "@svgr/babel-plugin-svg-dynamic-title": "8.0.0",
+ "@svgr/babel-plugin-svg-em-dimensions": "8.0.0",
+ "@svgr/babel-plugin-transform-react-native-svg": "8.1.0",
+ "@svgr/babel-plugin-transform-svg-component": "8.0.0"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/gregberge"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@svgr/core": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/@svgr/core/-/core-8.1.0.tgz",
+ "integrity": "sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "@babel/core": "^7.21.3",
+ "@svgr/babel-preset": "8.1.0",
+ "camelcase": "^6.2.0",
+ "cosmiconfig": "^8.1.3",
+ "snake-case": "^3.0.4"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/gregberge"
+ }
+ },
+ "node_modules/@svgr/hast-util-to-babel-ast": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-8.0.0.tgz",
+ "integrity": "sha512-EbDKwO9GpfWP4jN9sGdYwPBU0kdomaPIL2Eu4YwmgP+sJeXT+L7bMwJUBnhzfH8Q2qMBqZ4fJwpCyYsAN3mt2Q==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.21.3",
+ "entities": "^4.4.0"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/gregberge"
+ }
+ },
+ "node_modules/@svgr/plugin-jsx": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-8.1.0.tgz",
+ "integrity": "sha512-0xiIyBsLlr8quN+WyuxooNW9RJ0Dpr8uOnH/xrCVO8GLUcwHISwj1AG0k+LFzteTkAA0GbX0kj9q6Dk70PTiPA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/core": "^7.21.3",
+ "@svgr/babel-preset": "8.1.0",
+ "@svgr/hast-util-to-babel-ast": "8.0.0",
+ "svg-parser": "^2.0.4"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/gregberge"
+ },
+ "peerDependencies": {
+ "@svgr/core": "*"
+ }
+ },
+ "node_modules/@swc/core": {
+ "version": "1.15.8",
+ "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.15.8.tgz",
+ "integrity": "sha512-T8keoJjXaSUoVBCIjgL6wAnhADIb09GOELzKg10CjNg+vLX48P93SME6jTfte9MZIm5m+Il57H3rTSk/0kzDUw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "dependencies": {
+ "@swc/counter": "^0.1.3",
+ "@swc/types": "^0.1.25"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/swc"
+ },
+ "optionalDependencies": {
+ "@swc/core-darwin-arm64": "1.15.8",
+ "@swc/core-darwin-x64": "1.15.8",
+ "@swc/core-linux-arm-gnueabihf": "1.15.8",
+ "@swc/core-linux-arm64-gnu": "1.15.8",
+ "@swc/core-linux-arm64-musl": "1.15.8",
+ "@swc/core-linux-x64-gnu": "1.15.8",
+ "@swc/core-linux-x64-musl": "1.15.8",
+ "@swc/core-win32-arm64-msvc": "1.15.8",
+ "@swc/core-win32-ia32-msvc": "1.15.8",
+ "@swc/core-win32-x64-msvc": "1.15.8"
+ },
+ "peerDependencies": {
+ "@swc/helpers": ">=0.5.17"
+ },
+ "peerDependenciesMeta": {
+ "@swc/helpers": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@swc/core-darwin-arm64": {
+ "version": "1.15.8",
+ "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.15.8.tgz",
+ "integrity": "sha512-M9cK5GwyWWRkRGwwCbREuj6r8jKdES/haCZ3Xckgkl8MUQJZA3XB7IXXK1IXRNeLjg6m7cnoMICpXv1v1hlJOg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-darwin-x64": {
+ "version": "1.15.8",
+ "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.15.8.tgz",
+ "integrity": "sha512-j47DasuOvXl80sKJHSi2X25l44CMc3VDhlJwA7oewC1nV1VsSzwX+KOwE5tLnfORvVJJyeiXgJORNYg4jeIjYQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-linux-arm-gnueabihf": {
+ "version": "1.15.8",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.15.8.tgz",
+ "integrity": "sha512-siAzDENu2rUbwr9+fayWa26r5A9fol1iORG53HWxQL1J8ym4k7xt9eME0dMPXlYZDytK5r9sW8zEA10F2U3Xwg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-linux-arm64-gnu": {
+ "version": "1.15.8",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.15.8.tgz",
+ "integrity": "sha512-o+1y5u6k2FfPYbTRUPvurwzNt5qd0NTumCTFscCNuBksycloXY16J8L+SMW5QRX59n4Hp9EmFa3vpvNHRVv1+Q==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-linux-arm64-musl": {
+ "version": "1.15.8",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.15.8.tgz",
+ "integrity": "sha512-koiCqL09EwOP1S2RShCI7NbsQuG6r2brTqUYE7pV7kZm9O17wZ0LSz22m6gVibpwEnw8jI3IE1yYsQTVpluALw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-linux-x64-gnu": {
+ "version": "1.15.8",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.15.8.tgz",
+ "integrity": "sha512-4p6lOMU3bC+Vd5ARtKJ/FxpIC5G8v3XLoPEZ5s7mLR8h7411HWC/LmTXDHcrSXRC55zvAVia1eldy6zDLz8iFQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-linux-x64-musl": {
+ "version": "1.15.8",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.15.8.tgz",
+ "integrity": "sha512-z3XBnbrZAL+6xDGAhJoN4lOueIxC/8rGrJ9tg+fEaeqLEuAtHSW2QHDHxDwkxZMjuF/pZ6MUTjHjbp8wLbuRLA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-win32-arm64-msvc": {
+ "version": "1.15.8",
+ "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.15.8.tgz",
+ "integrity": "sha512-djQPJ9Rh9vP8GTS/Df3hcc6XP6xnG5c8qsngWId/BLA9oX6C7UzCPAn74BG/wGb9a6j4w3RINuoaieJB3t+7iQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-win32-ia32-msvc": {
+ "version": "1.15.8",
+ "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.15.8.tgz",
+ "integrity": "sha512-/wfAgxORg2VBaUoFdytcVBVCgf1isWZIEXB9MZEUty4wwK93M/PxAkjifOho9RN3WrM3inPLabICRCEgdHpKKQ==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-win32-x64-msvc": {
+ "version": "1.15.8",
+ "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.15.8.tgz",
+ "integrity": "sha512-GpMePrh9Sl4d61o4KAHOOv5is5+zt6BEXCOCgs/H0FLGeii7j9bWDE8ExvKFy2GRRZVNR1ugsnzaGWHKM6kuzA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/counter": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz",
+ "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==",
+ "dev": true
+ },
+ "node_modules/@swc/types": {
+ "version": "0.1.25",
+ "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.25.tgz",
+ "integrity": "sha512-iAoY/qRhNH8a/hBvm3zKj9qQ4oc2+3w1unPJa2XvTK3XjeLXtzcCingVPw/9e5mn1+0yPqxcBGp9Jf0pkfMb1g==",
+ "dev": true,
+ "dependencies": {
+ "@swc/counter": "^0.1.3"
+ }
+ },
+ "node_modules/@tailwindcss/node": {
+ "version": "4.1.18",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.18.tgz",
+ "integrity": "sha512-DoR7U1P7iYhw16qJ49fgXUlry1t4CpXeErJHnQ44JgTSKMaZUdf17cfn5mHchfJ4KRBZRFA/Coo+MUF5+gOaCQ==",
+ "dependencies": {
+ "@jridgewell/remapping": "^2.3.4",
+ "enhanced-resolve": "^5.18.3",
+ "jiti": "^2.6.1",
+ "lightningcss": "1.30.2",
+ "magic-string": "^0.30.21",
+ "source-map-js": "^1.2.1",
+ "tailwindcss": "4.1.18"
+ }
+ },
+ "node_modules/@tailwindcss/oxide": {
+ "version": "4.1.18",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.18.tgz",
+ "integrity": "sha512-EgCR5tTS5bUSKQgzeMClT6iCY3ToqE1y+ZB0AKldj809QXk1Y+3jB0upOYZrn9aGIzPtUsP7sX4QQ4XtjBB95A==",
+ "engines": {
+ "node": ">= 10"
+ },
+ "optionalDependencies": {
+ "@tailwindcss/oxide-android-arm64": "4.1.18",
+ "@tailwindcss/oxide-darwin-arm64": "4.1.18",
+ "@tailwindcss/oxide-darwin-x64": "4.1.18",
+ "@tailwindcss/oxide-freebsd-x64": "4.1.18",
+ "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.18",
+ "@tailwindcss/oxide-linux-arm64-gnu": "4.1.18",
+ "@tailwindcss/oxide-linux-arm64-musl": "4.1.18",
+ "@tailwindcss/oxide-linux-x64-gnu": "4.1.18",
+ "@tailwindcss/oxide-linux-x64-musl": "4.1.18",
+ "@tailwindcss/oxide-wasm32-wasi": "4.1.18",
+ "@tailwindcss/oxide-win32-arm64-msvc": "4.1.18",
+ "@tailwindcss/oxide-win32-x64-msvc": "4.1.18"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-android-arm64": {
+ "version": "4.1.18",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.18.tgz",
+ "integrity": "sha512-dJHz7+Ugr9U/diKJA0W6N/6/cjI+ZTAoxPf9Iz9BFRF2GzEX8IvXxFIi/dZBloVJX/MZGvRuFA9rqwdiIEZQ0Q==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-darwin-arm64": {
+ "version": "4.1.18",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.18.tgz",
+ "integrity": "sha512-Gc2q4Qhs660bhjyBSKgq6BYvwDz4G+BuyJ5H1xfhmDR3D8HnHCmT/BSkvSL0vQLy/nkMLY20PQ2OoYMO15Jd0A==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-darwin-x64": {
+ "version": "4.1.18",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.18.tgz",
+ "integrity": "sha512-FL5oxr2xQsFrc3X9o1fjHKBYBMD1QZNyc1Xzw/h5Qu4XnEBi3dZn96HcHm41c/euGV+GRiXFfh2hUCyKi/e+yw==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-freebsd-x64": {
+ "version": "4.1.18",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.18.tgz",
+ "integrity": "sha512-Fj+RHgu5bDodmV1dM9yAxlfJwkkWvLiRjbhuO2LEtwtlYlBgiAT4x/j5wQr1tC3SANAgD+0YcmWVrj8R9trVMA==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": {
+ "version": "4.1.18",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.18.tgz",
+ "integrity": "sha512-Fp+Wzk/Ws4dZn+LV2Nqx3IilnhH51YZoRaYHQsVq3RQvEl+71VGKFpkfHrLM/Li+kt5c0DJe/bHXK1eHgDmdiA==",
+ "cpu": [
+ "arm"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-linux-arm64-gnu": {
+ "version": "4.1.18",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.18.tgz",
+ "integrity": "sha512-S0n3jboLysNbh55Vrt7pk9wgpyTTPD0fdQeh7wQfMqLPM/Hrxi+dVsLsPrycQjGKEQk85Kgbx+6+QnYNiHalnw==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-linux-arm64-musl": {
+ "version": "4.1.18",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.18.tgz",
+ "integrity": "sha512-1px92582HkPQlaaCkdRcio71p8bc8i/ap5807tPRDK/uw953cauQBT8c5tVGkOwrHMfc2Yh6UuxaH4vtTjGvHg==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-linux-x64-gnu": {
+ "version": "4.1.18",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.18.tgz",
+ "integrity": "sha512-v3gyT0ivkfBLoZGF9LyHmts0Isc8jHZyVcbzio6Wpzifg/+5ZJpDiRiUhDLkcr7f/r38SWNe7ucxmGW3j3Kb/g==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-linux-x64-musl": {
+ "version": "4.1.18",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.18.tgz",
+ "integrity": "sha512-bhJ2y2OQNlcRwwgOAGMY0xTFStt4/wyU6pvI6LSuZpRgKQwxTec0/3Scu91O8ir7qCR3AuepQKLU/kX99FouqQ==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-wasm32-wasi": {
+ "version": "4.1.18",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.18.tgz",
+ "integrity": "sha512-LffYTvPjODiP6PT16oNeUQJzNVyJl1cjIebq/rWWBF+3eDst5JGEFSc5cWxyRCJ0Mxl+KyIkqRxk1XPEs9x8TA==",
+ "bundleDependencies": [
+ "@napi-rs/wasm-runtime",
+ "@emnapi/core",
+ "@emnapi/runtime",
+ "@tybys/wasm-util",
+ "@emnapi/wasi-threads",
+ "tslib"
+ ],
+ "cpu": [
+ "wasm32"
+ ],
+ "optional": true,
+ "dependencies": {
+ "@emnapi/core": "^1.7.1",
+ "@emnapi/runtime": "^1.7.1",
+ "@emnapi/wasi-threads": "^1.1.0",
+ "@napi-rs/wasm-runtime": "^1.1.0",
+ "@tybys/wasm-util": "^0.10.1",
+ "tslib": "^2.4.0"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-win32-arm64-msvc": {
+ "version": "4.1.18",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.18.tgz",
+ "integrity": "sha512-HjSA7mr9HmC8fu6bdsZvZ+dhjyGCLdotjVOgLA2vEqxEBZaQo9YTX4kwgEvPCpRh8o4uWc4J/wEoFzhEmjvPbA==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-win32-x64-msvc": {
+ "version": "4.1.18",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.18.tgz",
+ "integrity": "sha512-bJWbyYpUlqamC8dpR7pfjA0I7vdF6t5VpUGMWRkXVE3AXgIZjYUYAK7II1GNaxR8J1SSrSrppRar8G++JekE3Q==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tailwindcss/vite": {
+ "version": "4.1.18",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.1.18.tgz",
+ "integrity": "sha512-jVA+/UpKL1vRLg6Hkao5jldawNmRo7mQYrZtNHMIVpLfLhDml5nMRUo/8MwoX2vNXvnaXNNMedrMfMugAVX1nA==",
+ "dependencies": {
+ "@tailwindcss/node": "4.1.18",
+ "@tailwindcss/oxide": "4.1.18",
+ "tailwindcss": "4.1.18"
+ },
+ "peerDependencies": {
+ "vite": "^5.2.0 || ^6 || ^7"
+ }
+ },
+ "node_modules/@tanstack/query-core": {
+ "version": "5.90.19",
+ "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.90.19.tgz",
+ "integrity": "sha512-GLW5sjPVIvH491VV1ufddnfldyVB+teCnpPIvweEfkpRx7CfUmUGhoh9cdcUKBh/KwVxk22aNEDxeTsvmyB/WA==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/tannerlinsley"
+ }
+ },
+ "node_modules/@tanstack/react-query": {
+ "version": "5.90.19",
+ "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.90.19.tgz",
+ "integrity": "sha512-qTZRZ4QyTzQc+M0IzrbKHxSeISUmRB3RPGmao5bT+sI6ayxSRhn0FXEnT5Hg3as8SBFcRosrXXRFB+yAcxVxJQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@tanstack/query-core": "5.90.19"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/tannerlinsley"
+ },
+ "peerDependencies": {
+ "react": "^18 || ^19"
+ }
+ },
+ "node_modules/@types/estree": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
+ "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="
+ },
+ "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
+ },
+ "node_modules/@types/node": {
+ "version": "24.10.4",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.4.tgz",
+ "integrity": "sha512-vnDVpYPMzs4wunl27jHrfmwojOGKya0xyM3sH+UE5iv5uPS6vX7UIoh6m+vQc5LGBq52HBKPIn/zcSZVzeDEZg==",
+ "devOptional": true,
+ "peer": true,
+ "dependencies": {
+ "undici-types": "~7.16.0"
+ }
+ },
+ "node_modules/@types/prop-types": {
+ "version": "15.7.15",
+ "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz",
+ "integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==",
+ "devOptional": true
+ },
+ "node_modules/@types/react": {
+ "version": "18.3.27",
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.27.tgz",
+ "integrity": "sha512-cisd7gxkzjBKU2GgdYrTdtQx1SORymWyaAFhaxQPK9bYO9ot3Y5OikQRvY0VYQtvwjeQnizCINJAenh/V7MK2w==",
+ "devOptional": true,
+ "peer": true,
+ "dependencies": {
+ "@types/prop-types": "*",
+ "csstype": "^3.2.2"
+ }
+ },
+ "node_modules/@types/react-dom": {
+ "version": "18.3.7",
+ "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.7.tgz",
+ "integrity": "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==",
+ "dev": true,
+ "peerDependencies": {
+ "@types/react": "^18.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/eslint-plugin": {
+ "version": "8.51.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.51.0.tgz",
+ "integrity": "sha512-XtssGWJvypyM2ytBnSnKtHYOGT+4ZwTnBVl36TA4nRO2f4PRNGz5/1OszHzcZCvcBMh+qb7I06uoCmLTRdR9og==",
+ "dev": true,
+ "dependencies": {
+ "@eslint-community/regexpp": "^4.10.0",
+ "@typescript-eslint/scope-manager": "8.51.0",
+ "@typescript-eslint/type-utils": "8.51.0",
+ "@typescript-eslint/utils": "8.51.0",
+ "@typescript-eslint/visitor-keys": "8.51.0",
+ "ignore": "^7.0.0",
+ "natural-compare": "^1.4.0",
+ "ts-api-utils": "^2.2.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "@typescript-eslint/parser": "^8.51.0",
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <6.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": {
+ "version": "7.0.5",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz",
+ "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==",
+ "dev": true,
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/@typescript-eslint/parser": {
+ "version": "8.51.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.51.0.tgz",
+ "integrity": "sha512-3xP4XzzDNQOIqBMWogftkwxhg5oMKApqY0BAflmLZiFYHqyhSOxv/cd/zPQLTcCXr4AkaKb25joocY0BD1WC6A==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "@typescript-eslint/scope-manager": "8.51.0",
+ "@typescript-eslint/types": "8.51.0",
+ "@typescript-eslint/typescript-estree": "8.51.0",
+ "@typescript-eslint/visitor-keys": "8.51.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 <6.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/project-service": {
+ "version": "8.51.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.51.0.tgz",
+ "integrity": "sha512-Luv/GafO07Z7HpiI7qeEW5NW8HUtZI/fo/kE0YbtQEFpJRUuR0ajcWfCE5bnMvL7QQFrmT/odMe8QZww8X2nfQ==",
+ "dev": true,
+ "dependencies": {
+ "@typescript-eslint/tsconfig-utils": "^8.51.0",
+ "@typescript-eslint/types": "^8.51.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": {
+ "typescript": ">=4.8.4 <6.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/scope-manager": {
+ "version": "8.51.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.51.0.tgz",
+ "integrity": "sha512-JhhJDVwsSx4hiOEQPeajGhCWgBMBwVkxC/Pet53EpBVs7zHHtayKefw1jtPaNRXpI9RA2uocdmpdfE7T+NrizA==",
+ "dev": true,
+ "dependencies": {
+ "@typescript-eslint/types": "8.51.0",
+ "@typescript-eslint/visitor-keys": "8.51.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/tsconfig-utils": {
+ "version": "8.51.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.51.0.tgz",
+ "integrity": "sha512-Qi5bSy/vuHeWyir2C8u/uqGMIlIDu8fuiYWv48ZGlZ/k+PRPHtaAu7erpc7p5bzw2WNNSniuxoMSO4Ar6V9OXw==",
+ "dev": true,
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.8.4 <6.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/type-utils": {
+ "version": "8.51.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.51.0.tgz",
+ "integrity": "sha512-0XVtYzxnobc9K0VU7wRWg1yiUrw4oQzexCG2V2IDxxCxhqBMSMbjB+6o91A+Uc0GWtgjCa3Y8bi7hwI0Tu4n5Q==",
+ "dev": true,
+ "dependencies": {
+ "@typescript-eslint/types": "8.51.0",
+ "@typescript-eslint/typescript-estree": "8.51.0",
+ "@typescript-eslint/utils": "8.51.0",
+ "debug": "^4.3.4",
+ "ts-api-utils": "^2.2.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 <6.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/types": {
+ "version": "8.51.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.51.0.tgz",
+ "integrity": "sha512-TizAvWYFM6sSscmEakjY3sPqGwxZRSywSsPEiuZF6d5GmGD9Gvlsv0f6N8FvAAA0CD06l3rIcWNbsN1e5F/9Ag==",
+ "dev": true,
+ "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.51.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.51.0.tgz",
+ "integrity": "sha512-1qNjGqFRmlq0VW5iVlcyHBbCjPB7y6SxpBkrbhNWMy/65ZoncXCEPJxkRZL8McrseNH6lFhaxCIaX+vBuFnRng==",
+ "dev": true,
+ "dependencies": {
+ "@typescript-eslint/project-service": "8.51.0",
+ "@typescript-eslint/tsconfig-utils": "8.51.0",
+ "@typescript-eslint/types": "8.51.0",
+ "@typescript-eslint/visitor-keys": "8.51.0",
+ "debug": "^4.3.4",
+ "minimatch": "^9.0.4",
+ "semver": "^7.6.0",
+ "tinyglobby": "^0.2.15",
+ "ts-api-utils": "^2.2.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.8.4 <6.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
+ "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
+ "dev": true,
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree/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,
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": {
+ "version": "7.7.3",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
+ "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@typescript-eslint/utils": {
+ "version": "8.51.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.51.0.tgz",
+ "integrity": "sha512-11rZYxSe0zabiKaCP2QAwRf/dnmgFgvTmeDTtZvUvXG3UuAdg/GU02NExmmIXzz3vLGgMdtrIosI84jITQOxUA==",
+ "dev": true,
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.7.0",
+ "@typescript-eslint/scope-manager": "8.51.0",
+ "@typescript-eslint/types": "8.51.0",
+ "@typescript-eslint/typescript-estree": "8.51.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 <6.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/visitor-keys": {
+ "version": "8.51.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.51.0.tgz",
+ "integrity": "sha512-mM/JRQOzhVN1ykejrvwnBRV3+7yTKK8tVANVN3o1O0t0v7o+jqdVu9crPy5Y9dov15TJk/FTIgoUGHrTOVL3Zg==",
+ "dev": true,
+ "dependencies": {
+ "@typescript-eslint/types": "8.51.0",
+ "eslint-visitor-keys": "^4.2.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@vitejs/plugin-react-swc": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/@vitejs/plugin-react-swc/-/plugin-react-swc-4.2.2.tgz",
+ "integrity": "sha512-x+rE6tsxq/gxrEJN3Nv3dIV60lFflPj94c90b+NNo6n1QV1QQUTLoL0MpaOVasUZ0zqVBn7ead1B5ecx1JAGfA==",
+ "dev": true,
+ "dependencies": {
+ "@rolldown/pluginutils": "1.0.0-beta.47",
+ "@swc/core": "^1.13.5"
+ },
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ },
+ "peerDependencies": {
+ "vite": "^4 || ^5 || ^6 || ^7"
+ }
+ },
+ "node_modules/acorn": {
+ "version": "8.15.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
+ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
+ "dev": true,
+ "peer": true,
+ "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,
+ "peerDependencies": {
+ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ }
+ },
+ "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,
+ "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-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "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
+ },
+ "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-includes": {
+ "version": "3.1.9",
+ "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.9.tgz",
+ "integrity": "sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.4",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.24.0",
+ "es-object-atoms": "^1.1.1",
+ "get-intrinsic": "^1.3.0",
+ "is-string": "^1.1.1",
+ "math-intrinsics": "^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/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/asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
+ "license": "MIT"
+ },
+ "node_modules/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.11.1",
+ "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.11.1.tgz",
+ "integrity": "sha512-BASOg+YwO2C+346x3LZOeoovTIoTrRqEsqMa6fmfAV0P+U9mFr9NsyOEpiYvFjbc64NMrSswhV50WdXzdb/Z5A==",
+ "dev": true,
+ "license": "MPL-2.0",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/axios": {
+ "version": "1.13.5",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.5.tgz",
+ "integrity": "sha512-cz4ur7Vb0xS4/KUN0tPWe44eqxrIu31me+fbang3ijiNscE129POzipJJA6zniq2C/Z6sJCjMimjS8Lc/GAs8Q==",
+ "license": "MIT",
+ "dependencies": {
+ "follow-redirects": "^1.15.11",
+ "form-data": "^4.0.5",
+ "proxy-from-env": "^1.1.0"
+ }
+ },
+ "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
+ },
+ "node_modules/baseline-browser-mapping": {
+ "version": "2.9.11",
+ "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.11.tgz",
+ "integrity": "sha512-Sg0xJUNDU1sJNGdfGWhVHX0kkZ+HWcvmVymJbj6NSgZZmW/8S9Y2HQ5euytnIgakgxN6papOAWiwDo1ctFDcoQ==",
+ "dev": true,
+ "bin": {
+ "baseline-browser-mapping": "dist/cli.js"
+ }
+ },
+ "node_modules/brace-expansion": {
+ "version": "1.1.12",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
+ "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
+ "dev": true,
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/browserslist": {
+ "version": "4.28.1",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz",
+ "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==",
+ "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"
+ }
+ ],
+ "peer": true,
+ "dependencies": {
+ "baseline-browser-mapping": "^2.9.0",
+ "caniuse-lite": "^1.0.30001759",
+ "electron-to-chromium": "^1.5.263",
+ "node-releases": "^2.0.27",
+ "update-browserslist-db": "^1.2.0"
+ },
+ "bin": {
+ "browserslist": "cli.js"
+ },
+ "engines": {
+ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+ }
+ },
+ "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==",
+ "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,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/camelcase": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
+ "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/caniuse-lite": {
+ "version": "1.0.30001762",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001762.tgz",
+ "integrity": "sha512-PxZwGNvH7Ak8WX5iXzoK1KPZttBXNPuaOvI2ZYU7NrlM+d9Ov+TUvlLOBNGzVXAntMSMMlJPd+jY6ovrVjSmUw==",
+ "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"
+ }
+ ]
+ },
+ "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,
+ "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/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,
+ "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
+ },
+ "node_modules/combined-stream": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+ "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+ "license": "MIT",
+ "dependencies": {
+ "delayed-stream": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
+ "dev": true
+ },
+ "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
+ },
+ "node_modules/cosmiconfig": {
+ "version": "8.3.6",
+ "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz",
+ "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==",
+ "dev": true,
+ "dependencies": {
+ "import-fresh": "^3.3.0",
+ "js-yaml": "^4.1.0",
+ "parse-json": "^5.2.0",
+ "path-type": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/d-fischer"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.9.5"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "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,
+ "dependencies": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/csstype": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
+ "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
+ "devOptional": true
+ },
+ "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/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/debug": {
+ "version": "4.4.3",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
+ "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
+ "dev": true,
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/deep-is": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
+ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
+ "dev": true
+ },
+ "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/delayed-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/detect-libc": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
+ "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/dom-serializer": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
+ "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
+ "license": "MIT",
+ "dependencies": {
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.2",
+ "entities": "^4.2.0"
+ },
+ "funding": {
+ "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
+ }
+ },
+ "node_modules/domelementtype": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
+ "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fb55"
+ }
+ ],
+ "license": "BSD-2-Clause"
+ },
+ "node_modules/domhandler": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
+ "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "domelementtype": "^2.3.0"
+ },
+ "engines": {
+ "node": ">= 4"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domhandler?sponsor=1"
+ }
+ },
+ "node_modules/domutils": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz",
+ "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==",
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "dom-serializer": "^2.0.0",
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.3"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domutils?sponsor=1"
+ }
+ },
+ "node_modules/dot-case": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz",
+ "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==",
+ "dev": true,
+ "dependencies": {
+ "no-case": "^3.0.4",
+ "tslib": "^2.0.3"
+ }
+ },
+ "node_modules/dunder-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
+ "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "gopd": "^1.2.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/electron-to-chromium": {
+ "version": "1.5.267",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.267.tgz",
+ "integrity": "sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==",
+ "dev": true
+ },
+ "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/enhanced-resolve": {
+ "version": "5.18.4",
+ "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.4.tgz",
+ "integrity": "sha512-LgQMM4WXU3QI+SYgEc2liRgznaD5ojbmY3sb8LxyguVkIg5FxdpTkvk72te2R38/TGKxH634oLxXRGY6d7AP+Q==",
+ "dependencies": {
+ "graceful-fs": "^4.2.4",
+ "tapable": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/entities": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
+ "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
+ "engines": {
+ "node": ">=0.12"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/error-ex": {
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz",
+ "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==",
+ "dev": true,
+ "dependencies": {
+ "is-arrayish": "^0.2.1"
+ }
+ },
+ "node_modules/es-abstract": {
+ "version": "1.24.1",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.1.tgz",
+ "integrity": "sha512-zHXBLhP+QehSSbsS9Pt23Gg964240DPd6QCf8WpkqEXxQ7fhdZzYsocOr5u7apWonsS5EjZDmTF+/slGMyasvw==",
+ "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.4",
+ "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.1.1",
+ "es-set-tostringtag": "^2.1.0",
+ "es-to-primitive": "^1.3.0",
+ "function.prototype.name": "^1.1.8",
+ "get-intrinsic": "^1.3.0",
+ "get-proto": "^1.0.1",
+ "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-negative-zero": "^2.0.3",
+ "is-regex": "^1.2.1",
+ "is-set": "^2.0.3",
+ "is-shared-array-buffer": "^1.0.4",
+ "is-string": "^1.1.1",
+ "is-typed-array": "^1.1.15",
+ "is-weakref": "^1.1.1",
+ "math-intrinsics": "^1.1.0",
+ "object-inspect": "^1.13.4",
+ "object-keys": "^1.1.1",
+ "object.assign": "^4.1.7",
+ "own-keys": "^1.0.1",
+ "regexp.prototype.flags": "^1.5.4",
+ "safe-array-concat": "^1.1.3",
+ "safe-push-apply": "^1.0.0",
+ "safe-regex-test": "^1.1.0",
+ "set-proto": "^1.0.0",
+ "stop-iteration-iterator": "^1.1.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.19"
+ },
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-errors": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
+ "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-object-atoms": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
+ "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-set-tostringtag": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
+ "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.6",
+ "has-tostringtag": "^1.0.2",
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/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.27.2",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.2.tgz",
+ "integrity": "sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==",
+ "hasInstallScript": true,
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "optionalDependencies": {
+ "@esbuild/aix-ppc64": "0.27.2",
+ "@esbuild/android-arm": "0.27.2",
+ "@esbuild/android-arm64": "0.27.2",
+ "@esbuild/android-x64": "0.27.2",
+ "@esbuild/darwin-arm64": "0.27.2",
+ "@esbuild/darwin-x64": "0.27.2",
+ "@esbuild/freebsd-arm64": "0.27.2",
+ "@esbuild/freebsd-x64": "0.27.2",
+ "@esbuild/linux-arm": "0.27.2",
+ "@esbuild/linux-arm64": "0.27.2",
+ "@esbuild/linux-ia32": "0.27.2",
+ "@esbuild/linux-loong64": "0.27.2",
+ "@esbuild/linux-mips64el": "0.27.2",
+ "@esbuild/linux-ppc64": "0.27.2",
+ "@esbuild/linux-riscv64": "0.27.2",
+ "@esbuild/linux-s390x": "0.27.2",
+ "@esbuild/linux-x64": "0.27.2",
+ "@esbuild/netbsd-arm64": "0.27.2",
+ "@esbuild/netbsd-x64": "0.27.2",
+ "@esbuild/openbsd-arm64": "0.27.2",
+ "@esbuild/openbsd-x64": "0.27.2",
+ "@esbuild/openharmony-arm64": "0.27.2",
+ "@esbuild/sunos-x64": "0.27.2",
+ "@esbuild/win32-arm64": "0.27.2",
+ "@esbuild/win32-ia32": "0.27.2",
+ "@esbuild/win32-x64": "0.27.2"
+ }
+ },
+ "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,
+ "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,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/eslint": {
+ "version": "9.39.2",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.2.tgz",
+ "integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.8.0",
+ "@eslint-community/regexpp": "^4.12.1",
+ "@eslint/config-array": "^0.21.1",
+ "@eslint/config-helpers": "^0.4.2",
+ "@eslint/core": "^0.17.0",
+ "@eslint/eslintrc": "^3.3.1",
+ "@eslint/js": "9.39.2",
+ "@eslint/plugin-kit": "^0.4.1",
+ "@humanfs/node": "^0.16.6",
+ "@humanwhocodes/module-importer": "^1.0.1",
+ "@humanwhocodes/retry": "^0.4.2",
+ "@types/estree": "^1.0.6",
+ "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.4.0",
+ "eslint-visitor-keys": "^4.2.1",
+ "espree": "^10.4.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-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-react-hooks": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-7.0.1.tgz",
+ "integrity": "sha512-O0d0m04evaNzEPoSW+59Mezf8Qt0InfgGIBJnpC0h3NH/WjUAR7BIKUfysC6todmtiZ/A0oUVS8Gce0WhBrHsA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/core": "^7.24.4",
+ "@babel/parser": "^7.24.4",
+ "hermes-parser": "^0.25.1",
+ "zod": "^3.25.0 || ^4.0.0",
+ "zod-validation-error": "^3.5.0 || ^4.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0"
+ }
+ },
+ "node_modules/eslint-plugin-react-refresh": {
+ "version": "0.4.26",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.26.tgz",
+ "integrity": "sha512-1RETEylht2O6FM/MvgnyvT+8K21wLqDNg4qD51Zj3guhjt433XbnnkVttHMyaVyAFD03QSV4LPS5iE3VQmO7XQ==",
+ "dev": true,
+ "peerDependencies": {
+ "eslint": ">=8.40"
+ }
+ },
+ "node_modules/eslint-scope": {
+ "version": "8.4.0",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz",
+ "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==",
+ "dev": true,
+ "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": "4.2.1",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
+ "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==",
+ "dev": true,
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/espree": {
+ "version": "10.4.0",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz",
+ "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==",
+ "dev": true,
+ "dependencies": {
+ "acorn": "^8.15.0",
+ "acorn-jsx": "^5.3.2",
+ "eslint-visitor-keys": "^4.2.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/esquery": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz",
+ "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==",
+ "dev": true,
+ "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,
+ "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,
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/estree-walker": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
+ "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
+ "dev": true
+ },
+ "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,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/fast-deep-equal": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+ "dev": true
+ },
+ "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
+ },
+ "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
+ },
+ "node_modules/fdir": {
+ "version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
+ "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "peerDependencies": {
+ "picomatch": "^3 || ^4"
+ },
+ "peerDependenciesMeta": {
+ "picomatch": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/file-entry-cache": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz",
+ "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==",
+ "dev": true,
+ "dependencies": {
+ "flat-cache": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "node_modules/find-up": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
+ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
+ "dev": true,
+ "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,
+ "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
+ },
+ "node_modules/follow-redirects": {
+ "version": "1.15.11",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz",
+ "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/RubenVerborgh"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=4.0"
+ },
+ "peerDependenciesMeta": {
+ "debug": {
+ "optional": true
+ }
+ }
+ },
+ "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/form-data": {
+ "version": "4.0.5",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz",
+ "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==",
+ "license": "MIT",
+ "dependencies": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.8",
+ "es-set-tostringtag": "^2.1.0",
+ "hasown": "^2.0.2",
+ "mime-types": "^2.1.12"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "hasInstallScript": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/function-bind": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/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/generator-function": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz",
+ "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "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,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/get-intrinsic": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
+ "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.2",
+ "es-define-property": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.1.1",
+ "function-bind": "^1.1.2",
+ "get-proto": "^1.0.1",
+ "gopd": "^1.2.0",
+ "has-symbols": "^1.1.0",
+ "hasown": "^2.0.2",
+ "math-intrinsics": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/get-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
+ "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
+ "license": "MIT",
+ "dependencies": {
+ "dunder-proto": "^1.0.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/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/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,
+ "dependencies": {
+ "is-glob": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/globals": {
+ "version": "16.5.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-16.5.0.tgz",
+ "integrity": "sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ==",
+ "dev": true,
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/graceful-fs": {
+ "version": "4.2.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
+ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="
+ },
+ "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,
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-tostringtag": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
+ "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
+ "license": "MIT",
+ "dependencies": {
+ "has-symbols": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/hasown": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
+ "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
+ "license": "MIT",
+ "dependencies": {
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/hermes-estree": {
+ "version": "0.25.1",
+ "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.25.1.tgz",
+ "integrity": "sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw==",
+ "dev": true
+ },
+ "node_modules/hermes-parser": {
+ "version": "0.25.1",
+ "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.25.1.tgz",
+ "integrity": "sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA==",
+ "dev": true,
+ "dependencies": {
+ "hermes-estree": "0.25.1"
+ }
+ },
+ "node_modules/html-dom-parser": {
+ "version": "5.1.7",
+ "resolved": "https://registry.npmjs.org/html-dom-parser/-/html-dom-parser-5.1.7.tgz",
+ "integrity": "sha512-Sn+6S3Z8P3P12qqUm4+9wnchC3Bjc4DHp60fgnUdgeiy6e3EbECFWdrmyTBuphxJA5Is7V400+v7ct/Ix2pJFw==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/remarkablemark"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "domhandler": "5.0.3",
+ "htmlparser2": "10.1.0"
+ }
+ },
+ "node_modules/html-react-parser": {
+ "version": "5.2.16",
+ "resolved": "https://registry.npmjs.org/html-react-parser/-/html-react-parser-5.2.16.tgz",
+ "integrity": "sha512-1S6KLse1hKWOXYL/PSnZhsARJBE6eIO93CjPlDKMneO0wz8YTnzTfc9Yw4mWsCk2kcB9IrU+R0W6Rdi4N7YfJw==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/remarkablemark"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/html-react-parser"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "domhandler": "5.0.3",
+ "html-dom-parser": "5.1.7",
+ "react-property": "2.0.2",
+ "style-to-js": "1.1.21"
+ },
+ "peerDependencies": {
+ "@types/react": "0.14 || 15 || 16 || 17 || 18 || 19",
+ "react": "0.14 || 15 || 16 || 17 || 18 || 19"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/htmlparser2": {
+ "version": "10.1.0",
+ "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-10.1.0.tgz",
+ "integrity": "sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ==",
+ "funding": [
+ "https://github.com/fb55/htmlparser2?sponsor=1",
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fb55"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.3",
+ "domutils": "^3.2.2",
+ "entities": "^7.0.1"
+ }
+ },
+ "node_modules/htmlparser2/node_modules/entities": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz",
+ "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==",
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.12"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/ignore": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
+ "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
+ "dev": true,
+ "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,
+ "dependencies": {
+ "parent-module": "^1.0.0",
+ "resolve-from": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.8.19"
+ }
+ },
+ "node_modules/inline-style-parser": {
+ "version": "0.2.7",
+ "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.7.tgz",
+ "integrity": "sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==",
+ "license": "MIT"
+ },
+ "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
+ },
+ "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-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-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,
+ "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-generator-function": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz",
+ "integrity": "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.4",
+ "generator-function": "^2.0.0",
+ "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-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "dev": true,
+ "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-negative-zero": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz",
+ "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "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-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-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-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
+ },
+ "node_modules/jiti": {
+ "version": "2.6.1",
+ "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz",
+ "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==",
+ "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=="
+ },
+ "node_modules/js-yaml": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz",
+ "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==",
+ "dev": true,
+ "dependencies": {
+ "argparse": "^2.0.1"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/jsesc": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
+ "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
+ "dev": true,
+ "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
+ },
+ "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
+ },
+ "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
+ },
+ "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
+ },
+ "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,
+ "bin": {
+ "json5": "lib/cli.js"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "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,
+ "dependencies": {
+ "json-buffer": "3.0.1"
+ }
+ },
+ "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,
+ "dependencies": {
+ "prelude-ls": "^1.2.1",
+ "type-check": "~0.4.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/lightningcss": {
+ "version": "1.30.2",
+ "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.2.tgz",
+ "integrity": "sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ==",
+ "dependencies": {
+ "detect-libc": "^2.0.3"
+ },
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ },
+ "optionalDependencies": {
+ "lightningcss-android-arm64": "1.30.2",
+ "lightningcss-darwin-arm64": "1.30.2",
+ "lightningcss-darwin-x64": "1.30.2",
+ "lightningcss-freebsd-x64": "1.30.2",
+ "lightningcss-linux-arm-gnueabihf": "1.30.2",
+ "lightningcss-linux-arm64-gnu": "1.30.2",
+ "lightningcss-linux-arm64-musl": "1.30.2",
+ "lightningcss-linux-x64-gnu": "1.30.2",
+ "lightningcss-linux-x64-musl": "1.30.2",
+ "lightningcss-win32-arm64-msvc": "1.30.2",
+ "lightningcss-win32-x64-msvc": "1.30.2"
+ }
+ },
+ "node_modules/lightningcss-android-arm64": {
+ "version": "1.30.2",
+ "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.30.2.tgz",
+ "integrity": "sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-darwin-arm64": {
+ "version": "1.30.2",
+ "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.2.tgz",
+ "integrity": "sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-darwin-x64": {
+ "version": "1.30.2",
+ "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.2.tgz",
+ "integrity": "sha512-oBZgKchomuDYxr7ilwLcyms6BCyLn0z8J0+ZZmfpjwg9fRVZIR5/GMXd7r9RH94iDhld3UmSjBM6nXWM2TfZTQ==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-freebsd-x64": {
+ "version": "1.30.2",
+ "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.2.tgz",
+ "integrity": "sha512-c2bH6xTrf4BDpK8MoGG4Bd6zAMZDAXS569UxCAGcA7IKbHNMlhGQ89eRmvpIUGfKWNVdbhSbkQaWhEoMGmGslA==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-arm-gnueabihf": {
+ "version": "1.30.2",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.2.tgz",
+ "integrity": "sha512-eVdpxh4wYcm0PofJIZVuYuLiqBIakQ9uFZmipf6LF/HRj5Bgm0eb3qL/mr1smyXIS1twwOxNWndd8z0E374hiA==",
+ "cpu": [
+ "arm"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-arm64-gnu": {
+ "version": "1.30.2",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.2.tgz",
+ "integrity": "sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-arm64-musl": {
+ "version": "1.30.2",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.2.tgz",
+ "integrity": "sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-x64-gnu": {
+ "version": "1.30.2",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.2.tgz",
+ "integrity": "sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-x64-musl": {
+ "version": "1.30.2",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.2.tgz",
+ "integrity": "sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-win32-arm64-msvc": {
+ "version": "1.30.2",
+ "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.2.tgz",
+ "integrity": "sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-win32-x64-msvc": {
+ "version": "1.30.2",
+ "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.2.tgz",
+ "integrity": "sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lines-and-columns": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
+ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
+ "dev": true
+ },
+ "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,
+ "dependencies": {
+ "p-locate": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "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
+ },
+ "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==",
+ "dependencies": {
+ "js-tokens": "^3.0.0 || ^4.0.0"
+ },
+ "bin": {
+ "loose-envify": "cli.js"
+ }
+ },
+ "node_modules/lower-case": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz",
+ "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==",
+ "dev": true,
+ "dependencies": {
+ "tslib": "^2.0.3"
+ }
+ },
+ "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,
+ "dependencies": {
+ "yallist": "^3.0.2"
+ }
+ },
+ "node_modules/magic-string": {
+ "version": "0.30.21",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz",
+ "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==",
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.5.5"
+ }
+ },
+ "node_modules/math-intrinsics": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
+ "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/mime-db": {
+ "version": "1.52.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+ "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mime-types": {
+ "version": "2.1.35",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+ "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+ "license": "MIT",
+ "dependencies": {
+ "mime-db": "1.52.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "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
+ },
+ "node_modules/nanoid": {
+ "version": "3.3.11",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
+ "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
+ },
+ "engines": {
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ }
+ },
+ "node_modules/natural-compare": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
+ "dev": true
+ },
+ "node_modules/no-case": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz",
+ "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==",
+ "dev": true,
+ "dependencies": {
+ "lower-case": "^2.0.2",
+ "tslib": "^2.0.3"
+ }
+ },
+ "node_modules/node-releases": {
+ "version": "2.0.27",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz",
+ "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==",
+ "dev": true
+ },
+ "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.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/optionator": {
+ "version": "0.9.4",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
+ "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==",
+ "dev": true,
+ "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,
+ "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,
+ "dependencies": {
+ "p-limit": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/parent-module": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
+ "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+ "dev": true,
+ "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,
+ "dependencies": {
+ "@babel/code-frame": "^7.0.0",
+ "error-ex": "^1.3.1",
+ "json-parse-even-better-errors": "^2.3.0",
+ "lines-and-columns": "^1.1.6"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true,
+ "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,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-type": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
+ "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/picocolors": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="
+ },
+ "node_modules/picomatch": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
+ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
+ "peer": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "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.6",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz",
+ "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==",
+ "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"
+ }
+ ],
+ "dependencies": {
+ "nanoid": "^3.3.11",
+ "picocolors": "^1.1.1",
+ "source-map-js": "^1.2.1"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ }
+ },
+ "node_modules/prelude-ls": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
+ "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/prettier": {
+ "version": "3.7.4",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.7.4.tgz",
+ "integrity": "sha512-v6UNi1+3hSlVvv8fSaoUbggEM5VErKmmpGA7Pl3HF8V6uKY7rvClBOJlH6yNwQtfTueNkGVpOv/mtWL9L4bgRA==",
+ "dev": true,
+ "bin": {
+ "prettier": "bin/prettier.cjs"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/prettier/prettier?sponsor=1"
+ }
+ },
+ "node_modules/proxy-from-env": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
+ "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
+ "license": "MIT"
+ },
+ "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,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/react": {
+ "version": "18.2.0",
+ "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz",
+ "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==",
+ "peer": true,
+ "dependencies": {
+ "loose-envify": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/react-dom": {
+ "version": "18.2.0",
+ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz",
+ "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==",
+ "peer": true,
+ "dependencies": {
+ "loose-envify": "^1.1.0",
+ "scheduler": "^0.23.0"
+ },
+ "peerDependencies": {
+ "react": "^18.2.0"
+ }
+ },
+ "node_modules/react-property": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/react-property/-/react-property-2.0.2.tgz",
+ "integrity": "sha512-+PbtI3VuDV0l6CleQMsx2gtK0JZbZKbpdu5ynr+lbsuvtmgbNcS3VM0tuY2QjFNOcWxvXeHjDpy42RO+4U2rug==",
+ "license": "MIT"
+ },
+ "node_modules/react-router": {
+ "version": "6.30.3",
+ "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.30.3.tgz",
+ "integrity": "sha512-XRnlbKMTmktBkjCLE8/XcZFlnHvr2Ltdr1eJX4idL55/9BbORzyZEaIkBFDhFGCEWBBItsVrDxwx3gnisMitdw==",
+ "license": "MIT",
+ "dependencies": {
+ "@remix-run/router": "1.23.2"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.8"
+ }
+ },
+ "node_modules/react-router-dom": {
+ "version": "6.30.3",
+ "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.30.3.tgz",
+ "integrity": "sha512-pxPcv1AczD4vso7G4Z3TKcvlxK7g7TNt3/FNGMhfqyntocvYKj+GCatfigGDjbLozC4baguJ0ReCigoDJXb0ag==",
+ "license": "MIT",
+ "dependencies": {
+ "@remix-run/router": "1.23.2",
+ "react-router": "6.30.3"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.8",
+ "react-dom": ">=16.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/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/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,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/rollup": {
+ "version": "4.54.0",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.54.0.tgz",
+ "integrity": "sha512-3nk8Y3a9Ea8szgKhinMlGMhGMw89mqule3KWczxhIzqudyHdCIOHw8WJlj/r329fACjKLEh13ZSk7oE22kyeIw==",
+ "dependencies": {
+ "@types/estree": "1.0.8"
+ },
+ "bin": {
+ "rollup": "dist/bin/rollup"
+ },
+ "engines": {
+ "node": ">=18.0.0",
+ "npm": ">=8.0.0"
+ },
+ "optionalDependencies": {
+ "@rollup/rollup-android-arm-eabi": "4.54.0",
+ "@rollup/rollup-android-arm64": "4.54.0",
+ "@rollup/rollup-darwin-arm64": "4.54.0",
+ "@rollup/rollup-darwin-x64": "4.54.0",
+ "@rollup/rollup-freebsd-arm64": "4.54.0",
+ "@rollup/rollup-freebsd-x64": "4.54.0",
+ "@rollup/rollup-linux-arm-gnueabihf": "4.54.0",
+ "@rollup/rollup-linux-arm-musleabihf": "4.54.0",
+ "@rollup/rollup-linux-arm64-gnu": "4.54.0",
+ "@rollup/rollup-linux-arm64-musl": "4.54.0",
+ "@rollup/rollup-linux-loong64-gnu": "4.54.0",
+ "@rollup/rollup-linux-ppc64-gnu": "4.54.0",
+ "@rollup/rollup-linux-riscv64-gnu": "4.54.0",
+ "@rollup/rollup-linux-riscv64-musl": "4.54.0",
+ "@rollup/rollup-linux-s390x-gnu": "4.54.0",
+ "@rollup/rollup-linux-x64-gnu": "4.54.0",
+ "@rollup/rollup-linux-x64-musl": "4.54.0",
+ "@rollup/rollup-openharmony-arm64": "4.54.0",
+ "@rollup/rollup-win32-arm64-msvc": "4.54.0",
+ "@rollup/rollup-win32-ia32-msvc": "4.54.0",
+ "@rollup/rollup-win32-x64-gnu": "4.54.0",
+ "@rollup/rollup-win32-x64-msvc": "4.54.0",
+ "fsevents": "~2.3.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/scheduler": {
+ "version": "0.23.2",
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz",
+ "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==",
+ "dependencies": {
+ "loose-envify": "^1.1.0"
+ }
+ },
+ "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,
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "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,
+ "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,
+ "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/snake-case": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz",
+ "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==",
+ "dev": true,
+ "dependencies": {
+ "dot-case": "^3.0.4",
+ "tslib": "^2.0.3"
+ }
+ },
+ "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==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/stop-iteration-iterator": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz",
+ "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "internal-slot": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "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-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,
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/style-to-js": {
+ "version": "1.1.21",
+ "resolved": "https://registry.npmjs.org/style-to-js/-/style-to-js-1.1.21.tgz",
+ "integrity": "sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ==",
+ "license": "MIT",
+ "dependencies": {
+ "style-to-object": "1.0.14"
+ }
+ },
+ "node_modules/style-to-object": {
+ "version": "1.0.14",
+ "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.14.tgz",
+ "integrity": "sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw==",
+ "license": "MIT",
+ "dependencies": {
+ "inline-style-parser": "0.2.7"
+ }
+ },
+ "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,
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/svg-parser": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz",
+ "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==",
+ "dev": true
+ },
+ "node_modules/tailwindcss": {
+ "version": "4.1.18",
+ "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.18.tgz",
+ "integrity": "sha512-4+Z+0yiYyEtUVCScyfHCxOYP06L5Ne+JiHhY2IjR2KWMIWhJOYZKLSGZaP5HkZ8+bY0cxfzwDE5uOmzFXyIwxw=="
+ },
+ "node_modules/tapable": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz",
+ "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==",
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ }
+ },
+ "node_modules/tinyglobby": {
+ "version": "0.2.15",
+ "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz",
+ "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==",
+ "dependencies": {
+ "fdir": "^6.5.0",
+ "picomatch": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/SuperchupuDev"
+ }
+ },
+ "node_modules/ts-api-utils": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.3.0.tgz",
+ "integrity": "sha512-6eg3Y9SF7SsAvGzRHQvvc1skDAhwI4YQ32ui1scxD1Ccr0G5qIIbUBT3pFTKX8kmWIQClHobtUdNuaBgwdfdWg==",
+ "dev": true,
+ "engines": {
+ "node": ">=18.12"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.8.4"
+ }
+ },
+ "node_modules/tslib": {
+ "version": "2.8.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
+ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
+ "devOptional": true
+ },
+ "node_modules/type-check": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
+ "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
+ "dev": true,
+ "dependencies": {
+ "prelude-ls": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "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.9.3",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
+ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
+ "dev": true,
+ "peer": true,
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=14.17"
+ }
+ },
+ "node_modules/typescript-eslint": {
+ "version": "8.51.0",
+ "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.51.0.tgz",
+ "integrity": "sha512-jh8ZuM5oEh2PSdyQG9YAEM1TCGuWenLSuSUhf/irbVUNW9O5FhbFVONviN2TgMTBnUmyHv7E56rYnfLZK6TkiA==",
+ "dev": true,
+ "dependencies": {
+ "@typescript-eslint/eslint-plugin": "8.51.0",
+ "@typescript-eslint/parser": "8.51.0",
+ "@typescript-eslint/typescript-estree": "8.51.0",
+ "@typescript-eslint/utils": "8.51.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 <6.0.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": "7.16.0",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz",
+ "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==",
+ "devOptional": true
+ },
+ "node_modules/update-browserslist-db": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz",
+ "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "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,
+ "dependencies": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "node_modules/vite": {
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.0.tgz",
+ "integrity": "sha512-dZwN5L1VlUBewiP6H9s2+B3e3Jg96D0vzN+Ry73sOefebhYr9f94wwkMNN/9ouoU8pV1BqA1d1zGk8928cx0rg==",
+ "peer": true,
+ "dependencies": {
+ "esbuild": "^0.27.0",
+ "fdir": "^6.5.0",
+ "picomatch": "^4.0.3",
+ "postcss": "^8.5.6",
+ "rollup": "^4.43.0",
+ "tinyglobby": "^0.2.15"
+ },
+ "bin": {
+ "vite": "bin/vite.js"
+ },
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ },
+ "funding": {
+ "url": "https://github.com/vitejs/vite?sponsor=1"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.3"
+ },
+ "peerDependencies": {
+ "@types/node": "^20.19.0 || >=22.12.0",
+ "jiti": ">=1.21.0",
+ "less": "^4.0.0",
+ "lightningcss": "^1.21.0",
+ "sass": "^1.70.0",
+ "sass-embedded": "^1.70.0",
+ "stylus": ">=0.54.8",
+ "sugarss": "^5.0.0",
+ "terser": "^5.16.0",
+ "tsx": "^4.8.1",
+ "yaml": "^2.4.2"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ },
+ "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-plugin-svgr": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/vite-plugin-svgr/-/vite-plugin-svgr-4.5.0.tgz",
+ "integrity": "sha512-W+uoSpmVkSmNOGPSsDCWVW/DDAyv+9fap9AZXBvWiQqrboJ08j2vh0tFxTD/LjwqwAd3yYSVJgm54S/1GhbdnA==",
+ "dev": true,
+ "dependencies": {
+ "@rollup/pluginutils": "^5.2.0",
+ "@svgr/core": "^8.1.0",
+ "@svgr/plugin-jsx": "^8.1.0"
+ },
+ "peerDependencies": {
+ "vite": ">=2.6.0"
+ }
+ },
+ "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,
+ "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.20",
+ "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.20.tgz",
+ "integrity": "sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==",
+ "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/word-wrap": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz",
+ "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/yallist": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
+ "dev": true
+ },
+ "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,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/zod": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/zod/-/zod-4.3.4.tgz",
+ "integrity": "sha512-Zw/uYiiyF6pUT1qmKbZziChgNPRu+ZRneAsMUDU6IwmXdWt5JwcUfy2bvLOCUtz5UniaN/Zx5aFttZYbYc7O/A==",
+ "dev": true,
+ "peer": true,
+ "funding": {
+ "url": "https://github.com/sponsors/colinhacks"
+ }
+ },
+ "node_modules/zod-validation-error": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/zod-validation-error/-/zod-validation-error-4.0.2.tgz",
+ "integrity": "sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=18.0.0"
+ },
+ "peerDependencies": {
+ "zod": "^3.25.0 || ^4.0.0"
+ }
+ },
+ "node_modules/zustand": {
+ "version": "5.0.10",
+ "resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.10.tgz",
+ "integrity": "sha512-U1AiltS1O9hSy3rul+Ub82ut2fqIAefiSuwECWt6jlMVUGejvf+5omLcRBSzqbRagSM3hQZbtzdeRc6QVScXTg==",
+ "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/Mine/package.json b/Mine/package.json
new file mode 100644
index 0000000..513102e
--- /dev/null
+++ b/Mine/package.json
@@ -0,0 +1,41 @@
+{
+ "name": "mine",
+ "private": true,
+ "version": "0.0.0",
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "tsc -b && vite build",
+ "lint": "eslint .",
+ "preview": "vite preview",
+ "svgr": "npx @svgr/cli -d src/assets/svg --ignore-existing --typescript --no-dimensions public/svg"
+ },
+ "dependencies": {
+ "@tailwindcss/vite": "^4.1.17",
+ "@tanstack/react-query": "^5.90.19",
+ "@vitejs/plugin-react-swc": "^4.2.1",
+ "axios": "^1.13.2",
+ "html-react-parser": "^5.2.16",
+ "react": "^18.2.0",
+ "react-dom": "^18.2.0",
+ "react-router-dom": "^6.30.2",
+ "tailwindcss": "^4.1.17",
+ "typescript": "~5.9.3",
+ "vite": "^7.2.2",
+ "vite-plugin-svgr": "^4.5.0",
+ "zustand": "^5.0.10"
+ },
+ "devDependencies": {
+ "@eslint/js": "^9.39.1",
+ "@types/node": "^24.10.0",
+ "@types/react": "^18.3.27",
+ "@types/react-dom": "^18.3.7",
+ "eslint": "^9.39.1",
+ "eslint-plugin-jsx-a11y": "^6.10.2",
+ "eslint-plugin-react-hooks": "^7.0.1",
+ "eslint-plugin-react-refresh": "^0.4.24",
+ "globals": "^16.5.0",
+ "prettier": "^3.6.2",
+ "typescript-eslint": "^8.46.3"
+ }
+}
\ No newline at end of file
diff --git a/Mine/public/fonts/NotoSerifKR-Medium.ttf b/Mine/public/fonts/NotoSerifKR-Medium.ttf
new file mode 100644
index 0000000..74dca59
Binary files /dev/null and b/Mine/public/fonts/NotoSerifKR-Medium.ttf differ
diff --git a/Mine/public/fonts/NotoSerifKR-SemiBold.ttf b/Mine/public/fonts/NotoSerifKR-SemiBold.ttf
new file mode 100644
index 0000000..095971f
Binary files /dev/null and b/Mine/public/fonts/NotoSerifKR-SemiBold.ttf differ
diff --git a/Mine/public/fonts/Pretendard-Bold.woff2 b/Mine/public/fonts/Pretendard-Bold.woff2
new file mode 100644
index 0000000..4d40a1a
Binary files /dev/null and b/Mine/public/fonts/Pretendard-Bold.woff2 differ
diff --git a/Mine/public/fonts/Pretendard-Light.woff2 b/Mine/public/fonts/Pretendard-Light.woff2
new file mode 100644
index 0000000..7f82fe8
Binary files /dev/null and b/Mine/public/fonts/Pretendard-Light.woff2 differ
diff --git a/Mine/public/fonts/Pretendard-Medium.woff2 b/Mine/public/fonts/Pretendard-Medium.woff2
new file mode 100644
index 0000000..f8c743d
Binary files /dev/null and b/Mine/public/fonts/Pretendard-Medium.woff2 differ
diff --git a/Mine/public/fonts/Pretendard-Regular.woff2 b/Mine/public/fonts/Pretendard-Regular.woff2
new file mode 100644
index 0000000..a9f6231
Binary files /dev/null and b/Mine/public/fonts/Pretendard-Regular.woff2 differ
diff --git a/Mine/public/fonts/Pretendard-SemiBold.woff2 b/Mine/public/fonts/Pretendard-SemiBold.woff2
new file mode 100644
index 0000000..4c6a32d
Binary files /dev/null and b/Mine/public/fonts/Pretendard-SemiBold.woff2 differ
diff --git a/Mine/src/App.tsx b/Mine/src/App.tsx
new file mode 100644
index 0000000..9c2d416
--- /dev/null
+++ b/Mine/src/App.tsx
@@ -0,0 +1,13 @@
+import { RouterProvider } from 'react-router-dom'
+import { router } from './router/router'
+
+
+function App() {
+ return (
+ <>
+
+ >
+ )
+}
+
+export default App
diff --git a/Mine/src/api/auth.ts b/Mine/src/api/auth.ts
new file mode 100644
index 0000000..b25b5a6
--- /dev/null
+++ b/Mine/src/api/auth.ts
@@ -0,0 +1,28 @@
+import type { AuthorizationDto, ResponseAuthorization, SignupDto } from '../types/user'
+import { axiosInstance } from './axios'
+
+export const postAuthorization = async ({ username, password }: AuthorizationDto): Promise => {
+ const body = {
+ username: username,
+ password: password,
+ }
+ const { data } = await axiosInstance.post('/api/auth/login', body)
+ return data
+}
+
+export const postLogout = async () => {
+ const { data } = await axiosInstance.post('api/auth/logout')
+ return data
+}
+
+export const postSignup = async ({ username, email, password, nickname, interests }: SignupDto) => {
+ const body = {
+ username: username,
+ email: email,
+ password: password,
+ nickname: nickname,
+ interests: interests,
+ }
+ const { data } = await axiosInstance.post('/api/auth/signup', body)
+ return data
+}
diff --git a/Mine/src/api/axios.ts b/Mine/src/api/axios.ts
new file mode 100644
index 0000000..8427911
--- /dev/null
+++ b/Mine/src/api/axios.ts
@@ -0,0 +1,55 @@
+import axios from 'axios'
+
+export const axiosInstance = axios.create({
+ baseURL: import.meta.env.VITE_API_BASE_URL,
+})
+
+axiosInstance.interceptors.request.use(
+ (config) => {
+ const token = localStorage.getItem('accessToken')
+ if (token) {
+ // ๋ชจ๋ ์์ฒญ ํค๋์ Authorization ์ถ๊ฐ
+ config.headers.Authorization = `Bearer ${token}`
+ }
+ return config
+ },
+ (error) => {
+ return Promise.reject(error)
+ }
+)
+
+axiosInstance.interceptors.response.use(
+ (response) => response, // ์ฑ๊ณต ์ ๊ทธ๋๋ก ๋ฐํ
+ async (error) => {
+ const originalRequest = error.config
+
+ // 401 ์๋ฌ(๋ง๋ฃ)์ด๊ณ , ์ด๋ฏธ ์ฌ์๋ํ ์์ฒญ์ด ์๋ ๋ ์คํ
+ if (error.response?.status === 401 && !originalRequest._retry) {
+ originalRequest._retry = true
+
+ try {
+ const refreshToken = localStorage.getItem('refreshToken')
+
+ // ์ค์จ๊ฑฐ์ ๋์จ ํ์๋๋ก ๋ฆฌํ๋ ์ ์์ฒญ ๋ณด๋
+ const { data } = await axios.post(`${import.meta.env.VITE_API_BASE_URL}/api/auth/refresh`, {
+ refreshToken: refreshToken,
+ })
+
+ // ์ ํ ํฐ ์ ์ฅ
+ localStorage.setItem('accessToken', data.accessToken)
+ localStorage.setItem('refreshToken', data.refreshToken)
+
+ // ์คํจํ๋ ์๋ ์์ฒญ์ ํค๋๋ฅผ ์ ํ ํฐ์ผ๋ก ๊ต์ฒด ํ ์ฌ์๋
+ originalRequest.headers.Authorization = `Bearer ${data.accessToken}`
+ return axiosInstance(originalRequest)
+ } catch (refreshError) {
+ // ๋ฆฌํ๋ ์ ํ ํฐ๋ง์ ๋ง๋ฃ๋ ๊ฒฝ์ฐ ๋ก๊ทธ์์ ์ฒ๋ฆฌ
+ localStorage.clear()
+ window.location.href = '/login'
+ alert('๋ก๊ทธ์ธ์ด ๋ง๋ฃ๋์์ต๋๋ค')
+ return Promise.reject(refreshError)
+ }
+ }
+ return Promise.reject(error)
+ }
+)
diff --git a/Mine/src/api/image.ts b/Mine/src/api/image.ts
new file mode 100644
index 0000000..e696cf3
--- /dev/null
+++ b/Mine/src/api/image.ts
@@ -0,0 +1,8 @@
+import { axiosInstance } from './axios'
+
+export const uploadImage = async (file: File): Promise => {
+ const formData = new FormData()
+ formData.append('file', file)
+ const res = await axiosInstance.post('api/images', formData)
+ return res.data
+}
\ No newline at end of file
diff --git a/Mine/src/api/interest.ts b/Mine/src/api/interest.ts
new file mode 100644
index 0000000..46b8e0a
--- /dev/null
+++ b/Mine/src/api/interest.ts
@@ -0,0 +1,6 @@
+import { axiosInstance } from './axios'
+
+export const putInterests = async (interests: string[]) => {
+ const res = await axiosInstance.put('api/interests/me', { interests })
+ return res.data
+}
\ No newline at end of file
diff --git a/Mine/src/api/magazine.ts b/Mine/src/api/magazine.ts
new file mode 100644
index 0000000..325764d
--- /dev/null
+++ b/Mine/src/api/magazine.ts
@@ -0,0 +1,94 @@
+import type {
+ DeleteParagraphDto,
+ DeleteSectionDto,
+ FeedDto,
+ PatchMagazineTitleDto,
+ PostMagazineDto,
+ RequestDeleteMagazine,
+ ResponseFeed,
+ ResponseRecentSection,
+ SectionDetailDto,
+} from '../types/magazine'
+import type { MyMagazinesDto, ResponseMyMagazine } from '../types/magazine'
+import { axiosInstance } from './axios'
+
+export const getMyMagazineList = async ({ page, size, sort }: MyMagazinesDto): Promise => {
+ const res = await axiosInstance.get(`api/magazines`, {
+ params: { page, size, sort },
+ })
+ return res.data
+}
+
+export const deleteMagazine = async ({ id }: RequestDeleteMagazine) => {
+ const res = await axiosInstance.delete(`api/magazines/${id}`)
+ return res.data
+}
+
+export const postMagazine = async ({ topic, user_mood }: PostMagazineDto) => {
+ const body = {
+ topic: topic,
+ user_mood: user_mood,
+ }
+ const res = await axiosInstance.post('api/magazines', body)
+ return res.data
+}
+
+export const patchMagazineTitle = async ({ id, title, introduction }: PatchMagazineTitleDto) => {
+ const body = {
+ title: title,
+ introduction: introduction,
+ }
+ const res = await axiosInstance.patch(`api/magazines/${id}`, body)
+ return res.data
+}
+
+export const getRecentSection = async (): Promise => {
+ const res = await axiosInstance.get(`api/sections/recent`)
+ return res.data
+}
+
+export const getSectionDetail = async ({ magazineId, sectionId }: SectionDetailDto) => {
+ const res = await axiosInstance.get(`api/magazines/${magazineId}/sections/${sectionId}`)
+ return res.data
+}
+
+export const getMagazineDetail = async (magazineId: number) => {
+ const res = await axiosInstance.get(`api/magazines/${magazineId}`)
+ return res.data
+}
+
+export const getLikedMagazineList = async ({ page, size, sort }: MyMagazinesDto): Promise => {
+ const res = await axiosInstance.get(`api/magazines/liked`, {
+ params: { page, size, sort },
+ })
+ return res.data
+}
+
+export const deleteSection = async ({ magazineId, sectionId }: DeleteSectionDto) => {
+ const res = await axiosInstance.delete(`api/magazines/${magazineId}/sections/${sectionId}`)
+ return res.data
+}
+
+export const postHeart = async (id: number) => {
+ const res = await axiosInstance.post(`api/magazines/${id}/likes`)
+ return res.data
+}
+
+export const deleteParagraph = async ({ magazineId, sectionId, paragraphId }: DeleteParagraphDto) => {
+ const res = await axiosInstance.delete(
+ `api/magazines/${magazineId}/sections/${sectionId}/paragraphs/${paragraphId}`
+ )
+ return res.data
+}
+
+export const getMagazineFeed = async ({ cursorId, limit = 10 }: FeedDto): Promise => {
+ const res = await axiosInstance.get(`api/magazines/feed`, {
+ params: { cursorId, limit },
+ })
+ return res.data
+}
+
+export const createMoodboard = async (magazineId: number) => {
+ const res = await axiosInstance.post(`api/magazines/${magazineId}/moodboards`)
+ return res.data
+}
\ No newline at end of file
diff --git a/Mine/src/api/user.ts b/Mine/src/api/user.ts
new file mode 100644
index 0000000..5a096a9
--- /dev/null
+++ b/Mine/src/api/user.ts
@@ -0,0 +1,25 @@
+import type { ProfileDto, ResponseProfile } from '../types/user'
+import { axiosInstance } from './axios'
+
+export const getMyProfile = async (): Promise => {
+ const res = await axiosInstance.get(`/api/users/me`)
+ return res.data
+}
+
+export const patchMyProfile = async (profileData: ProfileDto): Promise => {
+ const formData = new FormData()
+
+ formData.append('nickname', profileData.nickname)
+ formData.append('username', profileData.username)
+
+ if (profileData.profileImage instanceof File) {
+ formData.append('profileImage', profileData.profileImage)
+ }
+ const res = await axiosInstance.patch(`api/users/me`, formData)
+ return res.data
+}
+
+export const patchVisibility = async (isPublic: boolean) => {
+ const res = await axiosInstance.patch(`api/users/me/visibility`, { isPublic })
+ return res.data
+}
diff --git a/Mine/src/assets/bg1.jpg b/Mine/src/assets/bg1.jpg
new file mode 100644
index 0000000..42b3d9a
Binary files /dev/null and b/Mine/src/assets/bg1.jpg differ
diff --git a/Mine/src/assets/bg2.jpg b/Mine/src/assets/bg2.jpg
new file mode 100644
index 0000000..076321d
Binary files /dev/null and b/Mine/src/assets/bg2.jpg differ
diff --git a/Mine/src/assets/lookaround1.jpg b/Mine/src/assets/lookaround1.jpg
new file mode 100644
index 0000000..ea3e3a6
Binary files /dev/null and b/Mine/src/assets/lookaround1.jpg differ
diff --git a/Mine/src/assets/lookaround2.jpg b/Mine/src/assets/lookaround2.jpg
new file mode 100644
index 0000000..4099c65
Binary files /dev/null and b/Mine/src/assets/lookaround2.jpg differ
diff --git a/Mine/src/assets/lookaround3.jpg b/Mine/src/assets/lookaround3.jpg
new file mode 100644
index 0000000..1e93b25
Binary files /dev/null and b/Mine/src/assets/lookaround3.jpg differ
diff --git a/Mine/src/assets/lookaround4.jpg b/Mine/src/assets/lookaround4.jpg
new file mode 100644
index 0000000..775a589
Binary files /dev/null and b/Mine/src/assets/lookaround4.jpg differ
diff --git a/Mine/src/assets/lookaround5.jpg b/Mine/src/assets/lookaround5.jpg
new file mode 100644
index 0000000..ba32942
Binary files /dev/null and b/Mine/src/assets/lookaround5.jpg differ
diff --git a/Mine/src/assets/lookaround6.jpg b/Mine/src/assets/lookaround6.jpg
new file mode 100644
index 0000000..f572b5e
Binary files /dev/null and b/Mine/src/assets/lookaround6.jpg differ
diff --git a/Mine/src/components/ButtonwithText.tsx b/Mine/src/components/ButtonwithText.tsx
new file mode 100644
index 0000000..18a8601
--- /dev/null
+++ b/Mine/src/components/ButtonwithText.tsx
@@ -0,0 +1,23 @@
+interface ButtonProps {
+ title: string
+ size?: string
+ variant?: ButtonVariant
+ onclick?: () => void
+}
+
+type ButtonVariant = 'main' | 'white'
+
+export default function ButtonwithText({ title, size, variant = 'main', onclick }: ButtonProps) {
+ const VARIANT_CLASS: Record = {
+ main: 'bg-main-default text-white hover:bg-main-emphasis',
+ white: 'border border-main-default bg-white text-main-default hover:bg-main-opacity20',
+ }
+ return (
+
+ )
+}
diff --git a/Mine/src/components/EmailInputBox.tsx b/Mine/src/components/EmailInputBox.tsx
new file mode 100644
index 0000000..67f1ec0
--- /dev/null
+++ b/Mine/src/components/EmailInputBox.tsx
@@ -0,0 +1,44 @@
+import Vector from '../icon/vector.svg?react'
+
+interface EmailInputBoxProps {
+ id: string
+ title?: string
+ placeholder?: string
+ description?: string
+ domains?: string[]
+}
+
+export default function EmailInputBox({
+ id,
+ title,
+ placeholder = 'ex) abc123',
+ description,
+ domains = ['gmail.com', 'naver.com', 'daum.net'],
+}: EmailInputBoxProps) {
+ return (
+
+ {title &&
{title}
}
+
+
+
@
+
+
+
+
+
+
+ {description &&
{description}
}
+
+ )
+}
diff --git a/Mine/src/components/InputBox.tsx b/Mine/src/components/InputBox.tsx
new file mode 100644
index 0000000..11150a3
--- /dev/null
+++ b/Mine/src/components/InputBox.tsx
@@ -0,0 +1,33 @@
+import type { ChangeEvent, ReactNode } from 'react'
+
+interface InputBoxProps {
+ id: string
+ title?: string
+ placeholder?: string
+ description?: string
+ children?: ReactNode
+ value?: string
+ onChange?: (e: ChangeEvent) => void
+}
+
+export default function InputBox({ id, placeholder, title, description, children, value, onChange }: InputBoxProps) {
+ return (
+
+ {title &&
{title}
}
+
+ {children}
+
+
+
+ {description &&
{description}
}
+
+ )
+}
diff --git a/Mine/src/components/InputBoxWithPassword.tsx b/Mine/src/components/InputBoxWithPassword.tsx
new file mode 100644
index 0000000..57c4bdd
--- /dev/null
+++ b/Mine/src/components/InputBoxWithPassword.tsx
@@ -0,0 +1,44 @@
+import type { ChangeEvent, ReactNode } from 'react'
+// import Eye from '../icon/eye.svg?react'
+import EyeOff from '../icon/eyeoff.svg?react'
+
+interface InputBoxProps {
+ id: string
+ value?: string
+ title?: string
+ placeholder?: string
+ description?: string
+ children?: ReactNode
+ onChange?: (e: ChangeEvent) => void
+}
+export default function InputBoxWithPassword({
+ id,
+ value,
+ title,
+ placeholder,
+ description,
+ children,
+ onChange,
+}: InputBoxProps) {
+ return (
+ <>
+
+ {title &&
{title}
}
+
+ {children}
+
+
+
+
{description}
+
+ >
+ )
+}
diff --git a/Mine/src/components/LLMInputBox.tsx b/Mine/src/components/LLMInputBox.tsx
new file mode 100644
index 0000000..d349dde
--- /dev/null
+++ b/Mine/src/components/LLMInputBox.tsx
@@ -0,0 +1,71 @@
+import React, { useState, useRef, useEffect } from 'react'
+import Arrow from '../icon/arrow.svg?react'
+interface LLMInputBoxProps {
+ placeholder?: string
+ onSend?: (value: string) => void
+}
+
+export default function LLMInputBox({ onSend }: LLMInputBoxProps) {
+ const [text, setText] = useState('')
+ const [isFocused, setIsFocused] = useState(false)
+ const textareaRef = useRef(null)
+
+ const [isExpanded, setIsExpanded] = useState(false)
+
+ useEffect(() => {
+ if (textareaRef.current) {
+ textareaRef.current.style.height = 'auto'
+ const scrollHeight = textareaRef.current.scrollHeight
+
+ const expanded = scrollHeight > 30
+ setIsExpanded(expanded)
+
+ textareaRef.current.style.height = `${Math.min(scrollHeight, 104)}px`
+ }
+ }, [text])
+
+ const handleSend = () => {
+ if (text.trim() && onSend) {
+ onSend(text)
+ setText('')
+ }
+ }
+
+ const handleKeyDown = (e: React.KeyboardEvent) => {
+ if (e.key === 'Enter' && !e.shiftKey) {
+ e.preventDefault()
+ handleSend()
+ }
+ }
+
+ return (
+
+ )
+}
diff --git a/Mine/src/components/LLMInputLayout.tsx b/Mine/src/components/LLMInputLayout.tsx
new file mode 100644
index 0000000..dc9f5df
--- /dev/null
+++ b/Mine/src/components/LLMInputLayout.tsx
@@ -0,0 +1,16 @@
+import { useLocation } from 'react-router-dom'
+import LLMInputBox from './LLMInputBox'
+
+export default function LLMInputLayout() {
+ const location = useLocation()
+ const hiddenPath = ['/login', '/signup', '/landing', '/']
+ const isHiddenPath = hiddenPath.includes(location.pathname)
+
+ if (!isHiddenPath)
+ return (
+
+
+
+ )
+ return null
+}
diff --git a/Mine/src/components/NewMagazineInput.tsx b/Mine/src/components/NewMagazineInput.tsx
new file mode 100644
index 0000000..998c3a6
--- /dev/null
+++ b/Mine/src/components/NewMagazineInput.tsx
@@ -0,0 +1,66 @@
+import { type KeyboardEvent } from 'react'
+
+interface MagazineInputProps {
+ topic: string
+ userMood: string
+ onTopicChange: (value: string) => void
+ onUserMoodChange: (value: string) => void
+ onSubmit: () => void
+}
+
+export default function NewMagazineInput({
+ topic,
+ userMood,
+ onTopicChange,
+ onUserMoodChange,
+ onSubmit,
+}: MagazineInputProps) {
+ const isTopicValid = Boolean(topic.trim())
+ const handleKeyDown = (e: KeyboardEvent) => {
+ if (e.key === 'Enter' && !e.shiftKey) {
+ e.preventDefault()
+ onSubmit()
+ }
+ }
+
+ return (
+
+
+
+ ์ฃผ์
+ onTopicChange(e.target.value)}
+ onKeyDown={handleKeyDown}
+ placeholder="๊ด์ฌ์๋ ์ฃผ์ ๋ฅผ ์
๋ ฅํด ์ฃผ์ธ์."
+ className="w-full bg-transparent font-regular16 text-gray-100 outline-none placeholder-gray-100/40"
+ />
+
+
+
+
+
+ ๋ถ์๊ธฐ
+ onUserMoodChange(e.target.value)}
+ onKeyDown={handleKeyDown}
+ placeholder="์ํ๋ ๋ถ์๊ธฐ๋ฅผ ์
๋ ฅํด ์ฃผ์ธ์."
+ className="w-full bg-transparent font-regular16 text-gray-100 outline-none placeholder-gray-100/40"
+ />
+
+
+
+
+ )
+}
diff --git a/Mine/src/components/common/ConfirmModal.tsx b/Mine/src/components/common/ConfirmModal.tsx
new file mode 100644
index 0000000..7684373
--- /dev/null
+++ b/Mine/src/components/common/ConfirmModal.tsx
@@ -0,0 +1,51 @@
+interface ConfirmModalProps {
+ title: string
+ description?: string
+ confirmText?: string
+ cancelText?: string
+ onConfirm: () => void
+ onCancel: () => void
+ isLoading?: boolean
+}
+
+export default function ConfirmModal({
+ title,
+ description,
+ confirmText = '์',
+ cancelText = '์๋์',
+ onConfirm,
+ onCancel,
+ isLoading = false,
+}: ConfirmModalProps) {
+ return (
+
+
+
+
+
{title}
+ {description && (
+
+ {description}
+
+ )}
+
+
+
+
+
+
+
+
+ )
+}
\ No newline at end of file
diff --git a/Mine/src/components/common/Toast.tsx b/Mine/src/components/common/Toast.tsx
new file mode 100644
index 0000000..a3efc79
--- /dev/null
+++ b/Mine/src/components/common/Toast.tsx
@@ -0,0 +1,14 @@
+import Check from '../../icon/check.svg?react'
+
+interface ToastProps {
+ message: string
+}
+
+export default function Toast({ message }: ToastProps) {
+ return (
+
+
+ {message}
+
+ )
+}
\ No newline at end of file
diff --git a/Mine/src/components/hamburgerModal/HamburgerSection.tsx b/Mine/src/components/hamburgerModal/HamburgerSection.tsx
new file mode 100644
index 0000000..817e1c7
--- /dev/null
+++ b/Mine/src/components/hamburgerModal/HamburgerSection.tsx
@@ -0,0 +1,16 @@
+interface HamburgerSectionProps {
+ icon: React.ReactNode
+ title: string
+ onClick?: React.MouseEventHandler
+}
+export function HamburgerSection({ icon, title, onClick }: HamburgerSectionProps) {
+ return (
+
+ {icon}
+ {title}
+
+ )
+}
diff --git a/Mine/src/components/hamburgerModal/ParagraphHamburgerModal.tsx b/Mine/src/components/hamburgerModal/ParagraphHamburgerModal.tsx
new file mode 100644
index 0000000..491cbd8
--- /dev/null
+++ b/Mine/src/components/hamburgerModal/ParagraphHamburgerModal.tsx
@@ -0,0 +1,45 @@
+import Edit from '../../icon/edit.svg?react'
+import Delete from '../../icon/delete.svg?react'
+import { HamburgerSection } from './HamburgerSection'
+import useDeleteParagraph from '../../hooks/useDeleteParagraph'
+
+interface ParagraphHamburgerModalProps {
+ top: number
+ left: number
+ sectionId?: number
+ magazineId?: number
+ paragraphId?: number
+ children?: React.ReactNode
+ handleClose: () => void
+ // onEdit: (id?: number) => void
+}
+
+export default function ParagraphHamburgerModal({
+ paragraphId,
+ sectionId,
+ magazineId,
+ top,
+ left,
+ handleClose,
+}: ParagraphHamburgerModalProps) {
+ const deleteParagraphMutation = useDeleteParagraph()
+ const onDeleteClick: React.MouseEventHandler = () => {
+ deleteParagraphMutation.mutate({
+ magazineId: Number(magazineId),
+ sectionId: Number(sectionId),
+ paragraphId: Number(paragraphId),
+ })
+ handleClose()
+ }
+
+ return (
+
+ } />
+ } onClick={onDeleteClick} />
+
+ )
+}
diff --git a/Mine/src/components/hamburgerModal/SectionHamburgerModal.tsx b/Mine/src/components/hamburgerModal/SectionHamburgerModal.tsx
new file mode 100644
index 0000000..491a53f
--- /dev/null
+++ b/Mine/src/components/hamburgerModal/SectionHamburgerModal.tsx
@@ -0,0 +1,44 @@
+import Edit from '../../icon/edit.svg?react'
+import Share from '../../icon/share.svg?react'
+import Delete from '../../icon/delete.svg?react'
+import { HamburgerSection } from './HamburgerSection'
+import useDeleteSection from '../../hooks/useDeleteSection'
+import { useState } from 'react'
+import ShareModal from './ShareModal'
+
+interface SectionHamburgerModalProps {
+ top: number
+ left: number
+ sectionId?: number
+ magazineId?: number
+ handleClose: () => void
+}
+
+export default function SectionHamburgerModal({ sectionId, magazineId, top, left, handleClose }: SectionHamburgerModalProps) {
+ const deleteSectionMutation = useDeleteSection()
+ const [showShareModal, setShowShareModal] = useState(false)
+
+ const onDeleteClick: React.MouseEventHandler = () => {
+ deleteSectionMutation.mutate({ magazineId: Number(magazineId), sectionId: Number(sectionId) })
+ handleClose()
+ }
+
+ return (
+ <>
+ {!showShareModal && (
+
+ } onClick={() => setShowShareModal(true)} />
+ } />
+ } onClick={onDeleteClick} />
+
+ )}
+
+ {showShareModal && (
+
+ )}
+ >
+ )
+}
\ No newline at end of file
diff --git a/Mine/src/components/hamburgerModal/ShareModal.tsx b/Mine/src/components/hamburgerModal/ShareModal.tsx
new file mode 100644
index 0000000..d5b3885
--- /dev/null
+++ b/Mine/src/components/hamburgerModal/ShareModal.tsx
@@ -0,0 +1,72 @@
+import { useState } from 'react'
+import X from '../../icon/X.svg?react'
+import Link from '../../icon/link.svg?react'
+import Twit from '../../icon/twitter.svg?react'
+import Kakao from '../../icon/kakao.svg?react'
+import Instagram from '../../icon/instagram.svg?react'
+import Check from '../../icon/check.svg?react'
+
+const TOAST_MARGIN = 102
+const MODAL_HEIGHT = 212
+
+interface ShareModalProps {
+ onClose: () => void
+}
+
+export default function ShareModal({ onClose }: ShareModalProps) {
+ const [showToast, setShowToast] = useState(false)
+
+ const handleCopyLink = async () => {
+ try {
+ await navigator.clipboard.writeText(window.location.href)
+ setShowToast(true)
+ setTimeout(() => setShowToast(false), 2000)
+ } catch (err) {
+ console.error('๋งํฌ ๋ณต์ฌ์ ์คํจํ์ต๋๋ค:', err)
+ }
+ }
+
+ const buttons = [
+ { icon: , label: '๋งํฌ ๋ณต์ฌ', onClick: handleCopyLink },
+ { icon: , label: 'ํธ์ํฐ', onClick: () => {} },
+ { icon: , label: '์นด์นด์คํก', onClick: () => {} },
+ { icon: , label: '์ธ์คํ๊ทธ๋จ', onClick: () => {} },
+ ]
+
+ return (
+
+
+
+
+
๊ณต์
+
+
+ {buttons.map(({ icon, label, onClick }) => (
+
+ ))}
+
+
+
+ {showToast && (
+
+
+ ๋งํฌ๊ฐ ๋ณต์ฌ๋์์ต๋๋ค.
+
+ )}
+
+ )
+}
diff --git a/Mine/src/components/hamburgerModal/SidebarHamburgerModal.tsx b/Mine/src/components/hamburgerModal/SidebarHamburgerModal.tsx
new file mode 100644
index 0000000..59269af
--- /dev/null
+++ b/Mine/src/components/hamburgerModal/SidebarHamburgerModal.tsx
@@ -0,0 +1,36 @@
+import Share from '../../icon/share.svg?react'
+import Edit from '../../icon/edit.svg?react'
+import Delete from '../../icon/delete.svg?react'
+import useDeleteMagazine from '../../hooks/useDeleteMagazine'
+import { HamburgerSection } from './HamburgerSection'
+
+interface SidebarHamburgerModalProps {
+ top: number
+ left: number
+ id: number
+ handleClose: () => void
+ onEdit: (id: number) => void
+}
+
+export default function SidebarHamburgerModal({ id, top, left, handleClose, onEdit }: SidebarHamburgerModalProps) {
+ const deleteMutation = useDeleteMagazine()
+ const onDeleteClick: React.MouseEventHandler = () => {
+ deleteMutation.mutate({ id: id })
+ handleClose()
+ }
+ const onEditClick: React.MouseEventHandler = () => {
+ onEdit(id)
+ handleClose()
+ }
+ return (
+
+ } />
+ } onClick={onEditClick} />
+ } onClick={onDeleteClick} />
+
+ )
+}
diff --git a/Mine/src/components/settings/InterestSettings.tsx b/Mine/src/components/settings/InterestSettings.tsx
new file mode 100644
index 0000000..afd6a7f
--- /dev/null
+++ b/Mine/src/components/settings/InterestSettings.tsx
@@ -0,0 +1,42 @@
+import useGetInterests from '../../hooks/useGetInterests'
+
+const MAX_INTERESTS = 3
+
+interface Props {
+ interests: string[]
+ onChange: (interests: string[]) => void
+}
+
+export default function InterestSettings({ interests, onChange }: Props) {
+ const { data: categories, isLoading } = useGetInterests()
+
+ const toggleInterest = (code: string) => {
+ if (interests.includes(code)) {
+ onChange(interests.filter((i) => i !== code))
+ } else {
+ if (interests.length >= MAX_INTERESTS) return
+ onChange([...interests, code])
+ }
+ }
+
+ if (isLoading) return ๋ถ๋ฌ์ค๋ ์ค...
+
+ return (
+
+ {categories?.map((item) => (
+
toggleInterest(item.code)}
+ className={`cursor-pointer flex items-center justify-center px-3 py-1.5 rounded-full border font-semibold16 text-base transition-colors
+ ${
+ interests.includes(item.code)
+ ? 'bg-gray-100 text-gray-600'
+ : 'border-white/30 bg-transparent text-gray-100'
+ }`}
+ >
+ {item.name}
+
+ ))}
+
+ )
+}
diff --git a/Mine/src/components/settings/ProfileSettings.tsx b/Mine/src/components/settings/ProfileSettings.tsx
new file mode 100644
index 0000000..2b52ceb
--- /dev/null
+++ b/Mine/src/components/settings/ProfileSettings.tsx
@@ -0,0 +1,171 @@
+import { useEffect, useState, type RefObject } from 'react'
+import Camera from '../../icon/camera.svg?react'
+import useUserStore from '../../stores/user'
+import useUpdateProfile from '../../hooks/useUpdateProfile'
+import usePatchVisibility from '../../hooks/usePatchVisibility'
+import TabButton from '../../icon/tab_button.svg?react'
+
+interface ProfileData {
+ nickname: string
+ username: string
+ profileImageUrl: string
+ profileImage: File | null
+}
+
+interface ProfileSettingProps {
+ editMode: boolean
+ onCancelEdit: () => void
+ onSave: (data: ProfileData) => void
+ refCancel: RefObject
+ refSave: RefObject
+}
+
+export default function ProfileSettings({ editMode, onCancelEdit, onSave, refCancel, refSave }: ProfileSettingProps) {
+ const { user } = useUserStore()
+ const { mutateAsync: updateProfile } = useUpdateProfile()
+ const { mutate: patchVisibility } = usePatchVisibility()
+ const [saved, setSaved] = useState({
+ nickname: user?.nickname ?? '',
+ username: user?.username ?? '',
+ profileImageUrl: user?.profileImageUrl ?? '',
+ profileImage: null,
+ })
+ const [draft, setDraft] = useState(saved)
+ const [editingField, setEditingField] = useState(null)
+ const [isPublic, setIsPublic] = useState(false)
+
+ const handleToggleVisibility = () => {
+ const newValue = !isPublic
+ setIsPublic(newValue)
+ patchVisibility(newValue)
+ }
+
+ const handleSave = async () => {
+ try {
+ await updateProfile(draft)
+ setSaved(draft)
+ onSave(draft)
+ setEditingField(null)
+ } catch (error) {
+ console.error('์์ ์คํจ:', error)
+ alert('์์ ์ค ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค.')
+ handleCancel()
+ }
+ }
+
+ const handleCancel = () => {
+ setDraft(saved)
+ setEditingField(null)
+ onCancelEdit()
+ }
+
+ const handleImageChange = (e: React.ChangeEvent) => {
+ const file = e.target.files?.[0]
+ if (!file) return
+ const previewUrl = URL.createObjectURL(file)
+ setDraft({ ...draft, profileImageUrl: previewUrl, profileImage: file })
+ }
+
+ const viewData = editMode ? draft : saved
+
+ useEffect(() => {
+ const currentImageUrl = draft.profileImageUrl
+ return () => {
+ if (currentImageUrl && currentImageUrl.startsWith('blob:')) {
+ URL.revokeObjectURL(currentImageUrl)
+ }
+ }
+ }, [draft.profileImageUrl])
+
+ return (
+
+
+
+

+ {editMode && (
+
+ )}
+
+
+
+
+ ๋๋ค์
+ {editMode && editingField === 'nickname' ? (
+ setDraft({ ...draft, nickname: e.target.value })}
+ onBlur={() => setEditingField(null)}
+ className="border-b border-white outline-none font-medium16 pb-1 bg-transparent text-white"
+ />
+ ) : (
+ editMode && setEditingField('nickname')}
+ className={`font-medium16 text-white ${editMode ? 'border-b border-white cursor-text' : ''}`}
+ >
+ {viewData.nickname}
+
+ )}
+
+
+
+ ์์ด๋
+ {editMode && editingField === 'userId' ? (
+ setDraft({ ...draft, username: e.target.value })}
+ onBlur={() => setEditingField(null)}
+ className="border-b border-white outline-none font-medium16 pb-1 bg-transparent text-white"
+ />
+ ) : (
+ editMode && setEditingField('userId')}
+ className={`font-medium16 text-white ${editMode ? 'border-b border-white cursor-text' : ''}`}
+ >
+ {viewData.username}
+
+ )}
+
+
+
+
๋น๋ฐ๋ฒํธ
+
+
+ ********
+
+
+
+
+
+ ์ด๋ฉ์ผ
+ {user?.email}
+
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/Mine/src/components/settings/ScreenSettings.tsx b/Mine/src/components/settings/ScreenSettings.tsx
new file mode 100644
index 0000000..4f2d8c5
--- /dev/null
+++ b/Mine/src/components/settings/ScreenSettings.tsx
@@ -0,0 +1,88 @@
+import { useState, useRef } from 'react'
+import { useParams } from 'react-router-dom'
+import IconWandStars from '../../icon/wand_stars.svg?react'
+import IconAddPhoto from '../../icon/add_photo_alternate.svg?react'
+import useCreateMoodboard from '../../hooks/useCreateMoodboard'
+import useUploadImage from '../../hooks/useUploadImage'
+import ConfirmModal from '../common/ConfirmModal'
+import Toast from '../common/Toast'
+
+export default function ScreenSettings() {
+ const { magazineId } = useParams<{ magazineId: string }>()
+ const [isConfirmOpen, setIsConfirmOpen] = useState(false)
+ const [isLoading, setIsLoading] = useState(false)
+ const [showToast, setShowToast] = useState(false)
+ const fileInputRef = useRef(null)
+ const { mutateAsync: uploadImage } = useUploadImage()
+ const { mutateAsync: createMoodboard } = useCreateMoodboard()
+
+ const handleOpenFile = () => {
+ fileInputRef.current?.click()
+ }
+
+ const handleFileChange = async (e: React.ChangeEvent) => {
+ const file = e.target.files?.[0]
+ if (!file) return
+ try {
+ await uploadImage(file)
+ setShowToast(true)
+ setTimeout(() => setShowToast(false), 3000)
+ } catch (error) {
+ console.error('์ด๋ฏธ์ง ์
๋ก๋ ์คํจ:', error)
+ }
+ }
+
+ const handleConfirm = async () => {
+ if (isLoading) return
+ setIsLoading(true)
+ try {
+ await createMoodboard(Number(magazineId))
+ setIsConfirmOpen(false)
+ setShowToast(true)
+ setTimeout(() => setShowToast(false), 3000)
+ } catch (error) {
+ console.error('๋ฌด๋๋ณด๋ ์์ฑ ์คํจ:', error)
+ } finally {
+ setIsLoading(false)
+ }
+ }
+
+ return (
+ <>
+
+
+
+
+
+
+
+ {isConfirmOpen && (
+ setIsConfirmOpen(false)}
+ isLoading={isLoading}
+ />
+ )}
+
+ {showToast && (
+
+
+
+ )}
+ >
+ )
+}
diff --git a/Mine/src/components/settings/SettingsModal.tsx b/Mine/src/components/settings/SettingsModal.tsx
new file mode 100644
index 0000000..3c266d1
--- /dev/null
+++ b/Mine/src/components/settings/SettingsModal.tsx
@@ -0,0 +1,171 @@
+import { useRef, useState } from 'react'
+import ProfileSettings from './ProfileSettings'
+import ScreenSettings from './ScreenSettings'
+import InterestSettings from './InterestSettings'
+
+import X from '../../icon/X.svg?react'
+import Logout from '../../icon/logout.svg?react'
+import Edit from '../../icon/edit.svg?react'
+import usePostLogout from '../../hooks/usePostLogout'
+import usePutInterests from '../../hooks/usePutInterests'
+import Toast from '../common/Toast'
+
+interface SettingsProps {
+ onClose: () => void
+}
+
+export default function SettingsModal({ onClose }: SettingsProps) {
+ const [activeTab, setActiveTab] = useState<'profile' | 'interest' | 'screen'>('profile')
+ const [editMode, setEditMode] = useState(false)
+ const [showLogoutToast, setShowLogoutToast] = useState(false)
+ const [showSaveToast, setShowSaveToast] = useState(false)
+ const [selectedInterests, setSelectedInterests] = useState([])
+ const { mutate: logout, isPending } = usePostLogout()
+ const { mutateAsync: putInterests } = usePutInterests()
+
+ const handleLogout = () => {
+ if (isPending) return
+ logout()
+ onClose()
+ setShowLogoutToast(true)
+ setTimeout(() => {
+ setShowLogoutToast(false)
+ }, 2000)
+ }
+
+ const cancelRef = useRef(null)
+ const saveRef = useRef(null)
+
+ const handleClose = () => {
+ if (editMode) {
+ cancelRef.current?.click()
+ setEditMode(false)
+ }
+ onClose()
+ }
+
+ const handleSave = async () => {
+ if (activeTab === 'profile') {
+ saveRef.current?.click()
+ setEditMode(false)
+ } else if (activeTab === 'interest') {
+ if (selectedInterests.length === 0) return
+ try {
+ await putInterests(selectedInterests)
+ } catch (error) {
+ console.error('๊ด์ฌ์ฌ ์ ์ฅ ์คํจ:', error)
+ return
+ }
+ }
+ setShowSaveToast(true)
+ setTimeout(() => setShowSaveToast(false), 2000)
+ }
+
+ return (
+
+
e.stopPropagation()}>
+
+
+
+
+
+
+
+
+
+
+ {activeTab === 'profile' && (
+
setEditMode(false)}
+ onSave={() => setEditMode(false)}
+ refCancel={cancelRef}
+ refSave={saveRef}
+ />
+ )}
+ {activeTab === 'interest' && (
+
+ )}
+ {activeTab === 'screen' && }
+
+
+ {activeTab === 'profile' && (
+
+ )}
+
+ {activeTab === 'profile' &&
+ (!editMode ? (
+
+ ) : (
+
+ ))}
+ {activeTab === 'interest' && (
+
+ )}
+
+
+ {showLogoutToast && (
+
+
+
+ )}
+
+ {showSaveToast && (
+
+
+
+ )}
+
+
+ )
+}
diff --git a/Mine/src/hooks/useCreateMoodboard.ts b/Mine/src/hooks/useCreateMoodboard.ts
new file mode 100644
index 0000000..62010fb
--- /dev/null
+++ b/Mine/src/hooks/useCreateMoodboard.ts
@@ -0,0 +1,8 @@
+import { useMutation } from '@tanstack/react-query'
+import { createMoodboard } from '../api/magazine'
+
+export default function useCreateMoodboard() {
+ return useMutation({
+ mutationFn: (magazineId: number) => createMoodboard(magazineId),
+ })
+}
\ No newline at end of file
diff --git a/Mine/src/hooks/useDeleteMagazine.ts b/Mine/src/hooks/useDeleteMagazine.ts
new file mode 100644
index 0000000..1e17f10
--- /dev/null
+++ b/Mine/src/hooks/useDeleteMagazine.ts
@@ -0,0 +1,17 @@
+import { useMutation, useQueryClient } from '@tanstack/react-query'
+import { deleteMagazine } from '../api/magazine'
+import type { RequestDeleteMagazine } from '../types/magazine'
+
+export default function useDeleteMagazine() {
+ const queryClient = useQueryClient()
+ return useMutation({
+ mutationFn: (params: RequestDeleteMagazine) => deleteMagazine(params),
+ onSuccess: () => {
+ queryClient.invalidateQueries({ queryKey: ['mymagazines'] })
+ },
+ onError: (error) => {
+ console.log('์ญ์ ์คํจ', error)
+ alert('๋งค๊ฑฐ์ง ์ญ์ ์ ์คํจํ์ต๋๋ค. ์ ์ ํ์ ๋ค์ ์๋ํด ์ฃผ์ธ์')
+ },
+ })
+}
diff --git a/Mine/src/hooks/useDeleteParagraph.ts b/Mine/src/hooks/useDeleteParagraph.ts
new file mode 100644
index 0000000..1a74ba1
--- /dev/null
+++ b/Mine/src/hooks/useDeleteParagraph.ts
@@ -0,0 +1,17 @@
+import { useMutation, useQueryClient } from '@tanstack/react-query'
+import { deleteParagraph } from '../api/magazine'
+import type { DeleteParagraphDto } from '../types/magazine'
+
+export default function useDeleteParagraph() {
+ const queryClient = useQueryClient()
+ return useMutation({
+ mutationFn: (params: DeleteParagraphDto) => deleteParagraph(params),
+ onSuccess: (_, variables) => {
+ queryClient.invalidateQueries({ queryKey: ['mymagazines', variables.paragraphId] })
+ },
+ onError: (error) => {
+ console.log('์ญ์ ์คํจ', error)
+ alert('๋ฌธ๋จ ์ญ์ ์ ์คํจํ์ต๋๋ค. ์ ์ ํ์ ๋ค์ ์๋ํด ์ฃผ์ธ์')
+ },
+ })
+}
diff --git a/Mine/src/hooks/useDeleteSection.tsx b/Mine/src/hooks/useDeleteSection.tsx
new file mode 100644
index 0000000..64f8176
--- /dev/null
+++ b/Mine/src/hooks/useDeleteSection.tsx
@@ -0,0 +1,17 @@
+import { useMutation, useQueryClient } from '@tanstack/react-query'
+import { deleteSection } from '../api/magazine'
+import type { DeleteSectionDto } from '../types/magazine'
+
+export default function useDeleteSection() {
+ const queryClient = useQueryClient()
+ return useMutation({
+ mutationFn: (params: DeleteSectionDto) => deleteSection(params),
+ onSuccess: (_, variables) => {
+ queryClient.invalidateQueries({ queryKey: ['magazine', variables.magazineId] })
+ },
+ onError: (error) => {
+ console.log('์ญ์ ์คํจ', error)
+ alert('์น์
์ญ์ ์ ์คํจํ์ต๋๋ค. ์ ์ ํ์ ๋ค์ ์๋ํด ์ฃผ์ธ์')
+ },
+ })
+}
diff --git a/Mine/src/hooks/useGetInterests.ts b/Mine/src/hooks/useGetInterests.ts
new file mode 100644
index 0000000..3111b4c
--- /dev/null
+++ b/Mine/src/hooks/useGetInterests.ts
@@ -0,0 +1,13 @@
+import { useQuery } from '@tanstack/react-query'
+import type { ResponseInterestsList } from '../types/interest'
+import { axiosInstance } from '../api/axios'
+
+export default function useGetInterests() {
+ return useQuery({
+ queryKey: ['intersts'],
+ queryFn: async () => {
+ const { data } = await axiosInstance.get('/api/interests')
+ return data
+ },
+ })
+}
diff --git a/Mine/src/hooks/useGetLikedMagazineList.ts b/Mine/src/hooks/useGetLikedMagazineList.ts
new file mode 100644
index 0000000..4ae1cec
--- /dev/null
+++ b/Mine/src/hooks/useGetLikedMagazineList.ts
@@ -0,0 +1,10 @@
+import { useQuery } from '@tanstack/react-query'
+import type { MyMagazinesDto, ResponseMyMagazine } from '../types/magazine'
+import { getLikedMagazineList } from '../api/magazine'
+
+export default function useGetLikedMagazineList(params: MyMagazinesDto) {
+ return useQuery({
+ queryKey: ['likedMagazines', params],
+ queryFn: () => getLikedMagazineList(params),
+ })
+}
\ No newline at end of file
diff --git a/Mine/src/hooks/useGetMagazineDetail.ts b/Mine/src/hooks/useGetMagazineDetail.ts
new file mode 100644
index 0000000..d0e3a1a
--- /dev/null
+++ b/Mine/src/hooks/useGetMagazineDetail.ts
@@ -0,0 +1,11 @@
+import { useQuery } from '@tanstack/react-query'
+import type { ResponseMagazineDetail } from '../types/magazine'
+import { getMagazineDetail } from '../api/magazine'
+
+export default function useGetMagazineDetail(magazineId: number) {
+ return useQuery({
+ queryKey: ['magazine', magazineId],
+ queryFn: () => getMagazineDetail(magazineId),
+ select: (data) => data,
+ })
+}
diff --git a/Mine/src/hooks/useGetMagazineFeed.ts b/Mine/src/hooks/useGetMagazineFeed.ts
new file mode 100644
index 0000000..8df1b07
--- /dev/null
+++ b/Mine/src/hooks/useGetMagazineFeed.ts
@@ -0,0 +1,12 @@
+import { useInfiniteQuery } from '@tanstack/react-query'
+import type { ResponseFeed } from '../types/magazine'
+import { getMagazineFeed } from '../api/magazine'
+
+export default function useGetMagazineFeed() {
+ return useInfiniteQuery({
+ queryKey: ['magazineFeed'],
+ queryFn: ({ pageParam }: { pageParam: number | null }) => getMagazineFeed({ cursorId: pageParam }),
+ initialPageParam: null,
+ getNextPageParam: (lastPage: ResponseFeed) => lastPage.hasNext ? lastPage.nextCursor : undefined,
+ })
+}
\ No newline at end of file
diff --git a/Mine/src/hooks/useGetMyMagazines.ts b/Mine/src/hooks/useGetMyMagazines.ts
new file mode 100644
index 0000000..c30a6fa
--- /dev/null
+++ b/Mine/src/hooks/useGetMyMagazines.ts
@@ -0,0 +1,11 @@
+import { useQuery } from '@tanstack/react-query'
+import type { MyMagazinesDto, ResponseMyMagazine } from '../types/magazine'
+import { getMyMagazineList } from '../api/magazine'
+
+export default function useGetMyMagazineList({ page, size, sort }: MyMagazinesDto) {
+ return useQuery({
+ queryKey: ['mymagazines', page, size, sort],
+ queryFn: () => getMyMagazineList({ page, size, sort }),
+ select: (data) => data,
+ })
+}
diff --git a/Mine/src/hooks/useGetMyProfile.ts b/Mine/src/hooks/useGetMyProfile.ts
new file mode 100644
index 0000000..158cc02
--- /dev/null
+++ b/Mine/src/hooks/useGetMyProfile.ts
@@ -0,0 +1,15 @@
+import { useQuery } from '@tanstack/react-query'
+import type { ResponseProfile } from '../types/user'
+import { getMyProfile } from '../api/user'
+
+export default function useGetMyProfile() {
+ const token = typeof window !== 'undefined' ? localStorage.getItem('accessToken') : null
+ return useQuery({
+ queryKey: ['profile'],
+ queryFn: () => getMyProfile(),
+ retry: false,
+ throwOnError: false,
+ select: (data) => data,
+ enabled: !!token,
+ })
+}
diff --git a/Mine/src/hooks/useGetRecentSection.ts b/Mine/src/hooks/useGetRecentSection.ts
new file mode 100644
index 0000000..1dfdbd5
--- /dev/null
+++ b/Mine/src/hooks/useGetRecentSection.ts
@@ -0,0 +1,11 @@
+import { useQuery } from '@tanstack/react-query'
+import type { ResponseRecentSection } from '../types/magazine'
+import { getRecentSection } from '../api/magazine'
+
+export default function useGetRecentSection() {
+ return useQuery({
+ queryKey: ['recentsections'],
+ queryFn: () => getRecentSection(),
+ select: (data) => data,
+ })
+}
diff --git a/Mine/src/hooks/useGetSectionDetail.ts b/Mine/src/hooks/useGetSectionDetail.ts
new file mode 100644
index 0000000..9bb925d
--- /dev/null
+++ b/Mine/src/hooks/useGetSectionDetail.ts
@@ -0,0 +1,12 @@
+import { useQuery } from '@tanstack/react-query'
+import type { ResponseGetSectionDetail } from '../types/magazine'
+import { getSectionDetail } from '../api/magazine'
+
+export default function useGetSectionDetail(magazineId: number, sectionId: number) {
+ return useQuery({
+ queryKey: ['section', magazineId, sectionId],
+ queryFn: () => getSectionDetail({ magazineId, sectionId }),
+ enabled: Number.isFinite(magazineId) && Number.isFinite(sectionId),
+ select: (data) => data,
+ })
+}
diff --git a/Mine/src/hooks/usePatchVisibility.ts b/Mine/src/hooks/usePatchVisibility.ts
new file mode 100644
index 0000000..c2976bd
--- /dev/null
+++ b/Mine/src/hooks/usePatchVisibility.ts
@@ -0,0 +1,8 @@
+import { useMutation } from '@tanstack/react-query'
+import { patchVisibility } from '../api/user'
+
+export default function usePatchVisibility() {
+ return useMutation({
+ mutationFn: (isPublic: boolean) => patchVisibility(isPublic),
+ })
+}
\ No newline at end of file
diff --git a/Mine/src/hooks/usePostAuthorization.ts b/Mine/src/hooks/usePostAuthorization.ts
new file mode 100644
index 0000000..280c988
--- /dev/null
+++ b/Mine/src/hooks/usePostAuthorization.ts
@@ -0,0 +1,27 @@
+import { useMutation, useQueryClient } from '@tanstack/react-query'
+import type { AuthorizationDto, ResponseAuthorization } from '../types/user'
+import { useNavigate } from 'react-router-dom'
+import { postAuthorization } from '../api/auth'
+import { useAuthStore } from '../stores/auth'
+
+export default function usePostAuthorization() {
+ const navigate = useNavigate()
+ const queryClient = useQueryClient()
+ const { login } = useAuthStore()
+
+ return useMutation({
+ mutationFn: (loginData: AuthorizationDto) => postAuthorization(loginData),
+ onSuccess: (data: ResponseAuthorization) => {
+ login(data.accessToken)
+ console.log('๋ก๊ทธ์ธ ์ฑ๊ณต!', data)
+ localStorage.setItem('accessToken', data.accessToken)
+ localStorage.setItem('refreshToken', data.refreshToken)
+ queryClient.invalidateQueries({ queryKey: ['myInfo'] })
+ navigate('/')
+ },
+ onError: (error) => {
+ console.log('๋ก๊ทธ์ธ ์คํจ:', error)
+ alert('์์ด๋ ๋๋ ๋น๋ฐ๋ฒํธ๋ฅผ ํ์ธํด ์ฃผ์ธ์')
+ },
+ })
+}
diff --git a/Mine/src/hooks/usePostHeart.tsx b/Mine/src/hooks/usePostHeart.tsx
new file mode 100644
index 0000000..ec27c28
--- /dev/null
+++ b/Mine/src/hooks/usePostHeart.tsx
@@ -0,0 +1,17 @@
+import { useMutation, useQueryClient } from '@tanstack/react-query'
+import { postHeart } from '../api/magazine'
+
+export default function usePostHeart() {
+ const queryClient = useQueryClient()
+
+ return useMutation({
+ mutationFn: (id: number) => postHeart(id),
+ onSuccess: (magazineId) => {
+ queryClient.invalidateQueries({ queryKey: ['hearts', magazineId] })
+ },
+ onError: (error) => {
+ console.log('๋งค๊ฑฐ์ง ํํธ ๋๋ฅด๊ธฐ ์คํจ:', error)
+ alert('๋งค๊ฑฐ์ง ํํธ ๋๋ฅด๊ธฐ์ ์คํจํ์ต๋๋ค.')
+ },
+ })
+}
diff --git a/Mine/src/hooks/usePostLogout.ts b/Mine/src/hooks/usePostLogout.ts
new file mode 100644
index 0000000..81eabc0
--- /dev/null
+++ b/Mine/src/hooks/usePostLogout.ts
@@ -0,0 +1,24 @@
+import { useMutation, useQueryClient } from '@tanstack/react-query'
+import { postLogout } from '../api/auth'
+import { useNavigate } from 'react-router-dom'
+import { useAuthStore } from '../stores/auth'
+
+export default function usePostLogout() {
+ const navigate = useNavigate()
+ const queryClient = useQueryClient()
+ const { logout } = useAuthStore()
+ return useMutation({
+ mutationFn: () => postLogout(),
+ onSuccess: () => {
+ logout()
+ console.log('๋ก๊ทธ์์ ์ฑ๊ณต')
+ localStorage.clear()
+ queryClient.clear()
+ navigate('/login')
+ },
+ onError: (error) => {
+ console.log('๋ก๊ทธ์์ ์คํจ:', error)
+ alert('๋ก๊ทธ์์ ์คํจ')
+ },
+ })
+}
diff --git a/Mine/src/hooks/usePostMagazine.ts b/Mine/src/hooks/usePostMagazine.ts
new file mode 100644
index 0000000..320769a
--- /dev/null
+++ b/Mine/src/hooks/usePostMagazine.ts
@@ -0,0 +1,17 @@
+import { useMutation, useQueryClient } from '@tanstack/react-query'
+import type { PostMagazineDto } from '../types/magazine'
+import { postMagazine } from '../api/magazine'
+
+export default function usePostMagazine() {
+ const queryClient = useQueryClient()
+ return useMutation({
+ mutationFn: ({ topic, user_mood }: PostMagazineDto) => postMagazine({ topic, user_mood }),
+ onSuccess: () => {
+ queryClient.invalidateQueries({ queryKey: ['mymagazines'] })
+ },
+ onError: (error) => {
+ console.log('๋งค๊ฑฐ์ง ์์ฑ ์คํจ:', error)
+ alert('๋งค๊ฑฐ์ง ์์ฑ์ ์คํจํ์ต๋๋ค.')
+ },
+ })
+}
diff --git a/Mine/src/hooks/usePostSignup.ts b/Mine/src/hooks/usePostSignup.ts
new file mode 100644
index 0000000..77d5764
--- /dev/null
+++ b/Mine/src/hooks/usePostSignup.ts
@@ -0,0 +1,19 @@
+import { useNavigate } from 'react-router-dom'
+import type { SignupDto } from '../types/user'
+import { useMutation } from '@tanstack/react-query'
+import { postSignup } from '../api/auth'
+
+export default function usePostSignup() {
+ const navigate = useNavigate()
+ return useMutation({
+ mutationFn: (signupData: SignupDto) => postSignup(signupData),
+ onSuccess: (data) => {
+ console.log('ํ์๊ฐ์
์ฑ๊ณต!', data)
+ navigate('/')
+ },
+ onError: (error) => {
+ console.log('ํ์๊ฐ์
์คํจ:', error)
+ alert('์์ด๋ ๋๋ ๋น๋ฐ๋ฒํธ๋ฅผ ํ์ธํด ์ฃผ์ธ์')
+ }
+ })
+}
diff --git a/Mine/src/hooks/usePutInterests.ts b/Mine/src/hooks/usePutInterests.ts
new file mode 100644
index 0000000..40f19c6
--- /dev/null
+++ b/Mine/src/hooks/usePutInterests.ts
@@ -0,0 +1,8 @@
+import { useMutation } from '@tanstack/react-query'
+import { putInterests } from '../api/interest'
+
+export default function usePutInterests() {
+ return useMutation({
+ mutationFn: (interests: string[]) => putInterests(interests),
+ })
+}
\ No newline at end of file
diff --git a/Mine/src/hooks/useUpdateMagazineTitle.ts b/Mine/src/hooks/useUpdateMagazineTitle.ts
new file mode 100644
index 0000000..0888d12
--- /dev/null
+++ b/Mine/src/hooks/useUpdateMagazineTitle.ts
@@ -0,0 +1,18 @@
+import { useMutation, useQueryClient } from '@tanstack/react-query'
+import { patchMagazineTitle } from '../api/magazine'
+import type { PatchMagazineTitleDto } from '../types/magazine'
+
+export default function useUpdateMagazineTitle() {
+ const queryClient = useQueryClient()
+ return useMutation({
+ mutationFn: ({ id, title, introduction }: PatchMagazineTitleDto) =>
+ patchMagazineTitle({ id, title, introduction }),
+ onSuccess: () => {
+ queryClient.invalidateQueries({ queryKey: ['mymagazines'] })
+ },
+ onError: (error) => {
+ console.log('๋งค๊ฑฐ์ง ์ ๋ชฉ ๋ณ๊ฒฝ ์คํจ:', error)
+ alert('๋งค๊ฑฐ์ง ์ ๋ชฉ ๋ณ๊ฒฝ์ ์คํจํ์ต๋๋ค.')
+ },
+ })
+}
diff --git a/Mine/src/hooks/useUpdateProfile.ts b/Mine/src/hooks/useUpdateProfile.ts
new file mode 100644
index 0000000..c00b4a9
--- /dev/null
+++ b/Mine/src/hooks/useUpdateProfile.ts
@@ -0,0 +1,15 @@
+import { useMutation, useQueryClient } from '@tanstack/react-query'
+import { patchMyProfile } from '../api/user'
+import useUserStore from '../stores/user'
+
+export default function useUpdateProfile() {
+ const queryClient = useQueryClient()
+ const setUser = useUserStore((state) => state.setUser)
+ return useMutation({
+ mutationFn: patchMyProfile,
+ onSuccess: (data) => {
+ setUser(data)
+ queryClient.invalidateQueries({ queryKey: ['profile'] })
+ },
+ })
+}
diff --git a/Mine/src/hooks/useUploadImage.ts b/Mine/src/hooks/useUploadImage.ts
new file mode 100644
index 0000000..6b53fd4
--- /dev/null
+++ b/Mine/src/hooks/useUploadImage.ts
@@ -0,0 +1,8 @@
+import { useMutation } from '@tanstack/react-query'
+import { uploadImage } from '../api/image'
+
+export default function useUploadImage() {
+ return useMutation({
+ mutationFn: (file: File) => uploadImage(file),
+ })
+}
\ No newline at end of file
diff --git a/Mine/src/icon/Arrow2.svg b/Mine/src/icon/Arrow2.svg
new file mode 100644
index 0000000..733760c
--- /dev/null
+++ b/Mine/src/icon/Arrow2.svg
@@ -0,0 +1,3 @@
+
diff --git a/Mine/src/icon/X.svg b/Mine/src/icon/X.svg
new file mode 100644
index 0000000..a8cf064
--- /dev/null
+++ b/Mine/src/icon/X.svg
@@ -0,0 +1,8 @@
+
diff --git a/Mine/src/icon/add_photo_alternate.svg b/Mine/src/icon/add_photo_alternate.svg
new file mode 100644
index 0000000..5cb825a
--- /dev/null
+++ b/Mine/src/icon/add_photo_alternate.svg
@@ -0,0 +1,8 @@
+
diff --git a/Mine/src/icon/arrow.svg b/Mine/src/icon/arrow.svg
new file mode 100644
index 0000000..5266a4f
--- /dev/null
+++ b/Mine/src/icon/arrow.svg
@@ -0,0 +1,3 @@
+
diff --git a/Mine/src/icon/back.svg b/Mine/src/icon/back.svg
new file mode 100644
index 0000000..f069663
--- /dev/null
+++ b/Mine/src/icon/back.svg
@@ -0,0 +1,3 @@
+
diff --git a/Mine/src/icon/camera.svg b/Mine/src/icon/camera.svg
new file mode 100644
index 0000000..883aede
--- /dev/null
+++ b/Mine/src/icon/camera.svg
@@ -0,0 +1,9 @@
+
diff --git a/Mine/src/icon/check.svg b/Mine/src/icon/check.svg
new file mode 100644
index 0000000..64c8d1d
--- /dev/null
+++ b/Mine/src/icon/check.svg
@@ -0,0 +1,8 @@
+
diff --git a/Mine/src/icon/delete.svg b/Mine/src/icon/delete.svg
new file mode 100644
index 0000000..1c63b53
--- /dev/null
+++ b/Mine/src/icon/delete.svg
@@ -0,0 +1,3 @@
+
\ No newline at end of file
diff --git a/Mine/src/icon/edit.svg b/Mine/src/icon/edit.svg
new file mode 100644
index 0000000..311dd65
--- /dev/null
+++ b/Mine/src/icon/edit.svg
@@ -0,0 +1,8 @@
+
diff --git a/Mine/src/icon/email.svg b/Mine/src/icon/email.svg
new file mode 100644
index 0000000..1e2d72c
--- /dev/null
+++ b/Mine/src/icon/email.svg
@@ -0,0 +1,8 @@
+
diff --git a/Mine/src/icon/eye.svg b/Mine/src/icon/eye.svg
new file mode 100644
index 0000000..6db9905
--- /dev/null
+++ b/Mine/src/icon/eye.svg
@@ -0,0 +1,8 @@
+
diff --git a/Mine/src/icon/eyeoff.svg b/Mine/src/icon/eyeoff.svg
new file mode 100644
index 0000000..b77a448
--- /dev/null
+++ b/Mine/src/icon/eyeoff.svg
@@ -0,0 +1,8 @@
+
diff --git a/Mine/src/icon/hamburger.svg b/Mine/src/icon/hamburger.svg
new file mode 100644
index 0000000..8a285bf
--- /dev/null
+++ b/Mine/src/icon/hamburger.svg
@@ -0,0 +1,3 @@
+
diff --git a/Mine/src/icon/heart.svg b/Mine/src/icon/heart.svg
new file mode 100644
index 0000000..5f3874c
--- /dev/null
+++ b/Mine/src/icon/heart.svg
@@ -0,0 +1,8 @@
+
diff --git a/Mine/src/icon/instagram.svg b/Mine/src/icon/instagram.svg
new file mode 100644
index 0000000..1c4bf07
--- /dev/null
+++ b/Mine/src/icon/instagram.svg
@@ -0,0 +1,8 @@
+
diff --git a/Mine/src/icon/kakao.svg b/Mine/src/icon/kakao.svg
new file mode 100644
index 0000000..d240d2d
--- /dev/null
+++ b/Mine/src/icon/kakao.svg
@@ -0,0 +1,8 @@
+
diff --git a/Mine/src/icon/link.svg b/Mine/src/icon/link.svg
new file mode 100644
index 0000000..f4ccf6b
--- /dev/null
+++ b/Mine/src/icon/link.svg
@@ -0,0 +1,8 @@
+
diff --git a/Mine/src/icon/lock.svg b/Mine/src/icon/lock.svg
new file mode 100644
index 0000000..87c0154
--- /dev/null
+++ b/Mine/src/icon/lock.svg
@@ -0,0 +1,8 @@
+
diff --git a/Mine/src/icon/logout.svg b/Mine/src/icon/logout.svg
new file mode 100644
index 0000000..fd31a8d
--- /dev/null
+++ b/Mine/src/icon/logout.svg
@@ -0,0 +1,8 @@
+
diff --git a/Mine/src/icon/minelogo.svg b/Mine/src/icon/minelogo.svg
new file mode 100644
index 0000000..3f3716e
--- /dev/null
+++ b/Mine/src/icon/minelogo.svg
@@ -0,0 +1,9 @@
+
diff --git a/Mine/src/icon/minelogo_small.svg b/Mine/src/icon/minelogo_small.svg
new file mode 100644
index 0000000..93bc1b7
--- /dev/null
+++ b/Mine/src/icon/minelogo_small.svg
@@ -0,0 +1,9 @@
+
diff --git a/Mine/src/icon/progressbar_first.svg b/Mine/src/icon/progressbar_first.svg
new file mode 100644
index 0000000..72d966e
--- /dev/null
+++ b/Mine/src/icon/progressbar_first.svg
@@ -0,0 +1,5 @@
+
diff --git a/Mine/src/icon/progressbar_second.svg b/Mine/src/icon/progressbar_second.svg
new file mode 100644
index 0000000..b20db11
--- /dev/null
+++ b/Mine/src/icon/progressbar_second.svg
@@ -0,0 +1,5 @@
+
diff --git a/Mine/src/icon/replay.svg b/Mine/src/icon/replay.svg
new file mode 100644
index 0000000..0c111bd
--- /dev/null
+++ b/Mine/src/icon/replay.svg
@@ -0,0 +1,8 @@
+
diff --git a/Mine/src/icon/setting.svg b/Mine/src/icon/setting.svg
new file mode 100644
index 0000000..b288c48
--- /dev/null
+++ b/Mine/src/icon/setting.svg
@@ -0,0 +1,8 @@
+
diff --git a/Mine/src/icon/share.svg b/Mine/src/icon/share.svg
new file mode 100644
index 0000000..5e3e54d
--- /dev/null
+++ b/Mine/src/icon/share.svg
@@ -0,0 +1,8 @@
+
diff --git a/Mine/src/icon/sidebarButton.svg b/Mine/src/icon/sidebarButton.svg
new file mode 100644
index 0000000..505f1a3
--- /dev/null
+++ b/Mine/src/icon/sidebarButton.svg
@@ -0,0 +1,10 @@
+
diff --git a/Mine/src/icon/sidebar_like.svg b/Mine/src/icon/sidebar_like.svg
new file mode 100644
index 0000000..2f13e08
--- /dev/null
+++ b/Mine/src/icon/sidebar_like.svg
@@ -0,0 +1,8 @@
+
diff --git a/Mine/src/icon/sidebar_main.svg b/Mine/src/icon/sidebar_main.svg
new file mode 100644
index 0000000..be0a799
--- /dev/null
+++ b/Mine/src/icon/sidebar_main.svg
@@ -0,0 +1,8 @@
+
diff --git a/Mine/src/icon/sidebar_new.svg b/Mine/src/icon/sidebar_new.svg
new file mode 100644
index 0000000..f65ddd8
--- /dev/null
+++ b/Mine/src/icon/sidebar_new.svg
@@ -0,0 +1,8 @@
+
diff --git a/Mine/src/icon/sidebar_others.svg b/Mine/src/icon/sidebar_others.svg
new file mode 100644
index 0000000..50d30c7
--- /dev/null
+++ b/Mine/src/icon/sidebar_others.svg
@@ -0,0 +1,8 @@
+
diff --git a/Mine/src/icon/swipe.svg b/Mine/src/icon/swipe.svg
new file mode 100644
index 0000000..2a9bff9
--- /dev/null
+++ b/Mine/src/icon/swipe.svg
@@ -0,0 +1,8 @@
+
diff --git a/Mine/src/icon/tab_button.svg b/Mine/src/icon/tab_button.svg
new file mode 100644
index 0000000..e2a9119
--- /dev/null
+++ b/Mine/src/icon/tab_button.svg
@@ -0,0 +1,8 @@
+
diff --git a/Mine/src/icon/toggle.svg b/Mine/src/icon/toggle.svg
new file mode 100644
index 0000000..f15e168
--- /dev/null
+++ b/Mine/src/icon/toggle.svg
@@ -0,0 +1,8 @@
+
diff --git a/Mine/src/icon/twitter.svg b/Mine/src/icon/twitter.svg
new file mode 100644
index 0000000..071ecc2
--- /dev/null
+++ b/Mine/src/icon/twitter.svg
@@ -0,0 +1,8 @@
+
diff --git a/Mine/src/icon/user.svg b/Mine/src/icon/user.svg
new file mode 100644
index 0000000..28e5acd
--- /dev/null
+++ b/Mine/src/icon/user.svg
@@ -0,0 +1,8 @@
+
diff --git a/Mine/src/icon/vector.svg b/Mine/src/icon/vector.svg
new file mode 100644
index 0000000..24da7c3
--- /dev/null
+++ b/Mine/src/icon/vector.svg
@@ -0,0 +1,3 @@
+
diff --git a/Mine/src/icon/wand_stars.svg b/Mine/src/icon/wand_stars.svg
new file mode 100644
index 0000000..a2ca87f
--- /dev/null
+++ b/Mine/src/icon/wand_stars.svg
@@ -0,0 +1,8 @@
+
diff --git a/Mine/src/layout/Layout.tsx b/Mine/src/layout/Layout.tsx
new file mode 100644
index 0000000..655ba0d
--- /dev/null
+++ b/Mine/src/layout/Layout.tsx
@@ -0,0 +1,14 @@
+import type React from 'react'
+import Sidebar from './Sidebar'
+import { useAuthStore } from '../stores/auth'
+
+export default function Layout({ children }: { children: React.ReactNode }) {
+ const { isLoggedIn } = useAuthStore()
+ return (
+
+ {isLoggedIn && }
+
+ {children}
+
+ )
+}
diff --git a/Mine/src/layout/RootLayout.tsx b/Mine/src/layout/RootLayout.tsx
new file mode 100644
index 0000000..8eff0d6
--- /dev/null
+++ b/Mine/src/layout/RootLayout.tsx
@@ -0,0 +1,15 @@
+import { Outlet } from 'react-router-dom'
+
+import Layout from './Layout'
+import LLMInputLayout from '../components/LLMInputLayout'
+
+export default function RootLayout() {
+ return (
+
+
+
+
+
+
+ )
+}
diff --git a/Mine/src/layout/Sidebar.tsx b/Mine/src/layout/Sidebar.tsx
new file mode 100644
index 0000000..ec957d9
--- /dev/null
+++ b/Mine/src/layout/Sidebar.tsx
@@ -0,0 +1,55 @@
+import { useEffect } from 'react'
+import MineLogo from '../icon/minelogo_small.svg?react'
+import SidebarOpen from './sidebar/SidebarOpen'
+import Sidebar_main from '../icon/sidebar_main.svg?react'
+import Sidebar_new from '../icon/sidebar_new.svg?react'
+import Sidebar_like from '../icon/sidebar_like.svg?react'
+import Sidebar_others from '../icon/sidebar_others.svg?react'
+import SidebarClosedBlock from './sidebar/SidebarClosedBlock'
+import useGetMyProfile from '../hooks/useGetMyProfile'
+import useUserStore from '../stores/user'
+import useSidebarStore from '../stores/sidebar'
+
+export default function Sidebar() {
+ const { isOpen, toggleSidebar } = useSidebarStore()
+
+ const { data: profile, isLoading: isProfileLoading, isError: isProfileError } = useGetMyProfile()
+ const setUser = useUserStore((state) => state.setUser)
+ const user = useUserStore((state) => state.user)
+
+ useEffect(() => {
+ if (profile) {
+ setUser(profile) // API๋ก ๋ฐ์์จ ์ ๋ณด๋ฅผ ์ฃผ์คํ ๋์ ์ ์ฅ
+ }
+ }, [profile, setUser])
+
+ if (isProfileLoading) return null
+ if (isProfileError) {
+ return null
+ }
+
+ return (
+
+ {!isOpen && (
+
+
+
+ } title="๋ฉ์ธ" to="/mymagazine" />
+ } title="์ ๋งค๊ฑฐ์ง" to="" />
+ } title="์ ์ฅํ ๋งค๊ฑฐ์ง" to="/magazine/saved" />
+ } title="๋๋ฌ๋ณด๊ธฐ" to="/magazine/explore" />
+
+

+
+ )}
+
+ {isOpen && (
+ <>
+
+
+
+ >
+ )}
+
+ )
+}
diff --git a/Mine/src/layout/sidebar/SidebarBlock.tsx b/Mine/src/layout/sidebar/SidebarBlock.tsx
new file mode 100644
index 0000000..7404308
--- /dev/null
+++ b/Mine/src/layout/sidebar/SidebarBlock.tsx
@@ -0,0 +1,24 @@
+import { useNavigate } from 'react-router-dom'
+
+interface SidebarBlockProps {
+ title: string
+ icon?: React.ReactNode
+ to: string
+}
+
+export default function SidebarBlock({ title, icon, to }: SidebarBlockProps) {
+ const navigate = useNavigate()
+
+ const handleClick = () => {
+ navigate(to)
+ }
+ return (
+
+ {icon}
+ {title}
+
+ )
+}
diff --git a/Mine/src/layout/sidebar/SidebarClosedBlock.tsx b/Mine/src/layout/sidebar/SidebarClosedBlock.tsx
new file mode 100644
index 0000000..3032a6e
--- /dev/null
+++ b/Mine/src/layout/sidebar/SidebarClosedBlock.tsx
@@ -0,0 +1,27 @@
+import { useNavigate } from 'react-router-dom'
+
+interface SidebarClosedBlockProps {
+ icon: React.ReactNode
+ title: string
+ to: string
+}
+
+export default function SidebarClosedBlock({ icon, title, to }: SidebarClosedBlockProps) {
+ const navigate = useNavigate()
+
+ const handleClick = () => {
+ navigate(to)
+ }
+ return (
+
+
+
+
+ {title}
+
+
+
+ )
+}
diff --git a/Mine/src/layout/sidebar/SidebarMagazine.tsx b/Mine/src/layout/sidebar/SidebarMagazine.tsx
new file mode 100644
index 0000000..7be157f
--- /dev/null
+++ b/Mine/src/layout/sidebar/SidebarMagazine.tsx
@@ -0,0 +1,131 @@
+import { useRef, useState } from 'react'
+import Hamburger from '../../icon/hamburger.svg?react'
+import SidebarHamburgerModal from '../../components/hamburgerModal/SidebarHamburgerModal'
+import { createPortal } from 'react-dom'
+import useUpdateMagazineTitle from '../../hooks/useUpdateMagazineTitle'
+
+interface SidebarMagazineProps {
+ id: number
+ title: string
+ child?: React.ReactNode
+ onclick?: () => void
+}
+
+export default function SidebarMagazine({ title, id, onclick }: SidebarMagazineProps) {
+ const [isHamburgerOpen, setIsHamburgerOpen] = useState(false)
+ const [modalPos, setModalPos] = useState({ top: 0, left: 0 })
+
+ const [isEditing, setIsEditing] = useState(false)
+ const [draftTitle, setDraftTitle] = useState('')
+ const inputRef = useRef(null)
+
+ const updateTitleMutation = useUpdateMagazineTitle()
+
+ const openHamburger = () => setIsHamburgerOpen(true)
+ const closeHamburger = () => setIsHamburgerOpen(false)
+
+ const handleHamburger = (e: React.MouseEvent) => {
+ e.stopPropagation()
+ const rect = e.currentTarget.getBoundingClientRect()
+ setModalPos({
+ top: rect.top + window.scrollY + 15,
+ left: rect.right - 20,
+ })
+ openHamburger()
+ }
+
+ const beginEdit = () => {
+ setDraftTitle(title)
+ setIsEditing(true)
+ requestAnimationFrame(() => {
+ inputRef.current?.focus()
+ const len = inputRef.current?.value.length ?? 0
+ inputRef.current?.setSelectionRange(len, len)
+ })
+ }
+
+ const cancelEdit = () => {
+ setIsEditing(false)
+ setDraftTitle('')
+ }
+
+ const commitEdit = () => {
+ const next = draftTitle.trim()
+
+ if (!next) {
+ cancelEdit()
+ return
+ }
+
+ if (next === title) {
+ cancelEdit()
+ return
+ }
+
+ updateTitleMutation.mutate(
+ { id, title: next, introduction: '' },
+ {
+ onSuccess: () => {
+ cancelEdit()
+ },
+ }
+ )
+ }
+
+ const onKeyDown = (e: React.KeyboardEvent) => {
+ if (e.key === 'Escape') {
+ e.preventDefault()
+ cancelEdit()
+ return
+ }
+ if (e.key === 'Enter' && !e.shiftKey) {
+ e.preventDefault()
+ commitEdit()
+ }
+ }
+
+ const shownTitle = isEditing ? draftTitle : title
+
+ return (
+
+
+ {!isEditing ? (
+ {shownTitle}
+ ) : (
+
+
+ {isHamburgerOpen &&
+ createPortal(
+
beginEdit()}
+ />,
+ document.body
+ )}
+
+ )
+}
diff --git a/Mine/src/layout/sidebar/SidebarOpen.tsx b/Mine/src/layout/sidebar/SidebarOpen.tsx
new file mode 100644
index 0000000..2f89495
--- /dev/null
+++ b/Mine/src/layout/sidebar/SidebarOpen.tsx
@@ -0,0 +1,140 @@
+import MineLogo from '../../icon/minelogo_small.svg?react'
+import SidebarButton from '../../icon/sidebarButton.svg?react'
+
+import SidebarBlock from './SidebarBlock'
+import Sidebar_main from '../../icon/sidebar_main.svg?react'
+import Sidebar_new from '../../icon/sidebar_new.svg?react'
+import Sidebar_like from '../../icon/sidebar_like.svg?react'
+import Sidebar_others from '../../icon/sidebar_others.svg?react'
+import SidebarMagazine from './SidebarMagazine'
+import SidebarSectionList from './SidebarSectionList'
+import Setting from '../../icon/setting.svg?react'
+import { useState } from 'react'
+import SettingsModal from '../../components/settings/SettingsModal'
+import SidebarTitle from './SidebarTitle'
+import useUserStore from '../../stores/user'
+import useGetRecentSection from '../../hooks/useGetRecentSection'
+import { useNavigate } from 'react-router-dom'
+import useGetMyMagazineList from '../../hooks/useGetMyMagazines'
+
+interface SidebarProps {
+ onclick: () => void
+}
+
+export default function SidebarOpen({ onclick }: SidebarProps) {
+ const navigate = useNavigate()
+ const [isSettingOpen, setIsSettingOpen] = useState(false)
+ const [isMagazineOpen, setIsMagazineOpen] = useState(true)
+ const [isSectionOpen, setIsSectionOpen] = useState(true)
+
+ const handleMagazineToggleOpen = () => {
+ setIsMagazineOpen((prev) => !prev)
+ }
+ const handleSectionToggleOpen = () => {
+ setIsSectionOpen((prev) => !prev)
+ }
+
+ const {
+ data: magazine,
+ isLoading: isMagLoading,
+ isError: isMagError,
+ } = useGetMyMagazineList({
+ page: 0,
+ size: 100,
+ sort: [],
+ })
+
+ const { data: section, isLoading: isSecLoading, isError: isSecError } = useGetRecentSection()
+
+ const { user } = useUserStore()
+
+ const handleSectionClick = (magazineId: number, sectionId: number) => {
+ navigate(`/magazine/${magazineId}/section/${sectionId}`)
+ onclick()
+ }
+ const handleMagazineClick = (magazineId: number) => {
+ navigate(`/magazine/${magazineId}`)
+ onclick()
+ }
+
+ if (isMagLoading || isSecLoading) return null
+ if (isMagError) {
+ alert('๋ชฉ๋ก ๋ถ๋ฌ์ค๊ธฐ ์คํจ')
+ return null
+ }
+ if (isSecError) {
+ alert('์น์
๋ถ๋ฌ์ค๊ธฐ ์คํจ')
+ return null
+ }
+
+ return (
+ <>
+
+
+
+
+ } title="๋ฉ์ธ" to="/mymagazine" />
+ } title="์ ๋งค๊ฑฐ์ง" to="" />
+ } title="์ ์ฅํ ๋งค๊ฑฐ์ง" to="/magazine/saved" />
+ } title="๋๋ฌ๋ณด๊ธฐ" to="/magazine/explore" />
+
+
+
+
+ {isSectionOpen && (
+ <>
+ {section?.map((section) => (
+ handleSectionClick(section.magazineId, section.sectionId)}
+ magazineId={section.magazineId}
+ sectionId={section.sectionId}
+ />
+ ))}
+ >
+ )}
+
+
+
+
+ {isMagazineOpen && (
+
+ {magazine?.content.map((magazine) => (
+ handleMagazineClick(magazine.magazineId)}
+ />
+ ))}
+
+ )}
+
+
+
+
+

+
{user?.nickname}
+
+
+
+
+
+ {isSettingOpen && setIsSettingOpen(false)} />}
+ >
+ )
+}
diff --git a/Mine/src/layout/sidebar/SidebarSectionList.tsx b/Mine/src/layout/sidebar/SidebarSectionList.tsx
new file mode 100644
index 0000000..302eaf8
--- /dev/null
+++ b/Mine/src/layout/sidebar/SidebarSectionList.tsx
@@ -0,0 +1,21 @@
+interface SidebarSectionListProps {
+ title: string
+ key?: number
+ onclick: (magazineId: number, sectionId: number) => void
+ magazineId: number
+ sectionId: number
+}
+
+export default function SidebarSectionList({ title, key, onclick, magazineId, sectionId }: SidebarSectionListProps) {
+ return (
+ onclick(magazineId, sectionId)}
+ >
+
+
+ )
+}
diff --git a/Mine/src/layout/sidebar/SidebarTitle.tsx b/Mine/src/layout/sidebar/SidebarTitle.tsx
new file mode 100644
index 0000000..d558e47
--- /dev/null
+++ b/Mine/src/layout/sidebar/SidebarTitle.tsx
@@ -0,0 +1,18 @@
+import Toggle from '../../icon/toggle.svg?react'
+interface SidebarTitleProps {
+ onClick: () => void
+ title: string
+ isOpen: boolean
+}
+
+export default function SidebarTitle({ onClick, title, isOpen }: SidebarTitleProps) {
+ return (
+
+ {title}
+
+
+ )
+}
diff --git a/Mine/src/main.tsx b/Mine/src/main.tsx
new file mode 100644
index 0000000..14b70ad
--- /dev/null
+++ b/Mine/src/main.tsx
@@ -0,0 +1,13 @@
+import { StrictMode } from 'react'
+import { createRoot } from 'react-dom/client'
+import './style/global.css'
+import App from './App.tsx'
+import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
+const queryClient = new QueryClient()
+createRoot(document.getElementById('root')!).render(
+
+
+
+
+
+)
diff --git a/Mine/src/pages/landing/LandingPage.tsx b/Mine/src/pages/landing/LandingPage.tsx
new file mode 100644
index 0000000..ce5a662
--- /dev/null
+++ b/Mine/src/pages/landing/LandingPage.tsx
@@ -0,0 +1,41 @@
+import Minelogo from '../../icon/minelogo.svg?react'
+import landingBg from '../../assets/bg1.jpg'
+import { useNavigate } from 'react-router-dom'
+
+export default function LandingPage() {
+ const navigate = useNavigate()
+
+ const handleStart = () => {
+ sessionStorage.setItem('landingBg', landingBg)
+ navigate('/login', { state: { bgUrl: landingBg } })
+ }
+
+ return (
+
+
+
+
+
+
+ ๋๋ง์ ๋งค๊ฑฐ์ง
+
+ ์์นด์ด๋น ํ๋ซํผ
+
+
+
+
+
+ )
+}
diff --git a/Mine/src/pages/login/FindingPage.tsx b/Mine/src/pages/login/FindingPage.tsx
new file mode 100644
index 0000000..075498e
--- /dev/null
+++ b/Mine/src/pages/login/FindingPage.tsx
@@ -0,0 +1,81 @@
+import { useState } from 'react'
+import { useLocation } from 'react-router-dom'
+import logo from '../../icon/minelogo.svg?url'
+import FindIdForm from './components/FindIdForm'
+import FindPasswordForm from './components/FindPasswordForm'
+
+export default function FindingPage() {
+ const [tab, setTab] = useState<'id' | 'password'>('id')
+ const location = useLocation()
+
+ const bgUrl =
+ (location.state as { bgUrl?: string } | null)?.bgUrl ??
+ sessionStorage.getItem("landingBg") ??
+ ""
+
+ return (
+
+
+
+
+
+
+ ๋๋ง์ ๋งค๊ฑฐ์ง
์์นด์ด๋น
ํ๋ซํผ
+
+
+
+
+
+

+
+
+
+
+
+
+
+
+
+
+ {tab === 'id' &&
}
+ {tab === 'password' &&
}
+
+
+
+ )
+}
\ No newline at end of file
diff --git a/Mine/src/pages/login/LoginPage.tsx b/Mine/src/pages/login/LoginPage.tsx
new file mode 100644
index 0000000..a13a513
--- /dev/null
+++ b/Mine/src/pages/login/LoginPage.tsx
@@ -0,0 +1,130 @@
+import { useState } from 'react'
+import { useLocation, useNavigate } from 'react-router-dom'
+
+import logo from '../../icon/minelogo.svg?url'
+import UserIcon from '../../icon/user.svg?react'
+import LockIcon from '../../icon/lock.svg?react'
+import EyeIcon from '../../icon/eye.svg?react'
+import usePostAuthorization from '../../hooks/usePostAuthorization'
+
+export default function LoginPage() {
+ const navigate = useNavigate()
+ const location = useLocation()
+
+ const bgUrl = (location.state as { bgUrl?: string } | null)?.bgUrl ?? sessionStorage.getItem('landingBg') ?? ''
+
+ const [userId, setUserId] = useState('')
+ const [pw, setPw] = useState('')
+ const [showPw, setShowPw] = useState(false)
+
+ const { mutate: login, isPending } = usePostAuthorization()
+
+ const onSubmit = (e: React.FormEvent) => {
+ e.preventDefault()
+
+ if (!userId.trim() || !pw.trim()) {
+ alert('์์ด๋์ ๋น๋ฐ๋ฒํธ๋ฅผ ์
๋ ฅํด์ฃผ์ธ์.')
+ return
+ }
+
+ login({ username: userId, password: pw })
+ }
+
+ return (
+
+
+
+
+
+
+ ๋๋ง์ ๋งค๊ฑฐ์ง
+
+ ์์นด์ด๋น
+
+ ํ๋ซํผ
+
+
+
+
+
+

+
+
+
+
+
+
+ )
+}
diff --git a/Mine/src/pages/login/components/FindIdForm.tsx b/Mine/src/pages/login/components/FindIdForm.tsx
new file mode 100644
index 0000000..adb308a
--- /dev/null
+++ b/Mine/src/pages/login/components/FindIdForm.tsx
@@ -0,0 +1,93 @@
+import { useState } from 'react'
+import { useNavigate } from 'react-router-dom'
+
+export default function FindIdForm() {
+ const navigate = useNavigate()
+ const [nickname, setNickname] = useState('')
+ const [email, setEmail] = useState('')
+ const [submitted, setSubmitted] = useState(false)
+
+ const handleSubmit = () => {
+ const noNickname = nickname.trim() === ''
+ const noEmail = email.trim() === ''
+
+ if (noNickname && noEmail) {
+ alert('๋๋ค์๊ณผ ์ด๋ฉ์ผ์ ์
๋ ฅํด์ฃผ์ธ์.')
+ return
+ }
+ if (noNickname) {
+ alert('๋๋ค์์ ์
๋ ฅํด์ฃผ์ธ์.')
+ return
+ }
+ if (nickname.trim().length < 2) {
+ alert('๋๋ค์์ 2์ ์ด์ ์
๋ ฅํด์ฃผ์ธ์.')
+ return
+ }
+ if (noEmail) {
+ alert('์ด๋ฉ์ผ์ ์
๋ ฅํด์ฃผ์ธ์.')
+ return
+ }
+
+ setSubmitted(true)
+ }
+
+ return (
+
+
+
๋๋ค์
+
setNickname(e.target.value)}
+ placeholder="ํ๊ธธ๋"
+ maxLength={6}
+ className="w-100 h-12 py-5 px-7 rounded-[15px]
+ border border-black-textMain text-white
+ placeholder:text-white/60 outline-none focus:border-white"
+ style={{ background: '#FFFFFF4D' }}
+ />
+
+
+ {/* ์ด๋ฉ์ผ */}
+
+
์ด๋ฉ์ผ
+
setEmail(e.target.value)}
+ placeholder="abc123@gmail.com"
+ className="w-100 h-12 py-5 px-7 rounded-[15px]
+ border border-black-textMain text-white
+ placeholder:text-white/60 outline-none focus:border-white"
+ style={{ background: '#FFFFFF4D' }}
+ />
+
+
+
+
+
+
+
+
+
+ {submitted && (
+
+ ์์ฑํ์ ์ด๋ฉ์ผ๋ก ์์ด๋๊ฐ ์ ์ก๋์์ต๋๋ค.
+ ๋ฉ์ผํจ์ ํ์ธํด์ฃผ์ธ์.
+
+ )}
+
+ )
+}
\ No newline at end of file
diff --git a/Mine/src/pages/login/components/FindPasswordForm.tsx b/Mine/src/pages/login/components/FindPasswordForm.tsx
new file mode 100644
index 0000000..0bbc222
--- /dev/null
+++ b/Mine/src/pages/login/components/FindPasswordForm.tsx
@@ -0,0 +1,91 @@
+import { useState } from 'react'
+import { useNavigate } from 'react-router-dom'
+
+export default function FindPasswordForm() {
+ const navigate = useNavigate()
+ const [userId, setUserId] = useState('')
+ const [email, setEmail] = useState('')
+ const [submitted, setSubmitted] = useState(false)
+
+ const handleSubmit = () => {
+ const noUserId = userId.trim() === ''
+ const noEmail = email.trim() === ''
+
+ if (noUserId && noEmail) {
+ alert('์์ด๋์ ์ด๋ฉ์ผ์ ์
๋ ฅํด์ฃผ์ธ์.')
+ return
+ }
+ if (noUserId) {
+ alert('์์ด๋๋ฅผ ์
๋ ฅํด์ฃผ์ธ์.')
+ return
+ }
+ if (userId.trim().length < 6) {
+ alert('์์ด๋๋ 6์ ์ด์ ์
๋ ฅํด์ฃผ์ธ์.')
+ return
+ }
+ if (noEmail) {
+ alert('์ด๋ฉ์ผ์ ์
๋ ฅํด์ฃผ์ธ์.')
+ return
+ }
+
+ setSubmitted(true)
+ }
+
+ return (
+
+ {/* ์์ด๋ */}
+
+
์์ด๋
+
setUserId(e.target.value)}
+ placeholder="์์ด๋๋ฅผ ์
๋ ฅํด ์ฃผ์ธ์."
+ maxLength={20}
+ className="w-100 h-12 py-5 px-7 rounded-[15px]
+ border border-black-textMain text-white
+ placeholder:text-white/60 outline-none focus:border-white"
+ style={{ background: '#FFFFFF4D' }}
+ />
+
+
+
+
์ด๋ฉ์ผ
+
setEmail(e.target.value)}
+ placeholder="abc123@gmail.com"
+ className="w-100 h-12 py-5 px-7 rounded-[15px]
+ border border-black-textMain text-white
+ placeholder:text-white/60 outline-none focus:border-white"
+ style={{ background: '#FFFFFF4D' }}
+ />
+
+
+
+
+
+
+
+ {submitted && (
+
+ ์์ฑํ์ ์ด๋ฉ์ผ๋ก ๋น๋ฐ๋ฒํธ๊ฐ ์ ์ก๋์์ต๋๋ค.
+ ๋ฉ์ผํจ์ ํ์ธํด์ฃผ์ธ์.
+
+ )}
+
+ )
+}
\ No newline at end of file
diff --git a/Mine/src/pages/magazine/ExplorePage.tsx b/Mine/src/pages/magazine/ExplorePage.tsx
new file mode 100644
index 0000000..3cf53dc
--- /dev/null
+++ b/Mine/src/pages/magazine/ExplorePage.tsx
@@ -0,0 +1,32 @@
+import { useEffect, useRef } from 'react'
+import ExploreGrid from './components/ExploreGrid'
+import useGetMagazineFeed from '../../hooks/useGetMagazineFeed'
+
+export default function ExplorePage() {
+ const { data, fetchNextPage, hasNextPage, isFetchingNextPage } = useGetMagazineFeed()
+ const observerRef = useRef(null)
+
+ const magazines = data?.pages.flatMap((page) => page.content) ?? []
+
+ useEffect(() => {
+ const observer = new IntersectionObserver(
+ (entries) => {
+ if (entries[0].isIntersecting && hasNextPage && !isFetchingNextPage) {
+ fetchNextPage()
+ }
+ },
+ { threshold: 0.1 }
+ )
+
+ if (observerRef.current) observer.observe(observerRef.current)
+ return () => observer.disconnect()
+ }, [hasNextPage, isFetchingNextPage, fetchNextPage])
+
+ return (
+
+
+
+ {isFetchingNextPage &&
๋ก๋ฉ์ค...
}
+
+ )
+}
\ No newline at end of file
diff --git a/Mine/src/pages/magazine/MagazinePage.tsx b/Mine/src/pages/magazine/MagazinePage.tsx
new file mode 100644
index 0000000..bec43ba
--- /dev/null
+++ b/Mine/src/pages/magazine/MagazinePage.tsx
@@ -0,0 +1,67 @@
+import { useNavigate, useParams } from 'react-router-dom'
+import SectionCover from './components/SectionCover'
+import useGetMagazineDetail from '../../hooks/useGetMagazineDetail'
+import { GridContainor } from './components/GridContainor'
+import useSidebarStore from '../../stores/sidebar'
+import MagazineInfo from './components/MagazineInfo'
+import { MagazineProvider } from './MagazineProvider'
+
+const isValidUrl = (url?: string) => {
+ if (!url) return false
+ try {
+ const parsed = new URL(url)
+ return parsed.protocol === 'https:'
+ } catch {
+ return false
+ }
+}
+
+export default function MagazinePage() {
+ const { isOpen } = useSidebarStore()
+ const { magazineId } = useParams()
+ const { data, isPending } = useGetMagazineDetail(Number(magazineId))
+ const navigate = useNavigate()
+
+ const handleSectionClick = (magazineId: number, sectionId: number) => {
+ navigate(`/magazine/${magazineId}/section/${sectionId}`)
+ }
+
+ if (isPending) return <>>
+ if (!data) return <>>
+
+ const safeCoverImageUrl = isValidUrl(data.coverImageUrl) ? data.coverImageUrl : ''
+ const content = data?.sections
+
+ return (
+
+
+
+ {data.user && (
+
+
+
+ )}
+
+
+ {content?.map((item) => (
+ handleSectionClick(Number(magazineId), item.sectionId)}
+ />
+ ))}
+
+
+
+
+
+ )
+}
diff --git a/Mine/src/pages/magazine/MagazineProvider.tsx b/Mine/src/pages/magazine/MagazineProvider.tsx
new file mode 100644
index 0000000..ad48c34
--- /dev/null
+++ b/Mine/src/pages/magazine/MagazineProvider.tsx
@@ -0,0 +1,15 @@
+import { createContext, useContext, type ReactNode } from 'react'
+import type { ResponseMagazineDetail } from '../../types/magazine'
+import useGetMagazineDetail from '../../hooks/useGetMagazineDetail'
+
+// components/magazine/MagazineProvider.tsx
+const MagazineContext = createContext(null)
+
+export function MagazineProvider({ id, children }: { id: number; children: ReactNode }) {
+ const { data } = useGetMagazineDetail(id) // ์ด๋ฏธ ์บ์ฑ๋ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ด
+
+ return {children}
+}
+
+// ํ์ ์ด๋์๋ ๊บผ๋ด ์ฐ๋ ์ปค์คํ
ํ
+export const useMagazine = () => useContext(MagazineContext)
diff --git a/Mine/src/pages/magazine/SavedMagazinePage.tsx b/Mine/src/pages/magazine/SavedMagazinePage.tsx
new file mode 100644
index 0000000..21d5195
--- /dev/null
+++ b/Mine/src/pages/magazine/SavedMagazinePage.tsx
@@ -0,0 +1,66 @@
+import { useState } from 'react'
+import SavedMagazineItem from './components/SavedMagazineItem'
+import ArrowPagination from './components/ArrowPagination'
+import useGetLikedMagazineList from '../../hooks/useGetLikedMagazineList'
+
+const CARD_WIDTH = 476
+const GAP = 16
+const COLUMN_STEP = CARD_WIDTH + GAP
+const ITEMS_PER_COLUMN = 2
+
+export default function SavedMagazinePage() {
+ const [columnIndex, setColumnIndex] = useState(0)
+
+ const { data, isLoading, isError } = useGetLikedMagazineList({
+ page: 0,
+ size: 20,
+ sort: ['createdAt,desc'],
+ })
+
+ if (isLoading) return ๋ก๋ฉ์ค...
+ if (isError) return ๋ถ๋ฌ์ค๊ธฐ ์คํจ
+
+ const magazines = data?.content ?? []
+
+ if (magazines.length === 0) {
+ return ์ฐํ ๋งค๊ฑฐ์ง์ด ์์ง ์์ด์.
+ }
+
+ const columns = Array.from({ length: Math.ceil(magazines.length / ITEMS_PER_COLUMN) }, (_, i) =>
+ magazines.slice(i * ITEMS_PER_COLUMN, i * ITEMS_PER_COLUMN + ITEMS_PER_COLUMN),
+ )
+
+ const TOTAL_COLUMNS = columns.length
+
+ return (
+
+
+
+
+
+
+
+ {columns.map((col, colIdx) => (
+
+ {col.map((magazine) => (
+
+ ))}
+
+ ))}
+
+
+
+
+
setColumnIndex((prev) => Math.min(prev + 1, TOTAL_COLUMNS - 1))}
+ onPrev={() => setColumnIndex((prev) => Math.max(prev - 1, 0))}
+ />
+
+
+ )
+}
\ No newline at end of file
diff --git a/Mine/src/pages/magazine/SectionPage.tsx b/Mine/src/pages/magazine/SectionPage.tsx
new file mode 100644
index 0000000..725aeac
--- /dev/null
+++ b/Mine/src/pages/magazine/SectionPage.tsx
@@ -0,0 +1,15 @@
+import { useParams } from 'react-router-dom'
+import { MagazineProvider } from './MagazineProvider'
+import SectionContent from './components/SectionContent'
+
+export default function SectionPage() {
+ const { magazineId, sectionId } = useParams()
+
+ const id = Number(magazineId)
+
+ return (
+
+
+
+ )
+}
diff --git a/Mine/src/pages/magazine/components/ArrowPagination.tsx b/Mine/src/pages/magazine/components/ArrowPagination.tsx
new file mode 100644
index 0000000..1f3a2b6
--- /dev/null
+++ b/Mine/src/pages/magazine/components/ArrowPagination.tsx
@@ -0,0 +1,36 @@
+import ArrowIcon from '../../../icon/swipe.svg?react'
+
+interface Props {
+ currentPage: number
+ totalPages: number
+ onNext: () => void
+ onPrev: () => void
+}
+
+const HALF_DISTANCE = 600
+
+export default function ArrowPagination({ currentPage, totalPages, onNext, onPrev }: Props) {
+ return (
+ <>
+ {currentPage > 1 && (
+
+ )}
+
+ {currentPage < totalPages && (
+
+ )}
+ >
+ )
+}
diff --git a/Mine/src/pages/magazine/components/ExploreGrid.tsx b/Mine/src/pages/magazine/components/ExploreGrid.tsx
new file mode 100644
index 0000000..9cb5603
--- /dev/null
+++ b/Mine/src/pages/magazine/components/ExploreGrid.tsx
@@ -0,0 +1,16 @@
+import ExploreItem from './ExploreItem'
+import type { Magazine } from '../../../types/magazine'
+
+interface ExploreGridProps {
+ magazines: Magazine[]
+}
+
+export default function ExploreGrid({ magazines }: ExploreGridProps) {
+ return (
+
+ {magazines.map((magazine) => (
+
+ ))}
+
+ )
+}
\ No newline at end of file
diff --git a/Mine/src/pages/magazine/components/ExploreItem.tsx b/Mine/src/pages/magazine/components/ExploreItem.tsx
new file mode 100644
index 0000000..c786cb4
--- /dev/null
+++ b/Mine/src/pages/magazine/components/ExploreItem.tsx
@@ -0,0 +1,29 @@
+import { useNavigate } from 'react-router-dom'
+import type { Magazine } from '../../../types/magazine'
+import { isValidUrl } from '../../../utils/url'
+
+type Props = {
+ magazine: Magazine
+}
+
+export default function ExploreItem({ magazine }: Props) {
+ const navigate = useNavigate()
+ const safeImageUrl = isValidUrl(magazine.coverImageUrl) ? magazine.coverImageUrl : ''
+
+ return (
+ navigate(`/magazine/${magazine.magazineId}`)}
+ >
+
+ {magazine.title}
+
+
+ )
+}
\ No newline at end of file
diff --git a/Mine/src/pages/magazine/components/GridContainor.tsx b/Mine/src/pages/magazine/components/GridContainor.tsx
new file mode 100644
index 0000000..2b48d3b
--- /dev/null
+++ b/Mine/src/pages/magazine/components/GridContainor.tsx
@@ -0,0 +1,17 @@
+import React from 'react'
+import { GRID_ITEM_LAYOUT_PRESETS, GRID_LAYOUT_PRESENT } from '../../../style/gridpattern'
+
+export const GridContainor = ({ children }: { children: React.ReactNode }) => {
+ const count = React.Children.count(children)
+ const itemPattern = GRID_ITEM_LAYOUT_PRESETS[count] || []
+ const layoutClass = GRID_LAYOUT_PRESENT[count] || 'grid-cols-4'
+ return (
+
+ {React.Children.map(children, (child, index) => (
+
+ {child}
+
+ ))}
+
+ )
+}
diff --git a/Mine/src/pages/magazine/components/HeartCount.tsx b/Mine/src/pages/magazine/components/HeartCount.tsx
new file mode 100644
index 0000000..b2c2af8
--- /dev/null
+++ b/Mine/src/pages/magazine/components/HeartCount.tsx
@@ -0,0 +1,24 @@
+// import { useState } from 'react'
+import usePostHeart from '../../../hooks/usePostHeart'
+import Heart from '../../../icon/heart.svg?react'
+interface HeartCountProps {
+ hearts?: number
+ magazineId?: number
+ classname?: string
+}
+
+export default function HeartCount({ hearts, magazineId, classname }: HeartCountProps) {
+ // const [localLikeCount, setLocalLikeCount] = useState(Number(hearts))
+ const postMutation = usePostHeart()
+ const handleHeartClick = async () => {
+ // setLocalLikeCount((prev) => prev + 1)
+ postMutation.mutate(Number(magazineId))
+ }
+
+ return (
+
+ )
+}
diff --git a/Mine/src/pages/magazine/components/MagazineInfo.tsx b/Mine/src/pages/magazine/components/MagazineInfo.tsx
new file mode 100644
index 0000000..02e186a
--- /dev/null
+++ b/Mine/src/pages/magazine/components/MagazineInfo.tsx
@@ -0,0 +1,59 @@
+import Hamburger from '../../../icon/hamburger.svg?react'
+import ProfileBox from './ProfileBox'
+import { useState } from 'react'
+import SectionHamburgerModal from '../../../components/hamburgerModal/SectionHamburgerModal'
+import HeartCount from './HeartCount'
+import { useMagazine } from '../MagazineProvider'
+
+interface MagazineInfoProps {
+ nickname?: string
+ profileImage?: string
+ magazineId?: number
+ sectionId?: number
+ mode: 'section' | 'magazine'
+ onClick?: (magazineId: number) => void
+}
+export default function MagazineInfo({ nickname, profileImage, sectionId, mode, onClick }: MagazineInfoProps) {
+ const magazinedata = useMagazine()
+ const [modalPos, setModalPos] = useState({ top: 0, left: 0 })
+ const [isHamburgerOpen, setIsHamburgerOpen] = useState(false)
+ const openHamburger = () => setIsHamburgerOpen(true)
+ const closeHamburger = () => setIsHamburgerOpen(false)
+ const handleHamburger = (e: React.MouseEvent) => {
+ const rect = e.currentTarget.getBoundingClientRect()
+ setModalPos({
+ top: rect.top + window.scrollY,
+ left: rect.right + 10,
+ })
+ openHamburger()
+ }
+ return (
+
+
+
magazinedata?.magazineId && onClick?.(magazinedata.magazineId)}
+ >
+ {magazinedata?.title}
+
+
+ {isHamburgerOpen && magazinedata?.magazineId !== undefined && sectionId !== undefined && (
+
+ )}
+
+
+
+
+ )
+}
diff --git a/Mine/src/pages/magazine/components/ParagraphPart.tsx b/Mine/src/pages/magazine/components/ParagraphPart.tsx
new file mode 100644
index 0000000..077dfcb
--- /dev/null
+++ b/Mine/src/pages/magazine/components/ParagraphPart.tsx
@@ -0,0 +1,72 @@
+import { useState } from 'react'
+import Hamburger from '../../../icon/hamburger.svg?react'
+import parse from 'html-react-parser'
+import ParagraphHamburgerModal from '../../../components/hamburgerModal/ParagraphHamburgerModal'
+import { useMagazine } from '../MagazineProvider'
+
+interface ParagraphPartProps {
+ paragrahId?: number
+ sectionId?: number
+ sectionDir?: string
+ titleDir?: string
+ size?: string
+ smallTitle?: string
+ content: string
+ imageUrl?: string
+}
+
+export default function ParagraphPart({
+ paragrahId,
+ sectionId,
+ sectionDir,
+ titleDir,
+ size,
+ smallTitle,
+ content,
+ imageUrl,
+}: ParagraphPartProps) {
+ const magazinedata = useMagazine()
+
+ const htmlcontent = content
+ const [modalPos, setModalPos] = useState({ top: 0, left: 0 })
+ const [isHamburgerOpen, setIsHamburgerOpen] = useState(false)
+ const openHamburger = () => setIsHamburgerOpen(true)
+ const closeHamburger = () => setIsHamburgerOpen(false)
+
+ const handleHamburger = (e: React.MouseEvent) => {
+ const rect = e.currentTarget.getBoundingClientRect()
+ setModalPos({
+ top: rect.top + window.scrollY,
+ left: rect.right + 10,
+ })
+ openHamburger()
+ }
+ return (
+
+
+
+
+
{smallTitle}
+
+ {isHamburgerOpen && (
+
+ )}
+
+
+ {parse(htmlcontent)}
+
+
+
+ )
+}
diff --git a/Mine/src/pages/magazine/components/ProfileBox.tsx b/Mine/src/pages/magazine/components/ProfileBox.tsx
new file mode 100644
index 0000000..4168144
--- /dev/null
+++ b/Mine/src/pages/magazine/components/ProfileBox.tsx
@@ -0,0 +1,17 @@
+interface ProfileBoxProps {
+ nickname?: string
+ profileImage?: string
+ classname?: string
+ mode?: 'magazine' | 'section'
+}
+
+export default function ProfileBox({ nickname, profileImage, classname, mode }: ProfileBoxProps) {
+ return (
+
+
+ {nickname}
+
+

+
+ )
+}
diff --git a/Mine/src/pages/magazine/components/SavedMagazineGrid.tsx b/Mine/src/pages/magazine/components/SavedMagazineGrid.tsx
new file mode 100644
index 0000000..9d580a6
--- /dev/null
+++ b/Mine/src/pages/magazine/components/SavedMagazineGrid.tsx
@@ -0,0 +1,23 @@
+import SavedMagazineItem from './SavedMagazineItem'
+import type { Magazine } from '../../../types/magazine'
+
+interface Props {
+ itemsPerPage: number
+ currentPage: number
+ magazines: Magazine[]
+}
+
+export default function SavedMagazineGrid({ itemsPerPage, currentPage, magazines }: Props) {
+ const start = (currentPage - 1) * itemsPerPage
+ const end = start + itemsPerPage
+
+ const pageItems = magazines.slice(start, end)
+
+ return (
+
+ {pageItems.map((magazine) => (
+
+ ))}
+
+ )
+}
diff --git a/Mine/src/pages/magazine/components/SavedMagazineItem.tsx b/Mine/src/pages/magazine/components/SavedMagazineItem.tsx
new file mode 100644
index 0000000..874158c
--- /dev/null
+++ b/Mine/src/pages/magazine/components/SavedMagazineItem.tsx
@@ -0,0 +1,36 @@
+import { useNavigate } from 'react-router-dom'
+import type { Magazine } from '../../../types/magazine'
+
+type Props = {
+ magazine: Magazine
+}
+
+const isValidUrl = (url: string) => {
+ try {
+ const parsed = new URL(url)
+ return parsed.protocol === 'https:'
+ } catch {
+ return false
+ }
+}
+
+export default function SavedMagazineItem({ magazine }: Props) {
+ const navigate = useNavigate()
+ const safeImageUrl = isValidUrl(magazine.coverImageUrl) ? magazine.coverImageUrl : ''
+
+ return (
+ navigate(`/magazine/${magazine.magazineId}`)}
+ >
+
+ {magazine.title}
+
+
+ )
+}
\ No newline at end of file
diff --git a/Mine/src/pages/magazine/components/SectionContent.tsx b/Mine/src/pages/magazine/components/SectionContent.tsx
new file mode 100644
index 0000000..13077b4
--- /dev/null
+++ b/Mine/src/pages/magazine/components/SectionContent.tsx
@@ -0,0 +1,59 @@
+import useGetSectionDetail from '../../../hooks/useGetSectionDetail'
+import { useMagazine } from '../MagazineProvider'
+import MagazineInfo from './MagazineInfo'
+import SectionIndexList from './SectionIndexList'
+import ParagraphPart from './ParagraphPart'
+import useSidebarStore from '../../../stores/sidebar'
+import { useNavigate } from 'react-router-dom'
+
+interface SectionContentProps {
+ sectionId: number
+ magazineId: number
+}
+
+export default function SectionContent({ sectionId, magazineId }: SectionContentProps) {
+ const { isOpen } = useSidebarStore()
+ const magazinedata = useMagazine()
+ const navigate = useNavigate()
+ const { data, isLoading } = useGetSectionDetail(Number(magazineId), Number(sectionId))
+ const user = magazinedata?.user
+ const content = data?.paragraphs
+
+ const handleClick = (magazineId: number) => {
+ navigate(`/magazine/${magazineId}`)
+ }
+ if (isLoading) {
+ return <>>
+ }
+
+ return (
+
+
+
+
+
+
+ {content?.map((content) => (
+
+ ))}
+
+
+
+ )
+}
diff --git a/Mine/src/pages/magazine/components/SectionCover.tsx b/Mine/src/pages/magazine/components/SectionCover.tsx
new file mode 100644
index 0000000..a2c09dd
--- /dev/null
+++ b/Mine/src/pages/magazine/components/SectionCover.tsx
@@ -0,0 +1,15 @@
+interface SectionCoverProps {
+ size?: string
+ onclick?: () => void
+ imageUrl?: string
+}
+
+export default function SectionCover({ imageUrl, size, onclick }: SectionCoverProps) {
+ return (
+
+ )
+}
diff --git a/Mine/src/pages/magazine/components/SectionIndexClose.tsx b/Mine/src/pages/magazine/components/SectionIndexClose.tsx
new file mode 100644
index 0000000..4a06c6a
--- /dev/null
+++ b/Mine/src/pages/magazine/components/SectionIndexClose.tsx
@@ -0,0 +1,22 @@
+import { useNavigate } from 'react-router-dom'
+
+interface SectionIndexProps {
+ title: string
+ sectionId: number
+ magazineId?: number
+}
+
+export default function SectionIndexClose({ title, sectionId, magazineId }: SectionIndexProps) {
+ const navigate = useNavigate()
+ const onClickhandle = () => {
+ navigate(`/magazine/${magazineId}/section/${sectionId}`)
+ }
+ return (
+
+ )
+}
diff --git a/Mine/src/pages/magazine/components/SectionIndexList.tsx b/Mine/src/pages/magazine/components/SectionIndexList.tsx
new file mode 100644
index 0000000..a47ed98
--- /dev/null
+++ b/Mine/src/pages/magazine/components/SectionIndexList.tsx
@@ -0,0 +1,47 @@
+import { useMagazine } from '../MagazineProvider'
+import SectionIndexClose from './SectionIndexClose'
+import SectionIndexOpen from './SectionIndexOpen'
+
+interface SectionIndexListProps {
+ sectionId: number
+}
+
+export default function SectionIndexList({ sectionId }: SectionIndexListProps) {
+ const magazinedata = useMagazine()
+ const sections = magazinedata?.sections
+
+ return (
+ /* 1. ์ธ๋ฑ์ค ๋ฆฌ์คํธ ์ ์ฒด๋ฅผ ๊ฐ์ธ๋ ์ปจํ
์ด๋ */
+
+ {sections?.map((section) => {
+ const isOpen = section.sectionId === sectionId
+
+ return (
+
+ {/* 2. ๊ฐ์ง ๋ฒฝ (Fake Wall) */}
+ {/* Close ์ํ์ผ ๋๋ง ๋ํ๋์ ์ธ๋ฑ์ค์ ์ผ์ชฝ ์ผ๋ถ๋ฅผ ๋ฎ์ */}
+ {!isOpen && (
+
+ )}
+
+ {/* 3. ์ค์ ์ธ๋ฑ์ค ์์ดํ
*/}
+
+ {isOpen ? (
+
+ ) : (
+
+ )}
+
+
+ )
+ })}
+
+ )
+}
diff --git a/Mine/src/pages/magazine/components/SectionIndexOpen.tsx b/Mine/src/pages/magazine/components/SectionIndexOpen.tsx
new file mode 100644
index 0000000..c3eb147
--- /dev/null
+++ b/Mine/src/pages/magazine/components/SectionIndexOpen.tsx
@@ -0,0 +1,11 @@
+interface SectionIndexProps {
+ title: string
+}
+
+export default function SectionIndexOpen({ title }: SectionIndexProps) {
+ return (
+
+ )
+}
diff --git a/Mine/src/pages/main/GuestPage.tsx b/Mine/src/pages/main/GuestPage.tsx
new file mode 100644
index 0000000..0e74d61
--- /dev/null
+++ b/Mine/src/pages/main/GuestPage.tsx
@@ -0,0 +1,86 @@
+import { useNavigate } from 'react-router-dom'
+import bg1 from '../../assets/bg1.jpg'
+import bg2 from '../../assets/bg2.jpg'
+import lookaround1 from '../../assets/lookaround1.jpg'
+import lookaround2 from '../../assets/lookaround2.jpg'
+import lookaround3 from '../../assets/lookaround3.jpg'
+import lookaround4 from '../../assets/lookaround4.jpg'
+import lookaround5 from '../../assets/lookaround5.jpg'
+import lookaround6 from '../../assets/lookaround6.jpg'
+
+const dummyMagazines = [
+ { id: 1, title: '์คํค ํ ๋ ์ฃผ์ํ ์ ', image: lookaround1 },
+ { id: 2, title: '๋๋ฌด ํ ๊ทธ๋ฃจ', image: lookaround2 },
+ { id: 3, title: '๋ง์นด๋กฑ 3๊ฐ', image: lookaround3 },
+ { id: 4, title: '2025 ๋ธ๋๋ ๋ฆฌ๋ธ๋๋ฉ', image: lookaround4 },
+ { id: 5, title: '์ถ์ฒํ๋ ๋ฒ ์คํธ ์
๋ฌ', image: lookaround5 },
+ { id: 6, title: '์ฒ์ ์ด์ผ๊ธฐ๋ฅผ ๋ค์ด๋ด์', image: lookaround6 },
+]
+
+export default function GuestPage() {
+ const navigate = useNavigate()
+
+ const handleStart = () => {
+ sessionStorage.setItem('landingBg', bg1)
+ navigate('/login', { state: { bgUrl: bg1 } })
+ }
+
+ return (
+
+
+
+
+
+
+
+ {dummyMagazines.map((magazine) => (
+
+

+
+
+ {magazine.title}
+
+
+ ))}
+
+
+
+ ๋ค๋ฅธ ๋งค๊ฑฐ์ง๋ค์ด ๊ถ๊ธํ๊ฐ์?
+
+ ํ์๊ฐ์
ํ๊ณ ๋๋ง์ ๋งค๊ฑฐ์ง์ ๋ง๋ค์ด ๋ณด์ธ์.
+
+
+
+
+ )
+}
diff --git a/Mine/src/pages/main/MainPage.tsx b/Mine/src/pages/main/MainPage.tsx
new file mode 100644
index 0000000..09a9c4e
--- /dev/null
+++ b/Mine/src/pages/main/MainPage.tsx
@@ -0,0 +1,54 @@
+import { useState } from 'react'
+import usePostMagazine from '../../hooks/usePostMagazine'
+import GuestPage from './GuestPage'
+import landingBg from '../../assets/bg1.jpg'
+import NewMagazineInput from '../../components/NewMagazineInput'
+import MakingLoadingPage from './MakingLoadingPage'
+import { useAuthStore } from '../../stores/auth'
+
+export default function MainPage() {
+ const postMagazineMutation = usePostMagazine()
+ const isPending = postMagazineMutation.isPending
+ const [topic, setTopic] = useState('')
+ const [userMood, setUserMood] = useState('')
+ const { isLoggedIn } = useAuthStore()
+
+ if (!isLoggedIn) return
+
+ const handleSend = () => {
+ if (!topic.trim()) return
+ postMagazineMutation.mutate({ topic: topic, user_mood: userMood })
+ }
+
+ return (
+
+
+
+
๋๋ง์ ๋งค๊ฑฐ์ง์ ๋ง๋ค์ด๋ณผ๊น์?
+
+
+
+
+
+
+ {isPending &&
}
+
+ )
+}
diff --git a/Mine/src/pages/main/MakingLoadingPage.tsx b/Mine/src/pages/main/MakingLoadingPage.tsx
new file mode 100644
index 0000000..10ca605
--- /dev/null
+++ b/Mine/src/pages/main/MakingLoadingPage.tsx
@@ -0,0 +1,10 @@
+export default function MakingLoadingPage() {
+ return (
+
+
+
+ ๋น์ ๋ง์ ์ํ ๋งค๊ฑฐ์ง์ ๋ง๋ค๊ณ ์์ด์...
+
+
+ )
+}
diff --git a/Mine/src/pages/signup/SignupPage.tsx b/Mine/src/pages/signup/SignupPage.tsx
new file mode 100644
index 0000000..786f1ce
--- /dev/null
+++ b/Mine/src/pages/signup/SignupPage.tsx
@@ -0,0 +1,134 @@
+import { useState, useMemo } from 'react'
+import { useLocation, useNavigate } from 'react-router-dom'
+
+import logo from '../../icon/minelogo.svg?url'
+import SignupChecks from './components/SignupChecks'
+import SignupForms from './components/SignupForms'
+import SignupInterests from './components/SignupInterest'
+import usePostSignup from '../../hooks/usePostSignup'
+
+export default function SignupPage() {
+ const location = useLocation()
+ const navigate = useNavigate()
+
+ const bgUrl = (location.state as { bgUrl?: string } | null)?.bgUrl ?? sessionStorage.getItem('landingBg') ?? ''
+
+ const [step, setStep] = useState(1)
+ const { mutate: signup, isPending } = usePostSignup()
+
+ const [signupForm, setSignupForm] = useState({
+ nickname: '',
+ id: '',
+ password: '',
+ passwordCheck: '',
+ email: '',
+ interests: [] as string[],
+ })
+
+ const handleChange = (e: React.ChangeEvent) => {
+ const { id, value } = e.target
+ setSignupForm((prev) => ({ ...prev, [id]: value }))
+ }
+
+ const handleInterestsChange = (newInterests: string[]) => {
+ setSignupForm((prev) => ({ ...prev, interests: newInterests }))
+ }
+
+ const handleSignupSubmit = () => {
+ if (isPending) return
+ signup({
+ nickname: signupForm.nickname,
+ username: signupForm.id,
+ password: signupForm.password,
+ email: signupForm.email,
+ interests: signupForm.interests,
+ })
+ }
+
+ const goNext = () => setStep((s) => Math.min(3, s + 1))
+ const goPrev = () => setStep((s) => Math.max(1, s - 1))
+
+ const canGoNext1 =
+ signupForm.id.trim() !== '' && signupForm.nickname.trim() !== '' && signupForm.email.trim() !== ''
+
+ const isValidPassword = useMemo(() => {
+ const pw = signupForm.password
+ if (pw.length < 8 || pw.length > 16) return false
+ return /[A-Za-z]/.test(pw) && /[0-9]/.test(pw)
+ }, [signupForm.password])
+
+ const canGoNext2 = isValidPassword && !!signupForm.passwordCheck && signupForm.password === signupForm.passwordCheck
+
+ const canSubmit3 = signupForm.interests.length > 0
+
+ const handlePrevClick = () => {
+ if (step === 1) navigate('/login')
+ else goPrev()
+ }
+
+ const handleNextClick = () => {
+ if (step === 1) goNext()
+ else if (step === 2) goNext()
+ else if (step === 3) handleSignupSubmit()
+ }
+
+ const nextLabel = step === 3 ? '๊ฐ์
ํ๊ธฐ' : '๋ค์์ผ๋ก'
+ const isNextDisabled = (step === 1 && !canGoNext1) || (step === 2 && !canGoNext2) || (step === 3 && !canSubmit3)
+
+ return (
+
+ {/* ๋ฐฐ๊ฒฝ ์ด๋ก๊ฒ */}
+
+
+
+
+ ๋๋ง์ ๋งค๊ฑฐ์ง
+
+ ์์นด์ด๋น
+
+ ํ๋ซํผ
+
+
+
+

+
+
+
+
+ {step === 1 && }
+ {step === 2 && }
+ {step === 3 && (
+
+ )}
+
+
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/Mine/src/pages/signup/components/Chips.tsx b/Mine/src/pages/signup/components/Chips.tsx
new file mode 100644
index 0000000..a48459e
--- /dev/null
+++ b/Mine/src/pages/signup/components/Chips.tsx
@@ -0,0 +1,23 @@
+interface ChipProps {
+ title: string;
+ isActive: boolean;
+ onClick: () => void;
+}
+
+export default function Chip({ title, isActive, onClick }: ChipProps) {
+ return (
+
+ {title}
+
+ );
+}
\ No newline at end of file
diff --git a/Mine/src/pages/signup/components/SignupChecks.tsx b/Mine/src/pages/signup/components/SignupChecks.tsx
new file mode 100644
index 0000000..fa9b3eb
--- /dev/null
+++ b/Mine/src/pages/signup/components/SignupChecks.tsx
@@ -0,0 +1,104 @@
+import { useMemo, useState } from "react";
+import EyeoffIcon from "../../../icon/eyeoff.svg?react";
+
+interface SignupChecksProps {
+ formData: {
+ password: string;
+ passwordCheck: string;
+ };
+ onChange: (e: React.ChangeEvent) => void;
+}
+
+export default function SignupChecks({ formData, onChange }: SignupChecksProps) {
+ const [showPassword, setShowPassword] = useState(false);
+ const [showPasswordCheck, setShowPasswordCheck] = useState(false);
+
+ const isValidPassword = useMemo(() => {
+ const pw = formData.password;
+ if (pw.length < 8 || pw.length > 16) return false;
+ return /[A-Za-z]/.test(pw) && /[0-9]/.test(pw);
+ }, [formData.password]);
+
+ const showPwRuleError = useMemo(() => {
+ if (!formData.password) return false;
+ return !isValidPassword;
+ }, [formData.password, isValidPassword]);
+
+ const isMismatch = useMemo(() => {
+ if (!formData.passwordCheck) return false;
+ return formData.password !== formData.passwordCheck;
+ }, [formData.password, formData.passwordCheck]);
+
+ const fieldWrap =
+ "flex items-center w-full h-[48px] py-[20px] px-[18px] " +
+ "rounded-[15px] border border-[#505050] bg-white/30";
+
+ const inputBase =
+ "flex-1 bg-transparent outline-none text-white placeholder:text-white/60";
+
+ return (
+
+
+ {/* ๋น๋ฐ๋ฒํธ */}
+
+
๋น๋ฐ๋ฒํธ
+
+
+
+
+
+ {showPwRuleError ? (
+ ๋น๋ฐ๋ฒํธ๋ 8~16์์ด๋ฉฐ ์์ด์ ์ซ์๋ฅผ ๋ชจ๋ ํฌํจํด์ผ ํฉ๋๋ค.
+ ) : (
+ ์์ด, ์ซ์ ํฌํจ 8~16์
+ )}
+
+
+
+ {/* ๋น๋ฐ๋ฒํธ ํ์ธ */}
+
+
๋น๋ฐ๋ฒํธ ํ์ธ
+
+
+
+
+
+ {isMismatch ? (
+ ๋น๋ฐ๋ฒํธ๊ฐ ๊ฐ์ง ์์ต๋๋ค
+ ) : (
+
+ )}
+
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/Mine/src/pages/signup/components/SignupForms.tsx b/Mine/src/pages/signup/components/SignupForms.tsx
new file mode 100644
index 0000000..a73d82c
--- /dev/null
+++ b/Mine/src/pages/signup/components/SignupForms.tsx
@@ -0,0 +1,61 @@
+import type { ChangeEvent } from "react";
+
+interface SignupFormsProps {
+ formData: {
+ nickname: string;
+ id: string;
+ password: string;
+ passwordCheck: string;
+ email: string;
+ };
+ onChange: (e: ChangeEvent) => void;
+}
+
+export default function SignupForms({ formData, onChange }: SignupFormsProps) {
+ return (
+
+
+
+
์์ด๋
+
+
์์ด, ์ซ์ ํฌํจ 6~20์
+
+
+
+
๋๋ค์
+
+
ํ๊ธ 2~6์
+
+
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/Mine/src/pages/signup/components/SignupInterest.tsx b/Mine/src/pages/signup/components/SignupInterest.tsx
new file mode 100644
index 0000000..6cdd8ec
--- /dev/null
+++ b/Mine/src/pages/signup/components/SignupInterest.tsx
@@ -0,0 +1,54 @@
+import Chip from "./Chips";
+import useGetInterests from "../../../hooks/useGetInterests";
+
+interface Props {
+ interests: string[];
+ onChange: (interests: string[]) => void;
+}
+
+export default function SignupInterests({ interests, onChange }: Props) {
+ const { data: categories, isLoading } = useGetInterests();
+
+ const toggleInterest = (code: string) => {
+ if (interests.includes(code)) {
+ onChange(interests.filter((i) => i !== code));
+ } else {
+ if (interests.length >= 3) return;
+ onChange([...interests, code]);
+ }
+ };
+
+ if (isLoading) {
+ return ๋ถ๋ฌ์ค๋ ์ค...
;
+ }
+
+ return (
+
+
+
+ ๊ด์ฌ์ฌ{" "}
+
+ ์ต๋ 3๊ฐ๋ฅผ ์ ํํด ์ฃผ์ธ์.
+
+
+
+
+
+ {categories?.map((item) => (
+ toggleInterest(item.code)}
+ />
+ ))}
+
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/Mine/src/router/router.tsx b/Mine/src/router/router.tsx
new file mode 100644
index 0000000..be1db1c
--- /dev/null
+++ b/Mine/src/router/router.tsx
@@ -0,0 +1,29 @@
+import { createBrowserRouter } from 'react-router-dom'
+import MainPage from '../pages/main/MainPage'
+import MagazinePage from '../pages/magazine/MagazinePage'
+import LoginPage from '../pages/login/LoginPage'
+import FindingPage from '../pages/login/FindingPage'
+import SignupPage from '../pages/signup/SignupPage'
+import LandingPage from '../pages/landing/LandingPage'
+import ExplorePage from '../pages/magazine/ExplorePage'
+import SavedMagazinePage from '../pages/magazine/SavedMagazinePage'
+import RootLayout from '../layout/RootLayout'
+import SectionPage from '../pages/magazine/SectionPage'
+
+export const router = createBrowserRouter([
+ {
+ path: '/',
+ element: ,
+ children: [
+ { index: true, element: },
+ { path: 'magazine/:magazineId', element: },
+ { path: 'magazine/:magazineId/section/:sectionId', element: },
+ { path: 'magazine/explore', element: },
+ { path: 'magazine/saved', element: },
+ { path: '/landing', element: },
+ { path: '/login', element: },
+ { path: '/login/finding', element: },
+ { path: '/signup', element: },
+ ],
+ },
+])
diff --git a/Mine/src/stores/auth.ts b/Mine/src/stores/auth.ts
new file mode 100644
index 0000000..ac7c0b6
--- /dev/null
+++ b/Mine/src/stores/auth.ts
@@ -0,0 +1,31 @@
+import { create } from 'zustand'
+
+interface AuthState {
+ isLoggedIn: boolean
+ // ๋ก๊ทธ์ธ ์ก์
(ํ ํฐ์ ๋ฐ์์ ์ ์ฅํ๊ณ ์ํ ๋ณ๊ฒฝ)
+ login: (token: string) => void
+ // ๋ก๊ทธ์์ ์ก์
(ํ ํฐ ์ง์ฐ๊ณ ์ํ ๋ณ๊ฒฝ)
+ logout: () => void
+ // ์๋ก๊ณ ์นจ ์ ์ํ ๋ณต๊ตฌ๋ฅผ ์ํ ํจ์ (์ ํ ์ฌํญ)
+ checkLoginStatus: () => void
+}
+
+export const useAuthStore = create((set) => ({
+ //Next.js(SSR) ์๋ฌ๋ฅผ ๋ง๊ธฐ ์ํด window ๊ฐ์ฒด ํ์ธ ํ ๋ก์ปฌ์คํ ๋ฆฌ์ง ์ฒดํฌ
+ isLoggedIn: typeof window !== 'undefined' ? !!localStorage.getItem('accessToken') : false,
+
+ login: (token) => {
+ localStorage.setItem('accessToken', token)
+ set({ isLoggedIn: true })
+ },
+
+ logout: () => {
+ localStorage.removeItem('accessToken')
+ set({ isLoggedIn: false })
+ },
+ //์ฑ ์ด๊ธฐํ ์ ์คํ(ํ์ ์ App ์ต์๋จ์์ ํ ๋ฒ ํธ์ถ)
+ checkLoginStatus: () => {
+ const token = typeof window !== 'undefined' ? localStorage.getItem('accessToken') : null
+ set({ isLoggedIn: !!token })
+ },
+}))
diff --git a/Mine/src/stores/sidebar.ts b/Mine/src/stores/sidebar.ts
new file mode 100644
index 0000000..137cfd0
--- /dev/null
+++ b/Mine/src/stores/sidebar.ts
@@ -0,0 +1,15 @@
+import { create } from 'zustand'
+
+interface SidebarState {
+ isOpen: boolean
+ setIsOpen: (val: boolean) => void
+ toggleSidebar: () => void
+}
+
+const useSidebarStore = create((set) => ({
+ isOpen: false,
+ setIsOpen: (val) => set({ isOpen: val }),
+ toggleSidebar: () => set((state) => ({ isOpen: !state.isOpen })),
+}))
+
+export default useSidebarStore
diff --git a/Mine/src/stores/user.ts b/Mine/src/stores/user.ts
new file mode 100644
index 0000000..0db2517
--- /dev/null
+++ b/Mine/src/stores/user.ts
@@ -0,0 +1,18 @@
+import { create } from 'zustand'
+import type { ResponseProfile } from '../types/user'
+
+interface UserState {
+ user: ResponseProfile | null // ์ด๊ธฐ๊ฐ์ ๋ฐ์ดํฐ๊ฐ ์์ผ๋ฏ๋ก null
+ isLoading: boolean
+ setUser: (userData: ResponseProfile) => void
+ clearUser: () => void
+}
+
+const useUserStore = create((set) => ({
+ user: null,
+ isLoading: false,
+ setUser: (userData) => set({ user: userData }),
+ clearUser: () => set({ user: null }),
+}))
+
+export default useUserStore
diff --git a/Mine/src/style/global.css b/Mine/src/style/global.css
new file mode 100644
index 0000000..6b0ef49
--- /dev/null
+++ b/Mine/src/style/global.css
@@ -0,0 +1,98 @@
+@import 'tailwindcss';
+@import './typo.css';
+
+@font-face {
+ font-family: 'Pretendard';
+ src: url('/fonts/Pretendard-Light.woff2') format('woff2');
+ font-weight: 300;
+ font-style: normal;
+}
+
+@font-face {
+ font-family: 'Pretendard';
+ src: url('/fonts/Pretendard-Regular.woff2') format('woff2');
+ font-weight: 400;
+ font-style: normal;
+}
+
+@font-face {
+ font-family: 'Pretendard';
+ src: url('/fonts/Pretendard-Medium.woff2') format('woff2');
+ font-weight: 500;
+ font-style: normal;
+}
+
+@font-face {
+ font-family: 'Pretendard';
+ src: url('/fonts/Pretendard-Bold.woff2') format('woff2');
+ font-weight: 700;
+ font-style: normal;
+}
+@font-face {
+ font-family: 'Pretendard';
+ src: url('/fonts/Pretendard-SemiBold.woff2') format('woff2');
+ font-weight: 600;
+ font-style: normal;
+}
+
+@font-face {
+ font-family: 'NotoSerif';
+ src: url('/fonts/NotoSerifKR-Medium.ttf');
+ font-weight: 500;
+ font-style: normal;
+}
+
+@font-face {
+ font-family: 'NotoSerif';
+ src: url('/fonts/NotoSerifKR-SemiBold.ttf');
+ font-weight: 600;
+ font-style: normal;
+}
+
+@theme {
+ --font-pretendard: 'Pretendard';
+ --font-notoserif: 'NotoSerif';
+
+ --color-gray-100: #ffffff;
+ --color-gray-200: #d9d9d9;
+ --color-gray-300: #a9a9a9;
+ --color-gray-400: #767676;
+ --color-gray-500: #505050;
+ --color-gray-600: #111111;
+ --color-heart: #f95c40;
+
+ --color-gray-100-op30: #ffffff4d;
+ --color-gray-100-op40: #ffffff66;
+ --color-gray-100-op70: #ffffffb3;
+
+ --color-gray-300-op70: #a9a9a9b3;
+
+ --color-gray-500-op40: #50505066;
+ --color-gray-500-op70: #505050b3;
+
+ --color-gray-600-op30: #1111114d;
+ --color-gray-600-op70: #111111b3;
+}
+html,
+body {
+ font-family: Pretendard, NotoSerif;
+}
+
+@layer utilities {
+ .custom-scrollbar::-webkit-scrollbar {
+ width: 6px; /* ์คํฌ๋กค๋ฐ ๋๊ป */
+ }
+
+ .custom-scrollbar::-webkit-scrollbar-track {
+ background: transparent; /* ํธ๋ ๋ฐฐ๊ฒฝ์ ํฌ๋ช
ํ๊ฒ */
+ }
+
+ .custom-scrollbar::-webkit-scrollbar-thumb {
+ background: #1111114d; /* ์คํฌ๋กค๋ฐ ํธ๋ค ์์ (gray-600 ์ ๋) */
+ border-radius: 10px; /* ํธ๋ค์ ๋ฅ๊ธ๊ฒ */
+ }
+
+ .custom-scrollbar::-webkit-scrollbar-thumb:hover {
+ background: #6b7280; /* ํธ๋ฒ ์ ์์ (gray-500) */
+ }
+}
diff --git a/Mine/src/style/gridpattern.ts b/Mine/src/style/gridpattern.ts
new file mode 100644
index 0000000..3552f5c
--- /dev/null
+++ b/Mine/src/style/gridpattern.ts
@@ -0,0 +1,78 @@
+export const GRID_ITEM_LAYOUT_PRESETS: Record = {
+ 1: ['col-span-2 row-span-4'], // 1๊ฐ์ผ ๋: ์ ์ฒด ๊ฝ ์ฐจ๊ฒ
+ 2: ['col-span-2 row-span-2', 'col-span-2 row-span-2'], // 2๊ฐ์ผ ๋: ๋ฐ๋ฐ
+ 3: ['col-span-2 row-span-1', 'col-span-1 row-span-1', 'col-span-2 row-span-1'],
+ 4: ['col-span-2 row-span-1', 'col-span-1 row-span-1', 'col-span-1 row-span-1', 'col-span-2 row-span-1'],
+ 5: [
+ 'col-span-10 row-span-1',
+ 'col-span-9 row-span-1',
+ 'col-span-6 row-span-1',
+ 'col-span-6 row-span-1',
+ 'col-span-7 row-span-1',
+ ],
+ 6: [
+ 'col-span-4 row-span-1',
+ 'col-span-3 row-span-1',
+ 'col-span-5 row-span-1',
+ 'col-span-5 row-span-1',
+ 'col-span-4 row-span-1',
+ 'col-span-3 row-span-1',
+ ],
+ 7: [
+ 'col-span-5 row-span-1',
+ 'col-span-5 row-span-1',
+ 'col-span-4 row-span-1',
+ 'col-span-4 row-span-1',
+ 'col-span-6 row-span-1',
+ 'col-span-6 row-span-1',
+ 'col-span-6 row-span-1',
+ ],
+ 8: [
+ 'col-span-9 row-span-1',
+ 'col-span-8 row-span-1',
+ 'col-span-8 row-span-1',
+ 'col-span-9 row-span-1',
+ 'col-span-8 row-span-1',
+ 'col-span-9 row-span-1',
+ 'col-span-9 row-span-1',
+ 'col-span-8 row-span-1',
+ ],
+ 9: [
+ 'col-span-2 row-span-5',
+ 'col-span-3 row-span-9',
+ 'col-span-2 row-span-9',
+ 'col-span-2 row-span-9',
+ 'col-span-2 row-span-7',
+ 'col-span-2 row-span-9',
+ 'col-span-2 row-span-9',
+ 'col-span-3 row-span-9',
+ 'col-span-2 row-span-6',
+ ],
+ 10: [
+ 'col-span-2 row-span-5',
+ 'col-span-3 row-span-9',
+ 'col-span-2 row-span-9',
+ 'col-span-2 row-span-6',
+ 'col-span-2 row-span-7',
+ 'col-span-2 row-span-7',
+
+ 'col-span-2 row-span-9',
+ 'col-span-3 row-span-9',
+
+ 'col-span-2 row-span-6',
+ 'col-span-2 row-span-5',
+ ],
+}
+
+export const GRID_LAYOUT_PRESENT: Record = {
+ 1: 'grid-col-1',
+ 2: 'grid-col-1',
+ 3: 'grid-cols-5',
+ 4: 'grid-cols-3 grid-rows-2',
+ 5: 'grid-cols-19 grid-rows-2',
+ 6: 'grid-cols-12 grid-rows-2',
+ 7: 'grid-cols-18 grid-rows-2',
+ 8: 'grid-cols-34 grid-rows-2',
+ 9: 'grid-cols-9 grid-rows-18',
+ 10: 'grid-cols-9 grid-rows-18',
+}
diff --git a/Mine/src/style/typo.css b/Mine/src/style/typo.css
new file mode 100644
index 0000000..15631a7
--- /dev/null
+++ b/Mine/src/style/typo.css
@@ -0,0 +1,44 @@
+@layer components {
+ .font-medium12 {
+ @apply text-[12px] leading-[140%] tracking-[-0.025em] font-medium;
+ }
+ .font-light14 {
+ @apply text-[14px] leading-[140%] tracking-[-0.025em] font-light;
+ }
+ .font-regular14 {
+ @apply text-[14px] leading-[140%] tracking-[-0.025em] font-normal;
+ }
+ .font-medium14 {
+ @apply text-[14px] leading-[140%] tracking-[-0.025em] font-medium;
+ }
+ .font-semibold14 {
+ @apply text-[14px] leading-[140%] tracking-[-0.025em] font-semibold;
+ }
+ .font-regular16 {
+ @apply text-[16px] leading-[180%] tracking-[-0.025em] font-normal;
+ }
+ .font-medium16 {
+ @apply text-[16px] leading-[140%] tracking-[-0.025em] font-medium;
+ }
+ .font-semibold16 {
+ @apply text-[16px] leading-[140%] tracking-[-0.025em] font-semibold;
+ }
+ .font-regular20 {
+ @apply text-[20px] leading-[140%] tracking-[-0.025em] font-normal;
+ }
+ .font-semibold20 {
+ @apply text-[20px] leading-[140%] tracking-[-0.025em] font-semibold;
+ }
+ .font-semibold24 {
+ @apply text-[24px] leading-[140%] tracking-[-0.025em] font-semibold;
+ }
+ .font-bold32 {
+ @apply text-[32px] leading-[140%] tracking-[-0.025em] font-bold;
+ }
+ .font-bold80 {
+ @apply text-[80px] leading-[140%] tracking-[-0.025em] font-bold;
+ }
+ .font-medium36 {
+ @apply text-[36px] leading-[140%] tracking-[-0.025em] font-medium;
+ }
+}
diff --git a/Mine/src/svg.d.ts b/Mine/src/svg.d.ts
new file mode 100644
index 0000000..e2a303b
--- /dev/null
+++ b/Mine/src/svg.d.ts
@@ -0,0 +1,4 @@
+declare module '*.svg' {
+ const content: React.FC>
+ export default content
+}
diff --git a/Mine/src/types/interest.ts b/Mine/src/types/interest.ts
new file mode 100644
index 0000000..121916e
--- /dev/null
+++ b/Mine/src/types/interest.ts
@@ -0,0 +1,8 @@
+export interface InterestItem {
+ id: number
+ code: string
+ name: string
+ category: string
+}
+
+export type ResponseInterestsList = InterestItem[]
diff --git a/Mine/src/types/magazine.ts b/Mine/src/types/magazine.ts
new file mode 100644
index 0000000..7f4cbcb
--- /dev/null
+++ b/Mine/src/types/magazine.ts
@@ -0,0 +1,139 @@
+import type { User } from './user'
+
+export type PageResponse = {
+ totalPages: number
+ totalElements: number
+ pageable: {
+ pageNumber: number
+ pageSize: number
+ offset: number
+ sort: SortInfo
+ paged: boolean
+ unpaged: boolean
+ }
+ size: number
+ content: T[]
+ number: number
+ sort: SortInfo
+ numberOfElements: number
+ first: boolean
+ last: boolean
+ empty: boolean
+}
+
+type SortInfo = {
+ sorted: boolean
+ empty: boolean
+ unsorted: boolean
+}
+
+export type MyMagazinesDto = {
+ page: number
+ size: number
+ sort: string[]
+}
+
+type BaseMagazine = {
+ magazineId: number
+ title: string
+ subtitle: string
+ introduction: string
+ coverImageUrl: string
+ createdAt: string
+}
+
+//๋ชฉ๋ก ์กฐํ๋ฅผ ์ํ ํ์
+export type Magazine = BaseMagazine & {
+ username: string
+ likeCount: number
+ commentCount: number
+}
+
+export type ResponseMyMagazine = PageResponse
+
+export type ResponseMagazineDetail = BaseMagazine & {
+ tags: string
+ moodboardImageUrl: string
+ moodboardDescription: string
+ createdAt: string
+ user: User
+ sections: Section[]
+ likeCount: number
+ // version: number
+}
+
+type Paragraph = {
+ paragraphId: number
+ section: string
+ subtitle: string
+ text: string
+ imageUrl: string
+ displayOrder: 0
+}
+type Section = {
+ sectionId: number
+ heading: string
+ thumbnailUrl: string
+ paragraphs: Paragraph[]
+ imageUrl: string
+ layoutType: string
+ layoutHint: string
+ displayOrder: number
+ magazineId: number
+ magazineTitle: string
+ viewedAt: string
+}
+
+export type RequestDeleteMagazine = {
+ id: number
+}
+
+export type PostMagazineDto = {
+ topic: string
+ user_mood: string
+}
+
+export type PatchMagazineTitleDto = {
+ id: number
+ title: string
+ introduction: string
+}
+
+export type ResponseRecentSection = Section[]
+
+export type SectionDetailDto = BaseSection
+
+type BaseSection = {
+ magazineId: number
+ sectionId: number
+}
+export type DeleteSectionDto = BaseSection
+
+export type ResponseGetSectionDetail = {
+ sectionId: number
+ heading: string
+ paragraphs: Paragraph[]
+ thumnbnail_url: string
+ layout_type: string
+ layout_hint: string
+ caption: string
+ display_order: number
+ // magazineId: number
+ // magazineTitle: string
+ // viewedAt: string
+}
+
+export type DeleteParagraphDto = BaseSection & {
+ paragraphId: number
+}
+
+export type FeedDto = {
+ cursorId?: number | null
+ limit?: number
+}
+
+export type ResponseFeed = {
+ content: Magazine[]
+ nextCursor: number
+ hasNext: boolean
+}
\ No newline at end of file
diff --git a/Mine/src/types/user.ts b/Mine/src/types/user.ts
new file mode 100644
index 0000000..f30c890
--- /dev/null
+++ b/Mine/src/types/user.ts
@@ -0,0 +1,57 @@
+export type AuthorizationDto = {
+ username: string
+ password: string
+}
+
+export type ResponseAuthorization = {
+ accessToken: string
+ tokenType: 'Bearer'
+ refreshToken: string
+ expiresIn: number
+}
+
+export type SignupDto = {
+ username: string
+ email: string
+ password: string
+ nickname: string
+ interests: string[]
+}
+
+export type ResponseProfile = {
+ id: number
+ username: string
+ nickname: string
+ email: string
+ profileImageUrl: string
+ followerCount: number
+ followingCount: number
+ magazineCount: number
+ isPublic: boolean
+ interests: string[]
+ isFollowing: boolean
+}
+export type ProfileDto = {
+ nickname: string
+ username: string
+ profileImage: File | null
+}
+
+export type User = {
+ id: number
+ username: string
+ nickname: string
+ email: string
+ profileImageUrl: string
+ followerCount: number
+ followingCount: number
+ magazineCount: number
+ isPublic: boolean
+ interests: string[]
+ isFollowing: boolean
+ role: 'USER'
+ createdAt: string
+ updatedAt: string
+ deleted: boolean
+ deletedAt: string
+}
diff --git a/Mine/src/utils/url.ts b/Mine/src/utils/url.ts
new file mode 100644
index 0000000..e936dbe
--- /dev/null
+++ b/Mine/src/utils/url.ts
@@ -0,0 +1,9 @@
+export const isValidUrl = (url?: string) => {
+ if (!url) return false
+ try {
+ const parsed = new URL(url)
+ return parsed.protocol === 'https:'
+ } catch {
+ return false
+ }
+}
\ No newline at end of file
diff --git a/Mine/src/vite-env.d.ts b/Mine/src/vite-env.d.ts
new file mode 100644
index 0000000..d816124
--- /dev/null
+++ b/Mine/src/vite-env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/Mine/tsconfig.app.json b/Mine/tsconfig.app.json
new file mode 100644
index 0000000..a9b5a59
--- /dev/null
+++ b/Mine/tsconfig.app.json
@@ -0,0 +1,28 @@
+{
+ "compilerOptions": {
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+ "target": "ES2022",
+ "useDefineForClassFields": true,
+ "lib": ["ES2022", "DOM", "DOM.Iterable"],
+ "module": "ESNext",
+ "types": ["vite/client"],
+ "skipLibCheck": true,
+
+ /* Bundler mode */
+ "moduleResolution": "bundler",
+ "allowImportingTsExtensions": true,
+ "verbatimModuleSyntax": true,
+ "moduleDetection": "force",
+ "noEmit": true,
+ "jsx": "react-jsx",
+
+ /* Linting */
+ "strict": true,
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "erasableSyntaxOnly": true,
+ "noFallthroughCasesInSwitch": true,
+ "noUncheckedSideEffectImports": true
+ },
+ "include": ["src"]
+}
diff --git a/Mine/tsconfig.json b/Mine/tsconfig.json
new file mode 100644
index 0000000..3b6cb28
--- /dev/null
+++ b/Mine/tsconfig.json
@@ -0,0 +1,11 @@
+{
+ "files": [],
+ "include": [ "svg.d.ts"],
+ "references": [
+ { "path": "./tsconfig.app.json" },
+ { "path": "./tsconfig.node.json" }
+ ],
+ "compilerOptions": {
+ "types": ["vite-plugin-svgr/client"]
+ }
+}
diff --git a/Mine/tsconfig.node.json b/Mine/tsconfig.node.json
new file mode 100644
index 0000000..8a67f62
--- /dev/null
+++ b/Mine/tsconfig.node.json
@@ -0,0 +1,26 @@
+{
+ "compilerOptions": {
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+ "target": "ES2023",
+ "lib": ["ES2023"],
+ "module": "ESNext",
+ "types": ["node"],
+ "skipLibCheck": true,
+
+ /* Bundler mode */
+ "moduleResolution": "bundler",
+ "allowImportingTsExtensions": true,
+ "verbatimModuleSyntax": true,
+ "moduleDetection": "force",
+ "noEmit": true,
+
+ /* Linting */
+ "strict": true,
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "erasableSyntaxOnly": true,
+ "noFallthroughCasesInSwitch": true,
+ "noUncheckedSideEffectImports": true
+ },
+ "include": ["vite.config.ts"]
+}
diff --git a/Mine/vercel.json b/Mine/vercel.json
new file mode 100644
index 0000000..effcbd3
--- /dev/null
+++ b/Mine/vercel.json
@@ -0,0 +1,3 @@
+{
+ "routes": [{"src":"/[^.]+", "dest": "/", "status":200}]
+}
\ No newline at end of file
diff --git a/Mine/vite.config.ts b/Mine/vite.config.ts
new file mode 100644
index 0000000..3f971e0
--- /dev/null
+++ b/Mine/vite.config.ts
@@ -0,0 +1,18 @@
+import { defineConfig } from 'vite'
+import react from '@vitejs/plugin-react-swc'
+import tailwindcss from '@tailwindcss/vite'
+import svgr from 'vite-plugin-svgr'
+
+// https://vite.dev/config/
+export default defineConfig({
+ plugins: [react(), tailwindcss(), svgr()],
+ server: {
+ proxy: {
+ '/api': {
+ target: 'http://52.63.142.228:8080',
+ changeOrigin: true,
+ },
+ },
+ },
+})
+