From b62856f8239e4633b5fbb427c3da0e0782a82cc5 Mon Sep 17 00:00:00 2001 From: anne-hyeyeon Date: Wed, 8 Jan 2025 22:54:32 +0900 Subject: [PATCH 1/8] =?UTF-8?q?chore:=20ESLint=20Airbnb=20=EC=8A=A4?= =?UTF-8?q?=ED=83=80=EC=9D=BC=20=EA=B0=80=EC=9D=B4=EB=93=9C=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .eslintignore | 3 + .eslintrc.cjs | 40 + .prettierignore | 4 + .prettierrc.cjs | 13 + package.json | 17 +- pnpm-lock.yaml | 3861 +++++++++++++++++++++++ src/advanced/__tests__/advanced.test.js | 6 +- src/basic/__tests__/basic.test.js | 161 +- src/basic/main.basic.js | 266 +- src/main.original.js | 295 +- 10 files changed, 4353 insertions(+), 313 deletions(-) create mode 100644 .eslintignore create mode 100644 .eslintrc.cjs create mode 100644 .prettierignore create mode 100644 .prettierrc.cjs create mode 100644 pnpm-lock.yaml diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 00000000..5a19e8ac --- /dev/null +++ b/.eslintignore @@ -0,0 +1,3 @@ +node_modules +dist +coverage \ No newline at end of file diff --git a/.eslintrc.cjs b/.eslintrc.cjs new file mode 100644 index 00000000..93156a28 --- /dev/null +++ b/.eslintrc.cjs @@ -0,0 +1,40 @@ +module.exports = { + root: true, + env: { + browser: true, + es2020: true, + }, + extends: [ + "airbnb", + "airbnb-typescript", + "airbnb/hooks", + "plugin:@typescript-eslint/recommended", + "plugin:react/jsx-runtime", + "prettier", + ], + parser: "@typescript-eslint/parser", + parserOptions: { + ecmaVersion: "latest", + sourceType: "module", + project: "./tsconfig.json", + }, + plugins: ["react-refresh", "@typescript-eslint", "react"], + settings: { + react: { + version: "detect", + }, + }, + rules: { + "react-refresh/only-export-components": [ + "warn", + { allowConstantExport: true }, + ], + // Airbnb 스타일 예외 규칙들 + "react/react-in-jsx-scope": "off", + "react/require-default-props": "off", + "react/jsx-props-no-spreading": "off", + "@typescript-eslint/no-unused-vars": "warn", + "import/no-extraneous-dependencies": ["error", { devDependencies: true }], + "import/prefer-default-export": "off", + }, +}; diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 00000000..349cc3a8 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,4 @@ +node_modules +dist +coverage +pnpm-lock.yaml \ No newline at end of file diff --git a/.prettierrc.cjs b/.prettierrc.cjs new file mode 100644 index 00000000..2c2c0e22 --- /dev/null +++ b/.prettierrc.cjs @@ -0,0 +1,13 @@ +module.exports = { + printWidth: 100, + tabWidth: 2, + useTabs: false, + semi: true, + singleQuote: true, + quoteProps: "as-needed", + trailingComma: "all", + bracketSpacing: true, + bracketSameLine: false, + arrowParens: "always", + endOfLine: "lf", +}; diff --git a/package.json b/package.json index 02cd2326..dd00ca22 100644 --- a/package.json +++ b/package.json @@ -12,13 +12,28 @@ "test": "vitest", "test:basic": "vitest basic.test.js", "test:advanced": "vitest advanced.test.js", - "test:ui": "vitest --ui" + "test:ui": "vitest --ui", + "lint": "eslint src --ext ts,tsx --report-unused-disable-directives --max-warnings 0", + "lint:fix": "eslint src --ext ts,tsx --fix", + "format": "prettier --write \"src/**/*.{ts,tsx,js,jsx,json}\"" }, "devDependencies": { "@testing-library/jest-dom": "^6.5.0", "@testing-library/user-event": "^14.5.2", + "@typescript-eslint/eslint-plugin": "^8.19.1", + "@typescript-eslint/parser": "^8.19.1", "@vitest/ui": "^2.1.1", + "eslint": "^9.17.0", + "eslint-config-airbnb": "^19.0.4", + "eslint-config-airbnb-typescript": "^18.0.0", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-import": "^2.31.0", + "eslint-plugin-jsx-a11y": "^6.10.2", + "eslint-plugin-prettier": "^5.2.1", + "eslint-plugin-react": "^7.37.3", + "eslint-plugin-react-hooks": "^5.1.0", "jsdom": "^25.0.0", + "prettier": "^3.4.2", "vite": "^5.1.0", "vitest": "^2.1.1" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 00000000..c1d2226e --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,3861 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + devDependencies: + '@testing-library/jest-dom': + specifier: ^6.5.0 + version: 6.6.3 + '@testing-library/user-event': + specifier: ^14.5.2 + version: 14.5.2(@testing-library/dom@10.4.0) + '@typescript-eslint/eslint-plugin': + specifier: ^8.19.1 + version: 8.19.1(@typescript-eslint/parser@8.19.1(eslint@9.17.0)(typescript@5.7.2))(eslint@9.17.0)(typescript@5.7.2) + '@typescript-eslint/parser': + specifier: ^8.19.1 + version: 8.19.1(eslint@9.17.0)(typescript@5.7.2) + '@vitest/ui': + specifier: ^2.1.1 + version: 2.1.8(vitest@2.1.8) + eslint: + specifier: ^9.17.0 + version: 9.17.0 + eslint-config-airbnb: + specifier: ^19.0.4 + version: 19.0.4(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.19.1(eslint@9.17.0)(typescript@5.7.2))(eslint@9.17.0))(eslint-plugin-jsx-a11y@6.10.2(eslint@9.17.0))(eslint-plugin-react-hooks@5.1.0(eslint@9.17.0))(eslint-plugin-react@7.37.3(eslint@9.17.0))(eslint@9.17.0) + eslint-config-airbnb-typescript: + specifier: ^18.0.0 + version: 18.0.0(@typescript-eslint/eslint-plugin@8.19.1(@typescript-eslint/parser@8.19.1(eslint@9.17.0)(typescript@5.7.2))(eslint@9.17.0)(typescript@5.7.2))(@typescript-eslint/parser@8.19.1(eslint@9.17.0)(typescript@5.7.2))(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.19.1(eslint@9.17.0)(typescript@5.7.2))(eslint@9.17.0))(eslint@9.17.0) + eslint-config-prettier: + specifier: ^9.1.0 + version: 9.1.0(eslint@9.17.0) + eslint-plugin-import: + specifier: ^2.31.0 + version: 2.31.0(@typescript-eslint/parser@8.19.1(eslint@9.17.0)(typescript@5.7.2))(eslint@9.17.0) + eslint-plugin-jsx-a11y: + specifier: ^6.10.2 + version: 6.10.2(eslint@9.17.0) + eslint-plugin-prettier: + specifier: ^5.2.1 + version: 5.2.1(eslint-config-prettier@9.1.0(eslint@9.17.0))(eslint@9.17.0)(prettier@3.4.2) + eslint-plugin-react: + specifier: ^7.37.3 + version: 7.37.3(eslint@9.17.0) + eslint-plugin-react-hooks: + specifier: ^5.1.0 + version: 5.1.0(eslint@9.17.0) + jsdom: + specifier: ^25.0.0 + version: 25.0.1 + prettier: + specifier: ^3.4.2 + version: 3.4.2 + vite: + specifier: ^5.1.0 + version: 5.4.11 + vitest: + specifier: ^2.1.1 + version: 2.1.8(@vitest/ui@2.1.8)(jsdom@25.0.1) + +packages: + + '@adobe/css-tools@4.4.1': + resolution: {integrity: sha512-12WGKBQzjUAI4ayyF4IAtfw2QR/IDoqk6jTddXDhtYTJF9ASmoE1zst7cVtP0aL/F1jUJL5r+JxKXKEgHNbEUQ==} + + '@babel/code-frame@7.26.2': + resolution: {integrity: sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.25.9': + resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==} + engines: {node: '>=6.9.0'} + + '@babel/runtime@7.26.0': + resolution: {integrity: sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==} + engines: {node: '>=6.9.0'} + + '@esbuild/aix-ppc64@0.21.5': + resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.21.5': + resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.21.5': + resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.21.5': + resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.21.5': + resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.21.5': + resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.21.5': + resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.21.5': + resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.21.5': + resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.21.5': + resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.21.5': + resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.21.5': + resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.21.5': + resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.21.5': + resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.21.5': + resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.21.5': + resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.21.5': + resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-x64@0.21.5': + resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-x64@0.21.5': + resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + + '@esbuild/sunos-x64@0.21.5': + resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.21.5': + resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.21.5': + resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.21.5': + resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + + '@eslint-community/eslint-utils@4.4.1': + resolution: {integrity: sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + + '@eslint-community/regexpp@4.12.1': + resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + '@eslint/config-array@0.19.1': + resolution: {integrity: sha512-fo6Mtm5mWyKjA/Chy1BYTdn5mGJoDNjC7C64ug20ADsRDGrA85bN3uK3MaKbeRkRuuIEAR5N33Jr1pbm411/PA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/core@0.9.1': + resolution: {integrity: sha512-GuUdqkyyzQI5RMIWkHhvTWLCyLo1jNK3vzkSyaExH5kHPDHcuL2VOpHjmMY+y3+NC69qAKToBqldTBgYeLSr9Q==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/eslintrc@3.2.0': + resolution: {integrity: sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/js@9.17.0': + resolution: {integrity: sha512-Sxc4hqcs1kTu0iID3kcZDW3JHq2a77HO9P8CP6YEA/FpH3Ll8UXE2r/86Rz9YJLKme39S9vU5OWNjC6Xl0Cr3w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/object-schema@2.1.5': + resolution: {integrity: sha512-o0bhxnL89h5Bae5T318nFoFzGy+YE5i/gGkoPAgkmTVdRKTiv3p8JHevPiPaMwoloKfEiiaHlawCqaZMqRm+XQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/plugin-kit@0.2.4': + resolution: {integrity: sha512-zSkKow6H5Kdm0ZUQUB2kV5JIXqoG0+uH5YADhaEHswm664N9Db8dXSi0nMJpacpMf+MyyglF1vnZohpEg5yUtg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@humanfs/core@0.19.1': + resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} + engines: {node: '>=18.18.0'} + + '@humanfs/node@0.16.6': + resolution: {integrity: sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==} + engines: {node: '>=18.18.0'} + + '@humanwhocodes/module-importer@1.0.1': + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + + '@humanwhocodes/retry@0.3.1': + resolution: {integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==} + engines: {node: '>=18.18'} + + '@humanwhocodes/retry@0.4.1': + resolution: {integrity: sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==} + engines: {node: '>=18.18'} + + '@jridgewell/sourcemap-codec@1.5.0': + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@pkgr/core@0.1.1': + resolution: {integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==} + engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + + '@polka/url@1.0.0-next.28': + resolution: {integrity: sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw==} + + '@rollup/rollup-android-arm-eabi@4.30.1': + resolution: {integrity: sha512-pSWY+EVt3rJ9fQ3IqlrEUtXh3cGqGtPDH1FQlNZehO2yYxCHEX1SPsz1M//NXwYfbTlcKr9WObLnJX9FsS9K1Q==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.30.1': + resolution: {integrity: sha512-/NA2qXxE3D/BRjOJM8wQblmArQq1YoBVJjrjoTSBS09jgUisq7bqxNHJ8kjCHeV21W/9WDGwJEWSN0KQ2mtD/w==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.30.1': + resolution: {integrity: sha512-r7FQIXD7gB0WJ5mokTUgUWPl0eYIH0wnxqeSAhuIwvnnpjdVB8cRRClyKLQr7lgzjctkbp5KmswWszlwYln03Q==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.30.1': + resolution: {integrity: sha512-x78BavIwSH6sqfP2xeI1hd1GpHL8J4W2BXcVM/5KYKoAD3nNsfitQhvWSw+TFtQTLZ9OmlF+FEInEHyubut2OA==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.30.1': + resolution: {integrity: sha512-HYTlUAjbO1z8ywxsDFWADfTRfTIIy/oUlfIDmlHYmjUP2QRDTzBuWXc9O4CXM+bo9qfiCclmHk1x4ogBjOUpUQ==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.30.1': + resolution: {integrity: sha512-1MEdGqogQLccphhX5myCJqeGNYTNcmTyaic9S7CG3JhwuIByJ7J05vGbZxsizQthP1xpVx7kd3o31eOogfEirw==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.30.1': + resolution: {integrity: sha512-PaMRNBSqCx7K3Wc9QZkFx5+CX27WFpAMxJNiYGAXfmMIKC7jstlr32UhTgK6T07OtqR+wYlWm9IxzennjnvdJg==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm-musleabihf@4.30.1': + resolution: {integrity: sha512-B8Rcyj9AV7ZlEFqvB5BubG5iO6ANDsRKlhIxySXcF1axXYUyqwBok+XZPgIYGBgs7LDXfWfifxhw0Ik57T0Yug==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm64-gnu@4.30.1': + resolution: {integrity: sha512-hqVyueGxAj3cBKrAI4aFHLV+h0Lv5VgWZs9CUGqr1z0fZtlADVV1YPOij6AhcK5An33EXaxnDLmJdQikcn5NEw==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-musl@4.30.1': + resolution: {integrity: sha512-i4Ab2vnvS1AE1PyOIGp2kXni69gU2DAUVt6FSXeIqUCPIR3ZlheMW3oP2JkukDfu3PsexYRbOiJrY+yVNSk9oA==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-loongarch64-gnu@4.30.1': + resolution: {integrity: sha512-fARcF5g296snX0oLGkVxPmysetwUk2zmHcca+e9ObOovBR++9ZPOhqFUM61UUZ2EYpXVPN1redgqVoBB34nTpQ==} + cpu: [loong64] + os: [linux] + + '@rollup/rollup-linux-powerpc64le-gnu@4.30.1': + resolution: {integrity: sha512-GLrZraoO3wVT4uFXh67ElpwQY0DIygxdv0BNW9Hkm3X34wu+BkqrDrkcsIapAY+N2ATEbvak0XQ9gxZtCIA5Rw==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.30.1': + resolution: {integrity: sha512-0WKLaAUUHKBtll0wvOmh6yh3S0wSU9+yas923JIChfxOaaBarmb/lBKPF0w/+jTVozFnOXJeRGZ8NvOxvk/jcw==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-s390x-gnu@4.30.1': + resolution: {integrity: sha512-GWFs97Ruxo5Bt+cvVTQkOJ6TIx0xJDD/bMAOXWJg8TCSTEK8RnFeOeiFTxKniTc4vMIaWvCplMAFBt9miGxgkA==} + cpu: [s390x] + os: [linux] + + '@rollup/rollup-linux-x64-gnu@4.30.1': + resolution: {integrity: sha512-UtgGb7QGgXDIO+tqqJ5oZRGHsDLO8SlpE4MhqpY9Llpzi5rJMvrK6ZGhsRCST2abZdBqIBeXW6WPD5fGK5SDwg==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-musl@4.30.1': + resolution: {integrity: sha512-V9U8Ey2UqmQsBT+xTOeMzPzwDzyXmnAoO4edZhL7INkwQcaW1Ckv3WJX3qrrp/VHaDkEWIBWhRwP47r8cdrOow==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-win32-arm64-msvc@4.30.1': + resolution: {integrity: sha512-WabtHWiPaFF47W3PkHnjbmWawnX/aE57K47ZDT1BXTS5GgrBUEpvOzq0FI0V/UYzQJgdb8XlhVNH8/fwV8xDjw==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.30.1': + resolution: {integrity: sha512-pxHAU+Zv39hLUTdQQHUVHf4P+0C47y/ZloorHpzs2SXMRqeAWmGghzAhfOlzFHHwjvgokdFAhC4V+6kC1lRRfw==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.30.1': + resolution: {integrity: sha512-D6qjsXGcvhTjv0kI4fU8tUuBDF/Ueee4SVX79VfNDXZa64TfCW1Slkb6Z7O1p7vflqZjcmOVdZlqf8gvJxc6og==} + cpu: [x64] + os: [win32] + + '@rtsao/scc@1.1.0': + resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} + + '@testing-library/dom@10.4.0': + resolution: {integrity: sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==} + engines: {node: '>=18'} + + '@testing-library/jest-dom@6.6.3': + resolution: {integrity: sha512-IteBhl4XqYNkM54f4ejhLRJiZNqcSCoXUOG2CPK7qbD322KjQozM4kHQOfkG2oln9b9HTYqs+Sae8vBATubxxA==} + engines: {node: '>=14', npm: '>=6', yarn: '>=1'} + + '@testing-library/user-event@14.5.2': + resolution: {integrity: sha512-YAh82Wh4TIrxYLmfGcixwD18oIjyC1pFQC2Y01F2lzV2HTMiYrI0nze0FD0ocB//CKS/7jIUgae+adPqxK5yCQ==} + engines: {node: '>=12', npm: '>=6'} + peerDependencies: + '@testing-library/dom': '>=7.21.4' + + '@types/aria-query@5.0.4': + resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==} + + '@types/estree@1.0.6': + resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/json5@0.0.29': + resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + + '@typescript-eslint/eslint-plugin@8.19.1': + resolution: {integrity: sha512-tJzcVyvvb9h/PB96g30MpxACd9IrunT7GF9wfA9/0TJ1LxGOJx1TdPzSbBBnNED7K9Ka8ybJsnEpiXPktolTLg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + '@typescript-eslint/parser': ^8.0.0 || ^8.0.0-alpha.0 + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <5.8.0' + + '@typescript-eslint/parser@8.19.1': + resolution: {integrity: sha512-67gbfv8rAwawjYx3fYArwldTQKoYfezNUT4D5ioWetr/xCrxXxvleo3uuiFuKfejipvq+og7mjz3b0G2bVyUCw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <5.8.0' + + '@typescript-eslint/scope-manager@8.19.1': + resolution: {integrity: sha512-60L9KIuN/xgmsINzonOcMDSB8p82h95hoBfSBtXuO4jlR1R9L1xSkmVZKgCPVfavDlXihh4ARNjXhh1gGnLC7Q==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/type-utils@8.19.1': + resolution: {integrity: sha512-Rp7k9lhDKBMRJB/nM9Ksp1zs4796wVNyihG9/TU9R6KCJDNkQbc2EOKjrBtLYh3396ZdpXLtr/MkaSEmNMtykw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <5.8.0' + + '@typescript-eslint/types@8.19.1': + resolution: {integrity: sha512-JBVHMLj7B1K1v1051ZaMMgLW4Q/jre5qGK0Ew6UgXz1Rqh+/xPzV1aW581OM00X6iOfyr1be+QyW8LOUf19BbA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/typescript-estree@8.19.1': + resolution: {integrity: sha512-jk/TZwSMJlxlNnqhy0Eod1PNEvCkpY6MXOXE/WLlblZ6ibb32i2We4uByoKPv1d0OD2xebDv4hbs3fm11SMw8Q==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <5.8.0' + + '@typescript-eslint/utils@8.19.1': + resolution: {integrity: sha512-IxG5gLO0Ne+KaUc8iW1A+XuKLd63o4wlbI1Zp692n1xojCl/THvgIKXJXBZixTh5dd5+yTJ/VXH7GJaaw21qXA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <5.8.0' + + '@typescript-eslint/visitor-keys@8.19.1': + resolution: {integrity: sha512-fzmjU8CHK853V/avYZAvuVut3ZTfwN5YtMaoi+X9Y9MA9keaWNHC3zEQ9zvyX/7Hj+5JkNyK1l7TOR2hevHB6Q==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@vitest/expect@2.1.8': + resolution: {integrity: sha512-8ytZ/fFHq2g4PJVAtDX57mayemKgDR6X3Oa2Foro+EygiOJHUXhCqBAAKQYYajZpFoIfvBCF1j6R6IYRSIUFuw==} + + '@vitest/mocker@2.1.8': + resolution: {integrity: sha512-7guJ/47I6uqfttp33mgo6ga5Gr1VnL58rcqYKyShoRK9ebu8T5Rs6HN3s1NABiBeVTdWNrwUMcHH54uXZBN4zA==} + peerDependencies: + msw: ^2.4.9 + vite: ^5.0.0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + + '@vitest/pretty-format@2.1.8': + resolution: {integrity: sha512-9HiSZ9zpqNLKlbIDRWOnAWqgcA7xu+8YxXSekhr0Ykab7PAYFkhkwoqVArPOtJhPmYeE2YHgKZlj3CP36z2AJQ==} + + '@vitest/runner@2.1.8': + resolution: {integrity: sha512-17ub8vQstRnRlIU5k50bG+QOMLHRhYPAna5tw8tYbj+jzjcspnwnwtPtiOlkuKC4+ixDPTuLZiqiWWQ2PSXHVg==} + + '@vitest/snapshot@2.1.8': + resolution: {integrity: sha512-20T7xRFbmnkfcmgVEz+z3AU/3b0cEzZOt/zmnvZEctg64/QZbSDJEVm9fLnnlSi74KibmRsO9/Qabi+t0vCRPg==} + + '@vitest/spy@2.1.8': + resolution: {integrity: sha512-5swjf2q95gXeYPevtW0BLk6H8+bPlMb4Vw/9Em4hFxDcaOxS+e0LOX4yqNxoHzMR2akEB2xfpnWUzkZokmgWDg==} + + '@vitest/ui@2.1.8': + resolution: {integrity: sha512-5zPJ1fs0ixSVSs5+5V2XJjXLmNzjugHRyV11RqxYVR+oMcogZ9qTuSfKW+OcTV0JeFNznI83BNylzH6SSNJ1+w==} + peerDependencies: + vitest: 2.1.8 + + '@vitest/utils@2.1.8': + resolution: {integrity: sha512-dwSoui6djdwbfFmIgbIjX2ZhIoG7Ex/+xpxyiEgIGzjliY8xGkcpITKTlp6B4MgtGkF2ilvm97cPM96XZaAgcA==} + + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn@8.14.0: + resolution: {integrity: sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==} + engines: {node: '>=0.4.0'} + hasBin: true + + agent-base@7.1.3: + resolution: {integrity: sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==} + engines: {node: '>= 14'} + + ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@5.2.0: + resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} + engines: {node: '>=10'} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + aria-query@5.3.0: + resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} + + aria-query@5.3.2: + resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} + engines: {node: '>= 0.4'} + + array-buffer-byte-length@1.0.2: + resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==} + engines: {node: '>= 0.4'} + + array-includes@3.1.8: + resolution: {integrity: sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==} + engines: {node: '>= 0.4'} + + array.prototype.findlast@1.2.5: + resolution: {integrity: sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==} + engines: {node: '>= 0.4'} + + array.prototype.findlastindex@1.2.5: + resolution: {integrity: sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==} + engines: {node: '>= 0.4'} + + array.prototype.flat@1.3.3: + resolution: {integrity: sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==} + engines: {node: '>= 0.4'} + + array.prototype.flatmap@1.3.3: + resolution: {integrity: sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==} + engines: {node: '>= 0.4'} + + array.prototype.tosorted@1.1.4: + resolution: {integrity: sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==} + engines: {node: '>= 0.4'} + + arraybuffer.prototype.slice@1.0.4: + resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==} + engines: {node: '>= 0.4'} + + assertion-error@2.0.1: + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} + engines: {node: '>=12'} + + ast-types-flow@0.0.8: + resolution: {integrity: sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==} + + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} + engines: {node: '>= 0.4'} + + axe-core@4.10.2: + resolution: {integrity: sha512-RE3mdQ7P3FRSe7eqCWoeQ/Z9QXrtniSjp1wUjt5nRC3WIpz5rSCve6o3fsZ2aCpJtrZjSZgjwXAoTO5k4tEI0w==} + engines: {node: '>=4'} + + axobject-query@4.1.0: + resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} + engines: {node: '>= 0.4'} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + + brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} + engines: {node: '>=8'} + + call-bind-apply-helpers@1.0.1: + resolution: {integrity: sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==} + engines: {node: '>= 0.4'} + + call-bind@1.0.8: + resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==} + engines: {node: '>= 0.4'} + + call-bound@1.0.3: + resolution: {integrity: sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==} + engines: {node: '>= 0.4'} + + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + + chai@5.1.2: + resolution: {integrity: sha512-aGtmf24DW6MLHHG5gCx4zaI3uBq3KRtxeVs0DjFH6Z0rDNbsvTxFASFvdj79pxjxZ8/5u3PIiN3IwEIQkiiuPw==} + engines: {node: '>=12'} + + chalk@3.0.0: + resolution: {integrity: sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==} + engines: {node: '>=8'} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + check-error@2.1.1: + resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} + engines: {node: '>= 16'} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + confusing-browser-globals@1.0.11: + resolution: {integrity: sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + css.escape@1.5.1: + resolution: {integrity: sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==} + + cssstyle@4.1.0: + resolution: {integrity: sha512-h66W1URKpBS5YMI/V8PyXvTMFT8SupJ1IzoIV8IeBC/ji8WVmrO8dGlTi+2dh6whmdk6BiKJLD/ZBkhWbcg6nA==} + engines: {node: '>=18'} + + damerau-levenshtein@1.0.8: + resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==} + + data-urls@5.0.0: + resolution: {integrity: sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==} + engines: {node: '>=18'} + + data-view-buffer@1.0.2: + resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==} + engines: {node: '>= 0.4'} + + data-view-byte-length@1.0.2: + resolution: {integrity: sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==} + engines: {node: '>= 0.4'} + + data-view-byte-offset@1.0.1: + resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==} + engines: {node: '>= 0.4'} + + debug@3.2.7: + resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@4.4.0: + resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decimal.js@10.4.3: + resolution: {integrity: sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==} + + deep-eql@5.0.2: + resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} + engines: {node: '>=6'} + + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + + define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} + engines: {node: '>= 0.4'} + + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + + dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + + doctrine@2.1.0: + resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} + engines: {node: '>=0.10.0'} + + dom-accessibility-api@0.5.16: + resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==} + + dom-accessibility-api@0.6.3: + resolution: {integrity: sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==} + + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + + es-abstract@1.23.9: + resolution: {integrity: sha512-py07lI0wjxAC/DcfK1S6G7iANonniZwTISvdPzk9hzeH0IZIshbuuFxLIU96OyF89Yb9hiqWn8M/bY83KY5vzA==} + engines: {node: '>= 0.4'} + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-iterator-helpers@1.2.1: + resolution: {integrity: sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w==} + engines: {node: '>= 0.4'} + + es-module-lexer@1.6.0: + resolution: {integrity: sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==} + + es-object-atoms@1.0.0: + resolution: {integrity: sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==} + engines: {node: '>= 0.4'} + + es-set-tostringtag@2.1.0: + resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} + engines: {node: '>= 0.4'} + + es-shim-unscopables@1.0.2: + resolution: {integrity: sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==} + + es-to-primitive@1.3.0: + resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} + engines: {node: '>= 0.4'} + + esbuild@0.21.5: + resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} + engines: {node: '>=12'} + hasBin: true + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + eslint-config-airbnb-base@15.0.0: + resolution: {integrity: sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==} + engines: {node: ^10.12.0 || >=12.0.0} + peerDependencies: + eslint: ^7.32.0 || ^8.2.0 + eslint-plugin-import: ^2.25.2 + + eslint-config-airbnb-typescript@18.0.0: + resolution: {integrity: sha512-oc+Lxzgzsu8FQyFVa4QFaVKiitTYiiW3frB9KYW5OWdPrqFc7FzxgB20hP4cHMlr+MBzGcLl3jnCOVOydL9mIg==} + peerDependencies: + '@typescript-eslint/eslint-plugin': ^7.0.0 + '@typescript-eslint/parser': ^7.0.0 + eslint: ^8.56.0 + + eslint-config-airbnb@19.0.4: + resolution: {integrity: sha512-T75QYQVQX57jiNgpF9r1KegMICE94VYwoFQyMGhrvc+lB8YF2E/M/PYDaQe1AJcWaEgqLE+ErXV1Og/+6Vyzew==} + engines: {node: ^10.12.0 || ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^7.32.0 || ^8.2.0 + eslint-plugin-import: ^2.25.3 + eslint-plugin-jsx-a11y: ^6.5.1 + eslint-plugin-react: ^7.28.0 + eslint-plugin-react-hooks: ^4.3.0 + + eslint-config-prettier@9.1.0: + resolution: {integrity: sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==} + hasBin: true + peerDependencies: + eslint: '>=7.0.0' + + eslint-import-resolver-node@0.3.9: + resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} + + eslint-module-utils@2.12.0: + resolution: {integrity: sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: '*' + eslint-import-resolver-node: '*' + eslint-import-resolver-typescript: '*' + eslint-import-resolver-webpack: '*' + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + eslint: + optional: true + eslint-import-resolver-node: + optional: true + eslint-import-resolver-typescript: + optional: true + eslint-import-resolver-webpack: + optional: true + + eslint-plugin-import@2.31.0: + resolution: {integrity: sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9 + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + + eslint-plugin-jsx-a11y@6.10.2: + resolution: {integrity: sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q==} + engines: {node: '>=4.0'} + peerDependencies: + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9 + + eslint-plugin-prettier@5.2.1: + resolution: {integrity: sha512-gH3iR3g4JfF+yYPaJYkN7jEl9QbweL/YfkoRlNnuIEHEz1vHVlCmWOS+eGGiRuzHQXdJFCOTxRgvju9b8VUmrw==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + '@types/eslint': '>=8.0.0' + eslint: '>=8.0.0' + eslint-config-prettier: '*' + prettier: '>=3.0.0' + peerDependenciesMeta: + '@types/eslint': + optional: true + eslint-config-prettier: + optional: true + + eslint-plugin-react-hooks@5.1.0: + resolution: {integrity: sha512-mpJRtPgHN2tNAvZ35AMfqeB3Xqeo273QxrHJsbBEPWODRM4r0yB6jfoROqKEYrOn27UtRPpcpHc2UqyBSuUNTw==} + 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 + + eslint-plugin-react@7.37.3: + resolution: {integrity: sha512-DomWuTQPFYZwF/7c9W2fkKkStqZmBd3uugfqBYLdkZ3Hii23WzZuOLUskGxB8qkSKqftxEeGL1TB2kMhrce0jA==} + engines: {node: '>=4'} + peerDependencies: + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7 + + eslint-scope@8.2.0: + resolution: {integrity: sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-visitor-keys@4.2.0: + resolution: {integrity: sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint@9.17.0: + resolution: {integrity: sha512-evtlNcpJg+cZLcnVKwsai8fExnqjGPicK7gnUtlNuzu+Fv9bI0aLpND5T44VLQtoMEnI57LoXO9XAkIXwohKrA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + hasBin: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true + + espree@10.3.0: + resolution: {integrity: sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + esquery@1.6.0: + resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} + engines: {node: '>=0.10'} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + expect-type@1.1.0: + resolution: {integrity: sha512-bFi65yM+xZgk+u/KRIpekdSYkTB5W1pEf0Lt8Q8Msh7b+eQ7LXVtIB1Bkm4fvclDEL1b2CZkMhv2mOeF8tMdkA==} + engines: {node: '>=12.0.0'} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-diff@1.3.0: + resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} + + fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} + engines: {node: '>=8.6.0'} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + + fastq@1.18.0: + resolution: {integrity: sha512-QKHXPW0hD8g4UET03SdOdunzSouc9N4AuHdsX8XNcTsuz+yYFILVNIX4l9yHABMhiEI9Db0JTTIpu0wB+Y1QQw==} + + fdir@6.4.2: + resolution: {integrity: sha512-KnhMXsKSPZlAhp7+IjUkRZKPb4fUyccpDrdFXbi4QL1qkmFh9kVY09Yox+n4MaOb3lHZ1Tv829C3oaaXoMYPDQ==} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + fflate@0.8.2: + resolution: {integrity: sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==} + + file-entry-cache@8.0.0: + resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} + engines: {node: '>=16.0.0'} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + flat-cache@4.0.1: + resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} + engines: {node: '>=16'} + + flatted@3.3.2: + resolution: {integrity: sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==} + + for-each@0.3.3: + resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} + + form-data@4.0.1: + resolution: {integrity: sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==} + engines: {node: '>= 6'} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + function.prototype.name@1.1.8: + resolution: {integrity: sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==} + engines: {node: '>= 0.4'} + + functions-have-names@1.2.3: + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + + get-intrinsic@1.2.7: + resolution: {integrity: sha512-VW6Pxhsrk0KAOqs3WEd0klDiF/+V7gQOpAvY1jVU/LHmaD/kQO4523aiJuikX/QAKYiW6x8Jh+RJej1almdtCA==} + engines: {node: '>= 0.4'} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + + get-symbol-description@1.1.0: + resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} + engines: {node: '>= 0.4'} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + + globals@14.0.0: + resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} + engines: {node: '>=18'} + + globalthis@1.0.4: + resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} + engines: {node: '>= 0.4'} + + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + + graphemer@1.4.0: + resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + + has-bigints@1.1.0: + resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==} + engines: {node: '>= 0.4'} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + + has-proto@1.2.0: + resolution: {integrity: sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==} + engines: {node: '>= 0.4'} + + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + html-encoding-sniffer@4.0.0: + resolution: {integrity: sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==} + engines: {node: '>=18'} + + http-proxy-agent@7.0.2: + resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} + engines: {node: '>= 14'} + + https-proxy-agent@7.0.6: + resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} + engines: {node: '>= 14'} + + iconv-lite@0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + import-fresh@3.3.0: + resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} + engines: {node: '>=6'} + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + indent-string@4.0.0: + resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} + engines: {node: '>=8'} + + internal-slot@1.1.0: + resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} + engines: {node: '>= 0.4'} + + is-array-buffer@3.0.5: + resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} + engines: {node: '>= 0.4'} + + is-async-function@2.1.0: + resolution: {integrity: sha512-GExz9MtyhlZyXYLxzlJRj5WUCE661zhDa1Yna52CN57AJsymh+DvXXjyveSioqSRdxvUrdKdvqB1b5cVKsNpWQ==} + engines: {node: '>= 0.4'} + + is-bigint@1.1.0: + resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==} + engines: {node: '>= 0.4'} + + is-boolean-object@1.2.1: + resolution: {integrity: sha512-l9qO6eFlUETHtuihLcYOaLKByJ1f+N4kthcU9YjHy3N+B3hWv0y/2Nd0mu/7lTFnRQHTrSdXF50HQ3bl5fEnng==} + engines: {node: '>= 0.4'} + + is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + + is-core-module@2.16.1: + resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} + engines: {node: '>= 0.4'} + + is-data-view@1.0.2: + resolution: {integrity: sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==} + engines: {node: '>= 0.4'} + + is-date-object@1.1.0: + resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==} + engines: {node: '>= 0.4'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-finalizationregistry@1.1.1: + resolution: {integrity: sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==} + engines: {node: '>= 0.4'} + + is-generator-function@1.1.0: + resolution: {integrity: sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==} + engines: {node: '>= 0.4'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-map@2.0.3: + resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} + engines: {node: '>= 0.4'} + + is-number-object@1.1.1: + resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==} + engines: {node: '>= 0.4'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-potential-custom-element-name@1.0.1: + resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} + + is-regex@1.2.1: + resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} + engines: {node: '>= 0.4'} + + is-set@2.0.3: + resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} + engines: {node: '>= 0.4'} + + is-shared-array-buffer@1.0.4: + resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==} + engines: {node: '>= 0.4'} + + is-string@1.1.1: + resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==} + engines: {node: '>= 0.4'} + + is-symbol@1.1.1: + resolution: {integrity: sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==} + engines: {node: '>= 0.4'} + + is-typed-array@1.1.15: + resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} + engines: {node: '>= 0.4'} + + is-weakmap@2.0.2: + resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} + engines: {node: '>= 0.4'} + + is-weakref@1.1.0: + resolution: {integrity: sha512-SXM8Nwyys6nT5WP6pltOwKytLV7FqQ4UiibxVmW+EIosHcmCqkkjViTb5SNssDlkCiEYRP1/pdWUKVvZBmsR2Q==} + engines: {node: '>= 0.4'} + + is-weakset@2.0.4: + resolution: {integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==} + engines: {node: '>= 0.4'} + + isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + iterator.prototype@1.1.5: + resolution: {integrity: sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==} + engines: {node: '>= 0.4'} + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + + jsdom@25.0.1: + resolution: {integrity: sha512-8i7LzZj7BF8uplX+ZyOlIz86V6TAsSs+np6m1kpW9u0JWi4z/1t+FzcK1aek+ybTnAC4KhBL4uXCNT0wcUIeCw==} + engines: {node: '>=18'} + peerDependencies: + canvas: ^2.11.2 + peerDependenciesMeta: + canvas: + optional: true + + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + + json5@1.0.2: + resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} + hasBin: true + + jsx-ast-utils@3.3.5: + resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} + engines: {node: '>=4.0'} + + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + + language-subtag-registry@0.3.23: + resolution: {integrity: sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==} + + language-tags@1.0.9: + resolution: {integrity: sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==} + engines: {node: '>=0.10'} + + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + + lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + + loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + + loupe@3.1.2: + resolution: {integrity: sha512-23I4pFZHmAemUnz8WZXbYRSKYj801VDaNv9ETuMh7IrMc7VuVVSo+Z9iLE3ni30+U48iDWfi30d3twAXBYmnCg==} + + lz-string@1.5.0: + resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} + hasBin: true + + magic-string@0.30.17: + resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + min-indent@1.0.1: + resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} + engines: {node: '>=4'} + + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + engines: {node: '>=16 || 14 >=14.17'} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + mrmime@2.0.0: + resolution: {integrity: sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==} + engines: {node: '>=10'} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + nanoid@3.3.8: + resolution: {integrity: sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + + nwsapi@2.2.16: + resolution: {integrity: sha512-F1I/bimDpj3ncaNDhfyMWuFqmQDBwDB0Fogc2qpL3BWvkQteFD/8BzWuIRl83rq0DXfm8SGt/HFhLXZyljTXcQ==} + + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + object-inspect@1.13.3: + resolution: {integrity: sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==} + engines: {node: '>= 0.4'} + + object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + + object.assign@4.1.7: + resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==} + engines: {node: '>= 0.4'} + + object.entries@1.1.8: + resolution: {integrity: sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==} + engines: {node: '>= 0.4'} + + object.fromentries@2.0.8: + resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==} + engines: {node: '>= 0.4'} + + object.groupby@1.0.3: + resolution: {integrity: sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==} + engines: {node: '>= 0.4'} + + object.values@1.2.1: + resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==} + engines: {node: '>= 0.4'} + + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} + + own-keys@1.0.1: + resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} + engines: {node: '>= 0.4'} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + + parse5@7.2.1: + resolution: {integrity: sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + pathe@1.1.2: + resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} + + pathval@2.0.0: + resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==} + engines: {node: '>= 14.16'} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + picomatch@4.0.2: + resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} + engines: {node: '>=12'} + + possible-typed-array-names@1.0.0: + resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} + engines: {node: '>= 0.4'} + + postcss@8.4.49: + resolution: {integrity: sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==} + engines: {node: ^10 || ^12 || >=14} + + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + + prettier-linter-helpers@1.0.0: + resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==} + engines: {node: '>=6.0.0'} + + prettier@3.4.2: + resolution: {integrity: sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==} + engines: {node: '>=14'} + hasBin: true + + pretty-format@27.5.1: + resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + prop-types@15.8.1: + resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + react-is@16.13.1: + resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + + react-is@17.0.2: + resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} + + redent@3.0.0: + resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==} + engines: {node: '>=8'} + + reflect.getprototypeof@1.0.10: + resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} + engines: {node: '>= 0.4'} + + regenerator-runtime@0.14.1: + resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} + + regexp.prototype.flags@1.5.4: + resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} + engines: {node: '>= 0.4'} + + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + + resolve@1.22.10: + resolution: {integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==} + engines: {node: '>= 0.4'} + hasBin: true + + resolve@2.0.0-next.5: + resolution: {integrity: sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==} + hasBin: true + + reusify@1.0.4: + resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + rollup@4.30.1: + resolution: {integrity: sha512-mlJ4glW020fPuLi7DkM/lN97mYEZGWeqBnrljzN0gs7GLctqX3lNWxKQ7Gl712UAX+6fog/L3jh4gb7R6aVi3w==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + rrweb-cssom@0.7.1: + resolution: {integrity: sha512-TrEMa7JGdVm0UThDJSx7ddw5nVm3UJS9o9CCIZ72B1vSyEZoziDqBYP3XIoi/12lKrJR8rE3jeFHMok2F/Mnsg==} + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + safe-array-concat@1.1.3: + resolution: {integrity: sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==} + engines: {node: '>=0.4'} + + safe-push-apply@1.0.0: + resolution: {integrity: sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==} + engines: {node: '>= 0.4'} + + safe-regex-test@1.1.0: + resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==} + engines: {node: '>= 0.4'} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + saxes@6.0.0: + resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==} + engines: {node: '>=v12.22.7'} + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + semver@7.6.3: + resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} + engines: {node: '>=10'} + hasBin: true + + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + + set-function-name@2.0.2: + resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} + engines: {node: '>= 0.4'} + + set-proto@1.0.0: + resolution: {integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==} + engines: {node: '>= 0.4'} + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + side-channel-list@1.0.0: + resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} + engines: {node: '>= 0.4'} + + side-channel-map@1.0.1: + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} + engines: {node: '>= 0.4'} + + side-channel-weakmap@1.0.2: + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} + engines: {node: '>= 0.4'} + + side-channel@1.1.0: + resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} + engines: {node: '>= 0.4'} + + siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + + sirv@3.0.0: + resolution: {integrity: sha512-BPwJGUeDaDCHihkORDchNyyTvWFhcusy1XMmhEVTQTwGeybFbp8YEmB+njbPnth1FibULBSBVwCQni25XlCUDg==} + engines: {node: '>=18'} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + + std-env@3.8.0: + resolution: {integrity: sha512-Bc3YwwCB+OzldMxOXJIIvC6cPRWr/LxOp48CdQTOkPyk/t4JWWJbrilwBd7RJzKV8QW7tJkcgAmeuLLJugl5/w==} + + string.prototype.includes@2.0.1: + resolution: {integrity: sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==} + engines: {node: '>= 0.4'} + + string.prototype.matchall@4.0.12: + resolution: {integrity: sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==} + engines: {node: '>= 0.4'} + + string.prototype.repeat@1.0.0: + resolution: {integrity: sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==} + + string.prototype.trim@1.2.10: + resolution: {integrity: sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==} + engines: {node: '>= 0.4'} + + string.prototype.trimend@1.0.9: + resolution: {integrity: sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==} + engines: {node: '>= 0.4'} + + string.prototype.trimstart@1.0.8: + resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} + engines: {node: '>= 0.4'} + + strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + + strip-indent@3.0.0: + resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} + engines: {node: '>=8'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + symbol-tree@3.2.4: + resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} + + synckit@0.9.2: + resolution: {integrity: sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw==} + engines: {node: ^14.18.0 || >=16.0.0} + + tinybench@2.9.0: + resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} + + tinyexec@0.3.2: + resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} + + tinyglobby@0.2.10: + resolution: {integrity: sha512-Zc+8eJlFMvgatPZTl6A9L/yht8QqdmUNtURHaKZLmKBE12hNPSrqNkUp2cs3M/UKmNVVAMFQYSjYIVHDjW5zew==} + engines: {node: '>=12.0.0'} + + tinypool@1.0.2: + resolution: {integrity: sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA==} + engines: {node: ^18.0.0 || >=20.0.0} + + tinyrainbow@1.2.0: + resolution: {integrity: sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==} + engines: {node: '>=14.0.0'} + + tinyspy@3.0.2: + resolution: {integrity: sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==} + engines: {node: '>=14.0.0'} + + tldts-core@6.1.71: + resolution: {integrity: sha512-LRbChn2YRpic1KxY+ldL1pGXN/oVvKfCVufwfVzEQdFYNo39uF7AJa/WXdo+gYO7PTvdfkCPCed6Hkvz/kR7jg==} + + tldts@6.1.71: + resolution: {integrity: sha512-LQIHmHnuzfZgZWAf2HzL83TIIrD8NhhI0DVxqo9/FdOd4ilec+NTNZOlDZf7EwrTNoutccbsHjvWHYXLAtvxjw==} + hasBin: true + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + totalist@3.0.1: + resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} + engines: {node: '>=6'} + + tough-cookie@5.0.0: + resolution: {integrity: sha512-FRKsF7cz96xIIeMZ82ehjC3xW2E+O2+v11udrDYewUbszngYhsGa8z6YUMMzO9QJZzzyd0nGGXnML/TReX6W8Q==} + engines: {node: '>=16'} + + tr46@5.0.0: + resolution: {integrity: sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==} + engines: {node: '>=18'} + + ts-api-utils@2.0.0: + resolution: {integrity: sha512-xCt/TOAc+EOHS1XPnijD3/yzpH6qg2xppZO1YDqGoVsNXfQfzHpOdNuXwrwOU8u4ITXJyDCTyt8w5g1sZv9ynQ==} + engines: {node: '>=18.12'} + peerDependencies: + typescript: '>=4.8.4' + + tsconfig-paths@3.15.0: + resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + + typed-array-buffer@1.0.3: + resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} + engines: {node: '>= 0.4'} + + typed-array-byte-length@1.0.3: + resolution: {integrity: sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==} + engines: {node: '>= 0.4'} + + typed-array-byte-offset@1.0.4: + resolution: {integrity: sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==} + engines: {node: '>= 0.4'} + + typed-array-length@1.0.7: + resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==} + engines: {node: '>= 0.4'} + + typescript@5.7.2: + resolution: {integrity: sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==} + engines: {node: '>=14.17'} + hasBin: true + + unbox-primitive@1.1.0: + resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} + engines: {node: '>= 0.4'} + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + vite-node@2.1.8: + resolution: {integrity: sha512-uPAwSr57kYjAUux+8E2j0q0Fxpn8M9VoyfGiRI8Kfktz9NcYMCenwY5RnZxnF1WTu3TGiYipirIzacLL3VVGFg==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + + vite@5.4.11: + resolution: {integrity: sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || >=20.0.0 + less: '*' + lightningcss: ^1.21.0 + sass: '*' + sass-embedded: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + + vitest@2.1.8: + resolution: {integrity: sha512-1vBKTZskHw/aosXqQUlVWWlGUxSJR8YtiyZDJAFeW2kPAeX6S3Sool0mjspO+kXLuxVWlEDDowBAeqeAQefqLQ==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@types/node': ^18.0.0 || >=20.0.0 + '@vitest/browser': 2.1.8 + '@vitest/ui': 2.1.8 + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@types/node': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + + w3c-xmlserializer@5.0.0: + resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==} + engines: {node: '>=18'} + + webidl-conversions@7.0.0: + resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==} + engines: {node: '>=12'} + + whatwg-encoding@3.1.1: + resolution: {integrity: sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==} + engines: {node: '>=18'} + + whatwg-mimetype@4.0.0: + resolution: {integrity: sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==} + engines: {node: '>=18'} + + whatwg-url@14.1.0: + resolution: {integrity: sha512-jlf/foYIKywAt3x/XWKZ/3rz8OSJPiWktjmk891alJUEjiVxKX9LEO92qH3hv4aJ0mN3MWPvGMCy8jQi95xK4w==} + engines: {node: '>=18'} + + which-boxed-primitive@1.1.1: + resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==} + engines: {node: '>= 0.4'} + + which-builtin-type@1.2.1: + resolution: {integrity: sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==} + engines: {node: '>= 0.4'} + + which-collection@1.0.2: + resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} + engines: {node: '>= 0.4'} + + which-typed-array@1.1.18: + resolution: {integrity: sha512-qEcY+KJYlWyLH9vNbsr6/5j59AXk5ni5aakf8ldzBvGde6Iz4sxZGkJyWSAueTG7QhOvNRYb1lDdFmL5Td0QKA==} + engines: {node: '>= 0.4'} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + why-is-node-running@2.3.0: + resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} + engines: {node: '>=8'} + hasBin: true + + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + + ws@8.18.0: + resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + xml-name-validator@5.0.0: + resolution: {integrity: sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==} + engines: {node: '>=18'} + + xmlchars@2.2.0: + resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==} + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + +snapshots: + + '@adobe/css-tools@4.4.1': {} + + '@babel/code-frame@7.26.2': + dependencies: + '@babel/helper-validator-identifier': 7.25.9 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/helper-validator-identifier@7.25.9': {} + + '@babel/runtime@7.26.0': + dependencies: + regenerator-runtime: 0.14.1 + + '@esbuild/aix-ppc64@0.21.5': + optional: true + + '@esbuild/android-arm64@0.21.5': + optional: true + + '@esbuild/android-arm@0.21.5': + optional: true + + '@esbuild/android-x64@0.21.5': + optional: true + + '@esbuild/darwin-arm64@0.21.5': + optional: true + + '@esbuild/darwin-x64@0.21.5': + optional: true + + '@esbuild/freebsd-arm64@0.21.5': + optional: true + + '@esbuild/freebsd-x64@0.21.5': + optional: true + + '@esbuild/linux-arm64@0.21.5': + optional: true + + '@esbuild/linux-arm@0.21.5': + optional: true + + '@esbuild/linux-ia32@0.21.5': + optional: true + + '@esbuild/linux-loong64@0.21.5': + optional: true + + '@esbuild/linux-mips64el@0.21.5': + optional: true + + '@esbuild/linux-ppc64@0.21.5': + optional: true + + '@esbuild/linux-riscv64@0.21.5': + optional: true + + '@esbuild/linux-s390x@0.21.5': + optional: true + + '@esbuild/linux-x64@0.21.5': + optional: true + + '@esbuild/netbsd-x64@0.21.5': + optional: true + + '@esbuild/openbsd-x64@0.21.5': + optional: true + + '@esbuild/sunos-x64@0.21.5': + optional: true + + '@esbuild/win32-arm64@0.21.5': + optional: true + + '@esbuild/win32-ia32@0.21.5': + optional: true + + '@esbuild/win32-x64@0.21.5': + optional: true + + '@eslint-community/eslint-utils@4.4.1(eslint@9.17.0)': + dependencies: + eslint: 9.17.0 + eslint-visitor-keys: 3.4.3 + + '@eslint-community/regexpp@4.12.1': {} + + '@eslint/config-array@0.19.1': + dependencies: + '@eslint/object-schema': 2.1.5 + debug: 4.4.0 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + + '@eslint/core@0.9.1': + dependencies: + '@types/json-schema': 7.0.15 + + '@eslint/eslintrc@3.2.0': + dependencies: + ajv: 6.12.6 + debug: 4.4.0 + espree: 10.3.0 + globals: 14.0.0 + ignore: 5.3.2 + import-fresh: 3.3.0 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + '@eslint/js@9.17.0': {} + + '@eslint/object-schema@2.1.5': {} + + '@eslint/plugin-kit@0.2.4': + dependencies: + levn: 0.4.1 + + '@humanfs/core@0.19.1': {} + + '@humanfs/node@0.16.6': + dependencies: + '@humanfs/core': 0.19.1 + '@humanwhocodes/retry': 0.3.1 + + '@humanwhocodes/module-importer@1.0.1': {} + + '@humanwhocodes/retry@0.3.1': {} + + '@humanwhocodes/retry@0.4.1': {} + + '@jridgewell/sourcemap-codec@1.5.0': {} + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.18.0 + + '@pkgr/core@0.1.1': {} + + '@polka/url@1.0.0-next.28': {} + + '@rollup/rollup-android-arm-eabi@4.30.1': + optional: true + + '@rollup/rollup-android-arm64@4.30.1': + optional: true + + '@rollup/rollup-darwin-arm64@4.30.1': + optional: true + + '@rollup/rollup-darwin-x64@4.30.1': + optional: true + + '@rollup/rollup-freebsd-arm64@4.30.1': + optional: true + + '@rollup/rollup-freebsd-x64@4.30.1': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.30.1': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.30.1': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.30.1': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.30.1': + optional: true + + '@rollup/rollup-linux-loongarch64-gnu@4.30.1': + optional: true + + '@rollup/rollup-linux-powerpc64le-gnu@4.30.1': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.30.1': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.30.1': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.30.1': + optional: true + + '@rollup/rollup-linux-x64-musl@4.30.1': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.30.1': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.30.1': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.30.1': + optional: true + + '@rtsao/scc@1.1.0': {} + + '@testing-library/dom@10.4.0': + dependencies: + '@babel/code-frame': 7.26.2 + '@babel/runtime': 7.26.0 + '@types/aria-query': 5.0.4 + aria-query: 5.3.0 + chalk: 4.1.2 + dom-accessibility-api: 0.5.16 + lz-string: 1.5.0 + pretty-format: 27.5.1 + + '@testing-library/jest-dom@6.6.3': + dependencies: + '@adobe/css-tools': 4.4.1 + aria-query: 5.3.2 + chalk: 3.0.0 + css.escape: 1.5.1 + dom-accessibility-api: 0.6.3 + lodash: 4.17.21 + redent: 3.0.0 + + '@testing-library/user-event@14.5.2(@testing-library/dom@10.4.0)': + dependencies: + '@testing-library/dom': 10.4.0 + + '@types/aria-query@5.0.4': {} + + '@types/estree@1.0.6': {} + + '@types/json-schema@7.0.15': {} + + '@types/json5@0.0.29': {} + + '@typescript-eslint/eslint-plugin@8.19.1(@typescript-eslint/parser@8.19.1(eslint@9.17.0)(typescript@5.7.2))(eslint@9.17.0)(typescript@5.7.2)': + dependencies: + '@eslint-community/regexpp': 4.12.1 + '@typescript-eslint/parser': 8.19.1(eslint@9.17.0)(typescript@5.7.2) + '@typescript-eslint/scope-manager': 8.19.1 + '@typescript-eslint/type-utils': 8.19.1(eslint@9.17.0)(typescript@5.7.2) + '@typescript-eslint/utils': 8.19.1(eslint@9.17.0)(typescript@5.7.2) + '@typescript-eslint/visitor-keys': 8.19.1 + eslint: 9.17.0 + graphemer: 1.4.0 + ignore: 5.3.2 + natural-compare: 1.4.0 + ts-api-utils: 2.0.0(typescript@5.7.2) + typescript: 5.7.2 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@8.19.1(eslint@9.17.0)(typescript@5.7.2)': + dependencies: + '@typescript-eslint/scope-manager': 8.19.1 + '@typescript-eslint/types': 8.19.1 + '@typescript-eslint/typescript-estree': 8.19.1(typescript@5.7.2) + '@typescript-eslint/visitor-keys': 8.19.1 + debug: 4.4.0 + eslint: 9.17.0 + typescript: 5.7.2 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/scope-manager@8.19.1': + dependencies: + '@typescript-eslint/types': 8.19.1 + '@typescript-eslint/visitor-keys': 8.19.1 + + '@typescript-eslint/type-utils@8.19.1(eslint@9.17.0)(typescript@5.7.2)': + dependencies: + '@typescript-eslint/typescript-estree': 8.19.1(typescript@5.7.2) + '@typescript-eslint/utils': 8.19.1(eslint@9.17.0)(typescript@5.7.2) + debug: 4.4.0 + eslint: 9.17.0 + ts-api-utils: 2.0.0(typescript@5.7.2) + typescript: 5.7.2 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/types@8.19.1': {} + + '@typescript-eslint/typescript-estree@8.19.1(typescript@5.7.2)': + dependencies: + '@typescript-eslint/types': 8.19.1 + '@typescript-eslint/visitor-keys': 8.19.1 + debug: 4.4.0 + fast-glob: 3.3.3 + is-glob: 4.0.3 + minimatch: 9.0.5 + semver: 7.6.3 + ts-api-utils: 2.0.0(typescript@5.7.2) + typescript: 5.7.2 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@8.19.1(eslint@9.17.0)(typescript@5.7.2)': + dependencies: + '@eslint-community/eslint-utils': 4.4.1(eslint@9.17.0) + '@typescript-eslint/scope-manager': 8.19.1 + '@typescript-eslint/types': 8.19.1 + '@typescript-eslint/typescript-estree': 8.19.1(typescript@5.7.2) + eslint: 9.17.0 + typescript: 5.7.2 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/visitor-keys@8.19.1': + dependencies: + '@typescript-eslint/types': 8.19.1 + eslint-visitor-keys: 4.2.0 + + '@vitest/expect@2.1.8': + dependencies: + '@vitest/spy': 2.1.8 + '@vitest/utils': 2.1.8 + chai: 5.1.2 + tinyrainbow: 1.2.0 + + '@vitest/mocker@2.1.8(vite@5.4.11)': + dependencies: + '@vitest/spy': 2.1.8 + estree-walker: 3.0.3 + magic-string: 0.30.17 + optionalDependencies: + vite: 5.4.11 + + '@vitest/pretty-format@2.1.8': + dependencies: + tinyrainbow: 1.2.0 + + '@vitest/runner@2.1.8': + dependencies: + '@vitest/utils': 2.1.8 + pathe: 1.1.2 + + '@vitest/snapshot@2.1.8': + dependencies: + '@vitest/pretty-format': 2.1.8 + magic-string: 0.30.17 + pathe: 1.1.2 + + '@vitest/spy@2.1.8': + dependencies: + tinyspy: 3.0.2 + + '@vitest/ui@2.1.8(vitest@2.1.8)': + dependencies: + '@vitest/utils': 2.1.8 + fflate: 0.8.2 + flatted: 3.3.2 + pathe: 1.1.2 + sirv: 3.0.0 + tinyglobby: 0.2.10 + tinyrainbow: 1.2.0 + vitest: 2.1.8(@vitest/ui@2.1.8)(jsdom@25.0.1) + + '@vitest/utils@2.1.8': + dependencies: + '@vitest/pretty-format': 2.1.8 + loupe: 3.1.2 + tinyrainbow: 1.2.0 + + acorn-jsx@5.3.2(acorn@8.14.0): + dependencies: + acorn: 8.14.0 + + acorn@8.14.0: {} + + agent-base@7.1.3: {} + + ajv@6.12.6: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + ansi-regex@5.0.1: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@5.2.0: {} + + argparse@2.0.1: {} + + aria-query@5.3.0: + dependencies: + dequal: 2.0.3 + + aria-query@5.3.2: {} + + array-buffer-byte-length@1.0.2: + dependencies: + call-bound: 1.0.3 + is-array-buffer: 3.0.5 + + array-includes@3.1.8: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-object-atoms: 1.0.0 + get-intrinsic: 1.2.7 + is-string: 1.1.1 + + array.prototype.findlast@1.2.5: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-errors: 1.3.0 + es-object-atoms: 1.0.0 + es-shim-unscopables: 1.0.2 + + array.prototype.findlastindex@1.2.5: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-errors: 1.3.0 + es-object-atoms: 1.0.0 + es-shim-unscopables: 1.0.2 + + array.prototype.flat@1.3.3: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-shim-unscopables: 1.0.2 + + array.prototype.flatmap@1.3.3: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-shim-unscopables: 1.0.2 + + array.prototype.tosorted@1.1.4: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-errors: 1.3.0 + es-shim-unscopables: 1.0.2 + + arraybuffer.prototype.slice@1.0.4: + dependencies: + array-buffer-byte-length: 1.0.2 + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-errors: 1.3.0 + get-intrinsic: 1.2.7 + is-array-buffer: 3.0.5 + + assertion-error@2.0.1: {} + + ast-types-flow@0.0.8: {} + + asynckit@0.4.0: {} + + available-typed-arrays@1.0.7: + dependencies: + possible-typed-array-names: 1.0.0 + + axe-core@4.10.2: {} + + axobject-query@4.1.0: {} + + balanced-match@1.0.2: {} + + brace-expansion@1.1.11: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@2.0.1: + dependencies: + balanced-match: 1.0.2 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + cac@6.7.14: {} + + call-bind-apply-helpers@1.0.1: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + call-bind@1.0.8: + dependencies: + call-bind-apply-helpers: 1.0.1 + es-define-property: 1.0.1 + get-intrinsic: 1.2.7 + set-function-length: 1.2.2 + + call-bound@1.0.3: + dependencies: + call-bind-apply-helpers: 1.0.1 + get-intrinsic: 1.2.7 + + callsites@3.1.0: {} + + chai@5.1.2: + dependencies: + assertion-error: 2.0.1 + check-error: 2.1.1 + deep-eql: 5.0.2 + loupe: 3.1.2 + pathval: 2.0.0 + + chalk@3.0.0: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + check-error@2.1.1: {} + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + + concat-map@0.0.1: {} + + confusing-browser-globals@1.0.11: {} + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + css.escape@1.5.1: {} + + cssstyle@4.1.0: + dependencies: + rrweb-cssom: 0.7.1 + + damerau-levenshtein@1.0.8: {} + + data-urls@5.0.0: + dependencies: + whatwg-mimetype: 4.0.0 + whatwg-url: 14.1.0 + + data-view-buffer@1.0.2: + dependencies: + call-bound: 1.0.3 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + data-view-byte-length@1.0.2: + dependencies: + call-bound: 1.0.3 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + data-view-byte-offset@1.0.1: + dependencies: + call-bound: 1.0.3 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + debug@3.2.7: + dependencies: + ms: 2.1.3 + + debug@4.4.0: + dependencies: + ms: 2.1.3 + + decimal.js@10.4.3: {} + + deep-eql@5.0.2: {} + + deep-is@0.1.4: {} + + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.1 + es-errors: 1.3.0 + gopd: 1.2.0 + + define-properties@1.2.1: + dependencies: + define-data-property: 1.1.4 + has-property-descriptors: 1.0.2 + object-keys: 1.1.1 + + delayed-stream@1.0.0: {} + + dequal@2.0.3: {} + + doctrine@2.1.0: + dependencies: + esutils: 2.0.3 + + dom-accessibility-api@0.5.16: {} + + dom-accessibility-api@0.6.3: {} + + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.1 + es-errors: 1.3.0 + gopd: 1.2.0 + + emoji-regex@9.2.2: {} + + entities@4.5.0: {} + + es-abstract@1.23.9: + dependencies: + array-buffer-byte-length: 1.0.2 + arraybuffer.prototype.slice: 1.0.4 + available-typed-arrays: 1.0.7 + call-bind: 1.0.8 + call-bound: 1.0.3 + data-view-buffer: 1.0.2 + data-view-byte-length: 1.0.2 + data-view-byte-offset: 1.0.1 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.0.0 + es-set-tostringtag: 2.1.0 + es-to-primitive: 1.3.0 + function.prototype.name: 1.1.8 + get-intrinsic: 1.2.7 + get-proto: 1.0.1 + get-symbol-description: 1.1.0 + globalthis: 1.0.4 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + has-proto: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + internal-slot: 1.1.0 + is-array-buffer: 3.0.5 + is-callable: 1.2.7 + is-data-view: 1.0.2 + is-regex: 1.2.1 + is-shared-array-buffer: 1.0.4 + is-string: 1.1.1 + is-typed-array: 1.1.15 + is-weakref: 1.1.0 + math-intrinsics: 1.1.0 + object-inspect: 1.13.3 + object-keys: 1.1.1 + object.assign: 4.1.7 + own-keys: 1.0.1 + regexp.prototype.flags: 1.5.4 + safe-array-concat: 1.1.3 + safe-push-apply: 1.0.0 + safe-regex-test: 1.1.0 + set-proto: 1.0.0 + string.prototype.trim: 1.2.10 + string.prototype.trimend: 1.0.9 + string.prototype.trimstart: 1.0.8 + typed-array-buffer: 1.0.3 + typed-array-byte-length: 1.0.3 + typed-array-byte-offset: 1.0.4 + typed-array-length: 1.0.7 + unbox-primitive: 1.1.0 + which-typed-array: 1.1.18 + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-iterator-helpers@1.2.1: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.3 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-errors: 1.3.0 + es-set-tostringtag: 2.1.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.7 + globalthis: 1.0.4 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + has-proto: 1.2.0 + has-symbols: 1.1.0 + internal-slot: 1.1.0 + iterator.prototype: 1.1.5 + safe-array-concat: 1.1.3 + + es-module-lexer@1.6.0: {} + + es-object-atoms@1.0.0: + dependencies: + es-errors: 1.3.0 + + es-set-tostringtag@2.1.0: + dependencies: + es-errors: 1.3.0 + get-intrinsic: 1.2.7 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + es-shim-unscopables@1.0.2: + dependencies: + hasown: 2.0.2 + + es-to-primitive@1.3.0: + dependencies: + is-callable: 1.2.7 + is-date-object: 1.1.0 + is-symbol: 1.1.1 + + esbuild@0.21.5: + optionalDependencies: + '@esbuild/aix-ppc64': 0.21.5 + '@esbuild/android-arm': 0.21.5 + '@esbuild/android-arm64': 0.21.5 + '@esbuild/android-x64': 0.21.5 + '@esbuild/darwin-arm64': 0.21.5 + '@esbuild/darwin-x64': 0.21.5 + '@esbuild/freebsd-arm64': 0.21.5 + '@esbuild/freebsd-x64': 0.21.5 + '@esbuild/linux-arm': 0.21.5 + '@esbuild/linux-arm64': 0.21.5 + '@esbuild/linux-ia32': 0.21.5 + '@esbuild/linux-loong64': 0.21.5 + '@esbuild/linux-mips64el': 0.21.5 + '@esbuild/linux-ppc64': 0.21.5 + '@esbuild/linux-riscv64': 0.21.5 + '@esbuild/linux-s390x': 0.21.5 + '@esbuild/linux-x64': 0.21.5 + '@esbuild/netbsd-x64': 0.21.5 + '@esbuild/openbsd-x64': 0.21.5 + '@esbuild/sunos-x64': 0.21.5 + '@esbuild/win32-arm64': 0.21.5 + '@esbuild/win32-ia32': 0.21.5 + '@esbuild/win32-x64': 0.21.5 + + escape-string-regexp@4.0.0: {} + + eslint-config-airbnb-base@15.0.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.19.1(eslint@9.17.0)(typescript@5.7.2))(eslint@9.17.0))(eslint@9.17.0): + dependencies: + confusing-browser-globals: 1.0.11 + eslint: 9.17.0 + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.19.1(eslint@9.17.0)(typescript@5.7.2))(eslint@9.17.0) + object.assign: 4.1.7 + object.entries: 1.1.8 + semver: 6.3.1 + + eslint-config-airbnb-typescript@18.0.0(@typescript-eslint/eslint-plugin@8.19.1(@typescript-eslint/parser@8.19.1(eslint@9.17.0)(typescript@5.7.2))(eslint@9.17.0)(typescript@5.7.2))(@typescript-eslint/parser@8.19.1(eslint@9.17.0)(typescript@5.7.2))(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.19.1(eslint@9.17.0)(typescript@5.7.2))(eslint@9.17.0))(eslint@9.17.0): + dependencies: + '@typescript-eslint/eslint-plugin': 8.19.1(@typescript-eslint/parser@8.19.1(eslint@9.17.0)(typescript@5.7.2))(eslint@9.17.0)(typescript@5.7.2) + '@typescript-eslint/parser': 8.19.1(eslint@9.17.0)(typescript@5.7.2) + eslint: 9.17.0 + eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.19.1(eslint@9.17.0)(typescript@5.7.2))(eslint@9.17.0))(eslint@9.17.0) + transitivePeerDependencies: + - eslint-plugin-import + + eslint-config-airbnb@19.0.4(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.19.1(eslint@9.17.0)(typescript@5.7.2))(eslint@9.17.0))(eslint-plugin-jsx-a11y@6.10.2(eslint@9.17.0))(eslint-plugin-react-hooks@5.1.0(eslint@9.17.0))(eslint-plugin-react@7.37.3(eslint@9.17.0))(eslint@9.17.0): + dependencies: + eslint: 9.17.0 + eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.19.1(eslint@9.17.0)(typescript@5.7.2))(eslint@9.17.0))(eslint@9.17.0) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.19.1(eslint@9.17.0)(typescript@5.7.2))(eslint@9.17.0) + eslint-plugin-jsx-a11y: 6.10.2(eslint@9.17.0) + eslint-plugin-react: 7.37.3(eslint@9.17.0) + eslint-plugin-react-hooks: 5.1.0(eslint@9.17.0) + object.assign: 4.1.7 + object.entries: 1.1.8 + + eslint-config-prettier@9.1.0(eslint@9.17.0): + dependencies: + eslint: 9.17.0 + + eslint-import-resolver-node@0.3.9: + dependencies: + debug: 3.2.7 + is-core-module: 2.16.1 + resolve: 1.22.10 + transitivePeerDependencies: + - supports-color + + eslint-module-utils@2.12.0(@typescript-eslint/parser@8.19.1(eslint@9.17.0)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint@9.17.0): + dependencies: + debug: 3.2.7 + optionalDependencies: + '@typescript-eslint/parser': 8.19.1(eslint@9.17.0)(typescript@5.7.2) + eslint: 9.17.0 + eslint-import-resolver-node: 0.3.9 + transitivePeerDependencies: + - supports-color + + eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.19.1(eslint@9.17.0)(typescript@5.7.2))(eslint@9.17.0): + dependencies: + '@rtsao/scc': 1.1.0 + array-includes: 3.1.8 + array.prototype.findlastindex: 1.2.5 + array.prototype.flat: 1.3.3 + array.prototype.flatmap: 1.3.3 + debug: 3.2.7 + doctrine: 2.1.0 + eslint: 9.17.0 + eslint-import-resolver-node: 0.3.9 + eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.19.1(eslint@9.17.0)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint@9.17.0) + hasown: 2.0.2 + is-core-module: 2.16.1 + is-glob: 4.0.3 + minimatch: 3.1.2 + object.fromentries: 2.0.8 + object.groupby: 1.0.3 + object.values: 1.2.1 + semver: 6.3.1 + string.prototype.trimend: 1.0.9 + tsconfig-paths: 3.15.0 + optionalDependencies: + '@typescript-eslint/parser': 8.19.1(eslint@9.17.0)(typescript@5.7.2) + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + + eslint-plugin-jsx-a11y@6.10.2(eslint@9.17.0): + dependencies: + aria-query: 5.3.2 + array-includes: 3.1.8 + array.prototype.flatmap: 1.3.3 + ast-types-flow: 0.0.8 + axe-core: 4.10.2 + axobject-query: 4.1.0 + damerau-levenshtein: 1.0.8 + emoji-regex: 9.2.2 + eslint: 9.17.0 + hasown: 2.0.2 + jsx-ast-utils: 3.3.5 + language-tags: 1.0.9 + minimatch: 3.1.2 + object.fromentries: 2.0.8 + safe-regex-test: 1.1.0 + string.prototype.includes: 2.0.1 + + eslint-plugin-prettier@5.2.1(eslint-config-prettier@9.1.0(eslint@9.17.0))(eslint@9.17.0)(prettier@3.4.2): + dependencies: + eslint: 9.17.0 + prettier: 3.4.2 + prettier-linter-helpers: 1.0.0 + synckit: 0.9.2 + optionalDependencies: + eslint-config-prettier: 9.1.0(eslint@9.17.0) + + eslint-plugin-react-hooks@5.1.0(eslint@9.17.0): + dependencies: + eslint: 9.17.0 + + eslint-plugin-react@7.37.3(eslint@9.17.0): + dependencies: + array-includes: 3.1.8 + array.prototype.findlast: 1.2.5 + array.prototype.flatmap: 1.3.3 + array.prototype.tosorted: 1.1.4 + doctrine: 2.1.0 + es-iterator-helpers: 1.2.1 + eslint: 9.17.0 + estraverse: 5.3.0 + hasown: 2.0.2 + jsx-ast-utils: 3.3.5 + minimatch: 3.1.2 + object.entries: 1.1.8 + object.fromentries: 2.0.8 + object.values: 1.2.1 + prop-types: 15.8.1 + resolve: 2.0.0-next.5 + semver: 6.3.1 + string.prototype.matchall: 4.0.12 + string.prototype.repeat: 1.0.0 + + eslint-scope@8.2.0: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-visitor-keys@3.4.3: {} + + eslint-visitor-keys@4.2.0: {} + + eslint@9.17.0: + dependencies: + '@eslint-community/eslint-utils': 4.4.1(eslint@9.17.0) + '@eslint-community/regexpp': 4.12.1 + '@eslint/config-array': 0.19.1 + '@eslint/core': 0.9.1 + '@eslint/eslintrc': 3.2.0 + '@eslint/js': 9.17.0 + '@eslint/plugin-kit': 0.2.4 + '@humanfs/node': 0.16.6 + '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.4.1 + '@types/estree': 1.0.6 + '@types/json-schema': 7.0.15 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.6 + debug: 4.4.0 + escape-string-regexp: 4.0.0 + eslint-scope: 8.2.0 + eslint-visitor-keys: 4.2.0 + espree: 10.3.0 + esquery: 1.6.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 8.0.0 + find-up: 5.0.0 + glob-parent: 6.0.2 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + 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.4 + transitivePeerDependencies: + - supports-color + + espree@10.3.0: + dependencies: + acorn: 8.14.0 + acorn-jsx: 5.3.2(acorn@8.14.0) + eslint-visitor-keys: 4.2.0 + + esquery@1.6.0: + dependencies: + estraverse: 5.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@5.3.0: {} + + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.6 + + esutils@2.0.3: {} + + expect-type@1.1.0: {} + + fast-deep-equal@3.1.3: {} + + fast-diff@1.3.0: {} + + fast-glob@3.3.3: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fast-json-stable-stringify@2.1.0: {} + + fast-levenshtein@2.0.6: {} + + fastq@1.18.0: + dependencies: + reusify: 1.0.4 + + fdir@6.4.2(picomatch@4.0.2): + optionalDependencies: + picomatch: 4.0.2 + + fflate@0.8.2: {} + + file-entry-cache@8.0.0: + dependencies: + flat-cache: 4.0.1 + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + flat-cache@4.0.1: + dependencies: + flatted: 3.3.2 + keyv: 4.5.4 + + flatted@3.3.2: {} + + for-each@0.3.3: + dependencies: + is-callable: 1.2.7 + + form-data@4.0.1: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + function.prototype.name@1.1.8: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.3 + define-properties: 1.2.1 + functions-have-names: 1.2.3 + hasown: 2.0.2 + is-callable: 1.2.7 + + functions-have-names@1.2.3: {} + + get-intrinsic@1.2.7: + dependencies: + call-bind-apply-helpers: 1.0.1 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.0.0 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + math-intrinsics: 1.1.0 + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.0.0 + + get-symbol-description@1.1.0: + dependencies: + call-bound: 1.0.3 + es-errors: 1.3.0 + get-intrinsic: 1.2.7 + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + + globals@14.0.0: {} + + globalthis@1.0.4: + dependencies: + define-properties: 1.2.1 + gopd: 1.2.0 + + gopd@1.2.0: {} + + graphemer@1.4.0: {} + + has-bigints@1.1.0: {} + + has-flag@4.0.0: {} + + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.1 + + has-proto@1.2.0: + dependencies: + dunder-proto: 1.0.1 + + has-symbols@1.1.0: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.1.0 + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + html-encoding-sniffer@4.0.0: + dependencies: + whatwg-encoding: 3.1.1 + + http-proxy-agent@7.0.2: + dependencies: + agent-base: 7.1.3 + debug: 4.4.0 + transitivePeerDependencies: + - supports-color + + https-proxy-agent@7.0.6: + dependencies: + agent-base: 7.1.3 + debug: 4.4.0 + transitivePeerDependencies: + - supports-color + + iconv-lite@0.6.3: + dependencies: + safer-buffer: 2.1.2 + + ignore@5.3.2: {} + + import-fresh@3.3.0: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + imurmurhash@0.1.4: {} + + indent-string@4.0.0: {} + + internal-slot@1.1.0: + dependencies: + es-errors: 1.3.0 + hasown: 2.0.2 + side-channel: 1.1.0 + + is-array-buffer@3.0.5: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.3 + get-intrinsic: 1.2.7 + + is-async-function@2.1.0: + dependencies: + call-bound: 1.0.3 + get-proto: 1.0.1 + has-tostringtag: 1.0.2 + safe-regex-test: 1.1.0 + + is-bigint@1.1.0: + dependencies: + has-bigints: 1.1.0 + + is-boolean-object@1.2.1: + dependencies: + call-bound: 1.0.3 + has-tostringtag: 1.0.2 + + is-callable@1.2.7: {} + + is-core-module@2.16.1: + dependencies: + hasown: 2.0.2 + + is-data-view@1.0.2: + dependencies: + call-bound: 1.0.3 + get-intrinsic: 1.2.7 + is-typed-array: 1.1.15 + + is-date-object@1.1.0: + dependencies: + call-bound: 1.0.3 + has-tostringtag: 1.0.2 + + is-extglob@2.1.1: {} + + is-finalizationregistry@1.1.1: + dependencies: + call-bound: 1.0.3 + + is-generator-function@1.1.0: + dependencies: + call-bound: 1.0.3 + get-proto: 1.0.1 + has-tostringtag: 1.0.2 + safe-regex-test: 1.1.0 + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-map@2.0.3: {} + + is-number-object@1.1.1: + dependencies: + call-bound: 1.0.3 + has-tostringtag: 1.0.2 + + is-number@7.0.0: {} + + is-potential-custom-element-name@1.0.1: {} + + is-regex@1.2.1: + dependencies: + call-bound: 1.0.3 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + is-set@2.0.3: {} + + is-shared-array-buffer@1.0.4: + dependencies: + call-bound: 1.0.3 + + is-string@1.1.1: + dependencies: + call-bound: 1.0.3 + has-tostringtag: 1.0.2 + + is-symbol@1.1.1: + dependencies: + call-bound: 1.0.3 + has-symbols: 1.1.0 + safe-regex-test: 1.1.0 + + is-typed-array@1.1.15: + dependencies: + which-typed-array: 1.1.18 + + is-weakmap@2.0.2: {} + + is-weakref@1.1.0: + dependencies: + call-bound: 1.0.3 + + is-weakset@2.0.4: + dependencies: + call-bound: 1.0.3 + get-intrinsic: 1.2.7 + + isarray@2.0.5: {} + + isexe@2.0.0: {} + + iterator.prototype@1.1.5: + dependencies: + define-data-property: 1.1.4 + es-object-atoms: 1.0.0 + get-intrinsic: 1.2.7 + get-proto: 1.0.1 + has-symbols: 1.1.0 + set-function-name: 2.0.2 + + js-tokens@4.0.0: {} + + js-yaml@4.1.0: + dependencies: + argparse: 2.0.1 + + jsdom@25.0.1: + dependencies: + cssstyle: 4.1.0 + data-urls: 5.0.0 + decimal.js: 10.4.3 + form-data: 4.0.1 + html-encoding-sniffer: 4.0.0 + http-proxy-agent: 7.0.2 + https-proxy-agent: 7.0.6 + is-potential-custom-element-name: 1.0.1 + nwsapi: 2.2.16 + parse5: 7.2.1 + rrweb-cssom: 0.7.1 + saxes: 6.0.0 + symbol-tree: 3.2.4 + tough-cookie: 5.0.0 + w3c-xmlserializer: 5.0.0 + webidl-conversions: 7.0.0 + whatwg-encoding: 3.1.1 + whatwg-mimetype: 4.0.0 + whatwg-url: 14.1.0 + ws: 8.18.0 + xml-name-validator: 5.0.0 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + json-buffer@3.0.1: {} + + json-schema-traverse@0.4.1: {} + + json-stable-stringify-without-jsonify@1.0.1: {} + + json5@1.0.2: + dependencies: + minimist: 1.2.8 + + jsx-ast-utils@3.3.5: + dependencies: + array-includes: 3.1.8 + array.prototype.flat: 1.3.3 + object.assign: 4.1.7 + object.values: 1.2.1 + + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + + language-subtag-registry@0.3.23: {} + + language-tags@1.0.9: + dependencies: + language-subtag-registry: 0.3.23 + + levn@0.4.1: + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + lodash.merge@4.6.2: {} + + lodash@4.17.21: {} + + loose-envify@1.4.0: + dependencies: + js-tokens: 4.0.0 + + loupe@3.1.2: {} + + lz-string@1.5.0: {} + + magic-string@0.30.17: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.0 + + math-intrinsics@1.1.0: {} + + merge2@1.4.1: {} + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + + mime-db@1.52.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + min-indent@1.0.1: {} + + minimatch@3.1.2: + dependencies: + brace-expansion: 1.1.11 + + minimatch@9.0.5: + dependencies: + brace-expansion: 2.0.1 + + minimist@1.2.8: {} + + mrmime@2.0.0: {} + + ms@2.1.3: {} + + nanoid@3.3.8: {} + + natural-compare@1.4.0: {} + + nwsapi@2.2.16: {} + + object-assign@4.1.1: {} + + object-inspect@1.13.3: {} + + object-keys@1.1.1: {} + + object.assign@4.1.7: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.3 + define-properties: 1.2.1 + es-object-atoms: 1.0.0 + has-symbols: 1.1.0 + object-keys: 1.1.1 + + object.entries@1.1.8: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-object-atoms: 1.0.0 + + object.fromentries@2.0.8: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-object-atoms: 1.0.0 + + object.groupby@1.0.3: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + + object.values@1.2.1: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.3 + define-properties: 1.2.1 + es-object-atoms: 1.0.0 + + optionator@0.9.4: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.5 + + own-keys@1.0.1: + dependencies: + get-intrinsic: 1.2.7 + object-keys: 1.1.1 + safe-push-apply: 1.0.0 + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + + parse5@7.2.1: + dependencies: + entities: 4.5.0 + + path-exists@4.0.0: {} + + path-key@3.1.1: {} + + path-parse@1.0.7: {} + + pathe@1.1.2: {} + + pathval@2.0.0: {} + + picocolors@1.1.1: {} + + picomatch@2.3.1: {} + + picomatch@4.0.2: {} + + possible-typed-array-names@1.0.0: {} + + postcss@8.4.49: + dependencies: + nanoid: 3.3.8 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + prelude-ls@1.2.1: {} + + prettier-linter-helpers@1.0.0: + dependencies: + fast-diff: 1.3.0 + + prettier@3.4.2: {} + + pretty-format@27.5.1: + dependencies: + ansi-regex: 5.0.1 + ansi-styles: 5.2.0 + react-is: 17.0.2 + + prop-types@15.8.1: + dependencies: + loose-envify: 1.4.0 + object-assign: 4.1.1 + react-is: 16.13.1 + + punycode@2.3.1: {} + + queue-microtask@1.2.3: {} + + react-is@16.13.1: {} + + react-is@17.0.2: {} + + redent@3.0.0: + dependencies: + indent-string: 4.0.0 + strip-indent: 3.0.0 + + reflect.getprototypeof@1.0.10: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-errors: 1.3.0 + es-object-atoms: 1.0.0 + get-intrinsic: 1.2.7 + get-proto: 1.0.1 + which-builtin-type: 1.2.1 + + regenerator-runtime@0.14.1: {} + + regexp.prototype.flags@1.5.4: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-errors: 1.3.0 + get-proto: 1.0.1 + gopd: 1.2.0 + set-function-name: 2.0.2 + + resolve-from@4.0.0: {} + + resolve@1.22.10: + dependencies: + is-core-module: 2.16.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + resolve@2.0.0-next.5: + dependencies: + is-core-module: 2.16.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + reusify@1.0.4: {} + + rollup@4.30.1: + dependencies: + '@types/estree': 1.0.6 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.30.1 + '@rollup/rollup-android-arm64': 4.30.1 + '@rollup/rollup-darwin-arm64': 4.30.1 + '@rollup/rollup-darwin-x64': 4.30.1 + '@rollup/rollup-freebsd-arm64': 4.30.1 + '@rollup/rollup-freebsd-x64': 4.30.1 + '@rollup/rollup-linux-arm-gnueabihf': 4.30.1 + '@rollup/rollup-linux-arm-musleabihf': 4.30.1 + '@rollup/rollup-linux-arm64-gnu': 4.30.1 + '@rollup/rollup-linux-arm64-musl': 4.30.1 + '@rollup/rollup-linux-loongarch64-gnu': 4.30.1 + '@rollup/rollup-linux-powerpc64le-gnu': 4.30.1 + '@rollup/rollup-linux-riscv64-gnu': 4.30.1 + '@rollup/rollup-linux-s390x-gnu': 4.30.1 + '@rollup/rollup-linux-x64-gnu': 4.30.1 + '@rollup/rollup-linux-x64-musl': 4.30.1 + '@rollup/rollup-win32-arm64-msvc': 4.30.1 + '@rollup/rollup-win32-ia32-msvc': 4.30.1 + '@rollup/rollup-win32-x64-msvc': 4.30.1 + fsevents: 2.3.3 + + rrweb-cssom@0.7.1: {} + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + safe-array-concat@1.1.3: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.3 + get-intrinsic: 1.2.7 + has-symbols: 1.1.0 + isarray: 2.0.5 + + safe-push-apply@1.0.0: + dependencies: + es-errors: 1.3.0 + isarray: 2.0.5 + + safe-regex-test@1.1.0: + dependencies: + call-bound: 1.0.3 + es-errors: 1.3.0 + is-regex: 1.2.1 + + safer-buffer@2.1.2: {} + + saxes@6.0.0: + dependencies: + xmlchars: 2.2.0 + + semver@6.3.1: {} + + semver@7.6.3: {} + + set-function-length@1.2.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.7 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + + set-function-name@2.0.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + functions-have-names: 1.2.3 + has-property-descriptors: 1.0.2 + + set-proto@1.0.0: + dependencies: + dunder-proto: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.0.0 + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + side-channel-list@1.0.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.3 + + side-channel-map@1.0.1: + dependencies: + call-bound: 1.0.3 + es-errors: 1.3.0 + get-intrinsic: 1.2.7 + object-inspect: 1.13.3 + + side-channel-weakmap@1.0.2: + dependencies: + call-bound: 1.0.3 + es-errors: 1.3.0 + get-intrinsic: 1.2.7 + object-inspect: 1.13.3 + side-channel-map: 1.0.1 + + side-channel@1.1.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.3 + side-channel-list: 1.0.0 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 + + siginfo@2.0.0: {} + + sirv@3.0.0: + dependencies: + '@polka/url': 1.0.0-next.28 + mrmime: 2.0.0 + totalist: 3.0.1 + + source-map-js@1.2.1: {} + + stackback@0.0.2: {} + + std-env@3.8.0: {} + + string.prototype.includes@2.0.1: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + + string.prototype.matchall@4.0.12: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.3 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-errors: 1.3.0 + es-object-atoms: 1.0.0 + get-intrinsic: 1.2.7 + gopd: 1.2.0 + has-symbols: 1.1.0 + internal-slot: 1.1.0 + regexp.prototype.flags: 1.5.4 + set-function-name: 2.0.2 + side-channel: 1.1.0 + + string.prototype.repeat@1.0.0: + dependencies: + define-properties: 1.2.1 + es-abstract: 1.23.9 + + string.prototype.trim@1.2.10: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.3 + define-data-property: 1.1.4 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-object-atoms: 1.0.0 + has-property-descriptors: 1.0.2 + + string.prototype.trimend@1.0.9: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.3 + define-properties: 1.2.1 + es-object-atoms: 1.0.0 + + string.prototype.trimstart@1.0.8: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-object-atoms: 1.0.0 + + strip-bom@3.0.0: {} + + strip-indent@3.0.0: + dependencies: + min-indent: 1.0.1 + + strip-json-comments@3.1.1: {} + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + supports-preserve-symlinks-flag@1.0.0: {} + + symbol-tree@3.2.4: {} + + synckit@0.9.2: + dependencies: + '@pkgr/core': 0.1.1 + tslib: 2.8.1 + + tinybench@2.9.0: {} + + tinyexec@0.3.2: {} + + tinyglobby@0.2.10: + dependencies: + fdir: 6.4.2(picomatch@4.0.2) + picomatch: 4.0.2 + + tinypool@1.0.2: {} + + tinyrainbow@1.2.0: {} + + tinyspy@3.0.2: {} + + tldts-core@6.1.71: {} + + tldts@6.1.71: + dependencies: + tldts-core: 6.1.71 + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + totalist@3.0.1: {} + + tough-cookie@5.0.0: + dependencies: + tldts: 6.1.71 + + tr46@5.0.0: + dependencies: + punycode: 2.3.1 + + ts-api-utils@2.0.0(typescript@5.7.2): + dependencies: + typescript: 5.7.2 + + tsconfig-paths@3.15.0: + dependencies: + '@types/json5': 0.0.29 + json5: 1.0.2 + minimist: 1.2.8 + strip-bom: 3.0.0 + + tslib@2.8.1: {} + + type-check@0.4.0: + dependencies: + prelude-ls: 1.2.1 + + typed-array-buffer@1.0.3: + dependencies: + call-bound: 1.0.3 + es-errors: 1.3.0 + is-typed-array: 1.1.15 + + typed-array-byte-length@1.0.3: + dependencies: + call-bind: 1.0.8 + for-each: 0.3.3 + gopd: 1.2.0 + has-proto: 1.2.0 + is-typed-array: 1.1.15 + + typed-array-byte-offset@1.0.4: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.8 + for-each: 0.3.3 + gopd: 1.2.0 + has-proto: 1.2.0 + is-typed-array: 1.1.15 + reflect.getprototypeof: 1.0.10 + + typed-array-length@1.0.7: + dependencies: + call-bind: 1.0.8 + for-each: 0.3.3 + gopd: 1.2.0 + is-typed-array: 1.1.15 + possible-typed-array-names: 1.0.0 + reflect.getprototypeof: 1.0.10 + + typescript@5.7.2: {} + + unbox-primitive@1.1.0: + dependencies: + call-bound: 1.0.3 + has-bigints: 1.1.0 + has-symbols: 1.1.0 + which-boxed-primitive: 1.1.1 + + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + + vite-node@2.1.8: + dependencies: + cac: 6.7.14 + debug: 4.4.0 + es-module-lexer: 1.6.0 + pathe: 1.1.2 + vite: 5.4.11 + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + + vite@5.4.11: + dependencies: + esbuild: 0.21.5 + postcss: 8.4.49 + rollup: 4.30.1 + optionalDependencies: + fsevents: 2.3.3 + + vitest@2.1.8(@vitest/ui@2.1.8)(jsdom@25.0.1): + dependencies: + '@vitest/expect': 2.1.8 + '@vitest/mocker': 2.1.8(vite@5.4.11) + '@vitest/pretty-format': 2.1.8 + '@vitest/runner': 2.1.8 + '@vitest/snapshot': 2.1.8 + '@vitest/spy': 2.1.8 + '@vitest/utils': 2.1.8 + chai: 5.1.2 + debug: 4.4.0 + expect-type: 1.1.0 + magic-string: 0.30.17 + pathe: 1.1.2 + std-env: 3.8.0 + tinybench: 2.9.0 + tinyexec: 0.3.2 + tinypool: 1.0.2 + tinyrainbow: 1.2.0 + vite: 5.4.11 + vite-node: 2.1.8 + why-is-node-running: 2.3.0 + optionalDependencies: + '@vitest/ui': 2.1.8(vitest@2.1.8) + jsdom: 25.0.1 + transitivePeerDependencies: + - less + - lightningcss + - msw + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + + w3c-xmlserializer@5.0.0: + dependencies: + xml-name-validator: 5.0.0 + + webidl-conversions@7.0.0: {} + + whatwg-encoding@3.1.1: + dependencies: + iconv-lite: 0.6.3 + + whatwg-mimetype@4.0.0: {} + + whatwg-url@14.1.0: + dependencies: + tr46: 5.0.0 + webidl-conversions: 7.0.0 + + which-boxed-primitive@1.1.1: + dependencies: + is-bigint: 1.1.0 + is-boolean-object: 1.2.1 + is-number-object: 1.1.1 + is-string: 1.1.1 + is-symbol: 1.1.1 + + which-builtin-type@1.2.1: + dependencies: + call-bound: 1.0.3 + function.prototype.name: 1.1.8 + has-tostringtag: 1.0.2 + is-async-function: 2.1.0 + is-date-object: 1.1.0 + is-finalizationregistry: 1.1.1 + is-generator-function: 1.1.0 + is-regex: 1.2.1 + is-weakref: 1.1.0 + isarray: 2.0.5 + which-boxed-primitive: 1.1.1 + which-collection: 1.0.2 + which-typed-array: 1.1.18 + + which-collection@1.0.2: + dependencies: + is-map: 2.0.3 + is-set: 2.0.3 + is-weakmap: 2.0.2 + is-weakset: 2.0.4 + + which-typed-array@1.1.18: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.8 + call-bound: 1.0.3 + for-each: 0.3.3 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + why-is-node-running@2.3.0: + dependencies: + siginfo: 2.0.0 + stackback: 0.0.2 + + word-wrap@1.2.5: {} + + ws@8.18.0: {} + + xml-name-validator@5.0.0: {} + + xmlchars@2.2.0: {} + + yocto-queue@0.1.0: {} diff --git a/src/advanced/__tests__/advanced.test.js b/src/advanced/__tests__/advanced.test.js index 717d259f..7a724d4d 100644 --- a/src/advanced/__tests__/advanced.test.js +++ b/src/advanced/__tests__/advanced.test.js @@ -1,5 +1,3 @@ -import {describe} from "vitest"; +import { describe } from 'vitest'; -describe('advanced test', () => { - -}); \ No newline at end of file +describe('advanced test', () => {}); diff --git a/src/basic/__tests__/basic.test.js b/src/basic/__tests__/basic.test.js index 1afd4a58..7eda2660 100644 --- a/src/basic/__tests__/basic.test.js +++ b/src/basic/__tests__/basic.test.js @@ -1,150 +1,175 @@ -import { beforeAll, beforeEach, afterEach, describe, expect, it, vi } from "vitest"; - -describe('basic test', () => { - +import { + beforeAll, + beforeEach, + afterEach, + describe, + expect, + it, + vi, +} from "vitest"; + +describe("basic test", () => { describe.each([ - { type: 'origin', loadFile: () => import('../../main.original.js'), }, - { type: 'basic', loadFile: () => import('../main.basic.js'), }, - ])('$type 장바구니 시나리오 테스트', ({ loadFile }) => { + { type: "origin", loadFile: () => import("../../main.original.js") }, + { type: "basic", loadFile: () => import("../main.basic.js") }, + ])("$type 장바구니 시나리오 테스트", ({ loadFile }) => { let sel, addBtn, cartDisp, sum, stockInfo; beforeAll(async () => { // DOM 초기화 - document.body.innerHTML='
'; + document.body.innerHTML = '
'; await loadFile(); // 전역 변수 참조 - sel=document.getElementById('product-select'); - addBtn=document.getElementById('add-to-cart'); - cartDisp=document.getElementById('cart-items'); - sum=document.getElementById('cart-total'); - stockInfo=document.getElementById('stock-status'); + sel = document.getElementById("product-select"); + addBtn = document.getElementById("add-to-cart"); + cartDisp = document.getElementById("cart-items"); + sum = document.getElementById("cart-total"); + stockInfo = document.getElementById("stock-status"); }); beforeEach(() => { - vi.useRealTimers() - vi.spyOn(window, 'alert').mockImplementation(() => {}); + vi.useFakeTimers(); + const mockDate = new Date("2025-1-6"); + vi.setSystemTime(mockDate); + vi.spyOn(window, "alert").mockImplementation(() => {}); }); afterEach(() => { vi.restoreAllMocks(); }); - it('초기 상태: 상품 목록이 올바르게 그려졌는지 확인', () => { + it("초기 상태: 상품 목록이 올바르게 그려졌는지 확인", () => { expect(sel).toBeDefined(); - expect(sel.tagName.toLowerCase()).toBe('select'); + expect(sel.tagName.toLowerCase()).toBe("select"); expect(sel.children.length).toBe(5); // 첫 번째 상품 확인 - expect(sel.children[0].value).toBe('p1'); - expect(sel.children[0].textContent).toBe('상품1 - 10000원'); + expect(sel.children[0].value).toBe("p1"); + expect(sel.children[0].textContent).toBe("상품1 - 10000원"); expect(sel.children[0].disabled).toBe(false); // 마지막 상품 확인 - expect(sel.children[4].value).toBe('p5'); - expect(sel.children[4].textContent).toBe('상품5 - 25000원'); + expect(sel.children[4].value).toBe("p5"); + expect(sel.children[4].textContent).toBe("상품5 - 25000원"); expect(sel.children[4].disabled).toBe(false); // 재고 없는 상품 확인 (상품4) - expect(sel.children[3].value).toBe('p4'); - expect(sel.children[3].textContent).toBe('상품4 - 15000원'); + expect(sel.children[3].value).toBe("p4"); + expect(sel.children[3].textContent).toBe("상품4 - 15000원"); expect(sel.children[3].disabled).toBe(true); }); - it('초기 상태: DOM 요소가 올바르게 생성되었는지 확인', () => { - expect(document.querySelector('h1').textContent).toBe('장바구니'); + it("초기 상태: DOM 요소가 올바르게 생성되었는지 확인", () => { + expect(document.querySelector("h1").textContent).toBe("장바구니"); expect(sel).toBeDefined(); expect(addBtn).toBeDefined(); expect(cartDisp).toBeDefined(); - expect(sum.textContent).toContain('총액: 0원(포인트: 0)'); + expect(sum.textContent).toContain("총액: 0원(포인트: 0)"); expect(stockInfo).toBeDefined(); }); - it('상품을 장바구니에 추가할 수 있는지 확인', () => { - sel.value='p1'; + it("상품을 장바구니에 추가할 수 있는지 확인", () => { + sel.value = "p1"; addBtn.click(); expect(cartDisp.children.length).toBe(1); - expect(cartDisp.children[0].querySelector('span').textContent).toContain('상품1 - 10000원 x 1'); + expect(cartDisp.children[0].querySelector("span").textContent).toContain( + "상품1 - 10000원 x 1", + ); }); - it('장바구니에서 상품 수량을 변경할 수 있는지 확인', () => { - const increaseBtn=cartDisp.querySelector('.quantity-change[data-change="1"]'); + it("장바구니에서 상품 수량을 변경할 수 있는지 확인", () => { + const increaseBtn = cartDisp.querySelector( + '.quantity-change[data-change="1"]', + ); increaseBtn.click(); - expect(cartDisp.children[0].querySelector('span').textContent).toContain('상품1 - 10000원 x 2'); + expect(cartDisp.children[0].querySelector("span").textContent).toContain( + "상품1 - 10000원 x 2", + ); }); - it('장바구니에서 상품을 삭제할 수 있는지 확인', () => { - sel.value='p1'; + it("장바구니에서 상품을 삭제할 수 있는지 확인", () => { + sel.value = "p1"; addBtn.click(); - const removeBtn=cartDisp.querySelector('.remove-item'); + const removeBtn = cartDisp.querySelector(".remove-item"); removeBtn.click(); expect(cartDisp.children.length).toBe(0); - expect(sum.textContent).toContain('총액: 0원(포인트: 0)'); + expect(sum.textContent).toContain("총액: 0원(포인트: 0)"); }); - it('총액이 올바르게 계산되는지 확인', () => { - sel.value='p1'; + it("총액이 올바르게 계산되는지 확인", () => { + sel.value = "p1"; addBtn.click(); addBtn.click(); - expect(sum.textContent).toContain('총액: 20000원(포인트: 20)'); + expect(sum.textContent).toContain("총액: 20000원(포인트: 20)"); }); - it('할인이 올바르게 적용되는지 확인', () => { - sel.value='p1'; - for (let i=0; i < 10; i++) { + it("할인이 올바르게 적용되는지 확인", () => { + sel.value = "p1"; + for (let i = 0; i < 10; i++) { addBtn.click(); } - expect(sum.textContent).toContain('(10.0% 할인 적용)'); + expect(sum.textContent).toContain("(10.0% 할인 적용)"); }); - it('포인트가 올바르게 계산되는지 확인', () => { - sel.value='p2'; + it("포인트가 올바르게 계산되는지 확인", () => { + sel.value = "p2"; addBtn.click(); - expect(document.getElementById('loyalty-points').textContent).toContain('(포인트: 128)'); + expect(document.getElementById("loyalty-points").textContent).toContain( + "(포인트: 128)", + ); }); - it('번개세일 기능이 정상적으로 동작하는지 확인', () => { + it("번개세일 기능이 정상적으로 동작하는지 확인", () => { // 일부러 랜덤이 가득한 기능을 넣어서 테스트 하기를 어렵게 만들었습니다. 이런 코드는 어떻게 하면 좋을지 한번 고민해보세요! }); - it('추천 상품 알림이 표시되는지 확인', () => { + it("추천 상품 알림이 표시되는지 확인", () => { // 일부러 랜덤이 가득한 기능을 넣어서 테스트 하기를 어렵게 만들었습니다. 이런 코드는 어떻게 하면 좋을지 한번 고민해보세요! }); - it('화요일 할인이 적용되는지 확인', () => { - const mockDate=new Date('2024-10-15'); // 화요일 - vi.useFakeTimers() + it("화요일 할인이 적용되는지 확인", () => { + const mockDate = new Date("2024-10-15"); // 화요일 + vi.useFakeTimers(); vi.setSystemTime(mockDate); - sel.value='p1'; + sel.value = "p1"; addBtn.click(); - expect(document.getElementById('cart-total').textContent).toContain('(10.0% 할인 적용)'); + expect(document.getElementById("cart-total").textContent).toContain( + "(10.0% 할인 적용)", + ); }); - it('재고가 부족한 경우 추가되지 않는지 확인', () => { + it("재고가 부족한 경우 추가되지 않는지 확인", () => { // p4 상품 선택 (재고 없음) - sel.value='p4'; + sel.value = "p4"; addBtn.click(); // p4 상품이 장바구니에 없는지 확인 - const p4InCart=Array.from(cartDisp.children).some(item => item.id === 'p4'); + const p4InCart = Array.from(cartDisp.children).some( + (item) => item.id === "p4", + ); expect(p4InCart).toBe(false); - expect(stockInfo.textContent).toContain('상품4: 품절'); + expect(stockInfo.textContent).toContain("상품4: 품절"); }); - it('재고가 부족한 경우 추가되지 않고 알림이 표시되는지 확인', () => { - sel.value='p5'; + it("재고가 부족한 경우 추가되지 않고 알림이 표시되는지 확인", () => { + sel.value = "p5"; addBtn.click(); // p5 상품이 장바구니에 추가되었는지 확인 - const p5InCart=Array.from(cartDisp.children).some(item => item.id === 'p5'); + const p5InCart = Array.from(cartDisp.children).some( + (item) => item.id === "p5", + ); expect(p5InCart).toBe(true); // 수량 증가 버튼 찾기 - const increaseBtn=cartDisp.querySelector('#p5 .quantity-change[data-change="1"]'); + const increaseBtn = cartDisp.querySelector( + '#p5 .quantity-change[data-change="1"]', + ); expect(increaseBtn).not.toBeNull(); // 수량을 10번 증가시키기 - for (let i=0; i < 10; i++) { + for (let i = 0; i < 10; i++) { increaseBtn.click(); } @@ -152,14 +177,16 @@ describe('basic test', () => { increaseBtn.click(); // 재고 부족 알림이 표시되었는지 확인 - expect(window.alert).toHaveBeenCalledWith(expect.stringContaining('재고가 부족합니다')); + expect(window.alert).toHaveBeenCalledWith( + expect.stringContaining("재고가 부족합니다"), + ); // 장바구니의 상품 수량이 10개인지 확인 - const itemQuantity=cartDisp.querySelector('#p5 span').textContent; - expect(itemQuantity).toContain('x 10'); + const itemQuantity = cartDisp.querySelector("#p5 span").textContent; + expect(itemQuantity).toContain("x 10"); // 재고 상태 정보에 해당 상품이 재고 부족으로 표시되는지 확인 - expect(stockInfo.textContent).toContain('상품5: 품절'); + expect(stockInfo.textContent).toContain("상품5: 품절"); }); }); -}); \ No newline at end of file +}); diff --git a/src/basic/main.basic.js b/src/basic/main.basic.js index 0efffa28..d52d9756 100644 --- a/src/basic/main.basic.js +++ b/src/basic/main.basic.js @@ -1,36 +1,40 @@ var prodList, sel, addBtn, cartDisp, sum, stockInfo; -var lastSel, bonusPts=0, totalAmt=0, itemCnt=0; +var lastSel, + bonusPts = 0, + totalAmt = 0, + itemCnt = 0; function main() { - prodList=[ - {id: 'p1', name: '상품1', val: 10000, q: 50 }, - {id: 'p2', name: '상품2', val: 20000, q: 30 }, - {id: 'p3', name: '상품3', val: 30000, q: 20 }, - {id: 'p4', name: '상품4', val: 15000, q: 0 }, - {id: 'p5', name: '상품5', val: 25000, q: 10 } + prodList = [ + { id: 'p1', name: '상품1', val: 10000, q: 50 }, + { id: 'p2', name: '상품2', val: 20000, q: 30 }, + { id: 'p3', name: '상품3', val: 30000, q: 20 }, + { id: 'p4', name: '상품4', val: 15000, q: 0 }, + { id: 'p5', name: '상품5', val: 25000, q: 10 }, ]; - var root=document.getElementById('app'); - let cont=document.createElement('div'); - var wrap=document.createElement('div'); - let hTxt=document.createElement('h1'); - cartDisp=document.createElement('div'); - sum=document.createElement('div'); - sel=document.createElement('select'); - addBtn=document.createElement('button'); - stockInfo=document.createElement('div'); - cartDisp.id='cart-items'; - sum.id='cart-total'; - sel.id='product-select'; - addBtn.id='add-to-cart'; - stockInfo.id='stock-status'; - cont.className='bg-gray-100 p-8'; - wrap.className='max-w-md mx-auto bg-white rounded-xl shadow-md overflow-hidden md:max-w-2xl p-8'; - hTxt.className='text-2xl font-bold mb-4'; - sum.className='text-xl font-bold my-4'; - sel.className='border rounded p-2 mr-2'; - addBtn.className='bg-blue-500 text-white px-4 py-2 rounded'; - stockInfo.className='text-sm text-gray-500 mt-2'; - hTxt.textContent='장바구니'; - addBtn.textContent='추가'; + var root = document.getElementById('app'); + let cont = document.createElement('div'); + var wrap = document.createElement('div'); + let hTxt = document.createElement('h1'); + cartDisp = document.createElement('div'); + sum = document.createElement('div'); + sel = document.createElement('select'); + addBtn = document.createElement('button'); + stockInfo = document.createElement('div'); + cartDisp.id = 'cart-items'; + sum.id = 'cart-total'; + sel.id = 'product-select'; + addBtn.id = 'add-to-cart'; + stockInfo.id = 'stock-status'; + cont.className = 'bg-gray-100 p-8'; + wrap.className = + 'max-w-md mx-auto bg-white rounded-xl shadow-md overflow-hidden md:max-w-2xl p-8'; + hTxt.className = 'text-2xl font-bold mb-4'; + sum.className = 'text-xl font-bold my-4'; + sel.className = 'border rounded p-2 mr-2'; + addBtn.className = 'bg-blue-500 text-white px-4 py-2 rounded'; + stockInfo.className = 'text-sm text-gray-500 mt-2'; + hTxt.textContent = '장바구니'; + addBtn.textContent = '추가'; updateSelOpts(); wrap.appendChild(hTxt); wrap.appendChild(cartDisp); @@ -43,9 +47,9 @@ function main() { calcCart(); setTimeout(function () { setInterval(function () { - var luckyItem=prodList[Math.floor(Math.random() * prodList.length)]; - if(Math.random() < 0.3 && luckyItem.q > 0) { - luckyItem.val=Math.round(luckyItem.val * 0.8); + var luckyItem = prodList[Math.floor(Math.random() * prodList.length)]; + if (Math.random() < 0.3 && luckyItem.q > 0) { + luckyItem.val = Math.round(luckyItem.val * 0.8); alert('번개세일! ' + luckyItem.name + '이(가) 20% 할인 중입니다!'); updateSelOpts(); } @@ -53,152 +57,178 @@ function main() { }, Math.random() * 10000); setTimeout(function () { setInterval(function () { - if(lastSel) { - var suggest=prodList.find(function (item) { return item.id !== lastSel && item.q > 0; }); - if(suggest) { + if (lastSel) { + var suggest = prodList.find(function (item) { + return item.id !== lastSel && item.q > 0; + }); + if (suggest) { alert(suggest.name + '은(는) 어떠세요? 지금 구매하시면 5% 추가 할인!'); - suggest.val=Math.round(suggest.val * 0.95); + suggest.val = Math.round(suggest.val * 0.95); updateSelOpts(); } } }, 60000); }, Math.random() * 20000); -}; +} function updateSelOpts() { - sel.innerHTML=''; + sel.innerHTML = ''; prodList.forEach(function (item) { - var opt=document.createElement('option'); - opt.value=item.id; - opt.textContent=item.name + ' - ' + item.val + '원'; - if(item.q === 0) opt.disabled=true; + var opt = document.createElement('option'); + opt.value = item.id; + opt.textContent = item.name + ' - ' + item.val + '원'; + if (item.q === 0) opt.disabled = true; sel.appendChild(opt); }); } function calcCart() { - totalAmt=0; - itemCnt=0; - var cartItems=cartDisp.children; - var subTot=0; - for (var i=0; i < cartItems.length; i++) { + totalAmt = 0; + itemCnt = 0; + var cartItems = cartDisp.children; + var subTot = 0; + for (var i = 0; i < cartItems.length; i++) { (function () { var curItem; - for (var j=0; j < prodList.length; j++) { - if(prodList[j].id === cartItems[i].id) { - curItem=prodList[j]; + for (var j = 0; j < prodList.length; j++) { + if (prodList[j].id === cartItems[i].id) { + curItem = prodList[j]; break; } } - var q=parseInt(cartItems[i].querySelector('span').textContent.split('x ')[1]); - var itemTot=curItem.val * q; - var disc=0; + var q = parseInt(cartItems[i].querySelector('span').textContent.split('x ')[1]); + var itemTot = curItem.val * q; + var disc = 0; itemCnt += q; subTot += itemTot; - if(q >= 10) { - if(curItem.id === 'p1') disc=0.1; - else if(curItem.id === 'p2') disc=0.15; - else if(curItem.id === 'p3') disc=0.2; - else if(curItem.id === 'p4') disc=0.05; - else if(curItem.id === 'p5') disc=0.25; + if (q >= 10) { + if (curItem.id === 'p1') disc = 0.1; + else if (curItem.id === 'p2') disc = 0.15; + else if (curItem.id === 'p3') disc = 0.2; + else if (curItem.id === 'p4') disc = 0.05; + else if (curItem.id === 'p5') disc = 0.25; } totalAmt += itemTot * (1 - disc); })(); } - let discRate=0; - if(itemCnt >= 30) { - var bulkDisc=totalAmt * 0.25; - var itemDisc=subTot - totalAmt; - if(bulkDisc > itemDisc) { - totalAmt=subTot * (1 - 0.25); - discRate=0.25; + let discRate = 0; + if (itemCnt >= 30) { + var bulkDisc = totalAmt * 0.25; + var itemDisc = subTot - totalAmt; + if (bulkDisc > itemDisc) { + totalAmt = subTot * (1 - 0.25); + discRate = 0.25; } else { - discRate=(subTot - totalAmt) / subTot; + discRate = (subTot - totalAmt) / subTot; } } else { - discRate=(subTot - totalAmt) / subTot; + discRate = (subTot - totalAmt) / subTot; } - if(new Date().getDay() === 2) { - totalAmt *= (1 - 0.1); - discRate=Math.max(discRate, 0.1); + if (new Date().getDay() === 2) { + totalAmt *= 1 - 0.1; + discRate = Math.max(discRate, 0.1); } - sum.textContent='총액: ' + Math.round(totalAmt) + '원'; - if(discRate > 0) { - var span=document.createElement('span'); - span.className='text-green-500 ml-2'; - span.textContent='(' + (discRate * 100).toFixed(1) + '% 할인 적용)'; + sum.textContent = '총액: ' + Math.round(totalAmt) + '원'; + if (discRate > 0) { + var span = document.createElement('span'); + span.className = 'text-green-500 ml-2'; + span.textContent = '(' + (discRate * 100).toFixed(1) + '% 할인 적용)'; sum.appendChild(span); } updateStockInfo(); renderBonusPts(); } -const renderBonusPts=() => { +const renderBonusPts = () => { bonusPts = Math.floor(totalAmt / 1000); - var ptsTag=document.getElementById('loyalty-points'); - if(!ptsTag) { - ptsTag=document.createElement('span'); - ptsTag.id='loyalty-points'; - ptsTag.className='text-blue-500 ml-2'; + var ptsTag = document.getElementById('loyalty-points'); + if (!ptsTag) { + ptsTag = document.createElement('span'); + ptsTag.id = 'loyalty-points'; + ptsTag.className = 'text-blue-500 ml-2'; sum.appendChild(ptsTag); } - ptsTag.textContent='(포인트: ' + bonusPts + ')'; + ptsTag.textContent = '(포인트: ' + bonusPts + ')'; }; function updateStockInfo() { - var infoMsg=''; + var infoMsg = ''; prodList.forEach(function (item) { - if(item.q < 5) {infoMsg += item.name + ': ' + (item.q > 0 ? '재고 부족 ('+item.q+'개 남음)' : '품절') + '\n'; + if (item.q < 5) { + infoMsg += + item.name + ': ' + (item.q > 0 ? '재고 부족 (' + item.q + '개 남음)' : '품절') + '\n'; } }); - stockInfo.textContent=infoMsg; + stockInfo.textContent = infoMsg; } main(); addBtn.addEventListener('click', function () { - var selItem=sel.value; - var itemToAdd=prodList.find(function (p) { return p.id === selItem; }); - if(itemToAdd && itemToAdd.q > 0) { - var item=document.getElementById(itemToAdd.id); - if(item) { - var newQty=parseInt(item.querySelector('span').textContent.split('x ')[1]) + 1; - if(newQty <= itemToAdd.q) { - item.querySelector('span').textContent=itemToAdd.name + ' - ' + itemToAdd.val + '원 x ' + newQty; + var selItem = sel.value; + var itemToAdd = prodList.find(function (p) { + return p.id === selItem; + }); + if (itemToAdd && itemToAdd.q > 0) { + var item = document.getElementById(itemToAdd.id); + if (item) { + var newQty = parseInt(item.querySelector('span').textContent.split('x ')[1]) + 1; + if (newQty <= itemToAdd.q) { + item.querySelector('span').textContent = + itemToAdd.name + ' - ' + itemToAdd.val + '원 x ' + newQty; itemToAdd.q--; - } else {alert('재고가 부족합니다.');} + } else { + alert('재고가 부족합니다.'); + } } else { - var newItem=document.createElement('div'); - newItem.id=itemToAdd.id; - newItem.className='flex justify-between items-center mb-2'; - newItem.innerHTML='' + itemToAdd.name + ' - ' + itemToAdd.val + '원 x 1
' + - '' + - '' + - '
'; + var newItem = document.createElement('div'); + newItem.id = itemToAdd.id; + newItem.className = 'flex justify-between items-center mb-2'; + newItem.innerHTML = + '' + + itemToAdd.name + + ' - ' + + itemToAdd.val + + '원 x 1
' + + '' + + '' + + '
'; cartDisp.appendChild(newItem); itemToAdd.q--; } calcCart(); - lastSel=selItem; + lastSel = selItem; } }); cartDisp.addEventListener('click', function (event) { - var tgt=event.target; - if(tgt.classList.contains('quantity-change') || tgt.classList.contains('remove-item')) { - var prodId=tgt.dataset.productId; - var itemElem=document.getElementById(prodId); - var prod=prodList.find(function (p) { return p.id === prodId; }); - if(tgt.classList.contains('quantity-change')) { - var qtyChange=parseInt(tgt.dataset.change); - var newQty=parseInt(itemElem.querySelector('span').textContent.split('x ')[1]) + qtyChange; - if(newQty > 0 && newQty <= prod.q + parseInt(itemElem.querySelector('span').textContent.split('x ')[1])) { - itemElem.querySelector('span').textContent=itemElem.querySelector('span').textContent.split('x ')[0] + 'x ' + newQty; + var tgt = event.target; + if (tgt.classList.contains('quantity-change') || tgt.classList.contains('remove-item')) { + var prodId = tgt.dataset.productId; + var itemElem = document.getElementById(prodId); + var prod = prodList.find(function (p) { + return p.id === prodId; + }); + if (tgt.classList.contains('quantity-change')) { + var qtyChange = parseInt(tgt.dataset.change); + var newQty = parseInt(itemElem.querySelector('span').textContent.split('x ')[1]) + qtyChange; + if ( + newQty > 0 && + newQty <= prod.q + parseInt(itemElem.querySelector('span').textContent.split('x ')[1]) + ) { + itemElem.querySelector('span').textContent = + itemElem.querySelector('span').textContent.split('x ')[0] + 'x ' + newQty; prod.q -= qtyChange; - } else if(newQty <= 0) { + } else if (newQty <= 0) { itemElem.remove(); prod.q -= qtyChange; } else { alert('재고가 부족합니다.'); } - } else if(tgt.classList.contains('remove-item')) { - var remQty=parseInt(itemElem.querySelector('span').textContent.split('x ')[1]); + } else if (tgt.classList.contains('remove-item')) { + var remQty = parseInt(itemElem.querySelector('span').textContent.split('x ')[1]); prod.q += remQty; itemElem.remove(); } calcCart(); } -}); \ No newline at end of file +}); diff --git a/src/main.original.js b/src/main.original.js index 0efffa28..91eaea26 100644 --- a/src/main.original.js +++ b/src/main.original.js @@ -1,36 +1,40 @@ var prodList, sel, addBtn, cartDisp, sum, stockInfo; -var lastSel, bonusPts=0, totalAmt=0, itemCnt=0; +var lastSel, + bonusPts = 0, + totalAmt = 0, + itemCnt = 0; function main() { - prodList=[ - {id: 'p1', name: '상품1', val: 10000, q: 50 }, - {id: 'p2', name: '상품2', val: 20000, q: 30 }, - {id: 'p3', name: '상품3', val: 30000, q: 20 }, - {id: 'p4', name: '상품4', val: 15000, q: 0 }, - {id: 'p5', name: '상품5', val: 25000, q: 10 } + prodList = [ + { id: "p1", name: "상품1", val: 10000, q: 50 }, + { id: "p2", name: "상품2", val: 20000, q: 30 }, + { id: "p3", name: "상품3", val: 30000, q: 20 }, + { id: "p4", name: "상품4", val: 15000, q: 0 }, + { id: "p5", name: "상품5", val: 25000, q: 10 }, ]; - var root=document.getElementById('app'); - let cont=document.createElement('div'); - var wrap=document.createElement('div'); - let hTxt=document.createElement('h1'); - cartDisp=document.createElement('div'); - sum=document.createElement('div'); - sel=document.createElement('select'); - addBtn=document.createElement('button'); - stockInfo=document.createElement('div'); - cartDisp.id='cart-items'; - sum.id='cart-total'; - sel.id='product-select'; - addBtn.id='add-to-cart'; - stockInfo.id='stock-status'; - cont.className='bg-gray-100 p-8'; - wrap.className='max-w-md mx-auto bg-white rounded-xl shadow-md overflow-hidden md:max-w-2xl p-8'; - hTxt.className='text-2xl font-bold mb-4'; - sum.className='text-xl font-bold my-4'; - sel.className='border rounded p-2 mr-2'; - addBtn.className='bg-blue-500 text-white px-4 py-2 rounded'; - stockInfo.className='text-sm text-gray-500 mt-2'; - hTxt.textContent='장바구니'; - addBtn.textContent='추가'; + var root = document.getElementById("app"); + let cont = document.createElement("div"); + var wrap = document.createElement("div"); + let hTxt = document.createElement("h1"); + cartDisp = document.createElement("div"); + sum = document.createElement("div"); + sel = document.createElement("select"); + addBtn = document.createElement("button"); + stockInfo = document.createElement("div"); + cartDisp.id = "cart-items"; + sum.id = "cart-total"; + sel.id = "product-select"; + addBtn.id = "add-to-cart"; + stockInfo.id = "stock-status"; + cont.className = "bg-gray-100 p-8"; + wrap.className = + "max-w-md mx-auto bg-white rounded-xl shadow-md overflow-hidden md:max-w-2xl p-8"; + hTxt.className = "text-2xl font-bold mb-4"; + sum.className = "text-xl font-bold my-4"; + sel.className = "border rounded p-2 mr-2"; + addBtn.className = "bg-blue-500 text-white px-4 py-2 rounded"; + stockInfo.className = "text-sm text-gray-500 mt-2"; + hTxt.textContent = "장바구니"; + addBtn.textContent = "추가"; updateSelOpts(); wrap.appendChild(hTxt); wrap.appendChild(cartDisp); @@ -43,162 +47,207 @@ function main() { calcCart(); setTimeout(function () { setInterval(function () { - var luckyItem=prodList[Math.floor(Math.random() * prodList.length)]; - if(Math.random() < 0.3 && luckyItem.q > 0) { - luckyItem.val=Math.round(luckyItem.val * 0.8); - alert('번개세일! ' + luckyItem.name + '이(가) 20% 할인 중입니다!'); + var luckyItem = prodList[Math.floor(Math.random() * prodList.length)]; + if (Math.random() < 0.3 && luckyItem.q > 0) { + luckyItem.val = Math.round(luckyItem.val * 0.8); + alert("번개세일! " + luckyItem.name + "이(가) 20% 할인 중입니다!"); updateSelOpts(); } }, 30000); }, Math.random() * 10000); setTimeout(function () { setInterval(function () { - if(lastSel) { - var suggest=prodList.find(function (item) { return item.id !== lastSel && item.q > 0; }); - if(suggest) { - alert(suggest.name + '은(는) 어떠세요? 지금 구매하시면 5% 추가 할인!'); - suggest.val=Math.round(suggest.val * 0.95); + if (lastSel) { + var suggest = prodList.find(function (item) { + return item.id !== lastSel && item.q > 0; + }); + if (suggest) { + alert( + suggest.name + "은(는) 어떠세요? 지금 구매하시면 5% 추가 할인!", + ); + suggest.val = Math.round(suggest.val * 0.95); updateSelOpts(); } } }, 60000); }, Math.random() * 20000); -}; +} function updateSelOpts() { - sel.innerHTML=''; + sel.innerHTML = ""; prodList.forEach(function (item) { - var opt=document.createElement('option'); - opt.value=item.id; - opt.textContent=item.name + ' - ' + item.val + '원'; - if(item.q === 0) opt.disabled=true; + var opt = document.createElement("option"); + opt.value = item.id; + opt.textContent = item.name + " - " + item.val + "원"; + if (item.q === 0) opt.disabled = true; sel.appendChild(opt); }); } function calcCart() { - totalAmt=0; - itemCnt=0; - var cartItems=cartDisp.children; - var subTot=0; - for (var i=0; i < cartItems.length; i++) { + totalAmt = 0; + itemCnt = 0; + var cartItems = cartDisp.children; + var subTot = 0; + for (var i = 0; i < cartItems.length; i++) { (function () { var curItem; - for (var j=0; j < prodList.length; j++) { - if(prodList[j].id === cartItems[i].id) { - curItem=prodList[j]; + for (var j = 0; j < prodList.length; j++) { + if (prodList[j].id === cartItems[i].id) { + curItem = prodList[j]; break; } } - var q=parseInt(cartItems[i].querySelector('span').textContent.split('x ')[1]); - var itemTot=curItem.val * q; - var disc=0; + var q = parseInt( + cartItems[i].querySelector("span").textContent.split("x ")[1], + ); + var itemTot = curItem.val * q; + var disc = 0; itemCnt += q; subTot += itemTot; - if(q >= 10) { - if(curItem.id === 'p1') disc=0.1; - else if(curItem.id === 'p2') disc=0.15; - else if(curItem.id === 'p3') disc=0.2; - else if(curItem.id === 'p4') disc=0.05; - else if(curItem.id === 'p5') disc=0.25; + if (q >= 10) { + if (curItem.id === "p1") disc = 0.1; + else if (curItem.id === "p2") disc = 0.15; + else if (curItem.id === "p3") disc = 0.2; + else if (curItem.id === "p4") disc = 0.05; + else if (curItem.id === "p5") disc = 0.25; } totalAmt += itemTot * (1 - disc); })(); } - let discRate=0; - if(itemCnt >= 30) { - var bulkDisc=totalAmt * 0.25; - var itemDisc=subTot - totalAmt; - if(bulkDisc > itemDisc) { - totalAmt=subTot * (1 - 0.25); - discRate=0.25; + let discRate = 0; + if (itemCnt >= 30) { + var bulkDisc = totalAmt * 0.25; + var itemDisc = subTot - totalAmt; + if (bulkDisc > itemDisc) { + totalAmt = subTot * (1 - 0.25); + discRate = 0.25; } else { - discRate=(subTot - totalAmt) / subTot; + discRate = (subTot - totalAmt) / subTot; } } else { - discRate=(subTot - totalAmt) / subTot; + discRate = (subTot - totalAmt) / subTot; } - if(new Date().getDay() === 2) { - totalAmt *= (1 - 0.1); - discRate=Math.max(discRate, 0.1); + if (new Date().getDay() === 2) { + totalAmt *= 1 - 0.1; + discRate = Math.max(discRate, 0.1); } - sum.textContent='총액: ' + Math.round(totalAmt) + '원'; - if(discRate > 0) { - var span=document.createElement('span'); - span.className='text-green-500 ml-2'; - span.textContent='(' + (discRate * 100).toFixed(1) + '% 할인 적용)'; + sum.textContent = "총액: " + Math.round(totalAmt) + "원"; + if (discRate > 0) { + var span = document.createElement("span"); + span.className = "text-green-500 ml-2"; + span.textContent = "(" + (discRate * 100).toFixed(1) + "% 할인 적용)"; sum.appendChild(span); } updateStockInfo(); renderBonusPts(); } -const renderBonusPts=() => { +const renderBonusPts = () => { bonusPts = Math.floor(totalAmt / 1000); - var ptsTag=document.getElementById('loyalty-points'); - if(!ptsTag) { - ptsTag=document.createElement('span'); - ptsTag.id='loyalty-points'; - ptsTag.className='text-blue-500 ml-2'; + var ptsTag = document.getElementById("loyalty-points"); + if (!ptsTag) { + ptsTag = document.createElement("span"); + ptsTag.id = "loyalty-points"; + ptsTag.className = "text-blue-500 ml-2"; sum.appendChild(ptsTag); } - ptsTag.textContent='(포인트: ' + bonusPts + ')'; + ptsTag.textContent = "(포인트: " + bonusPts + ")"; }; function updateStockInfo() { - var infoMsg=''; + var infoMsg = ""; prodList.forEach(function (item) { - if(item.q < 5) {infoMsg += item.name + ': ' + (item.q > 0 ? '재고 부족 ('+item.q+'개 남음)' : '품절') + '\n'; + if (item.q < 5) { + infoMsg += + item.name + + ": " + + (item.q > 0 ? "재고 부족 (" + item.q + "개 남음)" : "품절") + + "\n"; } }); - stockInfo.textContent=infoMsg; + stockInfo.textContent = infoMsg; } main(); -addBtn.addEventListener('click', function () { - var selItem=sel.value; - var itemToAdd=prodList.find(function (p) { return p.id === selItem; }); - if(itemToAdd && itemToAdd.q > 0) { - var item=document.getElementById(itemToAdd.id); - if(item) { - var newQty=parseInt(item.querySelector('span').textContent.split('x ')[1]) + 1; - if(newQty <= itemToAdd.q) { - item.querySelector('span').textContent=itemToAdd.name + ' - ' + itemToAdd.val + '원 x ' + newQty; +addBtn.addEventListener("click", function () { + var selItem = sel.value; + var itemToAdd = prodList.find(function (p) { + return p.id === selItem; + }); + if (itemToAdd && itemToAdd.q > 0) { + var item = document.getElementById(itemToAdd.id); + if (item) { + var newQty = + parseInt(item.querySelector("span").textContent.split("x ")[1]) + 1; + if (newQty <= itemToAdd.q) { + item.querySelector("span").textContent = + itemToAdd.name + " - " + itemToAdd.val + "원 x " + newQty; itemToAdd.q--; - } else {alert('재고가 부족합니다.');} + } else { + alert("재고가 부족합니다."); + } } else { - var newItem=document.createElement('div'); - newItem.id=itemToAdd.id; - newItem.className='flex justify-between items-center mb-2'; - newItem.innerHTML='' + itemToAdd.name + ' - ' + itemToAdd.val + '원 x 1
' + - '' + - '' + - '
'; + var newItem = document.createElement("div"); + newItem.id = itemToAdd.id; + newItem.className = "flex justify-between items-center mb-2"; + newItem.innerHTML = + "" + + itemToAdd.name + + " - " + + itemToAdd.val + + "원 x 1
" + + '' + + '' + + '
'; cartDisp.appendChild(newItem); itemToAdd.q--; } calcCart(); - lastSel=selItem; + lastSel = selItem; } }); -cartDisp.addEventListener('click', function (event) { - var tgt=event.target; - if(tgt.classList.contains('quantity-change') || tgt.classList.contains('remove-item')) { - var prodId=tgt.dataset.productId; - var itemElem=document.getElementById(prodId); - var prod=prodList.find(function (p) { return p.id === prodId; }); - if(tgt.classList.contains('quantity-change')) { - var qtyChange=parseInt(tgt.dataset.change); - var newQty=parseInt(itemElem.querySelector('span').textContent.split('x ')[1]) + qtyChange; - if(newQty > 0 && newQty <= prod.q + parseInt(itemElem.querySelector('span').textContent.split('x ')[1])) { - itemElem.querySelector('span').textContent=itemElem.querySelector('span').textContent.split('x ')[0] + 'x ' + newQty; +cartDisp.addEventListener("click", function (event) { + var tgt = event.target; + if ( + tgt.classList.contains("quantity-change") || + tgt.classList.contains("remove-item") + ) { + var prodId = tgt.dataset.productId; + var itemElem = document.getElementById(prodId); + var prod = prodList.find(function (p) { + return p.id === prodId; + }); + if (tgt.classList.contains("quantity-change")) { + var qtyChange = parseInt(tgt.dataset.change); + var newQty = + parseInt(itemElem.querySelector("span").textContent.split("x ")[1]) + + qtyChange; + if ( + newQty > 0 && + newQty <= + prod.q + + parseInt(itemElem.querySelector("span").textContent.split("x ")[1]) + ) { + itemElem.querySelector("span").textContent = + itemElem.querySelector("span").textContent.split("x ")[0] + + "x " + + newQty; prod.q -= qtyChange; - } else if(newQty <= 0) { + } else if (newQty <= 0) { itemElem.remove(); prod.q -= qtyChange; } else { - alert('재고가 부족합니다.'); + alert("재고가 부족합니다."); } - } else if(tgt.classList.contains('remove-item')) { - var remQty=parseInt(itemElem.querySelector('span').textContent.split('x ')[1]); + } else if (tgt.classList.contains("remove-item")) { + var remQty = parseInt( + itemElem.querySelector("span").textContent.split("x ")[1], + ); prod.q += remQty; itemElem.remove(); } calcCart(); } -}); \ No newline at end of file +}); From 8b61a7b15712c55d9e2bfcbcec2dde6f4533ecde Mon Sep 17 00:00:00 2001 From: anne-hyeyeon Date: Thu, 9 Jan 2025 00:01:08 +0900 Subject: [PATCH 2/8] =?UTF-8?q?chore:=20=ED=94=84=EB=A1=9C=EC=A0=9D?= =?UTF-8?q?=ED=8A=B8=20=EA=B5=AC=EC=A1=B0=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.advanced.html | 22 +- index.basic.html | 22 +- index.html | 22 +- src/basic/app/initializeApp.js | 12 + src/basic/components/CartItem.js | 19 + src/basic/components/SelectProduct.js | 12 + src/basic/components/StockInfo.js | 9 + src/basic/components/TotalDisplay.js | 23 ++ src/basic/constants/products.js | 7 + src/basic/index.js | 6 + src/basic/main.basic.js | 490 ++++++++++++++------------ src/basic/store/store.js | 16 + src/basic/utils/calculateCart.js | 28 ++ 13 files changed, 437 insertions(+), 251 deletions(-) create mode 100644 src/basic/app/initializeApp.js create mode 100644 src/basic/components/CartItem.js create mode 100644 src/basic/components/SelectProduct.js create mode 100644 src/basic/components/StockInfo.js create mode 100644 src/basic/components/TotalDisplay.js create mode 100644 src/basic/constants/products.js create mode 100644 src/basic/index.js create mode 100644 src/basic/store/store.js create mode 100644 src/basic/utils/calculateCart.js diff --git a/index.advanced.html b/index.advanced.html index 1d45f718..ad62d5b2 100644 --- a/index.advanced.html +++ b/index.advanced.html @@ -1,13 +1,13 @@ - + - - - - 장바구니 - - - -
- - + + + + 장바구니 + + + +
+ + diff --git a/index.basic.html b/index.basic.html index 8494659b..fa817160 100644 --- a/index.basic.html +++ b/index.basic.html @@ -1,13 +1,13 @@ - + - - - - 장바구니 - - - -
- - + + + + 장바구니 + + + +
+ + diff --git a/index.html b/index.html index 694c78b8..0a48a09a 100644 --- a/index.html +++ b/index.html @@ -1,13 +1,13 @@ - - - - 장바구니 - - - -
- - - \ No newline at end of file + + + + 장바구니 + + + +
+ + + diff --git a/src/basic/app/initializeApp.js b/src/basic/app/initializeApp.js new file mode 100644 index 00000000..c60a969d --- /dev/null +++ b/src/basic/app/initializeApp.js @@ -0,0 +1,12 @@ +import { createStore } from "../store/store.js"; +import { renderProductOptions } from "../components/ProductSelect.js"; +import { renderTotal } from "../components/TotalDisplay.js"; +import { renderStockInfo } from "../components/StockInfo.js"; +import { createCartItem } from "../components/CartItem.js"; +import { calculateCart } from "../utils/calculateCart.js"; + +export function initializeApp(products) { + const store = createStore({ products, lastSelected: null }); + + const root = document.getElementById("app"); +} diff --git a/src/basic/components/CartItem.js b/src/basic/components/CartItem.js new file mode 100644 index 00000000..84c3de69 --- /dev/null +++ b/src/basic/components/CartItem.js @@ -0,0 +1,19 @@ +export function createCartItem(product) { + const item = document.createElement("div"); + item.id = product.id; + item.className = "flex justify-between items-center mb-2"; + + item.innerHTML = ` + ${product.name} - ${product.val}원 x 1 +
+ + + +
+ `; + + return item; +} diff --git a/src/basic/components/SelectProduct.js b/src/basic/components/SelectProduct.js new file mode 100644 index 00000000..91dd1bfb --- /dev/null +++ b/src/basic/components/SelectProduct.js @@ -0,0 +1,12 @@ +import { createUIElement } from "../utils/createUIElement.js"; + +export function renderProductOptions(select, products) { + select.innerHTML = ""; + products.forEach((item) => { + const option = createUIElement("option"); + option.value = item.id; + option.textContent = `${item.name} - ${item.val}원`; + option.disabled = item.q === 0; + select.appendChild(option); + }); +} diff --git a/src/basic/components/StockInfo.js b/src/basic/components/StockInfo.js new file mode 100644 index 00000000..d967fe36 --- /dev/null +++ b/src/basic/components/StockInfo.js @@ -0,0 +1,9 @@ +export function renderStockInfo(stockEl, products) { + const lowStockProducts = products.filter((item) => item.q < 5); + stockEl.textContent = lowStockProducts + .map( + (item) => + `${item.name}: ${item.q > 0 ? `재고 부족 (${item.q}개 남음)` : "품절"}`, + ) + .join("\n"); +} diff --git a/src/basic/components/TotalDisplay.js b/src/basic/components/TotalDisplay.js new file mode 100644 index 00000000..d4747e6d --- /dev/null +++ b/src/basic/components/TotalDisplay.js @@ -0,0 +1,23 @@ +import { createUIElement } from "../utils/createUIElement.js"; + +export function renderTotal(total, totalEl, discountRate = 0) { + totalEl.innerHTML = `총액: ${Math.round(total)}원`; + + if (discountRate > 0) { + const discountEl = createUIElement("span", { + className: "text-green-500 ml-2", + textContent: `(${(discountRate * 100).toFixed(1)}% 할인 적용)`, + }); + totalEl.appendChild(discountEl); + } + + let pointsEl = document.getElementById("loyalty-points"); + if (!pointsEl) { + pointsEl = createUIElement("span", { + id: "loyalty-points", + className: "text-blue-500 ml-2", + }); + totalEl.appendChild(pointsEl); + } + pointsEl.textContent = `(포인트: ${Math.floor(total / 1000)})`; +} diff --git a/src/basic/constants/products.js b/src/basic/constants/products.js new file mode 100644 index 00000000..066023b0 --- /dev/null +++ b/src/basic/constants/products.js @@ -0,0 +1,7 @@ +export const PRODUCTS = [ + { id: "p1", name: "상품1", val: 10000, q: 50 }, + { id: "p2", name: "상품2", val: 20000, q: 30 }, + { id: "p3", name: "상품3", val: 30000, q: 20 }, + { id: "p4", name: "상품4", val: 15000, q: 0 }, + { id: "p5", name: "상품5", val: 25000, q: 10 }, +]; diff --git a/src/basic/index.js b/src/basic/index.js new file mode 100644 index 00000000..d8d13c59 --- /dev/null +++ b/src/basic/index.js @@ -0,0 +1,6 @@ +import { initializeApp } from "./app/initializeApp.js"; +import { PRODUCTS } from "./constants/products.js"; + +document.addEventListener("DOMContentLoaded", () => { + initializeApp(PRODUCTS); +}); diff --git a/src/basic/main.basic.js b/src/basic/main.basic.js index d52d9756..a685b0bd 100644 --- a/src/basic/main.basic.js +++ b/src/basic/main.basic.js @@ -1,234 +1,288 @@ -var prodList, sel, addBtn, cartDisp, sum, stockInfo; -var lastSel, - bonusPts = 0, - totalAmt = 0, - itemCnt = 0; -function main() { - prodList = [ - { id: 'p1', name: '상품1', val: 10000, q: 50 }, - { id: 'p2', name: '상품2', val: 20000, q: 30 }, - { id: 'p3', name: '상품3', val: 30000, q: 20 }, - { id: 'p4', name: '상품4', val: 15000, q: 0 }, - { id: 'p5', name: '상품5', val: 25000, q: 10 }, - ]; - var root = document.getElementById('app'); - let cont = document.createElement('div'); - var wrap = document.createElement('div'); - let hTxt = document.createElement('h1'); - cartDisp = document.createElement('div'); - sum = document.createElement('div'); - sel = document.createElement('select'); - addBtn = document.createElement('button'); - stockInfo = document.createElement('div'); - cartDisp.id = 'cart-items'; - sum.id = 'cart-total'; - sel.id = 'product-select'; - addBtn.id = 'add-to-cart'; - stockInfo.id = 'stock-status'; - cont.className = 'bg-gray-100 p-8'; - wrap.className = - 'max-w-md mx-auto bg-white rounded-xl shadow-md overflow-hidden md:max-w-2xl p-8'; - hTxt.className = 'text-2xl font-bold mb-4'; - sum.className = 'text-xl font-bold my-4'; - sel.className = 'border rounded p-2 mr-2'; - addBtn.className = 'bg-blue-500 text-white px-4 py-2 rounded'; - stockInfo.className = 'text-sm text-gray-500 mt-2'; - hTxt.textContent = '장바구니'; - addBtn.textContent = '추가'; - updateSelOpts(); - wrap.appendChild(hTxt); - wrap.appendChild(cartDisp); - wrap.appendChild(sum); - wrap.appendChild(sel); - wrap.appendChild(addBtn); - wrap.appendChild(stockInfo); - cont.appendChild(wrap); - root.appendChild(cont); - calcCart(); - setTimeout(function () { - setInterval(function () { - var luckyItem = prodList[Math.floor(Math.random() * prodList.length)]; - if (Math.random() < 0.3 && luckyItem.q > 0) { - luckyItem.val = Math.round(luckyItem.val * 0.8); - alert('번개세일! ' + luckyItem.name + '이(가) 20% 할인 중입니다!'); - updateSelOpts(); - } - }, 30000); - }, Math.random() * 10000); - setTimeout(function () { - setInterval(function () { - if (lastSel) { - var suggest = prodList.find(function (item) { - return item.id !== lastSel && item.q > 0; - }); - if (suggest) { - alert(suggest.name + '은(는) 어떠세요? 지금 구매하시면 5% 추가 할인!'); - suggest.val = Math.round(suggest.val * 0.95); - updateSelOpts(); - } - } - }, 60000); - }, Math.random() * 20000); +const PRODUCTS = [ + { id: "p1", name: "상품1", val: 10000, q: 50 }, + { id: "p2", name: "상품2", val: 20000, q: 30 }, + { id: "p3", name: "상품3", val: 30000, q: 20 }, + { id: "p4", name: "상품4", val: 15000, q: 0 }, + { id: "p5", name: "상품5", val: 25000, q: 10 }, +]; + +const DISCOUNT_RATES = { + p1: 0.1, + p2: 0.15, + p3: 0.2, + p4: 0.05, + p5: 0.25, +}; + +function createStore(initialState) { + const state = { ...initialState }; + const listeners = new Set(); + + return { + getState: () => state, + update: (newState) => { + Object.assign(state, newState); + listeners.forEach((listener) => listener(state)); + }, + subscribe: (listener) => { + listeners.add(listener); + return () => listeners.delete(listener); + }, + }; } -function updateSelOpts() { - sel.innerHTML = ''; - prodList.forEach(function (item) { - var opt = document.createElement('option'); - opt.value = item.id; - opt.textContent = item.name + ' - ' + item.val + '원'; - if (item.q === 0) opt.disabled = true; - sel.appendChild(opt); - }); + +function createUIElement(tag, { id, className, textContent } = {}) { + const element = document.createElement(tag); + if (id) element.id = id; + if (className) element.className = className; + if (textContent) element.textContent = textContent; + return element; } -function calcCart() { - totalAmt = 0; - itemCnt = 0; - var cartItems = cartDisp.children; - var subTot = 0; - for (var i = 0; i < cartItems.length; i++) { - (function () { - var curItem; - for (var j = 0; j < prodList.length; j++) { - if (prodList[j].id === cartItems[i].id) { - curItem = prodList[j]; - break; - } - } - var q = parseInt(cartItems[i].querySelector('span').textContent.split('x ')[1]); - var itemTot = curItem.val * q; - var disc = 0; - itemCnt += q; - subTot += itemTot; - if (q >= 10) { - if (curItem.id === 'p1') disc = 0.1; - else if (curItem.id === 'p2') disc = 0.15; - else if (curItem.id === 'p3') disc = 0.2; - else if (curItem.id === 'p4') disc = 0.05; - else if (curItem.id === 'p5') disc = 0.25; - } - totalAmt += itemTot * (1 - disc); - })(); - } - let discRate = 0; - if (itemCnt >= 30) { - var bulkDisc = totalAmt * 0.25; - var itemDisc = subTot - totalAmt; - if (bulkDisc > itemDisc) { - totalAmt = subTot * (1 - 0.25); - discRate = 0.25; - } else { - discRate = (subTot - totalAmt) / subTot; - } - } else { - discRate = (subTot - totalAmt) / subTot; + +function calculateCart(cartItems, products) { + const result = { + total: 0, + count: 0, + items: new Map(), + discountRate: 0, + }; + + cartItems.forEach((item) => { + const productId = item.id; + const quantity = parseInt( + item.querySelector("span").textContent.split("x ")[1], + ); + const product = products.find((p) => p.id === productId); + + result.count += quantity; + const itemTotal = product.val * quantity; + result.total += itemTotal; + result.items.set(productId, { quantity, product }); + }); + + if (result.count >= 10 || new Date().getDay() === 2) { + result.discountRate = 0.1; + result.total *= 0.9; } - if (new Date().getDay() === 2) { - totalAmt *= 1 - 0.1; - discRate = Math.max(discRate, 0.1); + + return result; +} + +function renderProductOptions(select, products) { + select.innerHTML = ""; + products.forEach((item) => { + const option = createUIElement("option"); + option.value = item.id; + option.textContent = `${item.name} - ${item.val}원`; + option.disabled = item.q === 0; + select.appendChild(option); + }); +} + +function renderTotal(total, totalEl, discountRate = 0) { + totalEl.innerHTML = `총액: ${Math.round(total)}원`; + + if (discountRate > 0) { + const discountEl = createUIElement("span", { + className: "text-green-500 ml-2", + textContent: `(${(discountRate * 100).toFixed(1)}% 할인 적용)`, + }); + totalEl.appendChild(discountEl); } - sum.textContent = '총액: ' + Math.round(totalAmt) + '원'; - if (discRate > 0) { - var span = document.createElement('span'); - span.className = 'text-green-500 ml-2'; - span.textContent = '(' + (discRate * 100).toFixed(1) + '% 할인 적용)'; - sum.appendChild(span); + + let pointsEl = document.getElementById("loyalty-points"); + if (!pointsEl) { + pointsEl = createUIElement("span", { + id: "loyalty-points", + className: "text-blue-500 ml-2", + }); + totalEl.appendChild(pointsEl); } - updateStockInfo(); - renderBonusPts(); + pointsEl.textContent = `(포인트: ${Math.floor(total / 1000)})`; } -const renderBonusPts = () => { - bonusPts = Math.floor(totalAmt / 1000); - var ptsTag = document.getElementById('loyalty-points'); - if (!ptsTag) { - ptsTag = document.createElement('span'); - ptsTag.id = 'loyalty-points'; - ptsTag.className = 'text-blue-500 ml-2'; - sum.appendChild(ptsTag); - } - ptsTag.textContent = '(포인트: ' + bonusPts + ')'; -}; -function updateStockInfo() { - var infoMsg = ''; - prodList.forEach(function (item) { - if (item.q < 5) { - infoMsg += - item.name + ': ' + (item.q > 0 ? '재고 부족 (' + item.q + '개 남음)' : '품절') + '\n'; - } + +function renderStockInfo(stockEl, products) { + const lowStockProducts = products.filter((item) => item.q < 5); + stockEl.textContent = lowStockProducts + .map( + (item) => + `${item.name}: ${item.q > 0 ? `재고 부족 (${item.q}개 남음)` : "품절"}`, + ) + .join("\n"); +} + +function createCartItem(product) { + const item = createUIElement("div", { + id: product.id, + className: "flex justify-between items-center mb-2", }); - stockInfo.textContent = infoMsg; + + item.innerHTML = ` + ${product.name} - ${product.val}원 x 1 +
+ + + +
+ `; + + return item; } -main(); -addBtn.addEventListener('click', function () { - var selItem = sel.value; - var itemToAdd = prodList.find(function (p) { - return p.id === selItem; + +function initializeApp() { + const store = createStore({ + products: [...PRODUCTS], + lastSelected: null, }); - if (itemToAdd && itemToAdd.q > 0) { - var item = document.getElementById(itemToAdd.id); - if (item) { - var newQty = parseInt(item.querySelector('span').textContent.split('x ')[1]) + 1; - if (newQty <= itemToAdd.q) { - item.querySelector('span').textContent = - itemToAdd.name + ' - ' + itemToAdd.val + '원 x ' + newQty; - itemToAdd.q--; + + const root = document.getElementById("app"); + const elements = { + container: createUIElement("div", { className: "bg-gray-100 p-8" }), + wrapper: createUIElement("div", { + className: + "max-w-md mx-auto bg-white rounded-xl shadow-md overflow-hidden md:max-w-2xl p-8", + }), + title: createUIElement("h1", { + className: "text-2xl font-bold mb-4", + textContent: "장바구니", + }), + cartDisplay: createUIElement("div", { id: "cart-items" }), + total: createUIElement("div", { + id: "cart-total", + className: "text-xl font-bold my-4", + }), + productSelect: createUIElement("select", { + id: "product-select", + className: "border rounded p-2 mr-2", + }), + addButton: createUIElement("button", { + id: "add-to-cart", + className: "bg-blue-500 text-white px-4 py-2 rounded", + textContent: "추가", + }), + stockInfo: createUIElement("div", { + id: "stock-status", + className: "text-sm text-gray-500 mt-2", + }), + }; + + elements.wrapper.append( + elements.title, + elements.cartDisplay, + elements.total, + elements.productSelect, + elements.addButton, + elements.stockInfo, + ); + elements.container.appendChild(elements.wrapper); + root.appendChild(elements.container); + + renderProductOptions(elements.productSelect, store.getState().products); + renderTotal(0, elements.total); + renderStockInfo(elements.stockInfo, store.getState().products); + + elements.addButton.addEventListener("click", () => { + const state = store.getState(); + const selectedId = elements.productSelect.value; + const product = state.products.find((p) => p.id === selectedId); + + if (!product || product.q <= 0) { + alert("재고가 부족합니다."); + return; + } + + const existingItem = document.getElementById(selectedId); + if (existingItem) { + const currentQty = parseInt( + existingItem.querySelector("span").textContent.split("x ")[1], + ); + const newQty = currentQty + 1; + + if (newQty <= product.q + currentQty) { + existingItem.querySelector("span").textContent = + `${product.name} - ${product.val}원 x ${newQty}`; + + store.update({ + products: state.products.map((p) => + p.id === selectedId ? { ...p, q: p.q - 1 } : p, + ), + }); } else { - alert('재고가 부족합니다.'); + alert("재고가 부족합니다."); } } else { - var newItem = document.createElement('div'); - newItem.id = itemToAdd.id; - newItem.className = 'flex justify-between items-center mb-2'; - newItem.innerHTML = - '' + - itemToAdd.name + - ' - ' + - itemToAdd.val + - '원 x 1
' + - '' + - '' + - '
'; - cartDisp.appendChild(newItem); - itemToAdd.q--; + elements.cartDisplay.appendChild(createCartItem(product)); + store.update({ + products: state.products.map((p) => + p.id === selectedId ? { ...p, q: p.q - 1 } : p, + ), + }); } - calcCart(); - lastSel = selItem; - } -}); -cartDisp.addEventListener('click', function (event) { - var tgt = event.target; - if (tgt.classList.contains('quantity-change') || tgt.classList.contains('remove-item')) { - var prodId = tgt.dataset.productId; - var itemElem = document.getElementById(prodId); - var prod = prodList.find(function (p) { - return p.id === prodId; - }); - if (tgt.classList.contains('quantity-change')) { - var qtyChange = parseInt(tgt.dataset.change); - var newQty = parseInt(itemElem.querySelector('span').textContent.split('x ')[1]) + qtyChange; - if ( - newQty > 0 && - newQty <= prod.q + parseInt(itemElem.querySelector('span').textContent.split('x ')[1]) - ) { - itemElem.querySelector('span').textContent = - itemElem.querySelector('span').textContent.split('x ')[0] + 'x ' + newQty; - prod.q -= qtyChange; - } else if (newQty <= 0) { - itemElem.remove(); - prod.q -= qtyChange; + + const cartResult = calculateCart( + Array.from(elements.cartDisplay.children), + store.getState().products, + ); + + renderTotal(cartResult.total, elements.total, cartResult.discountRate); + renderStockInfo(elements.stockInfo, store.getState().products); + }); + + elements.cartDisplay.addEventListener("click", (event) => { + const button = event.target; + if (!button.matches("button")) return; + + const state = store.getState(); + const productId = button.dataset.productId; + const itemElement = document.getElementById(productId); + const product = state.products.find((p) => p.id === productId); + + if (button.classList.contains("remove-item")) { + const quantity = parseInt( + itemElement.querySelector("span").textContent.split("x ")[1], + ); + itemElement.remove(); + store.update({ + products: state.products.map((p) => + p.id === productId ? { ...p, q: p.q + quantity } : p, + ), + }); + } else if (button.classList.contains("quantity-change")) { + const change = parseInt(button.dataset.change); + const currentQty = parseInt( + itemElement.querySelector("span").textContent.split("x ")[1], + ); + const newQty = currentQty + change; + + if (change > 0 && product.q <= 0) { + alert("재고가 부족합니다."); + return; + } + + if (newQty <= 0) { + itemElement.remove(); } else { - alert('재고가 부족합니다.'); + itemElement.querySelector("span").textContent = + `${product.name} - ${product.val}원 x ${newQty}`; } - } else if (tgt.classList.contains('remove-item')) { - var remQty = parseInt(itemElem.querySelector('span').textContent.split('x ')[1]); - prod.q += remQty; - itemElem.remove(); + + store.update({ + products: state.products.map((p) => + p.id === productId ? { ...p, q: p.q - change } : p, + ), + }); } - calcCart(); - } -}); + + const cartResult = calculateCart( + Array.from(elements.cartDisplay.children), + store.getState().products, + ); + renderTotal(cartResult.total, elements.total, cartResult.discountRate); + renderStockInfo(elements.stockInfo, store.getState().products); + }); +} + +initializeApp(); diff --git a/src/basic/store/store.js b/src/basic/store/store.js new file mode 100644 index 00000000..7538a697 --- /dev/null +++ b/src/basic/store/store.js @@ -0,0 +1,16 @@ +export function createStore(initialState) { + const state = { ...initialState }; + const listeners = new Set(); + + return { + getState: () => state, + update: (newState) => { + Object.assign(state, newState); + listeners.forEach((listener) => listener(state)); + }, + subscribe: (listener) => { + listeners.add(listener); + return () => listeners.delete(listener); + }, + }; +} diff --git a/src/basic/utils/calculateCart.js b/src/basic/utils/calculateCart.js new file mode 100644 index 00000000..5673085e --- /dev/null +++ b/src/basic/utils/calculateCart.js @@ -0,0 +1,28 @@ +export function calculateCart(cartItems, products) { + const result = { + total: 0, + count: 0, + items: new Map(), + discountRate: 0, + }; + + cartItems.forEach((item) => { + const productId = item.id; + const quantity = parseInt( + item.querySelector("span").textContent.split("x ")[1], + ); + const product = products.find((p) => p.id === productId); + + result.count += quantity; + const itemTotal = product.val * quantity; + result.total += itemTotal; + result.items.set(productId, { quantity, product }); + }); + + if (result.count >= 10 || new Date().getDay() === 2) { + result.discountRate = 0.1; + result.total *= 0.9; + } + + return result; +} From dd365d26e14755cd00331f31140efea932508a0b Mon Sep 17 00:00:00 2001 From: anne-hyeyeon Date: Thu, 9 Jan 2025 00:32:49 +0900 Subject: [PATCH 3/8] =?UTF-8?q?fix:=20=EA=B5=AC=EC=A1=B0=20=EC=9B=90?= =?UTF-8?q?=EC=83=81=EB=B3=B5=EA=B5=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/basic/app/initializeApp.js | 12 ------------ src/basic/components/CartItem.js | 19 ------------------ src/basic/components/SelectProduct.js | 12 ------------ src/basic/components/StockInfo.js | 9 --------- src/basic/components/TotalDisplay.js | 23 ---------------------- src/basic/constants/products.js | 7 ------- src/basic/index.js | 6 ------ src/basic/store/store.js | 16 --------------- src/basic/utils/calculateCart.js | 28 --------------------------- 9 files changed, 132 deletions(-) delete mode 100644 src/basic/app/initializeApp.js delete mode 100644 src/basic/components/CartItem.js delete mode 100644 src/basic/components/SelectProduct.js delete mode 100644 src/basic/components/StockInfo.js delete mode 100644 src/basic/components/TotalDisplay.js delete mode 100644 src/basic/constants/products.js delete mode 100644 src/basic/index.js delete mode 100644 src/basic/store/store.js delete mode 100644 src/basic/utils/calculateCart.js diff --git a/src/basic/app/initializeApp.js b/src/basic/app/initializeApp.js deleted file mode 100644 index c60a969d..00000000 --- a/src/basic/app/initializeApp.js +++ /dev/null @@ -1,12 +0,0 @@ -import { createStore } from "../store/store.js"; -import { renderProductOptions } from "../components/ProductSelect.js"; -import { renderTotal } from "../components/TotalDisplay.js"; -import { renderStockInfo } from "../components/StockInfo.js"; -import { createCartItem } from "../components/CartItem.js"; -import { calculateCart } from "../utils/calculateCart.js"; - -export function initializeApp(products) { - const store = createStore({ products, lastSelected: null }); - - const root = document.getElementById("app"); -} diff --git a/src/basic/components/CartItem.js b/src/basic/components/CartItem.js deleted file mode 100644 index 84c3de69..00000000 --- a/src/basic/components/CartItem.js +++ /dev/null @@ -1,19 +0,0 @@ -export function createCartItem(product) { - const item = document.createElement("div"); - item.id = product.id; - item.className = "flex justify-between items-center mb-2"; - - item.innerHTML = ` - ${product.name} - ${product.val}원 x 1 -
- - - -
- `; - - return item; -} diff --git a/src/basic/components/SelectProduct.js b/src/basic/components/SelectProduct.js deleted file mode 100644 index 91dd1bfb..00000000 --- a/src/basic/components/SelectProduct.js +++ /dev/null @@ -1,12 +0,0 @@ -import { createUIElement } from "../utils/createUIElement.js"; - -export function renderProductOptions(select, products) { - select.innerHTML = ""; - products.forEach((item) => { - const option = createUIElement("option"); - option.value = item.id; - option.textContent = `${item.name} - ${item.val}원`; - option.disabled = item.q === 0; - select.appendChild(option); - }); -} diff --git a/src/basic/components/StockInfo.js b/src/basic/components/StockInfo.js deleted file mode 100644 index d967fe36..00000000 --- a/src/basic/components/StockInfo.js +++ /dev/null @@ -1,9 +0,0 @@ -export function renderStockInfo(stockEl, products) { - const lowStockProducts = products.filter((item) => item.q < 5); - stockEl.textContent = lowStockProducts - .map( - (item) => - `${item.name}: ${item.q > 0 ? `재고 부족 (${item.q}개 남음)` : "품절"}`, - ) - .join("\n"); -} diff --git a/src/basic/components/TotalDisplay.js b/src/basic/components/TotalDisplay.js deleted file mode 100644 index d4747e6d..00000000 --- a/src/basic/components/TotalDisplay.js +++ /dev/null @@ -1,23 +0,0 @@ -import { createUIElement } from "../utils/createUIElement.js"; - -export function renderTotal(total, totalEl, discountRate = 0) { - totalEl.innerHTML = `총액: ${Math.round(total)}원`; - - if (discountRate > 0) { - const discountEl = createUIElement("span", { - className: "text-green-500 ml-2", - textContent: `(${(discountRate * 100).toFixed(1)}% 할인 적용)`, - }); - totalEl.appendChild(discountEl); - } - - let pointsEl = document.getElementById("loyalty-points"); - if (!pointsEl) { - pointsEl = createUIElement("span", { - id: "loyalty-points", - className: "text-blue-500 ml-2", - }); - totalEl.appendChild(pointsEl); - } - pointsEl.textContent = `(포인트: ${Math.floor(total / 1000)})`; -} diff --git a/src/basic/constants/products.js b/src/basic/constants/products.js deleted file mode 100644 index 066023b0..00000000 --- a/src/basic/constants/products.js +++ /dev/null @@ -1,7 +0,0 @@ -export const PRODUCTS = [ - { id: "p1", name: "상품1", val: 10000, q: 50 }, - { id: "p2", name: "상품2", val: 20000, q: 30 }, - { id: "p3", name: "상품3", val: 30000, q: 20 }, - { id: "p4", name: "상품4", val: 15000, q: 0 }, - { id: "p5", name: "상품5", val: 25000, q: 10 }, -]; diff --git a/src/basic/index.js b/src/basic/index.js deleted file mode 100644 index d8d13c59..00000000 --- a/src/basic/index.js +++ /dev/null @@ -1,6 +0,0 @@ -import { initializeApp } from "./app/initializeApp.js"; -import { PRODUCTS } from "./constants/products.js"; - -document.addEventListener("DOMContentLoaded", () => { - initializeApp(PRODUCTS); -}); diff --git a/src/basic/store/store.js b/src/basic/store/store.js deleted file mode 100644 index 7538a697..00000000 --- a/src/basic/store/store.js +++ /dev/null @@ -1,16 +0,0 @@ -export function createStore(initialState) { - const state = { ...initialState }; - const listeners = new Set(); - - return { - getState: () => state, - update: (newState) => { - Object.assign(state, newState); - listeners.forEach((listener) => listener(state)); - }, - subscribe: (listener) => { - listeners.add(listener); - return () => listeners.delete(listener); - }, - }; -} diff --git a/src/basic/utils/calculateCart.js b/src/basic/utils/calculateCart.js deleted file mode 100644 index 5673085e..00000000 --- a/src/basic/utils/calculateCart.js +++ /dev/null @@ -1,28 +0,0 @@ -export function calculateCart(cartItems, products) { - const result = { - total: 0, - count: 0, - items: new Map(), - discountRate: 0, - }; - - cartItems.forEach((item) => { - const productId = item.id; - const quantity = parseInt( - item.querySelector("span").textContent.split("x ")[1], - ); - const product = products.find((p) => p.id === productId); - - result.count += quantity; - const itemTotal = product.val * quantity; - result.total += itemTotal; - result.items.set(productId, { quantity, product }); - }); - - if (result.count >= 10 || new Date().getDay() === 2) { - result.discountRate = 0.1; - result.total *= 0.9; - } - - return result; -} From 4dcb57a848f04dca8b6dfc3ab2d658a95913744a Mon Sep 17 00:00:00 2001 From: anne-hyeyeon Date: Thu, 9 Jan 2025 00:33:09 +0900 Subject: [PATCH 4/8] =?UTF-8?q?fix:=20=ED=95=A8=EC=88=98=20=EA=B7=B8?= =?UTF-8?q?=EB=A3=B9=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/basic/main.basic.js | 185 ++++++++++++++++++++++++++++------------ 1 file changed, 131 insertions(+), 54 deletions(-) diff --git a/src/basic/main.basic.js b/src/basic/main.basic.js index a685b0bd..c1929bcc 100644 --- a/src/basic/main.basic.js +++ b/src/basic/main.basic.js @@ -1,3 +1,4 @@ +/* 데이터 정의 */ const PRODUCTS = [ { id: "p1", name: "상품1", val: 10000, q: 50 }, { id: "p2", name: "상품2", val: 20000, q: 30 }, @@ -6,7 +7,7 @@ const PRODUCTS = [ { id: "p5", name: "상품5", val: 25000, q: 10 }, ]; -const DISCOUNT_RATES = { +const INDIVIDUAL_DISCOUNTS = { p1: 0.1, p2: 0.15, p3: 0.2, @@ -14,6 +15,7 @@ const DISCOUNT_RATES = { p5: 0.25, }; +/* 상태 관리 */ function createStore(initialState) { const state = { ...initialState }; const listeners = new Set(); @@ -31,43 +33,100 @@ function createStore(initialState) { }; } -function createUIElement(tag, { id, className, textContent } = {}) { - const element = document.createElement(tag); - if (id) element.id = id; - if (className) element.className = className; - if (textContent) element.textContent = textContent; - return element; +/* 할인 계산 로직 */ +// 10개 이상 구매 시 상품별 할인율 반환 +function getIndividualDiscountRate(productId, quantity) { + return quantity >= 10 ? (INDIVIDUAL_DISCOUNTS[productId] ?? 0) : 0; } -function calculateCart(cartItems, products) { - const result = { - total: 0, - count: 0, - items: new Map(), - discountRate: 0, +// reduce 콜백: 상품별 합계 및 할인 계산 +function accumulateItem(acc, itemElem, products) { + const productId = itemElem.id; + const quantity = parseInt( + itemElem.querySelector("span").textContent.split("x ")[1], + 10, + ); + const product = products.find((p) => p.id === productId); + + const itemTotal = product.val * quantity; + const discRate = getIndividualDiscountRate(productId, quantity); + const discountedItemTotal = itemTotal * (1 - discRate); + + const newItems = new Map(acc.items); + newItems.set(productId, { quantity, product }); + + return { + ...acc, + items: newItems, + subTotal: acc.subTotal + itemTotal, + totalAmt: acc.totalAmt + discountedItemTotal, + itemCount: acc.itemCount + quantity, }; +} - cartItems.forEach((item) => { - const productId = item.id; - const quantity = parseInt( - item.querySelector("span").textContent.split("x ")[1], - ); - const product = products.find((p) => p.id === productId); +// 대량 구매 할인 적용 +function applyBulkDiscount({ subTotal, totalAmt, itemCount, items }) { + if (itemCount < 30) { + const existedRate = subTotal === 0 ? 0 : (subTotal - totalAmt) / subTotal; + return { total: totalAmt, discountRate: existedRate, items }; + } - result.count += quantity; - const itemTotal = product.val * quantity; - result.total += itemTotal; - result.items.set(productId, { quantity, product }); - }); + const bulkDiscountAmount = subTotal * 0.25; + const individualDiscountAmount = subTotal - totalAmt; + + if (bulkDiscountAmount > individualDiscountAmount) { + return { total: subTotal * 0.75, discountRate: 0.25, items }; + } - if (result.count >= 10 || new Date().getDay() === 2) { - result.discountRate = 0.1; - result.total *= 0.9; + const existedRate = (subTotal - totalAmt) / subTotal; + return { total: totalAmt, discountRate: existedRate, items }; +} + +// 화요일 할인 적용 +function applyTuesdayDiscount({ currentTotal, currentRate, items }) { + if (new Date().getDay() !== 2) { + return { total: currentTotal, discountRate: currentRate, items }; } + return { + total: currentTotal * 0.9, + discountRate: Math.max(currentRate, 0.1), + items, + }; +} + +// 장바구니 계산 +function calculateCart(cartItems, products) { + const { subTotal, totalAmt, itemCount, items } = cartItems.reduce( + (acc, itemElem) => accumulateItem(acc, itemElem, products), + { subTotal: 0, totalAmt: 0, itemCount: 0, items: new Map() }, + ); + + const afterBulk = applyBulkDiscount({ subTotal, totalAmt, itemCount, items }); + const finalRes = applyTuesdayDiscount({ + currentTotal: afterBulk.total, + currentRate: afterBulk.discountRate, + items: afterBulk.items, + }); - return result; + return { + total: finalRes.total, + discountRate: finalRes.discountRate, + count: itemCount, + items: finalRes.items, + }; } +/* UI 관련 함수 */ +// UI 요소 생성 +function createUIElement(tag, { id, className, textContent } = {}) { + const element = document.createElement(tag); + if (id) element.id = id; + if (className) element.className = className; + if (textContent) element.textContent = textContent; + return element; +} + +// 상품 옵션 렌더링 function renderProductOptions(select, products) { select.innerHTML = ""; products.forEach((item) => { @@ -79,6 +138,7 @@ function renderProductOptions(select, products) { }); } +// 총액 렌더링 function renderTotal(total, totalEl, discountRate = 0) { totalEl.innerHTML = `총액: ${Math.round(total)}원`; @@ -101,6 +161,7 @@ function renderTotal(total, totalEl, discountRate = 0) { pointsEl.textContent = `(포인트: ${Math.floor(total / 1000)})`; } +// 재고 정보 렌더링 function renderStockInfo(stockEl, products) { const lowStockProducts = products.filter((item) => item.q < 5); stockEl.textContent = lowStockProducts @@ -111,6 +172,7 @@ function renderStockInfo(stockEl, products) { .join("\n"); } +// 장바구니 항목 생성 function createCartItem(product) { const item = createUIElement("div", { id: product.id, @@ -118,28 +180,21 @@ function createCartItem(product) { }); item.innerHTML = ` - ${product.name} - ${product.val}원 x 1 -
- - - -
- `; - + ${product.name} - ${product.val}원 x 1 +
+ + + +
+ `; return item; } - -function initializeApp() { - const store = createStore({ - products: [...PRODUCTS], - lastSelected: null, - }); - - const root = document.getElementById("app"); - const elements = { +/* UI 요소 생성 */ +function createUIElements() { + return { container: createUIElement("div", { className: "bg-gray-100 p-8" }), wrapper: createUIElement("div", { className: @@ -168,7 +223,10 @@ function initializeApp() { className: "text-sm text-gray-500 mt-2", }), }; +} +/* UI 요소 DOM에 추가 */ +function appendUIElements(root, elements) { elements.wrapper.append( elements.title, elements.cartDisplay, @@ -179,11 +237,10 @@ function initializeApp() { ); elements.container.appendChild(elements.wrapper); root.appendChild(elements.container); +} - renderProductOptions(elements.productSelect, store.getState().products); - renderTotal(0, elements.total); - renderStockInfo(elements.stockInfo, store.getState().products); - +/* [장바구니에 추가] 버튼 이벤트 */ +function setupAddButtonEvent(elements, store) { elements.addButton.addEventListener("click", () => { const state = store.getState(); const selectedId = elements.productSelect.value; @@ -226,11 +283,13 @@ function initializeApp() { Array.from(elements.cartDisplay.children), store.getState().products, ); - renderTotal(cartResult.total, elements.total, cartResult.discountRate); renderStockInfo(elements.stockInfo, store.getState().products); }); +} +/* 장바구니 내 버튼들(+/-/삭제) 이벤트 */ +function setupCartButtonEvents(elements, store) { elements.cartDisplay.addEventListener("click", (event) => { const button = event.target; if (!button.matches("button")) return; @@ -261,7 +320,6 @@ function initializeApp() { alert("재고가 부족합니다."); return; } - if (newQty <= 0) { itemElement.remove(); } else { @@ -285,4 +343,23 @@ function initializeApp() { }); } +/* 앱 초기화 */ +function initializeApp() { + const store = createStore({ + products: [...PRODUCTS], + lastSelected: null, + }); + + const root = document.getElementById("app"); + const elements = createUIElements(); + + appendUIElements(root, elements); + renderProductOptions(elements.productSelect, store.getState().products); + renderTotal(0, elements.total); + renderStockInfo(elements.stockInfo, store.getState().products); + + setupAddButtonEvent(elements, store); + setupCartButtonEvents(elements, store); +} + initializeApp(); From af125f63a5640d0bcf946be79dc9e50dec7c477c Mon Sep 17 00:00:00 2001 From: anne-hyeyeon Date: Thu, 9 Jan 2025 23:53:11 +0900 Subject: [PATCH 5/8] =?UTF-8?q?refactor:=20=EA=B8=B0=EC=A1=B4=20=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EB=A6=AC=EC=95=A1=ED=8A=B8,=20=ED=83=80=EC=9E=85?= =?UTF-8?q?=EC=8A=A4=ED=81=AC=EB=A6=BD=ED=8A=B8=EB=A1=9C=20=EA=B3=A0?= =?UTF-8?q?=EB=8F=84=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.advanced.html | 2 +- package.json | 14 + pnpm-lock.yaml | 1133 +++++++++++++++-- postcss.config.js | 6 + src/advanced/components/App.tsx | 33 + src/advanced/components/Cart/CartItem.tsx | 43 + src/advanced/components/Cart/CartList.tsx | 37 + src/advanced/components/Cart/CartTotal.tsx | 20 + .../components/Product/ProductSelect.tsx | 22 + src/advanced/components/Product/StockInfo.tsx | 19 + src/advanced/constants/products.ts | 17 + src/advanced/hooks/useCart.ts | 81 ++ src/advanced/main.advanced.js | 0 src/advanced/main.advanced.tsx | 13 + src/advanced/types/cart.ts | 17 + src/advanced/utils/calculate.ts | 93 ++ tailwind.config.js | 9 + tsconfig.json | 28 + tsconfig.node.json | 10 + vite.config.js | 9 - vite.config.ts | 6 + 21 files changed, 1512 insertions(+), 100 deletions(-) create mode 100644 postcss.config.js create mode 100644 src/advanced/components/App.tsx create mode 100644 src/advanced/components/Cart/CartItem.tsx create mode 100644 src/advanced/components/Cart/CartList.tsx create mode 100644 src/advanced/components/Cart/CartTotal.tsx create mode 100644 src/advanced/components/Product/ProductSelect.tsx create mode 100644 src/advanced/components/Product/StockInfo.tsx create mode 100644 src/advanced/constants/products.ts create mode 100644 src/advanced/hooks/useCart.ts delete mode 100644 src/advanced/main.advanced.js create mode 100644 src/advanced/main.advanced.tsx create mode 100644 src/advanced/types/cart.ts create mode 100644 src/advanced/utils/calculate.ts create mode 100644 tailwind.config.js create mode 100644 tsconfig.json create mode 100644 tsconfig.node.json delete mode 100644 vite.config.js create mode 100644 vite.config.ts diff --git a/index.advanced.html b/index.advanced.html index ad62d5b2..f734b1e0 100644 --- a/index.advanced.html +++ b/index.advanced.html @@ -8,6 +8,6 @@
- + diff --git a/package.json b/package.json index dd00ca22..91562d23 100644 --- a/package.json +++ b/package.json @@ -20,9 +20,14 @@ "devDependencies": { "@testing-library/jest-dom": "^6.5.0", "@testing-library/user-event": "^14.5.2", + "@types/node": "^22.10.5", + "@types/react": "^19.0.4", + "@types/react-dom": "^19.0.2", "@typescript-eslint/eslint-plugin": "^8.19.1", "@typescript-eslint/parser": "^8.19.1", + "@vitejs/plugin-react": "^4.3.4", "@vitest/ui": "^2.1.1", + "autoprefixer": "^10.4.20", "eslint": "^9.17.0", "eslint-config-airbnb": "^19.0.4", "eslint-config-airbnb-typescript": "^18.0.0", @@ -33,8 +38,17 @@ "eslint-plugin-react": "^7.37.3", "eslint-plugin-react-hooks": "^5.1.0", "jsdom": "^25.0.0", + "postcss": "^8.4.49", "prettier": "^3.4.2", + "tailwindcss": "^3.4.17", + "typescript": "^5.7.3", "vite": "^5.1.0", "vitest": "^2.1.1" + }, + "dependencies": { + "add": "^2.0.6", + "pnpm": "^9.15.3", + "react": "^19.0.0", + "react-dom": "^19.0.0" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c1d2226e..5e128dcf 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -7,6 +7,19 @@ settings: importers: .: + dependencies: + add: + specifier: ^2.0.6 + version: 2.0.6 + pnpm: + specifier: ^9.15.3 + version: 9.15.3 + react: + specifier: ^19.0.0 + version: 19.0.0 + react-dom: + specifier: ^19.0.0 + version: 19.0.0(react@19.0.0) devDependencies: '@testing-library/jest-dom': specifier: ^6.5.0 @@ -14,72 +27,175 @@ importers: '@testing-library/user-event': specifier: ^14.5.2 version: 14.5.2(@testing-library/dom@10.4.0) + '@types/node': + specifier: ^22.10.5 + version: 22.10.5 + '@types/react': + specifier: ^19.0.4 + version: 19.0.4 + '@types/react-dom': + specifier: ^19.0.2 + version: 19.0.2(@types/react@19.0.4) '@typescript-eslint/eslint-plugin': specifier: ^8.19.1 - version: 8.19.1(@typescript-eslint/parser@8.19.1(eslint@9.17.0)(typescript@5.7.2))(eslint@9.17.0)(typescript@5.7.2) + version: 8.19.1(@typescript-eslint/parser@8.19.1(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3))(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3) '@typescript-eslint/parser': specifier: ^8.19.1 - version: 8.19.1(eslint@9.17.0)(typescript@5.7.2) + version: 8.19.1(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3) + '@vitejs/plugin-react': + specifier: ^4.3.4 + version: 4.3.4(vite@5.4.11(@types/node@22.10.5)) '@vitest/ui': specifier: ^2.1.1 version: 2.1.8(vitest@2.1.8) + autoprefixer: + specifier: ^10.4.20 + version: 10.4.20(postcss@8.4.49) eslint: specifier: ^9.17.0 - version: 9.17.0 + version: 9.17.0(jiti@1.21.7) eslint-config-airbnb: specifier: ^19.0.4 - version: 19.0.4(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.19.1(eslint@9.17.0)(typescript@5.7.2))(eslint@9.17.0))(eslint-plugin-jsx-a11y@6.10.2(eslint@9.17.0))(eslint-plugin-react-hooks@5.1.0(eslint@9.17.0))(eslint-plugin-react@7.37.3(eslint@9.17.0))(eslint@9.17.0) + version: 19.0.4(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.19.1(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3))(eslint@9.17.0(jiti@1.21.7)))(eslint-plugin-jsx-a11y@6.10.2(eslint@9.17.0(jiti@1.21.7)))(eslint-plugin-react-hooks@5.1.0(eslint@9.17.0(jiti@1.21.7)))(eslint-plugin-react@7.37.3(eslint@9.17.0(jiti@1.21.7)))(eslint@9.17.0(jiti@1.21.7)) eslint-config-airbnb-typescript: specifier: ^18.0.0 - version: 18.0.0(@typescript-eslint/eslint-plugin@8.19.1(@typescript-eslint/parser@8.19.1(eslint@9.17.0)(typescript@5.7.2))(eslint@9.17.0)(typescript@5.7.2))(@typescript-eslint/parser@8.19.1(eslint@9.17.0)(typescript@5.7.2))(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.19.1(eslint@9.17.0)(typescript@5.7.2))(eslint@9.17.0))(eslint@9.17.0) + version: 18.0.0(@typescript-eslint/eslint-plugin@8.19.1(@typescript-eslint/parser@8.19.1(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3))(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3))(@typescript-eslint/parser@8.19.1(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3))(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.19.1(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3))(eslint@9.17.0(jiti@1.21.7)))(eslint@9.17.0(jiti@1.21.7)) eslint-config-prettier: specifier: ^9.1.0 - version: 9.1.0(eslint@9.17.0) + version: 9.1.0(eslint@9.17.0(jiti@1.21.7)) eslint-plugin-import: specifier: ^2.31.0 - version: 2.31.0(@typescript-eslint/parser@8.19.1(eslint@9.17.0)(typescript@5.7.2))(eslint@9.17.0) + version: 2.31.0(@typescript-eslint/parser@8.19.1(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3))(eslint@9.17.0(jiti@1.21.7)) eslint-plugin-jsx-a11y: specifier: ^6.10.2 - version: 6.10.2(eslint@9.17.0) + version: 6.10.2(eslint@9.17.0(jiti@1.21.7)) eslint-plugin-prettier: specifier: ^5.2.1 - version: 5.2.1(eslint-config-prettier@9.1.0(eslint@9.17.0))(eslint@9.17.0)(prettier@3.4.2) + version: 5.2.1(eslint-config-prettier@9.1.0(eslint@9.17.0(jiti@1.21.7)))(eslint@9.17.0(jiti@1.21.7))(prettier@3.4.2) eslint-plugin-react: specifier: ^7.37.3 - version: 7.37.3(eslint@9.17.0) + version: 7.37.3(eslint@9.17.0(jiti@1.21.7)) eslint-plugin-react-hooks: specifier: ^5.1.0 - version: 5.1.0(eslint@9.17.0) + version: 5.1.0(eslint@9.17.0(jiti@1.21.7)) jsdom: specifier: ^25.0.0 version: 25.0.1 + postcss: + specifier: ^8.4.49 + version: 8.4.49 prettier: specifier: ^3.4.2 version: 3.4.2 + tailwindcss: + specifier: ^3.4.17 + version: 3.4.17 + typescript: + specifier: ^5.7.3 + version: 5.7.3 vite: specifier: ^5.1.0 - version: 5.4.11 + version: 5.4.11(@types/node@22.10.5) vitest: specifier: ^2.1.1 - version: 2.1.8(@vitest/ui@2.1.8)(jsdom@25.0.1) + version: 2.1.8(@types/node@22.10.5)(@vitest/ui@2.1.8)(jsdom@25.0.1) packages: '@adobe/css-tools@4.4.1': resolution: {integrity: sha512-12WGKBQzjUAI4ayyF4IAtfw2QR/IDoqk6jTddXDhtYTJF9ASmoE1zst7cVtP0aL/F1jUJL5r+JxKXKEgHNbEUQ==} + '@alloc/quick-lru@5.2.0': + resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} + engines: {node: '>=10'} + + '@ampproject/remapping@2.3.0': + resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} + engines: {node: '>=6.0.0'} + '@babel/code-frame@7.26.2': resolution: {integrity: sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==} engines: {node: '>=6.9.0'} + '@babel/compat-data@7.26.3': + resolution: {integrity: sha512-nHIxvKPniQXpmQLb0vhY3VaFb3S0YrTAwpOWJZh1wn3oJPjJk9Asva204PsBdmAE8vpzfHudT8DB0scYvy9q0g==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.26.0': + resolution: {integrity: sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.26.3': + resolution: {integrity: sha512-6FF/urZvD0sTeO7k6/B15pMLC4CHUv1426lzr3N01aHJTl046uCAh9LXW/fzeXXjPNCJ6iABW5XaWOsIZB93aQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-compilation-targets@7.25.9': + resolution: {integrity: sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.25.9': + resolution: {integrity: sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-transforms@7.26.0': + resolution: {integrity: sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-plugin-utils@7.25.9': + resolution: {integrity: sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@7.25.9': + resolution: {integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==} + engines: {node: '>=6.9.0'} + '@babel/helper-validator-identifier@7.25.9': resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==} engines: {node: '>=6.9.0'} + '@babel/helper-validator-option@7.25.9': + resolution: {integrity: sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.26.0': + resolution: {integrity: sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.26.3': + resolution: {integrity: sha512-WJ/CvmY8Mea8iDXo6a7RK2wbmJITT5fN3BEkRuFlxVyNx8jOKIIhmC4fSkTcPcf8JyavbBwIe6OpiCOBXt/IcA==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/plugin-transform-react-jsx-self@7.25.9': + resolution: {integrity: sha512-y8quW6p0WHkEhmErnfe58r7x0A70uKphQm8Sp8cV7tjNQwK56sNVK0M73LK3WuYmsuyrftut4xAkjjgU0twaMg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-react-jsx-source@7.25.9': + resolution: {integrity: sha512-+iqjT8xmXhhYv4/uiYd8FNQsraMFZIfxVSqxxVSZP0WbbSAWvBXAul0m/zu+7Vv4O/3WtApy9pmaTMiumEZgfg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/runtime@7.26.0': resolution: {integrity: sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==} engines: {node: '>=6.9.0'} + '@babel/template@7.25.9': + resolution: {integrity: sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.26.4': + resolution: {integrity: sha512-fH+b7Y4p3yqvApJALCPJcwb0/XaOSgtK4pzV6WVjPR5GLFQBRI7pfoX2V2iM48NXvX07NUxxm1Vw98YjqTcU5w==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.26.3': + resolution: {integrity: sha512-vN5p+1kl59GVKMvTHt55NzzmYVxprfJD+ql7U9NFIfKCBkYE55LYtS+WtPlaYOyzydrKI8Nezd+aZextrd+FMA==} + engines: {node: '>=6.9.0'} + '@esbuild/aix-ppc64@0.21.5': resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} engines: {node: '>=12'} @@ -272,9 +388,28 @@ packages: resolution: {integrity: sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==} engines: {node: '>=18.18'} + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + + '@jridgewell/gen-mapping@0.3.8': + resolution: {integrity: sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==} + engines: {node: '>=6.0.0'} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/set-array@1.2.1': + resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} + engines: {node: '>=6.0.0'} + '@jridgewell/sourcemap-codec@1.5.0': resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + '@jridgewell/trace-mapping@0.3.25': + resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -287,6 +422,10 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + '@pkgr/core@0.1.1': resolution: {integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} @@ -409,6 +548,18 @@ packages: '@types/aria-query@5.0.4': resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==} + '@types/babel__core@7.20.5': + resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} + + '@types/babel__generator@7.6.8': + resolution: {integrity: sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==} + + '@types/babel__template@7.4.4': + resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} + + '@types/babel__traverse@7.20.6': + resolution: {integrity: sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==} + '@types/estree@1.0.6': resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} @@ -418,6 +569,17 @@ packages: '@types/json5@0.0.29': resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + '@types/node@22.10.5': + resolution: {integrity: sha512-F8Q+SeGimwOo86fiovQh8qiXfFEh2/ocYv7tU5pJ3EXMSSxk1Joj5wefpFK2fHTf/N6HKGSxIDBT9f3gCxXPkQ==} + + '@types/react-dom@19.0.2': + resolution: {integrity: sha512-c1s+7TKFaDRRxr1TxccIX2u7sfCnc3RxkVyBIUA2lCpyqCF+QoAwQ/CBg7bsMdVwP120HEH143VQezKtef5nCg==} + peerDependencies: + '@types/react': ^19.0.0 + + '@types/react@19.0.4': + resolution: {integrity: sha512-3O4QisJDYr1uTUMZHA2YswiQZRq+Pd8D+GdVFYikTutYsTz+QZgWkAPnP7rx9txoI6EXKcPiluMqWPFV3tT9Wg==} + '@typescript-eslint/eslint-plugin@8.19.1': resolution: {integrity: sha512-tJzcVyvvb9h/PB96g30MpxACd9IrunT7GF9wfA9/0TJ1LxGOJx1TdPzSbBBnNED7K9Ka8ybJsnEpiXPktolTLg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -465,6 +627,12 @@ packages: resolution: {integrity: sha512-fzmjU8CHK853V/avYZAvuVut3ZTfwN5YtMaoi+X9Y9MA9keaWNHC3zEQ9zvyX/7Hj+5JkNyK1l7TOR2hevHB6Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@vitejs/plugin-react@4.3.4': + resolution: {integrity: sha512-SCCPBJtYLdE8PX/7ZQAs1QAZ8Jqwih+0VBLum1EGqmCCQal+MIUqLCzj3ZUy8ufbC0cAM4LRlSTm7IQJwWT4ug==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + vite: ^4.2.0 || ^5.0.0 || ^6.0.0 + '@vitest/expect@2.1.8': resolution: {integrity: sha512-8ytZ/fFHq2g4PJVAtDX57mayemKgDR6X3Oa2Foro+EygiOJHUXhCqBAAKQYYajZpFoIfvBCF1j6R6IYRSIUFuw==} @@ -509,6 +677,9 @@ packages: engines: {node: '>=0.4.0'} hasBin: true + add@2.0.6: + resolution: {integrity: sha512-j5QzrmsokwWWp6kUcJQySpbG+xfOBqqKnup3OIk1pz+kB/80SLorZ9V8zHFLO92Lcd+hbvq8bT+zOGoPkmBV0Q==} + agent-base@7.1.3: resolution: {integrity: sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==} engines: {node: '>= 14'} @@ -520,6 +691,10 @@ packages: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} + ansi-regex@6.1.0: + resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==} + engines: {node: '>=12'} + ansi-styles@4.3.0: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} @@ -528,6 +703,20 @@ packages: resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} engines: {node: '>=10'} + ansi-styles@6.2.1: + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + engines: {node: '>=12'} + + any-promise@1.3.0: + resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + + arg@5.0.2: + resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} + argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} @@ -580,6 +769,13 @@ packages: asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + autoprefixer@10.4.20: + resolution: {integrity: sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==} + engines: {node: ^10 || ^12 || >=14} + hasBin: true + peerDependencies: + postcss: ^8.1.0 + available-typed-arrays@1.0.7: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} @@ -595,6 +791,10 @@ packages: balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + engines: {node: '>=8'} + brace-expansion@1.1.11: resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} @@ -605,6 +805,11 @@ packages: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} + browserslist@4.24.4: + resolution: {integrity: sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + cac@6.7.14: resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} engines: {node: '>=8'} @@ -625,6 +830,13 @@ packages: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} + camelcase-css@2.0.1: + resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} + engines: {node: '>= 6'} + + caniuse-lite@1.0.30001692: + resolution: {integrity: sha512-A95VKan0kdtrsnMubMKxEKUKImOPSuCpYgxSQBo036P5YYgVIcOYJEgt/txJWqObiRQeISNCfef9nvlQ0vbV7A==} + chai@5.1.2: resolution: {integrity: sha512-aGtmf24DW6MLHHG5gCx4zaI3uBq3KRtxeVs0DjFH6Z0rDNbsvTxFASFvdj79pxjxZ8/5u3PIiN3IwEIQkiiuPw==} engines: {node: '>=12'} @@ -641,6 +853,10 @@ packages: resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} engines: {node: '>= 16'} + chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + engines: {node: '>= 8.10.0'} + color-convert@2.0.1: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} engines: {node: '>=7.0.0'} @@ -652,12 +868,19 @@ packages: resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} engines: {node: '>= 0.8'} + commander@4.1.1: + resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} + engines: {node: '>= 6'} + concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} confusing-browser-globals@1.0.11: resolution: {integrity: sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==} + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + cross-spawn@7.0.6: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} @@ -665,10 +888,18 @@ packages: css.escape@1.5.1: resolution: {integrity: sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==} + cssesc@3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + cssstyle@4.1.0: resolution: {integrity: sha512-h66W1URKpBS5YMI/V8PyXvTMFT8SupJ1IzoIV8IeBC/ji8WVmrO8dGlTi+2dh6whmdk6BiKJLD/ZBkhWbcg6nA==} engines: {node: '>=18'} + csstype@3.1.3: + resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + damerau-levenshtein@1.0.8: resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==} @@ -731,6 +962,12 @@ packages: resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} engines: {node: '>=6'} + didyoumean@1.2.2: + resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} + + dlv@1.1.3: + resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} + doctrine@2.1.0: resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} engines: {node: '>=0.10.0'} @@ -745,6 +982,15 @@ packages: resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} engines: {node: '>= 0.4'} + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + + electron-to-chromium@1.5.79: + resolution: {integrity: sha512-nYOxJNxQ9Om4EC88BE4pPoNI8xwSFf8pU/BAeOl4Hh/b/i6V4biTAzwV7pXi3ARKeoYO5JZKMIXTryXSVer5RA==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + emoji-regex@9.2.2: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} @@ -791,6 +1037,10 @@ packages: engines: {node: '>=12'} hasBin: true + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + escape-string-regexp@4.0.0: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} @@ -992,10 +1242,17 @@ packages: for-each@0.3.3: resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} + foreground-child@3.3.0: + resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==} + engines: {node: '>=14'} + form-data@4.0.1: resolution: {integrity: sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==} engines: {node: '>= 6'} + fraction.js@4.3.7: + resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} + fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} @@ -1011,6 +1268,10 @@ packages: functions-have-names@1.2.3: resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + get-intrinsic@1.2.7: resolution: {integrity: sha512-VW6Pxhsrk0KAOqs3WEd0klDiF/+V7gQOpAvY1jVU/LHmaD/kQO4523aiJuikX/QAKYiW6x8Jh+RJej1almdtCA==} engines: {node: '>= 0.4'} @@ -1031,6 +1292,14 @@ packages: resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} engines: {node: '>=10.13.0'} + glob@10.4.5: + resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} + hasBin: true + + globals@11.12.0: + resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} + engines: {node: '>=4'} + globals@14.0.0: resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} engines: {node: '>=18'} @@ -1121,6 +1390,10 @@ packages: resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==} engines: {node: '>= 0.4'} + is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + is-boolean-object@1.2.1: resolution: {integrity: sha512-l9qO6eFlUETHtuihLcYOaLKByJ1f+N4kthcU9YjHy3N+B3hWv0y/2Nd0mu/7lTFnRQHTrSdXF50HQ3bl5fEnng==} engines: {node: '>= 0.4'} @@ -1149,6 +1422,10 @@ packages: resolution: {integrity: sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==} engines: {node: '>= 0.4'} + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + is-generator-function@1.1.0: resolution: {integrity: sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==} engines: {node: '>= 0.4'} @@ -1218,6 +1495,13 @@ packages: resolution: {integrity: sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==} engines: {node: '>= 0.4'} + jackspeak@3.4.3: + resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + + jiti@1.21.7: + resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==} + hasBin: true + js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} @@ -1234,6 +1518,11 @@ packages: canvas: optional: true + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} + hasBin: true + json-buffer@3.0.1: resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} @@ -1247,6 +1536,11 @@ packages: resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} hasBin: true + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + jsx-ast-utils@3.3.5: resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} engines: {node: '>=4.0'} @@ -1265,6 +1559,13 @@ packages: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} + lilconfig@3.1.3: + resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} + engines: {node: '>=14'} + + lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + locate-path@6.0.0: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} @@ -1282,6 +1583,12 @@ packages: loupe@3.1.2: resolution: {integrity: sha512-23I4pFZHmAemUnz8WZXbYRSKYj801VDaNv9ETuMh7IrMc7VuVVSo+Z9iLE3ni30+U48iDWfi30d3twAXBYmnCg==} + lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + lz-string@1.5.0: resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} hasBin: true @@ -1323,6 +1630,10 @@ packages: minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + engines: {node: '>=16 || 14 >=14.17'} + mrmime@2.0.0: resolution: {integrity: sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==} engines: {node: '>=10'} @@ -1330,6 +1641,9 @@ packages: ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + mz@2.7.0: + resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + nanoid@3.3.8: resolution: {integrity: sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} @@ -1338,6 +1652,17 @@ packages: natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + node-releases@2.0.19: + resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + normalize-range@0.1.2: + resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==} + engines: {node: '>=0.10.0'} + nwsapi@2.2.16: resolution: {integrity: sha512-F1I/bimDpj3ncaNDhfyMWuFqmQDBwDB0Fogc2qpL3BWvkQteFD/8BzWuIRl83rq0DXfm8SGt/HFhLXZyljTXcQ==} @@ -1345,6 +1670,10 @@ packages: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} + object-hash@3.0.0: + resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} + engines: {node: '>= 6'} + object-inspect@1.13.3: resolution: {integrity: sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==} engines: {node: '>= 0.4'} @@ -1389,6 +1718,9 @@ packages: resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} engines: {node: '>=10'} + package-json-from-dist@1.0.1: + resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + parent-module@1.0.1: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} @@ -1407,6 +1739,10 @@ packages: path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} + pathe@1.1.2: resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} @@ -1425,10 +1761,60 @@ packages: resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} engines: {node: '>=12'} + pify@2.3.0: + resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} + engines: {node: '>=0.10.0'} + + pirates@4.0.6: + resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} + engines: {node: '>= 6'} + + pnpm@9.15.3: + resolution: {integrity: sha512-H3m8JFpm6wsHxdTYMTEkB3RkLKqobvfQQ0q0fA0W9msE4h4MCG62HmLHfvxNf37Aca+tN5avZIkvrmZQkXOJOg==} + engines: {node: '>=18.12'} + hasBin: true + possible-typed-array-names@1.0.0: resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} engines: {node: '>= 0.4'} + postcss-import@15.1.0: + resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==} + engines: {node: '>=14.0.0'} + peerDependencies: + postcss: ^8.0.0 + + postcss-js@4.0.1: + resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==} + engines: {node: ^12 || ^14 || >= 16} + peerDependencies: + postcss: ^8.4.21 + + postcss-load-config@4.0.2: + resolution: {integrity: sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==} + engines: {node: '>= 14'} + peerDependencies: + postcss: '>=8.0.9' + ts-node: '>=9.0.0' + peerDependenciesMeta: + postcss: + optional: true + ts-node: + optional: true + + postcss-nested@6.2.0: + resolution: {integrity: sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==} + engines: {node: '>=12.0'} + peerDependencies: + postcss: ^8.2.14 + + postcss-selector-parser@6.1.2: + resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} + engines: {node: '>=4'} + + postcss-value-parser@4.2.0: + resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} + postcss@8.4.49: resolution: {integrity: sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==} engines: {node: ^10 || ^12 || >=14} @@ -1460,12 +1846,32 @@ packages: queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + react-dom@19.0.0: + resolution: {integrity: sha512-4GV5sHFG0e/0AD4X+ySy6UJd3jVl1iNsNHdpad0qhABJ11twS3TTBnseqsKurKcsNqCEFeGL3uLpVChpIO3QfQ==} + peerDependencies: + react: ^19.0.0 + react-is@16.13.1: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} react-is@17.0.2: resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} + react-refresh@0.14.2: + resolution: {integrity: sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==} + engines: {node: '>=0.10.0'} + + react@19.0.0: + resolution: {integrity: sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==} + engines: {node: '>=0.10.0'} + + read-cache@1.0.0: + resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==} + + readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + redent@3.0.0: resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==} engines: {node: '>=8'} @@ -1528,6 +1934,9 @@ packages: resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==} engines: {node: '>=v12.22.7'} + scheduler@0.25.0: + resolution: {integrity: sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA==} + semver@6.3.1: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true @@ -1576,6 +1985,10 @@ packages: siginfo@2.0.0: resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + sirv@3.0.0: resolution: {integrity: sha512-BPwJGUeDaDCHihkORDchNyyTvWFhcusy1XMmhEVTQTwGeybFbp8YEmB+njbPnth1FibULBSBVwCQni25XlCUDg==} engines: {node: '>=18'} @@ -1590,6 +2003,14 @@ packages: std-env@3.8.0: resolution: {integrity: sha512-Bc3YwwCB+OzldMxOXJIIvC6cPRWr/LxOp48CdQTOkPyk/t4JWWJbrilwBd7RJzKV8QW7tJkcgAmeuLLJugl5/w==} + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + string.prototype.includes@2.0.1: resolution: {integrity: sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==} engines: {node: '>= 0.4'} @@ -1613,6 +2034,14 @@ packages: resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} engines: {node: '>= 0.4'} + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-ansi@7.1.0: + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + engines: {node: '>=12'} + strip-bom@3.0.0: resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} engines: {node: '>=4'} @@ -1625,6 +2054,11 @@ packages: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} + sucrase@3.35.0: + resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==} + engines: {node: '>=16 || 14 >=14.17'} + hasBin: true + supports-color@7.2.0: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} @@ -1640,6 +2074,18 @@ packages: resolution: {integrity: sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw==} engines: {node: ^14.18.0 || >=16.0.0} + tailwindcss@3.4.17: + resolution: {integrity: sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==} + engines: {node: '>=14.0.0'} + hasBin: true + + thenify-all@1.6.0: + resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} + engines: {node: '>=0.8'} + + thenify@3.3.1: + resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + tinybench@2.9.0: resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} @@ -1691,6 +2137,9 @@ packages: peerDependencies: typescript: '>=4.8.4' + ts-interface-checker@0.1.13: + resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + tsconfig-paths@3.15.0: resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} @@ -1717,8 +2166,8 @@ packages: resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==} engines: {node: '>= 0.4'} - typescript@5.7.2: - resolution: {integrity: sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==} + typescript@5.7.3: + resolution: {integrity: sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==} engines: {node: '>=14.17'} hasBin: true @@ -1726,9 +2175,21 @@ packages: resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} engines: {node: '>= 0.4'} + undici-types@6.20.0: + resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==} + + update-browserslist-db@1.1.2: + resolution: {integrity: sha512-PPypAm5qvlD7XMZC3BujecnaOxwhrtoFR+Dqkk5Aa/6DssiH0ibKoketaj9w8LP7Bont1rYeoV5plxD7RTEPRg==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + vite-node@2.1.8: resolution: {integrity: sha512-uPAwSr57kYjAUux+8E2j0q0Fxpn8M9VoyfGiRI8Kfktz9NcYMCenwY5RnZxnF1WTu3TGiYipirIzacLL3VVGFg==} engines: {node: ^18.0.0 || >=20.0.0} @@ -1840,6 +2301,14 @@ packages: resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} engines: {node: '>=0.10.0'} + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + ws@8.18.0: resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} engines: {node: '>=10.0.0'} @@ -1859,6 +2328,14 @@ packages: xmlchars@2.2.0: resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==} + yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + + yaml@2.7.0: + resolution: {integrity: sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==} + engines: {node: '>= 14'} + hasBin: true + yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} @@ -1867,18 +2344,127 @@ snapshots: '@adobe/css-tools@4.4.1': {} + '@alloc/quick-lru@5.2.0': {} + + '@ampproject/remapping@2.3.0': + dependencies: + '@jridgewell/gen-mapping': 0.3.8 + '@jridgewell/trace-mapping': 0.3.25 + '@babel/code-frame@7.26.2': dependencies: '@babel/helper-validator-identifier': 7.25.9 js-tokens: 4.0.0 picocolors: 1.1.1 + '@babel/compat-data@7.26.3': {} + + '@babel/core@7.26.0': + dependencies: + '@ampproject/remapping': 2.3.0 + '@babel/code-frame': 7.26.2 + '@babel/generator': 7.26.3 + '@babel/helper-compilation-targets': 7.25.9 + '@babel/helper-module-transforms': 7.26.0(@babel/core@7.26.0) + '@babel/helpers': 7.26.0 + '@babel/parser': 7.26.3 + '@babel/template': 7.25.9 + '@babel/traverse': 7.26.4 + '@babel/types': 7.26.3 + convert-source-map: 2.0.0 + debug: 4.4.0 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/generator@7.26.3': + dependencies: + '@babel/parser': 7.26.3 + '@babel/types': 7.26.3 + '@jridgewell/gen-mapping': 0.3.8 + '@jridgewell/trace-mapping': 0.3.25 + jsesc: 3.1.0 + + '@babel/helper-compilation-targets@7.25.9': + dependencies: + '@babel/compat-data': 7.26.3 + '@babel/helper-validator-option': 7.25.9 + browserslist: 4.24.4 + lru-cache: 5.1.1 + semver: 6.3.1 + + '@babel/helper-module-imports@7.25.9': + dependencies: + '@babel/traverse': 7.26.4 + '@babel/types': 7.26.3 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.26.0(@babel/core@7.26.0)': + dependencies: + '@babel/core': 7.26.0 + '@babel/helper-module-imports': 7.25.9 + '@babel/helper-validator-identifier': 7.25.9 + '@babel/traverse': 7.26.4 + transitivePeerDependencies: + - supports-color + + '@babel/helper-plugin-utils@7.25.9': {} + + '@babel/helper-string-parser@7.25.9': {} + '@babel/helper-validator-identifier@7.25.9': {} + '@babel/helper-validator-option@7.25.9': {} + + '@babel/helpers@7.26.0': + dependencies: + '@babel/template': 7.25.9 + '@babel/types': 7.26.3 + + '@babel/parser@7.26.3': + dependencies: + '@babel/types': 7.26.3 + + '@babel/plugin-transform-react-jsx-self@7.25.9(@babel/core@7.26.0)': + dependencies: + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 + + '@babel/plugin-transform-react-jsx-source@7.25.9(@babel/core@7.26.0)': + dependencies: + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 + '@babel/runtime@7.26.0': dependencies: regenerator-runtime: 0.14.1 + '@babel/template@7.25.9': + dependencies: + '@babel/code-frame': 7.26.2 + '@babel/parser': 7.26.3 + '@babel/types': 7.26.3 + + '@babel/traverse@7.26.4': + dependencies: + '@babel/code-frame': 7.26.2 + '@babel/generator': 7.26.3 + '@babel/parser': 7.26.3 + '@babel/template': 7.25.9 + '@babel/types': 7.26.3 + debug: 4.4.0 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + + '@babel/types@7.26.3': + dependencies: + '@babel/helper-string-parser': 7.25.9 + '@babel/helper-validator-identifier': 7.25.9 + '@esbuild/aix-ppc64@0.21.5': optional: true @@ -1948,9 +2534,9 @@ snapshots: '@esbuild/win32-x64@0.21.5': optional: true - '@eslint-community/eslint-utils@4.4.1(eslint@9.17.0)': + '@eslint-community/eslint-utils@4.4.1(eslint@9.17.0(jiti@1.21.7))': dependencies: - eslint: 9.17.0 + eslint: 9.17.0(jiti@1.21.7) eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.1': {} @@ -2002,8 +2588,32 @@ snapshots: '@humanwhocodes/retry@0.4.1': {} + '@isaacs/cliui@8.0.2': + dependencies: + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.1.0 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 + + '@jridgewell/gen-mapping@0.3.8': + dependencies: + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping': 0.3.25 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/set-array@1.2.1': {} + '@jridgewell/sourcemap-codec@1.5.0': {} + '@jridgewell/trace-mapping@0.3.25': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 + '@nodelib/fs.scandir@2.1.5': dependencies: '@nodelib/fs.stat': 2.0.5 @@ -2016,6 +2626,9 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.18.0 + '@pkgjs/parseargs@0.11.0': + optional: true + '@pkgr/core@0.1.1': {} '@polka/url@1.0.0-next.28': {} @@ -2106,38 +2719,71 @@ snapshots: '@types/aria-query@5.0.4': {} + '@types/babel__core@7.20.5': + dependencies: + '@babel/parser': 7.26.3 + '@babel/types': 7.26.3 + '@types/babel__generator': 7.6.8 + '@types/babel__template': 7.4.4 + '@types/babel__traverse': 7.20.6 + + '@types/babel__generator@7.6.8': + dependencies: + '@babel/types': 7.26.3 + + '@types/babel__template@7.4.4': + dependencies: + '@babel/parser': 7.26.3 + '@babel/types': 7.26.3 + + '@types/babel__traverse@7.20.6': + dependencies: + '@babel/types': 7.26.3 + '@types/estree@1.0.6': {} '@types/json-schema@7.0.15': {} '@types/json5@0.0.29': {} - '@typescript-eslint/eslint-plugin@8.19.1(@typescript-eslint/parser@8.19.1(eslint@9.17.0)(typescript@5.7.2))(eslint@9.17.0)(typescript@5.7.2)': + '@types/node@22.10.5': + dependencies: + undici-types: 6.20.0 + + '@types/react-dom@19.0.2(@types/react@19.0.4)': + dependencies: + '@types/react': 19.0.4 + + '@types/react@19.0.4': + dependencies: + csstype: 3.1.3 + + '@typescript-eslint/eslint-plugin@8.19.1(@typescript-eslint/parser@8.19.1(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3))(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3)': dependencies: '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.19.1(eslint@9.17.0)(typescript@5.7.2) + '@typescript-eslint/parser': 8.19.1(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3) '@typescript-eslint/scope-manager': 8.19.1 - '@typescript-eslint/type-utils': 8.19.1(eslint@9.17.0)(typescript@5.7.2) - '@typescript-eslint/utils': 8.19.1(eslint@9.17.0)(typescript@5.7.2) + '@typescript-eslint/type-utils': 8.19.1(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3) + '@typescript-eslint/utils': 8.19.1(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3) '@typescript-eslint/visitor-keys': 8.19.1 - eslint: 9.17.0 + eslint: 9.17.0(jiti@1.21.7) graphemer: 1.4.0 ignore: 5.3.2 natural-compare: 1.4.0 - ts-api-utils: 2.0.0(typescript@5.7.2) - typescript: 5.7.2 + ts-api-utils: 2.0.0(typescript@5.7.3) + typescript: 5.7.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.19.1(eslint@9.17.0)(typescript@5.7.2)': + '@typescript-eslint/parser@8.19.1(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3)': dependencies: '@typescript-eslint/scope-manager': 8.19.1 '@typescript-eslint/types': 8.19.1 - '@typescript-eslint/typescript-estree': 8.19.1(typescript@5.7.2) + '@typescript-eslint/typescript-estree': 8.19.1(typescript@5.7.3) '@typescript-eslint/visitor-keys': 8.19.1 debug: 4.4.0 - eslint: 9.17.0 - typescript: 5.7.2 + eslint: 9.17.0(jiti@1.21.7) + typescript: 5.7.3 transitivePeerDependencies: - supports-color @@ -2146,20 +2792,20 @@ snapshots: '@typescript-eslint/types': 8.19.1 '@typescript-eslint/visitor-keys': 8.19.1 - '@typescript-eslint/type-utils@8.19.1(eslint@9.17.0)(typescript@5.7.2)': + '@typescript-eslint/type-utils@8.19.1(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3)': dependencies: - '@typescript-eslint/typescript-estree': 8.19.1(typescript@5.7.2) - '@typescript-eslint/utils': 8.19.1(eslint@9.17.0)(typescript@5.7.2) + '@typescript-eslint/typescript-estree': 8.19.1(typescript@5.7.3) + '@typescript-eslint/utils': 8.19.1(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3) debug: 4.4.0 - eslint: 9.17.0 - ts-api-utils: 2.0.0(typescript@5.7.2) - typescript: 5.7.2 + eslint: 9.17.0(jiti@1.21.7) + ts-api-utils: 2.0.0(typescript@5.7.3) + typescript: 5.7.3 transitivePeerDependencies: - supports-color '@typescript-eslint/types@8.19.1': {} - '@typescript-eslint/typescript-estree@8.19.1(typescript@5.7.2)': + '@typescript-eslint/typescript-estree@8.19.1(typescript@5.7.3)': dependencies: '@typescript-eslint/types': 8.19.1 '@typescript-eslint/visitor-keys': 8.19.1 @@ -2168,19 +2814,19 @@ snapshots: is-glob: 4.0.3 minimatch: 9.0.5 semver: 7.6.3 - ts-api-utils: 2.0.0(typescript@5.7.2) - typescript: 5.7.2 + ts-api-utils: 2.0.0(typescript@5.7.3) + typescript: 5.7.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.19.1(eslint@9.17.0)(typescript@5.7.2)': + '@typescript-eslint/utils@8.19.1(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3)': dependencies: - '@eslint-community/eslint-utils': 4.4.1(eslint@9.17.0) + '@eslint-community/eslint-utils': 4.4.1(eslint@9.17.0(jiti@1.21.7)) '@typescript-eslint/scope-manager': 8.19.1 '@typescript-eslint/types': 8.19.1 - '@typescript-eslint/typescript-estree': 8.19.1(typescript@5.7.2) - eslint: 9.17.0 - typescript: 5.7.2 + '@typescript-eslint/typescript-estree': 8.19.1(typescript@5.7.3) + eslint: 9.17.0(jiti@1.21.7) + typescript: 5.7.3 transitivePeerDependencies: - supports-color @@ -2189,6 +2835,17 @@ snapshots: '@typescript-eslint/types': 8.19.1 eslint-visitor-keys: 4.2.0 + '@vitejs/plugin-react@4.3.4(vite@5.4.11(@types/node@22.10.5))': + dependencies: + '@babel/core': 7.26.0 + '@babel/plugin-transform-react-jsx-self': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-react-jsx-source': 7.25.9(@babel/core@7.26.0) + '@types/babel__core': 7.20.5 + react-refresh: 0.14.2 + vite: 5.4.11(@types/node@22.10.5) + transitivePeerDependencies: + - supports-color + '@vitest/expect@2.1.8': dependencies: '@vitest/spy': 2.1.8 @@ -2196,13 +2853,13 @@ snapshots: chai: 5.1.2 tinyrainbow: 1.2.0 - '@vitest/mocker@2.1.8(vite@5.4.11)': + '@vitest/mocker@2.1.8(vite@5.4.11(@types/node@22.10.5))': dependencies: '@vitest/spy': 2.1.8 estree-walker: 3.0.3 magic-string: 0.30.17 optionalDependencies: - vite: 5.4.11 + vite: 5.4.11(@types/node@22.10.5) '@vitest/pretty-format@2.1.8': dependencies: @@ -2232,7 +2889,7 @@ snapshots: sirv: 3.0.0 tinyglobby: 0.2.10 tinyrainbow: 1.2.0 - vitest: 2.1.8(@vitest/ui@2.1.8)(jsdom@25.0.1) + vitest: 2.1.8(@types/node@22.10.5)(@vitest/ui@2.1.8)(jsdom@25.0.1) '@vitest/utils@2.1.8': dependencies: @@ -2246,6 +2903,8 @@ snapshots: acorn@8.14.0: {} + add@2.0.6: {} + agent-base@7.1.3: {} ajv@6.12.6: @@ -2257,12 +2916,25 @@ snapshots: ansi-regex@5.0.1: {} + ansi-regex@6.1.0: {} + ansi-styles@4.3.0: dependencies: color-convert: 2.0.1 ansi-styles@5.2.0: {} + ansi-styles@6.2.1: {} + + any-promise@1.3.0: {} + + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + + arg@5.0.2: {} + argparse@2.0.1: {} aria-query@5.3.0: @@ -2341,6 +3013,16 @@ snapshots: asynckit@0.4.0: {} + autoprefixer@10.4.20(postcss@8.4.49): + dependencies: + browserslist: 4.24.4 + caniuse-lite: 1.0.30001692 + fraction.js: 4.3.7 + normalize-range: 0.1.2 + picocolors: 1.1.1 + postcss: 8.4.49 + postcss-value-parser: 4.2.0 + available-typed-arrays@1.0.7: dependencies: possible-typed-array-names: 1.0.0 @@ -2351,6 +3033,8 @@ snapshots: balanced-match@1.0.2: {} + binary-extensions@2.3.0: {} + brace-expansion@1.1.11: dependencies: balanced-match: 1.0.2 @@ -2364,6 +3048,13 @@ snapshots: dependencies: fill-range: 7.1.1 + browserslist@4.24.4: + dependencies: + caniuse-lite: 1.0.30001692 + electron-to-chromium: 1.5.79 + node-releases: 2.0.19 + update-browserslist-db: 1.1.2(browserslist@4.24.4) + cac@6.7.14: {} call-bind-apply-helpers@1.0.1: @@ -2385,6 +3076,10 @@ snapshots: callsites@3.1.0: {} + camelcase-css@2.0.1: {} + + caniuse-lite@1.0.30001692: {} + chai@5.1.2: dependencies: assertion-error: 2.0.1 @@ -2405,6 +3100,18 @@ snapshots: check-error@2.1.1: {} + chokidar@3.6.0: + dependencies: + anymatch: 3.1.3 + braces: 3.0.3 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + color-convert@2.0.1: dependencies: color-name: 1.1.4 @@ -2415,10 +3122,14 @@ snapshots: dependencies: delayed-stream: 1.0.0 + commander@4.1.1: {} + concat-map@0.0.1: {} confusing-browser-globals@1.0.11: {} + convert-source-map@2.0.0: {} + cross-spawn@7.0.6: dependencies: path-key: 3.1.1 @@ -2427,10 +3138,14 @@ snapshots: css.escape@1.5.1: {} + cssesc@3.0.0: {} + cssstyle@4.1.0: dependencies: rrweb-cssom: 0.7.1 + csstype@3.1.3: {} + damerau-levenshtein@1.0.8: {} data-urls@5.0.0: @@ -2486,6 +3201,10 @@ snapshots: dequal@2.0.3: {} + didyoumean@1.2.2: {} + + dlv@1.1.3: {} + doctrine@2.1.0: dependencies: esutils: 2.0.3 @@ -2500,6 +3219,12 @@ snapshots: es-errors: 1.3.0 gopd: 1.2.0 + eastasianwidth@0.2.0: {} + + electron-to-chromium@1.5.79: {} + + emoji-regex@8.0.0: {} + emoji-regex@9.2.2: {} entities@4.5.0: {} @@ -2630,40 +3355,42 @@ snapshots: '@esbuild/win32-ia32': 0.21.5 '@esbuild/win32-x64': 0.21.5 + escalade@3.2.0: {} + escape-string-regexp@4.0.0: {} - eslint-config-airbnb-base@15.0.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.19.1(eslint@9.17.0)(typescript@5.7.2))(eslint@9.17.0))(eslint@9.17.0): + eslint-config-airbnb-base@15.0.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.19.1(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3))(eslint@9.17.0(jiti@1.21.7)))(eslint@9.17.0(jiti@1.21.7)): dependencies: confusing-browser-globals: 1.0.11 - eslint: 9.17.0 - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.19.1(eslint@9.17.0)(typescript@5.7.2))(eslint@9.17.0) + eslint: 9.17.0(jiti@1.21.7) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.19.1(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3))(eslint@9.17.0(jiti@1.21.7)) object.assign: 4.1.7 object.entries: 1.1.8 semver: 6.3.1 - eslint-config-airbnb-typescript@18.0.0(@typescript-eslint/eslint-plugin@8.19.1(@typescript-eslint/parser@8.19.1(eslint@9.17.0)(typescript@5.7.2))(eslint@9.17.0)(typescript@5.7.2))(@typescript-eslint/parser@8.19.1(eslint@9.17.0)(typescript@5.7.2))(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.19.1(eslint@9.17.0)(typescript@5.7.2))(eslint@9.17.0))(eslint@9.17.0): + eslint-config-airbnb-typescript@18.0.0(@typescript-eslint/eslint-plugin@8.19.1(@typescript-eslint/parser@8.19.1(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3))(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3))(@typescript-eslint/parser@8.19.1(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3))(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.19.1(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3))(eslint@9.17.0(jiti@1.21.7)))(eslint@9.17.0(jiti@1.21.7)): dependencies: - '@typescript-eslint/eslint-plugin': 8.19.1(@typescript-eslint/parser@8.19.1(eslint@9.17.0)(typescript@5.7.2))(eslint@9.17.0)(typescript@5.7.2) - '@typescript-eslint/parser': 8.19.1(eslint@9.17.0)(typescript@5.7.2) - eslint: 9.17.0 - eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.19.1(eslint@9.17.0)(typescript@5.7.2))(eslint@9.17.0))(eslint@9.17.0) + '@typescript-eslint/eslint-plugin': 8.19.1(@typescript-eslint/parser@8.19.1(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3))(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3) + '@typescript-eslint/parser': 8.19.1(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3) + eslint: 9.17.0(jiti@1.21.7) + eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.19.1(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3))(eslint@9.17.0(jiti@1.21.7)))(eslint@9.17.0(jiti@1.21.7)) transitivePeerDependencies: - eslint-plugin-import - eslint-config-airbnb@19.0.4(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.19.1(eslint@9.17.0)(typescript@5.7.2))(eslint@9.17.0))(eslint-plugin-jsx-a11y@6.10.2(eslint@9.17.0))(eslint-plugin-react-hooks@5.1.0(eslint@9.17.0))(eslint-plugin-react@7.37.3(eslint@9.17.0))(eslint@9.17.0): + eslint-config-airbnb@19.0.4(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.19.1(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3))(eslint@9.17.0(jiti@1.21.7)))(eslint-plugin-jsx-a11y@6.10.2(eslint@9.17.0(jiti@1.21.7)))(eslint-plugin-react-hooks@5.1.0(eslint@9.17.0(jiti@1.21.7)))(eslint-plugin-react@7.37.3(eslint@9.17.0(jiti@1.21.7)))(eslint@9.17.0(jiti@1.21.7)): dependencies: - eslint: 9.17.0 - eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.19.1(eslint@9.17.0)(typescript@5.7.2))(eslint@9.17.0))(eslint@9.17.0) - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.19.1(eslint@9.17.0)(typescript@5.7.2))(eslint@9.17.0) - eslint-plugin-jsx-a11y: 6.10.2(eslint@9.17.0) - eslint-plugin-react: 7.37.3(eslint@9.17.0) - eslint-plugin-react-hooks: 5.1.0(eslint@9.17.0) + eslint: 9.17.0(jiti@1.21.7) + eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.19.1(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3))(eslint@9.17.0(jiti@1.21.7)))(eslint@9.17.0(jiti@1.21.7)) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.19.1(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3))(eslint@9.17.0(jiti@1.21.7)) + eslint-plugin-jsx-a11y: 6.10.2(eslint@9.17.0(jiti@1.21.7)) + eslint-plugin-react: 7.37.3(eslint@9.17.0(jiti@1.21.7)) + eslint-plugin-react-hooks: 5.1.0(eslint@9.17.0(jiti@1.21.7)) object.assign: 4.1.7 object.entries: 1.1.8 - eslint-config-prettier@9.1.0(eslint@9.17.0): + eslint-config-prettier@9.1.0(eslint@9.17.0(jiti@1.21.7)): dependencies: - eslint: 9.17.0 + eslint: 9.17.0(jiti@1.21.7) eslint-import-resolver-node@0.3.9: dependencies: @@ -2673,17 +3400,17 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.0(@typescript-eslint/parser@8.19.1(eslint@9.17.0)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint@9.17.0): + eslint-module-utils@2.12.0(@typescript-eslint/parser@8.19.1(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint@9.17.0(jiti@1.21.7)): dependencies: debug: 3.2.7 optionalDependencies: - '@typescript-eslint/parser': 8.19.1(eslint@9.17.0)(typescript@5.7.2) - eslint: 9.17.0 + '@typescript-eslint/parser': 8.19.1(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3) + eslint: 9.17.0(jiti@1.21.7) eslint-import-resolver-node: 0.3.9 transitivePeerDependencies: - supports-color - eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.19.1(eslint@9.17.0)(typescript@5.7.2))(eslint@9.17.0): + eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.19.1(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3))(eslint@9.17.0(jiti@1.21.7)): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.8 @@ -2692,9 +3419,9 @@ snapshots: array.prototype.flatmap: 1.3.3 debug: 3.2.7 doctrine: 2.1.0 - eslint: 9.17.0 + eslint: 9.17.0(jiti@1.21.7) eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.19.1(eslint@9.17.0)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint@9.17.0) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.19.1(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint@9.17.0(jiti@1.21.7)) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -2706,13 +3433,13 @@ snapshots: string.prototype.trimend: 1.0.9 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 8.19.1(eslint@9.17.0)(typescript@5.7.2) + '@typescript-eslint/parser': 8.19.1(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack - supports-color - eslint-plugin-jsx-a11y@6.10.2(eslint@9.17.0): + eslint-plugin-jsx-a11y@6.10.2(eslint@9.17.0(jiti@1.21.7)): dependencies: aria-query: 5.3.2 array-includes: 3.1.8 @@ -2722,7 +3449,7 @@ snapshots: axobject-query: 4.1.0 damerau-levenshtein: 1.0.8 emoji-regex: 9.2.2 - eslint: 9.17.0 + eslint: 9.17.0(jiti@1.21.7) hasown: 2.0.2 jsx-ast-utils: 3.3.5 language-tags: 1.0.9 @@ -2731,20 +3458,20 @@ snapshots: safe-regex-test: 1.1.0 string.prototype.includes: 2.0.1 - eslint-plugin-prettier@5.2.1(eslint-config-prettier@9.1.0(eslint@9.17.0))(eslint@9.17.0)(prettier@3.4.2): + eslint-plugin-prettier@5.2.1(eslint-config-prettier@9.1.0(eslint@9.17.0(jiti@1.21.7)))(eslint@9.17.0(jiti@1.21.7))(prettier@3.4.2): dependencies: - eslint: 9.17.0 + eslint: 9.17.0(jiti@1.21.7) prettier: 3.4.2 prettier-linter-helpers: 1.0.0 synckit: 0.9.2 optionalDependencies: - eslint-config-prettier: 9.1.0(eslint@9.17.0) + eslint-config-prettier: 9.1.0(eslint@9.17.0(jiti@1.21.7)) - eslint-plugin-react-hooks@5.1.0(eslint@9.17.0): + eslint-plugin-react-hooks@5.1.0(eslint@9.17.0(jiti@1.21.7)): dependencies: - eslint: 9.17.0 + eslint: 9.17.0(jiti@1.21.7) - eslint-plugin-react@7.37.3(eslint@9.17.0): + eslint-plugin-react@7.37.3(eslint@9.17.0(jiti@1.21.7)): dependencies: array-includes: 3.1.8 array.prototype.findlast: 1.2.5 @@ -2752,7 +3479,7 @@ snapshots: array.prototype.tosorted: 1.1.4 doctrine: 2.1.0 es-iterator-helpers: 1.2.1 - eslint: 9.17.0 + eslint: 9.17.0(jiti@1.21.7) estraverse: 5.3.0 hasown: 2.0.2 jsx-ast-utils: 3.3.5 @@ -2775,9 +3502,9 @@ snapshots: eslint-visitor-keys@4.2.0: {} - eslint@9.17.0: + eslint@9.17.0(jiti@1.21.7): dependencies: - '@eslint-community/eslint-utils': 4.4.1(eslint@9.17.0) + '@eslint-community/eslint-utils': 4.4.1(eslint@9.17.0(jiti@1.21.7)) '@eslint-community/regexpp': 4.12.1 '@eslint/config-array': 0.19.1 '@eslint/core': 0.9.1 @@ -2811,6 +3538,8 @@ snapshots: minimatch: 3.1.2 natural-compare: 1.4.0 optionator: 0.9.4 + optionalDependencies: + jiti: 1.21.7 transitivePeerDependencies: - supports-color @@ -2888,12 +3617,19 @@ snapshots: dependencies: is-callable: 1.2.7 + foreground-child@3.3.0: + dependencies: + cross-spawn: 7.0.6 + signal-exit: 4.1.0 + form-data@4.0.1: dependencies: asynckit: 0.4.0 combined-stream: 1.0.8 mime-types: 2.1.35 + fraction.js@4.3.7: {} + fsevents@2.3.3: optional: true @@ -2910,6 +3646,8 @@ snapshots: functions-have-names@1.2.3: {} + gensync@1.0.0-beta.2: {} + get-intrinsic@1.2.7: dependencies: call-bind-apply-helpers: 1.0.1 @@ -2942,6 +3680,17 @@ snapshots: dependencies: is-glob: 4.0.3 + glob@10.4.5: + dependencies: + foreground-child: 3.3.0 + jackspeak: 3.4.3 + minimatch: 9.0.5 + minipass: 7.1.2 + package-json-from-dist: 1.0.1 + path-scurry: 1.11.1 + + globals@11.12.0: {} + globals@14.0.0: {} globalthis@1.0.4: @@ -3031,6 +3780,10 @@ snapshots: dependencies: has-bigints: 1.1.0 + is-binary-path@2.1.0: + dependencies: + binary-extensions: 2.3.0 + is-boolean-object@1.2.1: dependencies: call-bound: 1.0.3 @@ -3059,6 +3812,8 @@ snapshots: dependencies: call-bound: 1.0.3 + is-fullwidth-code-point@3.0.0: {} + is-generator-function@1.1.0: dependencies: call-bound: 1.0.3 @@ -3133,6 +3888,14 @@ snapshots: has-symbols: 1.1.0 set-function-name: 2.0.2 + jackspeak@3.4.3: + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + + jiti@1.21.7: {} + js-tokens@4.0.0: {} js-yaml@4.1.0: @@ -3167,6 +3930,8 @@ snapshots: - supports-color - utf-8-validate + jsesc@3.1.0: {} + json-buffer@3.0.1: {} json-schema-traverse@0.4.1: {} @@ -3177,6 +3942,8 @@ snapshots: dependencies: minimist: 1.2.8 + json5@2.2.3: {} + jsx-ast-utils@3.3.5: dependencies: array-includes: 3.1.8 @@ -3199,6 +3966,10 @@ snapshots: prelude-ls: 1.2.1 type-check: 0.4.0 + lilconfig@3.1.3: {} + + lines-and-columns@1.2.4: {} + locate-path@6.0.0: dependencies: p-locate: 5.0.0 @@ -3213,6 +3984,12 @@ snapshots: loupe@3.1.2: {} + lru-cache@10.4.3: {} + + lru-cache@5.1.1: + dependencies: + yallist: 3.1.1 + lz-string@1.5.0: {} magic-string@0.30.17: @@ -3246,18 +4023,34 @@ snapshots: minimist@1.2.8: {} + minipass@7.1.2: {} + mrmime@2.0.0: {} ms@2.1.3: {} + mz@2.7.0: + dependencies: + any-promise: 1.3.0 + object-assign: 4.1.1 + thenify-all: 1.6.0 + nanoid@3.3.8: {} natural-compare@1.4.0: {} + node-releases@2.0.19: {} + + normalize-path@3.0.0: {} + + normalize-range@0.1.2: {} + nwsapi@2.2.16: {} object-assign@4.1.1: {} + object-hash@3.0.0: {} + object-inspect@1.13.3: {} object-keys@1.1.1: {} @@ -3320,6 +4113,8 @@ snapshots: dependencies: p-limit: 3.1.0 + package-json-from-dist@1.0.1: {} + parent-module@1.0.1: dependencies: callsites: 3.1.0 @@ -3334,6 +4129,11 @@ snapshots: path-parse@1.0.7: {} + path-scurry@1.11.1: + dependencies: + lru-cache: 10.4.3 + minipass: 7.1.2 + pathe@1.1.2: {} pathval@2.0.0: {} @@ -3344,8 +4144,45 @@ snapshots: picomatch@4.0.2: {} + pify@2.3.0: {} + + pirates@4.0.6: {} + + pnpm@9.15.3: {} + possible-typed-array-names@1.0.0: {} + postcss-import@15.1.0(postcss@8.4.49): + dependencies: + postcss: 8.4.49 + postcss-value-parser: 4.2.0 + read-cache: 1.0.0 + resolve: 1.22.10 + + postcss-js@4.0.1(postcss@8.4.49): + dependencies: + camelcase-css: 2.0.1 + postcss: 8.4.49 + + postcss-load-config@4.0.2(postcss@8.4.49): + dependencies: + lilconfig: 3.1.3 + yaml: 2.7.0 + optionalDependencies: + postcss: 8.4.49 + + postcss-nested@6.2.0(postcss@8.4.49): + dependencies: + postcss: 8.4.49 + postcss-selector-parser: 6.1.2 + + postcss-selector-parser@6.1.2: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + + postcss-value-parser@4.2.0: {} + postcss@8.4.49: dependencies: nanoid: 3.3.8 @@ -3376,10 +4213,27 @@ snapshots: queue-microtask@1.2.3: {} + react-dom@19.0.0(react@19.0.0): + dependencies: + react: 19.0.0 + scheduler: 0.25.0 + react-is@16.13.1: {} react-is@17.0.2: {} + react-refresh@0.14.2: {} + + react@19.0.0: {} + + read-cache@1.0.0: + dependencies: + pify: 2.3.0 + + readdirp@3.6.0: + dependencies: + picomatch: 2.3.1 + redent@3.0.0: dependencies: indent-string: 4.0.0 @@ -3479,6 +4333,8 @@ snapshots: dependencies: xmlchars: 2.2.0 + scheduler@0.25.0: {} + semver@6.3.1: {} semver@7.6.3: {} @@ -3541,6 +4397,8 @@ snapshots: siginfo@2.0.0: {} + signal-exit@4.1.0: {} + sirv@3.0.0: dependencies: '@polka/url': 1.0.0-next.28 @@ -3553,6 +4411,18 @@ snapshots: std-env@3.8.0: {} + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string-width@5.1.2: + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.1.0 + string.prototype.includes@2.0.1: dependencies: call-bind: 1.0.8 @@ -3603,6 +4473,14 @@ snapshots: define-properties: 1.2.1 es-object-atoms: 1.0.0 + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-ansi@7.1.0: + dependencies: + ansi-regex: 6.1.0 + strip-bom@3.0.0: {} strip-indent@3.0.0: @@ -3611,6 +4489,16 @@ snapshots: strip-json-comments@3.1.1: {} + sucrase@3.35.0: + dependencies: + '@jridgewell/gen-mapping': 0.3.8 + commander: 4.1.1 + glob: 10.4.5 + lines-and-columns: 1.2.4 + mz: 2.7.0 + pirates: 4.0.6 + ts-interface-checker: 0.1.13 + supports-color@7.2.0: dependencies: has-flag: 4.0.0 @@ -3624,6 +4512,41 @@ snapshots: '@pkgr/core': 0.1.1 tslib: 2.8.1 + tailwindcss@3.4.17: + dependencies: + '@alloc/quick-lru': 5.2.0 + arg: 5.0.2 + chokidar: 3.6.0 + didyoumean: 1.2.2 + dlv: 1.1.3 + fast-glob: 3.3.3 + glob-parent: 6.0.2 + is-glob: 4.0.3 + jiti: 1.21.7 + lilconfig: 3.1.3 + micromatch: 4.0.8 + normalize-path: 3.0.0 + object-hash: 3.0.0 + picocolors: 1.1.1 + postcss: 8.4.49 + postcss-import: 15.1.0(postcss@8.4.49) + postcss-js: 4.0.1(postcss@8.4.49) + postcss-load-config: 4.0.2(postcss@8.4.49) + postcss-nested: 6.2.0(postcss@8.4.49) + postcss-selector-parser: 6.1.2 + resolve: 1.22.10 + sucrase: 3.35.0 + transitivePeerDependencies: + - ts-node + + thenify-all@1.6.0: + dependencies: + thenify: 3.3.1 + + thenify@3.3.1: + dependencies: + any-promise: 1.3.0 + tinybench@2.9.0: {} tinyexec@0.3.2: {} @@ -3659,9 +4582,11 @@ snapshots: dependencies: punycode: 2.3.1 - ts-api-utils@2.0.0(typescript@5.7.2): + ts-api-utils@2.0.0(typescript@5.7.3): dependencies: - typescript: 5.7.2 + typescript: 5.7.3 + + ts-interface-checker@0.1.13: {} tsconfig-paths@3.15.0: dependencies: @@ -3709,7 +4634,7 @@ snapshots: possible-typed-array-names: 1.0.0 reflect.getprototypeof: 1.0.10 - typescript@5.7.2: {} + typescript@5.7.3: {} unbox-primitive@1.1.0: dependencies: @@ -3718,17 +4643,27 @@ snapshots: has-symbols: 1.1.0 which-boxed-primitive: 1.1.1 + undici-types@6.20.0: {} + + update-browserslist-db@1.1.2(browserslist@4.24.4): + dependencies: + browserslist: 4.24.4 + escalade: 3.2.0 + picocolors: 1.1.1 + uri-js@4.4.1: dependencies: punycode: 2.3.1 - vite-node@2.1.8: + util-deprecate@1.0.2: {} + + vite-node@2.1.8(@types/node@22.10.5): dependencies: cac: 6.7.14 debug: 4.4.0 es-module-lexer: 1.6.0 pathe: 1.1.2 - vite: 5.4.11 + vite: 5.4.11(@types/node@22.10.5) transitivePeerDependencies: - '@types/node' - less @@ -3740,18 +4675,19 @@ snapshots: - supports-color - terser - vite@5.4.11: + vite@5.4.11(@types/node@22.10.5): dependencies: esbuild: 0.21.5 postcss: 8.4.49 rollup: 4.30.1 optionalDependencies: + '@types/node': 22.10.5 fsevents: 2.3.3 - vitest@2.1.8(@vitest/ui@2.1.8)(jsdom@25.0.1): + vitest@2.1.8(@types/node@22.10.5)(@vitest/ui@2.1.8)(jsdom@25.0.1): dependencies: '@vitest/expect': 2.1.8 - '@vitest/mocker': 2.1.8(vite@5.4.11) + '@vitest/mocker': 2.1.8(vite@5.4.11(@types/node@22.10.5)) '@vitest/pretty-format': 2.1.8 '@vitest/runner': 2.1.8 '@vitest/snapshot': 2.1.8 @@ -3767,10 +4703,11 @@ snapshots: tinyexec: 0.3.2 tinypool: 1.0.2 tinyrainbow: 1.2.0 - vite: 5.4.11 - vite-node: 2.1.8 + vite: 5.4.11(@types/node@22.10.5) + vite-node: 2.1.8(@types/node@22.10.5) why-is-node-running: 2.3.0 optionalDependencies: + '@types/node': 22.10.5 '@vitest/ui': 2.1.8(vitest@2.1.8) jsdom: 25.0.1 transitivePeerDependencies: @@ -3852,10 +4789,26 @@ snapshots: word-wrap@1.2.5: {} + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@8.1.0: + dependencies: + ansi-styles: 6.2.1 + string-width: 5.1.2 + strip-ansi: 7.1.0 + ws@8.18.0: {} xml-name-validator@5.0.0: {} xmlchars@2.2.0: {} + yallist@3.1.1: {} + + yaml@2.7.0: {} + yocto-queue@0.1.0: {} diff --git a/postcss.config.js b/postcss.config.js new file mode 100644 index 00000000..2e7af2b7 --- /dev/null +++ b/postcss.config.js @@ -0,0 +1,6 @@ +export default { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +} diff --git a/src/advanced/components/App.tsx b/src/advanced/components/App.tsx new file mode 100644 index 00000000..27d3b019 --- /dev/null +++ b/src/advanced/components/App.tsx @@ -0,0 +1,33 @@ +import { useCart } from "../hooks/useCart"; +import { CartList } from "./Cart/CartList"; +import { CartTotal } from "./Cart/CartTotal"; +import { ProductSelect } from "./Product/ProductSelect"; +import { StockInfo } from "./Product/StockInfo"; + +export function App() { + const { products, cartItems, addToCart, updateQuantity, getTotal } = + useCart(); + const cartResult = getTotal(); + + return ( +
+

장바구니

+ + + + updateQuantity(id, -9999)} + /> + + + + +
+ ); +} diff --git a/src/advanced/components/Cart/CartItem.tsx b/src/advanced/components/Cart/CartItem.tsx new file mode 100644 index 00000000..dd034e07 --- /dev/null +++ b/src/advanced/components/Cart/CartItem.tsx @@ -0,0 +1,43 @@ +import { Product } from "../../types/cart"; + +interface CartItemProps { + product: Product; + quantity: number; + onQuantityChange: (change: number) => void; + onRemove: () => void; +} + +export function CartItem({ + product, + quantity, + onQuantityChange, + onRemove, +}: CartItemProps) { + return ( +
+ + {product.name} - {product.val}원 x {quantity} + +
+ + + +
+
+ ); +} diff --git a/src/advanced/components/Cart/CartList.tsx b/src/advanced/components/Cart/CartList.tsx new file mode 100644 index 00000000..08cdb89a --- /dev/null +++ b/src/advanced/components/Cart/CartList.tsx @@ -0,0 +1,37 @@ +import { Product, CartItem as CartItemType } from "../../types/cart"; +import { CartItem } from "./CartItem"; + +interface CartListProps { + items: CartItemType[]; + products: Product[]; + onQuantityChange: (productId: string, change: number) => void; + onRemove: (productId: string) => void; +} + +export function CartList({ + items, + products, + onQuantityChange, + onRemove, +}: CartListProps) { + return ( +
+ {items.map((item) => { + const product = products.find((p) => p.id === item.productId); + if (!product) return null; + + return ( + + onQuantityChange(item.productId, change) + } + onRemove={() => onRemove(item.productId)} + /> + ); + })} +
+ ); +} diff --git a/src/advanced/components/Cart/CartTotal.tsx b/src/advanced/components/Cart/CartTotal.tsx new file mode 100644 index 00000000..5921fac5 --- /dev/null +++ b/src/advanced/components/Cart/CartTotal.tsx @@ -0,0 +1,20 @@ +interface CartTotalProps { + total: number; + discountRate: number; +} + +export function CartTotal({ total, discountRate }: CartTotalProps) { + return ( +
+ 총액: {Math.round(total)}원 + {discountRate > 0 && ( + + ({(discountRate * 100).toFixed(1)}% 할인 적용) + + )} + + (포인트: {Math.floor(total / 1000)}) + +
+ ); +} diff --git a/src/advanced/components/Product/ProductSelect.tsx b/src/advanced/components/Product/ProductSelect.tsx new file mode 100644 index 00000000..3431fc14 --- /dev/null +++ b/src/advanced/components/Product/ProductSelect.tsx @@ -0,0 +1,22 @@ +import { Product } from "../../types/cart"; + +interface ProductSelectProps { + products: Product[]; + onSelect: (productId: string) => void; +} + +export function ProductSelect({ products, onSelect }: ProductSelectProps) { + return ( + + ); +} diff --git a/src/advanced/components/Product/StockInfo.tsx b/src/advanced/components/Product/StockInfo.tsx new file mode 100644 index 00000000..5337d1a9 --- /dev/null +++ b/src/advanced/components/Product/StockInfo.tsx @@ -0,0 +1,19 @@ +import { Product } from "../../types/cart"; + +interface StockInfoProps { + products: Product[]; +} + +export function StockInfo({ products }: StockInfoProps) { + const lowStockProducts = products.filter((item) => item.q < 5); + + return ( +
+ {lowStockProducts.map((item) => ( +
+ {item.name}: {item.q > 0 ? `재고 부족 (${item.q}개 남음)` : "품절"} +
+ ))} +
+ ); +} diff --git a/src/advanced/constants/products.ts b/src/advanced/constants/products.ts new file mode 100644 index 00000000..dd4db205 --- /dev/null +++ b/src/advanced/constants/products.ts @@ -0,0 +1,17 @@ +import { Product } from "../types/cart"; + +export const PRODUCTS: Product[] = [ + { id: "p1", name: "상품1", val: 10000, q: 50 }, + { id: "p2", name: "상품2", val: 20000, q: 30 }, + { id: "p3", name: "상품3", val: 30000, q: 20 }, + { id: "p4", name: "상품4", val: 15000, q: 0 }, + { id: "p5", name: "상품5", val: 25000, q: 10 }, +]; + +export const INDIVIDUAL_DISCOUNTS: Record = { + p1: 0.1, // 10% 할인 + p2: 0.15, + p3: 0.2, + p4: 0.05, + p5: 0.25, +}; diff --git a/src/advanced/hooks/useCart.ts b/src/advanced/hooks/useCart.ts new file mode 100644 index 00000000..0622bc7d --- /dev/null +++ b/src/advanced/hooks/useCart.ts @@ -0,0 +1,81 @@ +import { useState, useCallback } from "react"; +import { Product, CartItem } from "../types/cart"; +import { PRODUCTS } from "../constants/products"; +import { calculateCartTotal } from "../utils/calculate"; + +export function useCart() { + const [products, setProducts] = useState([...PRODUCTS]); + const [cartItems, setCartItems] = useState([]); + + const addToCart = useCallback( + (productId: string) => { + const product = products.find((p) => p.id === productId); + if (!product || product.q <= 0) { + alert("재고가 부족합니다."); + return; + } + + setCartItems((prev) => { + const existingItem = prev.find((item) => item.productId === productId); + if (existingItem) { + return prev.map((item) => + item.productId === productId + ? { ...item, quantity: item.quantity + 1 } + : item, + ); + } + return [...prev, { productId, quantity: 1 }]; + }); + + setProducts((prev) => + prev.map((p) => (p.id === productId ? { ...p, q: p.q - 1 } : p)), + ); + }, + [products], + ); + + const updateQuantity = useCallback( + (productId: string, change: number) => { + const product = products.find((p) => p.id === productId); + if (!product) return; + + if (change > 0 && product.q <= 0) { + alert("재고가 부족합니다."); + return; + } + + setCartItems((prev) => { + const existingItem = prev.find((item) => item.productId === productId); + if (!existingItem) return prev; + + const newQuantity = existingItem.quantity + change; + if (newQuantity <= 0) { + return prev.filter((item) => item.productId !== productId); + } + + return prev.map((item) => + item.productId === productId + ? { ...item, quantity: newQuantity } + : item, + ); + }); + + setProducts((prev) => + prev.map((p) => (p.id === productId ? { ...p, q: p.q - change } : p)), + ); + }, + [products], + ); + + const getTotal = useCallback(() => { + return calculateCartTotal(cartItems, products); + }, [cartItems, products]); + + return { + products, + cartItems, + addToCart, + updateQuantity, + getTotal, + }; +} diff --git a/src/advanced/main.advanced.js b/src/advanced/main.advanced.js deleted file mode 100644 index e69de29b..00000000 diff --git a/src/advanced/main.advanced.tsx b/src/advanced/main.advanced.tsx new file mode 100644 index 00000000..c5f53e4f --- /dev/null +++ b/src/advanced/main.advanced.tsx @@ -0,0 +1,13 @@ +import React from "react"; +import ReactDOM from "react-dom/client"; +import { App } from "./components/App"; + +const rootElement = document.getElementById("app"); +if (!rootElement) throw new Error("Failed to find the root element"); + +const root = ReactDOM.createRoot(rootElement); +root.render( + + + , +); diff --git a/src/advanced/types/cart.ts b/src/advanced/types/cart.ts new file mode 100644 index 00000000..4fafce75 --- /dev/null +++ b/src/advanced/types/cart.ts @@ -0,0 +1,17 @@ +export interface Product { + id: string; + name: string; + val: number; + q: number; +} + +export interface CartItem { + productId: string; + quantity: number; +} + +export interface DiscountResult { + total: number; + discountRate: number; + items: Map; +} diff --git a/src/advanced/utils/calculate.ts b/src/advanced/utils/calculate.ts new file mode 100644 index 00000000..c346c768 --- /dev/null +++ b/src/advanced/utils/calculate.ts @@ -0,0 +1,93 @@ +import { Product, CartItem, DiscountResult } from "../types/cart"; +import { INDIVIDUAL_DISCOUNTS } from "../constants/products"; + +interface CalculationState { + subTotal: number; + totalAmt: number; + itemCount: number; + items: Map; +} + +function getIndividualDiscountRate( + productId: string, + quantity: number, +): number { + return quantity >= 10 ? (INDIVIDUAL_DISCOUNTS[productId] ?? 0) : 0; +} + +export function calculateCartTotal( + cartItems: CartItem[], + products: Product[], +): DiscountResult { + // 초기값 설정 + const initial: CalculationState = { + subTotal: 0, + totalAmt: 0, + itemCount: 0, + items: new Map(), + }; + + // 각 아이템별 계산 + const calculated = cartItems.reduce((acc, item) => { + const product = products.find((p) => p.id === item.productId); + if (!product) return acc; + + const itemTotal = product.val * item.quantity; + const discRate = getIndividualDiscountRate(item.productId, item.quantity); + const discountedItemTotal = itemTotal * (1 - discRate); + + const newItems = new Map(acc.items); + newItems.set(item.productId, { quantity: item.quantity, product }); + + return { + ...acc, + items: newItems, + subTotal: acc.subTotal + itemTotal, + totalAmt: acc.totalAmt + discountedItemTotal, + itemCount: acc.itemCount + item.quantity, + }; + }, initial); + + // 대량 구매 할인 적용 + const bulkDiscounted = applyBulkDiscount(calculated); + + // 화요일 할인 적용 + return applyTuesdayDiscount(bulkDiscounted); +} + +function applyBulkDiscount(data: CalculationState): DiscountResult { + if (data.itemCount < 30) { + const existedRate = + data.subTotal === 0 ? 0 : (data.subTotal - data.totalAmt) / data.subTotal; + return { + total: data.totalAmt, + discountRate: existedRate, + items: data.items, + }; + } + + const bulkDiscountAmount = data.subTotal * 0.25; + const individualDiscountAmount = data.subTotal - data.totalAmt; + + if (bulkDiscountAmount > individualDiscountAmount) { + return { + total: data.subTotal * 0.75, + discountRate: 0.25, + items: data.items, + }; + } + + const existedRate = (data.subTotal - data.totalAmt) / data.subTotal; + return { total: data.totalAmt, discountRate: existedRate, items: data.items }; +} + +function applyTuesdayDiscount(data: DiscountResult): DiscountResult { + if (new Date().getDay() !== 2) { + return data; + } + return { + total: data.total * 0.9, + discountRate: Math.max(data.discountRate, 0.1), + items: data.items, + }; +} diff --git a/tailwind.config.js b/tailwind.config.js new file mode 100644 index 00000000..c189a4a5 --- /dev/null +++ b/tailwind.config.js @@ -0,0 +1,9 @@ +/** @type {import('tailwindcss').Config} */ +export default { + content: [], + theme: { + extend: {}, + }, + plugins: [], +} + diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 00000000..c9dc72c4 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,28 @@ +{ + "compilerOptions": { + "target": "ES2020", + "useDefineForClassFields": true, + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "module": "ESNext", + "skipLibCheck": true, + + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "react-jsx", + + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true, + + "baseUrl": ".", + "paths": { + "@/*": ["./src/*"] + } + }, + "include": ["src"], + "references": [{ "path": "./tsconfig.node.json" }] +} diff --git a/tsconfig.node.json b/tsconfig.node.json new file mode 100644 index 00000000..42872c59 --- /dev/null +++ b/tsconfig.node.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "composite": true, + "skipLibCheck": true, + "module": "ESNext", + "moduleResolution": "bundler", + "allowSyntheticDefaultImports": true + }, + "include": ["vite.config.ts"] +} diff --git a/vite.config.js b/vite.config.js deleted file mode 100644 index 19977832..00000000 --- a/vite.config.js +++ /dev/null @@ -1,9 +0,0 @@ -import { defineConfig } from 'vitest/config'; - -export default defineConfig({ - test: { - globals: true, - environment: 'jsdom', - setupFiles: './src/setupTests.js' - }, -}) diff --git a/vite.config.ts b/vite.config.ts new file mode 100644 index 00000000..081c8d9f --- /dev/null +++ b/vite.config.ts @@ -0,0 +1,6 @@ +import { defineConfig } from "vite"; +import react from "@vitejs/plugin-react"; + +export default defineConfig({ + plugins: [react()], +}); From 8d1d488e588162fb194b5e6eb63a0f6a33e13f5a Mon Sep 17 00:00:00 2001 From: anne-hyeyeon Date: Fri, 10 Jan 2025 00:01:16 +0900 Subject: [PATCH 6/8] =?UTF-8?q?fix:=20test=20=EA=B4=80=EB=A0=A8=20vite=20?= =?UTF-8?q?=ED=99=98=EA=B2=BD=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- vite.config.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/vite.config.ts b/vite.config.ts index 081c8d9f..ed6088b3 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,6 +1,10 @@ -import { defineConfig } from "vite"; +import { defineConfig } from "vitest/config"; import react from "@vitejs/plugin-react"; export default defineConfig({ plugins: [react()], + test: { + environment: "jsdom", + globals: true, + }, }); From 2860425d14cb88bd2e97a9b037a41cce2997e779 Mon Sep 17 00:00:00 2001 From: anne-hyeyeon Date: Fri, 10 Jan 2025 00:11:09 +0900 Subject: [PATCH 7/8] =?UTF-8?q?refactor:=20=EB=B2=A0=EC=9D=B4=EC=A7=81=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EB=A6=AC=ED=8C=A9=ED=86=A0=EB=A7=81=20(?= =?UTF-8?q?=EB=A9=98=ED=86=A0=EB=A7=81=20=ED=9B=84)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/basic/main.basic.js | 283 +++++++++++++++++++++++----------------- 1 file changed, 163 insertions(+), 120 deletions(-) diff --git a/src/basic/main.basic.js b/src/basic/main.basic.js index c1929bcc..9082486a 100644 --- a/src/basic/main.basic.js +++ b/src/basic/main.basic.js @@ -1,20 +1,42 @@ /* 데이터 정의 */ const PRODUCTS = [ - { id: "p1", name: "상품1", val: 10000, q: 50 }, - { id: "p2", name: "상품2", val: 20000, q: 30 }, - { id: "p3", name: "상품3", val: 30000, q: 20 }, - { id: "p4", name: "상품4", val: 15000, q: 0 }, - { id: "p5", name: "상품5", val: 25000, q: 10 }, + { + id: "p1", + name: "상품1", + val: 10000, + q: 50, + discountRate: 0.1, + }, + { + id: "p2", + name: "상품2", + val: 20000, + q: 30, + discountRate: 0.15, + }, + { + id: "p3", + name: "상품3", + val: 30000, + q: 20, + discountRate: 0.2, + }, + { + id: "p4", + name: "상품4", + val: 15000, + q: 0, + discountRate: 0.05, + }, + { + id: "p5", + name: "상품5", + val: 25000, + q: 10, + discountRate: 0.25, + }, ]; -const INDIVIDUAL_DISCOUNTS = { - p1: 0.1, - p2: 0.15, - p3: 0.2, - p4: 0.05, - p5: 0.25, -}; - /* 상태 관리 */ function createStore(initialState) { const state = { ...initialState }; @@ -26,20 +48,14 @@ function createStore(initialState) { Object.assign(state, newState); listeners.forEach((listener) => listener(state)); }, - subscribe: (listener) => { - listeners.add(listener); - return () => listeners.delete(listener); - }, }; } /* 할인 계산 로직 */ -// 10개 이상 구매 시 상품별 할인율 반환 -function getIndividualDiscountRate(productId, quantity) { - return quantity >= 10 ? (INDIVIDUAL_DISCOUNTS[productId] ?? 0) : 0; +function getIndividualDiscountRate(product, quantity) { + return quantity >= 10 ? (product.discountRate ?? 0) : 0; } -// reduce 콜백: 상품별 합계 및 할인 계산 function accumulateItem(acc, itemElem, products) { const productId = itemElem.id; const quantity = parseInt( @@ -49,7 +65,7 @@ function accumulateItem(acc, itemElem, products) { const product = products.find((p) => p.id === productId); const itemTotal = product.val * quantity; - const discRate = getIndividualDiscountRate(productId, quantity); + const discRate = getIndividualDiscountRate(product, quantity); const discountedItemTotal = itemTotal * (1 - discRate); const newItems = new Map(acc.items); @@ -64,7 +80,6 @@ function accumulateItem(acc, itemElem, products) { }; } -// 대량 구매 할인 적용 function applyBulkDiscount({ subTotal, totalAmt, itemCount, items }) { if (itemCount < 30) { const existedRate = subTotal === 0 ? 0 : (subTotal - totalAmt) / subTotal; @@ -74,7 +89,8 @@ function applyBulkDiscount({ subTotal, totalAmt, itemCount, items }) { const bulkDiscountAmount = subTotal * 0.25; const individualDiscountAmount = subTotal - totalAmt; - if (bulkDiscountAmount > individualDiscountAmount) { + const shouldApplyBulkDiscount = bulkDiscountAmount > individualDiscountAmount; + if (shouldApplyBulkDiscount) { return { total: subTotal * 0.75, discountRate: 0.25, items }; } @@ -82,7 +98,6 @@ function applyBulkDiscount({ subTotal, totalAmt, itemCount, items }) { return { total: totalAmt, discountRate: existedRate, items }; } -// 화요일 할인 적용 function applyTuesdayDiscount({ currentTotal, currentRate, items }) { if (new Date().getDay() !== 2) { return { total: currentTotal, discountRate: currentRate, items }; @@ -94,11 +109,11 @@ function applyTuesdayDiscount({ currentTotal, currentRate, items }) { }; } -// 장바구니 계산 function calculateCart(cartItems, products) { + const initial = { subTotal: 0, totalAmt: 0, itemCount: 0, items: new Map() }; const { subTotal, totalAmt, itemCount, items } = cartItems.reduce( (acc, itemElem) => accumulateItem(acc, itemElem, products), - { subTotal: 0, totalAmt: 0, itemCount: 0, items: new Map() }, + initial, ); const afterBulk = applyBulkDiscount({ subTotal, totalAmt, itemCount, items }); @@ -117,7 +132,6 @@ function calculateCart(cartItems, products) { } /* UI 관련 함수 */ -// UI 요소 생성 function createUIElement(tag, { id, className, textContent } = {}) { const element = document.createElement(tag); if (id) element.id = id; @@ -126,19 +140,17 @@ function createUIElement(tag, { id, className, textContent } = {}) { return element; } -// 상품 옵션 렌더링 function renderProductOptions(select, products) { select.innerHTML = ""; - products.forEach((item) => { + products.forEach((product) => { const option = createUIElement("option"); - option.value = item.id; - option.textContent = `${item.name} - ${item.val}원`; - option.disabled = item.q === 0; + option.value = product.id; + option.textContent = `${product.name} - ${product.val}원`; + option.disabled = product.q === 0; select.appendChild(option); }); } -// 총액 렌더링 function renderTotal(total, totalEl, discountRate = 0) { totalEl.innerHTML = `총액: ${Math.round(total)}원`; @@ -161,18 +173,16 @@ function renderTotal(total, totalEl, discountRate = 0) { pointsEl.textContent = `(포인트: ${Math.floor(total / 1000)})`; } -// 재고 정보 렌더링 function renderStockInfo(stockEl, products) { - const lowStockProducts = products.filter((item) => item.q < 5); + const lowStockProducts = products.filter((product) => product.q < 5); stockEl.textContent = lowStockProducts .map( - (item) => - `${item.name}: ${item.q > 0 ? `재고 부족 (${item.q}개 남음)` : "품절"}`, + (product) => + `${product.name}: ${product.q > 0 ? `재고 부족 (${product.q}개 남음)` : "품절"}`, ) .join("\n"); } -// 장바구니 항목 생성 function createCartItem(product) { const item = createUIElement("div", { id: product.id, @@ -180,19 +190,19 @@ function createCartItem(product) { }); item.innerHTML = ` - ${product.name} - ${product.val}원 x 1 -
- - - -
- `; + ${product.name} - ${product.val}원 x 1 +
+ + + +
+ `; return item; } -/* UI 요소 생성 */ + function createUIElements() { return { container: createUIElement("div", { className: "bg-gray-100 p-8" }), @@ -225,7 +235,6 @@ function createUIElements() { }; } -/* UI 요소 DOM에 추가 */ function appendUIElements(root, elements) { elements.wrapper.append( elements.title, @@ -239,56 +248,114 @@ function appendUIElements(root, elements) { root.appendChild(elements.container); } -/* [장바구니에 추가] 버튼 이벤트 */ +/* 장바구니 관련 헬퍼 함수들 */ +function validateStock(product) { + if (!product || product.q <= 0) { + alert("재고가 부족합니다."); + return false; + } + return true; +} + +function getItemQuantity(itemElement) { + return parseInt(itemElement.querySelector("span").textContent.split("x ")[1]); +} + +function updateItemQuantity(itemElement, product, newQty) { + itemElement.querySelector("span").textContent = + `${product.name} - ${product.val}원 x ${newQty}`; +} + +function updateProductStock(store, productId, quantityChange) { + const state = store.getState(); + store.update({ + products: state.products.map((p) => + p.id === productId ? { ...p, q: p.q - quantityChange } : p, + ), + }); +} + +/* 장바구니 화면 업데이트 */ +function updateCartDisplay(elements, store) { + const cartResult = calculateCart( + Array.from(elements.cartDisplay.children), + store.getState().products, + ); + renderTotal(cartResult.total, elements.total, cartResult.discountRate); + renderStockInfo(elements.stockInfo, store.getState().products); +} + +function handleRemove(itemElement, productId, store) { + const quantity = getItemQuantity(itemElement); + itemElement.remove(); + + const state = store.getState(); + store.update({ + products: state.products.map((p) => + p.id === productId ? { ...p, q: p.q + quantity } : p, + ), + }); +} + +function handleQuantityChange(itemElement, product, change, store) { + if (change > 0 && product.q <= 0) { + alert("재고가 부족합니다."); + return; + } + + const currentQty = getItemQuantity(itemElement); + const newQty = currentQty + change; + + if (newQty <= 0) { + handleRemove(itemElement, product.id, store); + return; + } + + updateItemQuantity(itemElement, product, newQty); + const state = store.getState(); + store.update({ + products: state.products.map((p) => + p.id === product.id ? { ...p, q: p.q - change } : p, + ), + }); +} + +/* 이벤트 핸들러 설정 */ function setupAddButtonEvent(elements, store) { elements.addButton.addEventListener("click", () => { const state = store.getState(); const selectedId = elements.productSelect.value; const product = state.products.find((p) => p.id === selectedId); - if (!product || product.q <= 0) { - alert("재고가 부족합니다."); - return; - } + if (!validateStock(product)) return; const existingItem = document.getElementById(selectedId); if (existingItem) { - const currentQty = parseInt( - existingItem.querySelector("span").textContent.split("x ")[1], - ); + const currentQty = getItemQuantity(existingItem); const newQty = currentQty + 1; - if (newQty <= product.q + currentQty) { - existingItem.querySelector("span").textContent = - `${product.name} - ${product.val}원 x ${newQty}`; - - store.update({ - products: state.products.map((p) => - p.id === selectedId ? { ...p, q: p.q - 1 } : p, - ), - }); - } else { + if (newQty > product.q + currentQty) { alert("재고가 부족합니다."); + return; } + + updateItemQuantity(existingItem, product, newQty); + updateProductStock(store, product.id, 1); } else { elements.cartDisplay.appendChild(createCartItem(product)); - store.update({ - products: state.products.map((p) => - p.id === selectedId ? { ...p, q: p.q - 1 } : p, - ), - }); + updateProductStock(store, product.id, 1); } - const cartResult = calculateCart( - Array.from(elements.cartDisplay.children), - store.getState().products, - ); - renderTotal(cartResult.total, elements.total, cartResult.discountRate); - renderStockInfo(elements.stockInfo, store.getState().products); + updateCartDisplay(elements, store); }); } -/* 장바구니 내 버튼들(+/-/삭제) 이벤트 */ +function getButtonType(button) { + if (button.classList.contains("remove-item")) return "remove"; + if (button.classList.contains("quantity-change")) return "change"; + return null; +} + function setupCartButtonEvents(elements, store) { elements.cartDisplay.addEventListener("click", (event) => { const button = event.target; @@ -299,47 +366,24 @@ function setupCartButtonEvents(elements, store) { const itemElement = document.getElementById(productId); const product = state.products.find((p) => p.id === productId); - if (button.classList.contains("remove-item")) { - const quantity = parseInt( - itemElement.querySelector("span").textContent.split("x ")[1], - ); - itemElement.remove(); - store.update({ - products: state.products.map((p) => - p.id === productId ? { ...p, q: p.q + quantity } : p, - ), - }); - } else if (button.classList.contains("quantity-change")) { - const change = parseInt(button.dataset.change); - const currentQty = parseInt( - itemElement.querySelector("span").textContent.split("x ")[1], - ); - const newQty = currentQty + change; - - if (change > 0 && product.q <= 0) { - alert("재고가 부족합니다."); + const buttonType = getButtonType(button); + switch (buttonType) { + case "remove": + handleRemove(itemElement, productId, store); + break; + case "change": + handleQuantityChange( + itemElement, + product, + parseInt(button.dataset.change), + store, + ); + break; + default: return; - } - if (newQty <= 0) { - itemElement.remove(); - } else { - itemElement.querySelector("span").textContent = - `${product.name} - ${product.val}원 x ${newQty}`; - } - - store.update({ - products: state.products.map((p) => - p.id === productId ? { ...p, q: p.q - change } : p, - ), - }); } - const cartResult = calculateCart( - Array.from(elements.cartDisplay.children), - store.getState().products, - ); - renderTotal(cartResult.total, elements.total, cartResult.discountRate); - renderStockInfo(elements.stockInfo, store.getState().products); + updateCartDisplay(elements, store); }); } @@ -347,7 +391,6 @@ function setupCartButtonEvents(elements, store) { function initializeApp() { const store = createStore({ products: [...PRODUCTS], - lastSelected: null, }); const root = document.getElementById("app"); From 6f1672bc81c96eeccd65f4528b8231f4186f44dc Mon Sep 17 00:00:00 2001 From: anne-hyeyeon Date: Fri, 10 Jan 2025 00:43:54 +0900 Subject: [PATCH 8/8] =?UTF-8?q?fix:=20=EB=A6=B0=ED=8A=B8=20=EB=B2=84?= =?UTF-8?q?=EC=A0=84=20=EB=8B=A4=EC=9A=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 +- pnpm-lock.yaml | 399 +++++++++++++++++++++++++++---------------------- 2 files changed, 222 insertions(+), 179 deletions(-) diff --git a/package.json b/package.json index 91562d23..aa41e22b 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ "@vitejs/plugin-react": "^4.3.4", "@vitest/ui": "^2.1.1", "autoprefixer": "^10.4.20", - "eslint": "^9.17.0", + "eslint": "^8.2.0", "eslint-config-airbnb": "^19.0.4", "eslint-config-airbnb-typescript": "^18.0.0", "eslint-config-prettier": "^9.1.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5e128dcf..4c7e89f2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -38,10 +38,10 @@ importers: version: 19.0.2(@types/react@19.0.4) '@typescript-eslint/eslint-plugin': specifier: ^8.19.1 - version: 8.19.1(@typescript-eslint/parser@8.19.1(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3))(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3) + version: 8.19.1(@typescript-eslint/parser@8.19.1(eslint@8.57.1)(typescript@5.7.3))(eslint@8.57.1)(typescript@5.7.3) '@typescript-eslint/parser': specifier: ^8.19.1 - version: 8.19.1(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3) + version: 8.19.1(eslint@8.57.1)(typescript@5.7.3) '@vitejs/plugin-react': specifier: ^4.3.4 version: 4.3.4(vite@5.4.11(@types/node@22.10.5)) @@ -52,32 +52,32 @@ importers: specifier: ^10.4.20 version: 10.4.20(postcss@8.4.49) eslint: - specifier: ^9.17.0 - version: 9.17.0(jiti@1.21.7) + specifier: ^8.2.0 + version: 8.57.1 eslint-config-airbnb: specifier: ^19.0.4 - version: 19.0.4(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.19.1(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3))(eslint@9.17.0(jiti@1.21.7)))(eslint-plugin-jsx-a11y@6.10.2(eslint@9.17.0(jiti@1.21.7)))(eslint-plugin-react-hooks@5.1.0(eslint@9.17.0(jiti@1.21.7)))(eslint-plugin-react@7.37.3(eslint@9.17.0(jiti@1.21.7)))(eslint@9.17.0(jiti@1.21.7)) + version: 19.0.4(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.19.1(eslint@8.57.1)(typescript@5.7.3))(eslint@8.57.1))(eslint-plugin-jsx-a11y@6.10.2(eslint@8.57.1))(eslint-plugin-react-hooks@5.1.0(eslint@8.57.1))(eslint-plugin-react@7.37.3(eslint@8.57.1))(eslint@8.57.1) eslint-config-airbnb-typescript: specifier: ^18.0.0 - version: 18.0.0(@typescript-eslint/eslint-plugin@8.19.1(@typescript-eslint/parser@8.19.1(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3))(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3))(@typescript-eslint/parser@8.19.1(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3))(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.19.1(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3))(eslint@9.17.0(jiti@1.21.7)))(eslint@9.17.0(jiti@1.21.7)) + version: 18.0.0(@typescript-eslint/eslint-plugin@8.19.1(@typescript-eslint/parser@8.19.1(eslint@8.57.1)(typescript@5.7.3))(eslint@8.57.1)(typescript@5.7.3))(@typescript-eslint/parser@8.19.1(eslint@8.57.1)(typescript@5.7.3))(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.19.1(eslint@8.57.1)(typescript@5.7.3))(eslint@8.57.1))(eslint@8.57.1) eslint-config-prettier: specifier: ^9.1.0 - version: 9.1.0(eslint@9.17.0(jiti@1.21.7)) + version: 9.1.0(eslint@8.57.1) eslint-plugin-import: specifier: ^2.31.0 - version: 2.31.0(@typescript-eslint/parser@8.19.1(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3))(eslint@9.17.0(jiti@1.21.7)) + version: 2.31.0(@typescript-eslint/parser@8.19.1(eslint@8.57.1)(typescript@5.7.3))(eslint@8.57.1) eslint-plugin-jsx-a11y: specifier: ^6.10.2 - version: 6.10.2(eslint@9.17.0(jiti@1.21.7)) + version: 6.10.2(eslint@8.57.1) eslint-plugin-prettier: specifier: ^5.2.1 - version: 5.2.1(eslint-config-prettier@9.1.0(eslint@9.17.0(jiti@1.21.7)))(eslint@9.17.0(jiti@1.21.7))(prettier@3.4.2) + version: 5.2.1(eslint-config-prettier@9.1.0(eslint@8.57.1))(eslint@8.57.1)(prettier@3.4.2) eslint-plugin-react: specifier: ^7.37.3 - version: 7.37.3(eslint@9.17.0(jiti@1.21.7)) + version: 7.37.3(eslint@8.57.1) eslint-plugin-react-hooks: specifier: ^5.1.0 - version: 5.1.0(eslint@9.17.0(jiti@1.21.7)) + version: 5.1.0(eslint@8.57.1) jsdom: specifier: ^25.0.0 version: 25.0.1 @@ -344,49 +344,26 @@ packages: resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - '@eslint/config-array@0.19.1': - resolution: {integrity: sha512-fo6Mtm5mWyKjA/Chy1BYTdn5mGJoDNjC7C64ug20ADsRDGrA85bN3uK3MaKbeRkRuuIEAR5N33Jr1pbm411/PA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/core@0.9.1': - resolution: {integrity: sha512-GuUdqkyyzQI5RMIWkHhvTWLCyLo1jNK3vzkSyaExH5kHPDHcuL2VOpHjmMY+y3+NC69qAKToBqldTBgYeLSr9Q==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/eslintrc@3.2.0': - resolution: {integrity: sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/js@9.17.0': - resolution: {integrity: sha512-Sxc4hqcs1kTu0iID3kcZDW3JHq2a77HO9P8CP6YEA/FpH3Ll8UXE2r/86Rz9YJLKme39S9vU5OWNjC6Xl0Cr3w==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/object-schema@2.1.5': - resolution: {integrity: sha512-o0bhxnL89h5Bae5T318nFoFzGy+YE5i/gGkoPAgkmTVdRKTiv3p8JHevPiPaMwoloKfEiiaHlawCqaZMqRm+XQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/plugin-kit@0.2.4': - resolution: {integrity: sha512-zSkKow6H5Kdm0ZUQUB2kV5JIXqoG0+uH5YADhaEHswm664N9Db8dXSi0nMJpacpMf+MyyglF1vnZohpEg5yUtg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/eslintrc@2.1.4': + resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - '@humanfs/core@0.19.1': - resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} - engines: {node: '>=18.18.0'} + '@eslint/js@8.57.1': + resolution: {integrity: sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - '@humanfs/node@0.16.6': - resolution: {integrity: sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==} - engines: {node: '>=18.18.0'} + '@humanwhocodes/config-array@0.13.0': + resolution: {integrity: sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==} + engines: {node: '>=10.10.0'} + deprecated: Use @eslint/config-array instead '@humanwhocodes/module-importer@1.0.1': resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} engines: {node: '>=12.22'} - '@humanwhocodes/retry@0.3.1': - resolution: {integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==} - engines: {node: '>=18.18'} - - '@humanwhocodes/retry@0.4.1': - resolution: {integrity: sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==} - engines: {node: '>=18.18'} + '@humanwhocodes/object-schema@2.0.3': + resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} + deprecated: Use @eslint/object-schema instead '@isaacs/cliui@8.0.2': resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} @@ -563,9 +540,6 @@ packages: '@types/estree@1.0.6': resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} - '@types/json-schema@7.0.15': - resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - '@types/json5@0.0.29': resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} @@ -627,6 +601,9 @@ packages: resolution: {integrity: sha512-fzmjU8CHK853V/avYZAvuVut3ZTfwN5YtMaoi+X9Y9MA9keaWNHC3zEQ9zvyX/7Hj+5JkNyK1l7TOR2hevHB6Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@ungap/structured-clone@1.2.1': + resolution: {integrity: sha512-fEzPV3hSkSMltkw152tJKNARhOupqbH96MZWyRjNaYZOMIzbrTeQDG+MTc6Mr2pgzFQzFxAfmhGDNP5QK++2ZA==} + '@vitejs/plugin-react@4.3.4': resolution: {integrity: sha512-SCCPBJtYLdE8PX/7ZQAs1QAZ8Jqwih+0VBLum1EGqmCCQal+MIUqLCzj3ZUy8ufbC0cAM4LRlSTm7IQJwWT4ug==} engines: {node: ^14.18.0 || >=16.0.0} @@ -972,6 +949,10 @@ packages: resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} engines: {node: '>=0.10.0'} + doctrine@3.0.0: + resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} + engines: {node: '>=6.0.0'} + dom-accessibility-api@0.5.16: resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==} @@ -1141,9 +1122,9 @@ packages: peerDependencies: eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7 - eslint-scope@8.2.0: - resolution: {integrity: sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + eslint-scope@7.2.2: + resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} eslint-visitor-keys@3.4.3: resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} @@ -1153,19 +1134,15 @@ packages: resolution: {integrity: sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - eslint@9.17.0: - resolution: {integrity: sha512-evtlNcpJg+cZLcnVKwsai8fExnqjGPicK7gnUtlNuzu+Fv9bI0aLpND5T44VLQtoMEnI57LoXO9XAkIXwohKrA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + eslint@8.57.1: + resolution: {integrity: sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options. hasBin: true - peerDependencies: - jiti: '*' - peerDependenciesMeta: - jiti: - optional: true - espree@10.3.0: - resolution: {integrity: sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + espree@9.6.1: + resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} esquery@1.6.0: resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} @@ -1220,9 +1197,9 @@ packages: fflate@0.8.2: resolution: {integrity: sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==} - file-entry-cache@8.0.0: - resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} - engines: {node: '>=16.0.0'} + file-entry-cache@6.0.1: + resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} + engines: {node: ^10.12.0 || >=12.0.0} fill-range@7.1.1: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} @@ -1232,9 +1209,9 @@ packages: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} engines: {node: '>=10'} - flat-cache@4.0.1: - resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} - engines: {node: '>=16'} + flat-cache@3.2.0: + resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} + engines: {node: ^10.12.0 || >=12.0.0} flatted@3.3.2: resolution: {integrity: sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==} @@ -1253,6 +1230,9 @@ packages: fraction.js@4.3.7: resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} + fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} @@ -1296,13 +1276,17 @@ packages: resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} hasBin: true + glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Glob versions prior to v9 are no longer supported + globals@11.12.0: resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} engines: {node: '>=4'} - globals@14.0.0: - resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} - engines: {node: '>=18'} + globals@13.24.0: + resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==} + engines: {node: '>=8'} globalthis@1.0.4: resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} @@ -1374,6 +1358,13 @@ packages: resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} engines: {node: '>=8'} + inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + internal-slot@1.1.0: resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} engines: {node: '>= 0.4'} @@ -1446,6 +1437,10 @@ packages: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} + is-path-inside@3.0.3: + resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} + engines: {node: '>=8'} + is-potential-custom-element-name@1.0.1: resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} @@ -1702,6 +1697,9 @@ packages: resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==} engines: {node: '>= 0.4'} + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + optionator@0.9.4: resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} engines: {node: '>= 0.8.0'} @@ -1732,6 +1730,10 @@ packages: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} + path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + path-key@3.1.1: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} @@ -1904,6 +1906,11 @@ packages: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + rimraf@3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + deprecated: Rimraf versions prior to v4 are no longer supported + hasBin: true + rollup@4.30.1: resolution: {integrity: sha512-mlJ4glW020fPuLi7DkM/lN97mYEZGWeqBnrljzN0gs7GLctqX3lNWxKQ7Gl712UAX+6fog/L3jh4gb7R6aVi3w==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} @@ -2079,6 +2086,9 @@ packages: engines: {node: '>=14.0.0'} hasBin: true + text-table@0.2.0: + resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + thenify-all@1.6.0: resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} engines: {node: '>=0.8'} @@ -2150,6 +2160,10 @@ packages: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} + type-fest@0.20.2: + resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} + engines: {node: '>=10'} + typed-array-buffer@1.0.3: resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} engines: {node: '>= 0.4'} @@ -2309,6 +2323,9 @@ packages: resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} engines: {node: '>=12'} + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + ws@8.18.0: resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} engines: {node: '>=10.0.0'} @@ -2534,31 +2551,19 @@ snapshots: '@esbuild/win32-x64@0.21.5': optional: true - '@eslint-community/eslint-utils@4.4.1(eslint@9.17.0(jiti@1.21.7))': + '@eslint-community/eslint-utils@4.4.1(eslint@8.57.1)': dependencies: - eslint: 9.17.0(jiti@1.21.7) + eslint: 8.57.1 eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.1': {} - '@eslint/config-array@0.19.1': - dependencies: - '@eslint/object-schema': 2.1.5 - debug: 4.4.0 - minimatch: 3.1.2 - transitivePeerDependencies: - - supports-color - - '@eslint/core@0.9.1': - dependencies: - '@types/json-schema': 7.0.15 - - '@eslint/eslintrc@3.2.0': + '@eslint/eslintrc@2.1.4': dependencies: ajv: 6.12.6 debug: 4.4.0 - espree: 10.3.0 - globals: 14.0.0 + espree: 9.6.1 + globals: 13.24.0 ignore: 5.3.2 import-fresh: 3.3.0 js-yaml: 4.1.0 @@ -2567,26 +2572,19 @@ snapshots: transitivePeerDependencies: - supports-color - '@eslint/js@9.17.0': {} - - '@eslint/object-schema@2.1.5': {} + '@eslint/js@8.57.1': {} - '@eslint/plugin-kit@0.2.4': + '@humanwhocodes/config-array@0.13.0': dependencies: - levn: 0.4.1 - - '@humanfs/core@0.19.1': {} - - '@humanfs/node@0.16.6': - dependencies: - '@humanfs/core': 0.19.1 - '@humanwhocodes/retry': 0.3.1 + '@humanwhocodes/object-schema': 2.0.3 + debug: 4.4.0 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color '@humanwhocodes/module-importer@1.0.1': {} - '@humanwhocodes/retry@0.3.1': {} - - '@humanwhocodes/retry@0.4.1': {} + '@humanwhocodes/object-schema@2.0.3': {} '@isaacs/cliui@8.0.2': dependencies: @@ -2742,8 +2740,6 @@ snapshots: '@types/estree@1.0.6': {} - '@types/json-schema@7.0.15': {} - '@types/json5@0.0.29': {} '@types/node@22.10.5': @@ -2758,15 +2754,15 @@ snapshots: dependencies: csstype: 3.1.3 - '@typescript-eslint/eslint-plugin@8.19.1(@typescript-eslint/parser@8.19.1(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3))(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3)': + '@typescript-eslint/eslint-plugin@8.19.1(@typescript-eslint/parser@8.19.1(eslint@8.57.1)(typescript@5.7.3))(eslint@8.57.1)(typescript@5.7.3)': dependencies: '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.19.1(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3) + '@typescript-eslint/parser': 8.19.1(eslint@8.57.1)(typescript@5.7.3) '@typescript-eslint/scope-manager': 8.19.1 - '@typescript-eslint/type-utils': 8.19.1(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3) - '@typescript-eslint/utils': 8.19.1(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3) + '@typescript-eslint/type-utils': 8.19.1(eslint@8.57.1)(typescript@5.7.3) + '@typescript-eslint/utils': 8.19.1(eslint@8.57.1)(typescript@5.7.3) '@typescript-eslint/visitor-keys': 8.19.1 - eslint: 9.17.0(jiti@1.21.7) + eslint: 8.57.1 graphemer: 1.4.0 ignore: 5.3.2 natural-compare: 1.4.0 @@ -2775,14 +2771,14 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.19.1(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3)': + '@typescript-eslint/parser@8.19.1(eslint@8.57.1)(typescript@5.7.3)': dependencies: '@typescript-eslint/scope-manager': 8.19.1 '@typescript-eslint/types': 8.19.1 '@typescript-eslint/typescript-estree': 8.19.1(typescript@5.7.3) '@typescript-eslint/visitor-keys': 8.19.1 debug: 4.4.0 - eslint: 9.17.0(jiti@1.21.7) + eslint: 8.57.1 typescript: 5.7.3 transitivePeerDependencies: - supports-color @@ -2792,12 +2788,12 @@ snapshots: '@typescript-eslint/types': 8.19.1 '@typescript-eslint/visitor-keys': 8.19.1 - '@typescript-eslint/type-utils@8.19.1(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3)': + '@typescript-eslint/type-utils@8.19.1(eslint@8.57.1)(typescript@5.7.3)': dependencies: '@typescript-eslint/typescript-estree': 8.19.1(typescript@5.7.3) - '@typescript-eslint/utils': 8.19.1(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3) + '@typescript-eslint/utils': 8.19.1(eslint@8.57.1)(typescript@5.7.3) debug: 4.4.0 - eslint: 9.17.0(jiti@1.21.7) + eslint: 8.57.1 ts-api-utils: 2.0.0(typescript@5.7.3) typescript: 5.7.3 transitivePeerDependencies: @@ -2819,13 +2815,13 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.19.1(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3)': + '@typescript-eslint/utils@8.19.1(eslint@8.57.1)(typescript@5.7.3)': dependencies: - '@eslint-community/eslint-utils': 4.4.1(eslint@9.17.0(jiti@1.21.7)) + '@eslint-community/eslint-utils': 4.4.1(eslint@8.57.1) '@typescript-eslint/scope-manager': 8.19.1 '@typescript-eslint/types': 8.19.1 '@typescript-eslint/typescript-estree': 8.19.1(typescript@5.7.3) - eslint: 9.17.0(jiti@1.21.7) + eslint: 8.57.1 typescript: 5.7.3 transitivePeerDependencies: - supports-color @@ -2835,6 +2831,8 @@ snapshots: '@typescript-eslint/types': 8.19.1 eslint-visitor-keys: 4.2.0 + '@ungap/structured-clone@1.2.1': {} + '@vitejs/plugin-react@4.3.4(vite@5.4.11(@types/node@22.10.5))': dependencies: '@babel/core': 7.26.0 @@ -3209,6 +3207,10 @@ snapshots: dependencies: esutils: 2.0.3 + doctrine@3.0.0: + dependencies: + esutils: 2.0.3 + dom-accessibility-api@0.5.16: {} dom-accessibility-api@0.6.3: {} @@ -3359,38 +3361,38 @@ snapshots: escape-string-regexp@4.0.0: {} - eslint-config-airbnb-base@15.0.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.19.1(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3))(eslint@9.17.0(jiti@1.21.7)))(eslint@9.17.0(jiti@1.21.7)): + eslint-config-airbnb-base@15.0.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.19.1(eslint@8.57.1)(typescript@5.7.3))(eslint@8.57.1))(eslint@8.57.1): dependencies: confusing-browser-globals: 1.0.11 - eslint: 9.17.0(jiti@1.21.7) - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.19.1(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3))(eslint@9.17.0(jiti@1.21.7)) + eslint: 8.57.1 + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.19.1(eslint@8.57.1)(typescript@5.7.3))(eslint@8.57.1) object.assign: 4.1.7 object.entries: 1.1.8 semver: 6.3.1 - eslint-config-airbnb-typescript@18.0.0(@typescript-eslint/eslint-plugin@8.19.1(@typescript-eslint/parser@8.19.1(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3))(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3))(@typescript-eslint/parser@8.19.1(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3))(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.19.1(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3))(eslint@9.17.0(jiti@1.21.7)))(eslint@9.17.0(jiti@1.21.7)): + eslint-config-airbnb-typescript@18.0.0(@typescript-eslint/eslint-plugin@8.19.1(@typescript-eslint/parser@8.19.1(eslint@8.57.1)(typescript@5.7.3))(eslint@8.57.1)(typescript@5.7.3))(@typescript-eslint/parser@8.19.1(eslint@8.57.1)(typescript@5.7.3))(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.19.1(eslint@8.57.1)(typescript@5.7.3))(eslint@8.57.1))(eslint@8.57.1): dependencies: - '@typescript-eslint/eslint-plugin': 8.19.1(@typescript-eslint/parser@8.19.1(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3))(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3) - '@typescript-eslint/parser': 8.19.1(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3) - eslint: 9.17.0(jiti@1.21.7) - eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.19.1(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3))(eslint@9.17.0(jiti@1.21.7)))(eslint@9.17.0(jiti@1.21.7)) + '@typescript-eslint/eslint-plugin': 8.19.1(@typescript-eslint/parser@8.19.1(eslint@8.57.1)(typescript@5.7.3))(eslint@8.57.1)(typescript@5.7.3) + '@typescript-eslint/parser': 8.19.1(eslint@8.57.1)(typescript@5.7.3) + eslint: 8.57.1 + eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.19.1(eslint@8.57.1)(typescript@5.7.3))(eslint@8.57.1))(eslint@8.57.1) transitivePeerDependencies: - eslint-plugin-import - eslint-config-airbnb@19.0.4(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.19.1(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3))(eslint@9.17.0(jiti@1.21.7)))(eslint-plugin-jsx-a11y@6.10.2(eslint@9.17.0(jiti@1.21.7)))(eslint-plugin-react-hooks@5.1.0(eslint@9.17.0(jiti@1.21.7)))(eslint-plugin-react@7.37.3(eslint@9.17.0(jiti@1.21.7)))(eslint@9.17.0(jiti@1.21.7)): + eslint-config-airbnb@19.0.4(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.19.1(eslint@8.57.1)(typescript@5.7.3))(eslint@8.57.1))(eslint-plugin-jsx-a11y@6.10.2(eslint@8.57.1))(eslint-plugin-react-hooks@5.1.0(eslint@8.57.1))(eslint-plugin-react@7.37.3(eslint@8.57.1))(eslint@8.57.1): dependencies: - eslint: 9.17.0(jiti@1.21.7) - eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.19.1(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3))(eslint@9.17.0(jiti@1.21.7)))(eslint@9.17.0(jiti@1.21.7)) - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.19.1(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3))(eslint@9.17.0(jiti@1.21.7)) - eslint-plugin-jsx-a11y: 6.10.2(eslint@9.17.0(jiti@1.21.7)) - eslint-plugin-react: 7.37.3(eslint@9.17.0(jiti@1.21.7)) - eslint-plugin-react-hooks: 5.1.0(eslint@9.17.0(jiti@1.21.7)) + eslint: 8.57.1 + eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.19.1(eslint@8.57.1)(typescript@5.7.3))(eslint@8.57.1))(eslint@8.57.1) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.19.1(eslint@8.57.1)(typescript@5.7.3))(eslint@8.57.1) + eslint-plugin-jsx-a11y: 6.10.2(eslint@8.57.1) + eslint-plugin-react: 7.37.3(eslint@8.57.1) + eslint-plugin-react-hooks: 5.1.0(eslint@8.57.1) object.assign: 4.1.7 object.entries: 1.1.8 - eslint-config-prettier@9.1.0(eslint@9.17.0(jiti@1.21.7)): + eslint-config-prettier@9.1.0(eslint@8.57.1): dependencies: - eslint: 9.17.0(jiti@1.21.7) + eslint: 8.57.1 eslint-import-resolver-node@0.3.9: dependencies: @@ -3400,17 +3402,17 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.0(@typescript-eslint/parser@8.19.1(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint@9.17.0(jiti@1.21.7)): + eslint-module-utils@2.12.0(@typescript-eslint/parser@8.19.1(eslint@8.57.1)(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint@8.57.1): dependencies: debug: 3.2.7 optionalDependencies: - '@typescript-eslint/parser': 8.19.1(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3) - eslint: 9.17.0(jiti@1.21.7) + '@typescript-eslint/parser': 8.19.1(eslint@8.57.1)(typescript@5.7.3) + eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 transitivePeerDependencies: - supports-color - eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.19.1(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3))(eslint@9.17.0(jiti@1.21.7)): + eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.19.1(eslint@8.57.1)(typescript@5.7.3))(eslint@8.57.1): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.8 @@ -3419,9 +3421,9 @@ snapshots: array.prototype.flatmap: 1.3.3 debug: 3.2.7 doctrine: 2.1.0 - eslint: 9.17.0(jiti@1.21.7) + eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.19.1(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint@9.17.0(jiti@1.21.7)) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.19.1(eslint@8.57.1)(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint@8.57.1) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -3433,13 +3435,13 @@ snapshots: string.prototype.trimend: 1.0.9 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 8.19.1(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.3) + '@typescript-eslint/parser': 8.19.1(eslint@8.57.1)(typescript@5.7.3) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack - supports-color - eslint-plugin-jsx-a11y@6.10.2(eslint@9.17.0(jiti@1.21.7)): + eslint-plugin-jsx-a11y@6.10.2(eslint@8.57.1): dependencies: aria-query: 5.3.2 array-includes: 3.1.8 @@ -3449,7 +3451,7 @@ snapshots: axobject-query: 4.1.0 damerau-levenshtein: 1.0.8 emoji-regex: 9.2.2 - eslint: 9.17.0(jiti@1.21.7) + eslint: 8.57.1 hasown: 2.0.2 jsx-ast-utils: 3.3.5 language-tags: 1.0.9 @@ -3458,20 +3460,20 @@ snapshots: safe-regex-test: 1.1.0 string.prototype.includes: 2.0.1 - eslint-plugin-prettier@5.2.1(eslint-config-prettier@9.1.0(eslint@9.17.0(jiti@1.21.7)))(eslint@9.17.0(jiti@1.21.7))(prettier@3.4.2): + eslint-plugin-prettier@5.2.1(eslint-config-prettier@9.1.0(eslint@8.57.1))(eslint@8.57.1)(prettier@3.4.2): dependencies: - eslint: 9.17.0(jiti@1.21.7) + eslint: 8.57.1 prettier: 3.4.2 prettier-linter-helpers: 1.0.0 synckit: 0.9.2 optionalDependencies: - eslint-config-prettier: 9.1.0(eslint@9.17.0(jiti@1.21.7)) + eslint-config-prettier: 9.1.0(eslint@8.57.1) - eslint-plugin-react-hooks@5.1.0(eslint@9.17.0(jiti@1.21.7)): + eslint-plugin-react-hooks@5.1.0(eslint@8.57.1): dependencies: - eslint: 9.17.0(jiti@1.21.7) + eslint: 8.57.1 - eslint-plugin-react@7.37.3(eslint@9.17.0(jiti@1.21.7)): + eslint-plugin-react@7.37.3(eslint@8.57.1): dependencies: array-includes: 3.1.8 array.prototype.findlast: 1.2.5 @@ -3479,7 +3481,7 @@ snapshots: array.prototype.tosorted: 1.1.4 doctrine: 2.1.0 es-iterator-helpers: 1.2.1 - eslint: 9.17.0(jiti@1.21.7) + eslint: 8.57.1 estraverse: 5.3.0 hasown: 2.0.2 jsx-ast-utils: 3.3.5 @@ -3493,7 +3495,7 @@ snapshots: string.prototype.matchall: 4.0.12 string.prototype.repeat: 1.0.0 - eslint-scope@8.2.0: + eslint-scope@7.2.2: dependencies: esrecurse: 4.3.0 estraverse: 5.3.0 @@ -3502,52 +3504,54 @@ snapshots: eslint-visitor-keys@4.2.0: {} - eslint@9.17.0(jiti@1.21.7): + eslint@8.57.1: dependencies: - '@eslint-community/eslint-utils': 4.4.1(eslint@9.17.0(jiti@1.21.7)) + '@eslint-community/eslint-utils': 4.4.1(eslint@8.57.1) '@eslint-community/regexpp': 4.12.1 - '@eslint/config-array': 0.19.1 - '@eslint/core': 0.9.1 - '@eslint/eslintrc': 3.2.0 - '@eslint/js': 9.17.0 - '@eslint/plugin-kit': 0.2.4 - '@humanfs/node': 0.16.6 + '@eslint/eslintrc': 2.1.4 + '@eslint/js': 8.57.1 + '@humanwhocodes/config-array': 0.13.0 '@humanwhocodes/module-importer': 1.0.1 - '@humanwhocodes/retry': 0.4.1 - '@types/estree': 1.0.6 - '@types/json-schema': 7.0.15 + '@nodelib/fs.walk': 1.2.8 + '@ungap/structured-clone': 1.2.1 ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.6 debug: 4.4.0 + doctrine: 3.0.0 escape-string-regexp: 4.0.0 - eslint-scope: 8.2.0 - eslint-visitor-keys: 4.2.0 - espree: 10.3.0 + eslint-scope: 7.2.2 + eslint-visitor-keys: 3.4.3 + espree: 9.6.1 esquery: 1.6.0 esutils: 2.0.3 fast-deep-equal: 3.1.3 - file-entry-cache: 8.0.0 + file-entry-cache: 6.0.1 find-up: 5.0.0 glob-parent: 6.0.2 + globals: 13.24.0 + graphemer: 1.4.0 ignore: 5.3.2 imurmurhash: 0.1.4 is-glob: 4.0.3 + is-path-inside: 3.0.3 + js-yaml: 4.1.0 json-stable-stringify-without-jsonify: 1.0.1 + levn: 0.4.1 lodash.merge: 4.6.2 minimatch: 3.1.2 natural-compare: 1.4.0 optionator: 0.9.4 - optionalDependencies: - jiti: 1.21.7 + strip-ansi: 6.0.1 + text-table: 0.2.0 transitivePeerDependencies: - supports-color - espree@10.3.0: + espree@9.6.1: dependencies: acorn: 8.14.0 acorn-jsx: 5.3.2(acorn@8.14.0) - eslint-visitor-keys: 4.2.0 + eslint-visitor-keys: 3.4.3 esquery@1.6.0: dependencies: @@ -3593,9 +3597,9 @@ snapshots: fflate@0.8.2: {} - file-entry-cache@8.0.0: + file-entry-cache@6.0.1: dependencies: - flat-cache: 4.0.1 + flat-cache: 3.2.0 fill-range@7.1.1: dependencies: @@ -3606,10 +3610,11 @@ snapshots: locate-path: 6.0.0 path-exists: 4.0.0 - flat-cache@4.0.1: + flat-cache@3.2.0: dependencies: flatted: 3.3.2 keyv: 4.5.4 + rimraf: 3.0.2 flatted@3.3.2: {} @@ -3630,6 +3635,8 @@ snapshots: fraction.js@4.3.7: {} + fs.realpath@1.0.0: {} + fsevents@2.3.3: optional: true @@ -3689,9 +3696,20 @@ snapshots: package-json-from-dist: 1.0.1 path-scurry: 1.11.1 + glob@7.2.3: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + globals@11.12.0: {} - globals@14.0.0: {} + globals@13.24.0: + dependencies: + type-fest: 0.20.2 globalthis@1.0.4: dependencies: @@ -3757,6 +3775,13 @@ snapshots: indent-string@4.0.0: {} + inflight@1.0.6: + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + + inherits@2.0.4: {} + internal-slot@1.1.0: dependencies: es-errors: 1.3.0 @@ -3834,6 +3859,8 @@ snapshots: is-number@7.0.0: {} + is-path-inside@3.0.3: {} + is-potential-custom-element-name@1.0.1: {} is-regex@1.2.1: @@ -4090,6 +4117,10 @@ snapshots: define-properties: 1.2.1 es-object-atoms: 1.0.0 + once@1.4.0: + dependencies: + wrappy: 1.0.2 + optionator@0.9.4: dependencies: deep-is: 0.1.4 @@ -4125,6 +4156,8 @@ snapshots: path-exists@4.0.0: {} + path-is-absolute@1.0.1: {} + path-key@3.1.1: {} path-parse@1.0.7: {} @@ -4277,6 +4310,10 @@ snapshots: reusify@1.0.4: {} + rimraf@3.0.2: + dependencies: + glob: 7.2.3 + rollup@4.30.1: dependencies: '@types/estree': 1.0.6 @@ -4539,6 +4576,8 @@ snapshots: transitivePeerDependencies: - ts-node + text-table@0.2.0: {} + thenify-all@1.6.0: dependencies: thenify: 3.3.1 @@ -4601,6 +4640,8 @@ snapshots: dependencies: prelude-ls: 1.2.1 + type-fest@0.20.2: {} + typed-array-buffer@1.0.3: dependencies: call-bound: 1.0.3 @@ -4801,6 +4842,8 @@ snapshots: string-width: 5.1.2 strip-ansi: 7.1.0 + wrappy@1.0.2: {} + ws@8.18.0: {} xml-name-validator@5.0.0: {}