diff --git a/.gitignore b/.gitignore index a547bf3..1ab3c71 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,9 @@ dist dist-ssr *.local +# Environment variables +.env + # Editor directories and files .vscode/* !.vscode/extensions.json @@ -22,3 +25,5 @@ dist-ssr *.njsproj *.sln *.sw? + +*storybook.log diff --git a/.storybook/main.ts b/.storybook/main.ts new file mode 100644 index 0000000..568ce2f --- /dev/null +++ b/.storybook/main.ts @@ -0,0 +1,16 @@ +import type { StorybookConfig } from '@storybook/react-vite'; + +const config: StorybookConfig = { + stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'], + addons: [ + '@storybook/addon-onboarding', + '@storybook/addon-essentials', + '@chromatic-com/storybook', + '@storybook/addon-interactions', + ], + framework: { + name: '@storybook/react-vite', + options: {}, + }, +}; +export default config; diff --git a/.storybook/preview.ts b/.storybook/preview.ts new file mode 100644 index 0000000..838f72d --- /dev/null +++ b/.storybook/preview.ts @@ -0,0 +1,15 @@ +import type { Preview } from '@storybook/react'; +import '../src/styles/reset.css'; + +const preview: Preview = { + parameters: { + controls: { + matchers: { + color: /(background|color)$/i, + date: /Date$/i, + }, + }, + }, +}; + +export default preview; diff --git a/index.html b/index.html index e4b78ea..7457476 100644 --- a/index.html +++ b/index.html @@ -1,8 +1,9 @@ - + + Vite + React + TS diff --git a/package.json b/package.json index 9c80792..771508d 100644 --- a/package.json +++ b/package.json @@ -8,28 +8,61 @@ "build": "tsc -b && vite build", "lint": "eslint .", "preview": "vite preview", - "prepare": "husky" + "prepare": "husky", + "storybook": "storybook dev -p 6006", + "build-storybook": "storybook build" }, "dependencies": { + "@heroicons/react": "^2.2.0", "@reduxjs/toolkit": "^2.4.0", "@tanstack/react-query": "^5.62.2", + "@types/quill": "^2.0.14", + "@types/react-redux": "^7.1.34", + "axios": "^1.7.9", + "dompurify": "^3.2.3", + "jwt-decode": "^4.0.0", + "quill": "^2.0.3", "react": "^18.3.1", "react-dom": "^18.3.1", + "react-hook-form": "^7.54.1", + "react-quill": "^2.0.0", "react-redux": "^9.1.2", "react-router": "^7.0.2", + "redux-persist": "^6.0.0", "styled-components": "^6.1.13" }, "devDependencies": { + "@chromatic-com/storybook": "^3.2.2", "@eslint/js": "^9.15.0", - "@types/react": "^18.3.12", - "@types/react-dom": "^18.3.1", + "@storybook/addon-essentials": "^8.4.7", + "@storybook/addon-interactions": "^8.4.7", + "@storybook/addon-onboarding": "^8.4.7", + "@storybook/blocks": "^8.4.7", + "@storybook/react": "^8.4.7", + "@storybook/react-vite": "^8.4.7", + "@storybook/test": "^8.4.7", + "@types/jwt-decode": "^3.1.0", + "@types/react": "^18.3.14", + "@types/react-dom": "^18.3.2", + "@types/redux-persist": "^4.3.1", "@vitejs/plugin-react": "^4.3.4", "eslint": "^9.15.0", "eslint-plugin-react-hooks": "^5.0.0", "eslint-plugin-react-refresh": "^0.4.14", + "eslint-plugin-storybook": "^0.11.1", "globals": "^15.12.0", + "husky": "^9.1.7", + "msw": "^2.6.8", + "storybook": "^8.4.7", "typescript": "~5.6.2", "typescript-eslint": "^8.15.0", - "vite": "^6.0.1" + "vite": "^6.0.3", + "vite-plugin-svgr": "^4.3.0", + "vitest": "^2.1.8" + }, + "eslintConfig": { + "extends": [ + "plugin:storybook/recommended" + ] } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 475f3a1..263b7b0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,40 +8,100 @@ importers: .: dependencies: + '@heroicons/react': + specifier: ^2.2.0 + version: 2.2.0(react@18.3.1) '@reduxjs/toolkit': specifier: ^2.4.0 version: 2.4.0(react-redux@9.1.2(@types/react@18.3.14)(react@18.3.1)(redux@5.0.1))(react@18.3.1) '@tanstack/react-query': specifier: ^5.62.2 version: 5.62.2(react@18.3.1) + '@types/quill': + specifier: ^2.0.14 + version: 2.0.14 + '@types/react-redux': + specifier: ^7.1.34 + version: 7.1.34 + axios: + specifier: ^1.7.9 + version: 1.7.9 + dompurify: + specifier: ^3.2.3 + version: 3.2.3 + jwt-decode: + specifier: ^4.0.0 + version: 4.0.0 + quill: + specifier: ^2.0.3 + version: 2.0.3 react: specifier: ^18.3.1 version: 18.3.1 react-dom: specifier: ^18.3.1 version: 18.3.1(react@18.3.1) + react-hook-form: + specifier: ^7.54.1 + version: 7.54.1(react@18.3.1) + react-quill: + specifier: ^2.0.0 + version: 2.0.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react-redux: specifier: ^9.1.2 version: 9.1.2(@types/react@18.3.14)(react@18.3.1)(redux@5.0.1) react-router: specifier: ^7.0.2 version: 7.0.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + redux-persist: + specifier: ^6.0.0 + version: 6.0.0(react@18.3.1)(redux@5.0.1) styled-components: specifier: ^6.1.13 version: 6.1.13(react-dom@18.3.1(react@18.3.1))(react@18.3.1) devDependencies: + '@chromatic-com/storybook': + specifier: ^3.2.2 + version: 3.2.2(react@18.3.1)(storybook@8.4.7) '@eslint/js': specifier: ^9.15.0 version: 9.16.0 + '@storybook/addon-essentials': + specifier: ^8.4.7 + version: 8.4.7(@types/react@18.3.14)(storybook@8.4.7) + '@storybook/addon-interactions': + specifier: ^8.4.7 + version: 8.4.7(storybook@8.4.7) + '@storybook/addon-onboarding': + specifier: ^8.4.7 + version: 8.4.7(react@18.3.1)(storybook@8.4.7) + '@storybook/blocks': + specifier: ^8.4.7 + version: 8.4.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.4.7) + '@storybook/react': + specifier: ^8.4.7 + version: 8.4.7(@storybook/test@8.4.7(storybook@8.4.7))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.4.7)(typescript@5.6.3) + '@storybook/react-vite': + specifier: ^8.4.7 + version: 8.4.7(@storybook/test@8.4.7(storybook@8.4.7))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@4.28.0)(storybook@8.4.7)(typescript@5.6.3)(vite@6.0.3(@types/node@22.10.2)) + '@storybook/test': + specifier: ^8.4.7 + version: 8.4.7(storybook@8.4.7) + '@types/jwt-decode': + specifier: ^3.1.0 + version: 3.1.0 '@types/react': - specifier: ^18.3.12 + specifier: ^18.3.14 version: 18.3.14 '@types/react-dom': - specifier: ^18.3.1 + specifier: ^18.3.2 version: 18.3.2 + '@types/redux-persist': + specifier: ^4.3.1 + version: 4.3.1(react@18.3.1)(redux@5.0.1) '@vitejs/plugin-react': specifier: ^4.3.4 - version: 4.3.4(vite@6.0.3) + version: 4.3.4(vite@6.0.3(@types/node@22.10.2)) eslint: specifier: ^9.15.0 version: 9.16.0 @@ -51,9 +111,21 @@ importers: eslint-plugin-react-refresh: specifier: ^0.4.14 version: 0.4.16(eslint@9.16.0) + eslint-plugin-storybook: + specifier: ^0.11.1 + version: 0.11.1(eslint@9.16.0)(typescript@5.6.3) globals: specifier: ^15.12.0 version: 15.13.0 + husky: + specifier: ^9.1.7 + version: 9.1.7 + msw: + specifier: ^2.6.8 + version: 2.6.8(@types/node@22.10.2)(typescript@5.6.3) + storybook: + specifier: ^8.4.7 + version: 8.4.7 typescript: specifier: ~5.6.2 version: 5.6.3 @@ -61,11 +133,20 @@ importers: specifier: ^8.15.0 version: 8.17.0(eslint@9.16.0)(typescript@5.6.3) vite: - specifier: ^6.0.1 - version: 6.0.3 + specifier: ^6.0.3 + version: 6.0.3(@types/node@22.10.2) + vite-plugin-svgr: + specifier: ^4.3.0 + version: 4.3.0(rollup@4.28.0)(typescript@5.6.3)(vite@6.0.3(@types/node@22.10.2)) + vitest: + specifier: ^2.1.8 + version: 2.1.8(@types/node@22.10.2)(msw@2.6.8(@types/node@22.10.2)(typescript@5.6.3)) packages: + '@adobe/css-tools@4.4.1': + resolution: {integrity: sha512-12WGKBQzjUAI4ayyF4IAtfw2QR/IDoqk6jTddXDhtYTJF9ASmoE1zst7cVtP0aL/F1jUJL5r+JxKXKEgHNbEUQ==} + '@ampproject/remapping@2.3.0': resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} @@ -137,6 +218,10 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/runtime@7.26.0': + resolution: {integrity: sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==} + engines: {node: '>=6.9.0'} + '@babel/template@7.25.9': resolution: {integrity: sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==} engines: {node: '>=6.9.0'} @@ -149,6 +234,21 @@ packages: resolution: {integrity: sha512-vN5p+1kl59GVKMvTHt55NzzmYVxprfJD+ql7U9NFIfKCBkYE55LYtS+WtPlaYOyzydrKI8Nezd+aZextrd+FMA==} engines: {node: '>=6.9.0'} + '@bundled-es-modules/cookie@2.0.1': + resolution: {integrity: sha512-8o+5fRPLNbjbdGRRmJj3h6Hh1AQJf2dk3qQ/5ZFb+PXkRNiSoMGGUKlsgLfrxneb72axVJyIYji64E2+nNfYyw==} + + '@bundled-es-modules/statuses@1.0.1': + resolution: {integrity: sha512-yn7BklA5acgcBr+7w064fGV+SGIFySjCKpqjcWgBAIfrAkY+4GQTJJHQMeT3V/sgz23VTEVV8TtOmkvJAhFVfg==} + + '@bundled-es-modules/tough-cookie@0.1.6': + resolution: {integrity: sha512-dvMHbL464C0zI+Yqxbz6kZ5TOEp7GLW+pry/RWndAR8MJQAXZ2rPmIs8tziTZjeIyhSNZgZbCePtfSbdWqStJw==} + + '@chromatic-com/storybook@3.2.2': + resolution: {integrity: sha512-xmXt/GW0hAPbzNTrxYuVo43Adrtjue4DeVrsoIIEeJdGaPNNeNf+DHMlJKOBdlHmCnFUoe9R/0mLM9zUp5bKWw==} + engines: {node: '>=16.0.0', yarn: '>=1.22.18'} + peerDependencies: + storybook: ^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0 + '@emotion/is-prop-valid@1.2.2': resolution: {integrity: sha512-uNsoYd37AFmaCdXlg6EYD1KaPOaRWRByMCYzbKUX4+hhMfrxdVSelShywL4JVaAeM/eHUOSprYBQls+/neX3pw==} @@ -158,108 +258,216 @@ packages: '@emotion/unitless@0.8.1': resolution: {integrity: sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==} + '@esbuild/aix-ppc64@0.21.5': + resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + '@esbuild/aix-ppc64@0.24.0': resolution: {integrity: sha512-WtKdFM7ls47zkKHFVzMz8opM7LkcsIp9amDUBIAWirg70RM71WRSjdILPsY5Uv1D42ZpUfaPILDlfactHgsRkw==} engines: {node: '>=18'} cpu: [ppc64] os: [aix] + '@esbuild/android-arm64@0.21.5': + resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + '@esbuild/android-arm64@0.24.0': resolution: {integrity: sha512-Vsm497xFM7tTIPYK9bNTYJyF/lsP590Qc1WxJdlB6ljCbdZKU9SY8i7+Iin4kyhV/KV5J2rOKsBQbB77Ab7L/w==} engines: {node: '>=18'} cpu: [arm64] os: [android] + '@esbuild/android-arm@0.21.5': + resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + '@esbuild/android-arm@0.24.0': resolution: {integrity: sha512-arAtTPo76fJ/ICkXWetLCc9EwEHKaeya4vMrReVlEIUCAUncH7M4bhMQ+M9Vf+FFOZJdTNMXNBrWwW+OXWpSew==} engines: {node: '>=18'} cpu: [arm] os: [android] + '@esbuild/android-x64@0.21.5': + resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + '@esbuild/android-x64@0.24.0': resolution: {integrity: sha512-t8GrvnFkiIY7pa7mMgJd7p8p8qqYIz1NYiAoKc75Zyv73L3DZW++oYMSHPRarcotTKuSs6m3hTOa5CKHaS02TQ==} engines: {node: '>=18'} cpu: [x64] os: [android] + '@esbuild/darwin-arm64@0.21.5': + resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + '@esbuild/darwin-arm64@0.24.0': resolution: {integrity: sha512-CKyDpRbK1hXwv79soeTJNHb5EiG6ct3efd/FTPdzOWdbZZfGhpbcqIpiD0+vwmpu0wTIL97ZRPZu8vUt46nBSw==} engines: {node: '>=18'} cpu: [arm64] os: [darwin] + '@esbuild/darwin-x64@0.21.5': + resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + '@esbuild/darwin-x64@0.24.0': resolution: {integrity: sha512-rgtz6flkVkh58od4PwTRqxbKH9cOjaXCMZgWD905JOzjFKW+7EiUObfd/Kav+A6Gyud6WZk9w+xu6QLytdi2OA==} engines: {node: '>=18'} cpu: [x64] os: [darwin] + '@esbuild/freebsd-arm64@0.21.5': + resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + '@esbuild/freebsd-arm64@0.24.0': resolution: {integrity: sha512-6Mtdq5nHggwfDNLAHkPlyLBpE5L6hwsuXZX8XNmHno9JuL2+bg2BX5tRkwjyfn6sKbxZTq68suOjgWqCicvPXA==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] + '@esbuild/freebsd-x64@0.21.5': + resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + '@esbuild/freebsd-x64@0.24.0': resolution: {integrity: sha512-D3H+xh3/zphoX8ck4S2RxKR6gHlHDXXzOf6f/9dbFt/NRBDIE33+cVa49Kil4WUjxMGW0ZIYBYtaGCa2+OsQwQ==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] + '@esbuild/linux-arm64@0.21.5': + resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + '@esbuild/linux-arm64@0.24.0': resolution: {integrity: sha512-TDijPXTOeE3eaMkRYpcy3LarIg13dS9wWHRdwYRnzlwlA370rNdZqbcp0WTyyV/k2zSxfko52+C7jU5F9Tfj1g==} engines: {node: '>=18'} cpu: [arm64] os: [linux] + '@esbuild/linux-arm@0.21.5': + resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + '@esbuild/linux-arm@0.24.0': resolution: {integrity: sha512-gJKIi2IjRo5G6Glxb8d3DzYXlxdEj2NlkixPsqePSZMhLudqPhtZ4BUrpIuTjJYXxvF9njql+vRjB2oaC9XpBw==} engines: {node: '>=18'} cpu: [arm] os: [linux] + '@esbuild/linux-ia32@0.21.5': + resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + '@esbuild/linux-ia32@0.24.0': resolution: {integrity: sha512-K40ip1LAcA0byL05TbCQ4yJ4swvnbzHscRmUilrmP9Am7//0UjPreh4lpYzvThT2Quw66MhjG//20mrufm40mA==} engines: {node: '>=18'} cpu: [ia32] os: [linux] + '@esbuild/linux-loong64@0.21.5': + resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + '@esbuild/linux-loong64@0.24.0': resolution: {integrity: sha512-0mswrYP/9ai+CU0BzBfPMZ8RVm3RGAN/lmOMgW4aFUSOQBjA31UP8Mr6DDhWSuMwj7jaWOT0p0WoZ6jeHhrD7g==} engines: {node: '>=18'} cpu: [loong64] os: [linux] + '@esbuild/linux-mips64el@0.21.5': + resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + '@esbuild/linux-mips64el@0.24.0': resolution: {integrity: sha512-hIKvXm0/3w/5+RDtCJeXqMZGkI2s4oMUGj3/jM0QzhgIASWrGO5/RlzAzm5nNh/awHE0A19h/CvHQe6FaBNrRA==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] + '@esbuild/linux-ppc64@0.21.5': + resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + '@esbuild/linux-ppc64@0.24.0': resolution: {integrity: sha512-HcZh5BNq0aC52UoocJxaKORfFODWXZxtBaaZNuN3PUX3MoDsChsZqopzi5UupRhPHSEHotoiptqikjN/B77mYQ==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] + '@esbuild/linux-riscv64@0.21.5': + resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + '@esbuild/linux-riscv64@0.24.0': resolution: {integrity: sha512-bEh7dMn/h3QxeR2KTy1DUszQjUrIHPZKyO6aN1X4BCnhfYhuQqedHaa5MxSQA/06j3GpiIlFGSsy1c7Gf9padw==} engines: {node: '>=18'} cpu: [riscv64] os: [linux] + '@esbuild/linux-s390x@0.21.5': + resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + '@esbuild/linux-s390x@0.24.0': resolution: {integrity: sha512-ZcQ6+qRkw1UcZGPyrCiHHkmBaj9SiCD8Oqd556HldP+QlpUIe2Wgn3ehQGVoPOvZvtHm8HPx+bH20c9pvbkX3g==} engines: {node: '>=18'} cpu: [s390x] os: [linux] + '@esbuild/linux-x64@0.21.5': + resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + '@esbuild/linux-x64@0.24.0': resolution: {integrity: sha512-vbutsFqQ+foy3wSSbmjBXXIJ6PL3scghJoM8zCL142cGaZKAdCZHyf+Bpu/MmX9zT9Q0zFBVKb36Ma5Fzfa8xA==} engines: {node: '>=18'} cpu: [x64] os: [linux] + '@esbuild/netbsd-x64@0.21.5': + resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + '@esbuild/netbsd-x64@0.24.0': resolution: {integrity: sha512-hjQ0R/ulkO8fCYFsG0FZoH+pWgTTDreqpqY7UnQntnaKv95uP5iW3+dChxnx7C3trQQU40S+OgWhUVwCjVFLvg==} engines: {node: '>=18'} @@ -272,30 +480,60 @@ packages: cpu: [arm64] os: [openbsd] + '@esbuild/openbsd-x64@0.21.5': + resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + '@esbuild/openbsd-x64@0.24.0': resolution: {integrity: sha512-4ir0aY1NGUhIC1hdoCzr1+5b43mw99uNwVzhIq1OY3QcEwPDO3B7WNXBzaKY5Nsf1+N11i1eOfFcq+D/gOS15Q==} engines: {node: '>=18'} cpu: [x64] os: [openbsd] + '@esbuild/sunos-x64@0.21.5': + resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + '@esbuild/sunos-x64@0.24.0': resolution: {integrity: sha512-jVzdzsbM5xrotH+W5f1s+JtUy1UWgjU0Cf4wMvffTB8m6wP5/kx0KiaLHlbJO+dMgtxKV8RQ/JvtlFcdZ1zCPA==} engines: {node: '>=18'} cpu: [x64] os: [sunos] + '@esbuild/win32-arm64@0.21.5': + resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + '@esbuild/win32-arm64@0.24.0': resolution: {integrity: sha512-iKc8GAslzRpBytO2/aN3d2yb2z8XTVfNV0PjGlCxKo5SgWmNXx82I/Q3aG1tFfS+A2igVCY97TJ8tnYwpUWLCA==} engines: {node: '>=18'} cpu: [arm64] os: [win32] + '@esbuild/win32-ia32@0.21.5': + resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + '@esbuild/win32-ia32@0.24.0': resolution: {integrity: sha512-vQW36KZolfIudCcTnaTpmLQ24Ha1RjygBo39/aLkM2kmjkWmZGEJ5Gn9l5/7tzXA42QGIoWbICfg6KLLkIw6yw==} engines: {node: '>=18'} cpu: [ia32] os: [win32] + '@esbuild/win32-x64@0.21.5': + resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + '@esbuild/win32-x64@0.24.0': resolution: {integrity: sha512-7IAFPrjSQIJrGsK6flwg7NFmwBoSTyF3rl7If0hNUFQU4ilTsEPL6GuMuU9BfIWVVGuRnuIidkSMC+c0Otu8IA==} engines: {node: '>=18'} @@ -336,6 +574,11 @@ packages: resolution: {integrity: sha512-zSkKow6H5Kdm0ZUQUB2kV5JIXqoG0+uH5YADhaEHswm664N9Db8dXSi0nMJpacpMf+MyyglF1vnZohpEg5yUtg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@heroicons/react@2.2.0': + resolution: {integrity: sha512-LMcepvRaS9LYHJGsF0zzmgKCUim/X3N/DQKc4jepAXJ7l8QxJ1PmxJzqplF2Z3FE4PqBAIGyJAQ/w4B5dsqbtQ==} + peerDependencies: + react: '>= 16 || ^19.0.0-rc' + '@humanfs/core@0.19.1': resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} engines: {node: '>=18.18.0'} @@ -356,6 +599,35 @@ packages: resolution: {integrity: sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==} engines: {node: '>=18.18'} + '@inquirer/confirm@5.1.0': + resolution: {integrity: sha512-osaBbIMEqVFjTX5exoqPXs6PilWQdjaLhGtMDXMXg/yxkHXNq43GlxGyTA35lK2HpzUgDN+Cjh/2AmqCN0QJpw==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + + '@inquirer/core@10.1.1': + resolution: {integrity: sha512-rmZVXy9iZvO3ZStEe/ayuuwIJ23LSF13aPMlLMTQARX6lGUBDHGV8UB5i9MRrfy0+mZwt5/9bdy8llszSD3NQA==} + engines: {node: '>=18'} + + '@inquirer/figures@1.0.8': + resolution: {integrity: sha512-tKd+jsmhq21AP1LhexC0pPwsCxEhGgAkg28byjJAd+xhmIs8LUX8JbUc3vBf3PhLxWiB5EvyBE5X7JSPAqMAqg==} + engines: {node: '>=18'} + + '@inquirer/type@3.0.1': + resolution: {integrity: sha512-+ksJMIy92sOAiAccGpcKZUc3bYO07cADnscIxHBknEm3uNts3movSmBofc1908BNy5edKscxYeAdaX1NXkHS6A==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + + '@joshwooding/vite-plugin-react-docgen-typescript@0.4.2': + resolution: {integrity: sha512-feQ+ntr+8hbVudnsTUapiMN9q8T90XA1d5jn9QzY09sNoj4iD9wi0PY1vsBFTda4ZjEaxRK9S81oarR2nj7TFQ==} + peerDependencies: + typescript: '>= 4.3.x' + vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 + peerDependenciesMeta: + typescript: + optional: true + '@jridgewell/gen-mapping@0.3.5': resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} engines: {node: '>=6.0.0'} @@ -374,6 +646,16 @@ packages: '@jridgewell/trace-mapping@0.3.25': resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + '@mdx-js/react@3.1.0': + resolution: {integrity: sha512-QjHtSaoameoalGnKDT3FoIl4+9RwyTmo9ZJGBdLOks/YOiWHoRDI3PUwEzOE7kEmGcV3AFcp9K6dYu9rEuKLAQ==} + peerDependencies: + '@types/react': '>=16' + react: '>=16' + + '@mswjs/interceptors@0.37.3': + resolution: {integrity: sha512-USvgCL/uOGFtVa6SVyRrC8kIAedzRohxIXN5LISlg5C5vLZCn7dgMFVSNhSF9cuBEFrm/O2spDWEZeMnw4ZXYg==} + engines: {node: '>=18'} + '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -386,6 +668,15 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} + '@open-draft/deferred-promise@2.2.0': + resolution: {integrity: sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA==} + + '@open-draft/logger@0.3.0': + resolution: {integrity: sha512-X2g45fzhxH238HKO4xbSr7+wBS8Fvw6ixhTDuvLd5mqh6bJJCFAPwU9mPDxbcrRtfxv4u5IHCEH77BmxvXmmxQ==} + + '@open-draft/until@2.1.0': + resolution: {integrity: sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==} + '@reduxjs/toolkit@2.4.0': resolution: {integrity: sha512-wJZEuSKj14tvNfxiIiJws0tQN77/rDqucBq528ApebMIRHyWpCanJVQRxQ8WWZC19iCDKxDsGlbAir3F1layxA==} peerDependencies: @@ -397,6 +688,15 @@ packages: react-redux: optional: true + '@rollup/pluginutils@5.1.3': + resolution: {integrity: sha512-Pnsb6f32CD2W3uCaLZIzDmeFyQ2b8UWMFI7xtwUezpcGBDVDW6y9XgAWIlARiGAo6eNF5FK5aQTr0LFyNyqq5A==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + '@rollup/rollup-android-arm-eabi@4.28.0': resolution: {integrity: sha512-wLJuPLT6grGZsy34g4N1yRfYeouklTgPhH1gWXCYspenKYD0s3cR99ZevOGw5BexMNywkbV3UkjADisozBmpPQ==} cpu: [arm] @@ -487,6 +787,239 @@ packages: cpu: [x64] os: [win32] + '@storybook/addon-actions@8.4.7': + resolution: {integrity: sha512-mjtD5JxcPuW74T6h7nqMxWTvDneFtokg88p6kQ5OnC1M259iAXb//yiSZgu/quunMHPCXSiqn4FNOSgASTSbsA==} + peerDependencies: + storybook: ^8.4.7 + + '@storybook/addon-backgrounds@8.4.7': + resolution: {integrity: sha512-I4/aErqtFiazcoWyKafOAm3bLpxTj6eQuH/woSbk1Yx+EzN+Dbrgx1Updy8//bsNtKkcrXETITreqHC+a57DHQ==} + peerDependencies: + storybook: ^8.4.7 + + '@storybook/addon-controls@8.4.7': + resolution: {integrity: sha512-377uo5IsJgXLnQLJixa47+11V+7Wn9KcDEw+96aGCBCfLbWNH8S08tJHHnSu+jXg9zoqCAC23MetntVp6LetHA==} + peerDependencies: + storybook: ^8.4.7 + + '@storybook/addon-docs@8.4.7': + resolution: {integrity: sha512-NwWaiTDT5puCBSUOVuf6ME7Zsbwz7Y79WF5tMZBx/sLQ60vpmJVQsap6NSjvK1Ravhc21EsIXqemAcBjAWu80w==} + peerDependencies: + storybook: ^8.4.7 + + '@storybook/addon-essentials@8.4.7': + resolution: {integrity: sha512-+BtZHCBrYtQKILtejKxh0CDRGIgTl9PumfBOKRaihYb4FX1IjSAxoV/oo/IfEjlkF5f87vouShWsRa8EUauFDw==} + peerDependencies: + storybook: ^8.4.7 + + '@storybook/addon-highlight@8.4.7': + resolution: {integrity: sha512-whQIDBd3PfVwcUCrRXvCUHWClXe9mQ7XkTPCdPo4B/tZ6Z9c6zD8JUHT76ddyHivixFLowMnA8PxMU6kCMAiNw==} + peerDependencies: + storybook: ^8.4.7 + + '@storybook/addon-interactions@8.4.7': + resolution: {integrity: sha512-fnufT3ym8ht3HHUIRVXAH47iOJW/QOb0VSM+j269gDuvyDcY03D1civCu1v+eZLGaXPKJ8vtjr0L8zKQ/4P0JQ==} + peerDependencies: + storybook: ^8.4.7 + + '@storybook/addon-measure@8.4.7': + resolution: {integrity: sha512-QfvqYWDSI5F68mKvafEmZic3SMiK7zZM8VA0kTXx55hF/+vx61Mm0HccApUT96xCXIgmwQwDvn9gS4TkX81Dmw==} + peerDependencies: + storybook: ^8.4.7 + + '@storybook/addon-onboarding@8.4.7': + resolution: {integrity: sha512-FdC2NV60VNYeMxf6DVe0qV9ucSBAzMh1//C0Qqwq8CcjthMbmKlVZ7DqbVsbIHKnFaSCaUC88eR5olAfMaauCQ==} + peerDependencies: + storybook: ^8.4.7 + + '@storybook/addon-outline@8.4.7': + resolution: {integrity: sha512-6LYRqUZxSodmAIl8icr585Oi8pmzbZ90aloZJIpve+dBAzo7ydYrSQxxoQEVltXbKf3VeVcrs64ouAYqjisMYA==} + peerDependencies: + storybook: ^8.4.7 + + '@storybook/addon-toolbars@8.4.7': + resolution: {integrity: sha512-OSfdv5UZs+NdGB+nZmbafGUWimiweJ/56gShlw8Neo/4jOJl1R3rnRqqY7MYx8E4GwoX+i3GF5C3iWFNQqlDcw==} + peerDependencies: + storybook: ^8.4.7 + + '@storybook/addon-viewport@8.4.7': + resolution: {integrity: sha512-hvczh/jjuXXcOogih09a663sRDDSATXwbE866al1DXgbDFraYD/LxX/QDb38W9hdjU9+Qhx8VFIcNWoMQns5HQ==} + peerDependencies: + storybook: ^8.4.7 + + '@storybook/blocks@8.4.7': + resolution: {integrity: sha512-+QH7+JwXXXIyP3fRCxz/7E2VZepAanXJM7G8nbR3wWsqWgrRp4Wra6MvybxAYCxU7aNfJX5c+RW84SNikFpcIA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta + storybook: ^8.4.7 + peerDependenciesMeta: + react: + optional: true + react-dom: + optional: true + + '@storybook/builder-vite@8.4.7': + resolution: {integrity: sha512-LovyXG5VM0w7CovI/k56ZZyWCveQFVDl0m7WwetpmMh2mmFJ+uPQ35BBsgTvTfc8RHi+9Q3F58qP1MQSByXi9g==} + peerDependencies: + storybook: ^8.4.7 + vite: ^4.0.0 || ^5.0.0 || ^6.0.0 + + '@storybook/components@8.4.7': + resolution: {integrity: sha512-uyJIcoyeMWKAvjrG9tJBUCKxr2WZk+PomgrgrUwejkIfXMO76i6jw9BwLa0NZjYdlthDv30r9FfbYZyeNPmF0g==} + peerDependencies: + storybook: ^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0 + + '@storybook/core@8.4.7': + resolution: {integrity: sha512-7Z8Z0A+1YnhrrSXoKKwFFI4gnsLbWzr8fnDCU6+6HlDukFYh8GHRcZ9zKfqmy6U3hw2h8H5DrHsxWfyaYUUOoA==} + peerDependencies: + prettier: ^2 || ^3 + peerDependenciesMeta: + prettier: + optional: true + + '@storybook/csf-plugin@8.4.7': + resolution: {integrity: sha512-Fgogplu4HImgC+AYDcdGm1rmL6OR1rVdNX1Be9C/NEXwOCpbbBwi0BxTf/2ZxHRk9fCeaPEcOdP5S8QHfltc1g==} + peerDependencies: + storybook: ^8.4.7 + + '@storybook/csf@0.1.12': + resolution: {integrity: sha512-9/exVhabisyIVL0VxTCxo01Tdm8wefIXKXfltAPTSr8cbLn5JAxGQ6QV3mjdecLGEOucfoVhAKtJfVHxEK1iqw==} + + '@storybook/global@5.0.0': + resolution: {integrity: sha512-FcOqPAXACP0I3oJ/ws6/rrPT9WGhu915Cg8D02a9YxLo0DE9zI+a9A5gRGvmQ09fiWPukqI8ZAEoQEdWUKMQdQ==} + + '@storybook/icons@1.3.0': + resolution: {integrity: sha512-Nz/UzeYQdUZUhacrPyfkiiysSjydyjgg/p0P9HxB4p/WaJUUjMAcaoaLgy3EXx61zZJ3iD36WPuDkZs5QYrA0A==} + engines: {node: '>=14.0.0'} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta + + '@storybook/instrumenter@8.4.7': + resolution: {integrity: sha512-k6NSD3jaRCCHAFtqXZ7tw8jAzD/yTEWXGya+REgZqq5RCkmJ+9S4Ytp/6OhQMPtPFX23gAuJJzTQVLcCr+gjRg==} + peerDependencies: + storybook: ^8.4.7 + + '@storybook/manager-api@8.4.7': + resolution: {integrity: sha512-ELqemTviCxAsZ5tqUz39sDmQkvhVAvAgiplYy9Uf15kO0SP2+HKsCMzlrm2ue2FfkUNyqbDayCPPCB0Cdn/mpQ==} + peerDependencies: + storybook: ^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0 + + '@storybook/preview-api@8.4.7': + resolution: {integrity: sha512-0QVQwHw+OyZGHAJEXo6Knx+6/4er7n2rTDE5RYJ9F2E2Lg42E19pfdLlq2Jhoods2Xrclo3wj6GWR//Ahi39Eg==} + peerDependencies: + storybook: ^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0 + + '@storybook/react-dom-shim@8.4.7': + resolution: {integrity: sha512-6bkG2jvKTmWrmVzCgwpTxwIugd7Lu+2btsLAqhQSzDyIj2/uhMNp8xIMr/NBDtLgq3nomt9gefNa9xxLwk/OMg==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta + storybook: ^8.4.7 + + '@storybook/react-vite@8.4.7': + resolution: {integrity: sha512-iiY9iLdMXhDnilCEVxU6vQsN72pW3miaf0WSenOZRyZv3HdbpgOxI0qapOS0KCyRUnX9vTlmrSPTMchY4cAeOg==} + engines: {node: '>=18.0.0'} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta + storybook: ^8.4.7 + vite: ^4.0.0 || ^5.0.0 || ^6.0.0 + + '@storybook/react@8.4.7': + resolution: {integrity: sha512-nQ0/7i2DkaCb7dy0NaT95llRVNYWQiPIVuhNfjr1mVhEP7XD090p0g7eqUmsx8vfdHh2BzWEo6CoBFRd3+EXxw==} + engines: {node: '>=18.0.0'} + peerDependencies: + '@storybook/test': 8.4.7 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta + storybook: ^8.4.7 + typescript: '>= 4.2.x' + peerDependenciesMeta: + '@storybook/test': + optional: true + typescript: + optional: true + + '@storybook/test@8.4.7': + resolution: {integrity: sha512-AhvJsu5zl3uG40itSQVuSy5WByp3UVhS6xAnme4FWRwgSxhvZjATJ3AZkkHWOYjnnk+P2/sbz/XuPli1FVCWoQ==} + peerDependencies: + storybook: ^8.4.7 + + '@storybook/theming@8.4.7': + resolution: {integrity: sha512-99rgLEjf7iwfSEmdqlHkSG3AyLcK0sfExcr0jnc6rLiAkBhzuIsvcHjjUwkR210SOCgXqBPW0ZA6uhnuyppHLw==} + peerDependencies: + storybook: ^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0 + + '@svgr/babel-plugin-add-jsx-attribute@8.0.0': + resolution: {integrity: sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@svgr/babel-plugin-remove-jsx-attribute@8.0.0': + resolution: {integrity: sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@svgr/babel-plugin-remove-jsx-empty-expression@8.0.0': + resolution: {integrity: sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@svgr/babel-plugin-replace-jsx-attribute-value@8.0.0': + resolution: {integrity: sha512-KVQ+PtIjb1BuYT3ht8M5KbzWBhdAjjUPdlMtpuw/VjT8coTrItWX6Qafl9+ji831JaJcu6PJNKCV0bp01lBNzQ==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@svgr/babel-plugin-svg-dynamic-title@8.0.0': + resolution: {integrity: sha512-omNiKqwjNmOQJ2v6ge4SErBbkooV2aAWwaPFs2vUY7p7GhVkzRkJ00kILXQvRhA6miHnNpXv7MRnnSjdRjK8og==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@svgr/babel-plugin-svg-em-dimensions@8.0.0': + resolution: {integrity: sha512-mURHYnu6Iw3UBTbhGwE/vsngtCIbHE43xCRK7kCw4t01xyGqb2Pd+WXekRRoFOBIY29ZoOhUCTEweDMdrjfi9g==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@svgr/babel-plugin-transform-react-native-svg@8.1.0': + resolution: {integrity: sha512-Tx8T58CHo+7nwJ+EhUwx3LfdNSG9R2OKfaIXXs5soiy5HtgoAEkDay9LIimLOcG8dJQH1wPZp/cnAv6S9CrR1Q==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@svgr/babel-plugin-transform-svg-component@8.0.0': + resolution: {integrity: sha512-DFx8xa3cZXTdb/k3kfPeaixecQLgKh5NVBMwD0AQxOzcZawK4oo1Jh9LbrcACUivsCA7TLG8eeWgrDXjTMhRmw==} + engines: {node: '>=12'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@svgr/babel-preset@8.1.0': + resolution: {integrity: sha512-7EYDbHE7MxHpv4sxvnVPngw5fuR6pw79SkcrILHJ/iMpuKySNCl5W1qcwPEpU+LgyRXOaAFgH0KhwD18wwg6ug==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@svgr/core@8.1.0': + resolution: {integrity: sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==} + engines: {node: '>=14'} + + '@svgr/hast-util-to-babel-ast@8.0.0': + resolution: {integrity: sha512-EbDKwO9GpfWP4jN9sGdYwPBU0kdomaPIL2Eu4YwmgP+sJeXT+L7bMwJUBnhzfH8Q2qMBqZ4fJwpCyYsAN3mt2Q==} + engines: {node: '>=14'} + + '@svgr/plugin-jsx@8.1.0': + resolution: {integrity: sha512-0xiIyBsLlr8quN+WyuxooNW9RJ0Dpr8uOnH/xrCVO8GLUcwHISwj1AG0k+LFzteTkAA0GbX0kj9q6Dk70PTiPA==} + engines: {node: '>=14'} + peerDependencies: + '@svgr/core': '*' + '@tanstack/query-core@5.62.2': resolution: {integrity: sha512-LcwVcC5qpsDpHcqlXUUL5o9SaOBwhNkGeV+B06s0GBoyBr8FqXPuXT29XzYXR36lchhnerp6XO+CWc84/vh7Zg==} @@ -495,6 +1028,23 @@ packages: peerDependencies: react: ^18 || ^19 + '@testing-library/dom@10.4.0': + resolution: {integrity: sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==} + engines: {node: '>=18'} + + '@testing-library/jest-dom@6.5.0': + resolution: {integrity: sha512-xGGHpBXYSHUUr6XsKBfs85TWlYKpTc37cSBBVrXcib2MkHLboWlkClhWF37JKlDb9KEq3dHs+f2xR7XJEWGBxA==} + engines: {node: '>=14', npm: '>=6', yarn: '>=1'} + + '@testing-library/user-event@14.5.2': + resolution: {integrity: sha512-YAh82Wh4TIrxYLmfGcixwD18oIjyC1pFQC2Y01F2lzV2HTMiYrI0nze0FD0ocB//CKS/7jIUgae+adPqxK5yCQ==} + engines: {node: '>=12', npm: '>=6'} + peerDependencies: + '@testing-library/dom': '>=7.21.4' + + '@types/aria-query@5.0.4': + resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==} + '@types/babel__core@7.20.5': resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} @@ -510,27 +1060,71 @@ packages: '@types/cookie@0.6.0': resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==} + '@types/doctrine@0.0.9': + resolution: {integrity: sha512-eOIHzCUSH7SMfonMG1LsC2f8vxBFtho6NGBznK41R84YzPuvSBzrhEps33IsQiOW9+VL6NQ9DbjQJznk/S4uRA==} + '@types/estree@1.0.6': resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} + '@types/hoist-non-react-statics@3.3.6': + resolution: {integrity: sha512-lPByRJUer/iN/xa4qpyL0qmL11DqNW81iU/IG1S3uvRUq4oKagz8VCxZjiWkumgt66YT3vOdDgZ0o32sGKtCEw==} + '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + '@types/jwt-decode@3.1.0': + resolution: {integrity: sha512-tthwik7TKkou3mVnBnvVuHnHElbjtdbM63pdBCbZTirCt3WAdM73Y79mOri7+ljsS99ZVwUFZHLMxJuJnv/z1w==} + deprecated: This is a stub types definition. jwt-decode provides its own type definitions, so you do not need this installed. + + '@types/mdx@2.0.13': + resolution: {integrity: sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==} + + '@types/node@22.10.2': + resolution: {integrity: sha512-Xxr6BBRCAOQixvonOye19wnzyDiUtTeqldOOmj3CkeblonbccA12PFwlufvRdrpjXxqnmUaeiU5EOA+7s5diUQ==} + '@types/prop-types@15.7.14': resolution: {integrity: sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==} + '@types/quill@1.3.10': + resolution: {integrity: sha512-IhW3fPW+bkt9MLNlycw8u8fWb7oO7W5URC9MfZYHBlA24rex9rs23D5DETChu1zvgVdc5ka64ICjJOgQMr6Shw==} + + '@types/quill@2.0.14': + resolution: {integrity: sha512-zvoXCRnc2Dl8g+7/9VSAmRWPN6oH+MVhTPizmCR+GJCITplZ5VRVzMs4+a/nOE3yzNwEZqylJJrMB07bwbM1/g==} + '@types/react-dom@18.3.2': resolution: {integrity: sha512-Fqp+rcvem9wEnGr3RY8dYNvSQ8PoLqjZ9HLgaPUOjJJD120uDyOxOjc/39M4Kddp9JQCxpGQbnhVQF0C0ncYVg==} + '@types/react-redux@7.1.34': + resolution: {integrity: sha512-GdFaVjEbYv4Fthm2ZLvj1VSCedV7TqE5y1kNwnjSdBOTXuRSgowux6J8TAct15T3CKBr63UMk+2CO7ilRhyrAQ==} + '@types/react@18.3.14': resolution: {integrity: sha512-NzahNKvjNhVjuPBQ+2G7WlxstQ+47kXZNHlUvFakDViuIEfGY926GqhMueQFZ7woG+sPiQKlF36XfrIUVSUfFg==} + '@types/redux-persist@4.3.1': + resolution: {integrity: sha512-YkMnMUk+4//wPtiSTMfsxST/F9Gh9sPWX0LVxHuOidGjojHtMdpep2cYvQgfiDMnj34orXyZI+QJCQMZDlafKA==} + deprecated: This is a stub types definition for redux-persist (https://github.com/rt2zz/redux-persist). redux-persist provides its own type definitions, so you don't need @types/redux-persist installed! + + '@types/resolve@1.20.6': + resolution: {integrity: sha512-A4STmOXPhMUtHH+S6ymgE2GiBSMqf4oTvcQZMcHzokuTLVYzXTB8ttjcgxOVaAp2lGwEdzZ0J+cRbbeevQj1UQ==} + + '@types/statuses@2.0.5': + resolution: {integrity: sha512-jmIUGWrAiwu3dZpxntxieC+1n/5c3mjrImkmOSQ2NC5uP6cYO4aAZDdSmRcI5C1oiTmqlZGHC+/NmJrKogbP5A==} + '@types/stylis@4.2.5': resolution: {integrity: sha512-1Xve+NMN7FWjY14vLoY5tL3BVEQ/n42YLwaqJIPYhotZ9uBHt87VceMwWQpzmdEt2TNXIorIFG+YeCUUW7RInw==} + '@types/tough-cookie@4.0.5': + resolution: {integrity: sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==} + + '@types/trusted-types@2.0.7': + resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} + '@types/use-sync-external-store@0.0.3': resolution: {integrity: sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==} + '@types/uuid@9.0.8': + resolution: {integrity: sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==} + '@typescript-eslint/eslint-plugin@8.17.0': resolution: {integrity: sha512-HU1KAdW3Tt8zQkdvNoIijfWDMvdSweFYm4hWh+KwhPstv+sCmWb89hCIP8msFm9N1R/ooh9honpSuvqKWlYy3w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -599,6 +1193,47 @@ packages: peerDependencies: vite: ^4.2.0 || ^5.0.0 || ^6.0.0 + '@vitest/expect@2.0.5': + resolution: {integrity: sha512-yHZtwuP7JZivj65Gxoi8upUN2OzHTi3zVfjwdpu2WrvCZPLwsJ2Ey5ILIPccoW23dd/zQBlJ4/dhi7DWNyXCpA==} + + '@vitest/expect@2.1.8': + resolution: {integrity: sha512-8ytZ/fFHq2g4PJVAtDX57mayemKgDR6X3Oa2Foro+EygiOJHUXhCqBAAKQYYajZpFoIfvBCF1j6R6IYRSIUFuw==} + + '@vitest/mocker@2.1.8': + resolution: {integrity: sha512-7guJ/47I6uqfttp33mgo6ga5Gr1VnL58rcqYKyShoRK9ebu8T5Rs6HN3s1NABiBeVTdWNrwUMcHH54uXZBN4zA==} + peerDependencies: + msw: ^2.4.9 + vite: ^5.0.0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + + '@vitest/pretty-format@2.0.5': + resolution: {integrity: sha512-h8k+1oWHfwTkyTkb9egzwNMfJAEx4veaPSnMeKbVSjp4euqGSbQlm5+6VHwTr7u4FJslVVsUG5nopCaAYdOmSQ==} + + '@vitest/pretty-format@2.1.8': + resolution: {integrity: sha512-9HiSZ9zpqNLKlbIDRWOnAWqgcA7xu+8YxXSekhr0Ykab7PAYFkhkwoqVArPOtJhPmYeE2YHgKZlj3CP36z2AJQ==} + + '@vitest/runner@2.1.8': + resolution: {integrity: sha512-17ub8vQstRnRlIU5k50bG+QOMLHRhYPAna5tw8tYbj+jzjcspnwnwtPtiOlkuKC4+ixDPTuLZiqiWWQ2PSXHVg==} + + '@vitest/snapshot@2.1.8': + resolution: {integrity: sha512-20T7xRFbmnkfcmgVEz+z3AU/3b0cEzZOt/zmnvZEctg64/QZbSDJEVm9fLnnlSi74KibmRsO9/Qabi+t0vCRPg==} + + '@vitest/spy@2.0.5': + resolution: {integrity: sha512-c/jdthAhvJdpfVuaexSrnawxZz6pywlTPe84LUB2m/4t3rl2fTo9NFGBG4oWgaD+FTgDDV8hJ/nibT7IfH3JfA==} + + '@vitest/spy@2.1.8': + resolution: {integrity: sha512-5swjf2q95gXeYPevtW0BLk6H8+bPlMb4Vw/9Em4hFxDcaOxS+e0LOX4yqNxoHzMR2akEB2xfpnWUzkZokmgWDg==} + + '@vitest/utils@2.0.5': + resolution: {integrity: sha512-d8HKbqIcya+GR67mkZbrzhS5kKhtp8dQLcmRZLGTscGVg7yImT82cIrhtn2L8+VujWcy6KZweApgNmPsTAO/UQ==} + + '@vitest/utils@2.1.8': + resolution: {integrity: sha512-dwSoui6djdwbfFmIgbIjX2ZhIoG7Ex/+xpxyiEgIGzjliY8xGkcpITKTlp6B4MgtGkF2ilvm97cPM96XZaAgcA==} + acorn-jsx@5.3.2: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: @@ -612,16 +1247,61 @@ packages: ajv@6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + ansi-escapes@4.3.2: + resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} + engines: {node: '>=8'} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-regex@6.1.0: + resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==} + engines: {node: '>=12'} + ansi-styles@4.3.0: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} + ansi-styles@5.2.0: + resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} + engines: {node: '>=10'} + argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + aria-query@5.3.0: + resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} + + aria-query@5.3.2: + resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} + engines: {node: '>= 0.4'} + + assertion-error@2.0.1: + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} + engines: {node: '>=12'} + + ast-types@0.16.1: + resolution: {integrity: sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==} + engines: {node: '>=4'} + + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} + engines: {node: '>= 0.4'} + + axios@1.7.9: + resolution: {integrity: sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==} + balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + better-opn@3.0.2: + resolution: {integrity: sha512-aVNobHnJqLiUelTaHat9DZ1qM2w0C0Eym4LPI/3JxOnSokGVdsl1T1kN7TFvsEAD8G47A6VKQ0TVHqbBnYMJlQ==} + engines: {node: '>=12.0.0'} + brace-expansion@1.1.11: resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} @@ -632,25 +1312,88 @@ packages: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} + browser-assert@1.2.1: + resolution: {integrity: sha512-nfulgvOR6S4gt9UKCeGJOuSGBPGiFT6oQ/2UBnvTY/5aQ1PnksW72fhZkM30DzoRRv2WpwZf1vHHEr3mtuXIWQ==} + browserslist@4.24.2: resolution: {integrity: sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true - callsites@3.1.0: - resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} + engines: {node: '>=8'} + + call-bind-apply-helpers@1.0.0: + resolution: {integrity: sha512-CCKAP2tkPau7D3GE8+V8R6sQubA9R5foIzGp+85EXCVSCivuxBNAWqcpn72PKYiIcqoViv/kcUDpaEIMBVi1lQ==} + engines: {node: '>= 0.4'} + + call-bind-apply-helpers@1.0.1: + resolution: {integrity: sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==} + engines: {node: '>= 0.4'} + + call-bind@1.0.8: + resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==} + engines: {node: '>= 0.4'} + + call-bound@1.0.3: + resolution: {integrity: sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==} + engines: {node: '>= 0.4'} + + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} + camelcase@6.3.0: + resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} + engines: {node: '>=10'} + camelize@1.0.1: resolution: {integrity: sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==} caniuse-lite@1.0.30001686: resolution: {integrity: sha512-Y7deg0Aergpa24M3qLC5xjNklnKnhsmSyR/V89dLZ1n0ucJIFNs7PgR2Yfa/Zf6W79SbBicgtGxZr2juHkEUIA==} + chai@5.1.2: + resolution: {integrity: sha512-aGtmf24DW6MLHHG5gCx4zaI3uBq3KRtxeVs0DjFH6Z0rDNbsvTxFASFvdj79pxjxZ8/5u3PIiN3IwEIQkiiuPw==} + engines: {node: '>=12'} + + chalk@3.0.0: + resolution: {integrity: sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==} + engines: {node: '>=8'} + chalk@4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} + check-error@2.1.1: + resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} + engines: {node: '>= 16'} + + chromatic@11.20.0: + resolution: {integrity: sha512-Btdli1qoAI01UKmk3Iqe6vKhAhePRXqNI/2uKKy2R16q7SN/5kLTqhd1JI20LFOZSnH3xSJaUXeJ2xZOJB//3A==} + hasBin: true + peerDependencies: + '@chromatic-com/cypress': ^0.*.* || ^1.0.0 + '@chromatic-com/playwright': ^0.*.* || ^1.0.0 + peerDependenciesMeta: + '@chromatic-com/cypress': + optional: true + '@chromatic-com/playwright': + optional: true + + cli-width@4.1.0: + resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==} + engines: {node: '>= 12'} + + cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + + clone@2.1.2: + resolution: {integrity: sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==} + engines: {node: '>=0.8'} + color-convert@2.0.1: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} engines: {node: '>=7.0.0'} @@ -658,16 +1401,33 @@ packages: color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + cookie@0.7.2: + resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} + engines: {node: '>= 0.6'} + cookie@1.0.2: resolution: {integrity: sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==} engines: {node: '>=18'} + cosmiconfig@8.3.6: + resolution: {integrity: sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==} + engines: {node: '>=14'} + peerDependencies: + typescript: '>=4.9.5' + peerDependenciesMeta: + typescript: + optional: true + cross-spawn@7.0.6: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} @@ -679,6 +1439,9 @@ packages: css-to-react-native@3.2.0: resolution: {integrity: sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==} + css.escape@1.5.1: + resolution: {integrity: sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==} + csstype@3.1.3: resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} @@ -691,12 +1454,95 @@ packages: supports-color: optional: true + deep-eql@5.0.2: + resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} + engines: {node: '>=6'} + + deep-equal@1.1.2: + resolution: {integrity: sha512-5tdhKF6DbU7iIzrIOa1AOUt39ZRm13cmL1cGEh//aqR8x9+tNfbywRf0n5FD/18OKMdo7DNEtrX2t22ZAkI+eg==} + engines: {node: '>= 0.4'} + deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + + define-lazy-prop@2.0.0: + resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==} + engines: {node: '>=8'} + + define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} + engines: {node: '>= 0.4'} + + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + + dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + + doctrine@3.0.0: + resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} + engines: {node: '>=6.0.0'} + + dom-accessibility-api@0.5.16: + resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==} + + dom-accessibility-api@0.6.3: + resolution: {integrity: sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==} + + dompurify@3.2.3: + resolution: {integrity: sha512-U1U5Hzc2MO0oW3DF+G9qYN0aT7atAou4AgI0XjWz061nyBPbdxkfdhfy5uMgGn6+oLFCfn44ZGbdDqCzVmlOWA==} + + dot-case@3.0.4: + resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==} + + dunder-proto@1.0.0: + resolution: {integrity: sha512-9+Sj30DIu+4KvHqMfLUGLFYL2PkURSYMVXJyXe92nFRvlYq5hBjLEhblKB+vkd/WVlUYMWigiY07T91Fkk0+4A==} + engines: {node: '>= 0.4'} + electron-to-chromium@1.5.71: resolution: {integrity: sha512-dB68l59BI75W1BUGVTAEJy45CEVuEGy9qPVVQ8pnHyHMn36PLPPoE1mjLH+lo9rKulO3HC2OhbACI/8tCqJBcA==} + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + + error-ex@1.3.2: + resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-module-lexer@1.5.4: + resolution: {integrity: sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==} + + es-object-atoms@1.0.0: + resolution: {integrity: sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==} + engines: {node: '>= 0.4'} + + esbuild-register@3.6.0: + resolution: {integrity: sha512-H2/S7Pm8a9CL1uhp9OvjwrBh5Pvx0H8qVOxNu8Wed9Y7qv56MPtq+GGM8RJpq6glYJn9Wspr8uw7l55uyinNeg==} + peerDependencies: + esbuild: '>=0.12 <1' + + esbuild@0.21.5: + resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} + engines: {node: '>=12'} + hasBin: true + esbuild@0.24.0: resolution: {integrity: sha512-FuLPevChGDshgSicjisSooU0cemp/sGXR841D5LHMB7mTVOmsEHcAxaH3irL53+8YDIeVNQEySh4DaYU/iuPqQ==} engines: {node: '>=18'} @@ -721,6 +1567,12 @@ packages: peerDependencies: eslint: '>=8.40' + eslint-plugin-storybook@0.11.1: + resolution: {integrity: sha512-yGKpAYkBm/Q2hZg476vRUAvd9lAccjjSvzU5nYy3BSQbKTPy7uopx7JEpwk2vSuw4weTMZzWF64z9/gp/K5RCg==} + engines: {node: '>= 18'} + peerDependencies: + eslint: '>=6' + eslint-scope@8.2.0: resolution: {integrity: sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -747,6 +1599,11 @@ packages: resolution: {integrity: sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + esquery@1.6.0: resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} engines: {node: '>=0.10'} @@ -759,13 +1616,38 @@ packages: resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} engines: {node: '>=4.0'} + estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + esutils@2.0.3: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} + eventemitter3@2.0.3: + resolution: {integrity: sha512-jLN68Dx5kyFHaePoXWPsCGW5qdyZQtLYHkxkg02/Mz6g0kYpDx4FyP6XfArhQdlOC4b8Mv+EMxPo/8La7Tzghg==} + + eventemitter3@5.0.1: + resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} + + expect-type@1.1.0: + resolution: {integrity: sha512-bFi65yM+xZgk+u/KRIpekdSYkTB5W1pEf0Lt8Q8Msh7b+eQ7LXVtIB1Bkm4fvclDEL1b2CZkMhv2mOeF8tMdkA==} + engines: {node: '>=12.0.0'} + + extend@3.0.2: + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + fast-diff@1.1.2: + resolution: {integrity: sha512-KaJUt+M9t1qaIteSvjc6P3RbMdXsNhK61GRftR6SNxqmhthcd9MGIi4T+o0jD8LUSpSnSKXE20nLtJ3fOHxQig==} + + fast-diff@1.3.0: + resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} + fast-glob@3.3.2: resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} engines: {node: '>=8.6.0'} @@ -783,6 +1665,10 @@ packages: resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} engines: {node: '>=16.0.0'} + filesize@10.1.6: + resolution: {integrity: sha512-sJslQKU2uM33qH5nqewAwVB2QgR6w1aMNsYUp3aN5rMRyXEwJGmZvaWzeJFNTOXWlHQyBFCWrdj3fV/fsTOX8w==} + engines: {node: '>= 10.4.0'} + fill-range@7.1.1: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} @@ -798,15 +1684,49 @@ packages: flatted@3.3.2: resolution: {integrity: sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==} + follow-redirects@1.15.9: + resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + + for-each@0.3.3: + resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} + + form-data@4.0.1: + resolution: {integrity: sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==} + engines: {node: '>= 6'} + fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + functions-have-names@1.2.3: + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + gensync@1.0.0-beta.2: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} engines: {node: '>=6.9.0'} + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + + get-intrinsic@1.2.5: + resolution: {integrity: sha512-Y4+pKa7XeRUPWFNvOOYHkRYrfzW07oraURSvjDmRVOJ748OrVmeXtpE4+GCEHncjCjkTxPNRt8kEbxDhsn6VTg==} + engines: {node: '>= 0.4'} + + get-intrinsic@1.2.6: + resolution: {integrity: sha512-qxsEs+9A+u85HhllWJJFicJfPDhRmjzoYdl64aMWW9yRIJmSyxdn8IEkuIM530/7T+lv0TIHd8L6Q/ra0tEoeA==} + engines: {node: '>= 0.4'} + glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} @@ -827,13 +1747,50 @@ packages: resolution: {integrity: sha512-49TewVEz0UxZjr1WYYsWpPrhyC/B/pA8Bq0fUmet2n+eR7yn0IvNzNaoBwnK6mdkzcN+se7Ez9zUgULTz2QH4g==} engines: {node: '>=18'} + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + graphemer@1.4.0: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + graphql@16.9.0: + resolution: {integrity: sha512-GGTKBX4SD7Wdb8mqeDLni2oaRGYQWjWHGKPQ24ZMnUtKfcsVoiv4uX8+LJr1K6U5VW2Lu1BwJnj7uiori0YtRw==} + engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0} + has-flag@4.0.0: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + headers-polyfill@4.0.3: + resolution: {integrity: sha512-IScLbePpkvO846sIwOtOTDjutRMWdXdJmXdMvk6gCBHxFO8d+QKOQedyZSxFTTFYRSmlgSTDtXqqq4pcenBXLQ==} + + hoist-non-react-statics@3.3.2: + resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} + + husky@9.1.7: + resolution: {integrity: sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==} + engines: {node: '>=18'} + hasBin: true + ignore@5.3.2: resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} engines: {node: '>= 4'} @@ -849,18 +1806,72 @@ packages: resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} engines: {node: '>=0.8.19'} + indent-string@4.0.0: + resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} + engines: {node: '>=8'} + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + is-arguments@1.1.1: + resolution: {integrity: sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==} + engines: {node: '>= 0.4'} + + is-arrayish@0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + + is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + + is-core-module@2.15.1: + resolution: {integrity: sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==} + engines: {node: '>= 0.4'} + + is-date-object@1.1.0: + resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==} + engines: {node: '>= 0.4'} + + is-docker@2.2.1: + resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} + engines: {node: '>=8'} + hasBin: true + is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-generator-function@1.0.10: + resolution: {integrity: sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==} + engines: {node: '>= 0.4'} + is-glob@4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} + is-node-process@1.2.0: + resolution: {integrity: sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw==} + is-number@7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} + is-regex@1.2.1: + resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} + engines: {node: '>= 0.4'} + + is-typed-array@1.1.13: + resolution: {integrity: sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==} + engines: {node: '>= 0.4'} + + is-wsl@2.2.0: + resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} + engines: {node: '>=8'} + isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} @@ -871,6 +1882,10 @@ packages: resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} hasBin: true + jsdoc-type-pratt-parser@4.1.0: + resolution: {integrity: sha512-Hicd6JK5Njt2QB6XYFS7ok9e37O8AYk3jTcppG4YVQnYjOemymvTcmc7OWsmq/Qqj5TdRFO5/x/tIPmBeRtGHg==} + engines: {node: '>=12.0.0'} + jsesc@3.0.2: resolution: {integrity: sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==} engines: {node: '>=6'} @@ -879,6 +1894,9 @@ packages: json-buffer@3.0.1: resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + json-parse-even-better-errors@2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + json-schema-traverse@0.4.1: resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} @@ -890,6 +1908,13 @@ packages: engines: {node: '>=6'} hasBin: true + jsonfile@6.1.0: + resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + + jwt-decode@4.0.0: + resolution: {integrity: sha512-+KJGIyHgkGuIq3IEBNftfhW/LfWhXUIY6OmyVWjliu5KH1y0fw7VQ8YndE2O4qZdMSd9SqbnC8GOcZEy0Om7sA==} + engines: {node: '>=18'} + keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} @@ -897,20 +1922,62 @@ packages: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} + lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + locate-path@6.0.0: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} + lodash-es@4.17.21: + resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==} + + lodash.clonedeep@4.5.0: + resolution: {integrity: sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==} + + lodash.isequal@4.5.0: + resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==} + lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + loose-envify@1.4.0: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} hasBin: true + loupe@3.1.2: + resolution: {integrity: sha512-23I4pFZHmAemUnz8WZXbYRSKYj801VDaNv9ETuMh7IrMc7VuVVSo+Z9iLE3ni30+U48iDWfi30d3twAXBYmnCg==} + + lower-case@2.0.2: + resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} + lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + lz-string@1.5.0: + resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} + hasBin: true + + magic-string@0.27.0: + resolution: {integrity: sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==} + engines: {node: '>=12'} + + magic-string@0.30.14: + resolution: {integrity: sha512-5c99P1WKTed11ZC0HMJOj6CDIue6F8ySu+bJL+85q1zBEIY8IklrJ1eiKC2NDRh3Ct3FcvmJPyQHb9erXMTJNw==} + + map-or-similar@1.5.0: + resolution: {integrity: sha512-0aF7ZmVon1igznGI4VS30yugpduQW3y3GkcgGJOp7d8x8QrizhigUxjI/m2UojsXXto+jLAH3KSz+xOJTiORjg==} + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + memoizerific@1.11.3: + resolution: {integrity: sha512-/EuHYwAPdLtXwAwSZkh/Gutery6pD2KYd44oQLhAvQp/50mpyduZh8Q7PYHXTCJ+wuXxt7oij2LXyIJOOYFPog==} + merge2@1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} @@ -919,6 +1986,18 @@ packages: resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + min-indent@1.0.1: + resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} + engines: {node: '>=4'} + minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} @@ -926,9 +2005,26 @@ packages: resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} engines: {node: '>=16 || 14 >=14.17'} + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + msw@2.6.8: + resolution: {integrity: sha512-nxXxnH6WALZ9a7rsQp4HU2AaD4iGAiouMmE/MY4al7pXTibgA6OZOuKhmN2WBIM6w9qMKwRtX8p2iOb45B2M/Q==} + engines: {node: '>=18'} + hasBin: true + peerDependencies: + typescript: '>= 4.8.x' + peerDependenciesMeta: + typescript: + optional: true + + mute-stream@2.0.0: + resolution: {integrity: sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==} + engines: {node: ^18.17.0 || >=20.5.0} + nanoid@3.3.8: resolution: {integrity: sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} @@ -937,13 +2033,31 @@ packages: natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + no-case@3.0.4: + resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} + node-releases@2.0.18: resolution: {integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==} + object-is@1.1.6: + resolution: {integrity: sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==} + engines: {node: '>= 0.4'} + + object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + + open@8.4.2: + resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==} + engines: {node: '>=12'} + optionator@0.9.4: resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} engines: {node: '>= 0.8.0'} + outvariant@1.4.3: + resolution: {integrity: sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA==} + p-limit@3.1.0: resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} engines: {node: '>=10'} @@ -952,10 +2066,20 @@ packages: resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} engines: {node: '>=10'} + parchment@1.1.4: + resolution: {integrity: sha512-J5FBQt/pM2inLzg4hEWmzQx/8h8D0CiDxaG3vyp9rKrQRSDgBlhjdP5jQGgosEajXPSQouXGHOmVdgo7QmJuOg==} + + parchment@3.0.0: + resolution: {integrity: sha512-HUrJFQ/StvgmXRcQ1ftY6VEZUq3jA2t9ncFN4F84J/vN0/FPpQF+8FKXb3l6fLces6q0uOHj6NJn+2xvZnxO6A==} + parent-module@1.0.1: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} + parse-json@5.2.0: + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} + path-exists@4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} @@ -964,6 +2088,23 @@ packages: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + path-to-regexp@6.3.0: + resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==} + + path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + + pathe@1.1.2: + resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} + + pathval@2.0.0: + resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==} + engines: {node: '>= 14.16'} + picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} @@ -971,6 +2112,18 @@ packages: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} + picomatch@4.0.2: + resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} + engines: {node: '>=12'} + + polished@4.3.1: + resolution: {integrity: sha512-OBatVyC/N7SCW/FaDHrSd+vn0o5cS855TOmYi4OkdWUMSJCET/xip//ch8xGUvtr3i44X9LVyWwQlRMTN3pwSA==} + engines: {node: '>=10'} + + possible-typed-array-names@1.0.0: + resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} + engines: {node: '>= 0.4'} + postcss-value-parser@4.2.0: resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} @@ -986,18 +2139,83 @@ packages: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} + pretty-format@27.5.1: + resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + process@0.11.10: + resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} + engines: {node: '>= 0.6.0'} + + proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + + psl@1.15.0: + resolution: {integrity: sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==} + punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} + querystringify@2.2.0: + resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} + queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + quill-delta@3.6.3: + resolution: {integrity: sha512-wdIGBlcX13tCHOXGMVnnTVFtGRLoP0imqxM696fIPwIf5ODIYUHIvHbZcyvGlZFiFhK5XzDC2lpjbxRhnM05Tg==} + engines: {node: '>=0.10'} + + quill-delta@5.1.0: + resolution: {integrity: sha512-X74oCeRI4/p0ucjb5Ma8adTXd9Scumz367kkMK5V/IatcX6A0vlgLgKbzXWy5nZmCGeNJm2oQX0d2Eqj+ZIlCA==} + engines: {node: '>= 12.0.0'} + + quill@1.3.7: + resolution: {integrity: sha512-hG/DVzh/TiknWtE6QmWAF/pxoZKYxfe3J/d/+ShUWkDvvkZQVTPeVmUJVu1uE6DDooC4fWTiCLh84ul89oNz5g==} + + quill@2.0.3: + resolution: {integrity: sha512-xEYQBqfYx/sfb33VJiKnSJp8ehloavImQ2A6564GAbqG55PGw1dAWUn1MUbQB62t0azawUS2CZZhWCjO8gRvTw==} + engines: {npm: '>=8.2.3'} + + react-confetti@6.1.0: + resolution: {integrity: sha512-7Ypx4vz0+g8ECVxr88W9zhcQpbeujJAVqL14ZnXJ3I23mOI9/oBVTQ3dkJhUmB0D6XOtCZEM6N0Gm9PMngkORw==} + engines: {node: '>=10.18'} + peerDependencies: + react: ^16.3.0 || ^17.0.1 || ^18.0.0 + + react-docgen-typescript@2.2.2: + resolution: {integrity: sha512-tvg2ZtOpOi6QDwsb3GZhOjDkkX0h8Z2gipvTg6OVMUyoYoURhEiRNePT8NZItTVCDh39JJHnLdfCOkzoLbFnTg==} + peerDependencies: + typescript: '>= 4.3.x' + + react-docgen@7.1.0: + resolution: {integrity: sha512-APPU8HB2uZnpl6Vt/+0AFoVYgSRtfiP6FLrZgPPTDmqSb2R4qZRbgd0A3VzIFxDt5e+Fozjx79WjLWnF69DK8g==} + engines: {node: '>=16.14.0'} + react-dom@18.3.1: resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==} peerDependencies: react: ^18.3.1 + react-hook-form@7.54.1: + resolution: {integrity: sha512-PUNzFwQeQ5oHiiTUO7GO/EJXGEtuun2Y1A59rLnZBBj+vNEOWt/3ERTiG1/zt7dVeJEM+4vDX/7XQ/qanuvPMg==} + engines: {node: '>=18.0.0'} + peerDependencies: + react: ^16.8.0 || ^17 || ^18 || ^19 + + react-is@16.13.1: + resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + + react-is@17.0.2: + resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} + + react-quill@2.0.0: + resolution: {integrity: sha512-4qQtv1FtCfLgoD3PXAur5RyxuUbPXQGOHgTlFie3jtxp43mXDtzCKaOgQ3mLyZfi1PUlyjycfivKelFhy13QUg==} + peerDependencies: + react: ^16 || ^17 || ^18 + react-dom: ^16 || ^17 || ^18 + react-redux@9.1.2: resolution: {integrity: sha512-0OA4dhM1W48l3uzmv6B7TXPCGmokUU4p1M44DGN2/D9a1FjVPukVjER1PcPX97jIg6aUeLq1XJo1IpfbgULn0w==} peerDependencies: @@ -1028,14 +2246,48 @@ packages: resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} engines: {node: '>=0.10.0'} + recast@0.23.9: + resolution: {integrity: sha512-Hx/BGIbwj+Des3+xy5uAtAbdCyqK9y9wbBcDFDYanLS9JnMqf7OeF87HQwUimE87OEc72mr6tkKUKMBBL+hF9Q==} + engines: {node: '>= 4'} + + redent@3.0.0: + resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==} + engines: {node: '>=8'} + + redux-persist@6.0.0: + resolution: {integrity: sha512-71LLMbUq2r02ng2We9S215LtPu3fY0KgaGE0k8WRgl6RkqxtGfl7HUozz1Dftwsb0D/5mZ8dwAaPbtnzfvbEwQ==} + peerDependencies: + react: '>=16' + redux: '>4.0.0' + peerDependenciesMeta: + react: + optional: true + redux-thunk@3.1.0: resolution: {integrity: sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw==} peerDependencies: redux: ^5.0.0 + redux@4.2.1: + resolution: {integrity: sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==} + redux@5.0.1: resolution: {integrity: sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==} + regenerator-runtime@0.14.1: + resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} + + regexp.prototype.flags@1.5.3: + resolution: {integrity: sha512-vqlC04+RQoFalODCbCumG2xIOvapzVMHwsyIGM/SIE8fRhFFsXeH8/QQ+s0T0kDAhKc4k30s73/0ydkHQz6HlQ==} + engines: {node: '>= 0.4'} + + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + + requires-port@1.0.0: + resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} + reselect@5.1.1: resolution: {integrity: sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==} @@ -1043,6 +2295,10 @@ packages: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} + resolve@1.22.8: + resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} + hasBin: true + reusify@1.0.4: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} @@ -1070,6 +2326,14 @@ packages: set-cookie-parser@2.7.1: resolution: {integrity: sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==} + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + + set-function-name@2.0.2: + resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} + engines: {node: '>= 0.4'} + shallowequal@1.1.0: resolution: {integrity: sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==} @@ -1081,10 +2345,70 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} + siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + snake-case@3.0.4: + resolution: {integrity: sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==} + source-map-js@1.2.1: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + + stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + + statuses@2.0.1: + resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} + engines: {node: '>= 0.8'} + + std-env@3.8.0: + resolution: {integrity: sha512-Bc3YwwCB+OzldMxOXJIIvC6cPRWr/LxOp48CdQTOkPyk/t4JWWJbrilwBd7RJzKV8QW7tJkcgAmeuLLJugl5/w==} + + storybook@8.4.7: + resolution: {integrity: sha512-RP/nMJxiWyFc8EVMH5gp20ID032Wvk+Yr3lmKidoegto5Iy+2dVQnUoElZb2zpbVXNHWakGuAkfI0dY1Hfp/vw==} + hasBin: true + peerDependencies: + prettier: ^2 || ^3 + peerDependenciesMeta: + prettier: + optional: true + + strict-event-emitter@0.5.1: + resolution: {integrity: sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-ansi@7.1.0: + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + engines: {node: '>=12'} + + strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + + strip-indent@3.0.0: + resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} + engines: {node: '>=8'} + + strip-indent@4.0.0: + resolution: {integrity: sha512-mnVSV2l+Zv6BLpSD/8V87CW/y9EmmbYzGCIavsnsI6/nwn26DwffM/yztm30Z/I2DY9wdS3vXVCMnHDgZaVNoA==} + engines: {node: '>=12'} + strip-json-comments@3.1.1: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} @@ -1103,26 +2427,81 @@ packages: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + svg-parser@2.0.4: + resolution: {integrity: sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==} + + tiny-invariant@1.3.3: + resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} + + tinybench@2.9.0: + resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} + + tinyexec@0.3.1: + resolution: {integrity: sha512-WiCJLEECkO18gwqIp6+hJg0//p23HXp4S+gGtAKu3mI2F2/sXC4FvHvXvB0zJVVaTPhx1/tOwdbRsa1sOBIKqQ==} + + tinypool@1.0.2: + resolution: {integrity: sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA==} + engines: {node: ^18.0.0 || >=20.0.0} + + tinyrainbow@1.2.0: + resolution: {integrity: sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==} + engines: {node: '>=14.0.0'} + + tinyspy@3.0.2: + resolution: {integrity: sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==} + engines: {node: '>=14.0.0'} + to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} + tough-cookie@4.1.4: + resolution: {integrity: sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==} + engines: {node: '>=6'} + ts-api-utils@1.4.3: resolution: {integrity: sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==} engines: {node: '>=16'} peerDependencies: typescript: '>=4.2.0' + ts-dedent@2.2.0: + resolution: {integrity: sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==} + engines: {node: '>=6.10'} + + tsconfig-paths@4.2.0: + resolution: {integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==} + engines: {node: '>=6'} + tslib@2.6.2: resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} turbo-stream@2.4.0: resolution: {integrity: sha512-FHncC10WpBd2eOmGwpmQsWLDoK4cqsA/UT/GqNoaKOQnT8uzhtCbg3EoUDMvqpOSAI0S26mr0rkjzbOO6S3v1g==} + tween-functions@1.2.0: + resolution: {integrity: sha512-PZBtLYcCLtEcjL14Fzb1gSxPBeL7nWvGhO5ZFPGqziCcr8uvHp0NDmdjBchp6KHL+tExcg0m3NISmKxhU394dA==} + type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} + type-fest@0.21.3: + resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} + engines: {node: '>=10'} + + type-fest@2.19.0: + resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==} + engines: {node: '>=12.20'} + + type-fest@4.30.0: + resolution: {integrity: sha512-G6zXWS1dLj6eagy6sVhOMQiLtJdxQBHIA9Z6HFUNLOlr6MFOgzV8wvmidtPONfPtEUv0uZsy77XJNzTAfwPDaA==} + engines: {node: '>=16'} + typescript-eslint@8.17.0: resolution: {integrity: sha512-409VXvFd/f1br1DCbuKNFqQpXICoTB+V51afcwG1pn1a3Cp92MqAUges3YjwEdQ0cMUoCIodjVDAYzyD8h3SYA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -1138,20 +2517,86 @@ packages: engines: {node: '>=14.17'} hasBin: true - update-browserslist-db@1.1.1: - resolution: {integrity: sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==} - hasBin: true + undici-types@6.20.0: + resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==} + + universalify@0.2.0: + resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==} + engines: {node: '>= 4.0.0'} + + universalify@2.0.1: + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} + engines: {node: '>= 10.0.0'} + + unplugin@1.16.0: + resolution: {integrity: sha512-5liCNPuJW8dqh3+DM6uNM2EI3MLLpCKp/KY+9pB5M2S2SR2qvvDHhKgBOaTWEbZTAws3CXfB0rKTIolWKL05VQ==} + engines: {node: '>=14.0.0'} + + update-browserslist-db@1.1.1: + resolution: {integrity: sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==} + hasBin: true peerDependencies: browserslist: '>= 4.21.0' uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + url-parse@1.5.10: + resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==} + use-sync-external-store@1.4.0: resolution: {integrity: sha512-9WXSPC5fMv61vaupRkCKCxsPxBocVnwakBEkMIHHpkTTg6icbJtg6jzgtLDm4bl3cSHAca52rYWih0k4K3PfHw==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + util@0.12.5: + resolution: {integrity: sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==} + + uuid@9.0.1: + resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} + hasBin: true + + vite-node@2.1.8: + resolution: {integrity: sha512-uPAwSr57kYjAUux+8E2j0q0Fxpn8M9VoyfGiRI8Kfktz9NcYMCenwY5RnZxnF1WTu3TGiYipirIzacLL3VVGFg==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + + vite-plugin-svgr@4.3.0: + resolution: {integrity: sha512-Jy9qLB2/PyWklpYy0xk0UU3TlU0t2UMpJXZvf+hWII1lAmRHrOUKi11Uw8N3rxoNk7atZNYO3pR3vI1f7oi+6w==} + peerDependencies: + vite: '>=2.6.0' + + vite@5.4.11: + resolution: {integrity: sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || >=20.0.0 + less: '*' + lightningcss: ^1.21.0 + sass: '*' + sass-embedded: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + vite@6.0.3: resolution: {integrity: sha512-Cmuo5P0ENTN6HxLSo6IHsjCLn/81Vgrp81oaiFFMRa8gGDj5xEjIcEpf2ZymZtZR8oU0P2JX5WuUp/rlXcHkAw==} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} @@ -1192,24 +2637,99 @@ packages: yaml: optional: true + vitest@2.1.8: + resolution: {integrity: sha512-1vBKTZskHw/aosXqQUlVWWlGUxSJR8YtiyZDJAFeW2kPAeX6S3Sool0mjspO+kXLuxVWlEDDowBAeqeAQefqLQ==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@types/node': ^18.0.0 || >=20.0.0 + '@vitest/browser': 2.1.8 + '@vitest/ui': 2.1.8 + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@types/node': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + + webpack-virtual-modules@0.6.2: + resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==} + + which-typed-array@1.1.16: + resolution: {integrity: sha512-g+N+GAWiRj66DngFwHvISJd+ITsyphZvD1vChfVg6cEdnzy53GzB3oy0fUNlvhz7H7+MiqhYr26qxQShCpKTTQ==} + engines: {node: '>= 0.4'} + which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'} hasBin: true + why-is-node-running@2.3.0: + resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} + engines: {node: '>=8'} + hasBin: true + word-wrap@1.2.5: resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} engines: {node: '>=0.10.0'} + wrap-ansi@6.2.0: + resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} + engines: {node: '>=8'} + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + ws@8.18.0: + resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + + yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} + yoctocolors-cjs@2.1.2: + resolution: {integrity: sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA==} + engines: {node: '>=18'} + snapshots: + '@adobe/css-tools@4.4.1': {} + '@ampproject/remapping@2.3.0': dependencies: '@jridgewell/gen-mapping': 0.3.5 @@ -1302,6 +2822,10 @@ snapshots: '@babel/core': 7.26.0 '@babel/helper-plugin-utils': 7.25.9 + '@babel/runtime@7.26.0': + dependencies: + regenerator-runtime: 0.14.1 + '@babel/template@7.25.9': dependencies: '@babel/code-frame': 7.26.2 @@ -1325,6 +2849,32 @@ snapshots: '@babel/helper-string-parser': 7.25.9 '@babel/helper-validator-identifier': 7.25.9 + '@bundled-es-modules/cookie@2.0.1': + dependencies: + cookie: 0.7.2 + + '@bundled-es-modules/statuses@1.0.1': + dependencies: + statuses: 2.0.1 + + '@bundled-es-modules/tough-cookie@0.1.6': + dependencies: + '@types/tough-cookie': 4.0.5 + tough-cookie: 4.1.4 + + '@chromatic-com/storybook@3.2.2(react@18.3.1)(storybook@8.4.7)': + dependencies: + chromatic: 11.20.0 + filesize: 10.1.6 + jsonfile: 6.1.0 + react-confetti: 6.1.0(react@18.3.1) + storybook: 8.4.7 + strip-ansi: 7.1.0 + transitivePeerDependencies: + - '@chromatic-com/cypress' + - '@chromatic-com/playwright' + - react + '@emotion/is-prop-valid@1.2.2': dependencies: '@emotion/memoize': 0.8.1 @@ -1333,75 +2883,144 @@ snapshots: '@emotion/unitless@0.8.1': {} + '@esbuild/aix-ppc64@0.21.5': + optional: true + '@esbuild/aix-ppc64@0.24.0': optional: true + '@esbuild/android-arm64@0.21.5': + optional: true + '@esbuild/android-arm64@0.24.0': optional: true + '@esbuild/android-arm@0.21.5': + optional: true + '@esbuild/android-arm@0.24.0': optional: true + '@esbuild/android-x64@0.21.5': + optional: true + '@esbuild/android-x64@0.24.0': optional: true + '@esbuild/darwin-arm64@0.21.5': + optional: true + '@esbuild/darwin-arm64@0.24.0': optional: true + '@esbuild/darwin-x64@0.21.5': + optional: true + '@esbuild/darwin-x64@0.24.0': optional: true + '@esbuild/freebsd-arm64@0.21.5': + optional: true + '@esbuild/freebsd-arm64@0.24.0': optional: true + '@esbuild/freebsd-x64@0.21.5': + optional: true + '@esbuild/freebsd-x64@0.24.0': optional: true + '@esbuild/linux-arm64@0.21.5': + optional: true + '@esbuild/linux-arm64@0.24.0': optional: true + '@esbuild/linux-arm@0.21.5': + optional: true + '@esbuild/linux-arm@0.24.0': optional: true + '@esbuild/linux-ia32@0.21.5': + optional: true + '@esbuild/linux-ia32@0.24.0': optional: true + '@esbuild/linux-loong64@0.21.5': + optional: true + '@esbuild/linux-loong64@0.24.0': optional: true + '@esbuild/linux-mips64el@0.21.5': + optional: true + '@esbuild/linux-mips64el@0.24.0': optional: true + '@esbuild/linux-ppc64@0.21.5': + optional: true + '@esbuild/linux-ppc64@0.24.0': optional: true + '@esbuild/linux-riscv64@0.21.5': + optional: true + '@esbuild/linux-riscv64@0.24.0': optional: true + '@esbuild/linux-s390x@0.21.5': + optional: true + '@esbuild/linux-s390x@0.24.0': optional: true + '@esbuild/linux-x64@0.21.5': + optional: true + '@esbuild/linux-x64@0.24.0': optional: true + '@esbuild/netbsd-x64@0.21.5': + optional: true + '@esbuild/netbsd-x64@0.24.0': optional: true '@esbuild/openbsd-arm64@0.24.0': optional: true + '@esbuild/openbsd-x64@0.21.5': + optional: true + '@esbuild/openbsd-x64@0.24.0': optional: true + '@esbuild/sunos-x64@0.21.5': + optional: true + '@esbuild/sunos-x64@0.24.0': optional: true + '@esbuild/win32-arm64@0.21.5': + optional: true + '@esbuild/win32-arm64@0.24.0': optional: true + '@esbuild/win32-ia32@0.21.5': + optional: true + '@esbuild/win32-ia32@0.24.0': optional: true + '@esbuild/win32-x64@0.21.5': + optional: true + '@esbuild/win32-x64@0.24.0': optional: true @@ -1446,6 +3065,10 @@ snapshots: dependencies: levn: 0.4.1 + '@heroicons/react@2.2.0(react@18.3.1)': + dependencies: + react: 18.3.1 + '@humanfs/core@0.19.1': {} '@humanfs/node@0.16.6': @@ -1459,6 +3082,40 @@ snapshots: '@humanwhocodes/retry@0.4.1': {} + '@inquirer/confirm@5.1.0(@types/node@22.10.2)': + dependencies: + '@inquirer/core': 10.1.1(@types/node@22.10.2) + '@inquirer/type': 3.0.1(@types/node@22.10.2) + '@types/node': 22.10.2 + + '@inquirer/core@10.1.1(@types/node@22.10.2)': + dependencies: + '@inquirer/figures': 1.0.8 + '@inquirer/type': 3.0.1(@types/node@22.10.2) + ansi-escapes: 4.3.2 + cli-width: 4.1.0 + mute-stream: 2.0.0 + signal-exit: 4.1.0 + strip-ansi: 6.0.1 + wrap-ansi: 6.2.0 + yoctocolors-cjs: 2.1.2 + transitivePeerDependencies: + - '@types/node' + + '@inquirer/figures@1.0.8': {} + + '@inquirer/type@3.0.1(@types/node@22.10.2)': + dependencies: + '@types/node': 22.10.2 + + '@joshwooding/vite-plugin-react-docgen-typescript@0.4.2(typescript@5.6.3)(vite@6.0.3(@types/node@22.10.2))': + dependencies: + magic-string: 0.27.0 + react-docgen-typescript: 2.2.2(typescript@5.6.3) + vite: 6.0.3(@types/node@22.10.2) + optionalDependencies: + typescript: 5.6.3 + '@jridgewell/gen-mapping@0.3.5': dependencies: '@jridgewell/set-array': 1.2.1 @@ -1476,6 +3133,21 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.0 + '@mdx-js/react@3.1.0(@types/react@18.3.14)(react@18.3.1)': + dependencies: + '@types/mdx': 2.0.13 + '@types/react': 18.3.14 + react: 18.3.1 + + '@mswjs/interceptors@0.37.3': + dependencies: + '@open-draft/deferred-promise': 2.2.0 + '@open-draft/logger': 0.3.0 + '@open-draft/until': 2.1.0 + is-node-process: 1.2.0 + outvariant: 1.4.3 + strict-event-emitter: 0.5.1 + '@nodelib/fs.scandir@2.1.5': dependencies: '@nodelib/fs.stat': 2.0.5 @@ -1488,6 +3160,15 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.17.1 + '@open-draft/deferred-promise@2.2.0': {} + + '@open-draft/logger@0.3.0': + dependencies: + is-node-process: 1.2.0 + outvariant: 1.4.3 + + '@open-draft/until@2.1.0': {} + '@reduxjs/toolkit@2.4.0(react-redux@9.1.2(@types/react@18.3.14)(react@18.3.1)(redux@5.0.1))(react@18.3.1)': dependencies: immer: 10.1.1 @@ -1498,6 +3179,14 @@ snapshots: react: 18.3.1 react-redux: 9.1.2(@types/react@18.3.14)(react@18.3.1)(redux@5.0.1) + '@rollup/pluginutils@5.1.3(rollup@4.28.0)': + dependencies: + '@types/estree': 1.0.6 + estree-walker: 2.0.2 + picomatch: 4.0.2 + optionalDependencies: + rollup: 4.28.0 + '@rollup/rollup-android-arm-eabi@4.28.0': optional: true @@ -1552,112 +3241,482 @@ snapshots: '@rollup/rollup-win32-x64-msvc@4.28.0': optional: true - '@tanstack/query-core@5.62.2': {} - - '@tanstack/react-query@5.62.2(react@18.3.1)': + '@storybook/addon-actions@8.4.7(storybook@8.4.7)': dependencies: - '@tanstack/query-core': 5.62.2 - react: 18.3.1 + '@storybook/global': 5.0.0 + '@types/uuid': 9.0.8 + dequal: 2.0.3 + polished: 4.3.1 + storybook: 8.4.7 + uuid: 9.0.1 + + '@storybook/addon-backgrounds@8.4.7(storybook@8.4.7)': + dependencies: + '@storybook/global': 5.0.0 + memoizerific: 1.11.3 + storybook: 8.4.7 + ts-dedent: 2.2.0 - '@types/babel__core@7.20.5': + '@storybook/addon-controls@8.4.7(storybook@8.4.7)': dependencies: - '@babel/parser': 7.26.3 - '@babel/types': 7.26.3 - '@types/babel__generator': 7.6.8 - '@types/babel__template': 7.4.4 - '@types/babel__traverse': 7.20.6 + '@storybook/global': 5.0.0 + dequal: 2.0.3 + storybook: 8.4.7 + ts-dedent: 2.2.0 - '@types/babel__generator@7.6.8': + '@storybook/addon-docs@8.4.7(@types/react@18.3.14)(storybook@8.4.7)': dependencies: - '@babel/types': 7.26.3 + '@mdx-js/react': 3.1.0(@types/react@18.3.14)(react@18.3.1) + '@storybook/blocks': 8.4.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.4.7) + '@storybook/csf-plugin': 8.4.7(storybook@8.4.7) + '@storybook/react-dom-shim': 8.4.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.4.7) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + storybook: 8.4.7 + ts-dedent: 2.2.0 + transitivePeerDependencies: + - '@types/react' - '@types/babel__template@7.4.4': + '@storybook/addon-essentials@8.4.7(@types/react@18.3.14)(storybook@8.4.7)': dependencies: - '@babel/parser': 7.26.3 - '@babel/types': 7.26.3 + '@storybook/addon-actions': 8.4.7(storybook@8.4.7) + '@storybook/addon-backgrounds': 8.4.7(storybook@8.4.7) + '@storybook/addon-controls': 8.4.7(storybook@8.4.7) + '@storybook/addon-docs': 8.4.7(@types/react@18.3.14)(storybook@8.4.7) + '@storybook/addon-highlight': 8.4.7(storybook@8.4.7) + '@storybook/addon-measure': 8.4.7(storybook@8.4.7) + '@storybook/addon-outline': 8.4.7(storybook@8.4.7) + '@storybook/addon-toolbars': 8.4.7(storybook@8.4.7) + '@storybook/addon-viewport': 8.4.7(storybook@8.4.7) + storybook: 8.4.7 + ts-dedent: 2.2.0 + transitivePeerDependencies: + - '@types/react' - '@types/babel__traverse@7.20.6': + '@storybook/addon-highlight@8.4.7(storybook@8.4.7)': dependencies: - '@babel/types': 7.26.3 + '@storybook/global': 5.0.0 + storybook: 8.4.7 - '@types/cookie@0.6.0': {} + '@storybook/addon-interactions@8.4.7(storybook@8.4.7)': + dependencies: + '@storybook/global': 5.0.0 + '@storybook/instrumenter': 8.4.7(storybook@8.4.7) + '@storybook/test': 8.4.7(storybook@8.4.7) + polished: 4.3.1 + storybook: 8.4.7 + ts-dedent: 2.2.0 + + '@storybook/addon-measure@8.4.7(storybook@8.4.7)': + dependencies: + '@storybook/global': 5.0.0 + storybook: 8.4.7 + tiny-invariant: 1.3.3 - '@types/estree@1.0.6': {} + '@storybook/addon-onboarding@8.4.7(react@18.3.1)(storybook@8.4.7)': + dependencies: + react-confetti: 6.1.0(react@18.3.1) + storybook: 8.4.7 + transitivePeerDependencies: + - react - '@types/json-schema@7.0.15': {} + '@storybook/addon-outline@8.4.7(storybook@8.4.7)': + dependencies: + '@storybook/global': 5.0.0 + storybook: 8.4.7 + ts-dedent: 2.2.0 - '@types/prop-types@15.7.14': {} + '@storybook/addon-toolbars@8.4.7(storybook@8.4.7)': + dependencies: + storybook: 8.4.7 - '@types/react-dom@18.3.2': + '@storybook/addon-viewport@8.4.7(storybook@8.4.7)': dependencies: - '@types/react': 18.3.14 + memoizerific: 1.11.3 + storybook: 8.4.7 - '@types/react@18.3.14': + '@storybook/blocks@8.4.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.4.7)': dependencies: - '@types/prop-types': 15.7.14 - csstype: 3.1.3 + '@storybook/csf': 0.1.12 + '@storybook/icons': 1.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + storybook: 8.4.7 + ts-dedent: 2.2.0 + optionalDependencies: + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) - '@types/stylis@4.2.5': {} + '@storybook/builder-vite@8.4.7(storybook@8.4.7)(vite@6.0.3(@types/node@22.10.2))': + dependencies: + '@storybook/csf-plugin': 8.4.7(storybook@8.4.7) + browser-assert: 1.2.1 + storybook: 8.4.7 + ts-dedent: 2.2.0 + vite: 6.0.3(@types/node@22.10.2) - '@types/use-sync-external-store@0.0.3': {} + '@storybook/components@8.4.7(storybook@8.4.7)': + dependencies: + storybook: 8.4.7 - '@typescript-eslint/eslint-plugin@8.17.0(@typescript-eslint/parser@8.17.0(eslint@9.16.0)(typescript@5.6.3))(eslint@9.16.0)(typescript@5.6.3)': + '@storybook/core@8.4.7': dependencies: - '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.17.0(eslint@9.16.0)(typescript@5.6.3) - '@typescript-eslint/scope-manager': 8.17.0 - '@typescript-eslint/type-utils': 8.17.0(eslint@9.16.0)(typescript@5.6.3) - '@typescript-eslint/utils': 8.17.0(eslint@9.16.0)(typescript@5.6.3) - '@typescript-eslint/visitor-keys': 8.17.0 - eslint: 9.16.0 - graphemer: 1.4.0 - ignore: 5.3.2 - natural-compare: 1.4.0 - ts-api-utils: 1.4.3(typescript@5.6.3) - optionalDependencies: - typescript: 5.6.3 + '@storybook/csf': 0.1.12 + better-opn: 3.0.2 + browser-assert: 1.2.1 + esbuild: 0.24.0 + esbuild-register: 3.6.0(esbuild@0.24.0) + jsdoc-type-pratt-parser: 4.1.0 + process: 0.11.10 + recast: 0.23.9 + semver: 7.6.3 + util: 0.12.5 + ws: 8.18.0 transitivePeerDependencies: + - bufferutil - supports-color + - utf-8-validate - '@typescript-eslint/parser@8.17.0(eslint@9.16.0)(typescript@5.6.3)': + '@storybook/csf-plugin@8.4.7(storybook@8.4.7)': dependencies: - '@typescript-eslint/scope-manager': 8.17.0 - '@typescript-eslint/types': 8.17.0 - '@typescript-eslint/typescript-estree': 8.17.0(typescript@5.6.3) - '@typescript-eslint/visitor-keys': 8.17.0 - debug: 4.3.7 - eslint: 9.16.0 - optionalDependencies: - typescript: 5.6.3 - transitivePeerDependencies: - - supports-color + storybook: 8.4.7 + unplugin: 1.16.0 - '@typescript-eslint/scope-manager@8.17.0': + '@storybook/csf@0.1.12': dependencies: - '@typescript-eslint/types': 8.17.0 - '@typescript-eslint/visitor-keys': 8.17.0 + type-fest: 2.19.0 - '@typescript-eslint/type-utils@8.17.0(eslint@9.16.0)(typescript@5.6.3)': + '@storybook/global@5.0.0': {} + + '@storybook/icons@1.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@typescript-eslint/typescript-estree': 8.17.0(typescript@5.6.3) - '@typescript-eslint/utils': 8.17.0(eslint@9.16.0)(typescript@5.6.3) - debug: 4.3.7 - eslint: 9.16.0 - ts-api-utils: 1.4.3(typescript@5.6.3) - optionalDependencies: - typescript: 5.6.3 - transitivePeerDependencies: - - supports-color + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) - '@typescript-eslint/types@8.17.0': {} + '@storybook/instrumenter@8.4.7(storybook@8.4.7)': + dependencies: + '@storybook/global': 5.0.0 + '@vitest/utils': 2.1.8 + storybook: 8.4.7 - '@typescript-eslint/typescript-estree@8.17.0(typescript@5.6.3)': + '@storybook/manager-api@8.4.7(storybook@8.4.7)': dependencies: - '@typescript-eslint/types': 8.17.0 - '@typescript-eslint/visitor-keys': 8.17.0 - debug: 4.3.7 - fast-glob: 3.3.2 - is-glob: 4.0.3 + storybook: 8.4.7 + + '@storybook/preview-api@8.4.7(storybook@8.4.7)': + dependencies: + storybook: 8.4.7 + + '@storybook/react-dom-shim@8.4.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.4.7)': + dependencies: + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + storybook: 8.4.7 + + '@storybook/react-vite@8.4.7(@storybook/test@8.4.7(storybook@8.4.7))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@4.28.0)(storybook@8.4.7)(typescript@5.6.3)(vite@6.0.3(@types/node@22.10.2))': + dependencies: + '@joshwooding/vite-plugin-react-docgen-typescript': 0.4.2(typescript@5.6.3)(vite@6.0.3(@types/node@22.10.2)) + '@rollup/pluginutils': 5.1.3(rollup@4.28.0) + '@storybook/builder-vite': 8.4.7(storybook@8.4.7)(vite@6.0.3(@types/node@22.10.2)) + '@storybook/react': 8.4.7(@storybook/test@8.4.7(storybook@8.4.7))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.4.7)(typescript@5.6.3) + find-up: 5.0.0 + magic-string: 0.30.14 + react: 18.3.1 + react-docgen: 7.1.0 + react-dom: 18.3.1(react@18.3.1) + resolve: 1.22.8 + storybook: 8.4.7 + tsconfig-paths: 4.2.0 + vite: 6.0.3(@types/node@22.10.2) + transitivePeerDependencies: + - '@storybook/test' + - rollup + - supports-color + - typescript + + '@storybook/react@8.4.7(@storybook/test@8.4.7(storybook@8.4.7))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.4.7)(typescript@5.6.3)': + dependencies: + '@storybook/components': 8.4.7(storybook@8.4.7) + '@storybook/global': 5.0.0 + '@storybook/manager-api': 8.4.7(storybook@8.4.7) + '@storybook/preview-api': 8.4.7(storybook@8.4.7) + '@storybook/react-dom-shim': 8.4.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.4.7) + '@storybook/theming': 8.4.7(storybook@8.4.7) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + storybook: 8.4.7 + optionalDependencies: + '@storybook/test': 8.4.7(storybook@8.4.7) + typescript: 5.6.3 + + '@storybook/test@8.4.7(storybook@8.4.7)': + dependencies: + '@storybook/csf': 0.1.12 + '@storybook/global': 5.0.0 + '@storybook/instrumenter': 8.4.7(storybook@8.4.7) + '@testing-library/dom': 10.4.0 + '@testing-library/jest-dom': 6.5.0 + '@testing-library/user-event': 14.5.2(@testing-library/dom@10.4.0) + '@vitest/expect': 2.0.5 + '@vitest/spy': 2.0.5 + storybook: 8.4.7 + + '@storybook/theming@8.4.7(storybook@8.4.7)': + dependencies: + storybook: 8.4.7 + + '@svgr/babel-plugin-add-jsx-attribute@8.0.0(@babel/core@7.26.0)': + dependencies: + '@babel/core': 7.26.0 + + '@svgr/babel-plugin-remove-jsx-attribute@8.0.0(@babel/core@7.26.0)': + dependencies: + '@babel/core': 7.26.0 + + '@svgr/babel-plugin-remove-jsx-empty-expression@8.0.0(@babel/core@7.26.0)': + dependencies: + '@babel/core': 7.26.0 + + '@svgr/babel-plugin-replace-jsx-attribute-value@8.0.0(@babel/core@7.26.0)': + dependencies: + '@babel/core': 7.26.0 + + '@svgr/babel-plugin-svg-dynamic-title@8.0.0(@babel/core@7.26.0)': + dependencies: + '@babel/core': 7.26.0 + + '@svgr/babel-plugin-svg-em-dimensions@8.0.0(@babel/core@7.26.0)': + dependencies: + '@babel/core': 7.26.0 + + '@svgr/babel-plugin-transform-react-native-svg@8.1.0(@babel/core@7.26.0)': + dependencies: + '@babel/core': 7.26.0 + + '@svgr/babel-plugin-transform-svg-component@8.0.0(@babel/core@7.26.0)': + dependencies: + '@babel/core': 7.26.0 + + '@svgr/babel-preset@8.1.0(@babel/core@7.26.0)': + dependencies: + '@babel/core': 7.26.0 + '@svgr/babel-plugin-add-jsx-attribute': 8.0.0(@babel/core@7.26.0) + '@svgr/babel-plugin-remove-jsx-attribute': 8.0.0(@babel/core@7.26.0) + '@svgr/babel-plugin-remove-jsx-empty-expression': 8.0.0(@babel/core@7.26.0) + '@svgr/babel-plugin-replace-jsx-attribute-value': 8.0.0(@babel/core@7.26.0) + '@svgr/babel-plugin-svg-dynamic-title': 8.0.0(@babel/core@7.26.0) + '@svgr/babel-plugin-svg-em-dimensions': 8.0.0(@babel/core@7.26.0) + '@svgr/babel-plugin-transform-react-native-svg': 8.1.0(@babel/core@7.26.0) + '@svgr/babel-plugin-transform-svg-component': 8.0.0(@babel/core@7.26.0) + + '@svgr/core@8.1.0(typescript@5.6.3)': + dependencies: + '@babel/core': 7.26.0 + '@svgr/babel-preset': 8.1.0(@babel/core@7.26.0) + camelcase: 6.3.0 + cosmiconfig: 8.3.6(typescript@5.6.3) + snake-case: 3.0.4 + transitivePeerDependencies: + - supports-color + - typescript + + '@svgr/hast-util-to-babel-ast@8.0.0': + dependencies: + '@babel/types': 7.26.3 + entities: 4.5.0 + + '@svgr/plugin-jsx@8.1.0(@svgr/core@8.1.0(typescript@5.6.3))': + dependencies: + '@babel/core': 7.26.0 + '@svgr/babel-preset': 8.1.0(@babel/core@7.26.0) + '@svgr/core': 8.1.0(typescript@5.6.3) + '@svgr/hast-util-to-babel-ast': 8.0.0 + svg-parser: 2.0.4 + transitivePeerDependencies: + - supports-color + + '@tanstack/query-core@5.62.2': {} + + '@tanstack/react-query@5.62.2(react@18.3.1)': + dependencies: + '@tanstack/query-core': 5.62.2 + react: 18.3.1 + + '@testing-library/dom@10.4.0': + dependencies: + '@babel/code-frame': 7.26.2 + '@babel/runtime': 7.26.0 + '@types/aria-query': 5.0.4 + aria-query: 5.3.0 + chalk: 4.1.2 + dom-accessibility-api: 0.5.16 + lz-string: 1.5.0 + pretty-format: 27.5.1 + + '@testing-library/jest-dom@6.5.0': + dependencies: + '@adobe/css-tools': 4.4.1 + aria-query: 5.3.2 + chalk: 3.0.0 + css.escape: 1.5.1 + dom-accessibility-api: 0.6.3 + lodash: 4.17.21 + redent: 3.0.0 + + '@testing-library/user-event@14.5.2(@testing-library/dom@10.4.0)': + dependencies: + '@testing-library/dom': 10.4.0 + + '@types/aria-query@5.0.4': {} + + '@types/babel__core@7.20.5': + dependencies: + '@babel/parser': 7.26.3 + '@babel/types': 7.26.3 + '@types/babel__generator': 7.6.8 + '@types/babel__template': 7.4.4 + '@types/babel__traverse': 7.20.6 + + '@types/babel__generator@7.6.8': + dependencies: + '@babel/types': 7.26.3 + + '@types/babel__template@7.4.4': + dependencies: + '@babel/parser': 7.26.3 + '@babel/types': 7.26.3 + + '@types/babel__traverse@7.20.6': + dependencies: + '@babel/types': 7.26.3 + + '@types/cookie@0.6.0': {} + + '@types/doctrine@0.0.9': {} + + '@types/estree@1.0.6': {} + + '@types/hoist-non-react-statics@3.3.6': + dependencies: + '@types/react': 18.3.14 + hoist-non-react-statics: 3.3.2 + + '@types/json-schema@7.0.15': {} + + '@types/jwt-decode@3.1.0': + dependencies: + jwt-decode: 4.0.0 + + '@types/mdx@2.0.13': {} + + '@types/node@22.10.2': + dependencies: + undici-types: 6.20.0 + + '@types/prop-types@15.7.14': {} + + '@types/quill@1.3.10': + dependencies: + parchment: 1.1.4 + + '@types/quill@2.0.14': + dependencies: + parchment: 1.1.4 + quill-delta: 5.1.0 + + '@types/react-dom@18.3.2': + dependencies: + '@types/react': 18.3.14 + + '@types/react-redux@7.1.34': + dependencies: + '@types/hoist-non-react-statics': 3.3.6 + '@types/react': 18.3.14 + hoist-non-react-statics: 3.3.2 + redux: 4.2.1 + + '@types/react@18.3.14': + dependencies: + '@types/prop-types': 15.7.14 + csstype: 3.1.3 + + '@types/redux-persist@4.3.1(react@18.3.1)(redux@5.0.1)': + dependencies: + redux-persist: 6.0.0(react@18.3.1)(redux@5.0.1) + transitivePeerDependencies: + - react + - redux + + '@types/resolve@1.20.6': {} + + '@types/statuses@2.0.5': {} + + '@types/stylis@4.2.5': {} + + '@types/tough-cookie@4.0.5': {} + + '@types/trusted-types@2.0.7': + optional: true + + '@types/use-sync-external-store@0.0.3': {} + + '@types/uuid@9.0.8': {} + + '@typescript-eslint/eslint-plugin@8.17.0(@typescript-eslint/parser@8.17.0(eslint@9.16.0)(typescript@5.6.3))(eslint@9.16.0)(typescript@5.6.3)': + dependencies: + '@eslint-community/regexpp': 4.12.1 + '@typescript-eslint/parser': 8.17.0(eslint@9.16.0)(typescript@5.6.3) + '@typescript-eslint/scope-manager': 8.17.0 + '@typescript-eslint/type-utils': 8.17.0(eslint@9.16.0)(typescript@5.6.3) + '@typescript-eslint/utils': 8.17.0(eslint@9.16.0)(typescript@5.6.3) + '@typescript-eslint/visitor-keys': 8.17.0 + eslint: 9.16.0 + graphemer: 1.4.0 + ignore: 5.3.2 + natural-compare: 1.4.0 + ts-api-utils: 1.4.3(typescript@5.6.3) + optionalDependencies: + typescript: 5.6.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@8.17.0(eslint@9.16.0)(typescript@5.6.3)': + dependencies: + '@typescript-eslint/scope-manager': 8.17.0 + '@typescript-eslint/types': 8.17.0 + '@typescript-eslint/typescript-estree': 8.17.0(typescript@5.6.3) + '@typescript-eslint/visitor-keys': 8.17.0 + debug: 4.3.7 + eslint: 9.16.0 + optionalDependencies: + typescript: 5.6.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/scope-manager@8.17.0': + dependencies: + '@typescript-eslint/types': 8.17.0 + '@typescript-eslint/visitor-keys': 8.17.0 + + '@typescript-eslint/type-utils@8.17.0(eslint@9.16.0)(typescript@5.6.3)': + dependencies: + '@typescript-eslint/typescript-estree': 8.17.0(typescript@5.6.3) + '@typescript-eslint/utils': 8.17.0(eslint@9.16.0)(typescript@5.6.3) + debug: 4.3.7 + eslint: 9.16.0 + ts-api-utils: 1.4.3(typescript@5.6.3) + optionalDependencies: + typescript: 5.6.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/types@8.17.0': {} + + '@typescript-eslint/typescript-estree@8.17.0(typescript@5.6.3)': + dependencies: + '@typescript-eslint/types': 8.17.0 + '@typescript-eslint/visitor-keys': 8.17.0 + debug: 4.3.7 + fast-glob: 3.3.2 + is-glob: 4.0.3 minimatch: 9.0.5 semver: 7.6.3 ts-api-utils: 1.4.3(typescript@5.6.3) @@ -1683,17 +3742,80 @@ snapshots: '@typescript-eslint/types': 8.17.0 eslint-visitor-keys: 4.2.0 - '@vitejs/plugin-react@4.3.4(vite@6.0.3)': + '@vitejs/plugin-react@4.3.4(vite@6.0.3(@types/node@22.10.2))': dependencies: '@babel/core': 7.26.0 '@babel/plugin-transform-react-jsx-self': 7.25.9(@babel/core@7.26.0) '@babel/plugin-transform-react-jsx-source': 7.25.9(@babel/core@7.26.0) '@types/babel__core': 7.20.5 react-refresh: 0.14.2 - vite: 6.0.3 + vite: 6.0.3(@types/node@22.10.2) transitivePeerDependencies: - supports-color + '@vitest/expect@2.0.5': + dependencies: + '@vitest/spy': 2.0.5 + '@vitest/utils': 2.0.5 + chai: 5.1.2 + tinyrainbow: 1.2.0 + + '@vitest/expect@2.1.8': + dependencies: + '@vitest/spy': 2.1.8 + '@vitest/utils': 2.1.8 + chai: 5.1.2 + tinyrainbow: 1.2.0 + + '@vitest/mocker@2.1.8(msw@2.6.8(@types/node@22.10.2)(typescript@5.6.3))(vite@5.4.11(@types/node@22.10.2))': + dependencies: + '@vitest/spy': 2.1.8 + estree-walker: 3.0.3 + magic-string: 0.30.14 + optionalDependencies: + msw: 2.6.8(@types/node@22.10.2)(typescript@5.6.3) + vite: 5.4.11(@types/node@22.10.2) + + '@vitest/pretty-format@2.0.5': + dependencies: + tinyrainbow: 1.2.0 + + '@vitest/pretty-format@2.1.8': + dependencies: + tinyrainbow: 1.2.0 + + '@vitest/runner@2.1.8': + dependencies: + '@vitest/utils': 2.1.8 + pathe: 1.1.2 + + '@vitest/snapshot@2.1.8': + dependencies: + '@vitest/pretty-format': 2.1.8 + magic-string: 0.30.14 + pathe: 1.1.2 + + '@vitest/spy@2.0.5': + dependencies: + tinyspy: 3.0.2 + + '@vitest/spy@2.1.8': + dependencies: + tinyspy: 3.0.2 + + '@vitest/utils@2.0.5': + dependencies: + '@vitest/pretty-format': 2.0.5 + estree-walker: 3.0.3 + loupe: 3.1.2 + tinyrainbow: 1.2.0 + + '@vitest/utils@2.1.8': + dependencies: + '@vitest/pretty-format': 2.1.8 + loupe: 3.1.2 + tinyrainbow: 1.2.0 + acorn-jsx@5.3.2(acorn@8.14.0): dependencies: acorn: 8.14.0 @@ -1707,14 +3829,54 @@ snapshots: json-schema-traverse: 0.4.1 uri-js: 4.4.1 + ansi-escapes@4.3.2: + dependencies: + type-fest: 0.21.3 + + ansi-regex@5.0.1: {} + + ansi-regex@6.1.0: {} + ansi-styles@4.3.0: dependencies: color-convert: 2.0.1 + ansi-styles@5.2.0: {} + argparse@2.0.1: {} + aria-query@5.3.0: + dependencies: + dequal: 2.0.3 + + aria-query@5.3.2: {} + + assertion-error@2.0.1: {} + + ast-types@0.16.1: + dependencies: + tslib: 2.6.2 + + asynckit@0.4.0: {} + + available-typed-arrays@1.0.7: + dependencies: + possible-typed-array-names: 1.0.0 + + axios@1.7.9: + dependencies: + follow-redirects: 1.15.9 + form-data: 4.0.1 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + balanced-match@1.0.2: {} + better-opn@3.0.2: + dependencies: + open: 8.4.2 + brace-expansion@1.1.11: dependencies: balanced-match: 1.0.2 @@ -1728,6 +3890,8 @@ snapshots: dependencies: fill-range: 7.1.1 + browser-assert@1.2.1: {} + browserslist@4.24.2: dependencies: caniuse-lite: 1.0.30001686 @@ -1735,29 +3899,97 @@ snapshots: node-releases: 2.0.18 update-browserslist-db: 1.1.1(browserslist@4.24.2) + cac@6.7.14: {} + + call-bind-apply-helpers@1.0.0: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + call-bind-apply-helpers@1.0.1: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + call-bind@1.0.8: + dependencies: + call-bind-apply-helpers: 1.0.0 + es-define-property: 1.0.1 + get-intrinsic: 1.2.5 + set-function-length: 1.2.2 + + call-bound@1.0.3: + dependencies: + call-bind-apply-helpers: 1.0.1 + get-intrinsic: 1.2.6 + callsites@3.1.0: {} + camelcase@6.3.0: {} + camelize@1.0.1: {} caniuse-lite@1.0.30001686: {} + chai@5.1.2: + dependencies: + assertion-error: 2.0.1 + check-error: 2.1.1 + deep-eql: 5.0.2 + loupe: 3.1.2 + pathval: 2.0.0 + + chalk@3.0.0: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + chalk@4.1.2: dependencies: ansi-styles: 4.3.0 supports-color: 7.2.0 + check-error@2.1.1: {} + + chromatic@11.20.0: {} + + cli-width@4.1.0: {} + + cliui@8.0.1: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + + clone@2.1.2: {} + color-convert@2.0.1: dependencies: color-name: 1.1.4 color-name@1.1.4: {} + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + concat-map@0.0.1: {} convert-source-map@2.0.0: {} + cookie@0.7.2: {} + cookie@1.0.2: {} + cosmiconfig@8.3.6(typescript@5.6.3): + dependencies: + import-fresh: 3.3.0 + js-yaml: 4.1.0 + parse-json: 5.2.0 + path-type: 4.0.0 + optionalDependencies: + typescript: 5.6.3 + cross-spawn@7.0.6: dependencies: path-key: 3.1.1 @@ -1772,16 +4004,121 @@ snapshots: css-color-keywords: 1.0.0 postcss-value-parser: 4.2.0 + css.escape@1.5.1: {} + csstype@3.1.3: {} debug@4.3.7: dependencies: ms: 2.1.3 + deep-eql@5.0.2: {} + + deep-equal@1.1.2: + dependencies: + is-arguments: 1.1.1 + is-date-object: 1.1.0 + is-regex: 1.2.1 + object-is: 1.1.6 + object-keys: 1.1.1 + regexp.prototype.flags: 1.5.3 + deep-is@0.1.4: {} + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.1 + es-errors: 1.3.0 + gopd: 1.2.0 + + define-lazy-prop@2.0.0: {} + + define-properties@1.2.1: + dependencies: + define-data-property: 1.1.4 + has-property-descriptors: 1.0.2 + object-keys: 1.1.1 + + delayed-stream@1.0.0: {} + + dequal@2.0.3: {} + + doctrine@3.0.0: + dependencies: + esutils: 2.0.3 + + dom-accessibility-api@0.5.16: {} + + dom-accessibility-api@0.6.3: {} + + dompurify@3.2.3: + optionalDependencies: + '@types/trusted-types': 2.0.7 + + dot-case@3.0.4: + dependencies: + no-case: 3.0.4 + tslib: 2.6.2 + + dunder-proto@1.0.0: + dependencies: + call-bind-apply-helpers: 1.0.0 + es-errors: 1.3.0 + gopd: 1.2.0 + electron-to-chromium@1.5.71: {} + emoji-regex@8.0.0: {} + + entities@4.5.0: {} + + error-ex@1.3.2: + dependencies: + is-arrayish: 0.2.1 + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-module-lexer@1.5.4: {} + + es-object-atoms@1.0.0: + dependencies: + es-errors: 1.3.0 + + esbuild-register@3.6.0(esbuild@0.24.0): + dependencies: + debug: 4.3.7 + esbuild: 0.24.0 + transitivePeerDependencies: + - supports-color + + esbuild@0.21.5: + optionalDependencies: + '@esbuild/aix-ppc64': 0.21.5 + '@esbuild/android-arm': 0.21.5 + '@esbuild/android-arm64': 0.21.5 + '@esbuild/android-x64': 0.21.5 + '@esbuild/darwin-arm64': 0.21.5 + '@esbuild/darwin-x64': 0.21.5 + '@esbuild/freebsd-arm64': 0.21.5 + '@esbuild/freebsd-x64': 0.21.5 + '@esbuild/linux-arm': 0.21.5 + '@esbuild/linux-arm64': 0.21.5 + '@esbuild/linux-ia32': 0.21.5 + '@esbuild/linux-loong64': 0.21.5 + '@esbuild/linux-mips64el': 0.21.5 + '@esbuild/linux-ppc64': 0.21.5 + '@esbuild/linux-riscv64': 0.21.5 + '@esbuild/linux-s390x': 0.21.5 + '@esbuild/linux-x64': 0.21.5 + '@esbuild/netbsd-x64': 0.21.5 + '@esbuild/openbsd-x64': 0.21.5 + '@esbuild/sunos-x64': 0.21.5 + '@esbuild/win32-arm64': 0.21.5 + '@esbuild/win32-ia32': 0.21.5 + '@esbuild/win32-x64': 0.21.5 + esbuild@0.24.0: optionalDependencies: '@esbuild/aix-ppc64': 0.24.0 @@ -1821,6 +4158,16 @@ snapshots: dependencies: eslint: 9.16.0 + eslint-plugin-storybook@0.11.1(eslint@9.16.0)(typescript@5.6.3): + dependencies: + '@storybook/csf': 0.1.12 + '@typescript-eslint/utils': 8.17.0(eslint@9.16.0)(typescript@5.6.3) + eslint: 9.16.0 + ts-dedent: 2.2.0 + transitivePeerDependencies: + - supports-color + - typescript + eslint-scope@8.2.0: dependencies: esrecurse: 4.3.0 @@ -1875,6 +4222,8 @@ snapshots: acorn-jsx: 5.3.2(acorn@8.14.0) eslint-visitor-keys: 4.2.0 + esprima@4.0.1: {} + esquery@1.6.0: dependencies: estraverse: 5.3.0 @@ -1885,10 +4234,28 @@ snapshots: estraverse@5.3.0: {} + estree-walker@2.0.2: {} + + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.6 + esutils@2.0.3: {} + eventemitter3@2.0.3: {} + + eventemitter3@5.0.1: {} + + expect-type@1.1.0: {} + + extend@3.0.2: {} + fast-deep-equal@3.1.3: {} + fast-diff@1.1.2: {} + + fast-diff@1.3.0: {} + fast-glob@3.3.2: dependencies: '@nodelib/fs.stat': 2.0.5 @@ -1909,6 +4276,8 @@ snapshots: dependencies: flat-cache: 4.0.1 + filesize@10.1.6: {} + fill-range@7.1.1: dependencies: to-regex-range: 5.0.1 @@ -1925,11 +4294,53 @@ snapshots: flatted@3.3.2: {} + follow-redirects@1.15.9: {} + + for-each@0.3.3: + dependencies: + is-callable: 1.2.7 + + form-data@4.0.1: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + fsevents@2.3.3: optional: true + function-bind@1.1.2: {} + + functions-have-names@1.2.3: {} + gensync@1.0.0-beta.2: {} + get-caller-file@2.0.5: {} + + get-intrinsic@1.2.5: + dependencies: + call-bind-apply-helpers: 1.0.0 + dunder-proto: 1.0.0 + es-define-property: 1.0.1 + es-errors: 1.3.0 + function-bind: 1.1.2 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + + get-intrinsic@1.2.6: + dependencies: + call-bind-apply-helpers: 1.0.1 + dunder-proto: 1.0.0 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.0.0 + function-bind: 1.1.2 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + math-intrinsics: 1.1.0 + glob-parent@5.1.2: dependencies: is-glob: 4.0.3 @@ -1944,10 +4355,39 @@ snapshots: globals@15.13.0: {} + gopd@1.2.0: {} + + graceful-fs@4.2.11: + optional: true + graphemer@1.4.0: {} + graphql@16.9.0: {} + has-flag@4.0.0: {} + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.1 + + has-symbols@1.1.0: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.1.0 + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + headers-polyfill@4.0.3: {} + + hoist-non-react-statics@3.3.2: + dependencies: + react-is: 16.13.1 + + husky@9.1.7: {} + ignore@5.3.2: {} immer@10.1.1: {} @@ -1959,14 +4399,61 @@ snapshots: imurmurhash@0.1.4: {} + indent-string@4.0.0: {} + + inherits@2.0.4: {} + + is-arguments@1.1.1: + dependencies: + call-bind: 1.0.8 + has-tostringtag: 1.0.2 + + is-arrayish@0.2.1: {} + + is-callable@1.2.7: {} + + is-core-module@2.15.1: + dependencies: + hasown: 2.0.2 + + is-date-object@1.1.0: + dependencies: + call-bound: 1.0.3 + has-tostringtag: 1.0.2 + + is-docker@2.2.1: {} + is-extglob@2.1.1: {} + is-fullwidth-code-point@3.0.0: {} + + is-generator-function@1.0.10: + dependencies: + has-tostringtag: 1.0.2 + is-glob@4.0.3: dependencies: is-extglob: 2.1.1 + is-node-process@1.2.0: {} + is-number@7.0.0: {} + is-regex@1.2.1: + dependencies: + call-bound: 1.0.3 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + is-typed-array@1.1.13: + dependencies: + which-typed-array: 1.1.16 + + is-wsl@2.2.0: + dependencies: + is-docker: 2.2.1 + isexe@2.0.0: {} js-tokens@4.0.0: {} @@ -1975,16 +4462,28 @@ snapshots: dependencies: argparse: 2.0.1 + jsdoc-type-pratt-parser@4.1.0: {} + jsesc@3.0.2: {} json-buffer@3.0.1: {} + json-parse-even-better-errors@2.3.1: {} + json-schema-traverse@0.4.1: {} json-stable-stringify-without-jsonify@1.0.1: {} json5@2.2.3: {} + jsonfile@6.1.0: + dependencies: + universalify: 2.0.1 + optionalDependencies: + graceful-fs: 4.2.11 + + jwt-decode@4.0.0: {} + keyv@4.5.4: dependencies: json-buffer: 3.0.1 @@ -1994,20 +4493,54 @@ snapshots: prelude-ls: 1.2.1 type-check: 0.4.0 + lines-and-columns@1.2.4: {} + locate-path@6.0.0: dependencies: p-locate: 5.0.0 + lodash-es@4.17.21: {} + + lodash.clonedeep@4.5.0: {} + + lodash.isequal@4.5.0: {} + lodash.merge@4.6.2: {} + lodash@4.17.21: {} + loose-envify@1.4.0: dependencies: js-tokens: 4.0.0 + loupe@3.1.2: {} + + lower-case@2.0.2: + dependencies: + tslib: 2.6.2 + lru-cache@5.1.1: dependencies: yallist: 3.1.1 + lz-string@1.5.0: {} + + magic-string@0.27.0: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.0 + + magic-string@0.30.14: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.0 + + map-or-similar@1.5.0: {} + + math-intrinsics@1.1.0: {} + + memoizerific@1.11.3: + dependencies: + map-or-similar: 1.5.0 + merge2@1.4.1: {} micromatch@4.0.8: @@ -2015,6 +4548,14 @@ snapshots: braces: 3.0.3 picomatch: 2.3.1 + mime-db@1.52.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + min-indent@1.0.1: {} + minimatch@3.1.2: dependencies: brace-expansion: 1.1.11 @@ -2023,14 +4564,61 @@ snapshots: dependencies: brace-expansion: 2.0.1 + minimist@1.2.8: {} + ms@2.1.3: {} + msw@2.6.8(@types/node@22.10.2)(typescript@5.6.3): + dependencies: + '@bundled-es-modules/cookie': 2.0.1 + '@bundled-es-modules/statuses': 1.0.1 + '@bundled-es-modules/tough-cookie': 0.1.6 + '@inquirer/confirm': 5.1.0(@types/node@22.10.2) + '@mswjs/interceptors': 0.37.3 + '@open-draft/deferred-promise': 2.2.0 + '@open-draft/until': 2.1.0 + '@types/cookie': 0.6.0 + '@types/statuses': 2.0.5 + chalk: 4.1.2 + graphql: 16.9.0 + headers-polyfill: 4.0.3 + is-node-process: 1.2.0 + outvariant: 1.4.3 + path-to-regexp: 6.3.0 + strict-event-emitter: 0.5.1 + type-fest: 4.30.0 + yargs: 17.7.2 + optionalDependencies: + typescript: 5.6.3 + transitivePeerDependencies: + - '@types/node' + + mute-stream@2.0.0: {} + nanoid@3.3.8: {} natural-compare@1.4.0: {} + no-case@3.0.4: + dependencies: + lower-case: 2.0.2 + tslib: 2.6.2 + node-releases@2.0.18: {} + object-is@1.1.6: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + + object-keys@1.1.1: {} + + open@8.4.2: + dependencies: + define-lazy-prop: 2.0.0 + is-docker: 2.2.1 + is-wsl: 2.2.0 + optionator@0.9.4: dependencies: deep-is: 0.1.4 @@ -2040,6 +4628,8 @@ snapshots: type-check: 0.4.0 word-wrap: 1.2.5 + outvariant@1.4.3: {} + p-limit@3.1.0: dependencies: yocto-queue: 0.1.0 @@ -2048,18 +4638,47 @@ snapshots: dependencies: p-limit: 3.1.0 + parchment@1.1.4: {} + + parchment@3.0.0: {} + parent-module@1.0.1: dependencies: callsites: 3.1.0 + parse-json@5.2.0: + dependencies: + '@babel/code-frame': 7.26.2 + error-ex: 1.3.2 + json-parse-even-better-errors: 2.3.1 + lines-and-columns: 1.2.4 + path-exists@4.0.0: {} path-key@3.1.1: {} + path-parse@1.0.7: {} + + path-to-regexp@6.3.0: {} + + path-type@4.0.0: {} + + pathe@1.1.2: {} + + pathval@2.0.0: {} + picocolors@1.1.1: {} picomatch@2.3.1: {} + picomatch@4.0.2: {} + + polished@4.3.1: + dependencies: + '@babel/runtime': 7.26.0 + + possible-typed-array-names@1.0.0: {} + postcss-value-parser@4.2.0: {} postcss@8.4.38: @@ -2076,16 +4695,100 @@ snapshots: prelude-ls@1.2.1: {} + pretty-format@27.5.1: + dependencies: + ansi-regex: 5.0.1 + ansi-styles: 5.2.0 + react-is: 17.0.2 + + process@0.11.10: {} + + proxy-from-env@1.1.0: {} + + psl@1.15.0: + dependencies: + punycode: 2.3.1 + punycode@2.3.1: {} + querystringify@2.2.0: {} + queue-microtask@1.2.3: {} + quill-delta@3.6.3: + dependencies: + deep-equal: 1.1.2 + extend: 3.0.2 + fast-diff: 1.1.2 + + quill-delta@5.1.0: + dependencies: + fast-diff: 1.3.0 + lodash.clonedeep: 4.5.0 + lodash.isequal: 4.5.0 + + quill@1.3.7: + dependencies: + clone: 2.1.2 + deep-equal: 1.1.2 + eventemitter3: 2.0.3 + extend: 3.0.2 + parchment: 1.1.4 + quill-delta: 3.6.3 + + quill@2.0.3: + dependencies: + eventemitter3: 5.0.1 + lodash-es: 4.17.21 + parchment: 3.0.0 + quill-delta: 5.1.0 + + react-confetti@6.1.0(react@18.3.1): + dependencies: + react: 18.3.1 + tween-functions: 1.2.0 + + react-docgen-typescript@2.2.2(typescript@5.6.3): + dependencies: + typescript: 5.6.3 + + react-docgen@7.1.0: + dependencies: + '@babel/core': 7.26.0 + '@babel/traverse': 7.26.4 + '@babel/types': 7.26.3 + '@types/babel__core': 7.20.5 + '@types/babel__traverse': 7.20.6 + '@types/doctrine': 0.0.9 + '@types/resolve': 1.20.6 + doctrine: 3.0.0 + resolve: 1.22.8 + strip-indent: 4.0.0 + transitivePeerDependencies: + - supports-color + react-dom@18.3.1(react@18.3.1): dependencies: loose-envify: 1.4.0 react: 18.3.1 scheduler: 0.23.2 + react-hook-form@7.54.1(react@18.3.1): + dependencies: + react: 18.3.1 + + react-is@16.13.1: {} + + react-is@17.0.2: {} + + react-quill@2.0.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@types/quill': 1.3.10 + lodash: 4.17.21 + quill: 1.3.7 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-redux@9.1.2(@types/react@18.3.14)(react@18.3.1)(redux@5.0.1): dependencies: '@types/use-sync-external-store': 0.0.3 @@ -2111,16 +4814,58 @@ snapshots: dependencies: loose-envify: 1.4.0 + recast@0.23.9: + dependencies: + ast-types: 0.16.1 + esprima: 4.0.1 + source-map: 0.6.1 + tiny-invariant: 1.3.3 + tslib: 2.6.2 + + redent@3.0.0: + dependencies: + indent-string: 4.0.0 + strip-indent: 3.0.0 + + redux-persist@6.0.0(react@18.3.1)(redux@5.0.1): + dependencies: + redux: 5.0.1 + optionalDependencies: + react: 18.3.1 + redux-thunk@3.1.0(redux@5.0.1): dependencies: redux: 5.0.1 + redux@4.2.1: + dependencies: + '@babel/runtime': 7.26.0 + redux@5.0.1: {} + regenerator-runtime@0.14.1: {} + + regexp.prototype.flags@1.5.3: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-errors: 1.3.0 + set-function-name: 2.0.2 + + require-directory@2.1.1: {} + + requires-port@1.0.0: {} + reselect@5.1.1: {} resolve-from@4.0.0: {} + resolve@1.22.8: + dependencies: + is-core-module: 2.15.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + reusify@1.0.4: {} rollup@4.28.0: @@ -2161,6 +4906,22 @@ snapshots: set-cookie-parser@2.7.1: {} + set-function-length@1.2.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.5 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + + set-function-name@2.0.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + functions-have-names: 1.2.3 + has-property-descriptors: 1.0.2 + shallowequal@1.1.0: {} shebang-command@2.0.0: @@ -2169,8 +4930,59 @@ snapshots: shebang-regex@3.0.0: {} + siginfo@2.0.0: {} + + signal-exit@4.1.0: {} + + snake-case@3.0.4: + dependencies: + dot-case: 3.0.4 + tslib: 2.6.2 + source-map-js@1.2.1: {} + source-map@0.6.1: {} + + stackback@0.0.2: {} + + statuses@2.0.1: {} + + std-env@3.8.0: {} + + storybook@8.4.7: + dependencies: + '@storybook/core': 8.4.7 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + strict-event-emitter@0.5.1: {} + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-ansi@7.1.0: + dependencies: + ansi-regex: 6.1.0 + + strip-bom@3.0.0: {} + + strip-indent@3.0.0: + dependencies: + min-indent: 1.0.1 + + strip-indent@4.0.0: + dependencies: + min-indent: 1.0.1 + strip-json-comments@3.1.1: {} styled-components@6.1.13(react-dom@18.3.1(react@18.3.1))(react@18.3.1): @@ -2193,22 +5005,61 @@ snapshots: dependencies: has-flag: 4.0.0 + supports-preserve-symlinks-flag@1.0.0: {} + + svg-parser@2.0.4: {} + + tiny-invariant@1.3.3: {} + + tinybench@2.9.0: {} + + tinyexec@0.3.1: {} + + tinypool@1.0.2: {} + + tinyrainbow@1.2.0: {} + + tinyspy@3.0.2: {} + to-regex-range@5.0.1: dependencies: is-number: 7.0.0 + tough-cookie@4.1.4: + dependencies: + psl: 1.15.0 + punycode: 2.3.1 + universalify: 0.2.0 + url-parse: 1.5.10 + ts-api-utils@1.4.3(typescript@5.6.3): dependencies: typescript: 5.6.3 + ts-dedent@2.2.0: {} + + tsconfig-paths@4.2.0: + dependencies: + json5: 2.2.3 + minimist: 1.2.8 + strip-bom: 3.0.0 + tslib@2.6.2: {} turbo-stream@2.4.0: {} + tween-functions@1.2.0: {} + type-check@0.4.0: dependencies: prelude-ls: 1.2.1 + type-fest@0.21.3: {} + + type-fest@2.19.0: {} + + type-fest@4.30.0: {} + typescript-eslint@8.17.0(eslint@9.16.0)(typescript@5.6.3): dependencies: '@typescript-eslint/eslint-plugin': 8.17.0(@typescript-eslint/parser@8.17.0(eslint@9.16.0)(typescript@5.6.3))(eslint@9.16.0)(typescript@5.6.3) @@ -2222,6 +5073,17 @@ snapshots: typescript@5.6.3: {} + undici-types@6.20.0: {} + + universalify@0.2.0: {} + + universalify@2.0.1: {} + + unplugin@1.16.0: + dependencies: + acorn: 8.14.0 + webpack-virtual-modules: 0.6.2 + update-browserslist-db@1.1.1(browserslist@4.24.2): dependencies: browserslist: 4.24.2 @@ -2232,24 +5094,158 @@ snapshots: dependencies: punycode: 2.3.1 + url-parse@1.5.10: + dependencies: + querystringify: 2.2.0 + requires-port: 1.0.0 + use-sync-external-store@1.4.0(react@18.3.1): dependencies: react: 18.3.1 - vite@6.0.3: + util@0.12.5: + dependencies: + inherits: 2.0.4 + is-arguments: 1.1.1 + is-generator-function: 1.0.10 + is-typed-array: 1.1.13 + which-typed-array: 1.1.16 + + uuid@9.0.1: {} + + vite-node@2.1.8(@types/node@22.10.2): + dependencies: + cac: 6.7.14 + debug: 4.3.7 + es-module-lexer: 1.5.4 + pathe: 1.1.2 + vite: 5.4.11(@types/node@22.10.2) + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + + vite-plugin-svgr@4.3.0(rollup@4.28.0)(typescript@5.6.3)(vite@6.0.3(@types/node@22.10.2)): + dependencies: + '@rollup/pluginutils': 5.1.3(rollup@4.28.0) + '@svgr/core': 8.1.0(typescript@5.6.3) + '@svgr/plugin-jsx': 8.1.0(@svgr/core@8.1.0(typescript@5.6.3)) + vite: 6.0.3(@types/node@22.10.2) + transitivePeerDependencies: + - rollup + - supports-color + - typescript + + vite@5.4.11(@types/node@22.10.2): + dependencies: + esbuild: 0.21.5 + postcss: 8.4.49 + rollup: 4.28.0 + optionalDependencies: + '@types/node': 22.10.2 + fsevents: 2.3.3 + + vite@6.0.3(@types/node@22.10.2): dependencies: esbuild: 0.24.0 postcss: 8.4.49 rollup: 4.28.0 optionalDependencies: + '@types/node': 22.10.2 fsevents: 2.3.3 + vitest@2.1.8(@types/node@22.10.2)(msw@2.6.8(@types/node@22.10.2)(typescript@5.6.3)): + dependencies: + '@vitest/expect': 2.1.8 + '@vitest/mocker': 2.1.8(msw@2.6.8(@types/node@22.10.2)(typescript@5.6.3))(vite@5.4.11(@types/node@22.10.2)) + '@vitest/pretty-format': 2.1.8 + '@vitest/runner': 2.1.8 + '@vitest/snapshot': 2.1.8 + '@vitest/spy': 2.1.8 + '@vitest/utils': 2.1.8 + chai: 5.1.2 + debug: 4.3.7 + expect-type: 1.1.0 + magic-string: 0.30.14 + pathe: 1.1.2 + std-env: 3.8.0 + tinybench: 2.9.0 + tinyexec: 0.3.1 + tinypool: 1.0.2 + tinyrainbow: 1.2.0 + vite: 5.4.11(@types/node@22.10.2) + vite-node: 2.1.8(@types/node@22.10.2) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/node': 22.10.2 + transitivePeerDependencies: + - less + - lightningcss + - msw + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + + webpack-virtual-modules@0.6.2: {} + + which-typed-array@1.1.16: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.8 + for-each: 0.3.3 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + which@2.0.2: dependencies: isexe: 2.0.0 + why-is-node-running@2.3.0: + dependencies: + siginfo: 2.0.0 + stackback: 0.0.2 + word-wrap@1.2.5: {} + wrap-ansi@6.2.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + ws@8.18.0: {} + + y18n@5.0.8: {} + yallist@3.1.1: {} + yargs-parser@21.1.1: {} + + yargs@17.7.2: + dependencies: + cliui: 8.0.1 + escalade: 3.2.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + yocto-queue@0.1.0: {} + + yoctocolors-cjs@2.1.2: {} diff --git a/src/App.css b/src/App.css deleted file mode 100644 index b9d355d..0000000 --- a/src/App.css +++ /dev/null @@ -1,42 +0,0 @@ -#root { - max-width: 1280px; - margin: 0 auto; - padding: 2rem; - text-align: center; -} - -.logo { - height: 6em; - padding: 1.5em; - will-change: filter; - transition: filter 300ms; -} -.logo:hover { - filter: drop-shadow(0 0 2em #646cffaa); -} -.logo.react:hover { - filter: drop-shadow(0 0 2em #61dafbaa); -} - -@keyframes logo-spin { - from { - transform: rotate(0deg); - } - to { - transform: rotate(360deg); - } -} - -@media (prefers-reduced-motion: no-preference) { - a:nth-of-type(2) .logo { - animation: logo-spin infinite 20s linear; - } -} - -.card { - padding: 2em; -} - -.read-the-docs { - color: #888; -} diff --git a/src/App.tsx b/src/App.tsx index 3d7ded3..1a9921b 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,35 +1,33 @@ -import { useState } from 'react' -import reactLogo from './assets/react.svg' -import viteLogo from '/vite.svg' -import './App.css' +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; +import { RouterProvider, createBrowserRouter } from 'react-router'; +import router from '@/routes/router'; +import { Provider } from 'react-redux'; // Redux Provider 임포트 +import GlobalStyle from './styles/GlobalStyle'; +import { PersistGate } from 'redux-persist/integration/react'; +import { persistor, store } from './store/store'; -function App() { - const [count, setCount] = useState(0) +const queryClient = new QueryClient({ + defaultOptions: { + queries: { + refetchOnWindowFocus: false, // window 가 다시 포커스 될 때 + refetchOnMount: false, // 쿼리의 새 인스턴스가 마운트 될 때 + refetchOnReconnect: false, // 네트워크가 끊어졌다가 다시 연결될 때 + }, + }, +}); +const App = () => { + const appRouter = createBrowserRouter(router); return ( - <> -
- - Vite logo - - - React logo - -
-

Vite + React

-
- -

- Edit src/App.tsx and save to test HMR -

-
-

- Click on the Vite and React logos to learn more -

- - ) -} + + + + + + + + + ); +}; -export default App +export default App; diff --git a/src/admin/AdminRoute.tsx b/src/admin/AdminRoute.tsx new file mode 100644 index 0000000..47118d5 --- /dev/null +++ b/src/admin/AdminRoute.tsx @@ -0,0 +1,27 @@ +import { Navigate } from 'react-router'; +import { useSelector } from 'react-redux'; +import { RootState } from '@/store/rootReducer'; + +interface ProtectedRouteProps { + allowedRoles: string[]; + children: React.ReactNode; +} + +const ProtectedRoute = ({ allowedRoles, children }: ProtectedRouteProps) => { + const { userInfo } = useSelector((state: RootState) => state.user); + + // 로그인하지 않은 경우 + if (!userInfo) { + return ; + } else if (!allowedRoles.includes(userInfo.role)) { + } + + // 역할이 허용되지 않은 경우 + if (!allowedRoles.includes(userInfo.role)) { + return ; + } + + return <>{children}; // 자식 요소 렌더링 +}; + +export default ProtectedRoute; diff --git a/src/admin/UserCard.tsx b/src/admin/UserCard.tsx new file mode 100644 index 0000000..12c12f7 --- /dev/null +++ b/src/admin/UserCard.tsx @@ -0,0 +1,81 @@ +import styled from 'styled-components'; +import { ChevronDownIcon, ChevronUpIcon } from '@heroicons/react/24/outline'; + +interface UserCardProps { + nickname: string; + email: string; + createdAt: string; + icon: string | null; + isOpen: boolean; +} + +// Styled Components +const CardContainer = styled.div<{ isOpen: boolean }>` + display: flex; + justify-content: space-between; + align-items: center; + padding: 16px; + background-color: white; + border: 1px solid #ddd; + border-radius: ${(props) => (props.isOpen ? '8px 8px 0 0' : '8px')}; + box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); + cursor: pointer; + transition: all 0.3s ease; + + &:hover { + background-color: #f7f7f7; + } +`; + +const UserInfo = styled.div` + display: flex; + align-items: center; +`; + +const Avatar = styled.img` + width: 50px; + height: 50px; + border-radius: 50%; + margin-right: 12px; +`; + +const TextContainer = styled.div` + display: flex; + flex-direction: column; +`; + +const Name = styled.p` + font-weight: bold; +`; + +const IconWrapper = styled.div` + width: 24px; + height: 24px; + + svg { + width: 100%; + height: 100%; + } +`; + +const UserCard = ({ nickname, icon, isOpen }: UserCardProps) => { + return ( + + + + + {nickname} + + + + + {isOpen ? : } + + + ); +}; + +export default UserCard; diff --git a/src/admin/UserList.tsx b/src/admin/UserList.tsx new file mode 100644 index 0000000..63db182 --- /dev/null +++ b/src/admin/UserList.tsx @@ -0,0 +1,118 @@ +import { useEffect, useState } from 'react'; +import { AdminData } from '@/types/admindata'; +import UserCard from './UserCard'; +import styled from 'styled-components'; +import { deleteUser, fetchAdminData } from '@/apis/admin.api'; + +// Styled Components +const UserListContainer = styled.div` + width: 600px; + margin: 0; + padding-left: 10px; + max-height: 500px; + overflow-y: auto; + border: 1px solid #ddd; + border-radius: 8px; +`; + +const ListItem = styled.div` + margin-bottom: 12px; /* 리스트 아이템 간 간격 추가 */ + margin-top: 12px; + margin-right: 12px; +`; + +const DropdownContent = styled.div` + background-color: #f9f9f9; + padding: 16px; + border: 1px solid #ddd; + border-top: none; + border-radius: 0 0 8px 8px; + box-shadow: inset 0 2px 5px rgba(0, 0, 0, 0.1); +`; + +const DeleteButton = styled.button` + background-color: #ff4d4f; + color: white; + padding: 8px 12px; + border: none; + border-radius: 4px; + cursor: pointer; + font-weight: bold; + margin-top: 10px; + transition: background-color 0.3s; + + &:hover { + background-color: #e33e3e; + } +`; + +const UserList = () => { + const [users, setUsers] = useState([]); + const [openUserId, setOpenUserId] = useState(null); + + const toggleDropdown = (id: number) => { + setOpenUserId((prev) => (prev === id ? null : id)); + }; + + const handleDeleteUser = async (id: number) => { + const confirmed = window.confirm(`유저 ID ${id}를 삭제하시겠습니까?`); + if (!confirmed) return; + + try { + const result = await deleteUser(id); + if (result.success) { + alert('회원 탈퇴가 완료되었습니다.'); + setUsers((prevUsers) => prevUsers.filter((user) => user.id !== id)); + } else { + alert('회원 탈퇴에 실패했습니다.'); + } + } catch (error: any) { + alert(`오류 발생: ${error.message}`); + } + }; + + useEffect(() => { + const loadUsers = async () => { + try { + const data = await fetchAdminData(); + setUsers(data); + } catch (error) { + console.error('Failed to load users:', error); + } + }; + + loadUsers(); + }, []); + + return ( + + {users.map((user) => ( + +
toggleDropdown(user.id)}> + +
+ + {openUserId === user.id && ( + +

유저 ID: {user.id}

+

닉네임: {user.nickname}

+

이메일: {user.email}

+

가입 일자: {user.created_at}

+ handleDeleteUser(user.id)}> + 회원탈퇴 + +
+ )} +
+ ))} +
+ ); +}; + +export default UserList; diff --git a/src/apis/admin.api.ts b/src/apis/admin.api.ts new file mode 100644 index 0000000..54127f9 --- /dev/null +++ b/src/apis/admin.api.ts @@ -0,0 +1,26 @@ +import { AdminData } from '@/types/admindata'; +import { httpClient } from './http.api'; + +export const fetchAdminData = async () => { + try { + const response = await httpClient.get('/api/admin'); + console.log('응답 데이터:', response.data); + return response.data; + } catch (error) { + console.error('Error fetching admin data:', error); + throw error; + } +}; + +export const deleteUser = async (id: number): Promise<{ success: boolean }> => { + try { + const response = await httpClient.delete(`/api/users/${id}/delete`); + console.log('응답 데이터:', response.data); + return response.data; + } catch (error: any) { + console.error('API 호출 실패:', error); + throw new Error( + error.response?.data?.message || '회원 탈퇴 중 오류가 발생했습니다.' + ); + } +}; diff --git a/src/apis/api-path.ts b/src/apis/api-path.ts new file mode 100644 index 0000000..008f557 --- /dev/null +++ b/src/apis/api-path.ts @@ -0,0 +1 @@ +export const API_PATH = {}; diff --git a/src/apis/auth.api.ts b/src/apis/auth.api.ts new file mode 100644 index 0000000..3edd653 --- /dev/null +++ b/src/apis/auth.api.ts @@ -0,0 +1,13 @@ +import { JoinProps } from '@/pages/JoinPage'; +import { httpClient } from './http.api'; + +export const join = async (data: JoinProps) => { + const response = await httpClient.post('/api/users/join', data); + return response.data; +}; + +export interface LoginResponse { + message: any; + success: boolean; + token?: string; +} diff --git a/src/apis/board.api.ts b/src/apis/board.api.ts new file mode 100644 index 0000000..c27bc00 --- /dev/null +++ b/src/apis/board.api.ts @@ -0,0 +1,26 @@ +import { httpClient } from './http.api'; + +export const fetchUpdateReview = async ( + title: string, + tags: string[], + content: string +) => { + { + const response = await httpClient.post('/api/posts', { + title, + tags, + content, + }); + return response.data; + } +}; + +export const updateUserIntroduce = async (id: number, intro: string) => { + { + const response = await httpClient.put(`/api/users/${id}/intro`, { + intro, + }); + console.log('인트로 변경 response: ' + response); + return response.data; + } +}; diff --git a/src/apis/http.api.ts b/src/apis/http.api.ts new file mode 100644 index 0000000..e36cc7c --- /dev/null +++ b/src/apis/http.api.ts @@ -0,0 +1,52 @@ +import axios, { AxiosRequestConfig } from 'axios'; + +import { getToken, removeToken } from '@/utils/token'; + +export const BASE_URL = import.meta.env.VITE_API_BASE_URL; +const DEFAULT_TIMEOUT = 30000; + +export const createClient = (config?: AxiosRequestConfig) => { + const token = getToken(); + const axiosInstance = axios.create({ + baseURL: BASE_URL, + timeout: DEFAULT_TIMEOUT, + headers: { + 'Content-Type': 'application/json', + Authorization: token ? `Bearer ${token}` : '', + }, + withCredentials: true, + ...config, + }); + + axiosInstance.interceptors.request.use( + (config) => { + const token = getToken(); + if (token) { + config.headers.Authorization = `Bearer ${token}`; + } + return config; + }, + (error) => { + return Promise.reject(error); + } + ); + + axiosInstance.interceptors.response.use( + (response) => { + return response; + }, + (error) => { + // 로그인 만료 처리 + if (error.response.status === 401) { + removeToken(); + window.location.href = '/login'; + return; + } + return Promise.reject(error); + } + ); + + return axiosInstance; +}; + +export const httpClient = createClient(); diff --git a/src/apis/maindata.api.ts b/src/apis/maindata.api.ts new file mode 100644 index 0000000..63b8e83 --- /dev/null +++ b/src/apis/maindata.api.ts @@ -0,0 +1,11 @@ +import { httpClient } from './http.api'; +import { mainData } from '@/types/main.model'; + +export const fetchMainData = async () => { + const response = await httpClient.get('/api/main'); + try { + return response.data; + } catch { + throw Error; + } +}; diff --git a/src/apis/user-info.api.ts b/src/apis/user-info.api.ts new file mode 100644 index 0000000..42aa144 --- /dev/null +++ b/src/apis/user-info.api.ts @@ -0,0 +1,52 @@ +import { httpClient } from './http.api'; + +export interface Profile { + id: number; + email: string; + nickname: string; + introduce: string; + icon: string | null; +} + +export interface Post { + id: number; + title: string; + content: string; + created_at: string; + updated_at: string | null; + view: number; + solved: number; + nickname: string; + comment_count: number; + like_count: number; + tags: string; +} + +export interface UserData { + profile: Profile; + posts: Post[]; +} + +export const fetchUserInfo = async (nickname: string) => { + try { + const url = `/api/users/${nickname}`; + const response = await httpClient.get(url); + console.log(response); + return response.data; + } catch (error) { + console.error('Error fetching admin data:', error); + throw error; + } +}; + +export const fetchUserLikes = async (nickname: string) => { + try { + const url = `/api/users/${nickname}/likes`; + const response = await httpClient.get<{ posts: Post[] }>(url); + console.log(response.data.posts); + return response.data.posts; + } catch (error) { + console.error('Error fetching user likes:', error); + throw error; + } +}; diff --git a/src/assets/DefaultAvatar.svg b/src/assets/DefaultAvatar.svg new file mode 100644 index 0000000..e5daaa3 --- /dev/null +++ b/src/assets/DefaultAvatar.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/assets/logo.svg b/src/assets/logo.svg new file mode 100644 index 0000000..3ae79fb --- /dev/null +++ b/src/assets/logo.svg @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/qublogo.svg b/src/assets/qublogo.svg new file mode 100644 index 0000000..3ae79fb --- /dev/null +++ b/src/assets/qublogo.svg @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/components/Header.tsx b/src/components/Header.tsx new file mode 100644 index 0000000..5264699 --- /dev/null +++ b/src/components/Header.tsx @@ -0,0 +1,43 @@ +import styled from 'styled-components'; +import logo from '@/assets/logo.svg'; +import MenuButton from './MenuButton'; +import { useNavigate } from 'react-router'; + +const Header = () => { + const navigate = useNavigate(); + + const handleLogoClick = () => { + navigate('/'); + }; + + return ( + + + + + + + ); +}; + +export default Header; + +const HeaderContainer = styled.div` + width: 100%; + height: 170px; + display: flex; + align-items: center; + justify-content: center; +`; + +const HeaderWrapper = styled.div` + width: 980px; + height: 100%; + display: flex; + align-items: center; + justify-content: space-between; +`; + +const Logo = styled.img` + cursor: pointer; +`; diff --git a/src/components/MenuButton.tsx b/src/components/MenuButton.tsx new file mode 100644 index 0000000..807a178 --- /dev/null +++ b/src/components/MenuButton.tsx @@ -0,0 +1,163 @@ +import { useState } from 'react'; +import styled from 'styled-components'; +import { XMarkIcon, Bars3Icon } from '@heroicons/react/24/outline'; +import Avatar from './ui/atoms/Avator'; +import defaultAvatar from '@/assets/DefaultAvatar.svg'; +import { useNavigate } from 'react-router'; +import { logout } from '@/hooks/userSlice'; +import { useSelector, useDispatch } from 'react-redux'; +import { RootState } from '@/store/rootReducer'; +import { removeToken } from '@/utils/token'; + +const MenuButton = () => { + const [isOpen, setIsOpen] = useState(false); + const navigate = useNavigate(); + const dispatch = useDispatch(); + const isLoggedIn = useSelector((state: RootState) => state.user.isLoggedIn); + const role = useSelector((state: RootState) => state.user.userInfo?.role); + + const handleMyPage = () => { + setIsOpen(false); + navigate('/mypage'); + }; + + const handleAdminPage = () => { + setIsOpen(false); + navigate('/adminpage'); + }; + + const handleLogin = () => { + setIsOpen(false); + navigate('/login'); + }; + + const handleLogout = () => { + dispatch(logout()); + removeToken(); + setIsOpen(false); + navigate('/'); + }; + + const toggleMenu = () => { + setIsOpen((prev) => !prev); + }; + + const nickname = useSelector( + (state: RootState) => state.user.userInfo?.nickname + ); + + return ( + + + + {isOpen && ( + +
    +
  • { + setIsOpen(false); + if (isLoggedIn) { + role === 'admin' + ? navigate('/adminpage') + : navigate('/mypage'); + } else { + handleLogin(); + } + }} + > + + + {isLoggedIn ? nickname : '로그인'} + +
  • + {isLoggedIn ? ( + <> + {role === 'admin' ? ( +
  • 관리자페이지
  • + ) : ( +
  • 마이페이지
  • + )} +
  • 문의하기
  • +
  • 서비스 소개
  • +
  • 로그아웃
  • + + ) : ( + <> +
  • 문의하기
  • +
  • 서비스 소개
  • + + )} +
+
+ )} +
+ ); +}; + +export default MenuButton; + +const DropdownContainer = styled.div` + position: relative; +`; + +const Button = styled.button` + background: none; + border: none; + cursor: pointer; + + .icon { + width: 30px; + height: 30px; + color: #333; + } +`; + +const DropdownMenu = styled.div` + position: absolute; + top: 100%; + right: 0; + width: 250px; + background-color: white; + box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.1); + border: 1px solid #ddd; + z-index: 100; + + ul { + list-style: none; + padding: 10px 0; + margin: 0; + + li { + padding: 10px 15px; + cursor: pointer; + font-weight: bold; + display: flex; + align-items: center; + + &:hover { + background-color: #f3f3f3; + } + } + } +`; + +const AvatarContainer = styled.div` + display: flex; + align-items: center; + gap: 10px; +`; diff --git a/src/components/layout/Layout.tsx b/src/components/layout/Layout.tsx new file mode 100644 index 0000000..f5005af --- /dev/null +++ b/src/components/layout/Layout.tsx @@ -0,0 +1,22 @@ +import { Outlet } from 'react-router'; +import styled from 'styled-components'; +import Header from '../Header'; + +const Layout = () => { + return ( + +
+ + + ); +}; + +export default Layout; + +const LayoutContainer = styled.div` + width: 1000px; + margin: 0 auto; + min-height: 100vh; + display: flex; + flex-direction: column; +`; diff --git a/src/components/main-page/MainTagList.tsx b/src/components/main-page/MainTagList.tsx new file mode 100644 index 0000000..f4dabe0 --- /dev/null +++ b/src/components/main-page/MainTagList.tsx @@ -0,0 +1,60 @@ +import { useMainTags } from '@/hooks/useMainTags'; +import { useSearchParams } from 'react-router'; +import styled from 'styled-components'; + +const MainTagList = () => { + const { maintags } = useMainTags(); + const [searchParams, setSearchParams] = useSearchParams(); + + const handleTags = (id: number | null) => { + const newSearchParams = new URLSearchParams(searchParams); + if (id === null) { + newSearchParams.delete('id'); + } else { + newSearchParams.set('id', id.toString()); + } + setSearchParams(newSearchParams); + }; + + return ( + + {maintags.map((tag) => ( + handleTags(tag.id)} + > + {tag.name} + + ))} + + ); +}; + +const MainTagListContainer = styled.div` + display: flex; + justify-content: space-evenly; + align-items: center; +`; + +const TagButton = styled.button` + border-radius: 30px; + font-size: 1.1rem; + background-color: transparent; + color: #32c040; + border: 1px solid #32c040; + padding: 8px 20px; + text-decoration: none; + cursor: pointer; + transition: all 0.12s ease-in-out; + + &:hover { + background-color: rgba(49, 191, 63, 0.23); + } + + &.active { + background-color: rgba(49, 191, 63, 0.23); + } +`; + +export default MainTagList; diff --git a/src/components/main-page/QuestionBox.tsx b/src/components/main-page/QuestionBox.tsx new file mode 100644 index 0000000..664caf0 --- /dev/null +++ b/src/components/main-page/QuestionBox.tsx @@ -0,0 +1,64 @@ +import { useEffect, useState } from 'react'; +import styled from 'styled-components'; +import QuestionBody from '../ui/molecules/mainpage-molecule/QuestionBody'; +import QuestionHeader from '../ui/molecules/mainpage-molecule/QuestionHeader'; +import QuestionTag from '../ui/atoms/mainpage-atom/QuesitonTag'; +import QuestionBottom from '../ui/molecules/mainpage-molecule/QuestionBottom'; +import { fetchMainData } from '@/apis/maindata.api'; +import { mainPosts } from '@/types/main.model'; + +const QuestionBoxContainer = styled.div` + display: flex; + flex-direction: column; + margin-top: 30px; + gap: 30px; +`; + +const QuestionItem = styled.div` + margin: 10px; +`; + +function QuestionBox() { + const [posts, setPosts] = useState([]); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(null); + + useEffect(() => { + const loadPosts = async () => { + try { + const data = await fetchMainData(); + setPosts(data.posts); + } catch (err) { + setError('데이터를 불러오는 중 오류가 발생했습니다.'); + } finally { + setLoading(false); + } + }; + + loadPosts(); + }, []); + + if (loading) return
데이터를 불러오는 중...
; + if (error) return
{error}
; + + return ( + + {posts.map((post) => ( + + + + {post.tags && } + + + ))} + + ); +} + +export default QuestionBox; diff --git a/src/components/main-page/SearchInput.tsx b/src/components/main-page/SearchInput.tsx new file mode 100644 index 0000000..8072832 --- /dev/null +++ b/src/components/main-page/SearchInput.tsx @@ -0,0 +1,50 @@ +import { useState } from 'react'; +import styled from 'styled-components'; +import { MagnifyingGlassIcon as SearchIcon} from '@heroicons/react/24/outline'; +const SearchInput = () => { + const [searchText, setSearchText] = useState(''); + const handleSearchChange = (e:React.ChangeEvent) => { + const inputText = e.target.value; + setSearchText(inputText); + } + return ( + + + + + ); +} + +const SearchInputStyle = styled.div` + margin: 0 auto; + display: flex; + justify-content: space-between; + margin-bottom: 20px; + padding: 8px 20px; + border: 1px solid #727272; + border-radius: 30px; + width: 70%; + + input { + width: 95%; + font-size: 1.2rem; + font-weight: 500; + border: 0; + padding: 5px; + } + + button { + background-color: transparent; + border: 0; + margin-left: 10px; + cursor: pointer; + svg { + width: 24px; + height: 24px; + } + } + + +`; + +export default SearchInput; \ No newline at end of file diff --git a/src/components/my-page/Scraps.tsx b/src/components/my-page/Scraps.tsx new file mode 100644 index 0000000..97bd8ea --- /dev/null +++ b/src/components/my-page/Scraps.tsx @@ -0,0 +1,88 @@ +import { Post, fetchUserLikes } from '@/apis/user-info.api'; +import { RootState } from '@/store/rootReducer'; +import { useEffect, useState } from 'react'; +import { useSelector } from 'react-redux'; +import styled from 'styled-components'; +import QuestionHeader from '../ui/molecules/mainpage-molecule/QuestionHeader'; +import QuestionBody from '../ui/molecules/mainpage-molecule/QuestionBody'; +import QuestionTag from '../ui/atoms/mainpage-atom/QuesitonTag'; +import QuestionBottom from '../ui/molecules/mainpage-molecule/QuestionBottom'; + +const Scraps = () => { + const nickname = useSelector( + (state: RootState) => state.user.userInfo?.nickname + ); + + const [userData, setUserData] = useState([]); + const [loading, setLoading] = useState(true); + + useEffect(() => { + if (nickname) { + setLoading(true); + fetchUserLikes(nickname) + .then((posts) => { + setUserData(posts); + setLoading(false); + }) + .catch((error) => { + console.error('에러 발생:', error); + setLoading(false); + }); + } + }, [nickname]); + + if (loading) { + return
Loading...
; + } + + if (!userData.length) { + return
좋아요한 게시글이 없습니다.
; + } + + return ( + + 좋아요한 게시글 + + {userData.map((post) => ( + + + + {post.tags && } + + + ))} + + + ); +}; + +export default Scraps; + +const ScrapContainer = styled.div` + width: 100%; + display: flex; + flex-direction: column; +`; + +const ScrapTitle = styled.div` + width: 100%; + height: 40px; + padding: 5px 0px 10px 10px; + font-size: 30px; +`; + +const QuestionBoxContainer = styled.div` + display: flex; + flex-direction: column; + gap: 30px; +`; + +const QuestionItem = styled.div` + margin: 10px; +`; diff --git a/src/components/my-page/UserContents.tsx b/src/components/my-page/UserContents.tsx new file mode 100644 index 0000000..58ed2a3 --- /dev/null +++ b/src/components/my-page/UserContents.tsx @@ -0,0 +1,90 @@ +import { UserData, fetchUserInfo } from '@/apis/user-info.api'; +import { RootState } from '@/store/rootReducer'; +import { useEffect, useState } from 'react'; +import { useSelector } from 'react-redux'; +import styled from 'styled-components'; +import DOMPurify from 'dompurify'; +import Button from '../ui/atoms/Button'; +import { useNavigate } from 'react-router'; + +const UserContents = () => { + const navigate = useNavigate(); + const nickname = useSelector( + (state: RootState) => state.user.userInfo?.nickname + ); + + const [userData, setUserData] = useState(null); + const [loading, setLoading] = useState(true); + + useEffect(() => { + if (nickname) { + setLoading(true); + fetchUserInfo(nickname) + .then((data) => { + setUserData(data); + setLoading(false); + }) + .catch((error) => { + console.error('에러 발생:', error); + setLoading(false); + }); + } + }, [nickname]); + + if (loading) { + return
Loading...
; + } + + const sanitizedIntroduce = userData?.profile.introduce + ? DOMPurify.sanitize(userData.profile.introduce) + : ''; + + return ( + + + 소개 + + + + + ); +}; + +export default UserContents; + +const ContentSection = styled.div` + width: 100%; + min-height: 100vh; + display: flex; + flex-direction: column; +`; + +const ContentTitle = styled.div` + width: 100%; + height: 40px; + padding: 5px 0px 5px 0px; + font-size: 30px; +`; + +const ContentWrapper = styled.div` + width: 100%; + padding: 10px; + border: 1px solid black; + border-radius: 5px; + background-color: white; +`; + +const ContentHeaderSection = styled.div` + display: flex; + justify-content: space-between; + width: 100%; + height: 40px; +`; diff --git a/src/components/my-page/UserPosts.tsx b/src/components/my-page/UserPosts.tsx new file mode 100644 index 0000000..3223e4e --- /dev/null +++ b/src/components/my-page/UserPosts.tsx @@ -0,0 +1,85 @@ +import { UserData, fetchUserInfo } from '@/apis/user-info.api'; +import { RootState } from '@/store/rootReducer'; +import { useEffect, useState } from 'react'; +import { useSelector } from 'react-redux'; +import styled from 'styled-components'; +import QuestionHeader from '../ui/molecules/mainpage-molecule/QuestionHeader'; +import QuestionBody from '../ui/molecules/mainpage-molecule/QuestionBody'; +import QuestionTag from '../ui/atoms/mainpage-atom/QuesitonTag'; +import QuestionBottom from '../ui/molecules/mainpage-molecule/QuestionBottom'; + +const UserPosts = () => { + const nickname = useSelector( + (state: RootState) => state.user.userInfo?.nickname + ); + + const [userData, setUserData] = useState(null); + const [loading, setLoading] = useState(true); + + useEffect(() => { + if (nickname) { + setLoading(true); + fetchUserInfo(nickname) + .then((data) => { + setUserData(data); + setLoading(false); + }) + .catch((error) => { + console.error('에러 발생:', error); + setLoading(false); + }); + } + }, [nickname]); + + if (loading) { + return
Loading...
; + } + + return ( + + 작성한 게시글 + + {userData && + userData.posts.map((post) => ( + + + + {post.tags && } + + + ))} + + + ); +}; + +export default UserPosts; + +const ScrapContainer = styled.div` + width: 100%; + display: flex; + flex-direction: column; +`; + +const ScrapTitle = styled.div` + width: 100%; + height: 40px; + padding: 5px 0px 10px 10px; + font-size: 30px; +`; + +const QuestionBoxContainer = styled.div` + display: flex; + flex-direction: column; + gap: 30px; +`; + +const QuestionItem = styled.div` + margin: 10px; +`; diff --git a/src/components/ui/atoms/Avator.stories.tsx b/src/components/ui/atoms/Avator.stories.tsx new file mode 100644 index 0000000..b928162 --- /dev/null +++ b/src/components/ui/atoms/Avator.stories.tsx @@ -0,0 +1,28 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import Avatar from './Avator'; + +const meta: Meta = { + title: 'Components/Atoms/Avatar', + component: Avatar, +}; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + size: 'big', + src: 'https://jmagazine.joins.com/_data2/photo/2021/04/838745483_Kw79V5Pa_3.jpg', + alt: 'Default Avatar', + }, + render: (args) => , +}; + +export const Outlined: Story = { + args: { + size: 'small', + src: 'https://jmagazine.joins.com/_data2/photo/2021/04/838745483_D5lXOQuU_5.jpg', + alt: 'Outlined Avatar', + }, + render: (args) => , +}; diff --git a/src/components/ui/atoms/Avator.tsx b/src/components/ui/atoms/Avator.tsx new file mode 100644 index 0000000..2f493a4 --- /dev/null +++ b/src/components/ui/atoms/Avator.tsx @@ -0,0 +1,47 @@ +import styled from 'styled-components'; + +interface AvatarProps { + size?: 'big' | 'small'; + disabled?: boolean; + src: string; + alt?: string; +} + +const cx = (...classes: (string | boolean | undefined)[]) => + classes.filter(Boolean).join(' '); + +const styles = { + base: ` + display: inline-block; + border-radius: 50%; + overflow: hidden; + object-fit: cover; + `, + big: ` + width: 200px; + height: 200px; + `, + small: ` + width: 48px; + height: 48px; + `, + disabled: ` + opacity: 0.5; + pointer-events: none; + `, +}; + +const Avatar = styled.img.attrs(({ src, alt }) => ({ + src, + alt: alt || 'Avatar', +}))` + ${({ size, disabled }) => + cx( + styles.base, + size === 'big' && styles.big, + size === 'small' && styles.small, + disabled && styles.disabled + )} +`; + +export default Avatar; diff --git a/src/components/ui/atoms/Button.ts b/src/components/ui/atoms/Button.ts new file mode 100644 index 0000000..702dbac --- /dev/null +++ b/src/components/ui/atoms/Button.ts @@ -0,0 +1,62 @@ +import styled from 'styled-components'; + +interface ButtonProps { + variant?: 'primary' | 'outline' | 'tag'; + disabled?: boolean; + customStyle?: string; +} + +const cx = (...classes: (string | boolean | undefined)[]) => + classes.filter(Boolean).join(' '); + +const styles = { + base: ` + font-size: 1em; + padding: 0.5em 1em; + border-radius: 5px; + cursor: pointer; + `, + primary: ` + background-color: mediumseagreen; + color: white; + border: black; + height: 30px; + padding: 5px; + `, + tag: ` + background-color: white; + border: 1px solid mediumseagreen; + height: 30px; + padding: 5px; + color: mediumseagreen; + `, + outline: ` + background-color: white; + color: mediumseagreen; + border: 2px solid mediumseagreen; + + &:hover { + background-color: mediumseagreen; + color: white; + } + `, + disabled: ` + background-color: #ccc; + color: #666; + cursor: not-allowed; + `, +}; + +const Button = styled.button` + ${({ variant, disabled, customStyle }) => + cx( + styles.base, + variant === 'primary' && styles.primary, + variant === 'outline' && styles.outline, + variant === 'tag' && styles.tag, + disabled && styles.disabled, + customStyle + )} +`; + +export default Button; diff --git a/src/components/ui/atoms/Input.tsx b/src/components/ui/atoms/Input.tsx new file mode 100644 index 0000000..bc6de15 --- /dev/null +++ b/src/components/ui/atoms/Input.tsx @@ -0,0 +1,89 @@ +import React, { ForwardedRef, useState } from 'react'; +import styled from 'styled-components'; + +interface InputFieldProps extends React.InputHTMLAttributes { + label: string; + inputType?: 'text' | 'email' | 'password' | 'number' | 'nickname'; +} + +const Container = styled.div` + position: relative; + width: 100%; + align-items: center; + margin-top: 1.5rem; + justify-content: center; +`; + +interface LabelProps { + isActive: boolean; +} + +const StyledLabel = styled.label` + position: absolute; + left: 2rem; + top: 50%; + transform: translateY(-50%); + color: #727272; + font-family: sans-serif; + transition: all 0.2s ease-in-out; + + ${({ isActive }) => + isActive && + ` + top: 25%; + font-size: 0.75rem; /* text-xs */ + color: #6b7280; /* text-gray-500 */ + `} +`; + +const StyledInput = styled.input` + align-items: center; + width: 100%; + height: 70px; + padding: 0.1rem 1rem; + background-color: #ffffff; + border-radius: 0.375rem; + border: 0.5px solid #000000; + color: #727272; + font-size: 1.25rem; + + &:focus { + outline: none; + } + + ::placeholder { + color: transparent; + } +`; + +const Input = React.forwardRef( + ( + { label, inputType = 'text', onChange, ...props }: InputFieldProps, + ref: ForwardedRef + ) => { + const [isFocused, setIsFocused] = useState(false); + const [hasValue, setHasValue] = useState(false); + + const handleInputFocus = () => setIsFocused(true); + const handleInputBlur = (e: React.ChangeEvent) => { + setIsFocused(false); + setHasValue(e.target.value !== ''); + }; + + return ( + + {label} + + + ); + } +); + +export default Input; diff --git a/src/components/ui/atoms/join-atom/PasswordGuideLines.tsx b/src/components/ui/atoms/join-atom/PasswordGuideLines.tsx new file mode 100644 index 0000000..f5f03be --- /dev/null +++ b/src/components/ui/atoms/join-atom/PasswordGuideLines.tsx @@ -0,0 +1,87 @@ +import { useEffect, useState } from 'react'; +import { CheckCircleIcon } from '@heroicons/react/20/solid'; +import styled from 'styled-components'; + +interface Guideline { + label: string; + isValid: boolean; + check: (password: string) => boolean; +} + +const Container = styled.div` + display: flex; + flex-direction: column; + > * + * { + margin-top: 0.5rem; + } +`; + +const GuidelineItem = styled.div` + display: flex; + align-items: center; +`; + +const StyledCheckCircleIcon = styled(CheckCircleIcon)` + width: 1.25rem; + height: 1.25rem; + color: #32c040; +`; + +const EmptyCircle = styled.span` + margin-left: 0.15rem; + width: 0.85rem; + height: 0.85rem; + border: 1px solid #374151; + border-radius: 9999px; + display: inline-block; +`; + +const GuidelineLabel = styled.span<{ isValid: boolean }>` + margin-left: 0.5rem; + font-size: 0.875rem; + color: ${(props) => (props.isValid ? '#32C040' : '#6b7280')}; +`; + +const PasswordGuideLines = ({ password }: { password: string }) => { + const [guidelines, setGuidelines] = useState([ + { + label: '8자 이상, 15자 이하로 설정해 주세요', + isValid: false, + check: (password: string) => + password.length >= 8 && password.length <= 15, + }, + { + label: '특수 문자를 사용해 주세요', + isValid: false, + check: (password: string) => /[!@#$%^&*(),.?":{}|<>]/.test(password), + }, + { + label: '동일한 문자가 4번 반복되면 안돼요', + isValid: false, + check: (password: string) => + !/(.)\1{3}/.test(password.replace(/\s/g, '')), + }, + ]); + + useEffect(() => { + setGuidelines((prevGuidelines) => + prevGuidelines.map((guideline) => ({ + ...guideline, + isValid: guideline.check(password), + })) + ); + }, [password]); + + return ( + + {guidelines.map(({ label, isValid }, index) => ( + + {isValid ? : } + {label} + + ))} + + ); +}; + +export default PasswordGuideLines; diff --git a/src/components/ui/atoms/mainpage-atom/QuesitonTag.tsx b/src/components/ui/atoms/mainpage-atom/QuesitonTag.tsx new file mode 100644 index 0000000..dcd267e --- /dev/null +++ b/src/components/ui/atoms/mainpage-atom/QuesitonTag.tsx @@ -0,0 +1,34 @@ +import styled from 'styled-components'; + +// Styled Components +const TagsContainer = styled.div` + display: flex; + flex-wrap: wrap; + gap: 8px; + margin-top: 12px; +`; + +const TagItem = styled.div` + background-color: #deffe2; + color: #858585; + font-family: 'Pretendard-Light', Helvetica; + font-size: 12px; + padding: 8px 16px; + border-radius: 12px; +`; + +interface TagsProps { + tags: string[]; +} + +function QuestionTag({ tags }: TagsProps) { + return ( + + {tags.map((tag, index) => ( + {tag} + ))} + + ); +} + +export default QuestionTag; diff --git a/src/components/ui/atoms/mainpage-atom/QuestionButton.tsx b/src/components/ui/atoms/mainpage-atom/QuestionButton.tsx new file mode 100644 index 0000000..b584ecd --- /dev/null +++ b/src/components/ui/atoms/mainpage-atom/QuestionButton.tsx @@ -0,0 +1,97 @@ +import styled from 'styled-components'; + +const ProblemBox = styled.div` + height: 20px; + width: 77px; + + .group { + height: 20px; + left: 0; + position: relative; /* fixed → relative로 수정 */ + top: 0; + } + + .overlap-group { + background-color: #d9d9d9; + border-radius: 30px; + height: 30px; + position: relative; + width: 100px; + } + + .text-wrapper { + color: #ffffff; + font-family: 'Pretendard-ExtraBold', Helvetica; + font-size: 15px; + left: 20px; + line-height: 20px; + position: absolute; + text-align: center; + top: 3px; + white-space: nowrap; + width: 50px; + } +`; + +const SolveBox = styled.div` + height: 20px; + width: 77px; + + .group { + height: 20px; + left: 0; + position: relative; /* fixed → relative로 수정 */ + top: 0; + } + + .overlap-group { + background-color: #c9ffce; + border-radius: 30px; + height: 30px; + position: relative; + width: 100px; + } + + .text-wrapper { + color: #007c0c; + font-family: 'Pretendard-ExtraBold', Helvetica; + font-size: 15px; + left: 25px; + line-height: 20px; + position: absolute; + text-align: center; + top: 4px; + white-space: nowrap; + width: 50px; + } +`; + +export const ProblemButton = () => { + return ( + +
+
+
problem
+
+
+
+ ); +}; + +export const SolveButton = () => { + return ( + +
+
+
solve
+
+
+
+ ); +}; + +const QuestionButton = ({ solved }: { solved: number }) => { + return solved === 1 ? : ; +}; + +export default QuestionButton; diff --git a/src/components/ui/atoms/mainpage-atom/QuestionTitle.tsx b/src/components/ui/atoms/mainpage-atom/QuestionTitle.tsx new file mode 100644 index 0000000..0075131 --- /dev/null +++ b/src/components/ui/atoms/mainpage-atom/QuestionTitle.tsx @@ -0,0 +1,19 @@ +import styled from 'styled-components'; + +const TitleContainer = styled.div` + font-family: 'Pretendard-SemiBold', Helvetica; + font-size: 18px; + color: #000; + margin-top: 5px; + margin-left: 30px; +`; + +interface TitleProps { + text: string; +} + +function QuestionTitle({ text }: TitleProps) { + return {text}; +} + +export default QuestionTitle; diff --git a/src/components/ui/atoms/mainpage-atom/QuestionUser.tsx b/src/components/ui/atoms/mainpage-atom/QuestionUser.tsx new file mode 100644 index 0000000..58cd5f0 --- /dev/null +++ b/src/components/ui/atoms/mainpage-atom/QuestionUser.tsx @@ -0,0 +1,26 @@ +import styled from 'styled-components'; + +const UserContainer = styled.div` + font-family: 'Pretendard-ExtraLight', Helvetica; + font-size: 12px; + color: #666; + display: flex; + gap: 8px; + margin-left: 5px; +`; + +interface QuestionUserProps { + nickname: string; + time: string; +} + +function QuestionUser({ nickname, time }: QuestionUserProps) { + return ( + + {nickname} + {time} + + ); +} + +export default QuestionUser; diff --git a/src/components/ui/atoms/mainpage-atom/QuestionUtil.tsx b/src/components/ui/atoms/mainpage-atom/QuestionUtil.tsx new file mode 100644 index 0000000..f514bc9 --- /dev/null +++ b/src/components/ui/atoms/mainpage-atom/QuestionUtil.tsx @@ -0,0 +1,56 @@ +import styled from 'styled-components'; +import { + ChatBubbleOvalLeftEllipsisIcon, + EyeIcon, +} from '@heroicons/react/24/outline'; +import { HeartIcon as SolidHeartIcon } from '@heroicons/react/24/solid'; + +// Styled Components +const UtilContainer = styled.div` + display: flex; + gap: 12px; + font-family: 'Pretendard-ExtraLight', Helvetica; + font-size: 13px; + color: #666; + margin-right: 5px; +`; + +const IconWrapper = styled.span` + display: flex; + align-items: center; + gap: 4px; + cursor: pointer; + user-select: none; + + svg { + width: 16px; + height: 16px; + } +`; + +interface QuestionUtilProps { + likes: number; + comments: number; + views: number; +} + +function QuestionUtil({ likes, comments, views }: QuestionUtilProps) { + return ( + + + + {likes} + + + + {comments} + + + + {views} + + + ); +} + +export default QuestionUtil; diff --git a/src/components/ui/molecules/QuillEditor.tsx b/src/components/ui/molecules/QuillEditor.tsx new file mode 100644 index 0000000..1ed47b6 --- /dev/null +++ b/src/components/ui/molecules/QuillEditor.tsx @@ -0,0 +1,45 @@ +import React, { useRef } from 'react'; +import ReactQuill, { Quill } from 'react-quill'; +import 'react-quill/dist/quill.snow.css'; + +interface RichTextEditorProps { + value: string; + onChange: (value: string) => void; +} + +const RichTextEditor: React.FC = ({ value, onChange }) => { + const quillRef = useRef(null); // React ref 사용 + + const modules = { + toolbar: [ + [{ header: [1, 2, false] }], + ['bold', 'italic', 'underline', 'strike'], + [{ list: 'ordered' }, { list: 'bullet' }], + ['code-block'], + ], + }; + + const formats = [ + 'header', + 'bold', + 'italic', + 'underline', + 'strike', + 'list', + 'bullet', + 'code-block', + ]; + + return ( + + ); +}; + +export default RichTextEditor; diff --git a/src/components/ui/molecules/mainpage-molecule/QuestionBody.tsx b/src/components/ui/molecules/mainpage-molecule/QuestionBody.tsx new file mode 100644 index 0000000..12f73ba --- /dev/null +++ b/src/components/ui/molecules/mainpage-molecule/QuestionBody.tsx @@ -0,0 +1,21 @@ +import styled from 'styled-components'; + +const BodyContainer = styled.div` + font-family: 'Pretendard-Light', Helvetica; + font-size: 15px; + margin-left: 5px; + line-height: 1.5; + color: #333; + margin-top: 20px; + margin-right: 5px; +`; + +interface QuestionBodyProps { + content: string; +} + +function QuestionBody({ content }: QuestionBodyProps) { + return {content}; +} + +export default QuestionBody; diff --git a/src/components/ui/molecules/mainpage-molecule/QuestionBottom.tsx b/src/components/ui/molecules/mainpage-molecule/QuestionBottom.tsx new file mode 100644 index 0000000..810b3e8 --- /dev/null +++ b/src/components/ui/molecules/mainpage-molecule/QuestionBottom.tsx @@ -0,0 +1,35 @@ +import styled from 'styled-components'; +import QuestionUser from '../../atoms/mainpage-atom/QuestionUser'; +import QuestionUtil from '../../atoms/mainpage-atom/QuestionUtil'; + +const BottomContainer = styled.div` + display: flex; + justify-content: space-between; + align-items: center; + margin-top: 12px; +`; + +interface QuestionBottomProps { + nickname: string; + time: string; + likes: number; + comments: number; + views: number; +} + +function QuestionBottom({ + nickname, + time, + likes, + comments, + views, +}: QuestionBottomProps) { + return ( + + + + + ); +} + +export default QuestionBottom; diff --git a/src/components/ui/molecules/mainpage-molecule/QuestionHeader.tsx b/src/components/ui/molecules/mainpage-molecule/QuestionHeader.tsx new file mode 100644 index 0000000..28a4110 --- /dev/null +++ b/src/components/ui/molecules/mainpage-molecule/QuestionHeader.tsx @@ -0,0 +1,25 @@ +import styled from 'styled-components'; +import QuestionButton from '../../atoms/mainpage-atom/QuestionButton'; +import QuestionTitle from '../../atoms/mainpage-atom/QuestionTitle'; + +const HeaderContainer = styled.div` + display: flex; + align-items: center; + gap: 8px; +`; + +interface QuestionHeaderProps { + solved: number; + title: string; +} + +function QuestionHeader({ solved, title }: QuestionHeaderProps) { + return ( + + + + + ); +} + +export default QuestionHeader; diff --git a/src/constants/TagItems.ts b/src/constants/TagItems.ts new file mode 100644 index 0000000..dd2fb9c --- /dev/null +++ b/src/constants/TagItems.ts @@ -0,0 +1,10 @@ +export const TagItems = [ + 'Javascript', + 'NodeJs', + 'HTML', + 'CSS', + 'React', + 'C', + 'JAVA', + 'Python', +]; diff --git a/src/custom.d.ts b/src/custom.d.ts new file mode 100644 index 0000000..7458a9b --- /dev/null +++ b/src/custom.d.ts @@ -0,0 +1,7 @@ +declare module '*.svg' { + import React = require('react'); + + export const ReactComponent: React.FC>; + const src: string; + export default src; +} diff --git a/src/hooks/useMainTags.ts b/src/hooks/useMainTags.ts new file mode 100644 index 0000000..795a41b --- /dev/null +++ b/src/hooks/useMainTags.ts @@ -0,0 +1,48 @@ +import { fetchMainData } from '@/apis/maindata.api'; +import { mainTags } from '@/types/main.model'; +import { useEffect, useState } from 'react'; +import { useLocation } from 'react-router'; + +export const useMainTags = () => { + const location = useLocation(); + const [maintags, setMaintags] = useState([]); + + const setActive = () => { + const params = new URLSearchParams(location.search); + if (params.get('id')) { + setMaintags((prev) => { + return prev.map((item) => { + return { ...item, isActive: item.id === Number(params.get('id')) }; + }); + }); + } else { + setMaintags((prev) => { + return prev.map((item) => { + return { ...item, isActive: false }; + }); + }); + } + }; + + useEffect(() => { + fetchMainData().then((data) => { + if (!data.tags) return; + const tagsAll = [ + { + id: null, + name: '전체', + }, + ...data.tags, + ]; + + setMaintags(tagsAll); + setActive(); + }); + }, []); + + useEffect(() => { + setActive(); + }, [location.search]); + + return { maintags }; +}; diff --git a/src/hooks/useRichTextViewer.tsx b/src/hooks/useRichTextViewer.tsx new file mode 100644 index 0000000..475881c --- /dev/null +++ b/src/hooks/useRichTextViewer.tsx @@ -0,0 +1,13 @@ +import DOMPurify from 'dompurify'; + +const RichTextViewer = ({ content }: { content: string }) => { + const sanitizedContent = DOMPurify.sanitize(content); + return ( +
+ ); +}; + +export default RichTextViewer; diff --git a/src/hooks/userSlice.ts b/src/hooks/userSlice.ts new file mode 100644 index 0000000..882cabb --- /dev/null +++ b/src/hooks/userSlice.ts @@ -0,0 +1,85 @@ +import { DecodedToken, UserInfo, UserState } from '@/types/auth'; +import { createSlice, createAsyncThunk, PayloadAction } from '@reduxjs/toolkit'; +import axios from 'axios'; +import { jwtDecode } from 'jwt-decode'; +import { BASE_URL } from '@/apis/http.api'; + +const initialState: UserState = { + isLoggedIn: false, + token: null, + userInfo: null, + loading: false, + error: null, +}; + +export const loginAsync = createAsyncThunk( + 'user/loginAsync', + async ( + { email, password }: { email: string; password: string }, + { rejectWithValue } + ) => { + try { + const response = await axios.post(`${BASE_URL}/api/users/login`, { + email, + password, + }); + + if (response.data.success && response.data.token) { + return response.data.token; + } else { + return rejectWithValue('로그인 실패: 토큰 없음'); + } + } catch (error: any) { + return rejectWithValue( + error.response?.data?.message || '로그인 요청 실패' + ); + } + } +); + +const userSlice = createSlice({ + name: 'user', + initialState, + reducers: { + logout: (state) => { + state.isLoggedIn = false; + state.token = null; + state.userInfo = null; + state.loading = false; + state.error = null; + }, + }, + extraReducers: (builder) => { + builder + .addCase(loginAsync.pending, (state) => { + state.loading = true; + state.error = null; + }) + .addCase(loginAsync.fulfilled, (state, action) => { + const decoded: DecodedToken = jwtDecode(action.payload); + const userInfo: UserInfo = { + id: decoded.id, + email: decoded.email, + nickname: decoded.nickname, + role: decoded.role, + }; + + state.isLoggedIn = true; + state.token = action.payload; + state.userInfo = userInfo; + state.loading = false; + state.error = null; + + if (typeof window !== 'undefined') { + localStorage.setItem('token', action.payload); + } + }) + .addCase(loginAsync.rejected, (state, action) => { + state.loading = false; + state.error = action.payload as string; + }); + }, +}); + +export const { logout } = userSlice.actions; +export default userSlice.reducer; diff --git a/src/index.css b/src/index.css deleted file mode 100644 index 6119ad9..0000000 --- a/src/index.css +++ /dev/null @@ -1,68 +0,0 @@ -:root { - font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; - line-height: 1.5; - font-weight: 400; - - color-scheme: light dark; - color: rgba(255, 255, 255, 0.87); - background-color: #242424; - - font-synthesis: none; - text-rendering: optimizeLegibility; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -a { - font-weight: 500; - color: #646cff; - text-decoration: inherit; -} -a:hover { - color: #535bf2; -} - -body { - margin: 0; - display: flex; - place-items: center; - min-width: 320px; - min-height: 100vh; -} - -h1 { - font-size: 3.2em; - line-height: 1.1; -} - -button { - border-radius: 8px; - border: 1px solid transparent; - padding: 0.6em 1.2em; - font-size: 1em; - font-weight: 500; - font-family: inherit; - background-color: #1a1a1a; - cursor: pointer; - transition: border-color 0.25s; -} -button:hover { - border-color: #646cff; -} -button:focus, -button:focus-visible { - outline: 4px auto -webkit-focus-ring-color; -} - -@media (prefers-color-scheme: light) { - :root { - color: #213547; - background-color: #ffffff; - } - a:hover { - color: #747bff; - } - button { - background-color: #f9f9f9; - } -} diff --git a/src/main.tsx b/src/main.tsx index bef5202..4ee7573 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -1,10 +1,10 @@ -import { StrictMode } from 'react' -import { createRoot } from 'react-dom/client' -import './index.css' -import App from './App.tsx' +import { StrictMode } from 'react'; +import { createRoot } from 'react-dom/client'; +import App from './App.tsx'; +import '@/styles/reset.css'; createRoot(document.getElementById('root')!).render( - , -) + +); diff --git a/src/mocks/browser.ts b/src/mocks/browser.ts new file mode 100644 index 0000000..0a56427 --- /dev/null +++ b/src/mocks/browser.ts @@ -0,0 +1,4 @@ +import { setupWorker } from 'msw/browser'; +import { handlers } from './handlers'; + +export const worker = setupWorker(...handlers); diff --git a/src/mocks/handlers.ts b/src/mocks/handlers.ts new file mode 100644 index 0000000..85fe632 --- /dev/null +++ b/src/mocks/handlers.ts @@ -0,0 +1,13 @@ +import { http, HttpResponse } from 'msw'; + +export const handlers = [ + // Intercept "GET https://example.com/user" requests... + http.get('https://example.com/user', () => { + // ...and respond to them using this JSON response. + return HttpResponse.json({ + id: 'c7b3d8e0-5e0b-4b0f-8b3a-3b9f4b3d3b3d', + firstName: 'John', + lastName: 'Maverick', + }); + }), +]; diff --git a/src/pages/AdminPage.tsx b/src/pages/AdminPage.tsx new file mode 100644 index 0000000..c2d1874 --- /dev/null +++ b/src/pages/AdminPage.tsx @@ -0,0 +1,69 @@ +import { useState } from 'react'; +import { ChevronDownIcon, ChevronUpIcon } from '@heroicons/react/24/outline'; +import UserList from '@/admin/UserList'; +import styled from 'styled-components'; + +// Styled Components +const PageContainer = styled.div` + padding: 20px; +`; + +const TitleContainer = styled.div` + display: flex; + align-items: center; + justify-content: flex-start; + cursor: pointer; + margin-left: 10px; + margin-right: 10px; +`; + +const Title = styled.h1` + font-family: 'Pretendard', sans-serif; + font-size: 32px; + font-weight: 800; + text-align: left; + margin: 0; +`; + +const IconWrapper = styled.div` + width: 24px; + height: 24px; + margin-left: 10px; +`; + +const ListContainer = styled.div` + display: flex; + flex-direction: column; + align-items: flex-start; + width: 100%; + margin-top: 40px; +`; + +const AdminPage = () => { + const [showUserList, setShowUserList] = useState(false); + + const toggleUserList = () => { + setShowUserList((open) => !open); + }; + + return ( + + {/* 제목과 아이콘 */} + + 유저조회 + + {showUserList ? : } + + + + {/* 유저 리스트 */} + {showUserList && ( + + + + )} + + ); +}; + +export default AdminPage; diff --git a/src/pages/BoardModificationPage.tsx b/src/pages/BoardModificationPage.tsx new file mode 100644 index 0000000..f0c7f93 --- /dev/null +++ b/src/pages/BoardModificationPage.tsx @@ -0,0 +1,85 @@ +import { updateUserIntroduce } from '@/apis/board.api'; +import { fetchUserInfo } from '@/apis/user-info.api'; +import Button from '@/components/ui/atoms/Button'; +import RichTextEditor from '@/components/ui/molecules/QuillEditor'; +import { RootState } from '@/store/rootReducer'; +import { useEffect, useState } from 'react'; +import { useSelector } from 'react-redux'; +import styled from 'styled-components'; + +const BoardModificationPage = () => { + const nickname = useSelector( + (state: RootState) => state.user.userInfo?.nickname + ); + const id = useSelector((state: RootState) => state.user.userInfo?.id); + + const [content, setContent] = useState(''); + const [loading, setLoading] = useState(true); + + useEffect(() => { + if (nickname) { + setLoading(true); + fetchUserInfo(nickname) + .then((data) => { + setContent(data.profile.introduce); + setLoading(false); + }) + .catch((error) => { + console.error('에러 발생:', error); + setLoading(false); + }); + } + }, [nickname]); + + if (loading) { + return
Loading...
; + } + + const registerBoard = async () => { + if (!content.trim()) { + alert('내용을 입력해주세요.'); + return; + } + try { + const response = await updateUserIntroduce(id as number, content); + console.log('게시글 등록 성공:', response); + alert('게시글이 성공적으로 등록되었습니다!'); + } catch (error) { + console.error('게시글 등록 실패:', error); + alert('게시글 등록에 실패했습니다. 다시 시도해주세요.'); + } + }; + + return ( + +
+ +
+ + + + +
+ ); +}; + +export default BoardModificationPage; + +const WriteContainer = styled.div` + width: 100%; + height: fit-content; + border: 2px solid gray; + border-radius: 10px; + padding: 0px 0px 10px 0px; +`; + +const RegisterSection = styled.div` + display: flex; + flex-direction: row-reverse; + padding: 0px 20px 0px 20px; + gap: 10px; +`; diff --git a/src/pages/BoardWritePage.tsx b/src/pages/BoardWritePage.tsx new file mode 100644 index 0000000..0bbd356 --- /dev/null +++ b/src/pages/BoardWritePage.tsx @@ -0,0 +1,134 @@ +import { fetchUpdateReview } from '@/apis/board.api'; +import Button from '@/components/ui/atoms/Button'; +import RichTextEditor from '@/components/ui/molecules/QuillEditor'; +import { TagItems } from '@/constants/TagItems'; +import { useState } from 'react'; +import styled from 'styled-components'; + +const BoardWritePage = () => { + const [title, setTitle] = useState(''); + const [selectedTags, setSelectedTags] = useState([]); + const [content, setContent] = useState(''); + + const handleTagSelected = (index: number) => { + setSelectedTags((prev) => + prev.includes(index) ? prev.filter((i) => i !== index) : [...prev, index] + ); + }; + + const registerBoard = async () => { + if (!title.trim()) { + alert('제목을 입력해주세요.'); + return; + } + if (selectedTags.length === 0) { + alert('태그를 선택해주세요.'); + return; + } + if (!content.trim()) { + alert('내용을 입력해주세요.'); + return; + } + const selectedTagNames = selectedTags.map((index) => TagItems[index]); + try { + console.log('title: ', title); + const response = await fetchUpdateReview( + title, + selectedTagNames, + content + ); + console.log('게시글 등록 성공:', response); + alert('게시글이 성공적으로 등록되었습니다!'); + } catch (error) { + console.error('게시글 등록 실패:', error); + alert('게시글 등록에 실패했습니다. 다시 시도해주세요.'); + } + }; + + return ( + + + setTitle(e.target.value)} + /> + + + 태그를 등록해주세요 + + {TagItems.map((item, index) => ( + + ))} + + +
+ +
+ + + + +
+ ); +}; + +export default BoardWritePage; + +const WriteContainer = styled.div` + width: 100%; + height: fit-content; + border: 2px solid gray; + border-radius: 10px; + padding: 0px 0px 10px 0px; +`; + +const TitleSection = styled.div` + width: 100%; + display: flex; + align-items: center; + padding: 10px 10px 10px 20px; +`; + +const TitleInput = styled.input` + font-size: 22px; + height: 44px; + width: 500px; + border: none; + padding: 5px; +`; + +const TagSection = styled.div` + width: 100%; + height: 70px; + display: flex; + flex-direction: column; + padding: 10px 10px 10px 20px; + gap: 5px; +`; + +const TagTitle = styled.div` + font-size: 18px; + padding-left: 5px; +`; + +const TagWrapper = styled.div` + display: flex; + gap: 10px; + padding-left: 5px; +`; + +const RegisterSection = styled.div` + display: flex; + flex-direction: row-reverse; + padding: 0px 20px 0px 20px; + gap: 10px; +`; diff --git a/src/pages/HomePage.tsx b/src/pages/HomePage.tsx new file mode 100644 index 0000000..86020db --- /dev/null +++ b/src/pages/HomePage.tsx @@ -0,0 +1,15 @@ +import MainTagList from '@/components/main-page/MainTagList'; +import SearchInput from '@/components/main-page/SearchInput'; +import QuestionBox from '@/components/main-page/QuestionBox'; + +const HomePage = () => { + return ( +
+ + + +
+ ); +}; + +export default HomePage; diff --git a/src/pages/JoinPage.tsx b/src/pages/JoinPage.tsx new file mode 100644 index 0000000..651e03a --- /dev/null +++ b/src/pages/JoinPage.tsx @@ -0,0 +1,228 @@ +import { useState } from 'react'; +import { useForm } from 'react-hook-form'; +import styled from 'styled-components'; +import { useNavigate } from 'react-router'; +import qublogo from '@/assets/qublogo.svg'; +import { join } from '@/apis/auth.api'; +import PasswordGuideLines from '@/components/ui/atoms/join-atom/PasswordGuideLines'; +import Input from '@/components/ui/atoms/Input'; + +export interface JoinProps { + email: string; + nickname: string; + password: string; + confirmPassword: string; +} + +function JoinPage() { + const navigate = useNavigate(); + const [isLoading, setIsLoading] = useState(false); + + const { + register, + handleSubmit, + formState: { errors }, + watch, + } = useForm(); + + const password = watch('password'); + + const onSubmit = async (data: JoinProps) => { + setIsLoading(true); + try { + await join(data); + alert('회원가입이 완료되었습니다!'); + navigate('/login'); + } catch (error: any) { + console.error('회원가입 중 에러 발생:', error); + if (error.response?.data?.message) { + alert(error.response.data.message); + } else { + alert('회원가입에 실패했습니다. 다시 시도해주세요.'); + } + } finally { + setIsLoading(false); + } + }; + + return ( + + + navigate('/')}> + + + +
+ {/* 이메일 */} + + + + {errors.email && {errors.email.message}} + + {/* 닉네임 */} + + + + {errors.nickname && {errors.nickname.message}} + + {/* 비밀번호 */} + + + + {errors.password && {errors.password.message}} + + {/* 비밀번호 확인 */} + + + value === password || '비밀번호가 일치하지 않습니다.', + })} + /> + + {errors.confirmPassword && ( + {errors.confirmPassword.message} + )} + + {/* 비밀번호 가이드라인 */} + + + + + {/* 제출 버튼 */} + + {isLoading ? '처리 중...' : '회원가입'} + +
+
+
+ ); +} + +const Container = styled.div` + background-color: #ffffff; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + width: 100%; + height: 100vh; +`; + +const InnerWrapper = styled.div` + display: flex; + flex-direction: column; + align-items: center; + width: 100%; + max-width: 24rem; +`; + +const LogoWrapper = styled.div` + margin-bottom: 2.5rem; + cursor: pointer; +`; + +const LogoImage = styled.img` + width: 150px; + height: 80px; + object-fit: contain; +`; + +const Form = styled.form` + width: 100%; + display: flex; + flex-direction: column; + align-items: center; +`; + +const InputWrapper = styled.div` + width: 100%; + display: flex; + justify-content: center; + margin-bottom: 1rem; +`; + +const StyledInput = styled(Input)` + max-width: 350px; + width: 100%; + margin: 0 auto; + display: block; +`; + +const PasswordGuideLinesWrapper = styled.div` + width: 100%; + text-align: left; + margin-left: 1rem; + margin-top: 1rem; + margin-bottom: 1rem; +`; + +const SubmitButton = styled.button` + width: 300px; + height: 70px; + background-color: #ffffff; + border: 1px solid #000000; + border-radius: 9999px; + display: flex; + justify-content: center; + align-items: center; + color: #000000; + font-size: 15px; + font-weight: 400; + cursor: pointer; + margin: 0 auto; + margin-top: 2rem; + + &:hover { + background-color: #e5e7eb; + } + + &:disabled { + background-color: #e5e7eb; + cursor: not-allowed; + } +`; + +const ErrorText = styled.p` + color: #ef4444; + font-size: 0.875rem; + margin-bottom: 1rem; + text-align: left; + width: 100%; + max-width: 350px; +`; + +export default JoinPage; diff --git a/src/pages/LoginPage.tsx b/src/pages/LoginPage.tsx new file mode 100644 index 0000000..0c1c3ca --- /dev/null +++ b/src/pages/LoginPage.tsx @@ -0,0 +1,188 @@ +import styled from 'styled-components'; +import { useNavigate } from 'react-router'; +import qublogo from '@/assets/qublogo.svg'; +import { useForm } from 'react-hook-form'; +import { useDispatch, useSelector } from 'react-redux'; // Redux 추가 +import Input from '@/components/ui/atoms/Input'; +import { RootState } from '@/store/rootReducer'; +import { loginAsync } from '@/hooks/userSlice'; +import { AppDispatch } from '@/store/store'; + +export type LoginFormData = { + email: string; + password: string; +}; + +function LoginPage() { + const navigate = useNavigate(); + const dispatch = useDispatch(); + const { loading, error } = useSelector((state: RootState) => state.user); + + const { + register, + handleSubmit, + formState: { errors }, + } = useForm(); + + const onSubmit = async (data: LoginFormData) => { + const result = await dispatch(loginAsync(data)); + + if (loginAsync.fulfilled.match(result)) { + alert('로그인에 성공했습니다!'); + navigate('/'); + } else { + alert( + (result.payload as string) || + '로그인에 실패했습니다. 다시 시도해주세요.' + ); + } + }; + + return ( + + + navigate('/')}> + + + +
+ + + + {errors.email && {errors.email.message}} + + + + + {errors.password && {errors.password.message}} + + {error && {error}} + + + {loading ? '로그인 중...' : '로그인'} + +
+ + + 아직 회원이 아니신가요? + navigate('/join')}>이메일 회원가입 + +
+
+ ); +} + +const Container = styled.div` + background-color: #ffffff; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + width: 100%; + height: 100vh; +`; + +const InnerWrapper = styled.div` + display: flex; + flex-direction: column; + align-items: center; + width: 100%; + max-width: 24rem; +`; + +const LogoWrapper = styled.div` + margin-bottom: 2.5rem; + cursor: pointer; +`; + +const LogoImage = styled.img` + width: 150px; + height: 80px; + object-fit: contain; +`; + +const Form = styled.form` + width: 100%; + display: flex; + flex-direction: column; + align-items: center; +`; + +const InputWrapper = styled.div` + width: 100%; + display: flex; + justify-content: center; + margin-bottom: 1rem; +`; + +const StyledInput = styled(Input)` + max-width: 350px; + width: 100%; + margin: 0 auto; + display: block; +`; + +const SubmitButton = styled.button` + width: 300px; + height: 70px; + background-color: #ffffff; + border: 1px solid #000000; + border-radius: 9999px; + display: flex; + justify-content: center; + align-items: center; + color: #000000; + font-size: 18px; + font-weight: 400; + cursor: pointer; + margin: 0 auto; + margin-top: 2rem; + + &:hover { + background-color: #e5e7eb; + } + + &:disabled { + background-color: #e5e7eb; + cursor: not-allowed; + } +`; + +const BottomSection = styled.div` + width: 100%; + display: flex; + justify-content: center; + align-items: center; + margin-top: 3.5rem; + gap: 1rem; +`; + +const InfoText = styled.span` + color: #a7a7a7; + font-size: 12px; +`; + +const LinkText = styled.span` + color: #000000; + font-size: 12px; + cursor: pointer; +`; + +const ErrorText = styled.p` + color: #ef4444; + font-size: 0.875rem; + margin-bottom: 1rem; + text-align: left; + width: 100%; + max-width: 350px; +`; + +export default LoginPage; diff --git a/src/pages/MyPage.tsx b/src/pages/MyPage.tsx new file mode 100644 index 0000000..7238459 --- /dev/null +++ b/src/pages/MyPage.tsx @@ -0,0 +1,132 @@ +import { useEffect, useState } from 'react'; +import Avatar from '@/components/ui/atoms/Avator'; +import { useSelector } from 'react-redux'; +import { Link, Outlet, useLocation } from 'react-router'; +import styled from 'styled-components'; +import { RootState } from '@/store/rootReducer'; +import { fetchUserInfo, UserData } from '@/apis/user-info.api'; + +const MyPage = () => { + const location = useLocation(); + const nickname = useSelector( + (state: RootState) => state.user.userInfo?.nickname + ); + + const [userData, setUserData] = useState(null); + const [loading, setLoading] = useState(true); + + useEffect(() => { + if (nickname) { + setLoading(true); + fetchUserInfo(nickname) + .then((data) => { + setUserData(data); + setLoading(false); + }) + .catch((error) => { + console.error('에러 발생:', error); + setLoading(false); + }); + } + }, [nickname]); + + if (loading) { + return
Loading...
; + } + + return ( + + + + + {userData?.profile.nickname}님 + + + + + 홈 + + + + + 게시글 + + + + + 좋아요한 게시글 + + + + + + + + + ); +}; + +export default MyPage; + +const MyPageContainer = styled.div` + display: flex; + width: 100%; + min-height: 100vh; +`; + +const UserProfileSection = styled.section` + width: 300px; + min-height: 100vh; + position: relative; + padding: 20px 0; +`; + +const UserContentSection = styled.section` + flex: 1; + min-height: 100vh; + padding: 10px; +`; + +const AvatarContainer = styled.div` + display: flex; + flex-direction: column; + gap: 10px; + align-items: center; +`; + +const UserName = styled.div` + font-size: 18px; + font-weight: bold; + color: black; + margin-top: 10px; +`; + +const Navigation = styled.ul` + list-style: none; + padding: 0; + margin-top: 40px; + margin-left: 20px; +`; + +const NavItem = styled.li` + margin: 10px 0; +`; + +const StyledLink = styled(Link)<{ isActive: boolean }>` + text-decoration: none; + color: ${(props) => (props.isActive ? 'black' : 'gray')}; + font-size: 16px; + &:hover { + color: lightgray; + } +`; diff --git a/src/routes/router.tsx b/src/routes/router.tsx new file mode 100644 index 0000000..6feaa2b --- /dev/null +++ b/src/routes/router.tsx @@ -0,0 +1,69 @@ +import Layout from '@/components/layout/Layout'; +import Scraps from '@/components/my-page/Scraps'; +import UserContents from '@/components/my-page/UserContents'; +import UserPosts from '@/components/my-page/UserPosts'; +import AdminPage from '@/pages/AdminPage'; +import HomePage from '@/pages/HomePage'; +import JoinPage from '@/pages/JoinPage'; +import LoginPage from '@/pages/LoginPage'; +import MyPage from '@/pages/MyPage'; +import ProtectedRoute from '@/admin/AdminRoute'; +import BoardWritePage from '@/pages/BoardWritePage'; +import BoardModificationPage from '@/pages/BoardModificationPage'; + +const router = [ + { + path: '/', + element: , + children: [ + { + path: '/', + element: , + }, + { + path: '/boardwrite', + element: , + }, + { + path: '/boardModification', + element: , + }, + { + path: '/mypage', + element: , + children: [ + { + path: '', + element: , + }, + { + path: 'myposts', + element: , + }, + { + path: 'scrap', + element: , + }, + ], + }, + { + path: '/adminpage', + element: ( + + + + ), + }, + ], + }, + { + path: '/login', + element: , + }, + { + path: '/join', + element: , + }, +]; + +export default router; diff --git a/src/store/rootReducer.ts b/src/store/rootReducer.ts new file mode 100644 index 0000000..41d8039 --- /dev/null +++ b/src/store/rootReducer.ts @@ -0,0 +1,11 @@ +// src/app/rootReducer.ts +import { combineReducers } from '@reduxjs/toolkit'; +import userReducer from '@/hooks/userSlice'; + +const rootReducer = combineReducers({ + user: userReducer, + // 다른 slice reducer가 있다면 여기에 추가 +}); + +export type RootState = ReturnType; +export default rootReducer; diff --git a/src/store/store.ts b/src/store/store.ts new file mode 100644 index 0000000..18da92d --- /dev/null +++ b/src/store/store.ts @@ -0,0 +1,25 @@ +import { configureStore } from '@reduxjs/toolkit'; +import { persistStore, persistReducer } from 'redux-persist'; +import storage from 'redux-persist/lib/storage'; +import rootReducer from './rootReducer'; + +const persistConfig = { + key: 'root', + storage, + whitelist: ['user'], +}; + +const persistedReducer = persistReducer(persistConfig, rootReducer); + +export const store = configureStore({ + reducer: persistedReducer, + middleware: (getDefaultMiddleware) => + getDefaultMiddleware({ + serializableCheck: false, + }), +}); + +export const persistor = persistStore(store); + +// store의 타입 유추 +export type AppDispatch = typeof store.dispatch; diff --git a/src/stories/Configure.mdx b/src/stories/Configure.mdx new file mode 100644 index 0000000..6a53730 --- /dev/null +++ b/src/stories/Configure.mdx @@ -0,0 +1,364 @@ +import { Meta } from "@storybook/blocks"; + +import Github from "./assets/github.svg"; +import Discord from "./assets/discord.svg"; +import Youtube from "./assets/youtube.svg"; +import Tutorials from "./assets/tutorials.svg"; +import Styling from "./assets/styling.png"; +import Context from "./assets/context.png"; +import Assets from "./assets/assets.png"; +import Docs from "./assets/docs.png"; +import Share from "./assets/share.png"; +import FigmaPlugin from "./assets/figma-plugin.png"; +import Testing from "./assets/testing.png"; +import Accessibility from "./assets/accessibility.png"; +import Theming from "./assets/theming.png"; +import AddonLibrary from "./assets/addon-library.png"; + +export const RightArrow = () => + + + + + +
+
+ # Configure your project + + Because Storybook works separately from your app, you'll need to configure it for your specific stack and setup. Below, explore guides for configuring Storybook with popular frameworks and tools. If you get stuck, learn how you can ask for help from our community. +
+
+
+ A wall of logos representing different styling technologies +

Add styling and CSS

+

Like with web applications, there are many ways to include CSS within Storybook. Learn more about setting up styling within Storybook.

+ Learn more +
+
+ An abstraction representing the composition of data for a component +

Provide context and mocking

+

Often when a story doesn't render, it's because your component is expecting a specific environment or context (like a theme provider) to be available.

+ Learn more +
+
+ A representation of typography and image assets +
+

Load assets and resources

+

To link static files (like fonts) to your projects and stories, use the + `staticDirs` configuration option to specify folders to load when + starting Storybook.

+ Learn more +
+
+
+
+
+
+ # Do more with Storybook + + Now that you know the basics, let's explore other parts of Storybook that will improve your experience. This list is just to get you started. You can customise Storybook in many ways to fit your needs. +
+ +
+
+
+ A screenshot showing the autodocs tag being set, pointing a docs page being generated +

Autodocs

+

Auto-generate living, + interactive reference documentation from your components and stories.

+ Learn more +
+
+ A browser window showing a Storybook being published to a chromatic.com URL +

Publish to Chromatic

+

Publish your Storybook to review and collaborate with your entire team.

+ Learn more +
+
+ Windows showing the Storybook plugin in Figma +

Figma Plugin

+

Embed your stories into Figma to cross-reference the design and live + implementation in one place.

+ Learn more +
+
+ Screenshot of tests passing and failing +

Testing

+

Use stories to test a component in all its variations, no matter how + complex.

+ Learn more +
+
+ Screenshot of accessibility tests passing and failing +

Accessibility

+

Automatically test your components for a11y issues as you develop.

+ Learn more +
+
+ Screenshot of Storybook in light and dark mode +

Theming

+

Theme Storybook's UI to personalize it to your project.

+ Learn more +
+
+
+
+
+
+

Addons

+

Integrate your tools with Storybook to connect workflows.

+ Discover all addons +
+
+ Integrate your tools with Storybook to connect workflows. +
+
+ +
+
+ Github logo + Join our contributors building the future of UI development. + + Star on GitHub +
+
+ Discord logo +
+ Get support and chat with frontend developers. + + Join Discord server +
+
+
+ Youtube logo +
+ Watch tutorials, feature previews and interviews. + + Watch on YouTube +
+
+
+ A book +

Follow guided walkthroughs on for key workflows.

+ + Discover tutorials +
+
+ + diff --git a/src/stories/assets/accessibility.png b/src/stories/assets/accessibility.png new file mode 100644 index 0000000..6ffe6fe Binary files /dev/null and b/src/stories/assets/accessibility.png differ diff --git a/src/stories/assets/accessibility.svg b/src/stories/assets/accessibility.svg new file mode 100644 index 0000000..107e93f --- /dev/null +++ b/src/stories/assets/accessibility.svg @@ -0,0 +1 @@ +Accessibility \ No newline at end of file diff --git a/src/stories/assets/addon-library.png b/src/stories/assets/addon-library.png new file mode 100644 index 0000000..95deb38 Binary files /dev/null and b/src/stories/assets/addon-library.png differ diff --git a/src/stories/assets/assets.png b/src/stories/assets/assets.png new file mode 100644 index 0000000..cfba681 Binary files /dev/null and b/src/stories/assets/assets.png differ diff --git a/src/stories/assets/avif-test-image.avif b/src/stories/assets/avif-test-image.avif new file mode 100644 index 0000000..530709b Binary files /dev/null and b/src/stories/assets/avif-test-image.avif differ diff --git a/src/stories/assets/context.png b/src/stories/assets/context.png new file mode 100644 index 0000000..e5cd249 Binary files /dev/null and b/src/stories/assets/context.png differ diff --git a/src/stories/assets/discord.svg b/src/stories/assets/discord.svg new file mode 100644 index 0000000..d638958 --- /dev/null +++ b/src/stories/assets/discord.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/stories/assets/docs.png b/src/stories/assets/docs.png new file mode 100644 index 0000000..a749629 Binary files /dev/null and b/src/stories/assets/docs.png differ diff --git a/src/stories/assets/figma-plugin.png b/src/stories/assets/figma-plugin.png new file mode 100644 index 0000000..8f79b08 Binary files /dev/null and b/src/stories/assets/figma-plugin.png differ diff --git a/src/stories/assets/github.svg b/src/stories/assets/github.svg new file mode 100644 index 0000000..dc51352 --- /dev/null +++ b/src/stories/assets/github.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/stories/assets/share.png b/src/stories/assets/share.png new file mode 100644 index 0000000..8097a37 Binary files /dev/null and b/src/stories/assets/share.png differ diff --git a/src/stories/assets/styling.png b/src/stories/assets/styling.png new file mode 100644 index 0000000..d341e82 Binary files /dev/null and b/src/stories/assets/styling.png differ diff --git a/src/stories/assets/testing.png b/src/stories/assets/testing.png new file mode 100644 index 0000000..d4ac39a Binary files /dev/null and b/src/stories/assets/testing.png differ diff --git a/src/stories/assets/theming.png b/src/stories/assets/theming.png new file mode 100644 index 0000000..1535eb9 Binary files /dev/null and b/src/stories/assets/theming.png differ diff --git a/src/stories/assets/tutorials.svg b/src/stories/assets/tutorials.svg new file mode 100644 index 0000000..b492a9c --- /dev/null +++ b/src/stories/assets/tutorials.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/stories/assets/youtube.svg b/src/stories/assets/youtube.svg new file mode 100644 index 0000000..a7515d7 --- /dev/null +++ b/src/stories/assets/youtube.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/styles/GlobalStyle.tsx b/src/styles/GlobalStyle.tsx new file mode 100644 index 0000000..5332b3b --- /dev/null +++ b/src/styles/GlobalStyle.tsx @@ -0,0 +1,19 @@ +import { createGlobalStyle } from 'styled-components'; + +const GlobalStyle = createGlobalStyle` + *, *::before, *::after { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +html, body { + margin: 0; + padding: 0; + font-family: 'Pretendard-Regular', sans-serif; + width: 100%; + height: 100%; +} +`; + +export default GlobalStyle; diff --git a/src/styles/reset.css b/src/styles/reset.css new file mode 100644 index 0000000..6c9d5d7 --- /dev/null +++ b/src/styles/reset.css @@ -0,0 +1,130 @@ +/* http://meyerweb.com/eric/tools/css/reset/ + v2.0 | 20110126 + License: none (public domain) +*/ +@import 'react-quill/dist/quill.snow.css'; + +html, +body, +div, +span, +applet, +object, +iframe, +h1, +h2, +h3, +h4, +h5, +h6, +p, +blockquote, +pre, +a, +abbr, +acronym, +address, +big, +cite, +code, +del, +dfn, +em, +img, +ins, +kbd, +q, +s, +samp, +small, +strike, +strong, +sub, +sup, +tt, +var, +b, +u, +i, +center, +dl, +dt, +dd, +ol, +ul, +li, +fieldset, +form, +label, +legend, +table, +caption, +tbody, +tfoot, +thead, +tr, +th, +td, +article, +aside, +canvas, +details, +embed, +figure, +figcaption, +footer, +header, +hgroup, +menu, +nav, +output, +ruby, +section, +summary, +time, +mark, +audio, +video { + margin: 0; + padding: 0; + border: 0; + font-size: 100%; + font: inherit; + vertical-align: baseline; +} +/* HTML5 display-role reset for older browsers */ +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +menu, +nav, +section { + display: block; +} +body { + line-height: 1; +} +ol, +ul { + list-style: none; +} +blockquote, +q { + quotes: none; +} +blockquote:before, +blockquote:after, +q:before, +q:after { + content: ''; + content: none; +} +table { + border-collapse: collapse; + border-spacing: 0; +} diff --git a/src/types/admindata.ts b/src/types/admindata.ts new file mode 100644 index 0000000..55f18d6 --- /dev/null +++ b/src/types/admindata.ts @@ -0,0 +1,7 @@ +export interface AdminData { + id: number; + nickname: string; + email: string; + created_at: string; + icon: string | null; +} diff --git a/src/types/auth.ts b/src/types/auth.ts new file mode 100644 index 0000000..ba3e863 --- /dev/null +++ b/src/types/auth.ts @@ -0,0 +1,23 @@ +export interface UserInfo { + id: number; + email: string; + nickname: string; + role: string; +} + +export interface UserState { + isLoggedIn: boolean; + token: string | null; + userInfo: UserInfo | null; + loading: boolean; + error: string | null; +} + +export interface DecodedToken { + id: number; + email: string; + nickname: string; + role: string; + iat: number; + exp: number; +} diff --git a/src/types/main.model.ts b/src/types/main.model.ts new file mode 100644 index 0000000..c3ae25c --- /dev/null +++ b/src/types/main.model.ts @@ -0,0 +1,25 @@ +export interface mainUsers { + users: string | null; +} +export interface mainTags { + id: number | null; + name: string; + isActive?: boolean; +} +export interface mainPosts { + id: number; + title: string; + content: string; + solved: number; + nickname: string; + created_at: string; + comment_count: number; + like_count: number; + view: number; + tags: string | null; +} +export interface mainData { + users: mainUsers; + tags: mainTags[]; + posts: mainPosts[]; +} diff --git a/src/types/postdata.ts b/src/types/postdata.ts new file mode 100644 index 0000000..e357de7 --- /dev/null +++ b/src/types/postdata.ts @@ -0,0 +1,12 @@ +export interface PostData { + id: number; + title: string; + content: string; + solved: number; + nickname: string; + created_at: string; + comment_count: number; + like_count: number; + view: number; + tags: string | null; +} diff --git a/src/utils/token.ts b/src/utils/token.ts new file mode 100644 index 0000000..99a666a --- /dev/null +++ b/src/utils/token.ts @@ -0,0 +1,11 @@ +export function getToken(): string | null { + return localStorage.getItem('token'); +} + +export function setToken(token: string) { + localStorage.setItem('token', token); +} + +export function removeToken() { + localStorage.removeItem('token'); +} diff --git a/tsconfig.app.json b/tsconfig.app.json index 1556f12..7183d18 100644 --- a/tsconfig.app.json +++ b/tsconfig.app.json @@ -20,8 +20,11 @@ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, - "noFallthroughCasesInSwitch": true - // "noUncheckedSideEffectImports": true + "noFallthroughCasesInSwitch": true, + "baseUrl": "./", + "paths": { + "@/*": ["src/*"] + } }, "include": ["src"] } diff --git a/vite.config.ts b/vite.config.ts index 8b0f57b..b8cd6c4 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,7 +1,14 @@ -import { defineConfig } from 'vite' -import react from '@vitejs/plugin-react' +import { defineConfig } from 'vite'; +import react from '@vitejs/plugin-react'; +import path from 'path'; // https://vite.dev/config/ export default defineConfig({ plugins: [react()], -}) + resolve: { + alias: { + '@': path.resolve(__dirname, './src'), + '@styled-system': path.resolve(__dirname, './styled-system'), + }, + }, +});