diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..a547bf36 --- /dev/null +++ b/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/README.md b/README.md new file mode 100644 index 00000000..7059a962 --- /dev/null +++ b/README.md @@ -0,0 +1,12 @@ +# React + Vite + +This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. + +Currently, two official plugins are available: + +- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) for Fast Refresh +- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh + +## Expanding the ESLint configuration + +If you are developing a production application, we recommend using TypeScript with type-aware lint rules enabled. Check out the [TS template](https://github.com/vitejs/vite/tree/main/packages/create-vite/template-react-ts) for information on how to integrate TypeScript and [`typescript-eslint`](https://typescript-eslint.io) in your project. diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 00000000..ec2b712d --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,33 @@ +import js from '@eslint/js' +import globals from 'globals' +import reactHooks from 'eslint-plugin-react-hooks' +import reactRefresh from 'eslint-plugin-react-refresh' + +export default [ + { ignores: ['dist'] }, + { + files: ['**/*.{js,jsx}'], + languageOptions: { + ecmaVersion: 2020, + globals: globals.browser, + parserOptions: { + ecmaVersion: 'latest', + ecmaFeatures: { jsx: true }, + sourceType: 'module', + }, + }, + plugins: { + 'react-hooks': reactHooks, + 'react-refresh': reactRefresh, + }, + rules: { + ...js.configs.recommended.rules, + ...reactHooks.configs.recommended.rules, + 'no-unused-vars': ['error', { varsIgnorePattern: '^[A-Z_]' }], + 'react-refresh/only-export-components': [ + 'warn', + { allowConstantExport: true }, + ], + }, + }, +] diff --git a/images/Img_home_01.png b/images/Img_home_01.png deleted file mode 100644 index f496ba4c..00000000 Binary files a/images/Img_home_01.png and /dev/null differ diff --git a/images/Img_home_02.png b/images/Img_home_02.png deleted file mode 100644 index 1f3b1b83..00000000 Binary files a/images/Img_home_02.png and /dev/null differ diff --git a/images/Img_home_03.png b/images/Img_home_03.png deleted file mode 100644 index eb0d6cd2..00000000 Binary files a/images/Img_home_03.png and /dev/null differ diff --git a/images/Img_home_bottom.png b/images/Img_home_bottom.png deleted file mode 100644 index d4ef2c69..00000000 Binary files a/images/Img_home_bottom.png and /dev/null differ diff --git a/images/Img_home_top.png b/images/Img_home_top.png deleted file mode 100644 index f48df007..00000000 Binary files a/images/Img_home_top.png and /dev/null differ diff --git a/index.html b/index.html index 414a240e..fd931640 100644 --- a/index.html +++ b/index.html @@ -10,226 +10,12 @@ - - - - 판다 마켓 + 판다마켓 + + - -
-
-
-
-

일상의 모든 물건을 거래해보세요

- 구경하러 가기 - -
-
- 홈페이지를 소개하고 있는 그림 -
-
-
-
-
- - 가장 HOT한 중고거래 물품을 판다마켓에서 확인해보세요 -
-

Hot item

-

인기 상품을 확인해 보세요

-

- 가장 HOT한 중고거래 물품을
- 판다 마켓에서 확인해보세요 -

-
-
-
- 구매하고 싶은 물품은 검색해서 쉽게 찾아보세요 -
-

Search

-

구매를 원하는 상품을 검색하세요

-

- 구매하고 싶은 물품은 검색해서
- 쉽게 찾아보세요 -

-
-
-
- 어떤 물건이든 판매하고 싶은 상품을 쉽게 등록하세요 -
-

Register

-

판매를 원하는 상품을 등록하세요

-

- 어떤 물건이든 판매하고 싶은 상품을
- 쉽게 등록하세요 -

-
-
-
- -
- +
+ diff --git a/items.html b/items.html deleted file mode 100644 index 4e741baf..00000000 --- a/items.html +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - 판다 마켓 - 로그인 - - - diff --git a/login.html b/login.html deleted file mode 100644 index 068138c0..00000000 --- a/login.html +++ /dev/null @@ -1,109 +0,0 @@ - - - - - - - - - - - - 판다 마켓 - 로그인 - - - - 판다마켓 로고 - 판다마켓 - -
- - - - -
- - - - - - - -
- - 판다마켓이 처음이신가요? - 회원가입 - -
- - - diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 00000000..80568c27 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,2926 @@ +{ + "name": "mission5", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "mission5", + "version": "0.0.0", + "dependencies": { + "react": "^19.0.0", + "react-dom": "^19.0.0", + "react-responsive": "^10.0.1", + "react-router": "^7.5.3", + "react-router-dom": "^7.5.3" + }, + "devDependencies": { + "@eslint/js": "^9.22.0", + "@types/react": "^19.0.10", + "@types/react-dom": "^19.0.4", + "@vitejs/plugin-react": "^4.3.4", + "eslint": "^9.22.0", + "eslint-plugin-react-hooks": "^5.2.0", + "eslint-plugin-react-refresh": "^0.4.19", + "globals": "^16.0.0", + "vite": "^6.3.1" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", + "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.25.9", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.26.8", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.8.tgz", + "integrity": "sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.26.10", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.10.tgz", + "integrity": "sha512-vMqyb7XCDMPvJFFOaT9kxtiRh42GwlZEg1/uIgtZshS5a/8OaduUfCi7kynKgc3Tw/6Uo2D+db9qBttghhmxwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.26.2", + "@babel/generator": "^7.26.10", + "@babel/helper-compilation-targets": "^7.26.5", + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helpers": "^7.26.10", + "@babel/parser": "^7.26.10", + "@babel/template": "^7.26.9", + "@babel/traverse": "^7.26.10", + "@babel/types": "^7.26.10", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.27.0.tgz", + "integrity": "sha512-VybsKvpiN1gU1sdMZIp7FcqphVVKEwcuj02x73uvcHE0PTihx1nlBcowYWhDwjpoAXRv43+gDzyggGnn1XZhVw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.27.0", + "@babel/types": "^7.27.0", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.0.tgz", + "integrity": "sha512-LVk7fbXml0H2xH34dFzKQ7TDZ2G4/rVTOrq9V+icbbadjbVxxeFeDsNHv2SrZeWoA+6ZiTyWYWtScEIW07EAcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.26.8", + "@babel/helper-validator-option": "^7.25.9", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", + "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz", + "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.26.5.tgz", + "integrity": "sha512-RS+jZcRdZdRFzMyr+wcsaqOmld1/EqTghfaBGQQd/WnRdzdlvSZ//kF7U8VQTxf1ynZ4cjUcYgjVGx13ewNPMg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", + "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", + "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.27.0.tgz", + "integrity": "sha512-U5eyP/CTFPuNE3qk+WZMxFkp/4zUzdceQlfzf7DdGdhp+Fezd7HD+i8Y24ZuTMKX3wQBld449jijbGq6OdGNQg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.27.0", + "@babel/types": "^7.27.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.0.tgz", + "integrity": "sha512-iaepho73/2Pz7w2eMS0Q5f83+0RKI7i4xmiYeBmDzfRVbQtTOG7Ts0S4HzJVsTMGI9keU8rNfuZr8DKfSt7Yyg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.0" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.25.9.tgz", + "integrity": "sha512-y8quW6p0WHkEhmErnfe58r7x0A70uKphQm8Sp8cV7tjNQwK56sNVK0M73LK3WuYmsuyrftut4xAkjjgU0twaMg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.25.9.tgz", + "integrity": "sha512-+iqjT8xmXhhYv4/uiYd8FNQsraMFZIfxVSqxxVSZP0WbbSAWvBXAul0m/zu+7Vv4O/3WtApy9pmaTMiumEZgfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/template": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.0.tgz", + "integrity": "sha512-2ncevenBqXI6qRMukPlXwHKHchC7RyMuu4xv5JBXRfOGVcTy1mXCD12qrp7Jsoxll1EV3+9sE4GugBVRjT2jFA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.26.2", + "@babel/parser": "^7.27.0", + "@babel/types": "^7.27.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.27.0.tgz", + "integrity": "sha512-19lYZFzYVQkkHkl4Cy4WrAVcqBkgvV2YM2TU3xG6DIwO7O3ecbDPfW3yM3bjAGcqcQHi+CCtjMR3dIEHxsd6bA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.26.2", + "@babel/generator": "^7.27.0", + "@babel/parser": "^7.27.0", + "@babel/template": "^7.27.0", + "@babel/types": "^7.27.0", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/types": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.0.tgz", + "integrity": "sha512-H45s8fVLYjbhFH62dIJ3WtmJ6RSPt/3DRO0ZcT2SUiYiQyz3BLVb9ADEnLl91m74aQPS3AzzeajZHYOalWe3bg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.3.tgz", + "integrity": "sha512-W8bFfPA8DowP8l//sxjJLSLkD8iEjMc7cBVyP+u4cEv9sM7mdUCkgsj+t0n/BWPFtv7WWCN5Yzj0N6FJNUUqBQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.3.tgz", + "integrity": "sha512-PuwVXbnP87Tcff5I9ngV0lmiSu40xw1At6i3GsU77U7cjDDB4s0X2cyFuBiDa1SBk9DnvWwnGvVaGBqoFWPb7A==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.3.tgz", + "integrity": "sha512-XelR6MzjlZuBM4f5z2IQHK6LkK34Cvv6Rj2EntER3lwCBFdg6h2lKbtRjpTTsdEjD/WSe1q8UyPBXP1x3i/wYQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.3.tgz", + "integrity": "sha512-ogtTpYHT/g1GWS/zKM0cc/tIebFjm1F9Aw1boQ2Y0eUQ+J89d0jFY//s9ei9jVIlkYi8AfOjiixcLJSGNSOAdQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.3.tgz", + "integrity": "sha512-eESK5yfPNTqpAmDfFWNsOhmIOaQA59tAcF/EfYvo5/QWQCzXn5iUSOnqt3ra3UdzBv073ykTtmeLJZGt3HhA+w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.3.tgz", + "integrity": "sha512-Kd8glo7sIZtwOLcPbW0yLpKmBNWMANZhrC1r6K++uDR2zyzb6AeOYtI6udbtabmQpFaxJ8uduXMAo1gs5ozz8A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.3.tgz", + "integrity": "sha512-EJiyS70BYybOBpJth3M0KLOus0n+RRMKTYzhYhFeMwp7e/RaajXvP+BWlmEXNk6uk+KAu46j/kaQzr6au+JcIw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.3.tgz", + "integrity": "sha512-Q+wSjaLpGxYf7zC0kL0nDlhsfuFkoN+EXrx2KSB33RhinWzejOd6AvgmP5JbkgXKmjhmpfgKZq24pneodYqE8Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.3.tgz", + "integrity": "sha512-dUOVmAUzuHy2ZOKIHIKHCm58HKzFqd+puLaS424h6I85GlSDRZIA5ycBixb3mFgM0Jdh+ZOSB6KptX30DD8YOQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.3.tgz", + "integrity": "sha512-xCUgnNYhRD5bb1C1nqrDV1PfkwgbswTTBRbAd8aH5PhYzikdf/ddtsYyMXFfGSsb/6t6QaPSzxtbfAZr9uox4A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.3.tgz", + "integrity": "sha512-yplPOpczHOO4jTYKmuYuANI3WhvIPSVANGcNUeMlxH4twz/TeXuzEP41tGKNGWJjuMhotpGabeFYGAOU2ummBw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.3.tgz", + "integrity": "sha512-P4BLP5/fjyihmXCELRGrLd793q/lBtKMQl8ARGpDxgzgIKJDRJ/u4r1A/HgpBpKpKZelGct2PGI4T+axcedf6g==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.3.tgz", + "integrity": "sha512-eRAOV2ODpu6P5divMEMa26RRqb2yUoYsuQQOuFUexUoQndm4MdpXXDBbUoKIc0iPa4aCO7gIhtnYomkn2x+bag==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.3.tgz", + "integrity": "sha512-ZC4jV2p7VbzTlnl8nZKLcBkfzIf4Yad1SJM4ZMKYnJqZFD4rTI+pBG65u8ev4jk3/MPwY9DvGn50wi3uhdaghg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.3.tgz", + "integrity": "sha512-LDDODcFzNtECTrUUbVCs6j9/bDVqy7DDRsuIXJg6so+mFksgwG7ZVnTruYi5V+z3eE5y+BJZw7VvUadkbfg7QA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.3.tgz", + "integrity": "sha512-s+w/NOY2k0yC2p9SLen+ymflgcpRkvwwa02fqmAwhBRI3SC12uiS10edHHXlVWwfAagYSY5UpmT/zISXPMW3tQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.3.tgz", + "integrity": "sha512-nQHDz4pXjSDC6UfOE1Fw9Q8d6GCAd9KdvMZpfVGWSJztYCarRgSDfOVBY5xwhQXseiyxapkiSJi/5/ja8mRFFA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.3.tgz", + "integrity": "sha512-1QaLtOWq0mzK6tzzp0jRN3eccmN3hezey7mhLnzC6oNlJoUJz4nym5ZD7mDnS/LZQgkrhEbEiTn515lPeLpgWA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.3.tgz", + "integrity": "sha512-i5Hm68HXHdgv8wkrt+10Bc50zM0/eonPb/a/OFVfB6Qvpiirco5gBA5bz7S2SHuU+Y4LWn/zehzNX14Sp4r27g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.3.tgz", + "integrity": "sha512-zGAVApJEYTbOC6H/3QBr2mq3upG/LBEXr85/pTtKiv2IXcgKV0RT0QA/hSXZqSvLEpXeIxah7LczB4lkiYhTAQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.3.tgz", + "integrity": "sha512-fpqctI45NnCIDKBH5AXQBsD0NDPbEFczK98hk/aa6HJxbl+UtLkJV2+Bvy5hLSLk3LHmqt0NTkKNso1A9y1a4w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.3.tgz", + "integrity": "sha512-ROJhm7d8bk9dMCUZjkS8fgzsPAZEjtRJqCAmVgB0gMrvG7hfmPmz9k1rwO4jSiblFjYmNvbECL9uhaPzONMfgA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.3.tgz", + "integrity": "sha512-YWcow8peiHpNBiIXHwaswPnAXLsLVygFwCB3A7Bh5jRkIBFWHGmNQ48AlX4xDvQNoMZlPYzjVOQDYEzWCqufMQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.3.tgz", + "integrity": "sha512-qspTZOIGoXVS4DpNqUYUs9UxVb04khS1Degaw/MnfMe7goQ3lTfQ13Vw4qY/Nj0979BGvMRpAYbs/BAxEvU8ew==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.3.tgz", + "integrity": "sha512-ICgUR+kPimx0vvRzf+N/7L7tVSQeE3BYY+NhHRHXS1kBuPO7z2+7ea2HbhDyZdTephgvNvKrlDDKUexuCVBVvg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.6.1.tgz", + "integrity": "sha512-KTsJMmobmbrFLe3LDh0PC2FXpcSYJt/MLjlkh/9LEnmKYLSYmT/0EW9JWANjeoemiuZrmogti0tW5Ch+qNUYDw==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.20.0.tgz", + "integrity": "sha512-fxlS1kkIjx8+vy2SjuCB94q3htSNrufYTXubwiBFeaQHbH6Ipi43gFJq2zCMt6PHhImH3Xmr0NksKDvchWlpQQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.6", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.2.1.tgz", + "integrity": "sha512-RI17tsD2frtDu/3dmI7QRrD4bedNKPM08ziRYaC5AhkGrzIAJelm9kJU1TznK+apx6V+cqRz8tfpEeG3oIyjxw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.13.0.tgz", + "integrity": "sha512-yfkgDw1KR66rkT5A8ci4irzDysN7FRpq3ttJolR88OqQikAWqwA8j5VZyas+vjyBNFIJ7MfybJ9plMILI2UrCw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", + "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/js": { + "version": "9.25.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.25.1.tgz", + "integrity": "sha512-dEIwmjntEx8u3Uvv+kr3PDeeArL8Hw07H9kyYxCjnM9pBjfEhk6uLXSchxxzgiwtRhhzVzqmUSDFBOi1TuZ7qg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz", + "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.8.tgz", + "integrity": "sha512-ZAoA40rNMPwSm+AeHpCq8STiNAwzWLJuP8Xv4CHIc9wv/PSuExjMrmjfYNj682vW0OOiZ1HKxzvjQr9XZIisQA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.13.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.6", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", + "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.3.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", + "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.2.tgz", + "integrity": "sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", + "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.40.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.40.1.tgz", + "integrity": "sha512-kxz0YeeCrRUHz3zyqvd7n+TVRlNyTifBsmnmNPtk3hQURUyG9eAB+usz6DAwagMusjx/zb3AjvDUvhFGDAexGw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.40.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.40.1.tgz", + "integrity": "sha512-PPkxTOisoNC6TpnDKatjKkjRMsdaWIhyuMkA4UsBXT9WEZY4uHezBTjs6Vl4PbqQQeu6oION1w2voYZv9yquCw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.40.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.40.1.tgz", + "integrity": "sha512-VWXGISWFY18v/0JyNUy4A46KCFCb9NVsH+1100XP31lud+TzlezBbz24CYzbnA4x6w4hx+NYCXDfnvDVO6lcAA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.40.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.40.1.tgz", + "integrity": "sha512-nIwkXafAI1/QCS7pxSpv/ZtFW6TXcNUEHAIA9EIyw5OzxJZQ1YDrX+CL6JAIQgZ33CInl1R6mHet9Y/UZTg2Bw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.40.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.40.1.tgz", + "integrity": "sha512-BdrLJ2mHTrIYdaS2I99mriyJfGGenSaP+UwGi1kB9BLOCu9SR8ZpbkmmalKIALnRw24kM7qCN0IOm6L0S44iWw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.40.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.40.1.tgz", + "integrity": "sha512-VXeo/puqvCG8JBPNZXZf5Dqq7BzElNJzHRRw3vjBE27WujdzuOPecDPc/+1DcdcTptNBep3861jNq0mYkT8Z6Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.40.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.40.1.tgz", + "integrity": "sha512-ehSKrewwsESPt1TgSE/na9nIhWCosfGSFqv7vwEtjyAqZcvbGIg4JAcV7ZEh2tfj/IlfBeZjgOXm35iOOjadcg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.40.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.40.1.tgz", + "integrity": "sha512-m39iO/aaurh5FVIu/F4/Zsl8xppd76S4qoID8E+dSRQvTyZTOI2gVk3T4oqzfq1PtcvOfAVlwLMK3KRQMaR8lg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.40.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.40.1.tgz", + "integrity": "sha512-Y+GHnGaku4aVLSgrT0uWe2o2Rq8te9hi+MwqGF9r9ORgXhmHK5Q71N757u0F8yU1OIwUIFy6YiJtKjtyktk5hg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.40.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.40.1.tgz", + "integrity": "sha512-jEwjn3jCA+tQGswK3aEWcD09/7M5wGwc6+flhva7dsQNRZZTe30vkalgIzV4tjkopsTS9Jd7Y1Bsj6a4lzz8gQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loongarch64-gnu": { + "version": "4.40.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.40.1.tgz", + "integrity": "sha512-ySyWikVhNzv+BV/IDCsrraOAZ3UaC8SZB67FZlqVwXwnFhPihOso9rPOxzZbjp81suB1O2Topw+6Ug3JNegejQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.40.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.40.1.tgz", + "integrity": "sha512-BvvA64QxZlh7WZWqDPPdt0GH4bznuL6uOO1pmgPnnv86rpUpc8ZxgZwcEgXvo02GRIZX1hQ0j0pAnhwkhwPqWg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.40.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.40.1.tgz", + "integrity": "sha512-EQSP+8+1VuSulm9RKSMKitTav89fKbHymTf25n5+Yr6gAPZxYWpj3DzAsQqoaHAk9YX2lwEyAf9S4W8F4l3VBQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.40.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.40.1.tgz", + "integrity": "sha512-n/vQ4xRZXKuIpqukkMXZt9RWdl+2zgGNx7Uda8NtmLJ06NL8jiHxUawbwC+hdSq1rrw/9CghCpEONor+l1e2gA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.40.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.40.1.tgz", + "integrity": "sha512-h8d28xzYb98fMQKUz0w2fMc1XuGzLLjdyxVIbhbil4ELfk5/orZlSTpF/xdI9C8K0I8lCkq+1En2RJsawZekkg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.40.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.40.1.tgz", + "integrity": "sha512-XiK5z70PEFEFqcNj3/zRSz/qX4bp4QIraTy9QjwJAb/Z8GM7kVUsD0Uk8maIPeTyPCP03ChdI+VVmJriKYbRHQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.40.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.40.1.tgz", + "integrity": "sha512-2BRORitq5rQ4Da9blVovzNCMaUlyKrzMSvkVR0D4qPuOy/+pMCrh1d7o01RATwVy+6Fa1WBw+da7QPeLWU/1mQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.40.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.40.1.tgz", + "integrity": "sha512-b2bcNm9Kbde03H+q+Jjw9tSfhYkzrDUf2d5MAd1bOJuVplXvFhWz7tRtWvD8/ORZi7qSCy0idW6tf2HgxSXQSg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.40.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.40.1.tgz", + "integrity": "sha512-DfcogW8N7Zg7llVEfpqWMZcaErKfsj9VvmfSyRjCyo4BI3wPEfrzTtJkZG6gKP/Z92wFm6rz2aDO7/JfiR/whA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.40.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.40.1.tgz", + "integrity": "sha512-ECyOuDeH3C1I8jH2MK1RtBJW+YPMvSfT0a5NN0nHfQYnDSJ6tUiZH3gzwVP5/Kfh/+Tt7tpWVF9LXNTnhTJ3kA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.7.tgz", + "integrity": "sha512-dkO5fhS7+/oos4ciWxyEyjWe48zmG6wbCheo/G2ZnHx4fs3EU6YC6UM8rk56gAjNJ9P3MTH2jo5jb92/K6wbng==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.20.7" + } + }, + "node_modules/@types/estree": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz", + "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/react": { + "version": "19.1.2", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.2.tgz", + "integrity": "sha512-oxLPMytKchWGbnQM9O7D67uPa9paTNxO7jVoNMXgkkErULBPhPARCfkKL9ytcIJJRGjbsVwW4ugJzyFFvm/Tiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "19.1.2", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.1.2.tgz", + "integrity": "sha512-XGJkWF41Qq305SKWEILa1O8vzhb3aOo3ogBlSmiqNko/WmRb6QIaweuZCXjKygVDXpzXb5wyxKTSOsmkuqj+Qw==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^19.0.0" + } + }, + "node_modules/@vitejs/plugin-react": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.4.1.tgz", + "integrity": "sha512-IpEm5ZmeXAP/osiBXVVP5KjFMzbWOonMs0NaQQl+xYnUAcq4oHUBsF2+p4MgKWG4YMmFYJU8A6sxRPuowllm6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.26.10", + "@babel/plugin-transform-react-jsx-self": "^7.25.9", + "@babel/plugin-transform-react-jsx-source": "^7.25.9", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.17.0" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0" + } + }, + "node_modules/acorn": { + "version": "8.14.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz", + "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/browserslist": { + "version": "4.24.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz", + "integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "caniuse-lite": "^1.0.30001688", + "electron-to-chromium": "^1.5.73", + "node-releases": "^2.0.19", + "update-browserslist-db": "^1.1.1" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001715", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001715.tgz", + "integrity": "sha512-7ptkFGMm2OAOgvZpwgA4yjQ5SQbrNVGdRjzH0pBdy1Fasvcr+KAeECmbCAECzTuDuoX0FCY8KzUxjf9+9kfZEw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/cookie": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz", + "integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/css-mediaquery": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/css-mediaquery/-/css-mediaquery-0.1.2.tgz", + "integrity": "sha512-COtn4EROW5dBGlE/4PiKnh6rZpAPxDeFLaEEwt4i10jpDMFt2EhQGS79QmmrO+iKCHv0PU/HrOWEhijFd1x99Q==", + "license": "BSD" + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "dev": true, + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/electron-to-chromium": { + "version": "1.5.144", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.144.tgz", + "integrity": "sha512-eJIaMRKeAzxfBSxtjYnoIAw/tdD6VIH6tHBZepZnAbE3Gyqqs5mGN87DvcldPUbVkIljTK8pY0CMcUljP64lfQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/esbuild": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.3.tgz", + "integrity": "sha512-qKA6Pvai73+M2FtftpNKRxJ78GIjmFXFxd/1DVBqGo/qNhLSfv+G12n9pNoWdytJC8U00TrViOwpjT0zgqQS8Q==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.3", + "@esbuild/android-arm": "0.25.3", + "@esbuild/android-arm64": "0.25.3", + "@esbuild/android-x64": "0.25.3", + "@esbuild/darwin-arm64": "0.25.3", + "@esbuild/darwin-x64": "0.25.3", + "@esbuild/freebsd-arm64": "0.25.3", + "@esbuild/freebsd-x64": "0.25.3", + "@esbuild/linux-arm": "0.25.3", + "@esbuild/linux-arm64": "0.25.3", + "@esbuild/linux-ia32": "0.25.3", + "@esbuild/linux-loong64": "0.25.3", + "@esbuild/linux-mips64el": "0.25.3", + "@esbuild/linux-ppc64": "0.25.3", + "@esbuild/linux-riscv64": "0.25.3", + "@esbuild/linux-s390x": "0.25.3", + "@esbuild/linux-x64": "0.25.3", + "@esbuild/netbsd-arm64": "0.25.3", + "@esbuild/netbsd-x64": "0.25.3", + "@esbuild/openbsd-arm64": "0.25.3", + "@esbuild/openbsd-x64": "0.25.3", + "@esbuild/sunos-x64": "0.25.3", + "@esbuild/win32-arm64": "0.25.3", + "@esbuild/win32-ia32": "0.25.3", + "@esbuild/win32-x64": "0.25.3" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "9.25.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.25.1.tgz", + "integrity": "sha512-E6Mtz9oGQWDCpV12319d59n4tx9zOTXSTmc8BLVxBx+G/0RdM5MvEEJLU9c0+aleoePYYgVTOsRblx433qmhWQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.20.0", + "@eslint/config-helpers": "^0.2.1", + "@eslint/core": "^0.13.0", + "@eslint/eslintrc": "^3.3.1", + "@eslint/js": "9.25.1", + "@eslint/plugin-kit": "^0.2.8", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.3.0", + "eslint-visitor-keys": "^4.2.0", + "espree": "^10.3.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.2.0.tgz", + "integrity": "sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0" + } + }, + "node_modules/eslint-plugin-react-refresh": { + "version": "0.4.20", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.20.tgz", + "integrity": "sha512-XpbHQ2q5gUF8BGOX4dHe+71qoirYMhApEPZ7sfhF/dNnOF1UXnCMGZf79SFTBO7Bz5YEIT4TMieSlJBWhP9WBA==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "eslint": ">=8.40" + } + }, + "node_modules/eslint-scope": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.3.0.tgz", + "integrity": "sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", + "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.14.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fdir": { + "version": "6.4.4", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.4.tgz", + "integrity": "sha512-1NZP+GK4GfuAv3PqKvxQRDMjdSRZjnkq7KfhlNrCNNlZ0ygQFpebfrnfnq/W7fpUnAv9aGWmY1zKx7FYL3gwhg==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "dev": true, + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-16.0.0.tgz", + "integrity": "sha512-iInW14XItCXET01CQFqudPOWP2jYMl7T+QRQT+UNcR/iQncN/F0UNpgd76iFkBPgNQb4+X3LV9tLJYzwh+Gl3A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/hyphenate-style-name": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.1.0.tgz", + "integrity": "sha512-WDC/ui2VVRrz3jOVi+XtjqkDjiVjTtFaAGiW37k6b+ohyQ5wYDOGkvCZa8+H0nx3gyvv0+BST9xuOgIyGQ00gw==", + "license": "BSD-3-Clause" + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/matchmediaquery": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/matchmediaquery/-/matchmediaquery-0.4.2.tgz", + "integrity": "sha512-wrZpoT50ehYOudhDjt/YvUJc6eUzcdFPdmbizfgvswCKNHD1/OBOHYJpHie+HXpu6bSkEGieFMYk6VuutaiRfA==", + "license": "MIT", + "dependencies": { + "css-mediaquery": "^0.1.2" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-releases": { + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", + "dev": true, + "license": "MIT" + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.3", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz", + "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.8", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/react": { + "version": "19.1.0", + "resolved": "https://registry.npmjs.org/react/-/react-19.1.0.tgz", + "integrity": "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "19.1.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz", + "integrity": "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==", + "license": "MIT", + "dependencies": { + "scheduler": "^0.26.0" + }, + "peerDependencies": { + "react": "^19.1.0" + } + }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "license": "MIT" + }, + "node_modules/react-refresh": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz", + "integrity": "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-responsive": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/react-responsive/-/react-responsive-10.0.1.tgz", + "integrity": "sha512-OM5/cRvbtUWEX8le8RCT8scA8y2OPtb0Q/IViEyCEM5FBN8lRrkUOZnu87I88A6njxDldvxG+rLBxWiA7/UM9g==", + "license": "MIT", + "dependencies": { + "hyphenate-style-name": "^1.0.0", + "matchmediaquery": "^0.4.2", + "prop-types": "^15.6.1", + "shallow-equal": "^3.1.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/react-router": { + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.5.3.tgz", + "integrity": "sha512-3iUDM4/fZCQ89SXlDa+Ph3MevBrozBAI655OAfWQlTm9nBR0IKlrmNwFow5lPHttbwvITZfkeeeZFP6zt3F7pw==", + "license": "MIT", + "dependencies": { + "cookie": "^1.0.1", + "set-cookie-parser": "^2.6.0", + "turbo-stream": "2.4.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + } + } + }, + "node_modules/react-router-dom": { + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.5.3.tgz", + "integrity": "sha512-cK0jSaTyW4jV9SRKAItMIQfWZ/D6WEZafgHuuCb9g+SjhLolY78qc+De4w/Cz9ybjvLzShAmaIMEXt8iF1Cm+A==", + "license": "MIT", + "dependencies": { + "react-router": "7.5.3" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/rollup": { + "version": "4.40.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.40.1.tgz", + "integrity": "sha512-C5VvvgCCyfyotVITIAv+4efVytl5F7wt+/I2i9q9GZcEXW9BP52YYOXC58igUi+LFZVHukErIIqQSWwv/M3WRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.7" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.40.1", + "@rollup/rollup-android-arm64": "4.40.1", + "@rollup/rollup-darwin-arm64": "4.40.1", + "@rollup/rollup-darwin-x64": "4.40.1", + "@rollup/rollup-freebsd-arm64": "4.40.1", + "@rollup/rollup-freebsd-x64": "4.40.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.40.1", + "@rollup/rollup-linux-arm-musleabihf": "4.40.1", + "@rollup/rollup-linux-arm64-gnu": "4.40.1", + "@rollup/rollup-linux-arm64-musl": "4.40.1", + "@rollup/rollup-linux-loongarch64-gnu": "4.40.1", + "@rollup/rollup-linux-powerpc64le-gnu": "4.40.1", + "@rollup/rollup-linux-riscv64-gnu": "4.40.1", + "@rollup/rollup-linux-riscv64-musl": "4.40.1", + "@rollup/rollup-linux-s390x-gnu": "4.40.1", + "@rollup/rollup-linux-x64-gnu": "4.40.1", + "@rollup/rollup-linux-x64-musl": "4.40.1", + "@rollup/rollup-win32-arm64-msvc": "4.40.1", + "@rollup/rollup-win32-ia32-msvc": "4.40.1", + "@rollup/rollup-win32-x64-msvc": "4.40.1", + "fsevents": "~2.3.2" + } + }, + "node_modules/scheduler": { + "version": "0.26.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz", + "integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==", + "license": "MIT" + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/set-cookie-parser": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz", + "integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==", + "license": "MIT" + }, + "node_modules/shallow-equal": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/shallow-equal/-/shallow-equal-3.1.0.tgz", + "integrity": "sha512-pfVOw8QZIXpMbhBWvzBISicvToTiM5WBF1EeAUZDDSb5Dt29yl4AYbyywbJFSEsRUMr7gJaxqCdr4L3tQf9wVg==", + "license": "MIT" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.13.tgz", + "integrity": "sha512-mEwzpUgrLySlveBwEVDMKk5B57bhLPYovRfPAXD5gA/98Opn0rCDj3GtLwFvCvH5RK9uPCExUROW5NjDwvqkxw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.4.4", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/turbo-stream": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/turbo-stream/-/turbo-stream-2.4.0.tgz", + "integrity": "sha512-FHncC10WpBd2eOmGwpmQsWLDoK4cqsA/UT/GqNoaKOQnT8uzhtCbg3EoUDMvqpOSAI0S26mr0rkjzbOO6S3v1g==", + "license": "ISC" + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", + "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/vite": { + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.3.3.tgz", + "integrity": "sha512-5nXH+QsELbFKhsEfWLkHrvgRpTdGJzqOZ+utSdmPTvwHmvU6ITTm3xx+mRusihkcI8GeC7lCDyn3kDtiki9scw==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.25.0", + "fdir": "^6.4.4", + "picomatch": "^4.0.2", + "postcss": "^8.5.3", + "rollup": "^4.34.9", + "tinyglobby": "^0.2.13" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "jiti": ">=1.21.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 00000000..4796bcc1 --- /dev/null +++ b/package.json @@ -0,0 +1,30 @@ +{ + "name": "mission5", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build", + "lint": "eslint .", + "preview": "vite preview" + }, + "dependencies": { + "react": "^19.0.0", + "react-dom": "^19.0.0", + "react-responsive": "^10.0.1", + "react-router": "^7.5.3", + "react-router-dom": "^7.5.3" + }, + "devDependencies": { + "@eslint/js": "^9.22.0", + "@types/react": "^19.0.10", + "@types/react-dom": "^19.0.4", + "@vitejs/plugin-react": "^4.3.4", + "eslint": "^9.22.0", + "eslint-plugin-react-hooks": "^5.2.0", + "eslint-plugin-react-refresh": "^0.4.19", + "globals": "^16.0.0", + "vite": "^6.3.1" + } +} diff --git a/images/Img_home_01/Img_home_01@0.5x.png b/public/images/Img_home_01/Img_home_01@0.5x.png similarity index 100% rename from images/Img_home_01/Img_home_01@0.5x.png rename to public/images/Img_home_01/Img_home_01@0.5x.png diff --git a/images/Img_home_01/Img_home_01@1.5x.png b/public/images/Img_home_01/Img_home_01@1.5x.png similarity index 100% rename from images/Img_home_01/Img_home_01@1.5x.png rename to public/images/Img_home_01/Img_home_01@1.5x.png diff --git a/images/Img_home_01/Img_home_01@1x.png b/public/images/Img_home_01/Img_home_01@1x.png similarity index 100% rename from images/Img_home_01/Img_home_01@1x.png rename to public/images/Img_home_01/Img_home_01@1x.png diff --git a/images/Img_home_01/Img_home_01@2x.png b/public/images/Img_home_01/Img_home_01@2x.png similarity index 100% rename from images/Img_home_01/Img_home_01@2x.png rename to public/images/Img_home_01/Img_home_01@2x.png diff --git a/images/Img_home_02/Img_home_02@0.5x.png b/public/images/Img_home_02/Img_home_02@0.5x.png similarity index 100% rename from images/Img_home_02/Img_home_02@0.5x.png rename to public/images/Img_home_02/Img_home_02@0.5x.png diff --git a/images/Img_home_02/Img_home_02@1.5x.png b/public/images/Img_home_02/Img_home_02@1.5x.png similarity index 100% rename from images/Img_home_02/Img_home_02@1.5x.png rename to public/images/Img_home_02/Img_home_02@1.5x.png diff --git a/images/Img_home_02/Img_home_02@1x.png b/public/images/Img_home_02/Img_home_02@1x.png similarity index 100% rename from images/Img_home_02/Img_home_02@1x.png rename to public/images/Img_home_02/Img_home_02@1x.png diff --git a/images/Img_home_02/Img_home_02@2x.png b/public/images/Img_home_02/Img_home_02@2x.png similarity index 100% rename from images/Img_home_02/Img_home_02@2x.png rename to public/images/Img_home_02/Img_home_02@2x.png diff --git a/images/Img_home_03/Img_home_03@0.5x.png b/public/images/Img_home_03/Img_home_03@0.5x.png similarity index 100% rename from images/Img_home_03/Img_home_03@0.5x.png rename to public/images/Img_home_03/Img_home_03@0.5x.png diff --git a/images/Img_home_03/Img_home_03@1.5x.png b/public/images/Img_home_03/Img_home_03@1.5x.png similarity index 100% rename from images/Img_home_03/Img_home_03@1.5x.png rename to public/images/Img_home_03/Img_home_03@1.5x.png diff --git a/images/Img_home_03/Img_home_03@1x.png b/public/images/Img_home_03/Img_home_03@1x.png similarity index 100% rename from images/Img_home_03/Img_home_03@1x.png rename to public/images/Img_home_03/Img_home_03@1x.png diff --git a/images/Img_home_03/Img_home_03@2x.png b/public/images/Img_home_03/Img_home_03@2x.png similarity index 100% rename from images/Img_home_03/Img_home_03@2x.png rename to public/images/Img_home_03/Img_home_03@2x.png diff --git a/images/Img_home_bottom/Img_home_bottom@0.5x.png b/public/images/Img_home_bottom/Img_home_bottom@0.5x.png similarity index 100% rename from images/Img_home_bottom/Img_home_bottom@0.5x.png rename to public/images/Img_home_bottom/Img_home_bottom@0.5x.png diff --git a/images/Img_home_bottom/Img_home_bottom@1.5x.png b/public/images/Img_home_bottom/Img_home_bottom@1.5x.png similarity index 100% rename from images/Img_home_bottom/Img_home_bottom@1.5x.png rename to public/images/Img_home_bottom/Img_home_bottom@1.5x.png diff --git a/images/Img_home_bottom/Img_home_bottom@1x.png b/public/images/Img_home_bottom/Img_home_bottom@1x.png similarity index 100% rename from images/Img_home_bottom/Img_home_bottom@1x.png rename to public/images/Img_home_bottom/Img_home_bottom@1x.png diff --git a/images/Img_home_bottom/Img_home_bottom@2x.png b/public/images/Img_home_bottom/Img_home_bottom@2x.png similarity index 100% rename from images/Img_home_bottom/Img_home_bottom@2x.png rename to public/images/Img_home_bottom/Img_home_bottom@2x.png diff --git a/images/Img_home_top/Img_home_top@0.5x.png b/public/images/Img_home_top/Img_home_top@0.5x.png similarity index 100% rename from images/Img_home_top/Img_home_top@0.5x.png rename to public/images/Img_home_top/Img_home_top@0.5x.png diff --git a/images/Img_home_top/Img_home_top@1.5x.png b/public/images/Img_home_top/Img_home_top@1.5x.png similarity index 100% rename from images/Img_home_top/Img_home_top@1.5x.png rename to public/images/Img_home_top/Img_home_top@1.5x.png diff --git a/images/Img_home_top/Img_home_top@1x.png b/public/images/Img_home_top/Img_home_top@1x.png similarity index 100% rename from images/Img_home_top/Img_home_top@1x.png rename to public/images/Img_home_top/Img_home_top@1x.png diff --git a/images/Img_home_top/Img_home_top@2x.png b/public/images/Img_home_top/Img_home_top@2x.png similarity index 100% rename from images/Img_home_top/Img_home_top@2x.png rename to public/images/Img_home_top/Img_home_top@2x.png diff --git "a/images/\355\214\220\353\213\244 \354\226\274\352\265\264.png" b/public/images/Img_logo.png similarity index 100% rename from "images/\355\214\220\353\213\244 \354\226\274\352\265\264.png" rename to public/images/Img_logo.png diff --git a/images/Img_openGraph.png b/public/images/Img_openGraph.png similarity index 100% rename from images/Img_openGraph.png rename to public/images/Img_openGraph.png diff --git a/public/images/ic_arrow_down.png b/public/images/ic_arrow_down.png new file mode 100644 index 00000000..a8613b0f Binary files /dev/null and b/public/images/ic_arrow_down.png differ diff --git a/images/ic_facebook.png b/public/images/ic_facebook.png similarity index 100% rename from images/ic_facebook.png rename to public/images/ic_facebook.png diff --git a/images/ic_instagram.png b/public/images/ic_instagram.png similarity index 100% rename from images/ic_instagram.png rename to public/images/ic_instagram.png diff --git a/public/images/ic_nextPageClick_active.png b/public/images/ic_nextPageClick_active.png new file mode 100644 index 00000000..998d93a5 Binary files /dev/null and b/public/images/ic_nextPageClick_active.png differ diff --git a/public/images/ic_nextPageClick_inactive.png b/public/images/ic_nextPageClick_inactive.png new file mode 100644 index 00000000..44d6b715 Binary files /dev/null and b/public/images/ic_nextPageClick_inactive.png differ diff --git a/public/images/ic_prevPageClick_active.png b/public/images/ic_prevPageClick_active.png new file mode 100644 index 00000000..be9c1f15 Binary files /dev/null and b/public/images/ic_prevPageClick_active.png differ diff --git a/public/images/ic_prevPageClick_inactive.png b/public/images/ic_prevPageClick_inactive.png new file mode 100644 index 00000000..73b832f3 Binary files /dev/null and b/public/images/ic_prevPageClick_inactive.png differ diff --git a/public/images/ic_search.png b/public/images/ic_search.png new file mode 100644 index 00000000..5f98a65a Binary files /dev/null and b/public/images/ic_search.png differ diff --git a/public/images/ic_sort.png b/public/images/ic_sort.png new file mode 100644 index 00000000..9809c813 Binary files /dev/null and b/public/images/ic_sort.png differ diff --git a/images/ic_twitter.png b/public/images/ic_twitter.png similarity index 100% rename from images/ic_twitter.png rename to public/images/ic_twitter.png diff --git a/images/ic_youtube.png b/public/images/ic_youtube.png similarity index 100% rename from images/ic_youtube.png rename to public/images/ic_youtube.png diff --git a/images/icon_google.png b/public/images/icon_google.png similarity index 100% rename from images/icon_google.png rename to public/images/icon_google.png diff --git a/images/icon_kakao.png b/public/images/icon_kakao.png similarity index 100% rename from images/icon_kakao.png rename to public/images/icon_kakao.png diff --git a/images/icon_password_invisible.png b/public/images/icon_password_invisible.png similarity index 100% rename from images/icon_password_invisible.png rename to public/images/icon_password_invisible.png diff --git a/images/icon_password_visible.png b/public/images/icon_password_visible.png similarity index 100% rename from images/icon_password_visible.png rename to public/images/icon_password_visible.png diff --git a/public/images/icon_profile.png b/public/images/icon_profile.png new file mode 100644 index 00000000..0844dd1d Binary files /dev/null and b/public/images/icon_profile.png differ diff --git a/public/images/img_favorite_inactive.png b/public/images/img_favorite_inactive.png new file mode 100644 index 00000000..4c192d40 Binary files /dev/null and b/public/images/img_favorite_inactive.png differ diff --git a/public/images/img_items_default_md.png b/public/images/img_items_default_md.png new file mode 100644 index 00000000..3eb7f48e Binary files /dev/null and b/public/images/img_items_default_md.png differ diff --git a/scripts/auth/form_login.js b/scripts/auth/form_login.js deleted file mode 100644 index 5d201a2e..00000000 --- a/scripts/auth/form_login.js +++ /dev/null @@ -1,20 +0,0 @@ -import { validators } from './modules/validators.js'; -import { formEventHandler } from './modules/formEventHandler.js'; - -const form = document.querySelector('#form-login'); -const buttonElement = form.querySelector('.form-btn'); - -const fieldMap = { - email: validators.email, - password: validators.password, -}; - -const onButtonRedirectUrl = 'items.html'; -const formInfoObject = { - form, - buttonElement, - fieldMap, - onButtonRedirectUrl, -}; - -formEventHandler(formInfoObject); diff --git a/scripts/auth/form_signup.js b/scripts/auth/form_signup.js deleted file mode 100644 index 4c0f3497..00000000 --- a/scripts/auth/form_signup.js +++ /dev/null @@ -1,26 +0,0 @@ -import { validators } from './modules/validators.js'; -import { formEventHandler } from './modules/formEventHandler.js'; - -const form = document.querySelector('#form-signup'); -const buttonElement = form.querySelector('.form-btn'); - -const fieldMap = { - email: validators.email, - nickname: validators.nickname, - password: validators.password, - passwordVerify: (passwordVerifyText) => { - const passwordText = form.querySelector('#password .form-input').value; - return validators.passwordVerify(passwordVerifyText, passwordText); - }, -}; - -const onButtonRedirectUrl = 'login.html'; - -const formInfoObject = { - form, - buttonElement, - fieldMap, - onButtonRedirectUrl, -}; - -formEventHandler(formInfoObject); diff --git a/scripts/auth/modules/formEventHandler.js b/scripts/auth/modules/formEventHandler.js deleted file mode 100644 index 42cb6482..00000000 --- a/scripts/auth/modules/formEventHandler.js +++ /dev/null @@ -1,88 +0,0 @@ -export const formEventHandler = ({ - form, - buttonElement, - fieldMap, - onButtonRedirectUrl, -}) => { - const inputState = new Map(Object.keys(fieldMap).map((key) => [key, null])); - - const onInputFocusOut = (stateKey) => { - const validResult = getValidResult(stateKey); - setState(stateKey, validResult); - updateUIByState(stateKey, validResult); - updateButtonState(); - updatePasswordVerify(stateKey); - }; - - const getValidResult = (stateKey) => { - const inputText = form.querySelector(`#${stateKey} .form-input`).value; - const validtorFunction = fieldMap[stateKey]; - return validtorFunction(inputText); - }; - - const setState = (stateKey, validResult) => { - inputState.set(stateKey, validResult.isValid); - }; - - const updateUIByState = (stateKey, validResult) => { - //prettier-ignore - const inputContainerElement = form.querySelector(`#${stateKey} .form-input-container`); - //prettier-ignore - const spanStateElement = form.querySelector(`#${stateKey} .form-status-info`); - spanStateElement.textContent = validResult.message; - if (validResult.isValid) { - inputContainerElement.classList.add('valid'); - inputContainerElement.classList.remove('inValid'); - spanStateElement.classList.add('hidden'); - } else { - inputContainerElement.classList.add('inValid'); - inputContainerElement.classList.remove('valid'); - spanStateElement.classList.remove('hidden'); - } - }; - - const updateButtonState = () => { - //prettier-ignore - buttonElement.disabled = ![...inputState.values()].every((isValid) => isValid); - }; - - const updatePasswordVerify = (stateKey) => { - if ( - stateKey === 'password' && - inputState.get('passwordVerify') !== undefined && - inputState.get('passwordVerify') !== null - ) - onInputFocusOut('passwordVerify'); - }; - - const onButtonClick = (e) => { - e.preventDefault(); - location.href = onButtonRedirectUrl; - }; - - const onPasswordIconToggle = (stateKey, e) => { - const inputElement = form.querySelector(`#${stateKey} .form-input`); - e.target.classList.toggle('hidden'); - if (e.target.classList.contains('hidden')) { - inputElement.type = 'password'; - } else { - inputElement.type = 'text'; - } - }; - - //이벤트 할당 - for (const stateKey in fieldMap) { - const inputElement = form.querySelector(`#${stateKey} .form-input`); - inputElement.addEventListener('focusout', () => onInputFocusOut(stateKey)); - - const passwordIconElement = form.querySelector( - `#${stateKey} .form-icon-password` - ); - if (passwordIconElement) { - passwordIconElement.addEventListener('click', (e) => - onPasswordIconToggle(stateKey, e) - ); - } - } - buttonElement.addEventListener('click', onButtonClick); -}; diff --git a/scripts/auth/modules/validators.js b/scripts/auth/modules/validators.js deleted file mode 100644 index c5cbbb00..00000000 --- a/scripts/auth/modules/validators.js +++ /dev/null @@ -1,27 +0,0 @@ -export const validators = { - email: (emailText) => { - //prettier-ignore - const emailRegex = new RegExp(/^[0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*@[0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*\.[a-zA-Z]{2,3}$/i); - if (!emailText) return { isValid: false, message: '이메일을 입력해주세요' }; - if (emailRegex.test(emailText)) return { isValid: true, message: '' }; - else return { isValid: false, message: '잘못된 이메일 형식입니다' }; - }, - nickname: (nicknameText) => { - if (nicknameText) return { isValid: true, message: '' }; - else return { isValid: false, message: '닉네임을 입력해주세요' }; - }, - password: (passwordText) => { - if (passwordText.length < 8) - return { isValid: false, message: '비밀번호를 8자 이상 입력해주세요' }; - else if (passwordText.length >= 8) return { isValid: true, message: '' }; - }, - passwordVerify: (passwordVerifyText, passwordText) => { - if (passwordVerifyText.length < 8) - return { isValid: false, message: '비밀번호를 8자 이상 입력해주세요' }; - else if (passwordVerifyText.length >= 8) { - if (passwordVerifyText === passwordText) - return { isValid: true, message: '' }; - else return { isValid: false, message: '비밀번호가 일치하지 않습니다' }; - } - }, -}; diff --git a/scripts/package.json b/scripts/package.json deleted file mode 100644 index 3dbc1ca5..00000000 --- a/scripts/package.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "type": "module" -} diff --git a/signup.html b/signup.html deleted file mode 100644 index 6cfc00ec..00000000 --- a/signup.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - - - - - - - 판다 마켓 - 회원가입 - - - - 판다마켓 로고 - 판다마켓 - -
- - - - - -
- - - - - - - -
- - 이미 회원이신가요? - 로그인 - -
- - - diff --git a/src/App.jsx b/src/App.jsx new file mode 100644 index 00000000..eb06a0fd --- /dev/null +++ b/src/App.jsx @@ -0,0 +1,31 @@ +import { BrowserRouter, Routes, Route } from 'react-router-dom'; +import Home from './pages/Home/Home'; +import Login from './pages/Auth/Login'; +import Signup from './pages/Auth/Signup'; +import Items from './pages/Items/Items'; +import Privacy from './pages/Privacy/Privacy'; +import Faq from './pages/Faq/Faq'; +import AddItem from './pages/AddItem/AddItem'; +import { LoginStateProvider } from './contexts/LoginStateContext'; +import Board from './pages/Board/Board'; + +function App() { + return ( + + + + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + + + + ); +} + +export default App; diff --git a/src/apis/api.js b/src/apis/api.js new file mode 100644 index 00000000..3eddfee7 --- /dev/null +++ b/src/apis/api.js @@ -0,0 +1,22 @@ +const BASE_URL = 'https://panda-market-api.vercel.app'; + +export const getItems = async ({ + offset, + pageSize, + orderBy = 'recent', + keyword = '', +}) => { + //pc: 10개, 태블릿: 6개, 모바일: 4개 + //offset이 11이면 : page는? pc: 2, 태블릿: 2, 모바일: 3 + //offset이 8이면 : page는? pc: 1, 태블릿: 2, 모바일: 2 + + const page = Math.ceil(offset / pageSize); + const query = `page=${page}&pageSize=${pageSize}&orderBy=${orderBy}&keyword=${keyword}`; + + const response = await fetch(`${BASE_URL}/products?${query}`); + if (!response.ok) { + throw new Error('품목을 불러오지 못했습니다.'); + } + const body = await response.json(); + return body; +}; diff --git a/styles/common.css b/src/common.css similarity index 54% rename from styles/common.css rename to src/common.css index 6469a9df..7971659d 100644 --- a/styles/common.css +++ b/src/common.css @@ -1,39 +1,10 @@ -body { - font-family: 'Pretendard-Regular'; - margin: 0px; -} -@font-face { - font-family: 'Pretendard-Regular'; - src: url('https://fastly.jsdelivr.net/gh/Project-Noonnu/noonfonts_2107@1.1/Pretendard-Regular.woff') - format('woff'); -} -@font-face { - font-family: 'ROKAFSansMedium'; - src: url('../fonts/rokafsansmedium-normal.woff') format('woff'); -} - :root { - --font-size-xs: 12px; - --font-size-sm: 14px; - --font-size-base: 16px; - --font-size-lg: 18px; - --font-size-xl: 20px; - --font-size-2xl: 24px; - --font-size-3xl: 30px; - - --font-weight-bold: 700; - --font-weight-semi-bold: 600; - --font-weight-medium: 500; - --font-weight-regular: 400; - --font-weight-light: 300; - --color-blue950: #111827; --color-blue600: #1251aa; --color-blue500: #1967d6; --color-blue400: #3692ff; --color-blue200: #cfe5ff; --color-blue100: #e6f2ff; - --color-gray900: #111827; --color-gray800: #1f2937; --color-gray700: #374151; @@ -44,29 +15,41 @@ body { --color-gray200: #f3f4f6; --color-gray100: #f9fafb; --color-gray050: #fcfcfc; - --color-white: #ffffff; - --color-error: #f74747; +} - --border-radius-xs: 8px; - --border-radius-sm: 12px; - --border-radius-lg: 40px; +* { + box-sizing: border-box; } -.btn { - background-color: var(--color-blue400); +body { + background-color: var(--color-gray050); +} + +.button-style { text-decoration: none; - color: var(--color-white); - text-align: center; + display: inline-block; + background-color: var(--color-blue400); + font-weight: 600; + font-family: 'Pretendard'; border: none; - width: 100%; } -.btn:hover { +.button-style:hover { background-color: var(--color-blue500); } -.btn:disabled { +.button-style:disabled { background-color: var(--color-gray400); } + +@font-face { + font-family: 'Pretendard'; + src: url('https://fastly.jsdelivr.net/gh/Project-Noonnu/noonfonts_2107@1.1/Pretendard-Regular.woff') + format('woff'); +} +@font-face { + font-family: 'ROKAFSans'; + src: url('../src/fonts/rokafsansmedium-normal.woff') format('woff'); +} diff --git a/src/contexts/LoginStateContext.jsx b/src/contexts/LoginStateContext.jsx new file mode 100644 index 00000000..45a79710 --- /dev/null +++ b/src/contexts/LoginStateContext.jsx @@ -0,0 +1,28 @@ +import { createContext, useContext, useState } from 'react'; + +const LoginStateContext = createContext(); + +export const LoginStateProvider = ({ children }) => { + const [isLogin, setIsLogin] = useState(false); + return ( + + {children} + + ); +}; + +export const useIsLogin = () => { + const context = useContext(LoginStateContext); + if (!context) { + throw new Error('반드시 LoginStateProvider 안에서 사용해야 합니다'); + } + return context.isLogin; +}; + +export const useSetIsLogin = () => { + const context = useContext(LoginStateContext); + if (!context) { + throw new Error('반드시 LoginStateProvider 안에서 사용해야 합니다'); + } + return context.setIsLogin; +}; diff --git a/fonts/rokafsansmedium-normal.woff b/src/fonts/rokafsansmedium-normal.woff similarity index 100% rename from fonts/rokafsansmedium-normal.woff rename to src/fonts/rokafsansmedium-normal.woff diff --git a/src/hooks/useDeviceType.jsx b/src/hooks/useDeviceType.jsx new file mode 100644 index 00000000..72b9845e --- /dev/null +++ b/src/hooks/useDeviceType.jsx @@ -0,0 +1,21 @@ +import { useEffect, useState } from 'react'; + +export const useDeviceType = () => { + const getDeviceType = (width) => { + if (width >= 1200) return 'lg'; + else if (width >= 768) return 'md'; + else return 'sm'; + }; + + //prettier-ignore + const [deviceType, setDeviceType] = useState(getDeviceType(window.innerWidth)); + + useEffect(() => { + const handleResize = () => setDeviceType(getDeviceType(window.innerWidth)); + window.addEventListener('resize', handleResize); + return () => { + window.removeEventListener('resize', handleResize); + }; + }, []); + return { deviceType }; +}; diff --git a/src/hooks/useFormFields.jsx b/src/hooks/useFormFields.jsx new file mode 100644 index 00000000..b0e52314 --- /dev/null +++ b/src/hooks/useFormFields.jsx @@ -0,0 +1,83 @@ +import { useEffect, useState } from 'react'; + +export const useFormFields = ({ FIELDS }) => { + const createInitialStates = (initialFields, initialValue) => { + const returnFields = {}; + for (const field in initialFields) { + returnFields[field] = initialValue; + } + return returnFields; + }; + + //prettier-ignore + const [values, setValues] = useState(createInitialStates(FIELDS, '')); + //prettier-ignore + const [valids, setValids] = useState(createInitialStates(FIELDS, null)); + //prettier-ignore + const [hints, setHints] = useState(createInitialStates(FIELDS, '')); + //prettier-ignore + const [isVisibles, setIsVisibles] = useState(createInitialStates(FIELDS, false)); + const [isSubmitEnabled, setIsSubmitEnabled] = useState(false); + + useEffect(() => { + setIsSubmitEnabled(Object.values(valids).every((v) => v === true)); + }, [valids]); + + const handleInputChange = (e) => { + const { name, value } = e.target; + updateFieldValues(name, value); + }; + + const handleInputBlur = (e) => { + const { name, value } = e.target; + const validResults = getValidResults(name, value); + updateValidResults(validResults); + }; + + const updateFieldValues = (name, value) => { + setValues((prev) => ({ + ...prev, + [name]: value, + })); + }; + + const getValidResults = (name, value) => { + const validFunction = FIELDS[name]; + return validFunction(value); + }; + + const updateValidResults = (validResults) => { + const nextInputValids = {}; + const nextHints = {}; + for (const validKey in validResults) { + nextInputValids[validKey] = validResults[validKey].isValid; + nextHints[validKey] = validResults[validKey].message; + } + setValids((prev) => ({ + ...prev, + ...nextInputValids, + })); + setHints((prev) => ({ + ...prev, + ...nextHints, + })); + }; + + const handlePasswordIconClick = (name) => { + setIsVisibles((prev) => ({ + ...prev, + [name]: !isVisibles[name], + })); + }; + + return { + values, + valids, + hints, + isVisibles, + isSubmitEnabled, + handleInputChange, + handleInputBlur, + handlePasswordIconClick, + }; +}; diff --git a/src/main.jsx b/src/main.jsx new file mode 100644 index 00000000..393a6f4f --- /dev/null +++ b/src/main.jsx @@ -0,0 +1,4 @@ +import { createRoot } from 'react-dom/client'; +import App from './App'; + +createRoot(document.getElementById('root')).render(); diff --git a/src/modules/debounce.js b/src/modules/debounce.js new file mode 100644 index 00000000..c9dc362e --- /dev/null +++ b/src/modules/debounce.js @@ -0,0 +1,10 @@ +export default function debounce(callback, limit = 100) { + let timeout; // ← 이 변수는 debounce 함수의 '스코프(클로저)'에 저장됨 + + return function (...args) { + clearTimeout(timeout); // ← 클로저에 저장된 timeout 값을 사용 + timeout = setTimeout(() => { + callback.apply(this, args); + }, limit); + }; +} diff --git a/src/modules/formatPrice.js b/src/modules/formatPrice.js new file mode 100644 index 00000000..6fb6374b --- /dev/null +++ b/src/modules/formatPrice.js @@ -0,0 +1,3 @@ +export const formatPriceKRW = (price) => { + return price.toLocaleString('ko-KR') + '원'; +}; diff --git a/src/modules/validators.js b/src/modules/validators.js new file mode 100644 index 00000000..efd03a8a --- /dev/null +++ b/src/modules/validators.js @@ -0,0 +1,54 @@ +export const validators = { + email: (emailText) => { + if (!emailText) + return { email: { isValid: false, message: '이메일을 입력해주세요' } }; + const emailRegex = + /^[0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*@[0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*\.[a-zA-Z]{2,3}$/i; + if (!emailRegex.test(emailText)) + return { email: { isValid: false, message: '잘못된 이메일 형식입니다' } }; + else return { email: { isValid: true, message: '' } }; + }, + nickname: (nicknameText) => { + if (!nicknameText) + return { nickname: { isValid: false, message: '닉네임을 입력해주세요' } }; + else return { nickname: { isValid: true, message: '' } }; + }, + password: (passwordText, passwordVerifyText = '') => { + if (!passwordText) + //prettier-ignore + return { password: { isValid: false, message: '비밀번호를 입력해주세요' }}; + if (passwordText.length < 8) + //prettier-ignore + return { password: { isValid: false, message: '비밀번호를 8자 이상 입력해주세요' }}; + else if (passwordText.length >= 8) { + if (passwordVerifyText === '') + return { password: { isValid: true, message: '' } }; + if (passwordText !== passwordVerifyText) { + return { + password: { isValid: true, message: '' }, + //prettier-ignore + passwordVerify: { isValid: false, message: '비밀번호가 일치하지 않습니다' }, + }; + } else if (passwordText === passwordVerifyText) { + return { + password: { isValid: true, message: '' }, + passwordVerify: { isValid: true, message: '' }, + }; + } + } + }, + passwordVerify: (passwordVerifyText, passwordText) => { + if (!passwordVerifyText) + //prettier-ignore + return { passwordVerify: { isValid: false, message: '비밀번호를 입력해주세요' }}; + else if (passwordVerifyText.length < 8) + //prettier-ignore + return { passwordVerify: { isValid: false, message: '비밀번호 8자 이상 입력해주세요' }}; + else if (passwordVerifyText.length >= 8) { + if (passwordVerifyText !== passwordText) + //prettier-ignore + return { passwordVerify: { isValid: false, message: '비밀번호가 일치하지 않습니다' }}; + else return { passwordVerify: { isValid: true, message: '' } }; + } + }, +}; diff --git a/src/pages/AddItem/AddItem.jsx b/src/pages/AddItem/AddItem.jsx new file mode 100644 index 00000000..daa2c862 --- /dev/null +++ b/src/pages/AddItem/AddItem.jsx @@ -0,0 +1,5 @@ +const AddItem = () => { + return <>; +}; + +export default AddItem; diff --git a/src/pages/Auth/Field.jsx b/src/pages/Auth/Field.jsx new file mode 100644 index 00000000..5aa88bfd --- /dev/null +++ b/src/pages/Auth/Field.jsx @@ -0,0 +1,60 @@ +const Field = ({ + id, + labelText, + placeholder, + ariaLabel, + type = 'text', + autoComplete = 'on', + value, + valid, + hint, + isVisible, + handleInputChange, + handleInputBlur, + handlePasswordIconClick, +}) => { + const inputContainerClassName = () => { + if (valid === null) return ''; + if (valid === false) return 'invalid'; + else return 'valid'; + }; + + const passwordIconClassName = () => { + return isVisible ? '' : 'hidden'; + }; + + const inputType = () => { + return isVisible ? 'text' : type; + }; + + return ( + + ); +}; + +export default Field; diff --git a/src/pages/Auth/FormAuth.css b/src/pages/Auth/FormAuth.css new file mode 100644 index 00000000..1be4e3e6 --- /dev/null +++ b/src/pages/Auth/FormAuth.css @@ -0,0 +1,165 @@ +.page-form { + max-width: 672px; + margin: 0 auto; + padding: 80px 16px; + font-family: 'Pretendard'; + display: flex; + flex-direction: column; +} + +.form-logo-container { + text-decoration: none; + display: flex; + flex-direction: row; + gap: var(--form-logo-container-gap); + align-items: center; + justify-content: center; + height: var(--form-logo-container-height); + margin-bottom: var(--form-logo-container-margin-bottom); +} + +.form-logo-image { + aspect-ratio: 51.76 / 51.94; + width: var(--form-logo-image-width); +} + +.form-logo-text { + font-family: ''; + font-family: 'ROKAFSans'; + font-weight: 700; + font-size: var(--form-logo-text-font-size); + line-height: 100%; + color: var(--color-blue400); +} + +.form-label { + display: flex; + flex-direction: column; + font-weight: 700; + font-size: var(--form-label-font-size); + line-height: 24px; + margin-bottom: var(--form-label-margin-bottom); +} + +.form-input-container { + display: flex; + flex-direction: row; + align-items: center; + padding: 15px 24px; + background-color: var(--color-gray200); + border-radius: 12px; + margin-top: var(--form-input-container-margin-top); + margin-bottom: 8px; +} + +.form-input-container.valid { + border: 1px solid var(--color-blue400); +} +.form-input-container.invalid { + border: 1px solid var(--color-error); +} + +.form-input { + flex-grow: 1; + font-weight: 400; + font-size: 16px; + line-height: 26px; + background-color: var(--color-gray200); + border: none; + outline: none; + color: var(--color-gray800); +} + +.form-input::placeholder { + color: var(--color-gray400); +} + +.form-password-icon { + aspect-ratio: 20.39 / 14; + width: 20.39px; + content: url('./images/icon_password_visible.png'); +} +.form-password-icon.hidden { + aspect-ratio: 20.47 / 18.07; + width: 20.47px; + content: url('./images/icon_password_invisible.png'); +} + +.form-input-hint { + color: var(--color-error); + margin-left: 16px; + font-weight: 600; + font-size: 14px; + line-height: 24px; +} + +.form-input-hint.hidden { + display: none; +} + +#form-submit { + font-weight: 600; + font-size: 20px; + font-size: 20px; + line-height: 32px; + width: 100%; + padding: 12px; + border-radius: 40px; + color: var(--color-gray200); +} + +.form-social-container { + padding: 16px 23px; + border-radius: 8px; + display: flex; + flex-direction: row; + background-color: #e6f2ff; + align-items: center; + gap: 16px; + margin: 24px 0; +} + +.form-social-text { + font-weight: 500; + font-size: 16px; + line-height: 26px; + flex-grow: 1; +} + +.form-hint { + text-align: center; + font-weight: 500; + font-size: 14px; + line-height: 24px; + color: var(--color-gray800); +} + +.form-hint-link { + color: var(--color-blue400); + line-height: 100%; +} + +:root { + --form-logo-text-font-size: 33.17px; + --form-logo-container-margin-bottom: 24px; + --form-logo-image-width: 51.76px; + --form-logo-container-height: 66px; + --form-label-margin-bottom: 16px; + --form-label-font-size: 14px; + --form-logo-container-gap: 11.12px; + --form-input-container-margin-top: 8px; +} + +/* Tablet, PC */ +@media (min-width: 768px) { + :root { + --form-logo-text-font-size: 66.34px; + --form-logo-container-margin-bottom: 40px; + --form-logo-image-width: 103.53px; + --form-logo-container-height: 132px; + --form-label-margin-bottom: 24px; + --form-label-font-size: 18px; + --form-logo-container-gap: 22.24px; + --form-input-container-margin-top: 16px; + } +} diff --git a/src/pages/Auth/Login.jsx b/src/pages/Auth/Login.jsx new file mode 100644 index 00000000..bdd3d801 --- /dev/null +++ b/src/pages/Auth/Login.jsx @@ -0,0 +1,131 @@ +import { Link } from 'react-router-dom'; +import './FormAuth.css'; +import { validators } from '../../modules/validators'; +import { useFormFields } from '../../hooks/useFormFields'; +import { useNavigate } from 'react-router'; +import Field from './Field'; +import { useSetIsLogin } from '../../contexts/LoginStateContext'; + +const Login = () => { + const onSubmitNavigate = useNavigate(); + + const setIsLogin = useSetIsLogin(); + + const FIELDS = { + email: validators.email, + password: validators.password, + }; + + const onSubmitRedirect = (e) => { + e.preventDefault(); + onSubmitNavigate('/items'); + setIsLogin(true); + }; + + const formDataObject = { + FIELDS, + onSubmitRedirect, + }; + + const { + values, + valids, + hints, + isVisibles, + isSubmitEnabled, + handleInputChange, + handleInputBlur, + handlePasswordIconClick, + } = useFormFields(formDataObject); + + return ( + <> +
+ + +

판다마켓

+ +
+ + + + +
+ 간편 로그인하기 + + {'구글 + + + {'카카오 + +
+ + 판다마켓이 처음이신가요?{' '} + + 회원가입 + + +
+ + ); +}; + +export default Login; diff --git a/src/pages/Auth/Signup.jsx b/src/pages/Auth/Signup.jsx new file mode 100644 index 00000000..76629ce5 --- /dev/null +++ b/src/pages/Auth/Signup.jsx @@ -0,0 +1,160 @@ +import { Link } from 'react-router-dom'; +import './FormAuth.css'; +import { validators } from '../../modules/validators'; +import { useFormFields } from '../../hooks/useFormFields'; +import { useNavigate } from 'react-router'; +import Field from './Field'; + +const Signup = () => { + const onSubmitNavigate = useNavigate(); + + const FIELDS = { + email: validators.email, + nickname: validators.nickname, + password: (passwordText) => { + const passwordVerifyText = values.passwordVerify; + return validators.password(passwordText, passwordVerifyText); + }, + passwordVerify: (passwordVerifyText) => { + const passwordText = values.password; + return validators.passwordVerify(passwordVerifyText, passwordText); + }, + }; + const onSubmitRedirect = (e) => { + e.preventDefault(); + onSubmitNavigate('/login'); + }; + const formDataObject = { + FIELDS, + }; + + const { + values, + valids, + hints, + isVisibles, + isSubmitEnabled, + handleInputChange, + handleInputBlur, + handlePasswordIconClick, + } = useFormFields(formDataObject); + + return ( + <> +
+ + +

판다마켓

+ +
+ + + + + + +
+ 간편 로그인하기 + + {'구글 + + + {'카카오 + +
+ + 이미 회원이신가요?{' '} + + 로그인 + + +
+ + ); +}; + +export default Signup; diff --git a/src/pages/Board/Board.jsx b/src/pages/Board/Board.jsx new file mode 100644 index 00000000..cf384939 --- /dev/null +++ b/src/pages/Board/Board.jsx @@ -0,0 +1,11 @@ +import Header from '../components/Header'; + +const Board = () => { + return ( + <> +
+ + ); +}; + +export default Board; diff --git a/src/pages/Faq/Faq.jsx b/src/pages/Faq/Faq.jsx new file mode 100644 index 00000000..16ed36d8 --- /dev/null +++ b/src/pages/Faq/Faq.jsx @@ -0,0 +1,5 @@ +const Faq = () => { + return <>; +}; + +export default Faq; diff --git a/src/pages/Home/Banner.css b/src/pages/Home/Banner.css new file mode 100644 index 00000000..acd095a5 --- /dev/null +++ b/src/pages/Home/Banner.css @@ -0,0 +1,77 @@ +.banner { + background-color: #cfe5ff; +} + +.banner-container { + display: flex; + flex-direction: var(--banner-container-flex-direction); + align-items: center; + gap: var(--banner-container-gap); + padding-top: var(--banner-container-padding-top); + justify-content: center; +} + +.banner-image { + aspect-ratio: 746 / 340; + max-width: 746px; + min-width: 447px; + width: 100%; +} + +.banner-context { + display: flex; + flex-direction: column; + align-items: center; + text-align: center; + gap: 18px; + padding-bottom: 60px; +} + +.banner-title { + color: var(--color-gray700); + font-family: 'Pretendard'; + width: var(--banner-title-width); + font-weight: 700; + font-size: var(--banner-title-font-size); + text-align: var(--banner-title-text-align); + line-height: 140%; + word-break: keep-all; +} + +.banner-button { + max-width: 357px; + width: 100%; + color: var(--color-gray050); + line-height: 26px; + padding: 11px 0; + border-radius: 40px; +} + +:root { + --banner-container-gap: 72px; + --banner-container-flex-direction: column; + --banner-container-padding-top: 48px; + --banner-title-width: 240px; + --banner-title-text-align: center; +} + +/* Tablet */ +@media screen and (min-width: 768px) and (max-width: 1199px) { + :root { + --banner-container-gap: 151px; + --banner-container-flex-direction: column; + --banner-container-padding-top: 84px; + --banner-title-width: 530px; + --banner-title-text-align: center; + } +} +/* PC */ +@media (min-width: 1200px) { + :root { + --banner-container-gap: 7px; + --banner-container-flex-direction: row; + --banner-container-padding-top: 200px; + --banner-title-width: 357px; + --banner-title-text-align: left; + } +} diff --git a/src/pages/Home/BannerBottom.css b/src/pages/Home/BannerBottom.css new file mode 100644 index 00000000..b09362b2 --- /dev/null +++ b/src/pages/Home/BannerBottom.css @@ -0,0 +1,28 @@ +#banner-bottom .banner-image { + aspect-ratio: 746 / 397; + min-width: 373px; +} + +#banner-bottom .banner-container { + gap: var(--banner-bottom-container-gap); + padding-top: var(--banner-bottom-container-padding-top); +} + +:root { + --banner-bottom-container-gap: 71px; + --banner-bottom-container-padding-top: 121px; +} + +/* Tablet */ +@media screen and (min-width: 768px) and (max-width: 1199px) { + :root { + --banner-bottom-container-gap: 157px; + --banner-bottom-container-padding-top: 201px; + } +} +/* PC */ +@media (min-width: 1200px) { + :root { + --banner-bottom-container-gap: 7px; + } +} diff --git a/src/pages/Home/Card.css b/src/pages/Home/Card.css new file mode 100644 index 00000000..2d5b348b --- /dev/null +++ b/src/pages/Home/Card.css @@ -0,0 +1,117 @@ +.card-container { + background-color: var(--color-gray050); + display: flex; + flex-direction: var(--card-container-flex-direction); + justify-content: center; + margin: 0 auto; + gap: var(--card-container-gap); + align-items: var(--card-container-align-items); + width: var(--card-container-width); +} + +.card-container.reverse { + flex-direction: var(--card-container-flex-direction-reverse); + text-align: right; +} + +.card-context { + padding: 0 24px 0 0; +} + +.card-container.reverse .card-context { + padding: 0 0 0 24px; +} + +.card-image { + width: var(--card-image-width); +} + +.card-context-tag { + color: var(--color-blue400); + font-weight: 700; + font-size: var(--card-tag-font-size); + line-height: 26px; + margin-bottom: 8px; +} + +.card-context-title { + color: var(--color-gray700); + font-weight: 700; + font-size: var(--card-title-font-size); + line-height: 32px; + margin-bottom: 16px; + word-break: keep-all; + width: auto; +} + +.card-context-subtitle { + color: var(--color-gray700); + font-weight: 500; + font-size: var(--card-subtitle-font-size); + line-height: 26px; + white-space: nowrap; +} + +:root { + --card-container-flex-direction: column; + --card-container-flex-direction-reverse: column; + --card-image-width: 344px; + --card-container-align-items: stretch; + --card-container-width: auto; + --card-container-gap: 23.24px; +} + +/* Tablet */ +@media screen and (min-width: 768px) and (max-width: 1199px) { + :root { + --card-container-flex-direction: column; + --card-container-flex-direction-reverse: column; + --card-image-width: 696px; + --card-container-align-items: stretch; + --card-container-width: auto; + --card-container-gap: 22.45px; + } + + .card-context-tag { + line-height: 26px; + margin-bottom: 16px; + } + + .card-context-title { + line-height: 42px; + margin-bottom: 24px; + width: auto; + } + + .card-context-subtitle { + line-height: 26px; + } +} +/* PC */ +@media (min-width: 1200px) { + :root { + --card-container-flex-direction: row; + --card-container-flex-direction-reverse: row-reverse; + --card-image-width: 588px; + --card-tag-margin-bottom: 12px; + --card-context-title-margin-bottom: 24px; + --card-container-align-items: center; + --card-container-width: 988px; + --card-container-gap: 64px; + } + + .card-context-tag { + line-height: 26px; + margin-bottom: 12px; + } + + .card-context-title { + line-height: 140%; + margin-bottom: 24px; + width: 293px; + } + + .card-context-subtitle { + line-height: 32px; + } +} diff --git a/src/pages/Home/Cards.css b/src/pages/Home/Cards.css new file mode 100644 index 00000000..276a40bd --- /dev/null +++ b/src/pages/Home/Cards.css @@ -0,0 +1,38 @@ +.page-cards { + background-color: var(--page-cards-background-color); + display: flex; + flex-direction: column; + gap: var(--page-cards-gap); + padding-top: var(--page-cards-padding-top); + padding-bottom: var(--page-cards-padding-bottom); + margin-bottom: var(--page-cards-margin-bottom); +} + +:root { + --page-cards-background-color: var(--color-gray050); + --page-cards-padding-top: 52px; + --page-cards-padding-bottom: 83px; + --page-cards-margin-bottom: 0px; + --page-cards-gap: 40px; +} + +/* Tablet */ +@media screen and (min-width: 768px) and (max-width: 1199px) { + :root { + --page-cards-background-color: var(--color-gray050); + --page-cards-padding-top: 24px; + --page-cards-padding-bottom: 56px; + --page-cards-margin-bottom: 0px; + --page-cards-gap: 52px; + } +} +/* PC */ +@media (min-width: 1200px) { + :root { + --page-cards-background-color: var(--color-white); + --page-cards-padding-top: 138px; + --page-cards-padding-bottom: 138px; + --page-cards-margin-bottom: 138px; + --page-cards-gap: 276px; + } +} diff --git a/src/pages/Home/Footer.css b/src/pages/Home/Footer.css new file mode 100644 index 00000000..0229fae0 --- /dev/null +++ b/src/pages/Home/Footer.css @@ -0,0 +1,64 @@ +.page-footer { + background-color: #111322; + height: 160px; + font-family: 'Pretendard'; +} + +.footer-container { + display: flex; + flex-direction: row; + flex-wrap: wrap-reverse; + justify-content: space-between; + align-items: center; + margin: 0 auto; + padding: 32px var(--footer-container-padding-x); + max-width: 1520px; + row-gap: 60px; +} + +.footer-corporation { + flex-basis: var(--footer-corporation-flex-basis); + color: var(--color-gray050); +} + +.footer-link { + display: flex; + flex-direction: row; + gap: 30px; +} + +.footer-link a { + text-decoration: none; + color: var(--color-gray050); +} + +.footer-social { + display: flex; + flex-direction: row; + gap: 14px; +} + +.footer-social-image { + aspect-ratio: 1/1; +} + +:root { + --footer-corporation-flex-basis: 100%; + --footer-container-padding-x: 32px; +} + +/* Tablet */ +@media screen and (min-width: 768px) and (max-width: 1199px) { + :root { + --footer-corporation-flex-basis: auto; + --footer-container-padding-x: 104px; + } +} + +/* PC */ +@media (min-width: 1200px) { + :root { + --footer-corporation-flex-basis: auto; + --footer-container-padding-x: 200px; + } +} diff --git a/src/pages/Home/Home.css b/src/pages/Home/Home.css new file mode 100644 index 00000000..e69de29b diff --git a/src/pages/Home/Home.jsx b/src/pages/Home/Home.jsx new file mode 100644 index 00000000..d2f2585d --- /dev/null +++ b/src/pages/Home/Home.jsx @@ -0,0 +1,166 @@ +import { Link } from 'react-router-dom'; +import './Banner.css'; +import './Main.css'; +import './Cards.css'; +import './Card.css'; +import './BannerBottom.css'; +import './Footer.css'; +import Header from '../components/Header'; + +const Home = () => { + return ( + <> +
+
+
+
+
+

일상의 모든 물건을 거래해 보세요

+ + 구경하러 가기 + +
+ 판다마켓 중고거래 +
+
+
+
+ +
+

Hot item

+

+ {'인기 상품을 확인해 보세요'} +

+

+ 가장 HOT한 중고거래 물품을 +
+ 판다 마켓에서 확인해 보세요 +

+
+
+
+ +
+

Search

+

+ 구매를 원하는 상품을 검색하세요 +

+

+ 구매하고 싶은 물품을 검색해서 +
+ 쉽게 찾아보세요 +

+
+
+
+ +
+

Register

+

+ 판매를 원하는 상품을 등록하세요 +

+

+ 어떤 물건이든 판매하고 싶은 상품을 +
+ 쉽게 등록하세요 +

+
+
+
+ +
+ + + ); +}; + +export default Home; diff --git a/src/pages/Home/Main.css b/src/pages/Home/Main.css new file mode 100644 index 00000000..d4b6af72 --- /dev/null +++ b/src/pages/Home/Main.css @@ -0,0 +1,13 @@ +.page-main { + background-color: var(--color-gray050); + font-family: 'Pretendard'; +} +/* 폰트 반응형 스타일 적용 */ +@supports (font-size: clamp(1rem, 2vw, 3rem)) { + :root { + --banner-title-font-size: clamp(32px, 5vw, 40px); + --card-tag-font-size: clamp(16px, 2.3438vw, 18px); + --card-title-font-size: clamp(24px, 3.3vw, 40px); + --card-subtitle-font-size: clamp(16px, 2vw, 24px); + } +} diff --git a/src/pages/Items/Header.css b/src/pages/Items/Header.css new file mode 100644 index 00000000..97afd9dd --- /dev/null +++ b/src/pages/Items/Header.css @@ -0,0 +1,78 @@ +.page-header { + border-bottom: 1px solid #dfdfdf; +} + +.nav-container { + max-width: 1520px; + height: 70px; + display: flex; + flex-direction: row; + align-items: center; + padding: 0 var(--nav-padding-x); + margin: 0 auto; + gap: 32px; +} + +.nav-logo-container { + text-decoration: none; + display: flex; + flex-direction: row; + gap: 8.59px; + align-items: center; +} + +.nav-logo-img { + aspect-ratio: 40 / 40.14; + display: var(--display-logo-img); +} + +.nav-logo-text { + font-weight: 700; + font-size: 25.63px; + line-height: 100%; + color: var(--color-blue400); + font-family: 'ROKAFSans'; +} + +.nav-link-container { + display: flex; + flex-direction: row; + flex-grow: 1; +} + +.nav-link { + display: inline-block; + padding: 21px 15px; + text-decoration: none; + color: var(--color-gray600); + font-weight: 600; + font-size: 18px; + line-height: 26px; +} + +.nav-button { + border-radius: 8px; + padding: 12px 43px; + line-height: 26px; + color: var(--color-gray100); +} + +:root { + --nav-padding-x: 16px; + --display-logo-img: none; +} + +/* Tablet */ +@media screen and (min-width: 768px) and (max-width: 1199px) { + :root { + --nav-padding-x: 24px; + --display-logo-img: inline; + } +} +/* PC */ +@media (min-width: 1200px) { + :root { + --nav-padding-x: 200px; + --display-logo-img: inline; + } +} diff --git a/src/pages/Items/Items.css b/src/pages/Items/Items.css new file mode 100644 index 00000000..abb065b8 --- /dev/null +++ b/src/pages/Items/Items.css @@ -0,0 +1,294 @@ +.items-page-main { + background-color: var(--color-gray050); + display: flex; + flex-direction: column; + padding-top: var(--items-main-page-padding-top); + gap: 40px; +} + +.cards-section { + display: flex; + flex-direction: column; + max-width: 1250px; + width: 100%; + margin: 0 auto; + padding: 0 24px; +} + +#cards-best { + gap: 16px; +} + +#cards-all { + gap: 24px; +} + +.section-header-container { + display: flex; + flex-direction: row; + justify-content: space-between; + gap: 12px; + align-items: center; + /* height: 42px; */ + flex-wrap: wrap; +} + +.section-title { + font-weight: 700; + font-size: 20px; + line-height: 32px; + color: var(--color-gray900); + flex-grow: 1; + order: var(--search-title-order); + min-width: 200px; +} + +.search-input-container { + display: flex; + flex-direction: row; + align-items: center; + background-color: var(--color-gray200); + width: var(--search-input-container-width); + padding: 0 9px; + height: 42px; + border-radius: 12px; + order: var(--search-input-order); + flex-grow: var(--search-input-flex-grow); +} + +.search-input-icon { + aspect-ratio: 1/1; +} + +.search-input { + border: none; + background-color: var(--color-gray200); + flex-grow: 1; + font-weight: 400; + font-size: 16px; + line-height: 26px; + outline: none; +} + +.search-input::placeholder { + color: var(--color-gray400); +} + +.search-submit { + border-radius: 8px; + font-weight: 600; + font-size: 16px; + line-height: 26px; + padding: 0 23px; + color: var(--color-gray100); + height: 42px; + order: var(--search-submit-order); +} + +.search-select { + width: var(--search-select-width); + padding: 0 20px; + border-radius: 12px; + border: 1px solid var(--color-gray300); + appearance: none; /* 기본 브라우저 UI 제거 */ + -webkit-appearance: none; + -moz-appearance: none; + background-image: var(--search-select-image); + background-repeat: no-repeat; + background-position: var(--search-select-image-position); + background-size: 24px; + color: var(--color-gray800); + font-weight: 400; + font-size: 16px; + line-height: 26px; + height: 42px; + order: var(--search-select-order); +} + +.items-container { + display: grid; + row-gap: 40px; +} + +.item-container { + display: flex; + flex-direction: column; + gap: 16px; + flex-grow: 1; + width: 100%; +} + +#cards-best .items-container { + column-gap: 0; + grid-template-columns: repeat(1, 1fr); + grid-template-rows: repeat(1, 1fr); +} +#cards-all .items-container { + column-gap: 8px; + grid-template-columns: repeat(2, 1fr); + grid-template-rows: repeat(2, 1fr); +} + +.item-context { + display: flex; + flex-direction: column; + gap: 6px; +} + +.item-image { + aspect-ratio: 1/1; + width: 100%; + border-radius: 16px; +} + +.item-title { + font-weight: 500; + font-size: 14px; + line-height: 24px; +} +.item-price { + font-weight: 700; + font-size: 16px; + line-height: 26px; +} + +.item-favorite-container { + display: flex; + flex-direction: row; + align-items: center; + gap: 3.35px; +} + +.item-favorite-image { + aspect-ratio: 1/1; + width: 16px; +} + +.item-favorite-count { + font-weight: 500; + font-size: 12px; + line-height: 18px; +} + +.items-pagination { + display: flex; + flex-direction: row; + padding-top: var(--items-pagination-padding-top); + padding-bottom: var(--items-pagination-padding-bottom); + padding: 43px 0 58px; + justify-content: center; + align-items: center; + background-color: var(--color-gray050); + gap: 4px; +} + +.pagination-button { + display: flex; + flex-direction: row; + align-items: center; + justify-content: center; + width: 40px; + height: 40px; + border: 1px solid var(--color-gray300); + font-weight: 600; + font-size: 16px; + line-height: 26px; + border-radius: 40px; + color: var(--color-gray500); + background-color: var(--color-white); + cursor: pointer; +} + +.pagination-button.prev-page:disabled .pagination-button-image { + content: url('./images/ic_prevPageClick_inactive.png'); +} + +.pagination-button.next-page:disabled .pagination-button-image { + content: url('./images/ic_nextPageClick_inactive.png'); +} + +.pagination-button:disabled { + cursor: auto; +} + +.pagination-button.selected { + border: none; + background-color: #2f80ed; + color: var(--color-gray100); +} + +:root { + --items-main-page-padding-top: 17px; + --items-pagination-padding-top: 40px; + --items-pagination-padding-bottom: 35px; + --search-input-container-width: 288px; + --best-items-container-column-gap: 0; + --all-items-container-column-gap: 8px; + --search-title-order: 1; + --search-input-order: 3; + --search-submit-order: 2; + --search-select-order: 4; + --search-input-flex-grow: 1; + --search-select-width: 42px; + --search-select-image: url('./images/ic_sort.png'); + --search-select-image-position: center center; +} + +/* Tablet */ +@media screen and (min-width: 768px) and (max-width: 1199px) { + :root { + --items-main-page-padding-top: 24px; + --items-pagination-padding-top: 40px; + --items-pagination-padding-bottom: 72px; + --search-input-container-width: 242px; + --best-items-container-column-gap: 10px; + --all-items-container-column-gap: 16px; + --search-title-order: 1; + --search-input-order: 2; + --search-submit-order: 3; + --search-select-order: 4; + --search-input-flex-grow: 0; + --search-select-width: 130px; + --search-select-image: url('./images/ic_arrow_down.png'); + --search-select-image-position: right 20px center; + } + #cards-best .items-container { + column-gap: 10px; + grid-template-columns: repeat(2, 1fr); + grid-template-rows: repeat(1, 1fr); + } + #cards-all .items-container { + column-gap: 16px; + grid-template-columns: repeat(3, 1fr); + grid-template-rows: repeat(2, 1fr); + } +} +/* PC */ +@media (min-width: 1200px) { + :root { + --items-main-page-padding-top: 24px; + --items-pagination-padding-top: 43px; + --items-pagination-padding-bottom: 58px; + --search-input-container-width: 325px; + --best-items-container-column-gap: 24px; + --all-items-container-column-gap: 24px; + --search-title-order: 1; + --search-input-order: 2; + --search-submit-order: 3; + --search-select-order: 4; + --search-input-flex-grow: 0; + --search-select-width: 130px; + --search-select-image: url('./images/ic_arrow_down.png'); + --search-select-image-position: right 20px center; + } + #cards-best .items-container { + column-gap: 24px; + grid-template-columns: repeat(4, 1fr); + grid-template-rows: repeat(1, 1fr); + } + #cards-all .items-container { + column-gap: 24px; + grid-template-columns: repeat(5, 1fr); + grid-template-rows: repeat(2, 1fr); + } +} diff --git a/src/pages/Items/Items.jsx b/src/pages/Items/Items.jsx new file mode 100644 index 00000000..01b37e02 --- /dev/null +++ b/src/pages/Items/Items.jsx @@ -0,0 +1,298 @@ +import { Link } from 'react-router-dom'; +import './Items.css'; +import { getItems } from '../../apis/api'; +import { useEffect, useState } from 'react'; +import { useDeviceType } from '../../hooks/useDeviceType'; +import { formatPriceKRW } from '../../modules/formatPrice'; +import { useNavigate } from 'react-router'; +import Header from '../components/Header'; + +const ItemComponent = ({ + id, + imageUrl, + imageDefaultUrl, + name, + price, + favoriteCount, +}) => { + return ( +
+ { + e.target.onError = null; + e.target.src = imageDefaultUrl; + }} + alt={name} + width={282} + /> +
+

{name}

+

{formatPriceKRW(price)}

+
+ +

{favoriteCount}

+
+
+
+ ); +}; + +const pageSizeByDevice = { + best: (deviceType) => { + return deviceType === 'lg' + ? 4 + : deviceType === 'md' + ? 2 + : deviceType === 'sm' + ? 1 + : 0; + }, + current: (deviceType) => { + return deviceType === 'lg' + ? 10 + : deviceType === 'md' + ? 6 + : deviceType === 'sm' + ? 4 + : 0; + }, +}; + +const getCurrentPageState = ( + offset, + pageSize, + totalDataCount, + maxVisiblePageCount = 5 +) => { + //총페이지가 307일때 + //pagesize가 10이고 offset이 13이면? + //현재페이지: 2, pagenumbers = 1,2,3,4,5 + const currentPageNumber = Math.ceil(offset / pageSize); + const paginationStartPage = Math.floor((currentPageNumber - 1) / 5) * 5 + 1; + const lastPageNumber = Math.ceil(totalDataCount / pageSize); + const remainingPageCount = lastPageNumber - paginationStartPage + 1; + const visiblePageCount = + remainingPageCount >= maxVisiblePageCount + ? maxVisiblePageCount + : remainingPageCount; + const visiblePageNumbers = new Array(visiblePageCount) + .fill(0) + .map((v, i) => v + i + paginationStartPage); + return { currentPageNumber, visiblePageNumbers }; +}; + +const Items = () => { + const { deviceType } = useDeviceType(); + + const [offset, setOffset] = useState(1); + const [order, setOrder] = useState('recent'); + const [keyword, setKeyword] = useState(''); + + const [bestItemList, setBestItemList] = useState([]); + const [currentItemList, setCurrentItemList] = useState([]); + const [pageNumbers, setPageNumbers] = useState([1]); + const [currentPageNumber, setCurrentPageNumber] = useState(1); + const [lastPageIndex, setLastPageIndex] = useState(1); + + const [searchInputValue, setSearchInputValue] = useState(''); + + const onCreateNewItemNavigate = useNavigate(); + + const prevPageEnable = currentPageNumber > 1; + const nextPageEnable = currentPageNumber < lastPageIndex; + + const handleSearchOrderChange = (e) => { + setOffset(1); + setOrder(e.target.value); + }; + + const loadBestItemList = async (options) => { + const result = await getItems(options); + if (!result) return; + const { list } = result; + setBestItemList(list); + }; + + const loadCurrentItemList = async (option) => { + const result = await getItems(option); + if (!result) return; + const { list, totalCount } = result; + setCurrentItemList(list); + setLastPageIndex(Math.ceil(totalCount / option.pageSize)); + const currentPageState = getCurrentPageState( + option.offset, + option.pageSize, + totalCount + ); + setPageNumbers((prev) => { + const nextPageNumbers = currentPageState.visiblePageNumbers; + return JSON.stringify(prev) === JSON.stringify(nextPageNumbers) + ? prev + : nextPageNumbers; + }); + setCurrentPageNumber(currentPageState.currentPageNumber); + }; + + const handleSearchInputChange = (e) => setSearchInputValue(e.target.value); + const handleSearchInputEnterPress = (e) => { + if (e.key === 'Enter') { + setOffset(1); + setKeyword(searchInputValue); + } + }; + + //prettier-ignore + const handlePageNumberClick = (e) => onPaginationButtonClick(Number(e.target.value)); + const handlePagePrev = () => onPaginationButtonClick(currentPageNumber - 1); + const handlePageNext = () => onPaginationButtonClick(currentPageNumber + 1); + const onPaginationButtonClick = (nextPageNumber) => + setOffset((nextPageNumber - 1) * pageSizeByDevice.current(deviceType) + 1); + + const handleCreateNewItemClick = (e) => { + e.preventDefault(); + onCreateNewItemNavigate('/additem'); + }; + + useEffect(() => { + (async () => { + await loadBestItemList({ + offset: 1, + pageSize: pageSizeByDevice.best(deviceType), + orderBy: 'favorite', + keyword: '', + }); + })(); + }, [deviceType]); + + useEffect(() => { + (async () => { + await loadCurrentItemList({ + offset: offset, + pageSize: pageSizeByDevice.current(deviceType), + orderBy: order, + keyword: keyword, + }); + })(); + }, [deviceType, order, offset, keyword]); + + return ( + <> +
+
+
+
+

베스트 상품

+
+
+ {bestItemList.map((item) => { + return ( + + ); + })} +
+
+
+
+

전체 상품

+
+ + +
+ + +
+
+ {currentItemList.map((item) => { + return ( + + ); + })} +
+
+
+ + + ); +}; + +export default Items; diff --git a/src/pages/Items/mockItems.json b/src/pages/Items/mockItems.json new file mode 100644 index 00000000..e7084528 --- /dev/null +++ b/src/pages/Items/mockItems.json @@ -0,0 +1,140 @@ +[ + { + "id": 226, + "name": "푸바오 찾아 떠나는 청두 여행!!", + "description": "제 딸 푸바오가 있는 쓰촨성 청두로 날아가 보세요!!!", + "price": 99999999, + "tags": ["푸바오", "러바오", "아이바오", "루이바오", "후이바오"], + "images": [ + "https://image.hanatour.com/usr/cms/resize/800_0/2024/08/11/10000/687449d1-4e4f-4952-b6d1-5342465880f5.jpg" + ], + "ownerId": 177, + "favoriteCount": 45, + "createdAt": "2024-09-23T11:25:06.306Z", + "updatedAt": "2025-05-08T00:35:32.211Z" + }, + { + "id": 629, + "name": "돌아와..너가 죽으면 안돼", + "description": "젠슨형 우리좀 꺼내줘", + "price": 113, + "tags": ["S&P 투자사"], + "images": [ + "https://cdn.choicenews.co.kr/news/photo/202409/135215_98277_538.jpg" + ], + "ownerId": 895, + "favoriteCount": 18, + "createdAt": "2025-03-10T07:14:54.608Z", + "updatedAt": "2025-05-08T01:19:00.997Z" + }, + { + "id": 199, + "name": "아이폰 16 pro", + "description": "따끈한 아이폰!", + "price": 1290000, + "tags": [], + "images": [ + "https://sprint-fe-project.s3.ap-northeast-2.amazonaws.com/Sprint_Mission/user/98/1726837429259/iphone.jpg" + ], + "ownerId": 98, + "favoriteCount": 15, + "createdAt": "2024-09-20T13:03:49.397Z", + "updatedAt": "2025-04-27T08:34:36.366Z" + }, + { + "id": 197, + "name": "갤럭시 버즈3", + "description": "버즈3 입니다~", + "price": 500000, + "tags": ["이어폰"], + "images": [ + "https://sprint-fe-project.s3.ap-northeast-2.amazonaws.com/Sprint_Mission/user/107/1726730417522/buds.jpg" + ], + "ownerId": 107, + "favoriteCount": 13, + "createdAt": "2024-09-19T07:20:17.749Z", + "updatedAt": "2025-05-01T12:57:26.904Z" + }, + { + "id": 644, + "name": "판다마켓...", + "description": "teststes", + "price": 1111111111, + "tags": ["판다", "졸림"], + "images": [ + "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcT4fb9-Mrcz1_0IhrLpCFzG7zisGz8OvqzNog&s" + ], + "ownerId": 916, + "favoriteCount": 7, + "createdAt": "2025-03-14T02:53:34.608Z", + "updatedAt": "2025-04-25T17:30:18.213Z" + }, + { + "id": 355, + "name": "단풍잎", + "description": "단풍잎 하나 사세요", + "price": 1000, + "tags": ["단풍", "단풍잎"], + "images": [ + "https://sprint-fe-project.s3.ap-northeast-2.amazonaws.com/Sprint_Mission/user/36/1728454687724/leaf-6760484_640.jpg" + ], + "ownerId": 36, + "favoriteCount": 7, + "createdAt": "2024-10-09T06:18:33.271Z", + "updatedAt": "2025-02-27T01:46:49.928Z" + }, + { + "id": 646, + "name": "판다", + "description": "판다판다", + "price": 2222222, + "tags": [], + "images": [ + "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQOHuLhMBf7IOIwUUZAjjKzV5AZbw3qIJZ_sA&s" + ], + "ownerId": 916, + "favoriteCount": 6, + "createdAt": "2025-03-14T02:59:35.707Z", + "updatedAt": "2025-04-28T01:38:11.166Z" + }, + { + "id": 630, + "name": "상품", + "description": "상품 소개 수정1", + "price": 7701, + "tags": ["#게시글", "#게시판", "#상품"], + "images": ["https://placehold.co/300"], + "ownerId": 884, + "favoriteCount": 6, + "createdAt": "2025-03-10T07:16:02.104Z", + "updatedAt": "2025-03-16T09:17:57.410Z" + }, + { + "id": 114, + "name": "갤럭시 탭 S7", + "description": "삼성 갤럭시 탭 S7", + "price": 350000, + "tags": [], + "images": [ + "https://sprint-fe-project.s3.ap-northeast-2.amazonaws.com/Sprint_Mission/user/3/1721991844193/5146532.png" + ], + "ownerId": 1, + "favoriteCount": 6, + "createdAt": "2024-07-29T05:45:03.249Z", + "updatedAt": "2024-07-29T05:45:03.249Z" + }, + { + "id": 107, + "name": "퀸사이즈 침대", + "description": "퀸사이즈 침대 프레임", + "price": 500000, + "tags": ["가구"], + "images": [ + "https://sprint-fe-project.s3.ap-northeast-2.amazonaws.com/Sprint_Mission/user/3/1721991744735/2113.png" + ], + "ownerId": 1, + "favoriteCount": 6, + "createdAt": "2024-07-29T05:45:03.249Z", + "updatedAt": "2024-07-29T05:45:03.249Z" + } +] diff --git a/src/pages/Items/test.js b/src/pages/Items/test.js new file mode 100644 index 00000000..6e54df60 --- /dev/null +++ b/src/pages/Items/test.js @@ -0,0 +1,22 @@ +const pageSizeByDevice = { + best: (deviceType) => { + return deviceType === 'lg' + ? 4 + : deviceType === 'md' + ? 2 + : deviceType === 'sm' + ? 1 + : 0; + }, + current: (deviceType) => { + return deviceType === 'lg' + ? 10 + : deviceType === 'md' + ? 6 + : deviceType === 'sm' + ? 4 + : 0; + }, +}; + +console.log(pageSizeByDevice.current('lg')); diff --git a/src/pages/Privacy/Privacy.jsx b/src/pages/Privacy/Privacy.jsx new file mode 100644 index 00000000..fb9f1708 --- /dev/null +++ b/src/pages/Privacy/Privacy.jsx @@ -0,0 +1,5 @@ +const Privacy = () => { + return <>; +}; + +export default Privacy; diff --git a/src/pages/components/Header.css b/src/pages/components/Header.css new file mode 100644 index 00000000..b0835b3b --- /dev/null +++ b/src/pages/components/Header.css @@ -0,0 +1,89 @@ +.page-header { + border-bottom: 1px solid #dfdfdf; +} + +.nav-container { + max-width: 1520px; + height: 70px; + display: flex; + flex-direction: row; + align-items: center; + justify-content: space-between; + padding: 0 var(--nav-padding-x); + margin: 0 auto; + gap: var(--nav-conatiner-gap); +} + +.nav-logo-container { + text-decoration: none; + display: flex; + flex-direction: row; + gap: 8.59px; + align-items: center; +} + +.nav-logo-img { + aspect-ratio: 40 / 40.14; + display: var(--display-logo-img); +} + +.nav-logo-text { + font-weight: 700; + font-size: 25.63px; + line-height: 100%; + color: var(--color-blue400); + font-family: 'ROKAFSans'; +} + +.nav-link-container { + display: flex; + flex-direction: row; + flex-grow: 1; +} + +.nav-link { + display: inline-block; + padding: 21px var(--nav-link-padding-x); + text-decoration: none; + color: var(--color-gray600); + font-weight: 600; + font-size: 18px; + line-height: 26px; +} + +.nav-link.active { + color: var(--color-blue400); +} + +.nav-button { + border-radius: 8px; + padding: 12px 43px; + line-height: 26px; + color: var(--color-gray100); +} + +:root { + --nav-padding-x: 16px; + --display-logo-img: none; + --nav-conatiner-gap: 4px; + --nav-link-padding-x: 4px; +} + +/* Tablet */ +@media screen and (min-width: 768px) and (max-width: 1199px) { + :root { + --nav-padding-x: 24px; + --display-logo-img: inline; + --nav-conatiner-gap: 20px; + --nav-link-padding-x: 15px; + } +} +/* PC */ +@media (min-width: 1200px) { + :root { + --nav-padding-x: 200px; + --display-logo-img: inline; + --nav-conatiner-gap: 32px; + --nav-link-padding-x: 15px; + } +} diff --git a/src/pages/components/Header.jsx b/src/pages/components/Header.jsx new file mode 100644 index 00000000..50b035ef --- /dev/null +++ b/src/pages/components/Header.jsx @@ -0,0 +1,60 @@ +import { Link } from 'react-router-dom'; +import './Header.css'; +import { useIsLogin } from '../../contexts/LoginStateContext'; + +const Header = ({ currentSection }) => { + const isLogin = useIsLogin(); + const linkClassName = (linkName) => { + return currentSection === linkName ? 'active' : ''; + }; + return ( +
+ +
+ ); +}; + +export default Header; diff --git a/src/reset.css b/src/reset.css new file mode 100644 index 00000000..a3f76817 --- /dev/null +++ b/src/reset.css @@ -0,0 +1,129 @@ +/* http://meyerweb.com/eric/tools/css/reset/ + v2.0 | 20110126 + License: none (public domain) +*/ + +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/styles/auth-form-style.css b/styles/auth-form-style.css deleted file mode 100644 index d4de9a0c..00000000 --- a/styles/auth-form-style.css +++ /dev/null @@ -1,176 +0,0 @@ -body { - font-family: 'Pretendard-Regular'; - background-color: var(--color-gray050); -} - -.form-logo-container { - display: flex; - flex-direction: row; - justify-content: center; - align-items: center; - gap: 22.24px; - text-decoration: none; - margin: 80px auto 40px; - height: 66px; -} - -.form-logo-img { - width: 51.76px; - height: auto; -} - -.form-logo-text { - font-family: ROKAFSansMedium; - font-size: 33.17px; - font-weight: var(--font-weight-bold); - color: var(--color-blue400); -} - -.form-container { - max-width: 432px; - width: 100%; - margin: 0 auto; - padding: 0 16px; - display: flex; - flex-direction: column; -} - -.form-label { - font-size: var(--font-size-sm); - font-weight: var(--font-weight-bold); - color: var(--color-gray800); - margin-bottom: 16px; -} - -.form-input-container { - background-color: var(--color-gray200); - height: 56px; - margin-top: 16px; - padding: 0 0px; - border-radius: var(--border-radius-sm); - display: flex; - flex-direction: row; - align-items: center; -} - -.form-input-container.inValid { - border: 1px solid var(--color-error); -} - -.form-input-container.valid { - border: 1px solid var(--color-blue400); -} - -.form-input { - height: 100%; - font-size: var(--font-size-base); - color: var(--color-gray800); - background-color: var(--color-gray200); - border: none; - border-radius: var(--border-radius-sm); - flex-grow: 1; - padding: 0 24px 0; - outline: none; -} - -.form-input::placeholder { - color: var(--color-gray400); -} - -.form-status-info { - display: inline-block; - margin: 8px 0 0 16px; - font-size: 14px; - font-weight: 600; - color: var(--color-error); -} - -.form-status-info.hidden { - display: none; -} - -.form-icon-password { - width: 20.47px; - height: 14px; - margin-right: 25.8px; - content: url('../images/icon_password_visible.png'); -} - -.form-icon-password.hidden { - height: 18.07px; - content: url('../images/icon_password_invisible.png'); -} - -.form-btn { - height: 56px; - font-family: 'Pretendard-Regular'; - border-radius: var(--border-radius-lg); - font-size: var(--font-size-xl); - margin-bottom: 24px; -} - -.form-social-login { - font-weight: 500; - height: 74px; - background-color: var(--color-blue100); - border-radius: var(--border-radius-xs); - display: flex; - flex-direction: row; - align-items: center; - padding: 16px 23px; - margin-bottom: 24px; - gap: 16px; -} - -.form-social-text { - margin: 0; - color: var(--color-gray800); - font-size: var(--font-size-base); - flex-grow: 1; -} - -.form-social-icon { - width: 42px; - height: 42px; -} - -.form-footer { - font-size: 14px; - font-weight: 500; - margin: 0 auto; -} - -.form-footer-link { - color: var(--color-blue400); -} - -/* Tablet, PC */ -@media (min-width: 768px) { - .form-logo-img { - width: 103.53px; - } - - .form-logo-text { - font-size: 66.34px; - } - - .form-container { - max-width: 672px; - } - - .form-logo-container { - margin: 190px auto 40px; - height: 132px; - } - - .form-label { - font-size: var(--font-size-lg); - margin-bottom: 24px; - } -} - -@media (min-width: 1200px) { - .form-logo-container { - margin: 231px auto 40px; - } -} diff --git a/styles/index-style.css b/styles/index-style.css deleted file mode 100644 index cc9ecf82..00000000 --- a/styles/index-style.css +++ /dev/null @@ -1,392 +0,0 @@ -body { - font-family: 'Pretendard-Regular'; -} - -.page-header { - background-color: var(--color-white); - height: 70px; - position: sticky; - top: 0px; - width: 100%; -} - -.nav-container { - display: flex; - flex-direction: row; - align-items: center; - justify-content: space-between; - margin: 0 auto; - padding: 0 var(--nav-padding-x); - max-width: 1520px; - height: 100%; -} - -.nav-logo-link { - text-decoration: none; - display: flex; - flex-direction: row; - align-items: center; - gap: 8.59px; -} - -.nav-logo-image { - width: 40px; - display: var(--nav-log-display); -} - -.nav-logo-text { - font-family: 'ROKAFSansMedium'; - color: var(--color-blue400); - font-weight: var(--font-weight-bold); - font-size: 25.63px; -} - -.nav-btn { - max-width: 128px; - border-radius: var(--border-radius-xs); - padding: 11px 0; -} - -.page-hero { - background-color: var(--color-blue200); -} - -.hero-container { - display: flex; - justify-content: center; - align-items: center; - flex-direction: var(--main-container-flex-direction); - padding-top: var(--hero-container-padding-top); - gap: var(--hero-container-gap); -} - -#banner-bottom .hero-container { - padding-top: var(--hero-container-btm-padding-top); -} - -.hero-context { - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - width: 240px; - gap: var(--hero-context-gap); - margin-bottom: 0; -} - -.hero-title { - font-size: var(--hero-title-font-size); - font-weight: var(--font-weight-bold); - color: var(--color-gray700); - margin: 0; - word-break: keep-all; - width: 300px; - text-align: center; - line-height: 140%; -} - -.hero-img-container { - width: 100%; - max-width: 746px; - overflow: hidden; - display: flex; - justify-content: center; -} - -#hero-img-top, -#hero-img-bottom { - min-height: 200px; - width: 100%; - height: 100%; - object-fit: cover; -} -#hero-img-top { - aspect-ratio: 746 / 340; -} -#hero-img-bottom { - aspect-ratio: 746 / 397; -} - -.hero-btn { - padding: 12px 0; - border-radius: var(--border-radius-lg); - font-size: var(--font-size-xl); - font-weight: var(--font-weight-semi-bold); - max-width: 357px; -} - -.page-main { - background-color: var(--color-gray050); -} - -.cards { - display: flex; - flex-direction: column; - background-color: var(--cards-background-color); - padding-top: var(--cards-padding-top); - padding-bottom: var(--cards-padding-bottom); - margin-bottom: var(--cards-margin-bottom); - gap: var(--cards-gap); -} - -.card-container { - width: var(--card-container-width); - height: 100%; - background-color: var(--color-gray050); - border-radius: var(--border-radius-sm); - margin: 0 auto; - display: flex; - justify-content: center; - align-items: center; - gap: var(--card-container-gap); -} - -.card-container { - flex-direction: var(--main-container-flex-direction); -} - -.card-container.reverse { - flex-direction: var(--main-container-flex-direction-reverse); -} - -.card-img { - width: var(--card-img-width); - aspect-ratio: 588 / 444; - height: auto; -} - -.card-context { - padding: 0 24px 0 0; - width: 344px; -} - -.card-context.reverse { - text-align: right; - padding: 0 0 0 24px; -} - -.card-tag { - color: var(--color-blue400); - font-size: var(--card-tag-font-size); - font-weight: var(--font-weight-bold); - margin: 0 0 12px; -} - -.card-title { - color: var(--color-gray700); - font-size: var(--card-title-font-size); - font-weight: var(--font-weight-bold); - line-height: 140%; - margin: 0 0 24px; - word-break: keep-all; -} - -.card-description { - color: var(--color-gray700); - font-size: var(--card-description-font-size); - font-weight: var(--font-weight-medium); - line-height: 140%; - margin: 0; - white-space: nowrap; -} - -.page-spacing { - background-color: var(--color-gray050); - height: 138px; -} - -.page-footer { - background-color: var(--color-blue950); - height: 160px; - padding: 32px 0 0; -} - -.footer-container { - display: flex; - flex-direction: row-reverse; - flex-wrap: wrap-reverse; - justify-content: space-between; - padding: 0 var(--footer-padding-x); - max-width: 1520px; - margin: 0 auto; - gap: 60px 0; -} - -.footer-corp { - color: var(--color-gray400); - flex-basis: 100%; -} - -.footer-links { - display: flex; - flex-direction: row; - gap: 30px; -} - -.footer-links a { - text-decoration: none; - color: var(--color-gray300); - font-size: var(--font-size-base); -} - -.footer-icons { - display: flex; - flex-direction: row; - gap: 13px; -} - -.footer-icon { - width: 18px; -} - -/* 기본 변수 (Mobile 기준) */ -:root { - /* 로고 이미지 표시여부 변수 */ - --nav-log-display: none; - - /* 좌우 여백 변수 */ - --nav-padding-x: 16px; - --footer-padding-x: 32px; - - /* hero, card 배치방향 변수 */ - --main-container-flex-direction: column; - --main-container-flex-direction-reverse: column; - - /* 요소 간격조절 변수 */ - --cards-padding-top: 52px; - --cards-padding-bottom: 83px; - --cards-margin-bottom: 0px; - --cards-gap: 40px; - --card-container-gap: 24px; - --hero-container-padding-top: 48px; - --hero-container-btm-padding-top: 121px; - --hero-container-gap: 132px; - --hero-context-gap: 18px; - - /* 요소 크기조절 변수 */ - --card-container-width: 344px; - --card-img-width: 344px; - - /* cards 배경색 설정 */ - --cards-background-color: var(--color-gray050); -} - -/* Tablet */ -@media screen and (min-width: 768px) and (max-width: 1199px) { - :root { - /* 로고 이미지 표시여부 변수 */ - --nav-log-display: inline; - - /* 좌우 여백 변수 */ - --nav-padding-x: 24px; - --footer-padding-x: 104px; - - /* hero, card 배치방향 변수 */ - --main-container-flex-direction: column; - --main-container-flex-direction-reverse: column; - - /* 요소 간격조절 변수 */ - --cards-padding-top: 24px; - --cards-padding-bottom: 56px; - --cards-margin-bottom: 0px; - --cards-gap: 52px; - --card-container-gap: 24px; - --hero-container-padding-top: 84px; - --hero-container-btm-padding-top: 201px; - --hero-container-gap: 211px; - --hero-context-gap: 24px; - - /* 요소 크기조절 변수 */ - --card-container-width: 696px; - --card-img-width: 696px; - - /* cards 배경색 설정 */ - --cards-background-color: var(--color-gray050); - } - - .hero-title { - text-align: center; - width: auto; - } - - .card-context { - width: 696px; - } - - .hero-context { - width: auto; - align-items: center; - margin-bottom: 0px; - } - - .card-description { - line-height: 32px; - } -} - -/* PC */ -@media (min-width: 1200px) { - :root { - /* 로고 이미지 표시여부 변수 */ - --nav-log-display: inline; - - /* 좌우 여백 변수 */ - --nav-padding-x: 200px; - --footer-padding-x: 200px; - - /* hero, card 배치방향 변수 */ - --main-container-flex-direction: row; - --main-container-flex-direction-reverse: row-reverse; - - /* 요소 간격조절 변수 */ - --cards-padding-top: 138px; - --cards-padding-bottom: 138px; - --cards-margin-bottom: 138px; - --cards-gap: 276px; - --card-container-gap: 64px; - --hero-container-padding-top: 200px; - --hero-container-btm-padding-top: 200px; - --hero-container-gap: 7px; - --hero-context-gap: 32px; - - /* 요소 크기조절 변수 */ - --card-container-width: 988px; - --card-img-width: 579px; - - /* cards 배경색 설정 */ - --cards-background-color: var(--color-white); - } - - .hero-title { - text-align: left; - width: 300px; - } - - .card-context { - width: auto; - } - - .card-title { - width: 293px; - } - - .hero-context { - width: 357px; - align-items: start; - margin-bottom: 60px; - } - - .card-description { - line-height: 32px; - } -} - -/* 폰트 반응형 스타일 적용 */ -@supports (font-size: clamp(1rem, 2vw, 3rem)) { - :root { - --hero-title-font-size: clamp(32px, 5.3763vw, 40px); - --card-title-font-size: clamp(24px, 4.3011vw, 40px); - --card-tag-font-size: clamp(16px, 2.4194vw, 18px); - --card-description-font-size: clamp(16px, 2.4194vw, 24px); - } -} diff --git a/styles/reset.css b/styles/reset.css deleted file mode 100644 index 85e401f3..00000000 --- a/styles/reset.css +++ /dev/null @@ -1,23 +0,0 @@ -* { - box-sizing: border-box; -} - -body { - margin: 0; -} - -h1 { - margin: 0; -} - -h2 { - margin: 0; -} - -h3 { - margin: 0; -} - -p { - margin: 0; -} diff --git a/vite.config.js b/vite.config.js new file mode 100644 index 00000000..8b0f57b9 --- /dev/null +++ b/vite.config.js @@ -0,0 +1,7 @@ +import { defineConfig } from 'vite' +import react from '@vitejs/plugin-react' + +// https://vite.dev/config/ +export default defineConfig({ + plugins: [react()], +})