diff --git a/04-poke-battle-with-prisma/.env.example b/04-poke-battle-with-prisma/.env.example new file mode 100644 index 0000000..f375c30 --- /dev/null +++ b/04-poke-battle-with-prisma/.env.example @@ -0,0 +1,11 @@ +# Application +ENVIRONMENT="Development" #Development, Staging, Production +PORT=3000 +JWT_KEY="Your jwt key" #Base64 + +# Data base +DATABASE_URL="Your connection string" #PostgreSQL + +# Log System +FILE=general #log file name +FOLDER=logs #log folder name \ No newline at end of file diff --git a/04-poke-battle-with-prisma/frontend/.eslintrc.json b/04-poke-battle-with-prisma/frontend/.eslintrc.json new file mode 100644 index 0000000..d9e26d9 --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/.eslintrc.json @@ -0,0 +1,22 @@ +{ + "extends": [ + "eslint:recommended", + "plugin:react/recommended", + "plugin:react-hooks/recommended" + ], + "plugins": ["react", "react-hooks"], + "parserOptions": { + "ecmaVersion": 2020, + "sourceType": "module", + "ecmaFeatures": { + "jsx": true + } + }, + "env": { + "browser": true, + "es2020": true + }, + "rules": { + "react/react-in-jsx-scope": "on" + } +} diff --git a/04-poke-battle-with-prisma/frontend/.gitignore b/04-poke-battle-with-prisma/frontend/.gitignore new file mode 100644 index 0000000..a547bf3 --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/04-poke-battle-with-prisma/frontend/index.html b/04-poke-battle-with-prisma/frontend/index.html new file mode 100644 index 0000000..7b9f537 --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/index.html @@ -0,0 +1,13 @@ + + + + + + + Vite + React + TS + + +
+ + + diff --git a/04-poke-battle-with-prisma/frontend/package-lock.json b/04-poke-battle-with-prisma/frontend/package-lock.json new file mode 100644 index 0000000..b35b14e --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/package-lock.json @@ -0,0 +1,5670 @@ +{ + "name": "expressots-with-prisma-orm-fronted", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "expressots-with-prisma-orm-fronted", + "version": "0.0.0", + "dependencies": { + "@dicebear/avatars": "^4.10.8", + "@dicebear/collection": "^6.0.3", + "@dicebear/core": "^6.0.3", + "@heroicons/react": "^2.0.18", + "@radix-ui/react-dropdown-menu": "^2.0.5", + "@radix-ui/react-slot": "^1.0.1", + "@tanstack/react-query": "^4.29.3", + "axios": "^1.3.6", + "clsx": "^1.2.1", + "daisyui": "^2.51.5", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-inlinesvg": "^3.0.2", + "react-router-dom": "^6.10.0", + "react-use-draggable-scroll": "^0.4.7", + "tailwind-merge": "^1.12.0", + "tailwind-scrollbar-hide": "^1.1.7", + "zustand": "^4.3.7" + }, + "devDependencies": { + "@types/react": "^18.0.28", + "@types/react-dom": "^18.0.11", + "@vitejs/plugin-react": "^3.1.0", + "autoprefixer": "^10.4.14", + "eslint": "^8.41.0", + "eslint-plugin-react": "^7.32.2", + "eslint-plugin-react-hooks": "^4.6.0", + "postcss": "^8.4.23", + "tailwindcss": "^3.3.1", + "typescript": "^4.9.3", + "vite": "^4.2.0", + "vite-plugin-eslint": "^1.8.1" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", + "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.21.4.tgz", + "integrity": "sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.21.4.tgz", + "integrity": "sha512-/DYyDpeCfaVinT40FPGdkkb+lYSKvsVuMjDAG7jPOWWiM1ibOaB9CXJAlc4d1QpP/U2q2P9jbrSlClKSErd55g==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.21.4.tgz", + "integrity": "sha512-qt/YV149Jman/6AfmlxJ04LMIu8bMoyl3RB91yTFrxQmgbrSvQMy7cI8Q62FHx1t8wJ8B5fu0UDoLwHAhUo1QA==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.21.4", + "@babel/generator": "^7.21.4", + "@babel/helper-compilation-targets": "^7.21.4", + "@babel/helper-module-transforms": "^7.21.2", + "@babel/helpers": "^7.21.0", + "@babel/parser": "^7.21.4", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.21.4", + "@babel/types": "^7.21.4", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.2", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.21.4.tgz", + "integrity": "sha512-NieM3pVIYW2SwGzKoqfPrQsf4xGs9M9AIG3ThppsSRmO+m7eQhmI6amajKMUeIO37wFfsvnvcxQFx6x6iqxDnA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.21.4", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.21.4.tgz", + "integrity": "sha512-Fa0tTuOXZ1iL8IeDFUWCzjZcn+sJGd9RZdH9esYVjEejGmzf+FFYQpMi/kZUk2kPy/q1H3/GPw7np8qar/stfg==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.21.4", + "@babel/helper-validator-option": "^7.21.0", + "browserslist": "^4.21.3", + "lru-cache": "^5.1.1", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", + "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz", + "integrity": "sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==", + "dev": true, + "dependencies": { + "@babel/template": "^7.20.7", + "@babel/types": "^7.21.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", + "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", + "dev": true, + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.21.4.tgz", + "integrity": "sha512-orajc5T2PsRYUN3ZryCEFeMDYwyw09c/pZeaQEZPH0MpKzSvn3e0uXsDBu3k03VI+9DBiRo+l22BfKTpKwa/Wg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.21.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.21.2", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.21.2.tgz", + "integrity": "sha512-79yj2AR4U/Oqq/WOV7Lx6hUjau1Zfo4cI+JLAVYeMV5XIlbOhmjEk5ulbTc9fMpmlojzZHkUUxAiK+UKn+hNQQ==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-simple-access": "^7.20.2", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/helper-validator-identifier": "^7.19.1", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.21.2", + "@babel/types": "^7.21.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz", + "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", + "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.20.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", + "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", + "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.21.0.tgz", + "integrity": "sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.21.0.tgz", + "integrity": "sha512-XXve0CBtOW0pd7MRzzmoyuSj0e3SEzj8pgyFxnTT1NJZL38BD1MK7yYrm8yefRPIDvNNe14xR4FdbHwpInD4rA==", + "dev": true, + "dependencies": { + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.21.0", + "@babel/types": "^7.21.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.18.6", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.4.tgz", + "integrity": "sha512-alVJj7k7zIxqBZ7BTRhz0IqJFxW1VJbm6N8JbcYhQ186df9ZBPbZBmWSqAMXwHGsCJdYks7z/voa3ibiS5bCIw==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.21.0.tgz", + "integrity": "sha512-f/Eq+79JEu+KUANFks9UZCcvydOOGMgF7jBrcwjHa5jTZD8JivnhCJYvmlhR/WTXBWonDExPoW0eO/CR4QJirA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.20.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.19.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.19.6.tgz", + "integrity": "sha512-RpAi004QyMNisst/pvSanoRdJ4q+jMCWyk9zdw/CyLB9j8RXEahodR6l2GyttDRyEVWZtbN+TpLiHJ3t34LbsQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.19.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.21.0.tgz", + "integrity": "sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw==", + "dependencies": { + "regenerator-runtime": "^0.13.11" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", + "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.18.6", + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.21.4.tgz", + "integrity": "sha512-eyKrRHKdyZxqDm+fV1iqL9UAHMoIg0nDaGqfIOd8rKH17m5snv7Gn4qgjBoFfLz9APvjFU/ICT00NVCv1Epp8Q==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.21.4", + "@babel/generator": "^7.21.4", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.21.0", + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/parser": "^7.21.4", + "@babel/types": "^7.21.4", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.4.tgz", + "integrity": "sha512-rU2oY501qDxE8Pyo7i/Orqma4ziCOrby0/9mvbDUGEfvZjb279Nk9k19e2fiCxHbRRpY2ZyrgW1eq22mvmOIzA==", + "dev": true, + "dependencies": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@dicebear/adventurer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@dicebear/adventurer/-/adventurer-6.0.3.tgz", + "integrity": "sha512-52PkjZxjKT96+M4IO19WOUXClaAUV/6DjJivPnT1sST5i+e2kN/KgnkfgQ7jVDxT+5LrIg2onyOS/VK1vTBvOw==", + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@dicebear/core": "^6.0.0" + } + }, + "node_modules/@dicebear/adventurer-neutral": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@dicebear/adventurer-neutral/-/adventurer-neutral-6.0.3.tgz", + "integrity": "sha512-Ke+eyFqYdwi1VPREHMQXitI0/3pqrkoGT8P+3Z4dGPhmDwyWbXzedlS7e6jsQ6MhPed+FG+OKFmD92TRl+7tfQ==", + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@dicebear/core": "^6.0.0" + } + }, + "node_modules/@dicebear/avataaars": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@dicebear/avataaars/-/avataaars-6.0.3.tgz", + "integrity": "sha512-DVUPXuvPunNfC6Ffwd2FqrXWNxvACEdNSPZRrH2v9wfnVVNPKlYRlqVtZrnyCCtl50Gek2wosepg07u/eE5jKg==", + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@dicebear/core": "^6.0.0" + } + }, + "node_modules/@dicebear/avataaars-neutral": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@dicebear/avataaars-neutral/-/avataaars-neutral-6.0.3.tgz", + "integrity": "sha512-FnvttEB4zpRaAvHFSwo1qjgGEJXdLuucLK5GRARHHBcn8Cn5CzmHBtp7KPq6aj8HygupZUlBMXIJ/wGPXMljSg==", + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@dicebear/core": "^6.0.0" + } + }, + "node_modules/@dicebear/avatars": { + "version": "4.10.8", + "resolved": "https://registry.npmjs.org/@dicebear/avatars/-/avatars-4.10.8.tgz", + "integrity": "sha512-jni3+W1yRRh4sJYmuQUZ8JpKI9aEEud53TUcxNFtntdRyOUJygIFdC5JPKNac58eALnBTZZ4ox7b+oeo0Ux/oA==", + "deprecated": "This package is deprecated. Use '@dicebear/core' instead. Read more: https://dicebear.com/how-to-use/js-library", + "dependencies": { + "@types/json-schema": "^7.0.7", + "pure-color": "^1.3.0", + "svgson": "^5.2.1" + } + }, + "node_modules/@dicebear/big-ears": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@dicebear/big-ears/-/big-ears-6.0.3.tgz", + "integrity": "sha512-9zz+OeHjLl1/fT02mXHTnH/U1Upb9jP+CSMV0QE2PY4osPN+T34DS7C817FTBES9i/QPpGzfdX/QrS2TkC1bmA==", + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@dicebear/core": "^6.0.0" + } + }, + "node_modules/@dicebear/big-ears-neutral": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@dicebear/big-ears-neutral/-/big-ears-neutral-6.0.3.tgz", + "integrity": "sha512-0Y2nVxoC3M9C+vOhcMN7xPm/+FcHaXtEs/cMPgxSXEsAPyTlkrecHUhRUlCNuP4i1GiSJhVOKW3I6GloHoXudA==", + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@dicebear/core": "^6.0.0" + } + }, + "node_modules/@dicebear/big-smile": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@dicebear/big-smile/-/big-smile-6.0.3.tgz", + "integrity": "sha512-98BYBKHkf1EYyd2kMFZC4RjRwawsjMqFT2zExhT2ja3espu1wCdr/3tR0r2WzpYe1fYwVP/TwqsUxPjZl0FvjQ==", + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@dicebear/core": "^6.0.0" + } + }, + "node_modules/@dicebear/bottts": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@dicebear/bottts/-/bottts-6.0.3.tgz", + "integrity": "sha512-NhLUPi8YF3LGkfny5sH/ev+t3pKxoCcd9qPlx6qGl2n1knXiBqkAWqkGBGPuYdgLQbI0JbpgPzAOTRQlhVxZgQ==", + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@dicebear/core": "^6.0.0" + } + }, + "node_modules/@dicebear/bottts-neutral": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@dicebear/bottts-neutral/-/bottts-neutral-6.0.3.tgz", + "integrity": "sha512-FQC6SlqCoWzOg6XFgup9byGBa9zzEt+vtfCYasHQKvulgfCN80FCF0uJ9sMqi1WQyolnSr2QxXc5Djyutn3VNA==", + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@dicebear/core": "^6.0.0" + } + }, + "node_modules/@dicebear/collection": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@dicebear/collection/-/collection-6.0.3.tgz", + "integrity": "sha512-SA+ByZu3WtbbkcpVW+IUcP49cuy8+Ws9EX+6g5nJmj5Q6BUh5qrRhZKSV5AVWUECRN72ZMVU85PJezsYBIrVZQ==", + "dependencies": { + "@dicebear/adventurer": "6.0.3", + "@dicebear/adventurer-neutral": "6.0.3", + "@dicebear/avataaars": "6.0.3", + "@dicebear/avataaars-neutral": "6.0.3", + "@dicebear/big-ears": "6.0.3", + "@dicebear/big-ears-neutral": "6.0.3", + "@dicebear/big-smile": "6.0.3", + "@dicebear/bottts": "6.0.3", + "@dicebear/bottts-neutral": "6.0.3", + "@dicebear/croodles": "6.0.3", + "@dicebear/croodles-neutral": "6.0.3", + "@dicebear/fun-emoji": "6.0.3", + "@dicebear/icons": "6.0.3", + "@dicebear/identicon": "6.0.3", + "@dicebear/initials": "6.0.3", + "@dicebear/lorelei": "6.0.3", + "@dicebear/lorelei-neutral": "6.0.3", + "@dicebear/micah": "6.0.3", + "@dicebear/miniavs": "6.0.3", + "@dicebear/notionists": "6.0.3", + "@dicebear/notionists-neutral": "6.0.3", + "@dicebear/open-peeps": "6.0.3", + "@dicebear/personas": "6.0.3", + "@dicebear/pixel-art": "6.0.3", + "@dicebear/pixel-art-neutral": "6.0.3", + "@dicebear/shapes": "6.0.3", + "@dicebear/thumbs": "6.0.3" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@dicebear/core": "^6.0.0" + } + }, + "node_modules/@dicebear/converter": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@dicebear/converter/-/converter-6.0.3.tgz", + "integrity": "sha512-/xy8fYWskEdrAkfDCXhsJ22pkh/GVxVcYQ6AyDIJIG53NgzEsClCZ8FodP7FjPpPHra83x2AZoXIhV/yDPPrkw==", + "dependencies": { + "@types/json-schema": "^7.0.11", + "tmp-promise": "^3.0.3" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@resvg/resvg-js": "^2.4.1", + "exiftool-vendored": "^21.2.0", + "sharp": "^0.31.3" + }, + "peerDependenciesMeta": { + "@resvg/resvg-js": { + "optional": true + }, + "exiftool-vendored": { + "optional": true + }, + "sharp": { + "optional": true + } + } + }, + "node_modules/@dicebear/core": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@dicebear/core/-/core-6.0.3.tgz", + "integrity": "sha512-h+SG+RLaMNG6PR4if+uX8+GuO1r9Q/wKAoogpTrkOg0JkUBaaZv+CaUHSg3Ppd7zDZC0H7SuAEsCJuvJELa8iA==", + "dependencies": { + "@dicebear/converter": "6.0.3", + "@types/json-schema": "^7.0.11" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@dicebear/croodles": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@dicebear/croodles/-/croodles-6.0.3.tgz", + "integrity": "sha512-4/9hpfRa7csYS9OjKLZ0hdXUzlr6eJpmRNjepG36mF/sGuAnRfnAJkEY4I++1rDmAHEAvd/hU85ZXnEYbSdhVw==", + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@dicebear/core": "^6.0.0" + } + }, + "node_modules/@dicebear/croodles-neutral": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@dicebear/croodles-neutral/-/croodles-neutral-6.0.3.tgz", + "integrity": "sha512-/AN1x9hBObDW8nzgPumvQbzC41v8WsCepldHebxgxJWLYF/zIxQrMXDG7VVuBFVvGIMCpWmkRRxZRFmvZbkIFg==", + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@dicebear/core": "^6.0.0" + } + }, + "node_modules/@dicebear/fun-emoji": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@dicebear/fun-emoji/-/fun-emoji-6.0.3.tgz", + "integrity": "sha512-2O+vAIWSSQJWU/rDwK1T9eOfYDCUA5bsB9Z6uuTAl95bP0fCiVCqXp/gD+n/TgWu9GxGVaj6ZK4g8a9/3tUUEg==", + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@dicebear/core": "^6.0.0" + } + }, + "node_modules/@dicebear/icons": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@dicebear/icons/-/icons-6.0.3.tgz", + "integrity": "sha512-Hu1v0teMTpO4FN6Ww/TFlOqoHDCoTRAREs/zcMRJwtEagUOYjkA50vjG6S6kNVGKTphIeHNfa2+Am3t6pkK3qg==", + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@dicebear/core": "^6.0.0" + } + }, + "node_modules/@dicebear/identicon": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@dicebear/identicon/-/identicon-6.0.3.tgz", + "integrity": "sha512-JAGtpefkeZk/gvSx2VUbcCikxYlIyAasNiNl2XRBGuQ8pNtjw9XGYNeTMHc1RsEmfZ6RRSa5EM9mC6XZy+Dypw==", + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@dicebear/core": "^6.0.0" + } + }, + "node_modules/@dicebear/initials": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@dicebear/initials/-/initials-6.0.3.tgz", + "integrity": "sha512-IFridsnDsKBq6o7XZ+nNuEgFaHKhq4RTTZQLJDRi/tEbakiQJoUSNGDXIdcrdLNvJ7dDfKfcACCSRJ7+aj84Yg==", + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@dicebear/core": "^6.0.0" + } + }, + "node_modules/@dicebear/lorelei": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@dicebear/lorelei/-/lorelei-6.0.3.tgz", + "integrity": "sha512-LT3s/Sr8EBKmj++cjHmJLTzdHnAJYLOvDB/UhGVz7xLsepF2JfD3hzGgSLmlqkNCdkSJlEM2csn4EDdVYItoLw==", + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@dicebear/core": "^6.0.0" + } + }, + "node_modules/@dicebear/lorelei-neutral": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@dicebear/lorelei-neutral/-/lorelei-neutral-6.0.3.tgz", + "integrity": "sha512-XtPsqa0hZav8h8scENRSayxjVnrpbXLu2LzJa6foAYjYPmI6g0fqkBLjcE7UCoSOjOGYdqkbJ3265bXMaiROnw==", + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@dicebear/core": "^6.0.0" + } + }, + "node_modules/@dicebear/micah": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@dicebear/micah/-/micah-6.0.3.tgz", + "integrity": "sha512-hYtvqexzJumPvi5SSV+EfyllbJ807QF+gIUbZesd8jN6K0apzdfUhl3rDhzcGbvHz4Dxm3PRKORqYl44gdQ6CQ==", + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@dicebear/core": "^6.0.0" + } + }, + "node_modules/@dicebear/miniavs": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@dicebear/miniavs/-/miniavs-6.0.3.tgz", + "integrity": "sha512-8UozyFjDFT5VHZCvhUYbAhXVE7k/Asg1b4qMHlY5rTgvxy+v+KABnmUM1ng+zlN5lgd4MVnNUBdWrHx9GxOVdQ==", + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@dicebear/core": "^6.0.0" + } + }, + "node_modules/@dicebear/notionists": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@dicebear/notionists/-/notionists-6.0.3.tgz", + "integrity": "sha512-7WH/3KHzkiFHhmsxO99BpfGTy3aV7xDu5hWriZpu0o+UofqDBNeyLfC6jCqREJH1gBR+r+B/RtyHWSST7N4P7Q==", + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@dicebear/core": "^6.0.0" + } + }, + "node_modules/@dicebear/notionists-neutral": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@dicebear/notionists-neutral/-/notionists-neutral-6.0.3.tgz", + "integrity": "sha512-/QNvdLjL2Hoy7WIqxh5ITXWO6tUBS3h6BCaZ/KhkaFldtyOPYnLWouUWY5i+LyQ9/WwJ2yu6AnyXoGVhXcDl6w==", + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@dicebear/core": "^6.0.0" + } + }, + "node_modules/@dicebear/open-peeps": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@dicebear/open-peeps/-/open-peeps-6.0.3.tgz", + "integrity": "sha512-VK3+mfjewxCAppYjkGGJ4BJWmKkQ4T6N8OcoYmpthMfg4tasYLueQOQLd0duKphhzPK0dGyyuxvcfRI9ct/r9w==", + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@dicebear/core": "^6.0.0" + } + }, + "node_modules/@dicebear/personas": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@dicebear/personas/-/personas-6.0.3.tgz", + "integrity": "sha512-Ih9ISwNS9BXdrTGs/KNGgyE0JWRPmHpLKCC1bsEyzp70ChyDMIhPUPk4A4lNseLlfm/nmfQ40wgDhyzabcjPVA==", + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@dicebear/core": "^6.0.0" + } + }, + "node_modules/@dicebear/pixel-art": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@dicebear/pixel-art/-/pixel-art-6.0.3.tgz", + "integrity": "sha512-6l2ada7kw5S7y4Kg8Ciuor/NAbpxAW6jIKrScVFlb8uzcXTQmYE2h7Ecd/MerHjqtaMKliwqXSefnztKLstyyw==", + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@dicebear/core": "^6.0.0" + } + }, + "node_modules/@dicebear/pixel-art-neutral": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@dicebear/pixel-art-neutral/-/pixel-art-neutral-6.0.3.tgz", + "integrity": "sha512-IkSy8NTHYUeW/mll8f9tPFT8+G2h5SRec18flFjPdrz+KnfsdcPMUMtDLeJrWO/B2jqy8BwmNtqSuvXsX02oJw==", + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@dicebear/core": "^6.0.0" + } + }, + "node_modules/@dicebear/shapes": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@dicebear/shapes/-/shapes-6.0.3.tgz", + "integrity": "sha512-L0eW/Yvork3iNTVGBmy6Ayz878n55NiUxHSiWsHq/7szXv1KN9q0WB04As9bfTWitPJXTQ6TP+zuTHw3o6IUcw==", + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@dicebear/core": "^6.0.0" + } + }, + "node_modules/@dicebear/thumbs": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@dicebear/thumbs/-/thumbs-6.0.3.tgz", + "integrity": "sha512-Z5mvn6P4C8JBO4X8MMHWIB4H76tGhkfpPk7htaFWwGDS7dSg4vj+3HiR865acugS7edugwNXlJ3a2ex/6/yP3A==", + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@dicebear/core": "^6.0.0" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.17.tgz", + "integrity": "sha512-E6VAZwN7diCa3labs0GYvhEPL2M94WLF8A+czO8hfjREXxba8Ng7nM5VxV+9ihNXIY1iQO1XxUU4P7hbqbICxg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.17.tgz", + "integrity": "sha512-jaJ5IlmaDLFPNttv0ofcwy/cfeY4bh/n705Tgh+eLObbGtQBK3EPAu+CzL95JVE4nFAliyrnEu0d32Q5foavqg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.17.tgz", + "integrity": "sha512-446zpfJ3nioMC7ASvJB1pszHVskkw4u/9Eu8s5yvvsSDTzYh4p4ZIRj0DznSl3FBF0Z/mZfrKXTtt0QCoFmoHA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.17.tgz", + "integrity": "sha512-m/gwyiBwH3jqfUabtq3GH31otL/0sE0l34XKpSIqR7NjQ/XHQ3lpmQHLHbG8AHTGCw8Ao059GvV08MS0bhFIJQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.17.tgz", + "integrity": "sha512-4utIrsX9IykrqYaXR8ob9Ha2hAY2qLc6ohJ8c0CN1DR8yWeMrTgYFjgdeQ9LIoTOfLetXjuCu5TRPHT9yKYJVg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.17.tgz", + "integrity": "sha512-4PxjQII/9ppOrpEwzQ1b0pXCsFLqy77i0GaHodrmzH9zq2/NEhHMAMJkJ635Ns4fyJPFOlHMz4AsklIyRqFZWA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.17.tgz", + "integrity": "sha512-lQRS+4sW5S3P1sv0z2Ym807qMDfkmdhUYX30GRBURtLTrJOPDpoU0kI6pVz1hz3U0+YQ0tXGS9YWveQjUewAJw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.17.tgz", + "integrity": "sha512-biDs7bjGdOdcmIk6xU426VgdRUpGg39Yz6sT9Xp23aq+IEHDb/u5cbmu/pAANpDB4rZpY/2USPhCA+w9t3roQg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.17.tgz", + "integrity": "sha512-2+pwLx0whKY1/Vqt8lyzStyda1v0qjJ5INWIe+d8+1onqQxHLLi3yr5bAa4gvbzhZqBztifYEu8hh1La5+7sUw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.17.tgz", + "integrity": "sha512-IBTTv8X60dYo6P2t23sSUYym8fGfMAiuv7PzJ+0LcdAndZRzvke+wTVxJeCq4WgjppkOpndL04gMZIFvwoU34Q==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.17.tgz", + "integrity": "sha512-WVMBtcDpATjaGfWfp6u9dANIqmU9r37SY8wgAivuKmgKHE+bWSuv0qXEFt/p3qXQYxJIGXQQv6hHcm7iWhWjiw==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.17.tgz", + "integrity": "sha512-2kYCGh8589ZYnY031FgMLy0kmE4VoGdvfJkxLdxP4HJvWNXpyLhjOvxVsYjYZ6awqY4bgLR9tpdYyStgZZhi2A==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.17.tgz", + "integrity": "sha512-KIdG5jdAEeAKogfyMTcszRxy3OPbZhq0PPsW4iKKcdlbk3YE4miKznxV2YOSmiK/hfOZ+lqHri3v8eecT2ATwQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.17.tgz", + "integrity": "sha512-Cj6uWLBR5LWhcD/2Lkfg2NrkVsNb2sFM5aVEfumKB2vYetkA/9Uyc1jVoxLZ0a38sUhFk4JOVKH0aVdPbjZQeA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.17.tgz", + "integrity": "sha512-lK+SffWIr0XsFf7E0srBjhpkdFVJf3HEgXCwzkm69kNbRar8MhezFpkIwpk0qo2IOQL4JE4mJPJI8AbRPLbuOQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.17.tgz", + "integrity": "sha512-XcSGTQcWFQS2jx3lZtQi7cQmDYLrpLRyz1Ns1DzZCtn898cWfm5Icx/DEWNcTU+T+tyPV89RQtDnI7qL2PObPg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.17.tgz", + "integrity": "sha512-RNLCDmLP5kCWAJR+ItLM3cHxzXRTe4N00TQyQiimq+lyqVqZWGPAvcyfUBM0isE79eEZhIuGN09rAz8EL5KdLA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.17.tgz", + "integrity": "sha512-PAXswI5+cQq3Pann7FNdcpSUrhrql3wKjj3gVkmuz6OHhqqYxKvi6GgRBoaHjaG22HV/ZZEgF9TlS+9ftHVigA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.17.tgz", + "integrity": "sha512-V63egsWKnx/4V0FMYkr9NXWrKTB5qFftKGKuZKFIrAkO/7EWLFnbBZNM1CvJ6Sis+XBdPws2YQSHF1Gqf1oj/Q==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.17.tgz", + "integrity": "sha512-YtUXLdVnd6YBSYlZODjWzH+KzbaubV0YVd6UxSfoFfa5PtNJNaW+1i+Hcmjpg2nEe0YXUCNF5bkKy1NnBv1y7Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.17.tgz", + "integrity": "sha512-yczSLRbDdReCO74Yfc5tKG0izzm+lPMYyO1fFTcn0QNwnKmc3K+HdxZWLGKg4pZVte7XVgcFku7TIZNbWEJdeQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.17.tgz", + "integrity": "sha512-FNZw7H3aqhF9OyRQbDDnzUApDXfC1N6fgBhkqEO2jvYCJ+DxMTfZVqg3AX0R1khg1wHTBRD5SdcibSJ+XF6bFg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.5.1.tgz", + "integrity": "sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.3.tgz", + "integrity": "sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.5.2", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "13.20.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", + "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/js": { + "version": "8.41.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.41.0.tgz", + "integrity": "sha512-LxcyMGxwmTh2lY9FwHPGWOHmYFCZvbrFCBZL4FzSSsxsRPuhrYUg/49/0KDfW8tnIEaEHtfmn6+NPN+1DqaNmA==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@floating-ui/core": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.2.6.tgz", + "integrity": "sha512-EvYTiXet5XqweYGClEmpu3BoxmsQ4hkj3QaYA6qEnigCWffTP3vNRwBReTdrwDwo7OoJ3wM8Uoe9Uk4n+d4hfg==" + }, + "node_modules/@floating-ui/dom": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.2.9.tgz", + "integrity": "sha512-sosQxsqgxMNkV3C+3UqTS6LxP7isRLwX8WMepp843Rb3/b0Wz8+MdUkxJksByip3C2WwLugLHN1b4ibn//zKwQ==", + "dependencies": { + "@floating-ui/core": "^1.2.6" + } + }, + "node_modules/@floating-ui/react-dom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.0.0.tgz", + "integrity": "sha512-Ke0oU3SeuABC2C4OFu2mSAwHIP5WUiV98O9YWoHV4Q5aT6E9k06DV0Khi5uYspR8xmmBk08t8ZDcz3TR3ARkEg==", + "dependencies": { + "@floating-ui/dom": "^1.2.7" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@heroicons/react": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/@heroicons/react/-/react-2.0.18.tgz", + "integrity": "sha512-7TyMjRrZZMBPa+/5Y8lN0iyvUU/01PeMGX2+RE7cQWpEUIcb4QotzUObFkJDejj/HUH4qjP/eQ0gzzKs2f+6Yw==", + "peerDependencies": { + "react": ">= 16" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.8", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", + "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.18", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz", + "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==", + "dependencies": { + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" + } + }, + "node_modules/@jridgewell/trace-mapping/node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@radix-ui/primitive": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.0.1.tgz", + "integrity": "sha512-yQ8oGX2GVsEYMWGxcovu1uGWPCxV5BFfeeYxqPmuAzUyLT9qmaMXSAhXpb0WrspIeqYzdJpkh2vHModJPgRIaw==", + "dependencies": { + "@babel/runtime": "^7.13.10" + } + }, + "node_modules/@radix-ui/react-arrow": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.0.3.tgz", + "integrity": "sha512-wSP+pHsB/jQRaL6voubsQ/ZlrGBHHrOjmBnr19hxYgtS0WvAFwZhK2WP/YY5yF9uKECCEEDGxuLxq1NBK51wFA==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-primitive": "1.0.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-collection": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.0.3.tgz", + "integrity": "sha512-3SzW+0PW7yBBoQlT8wNcGtaxaD0XSu0uLUFgrtHY08Acx05TaHaOmVLR73c0j/cqpDy53KBMO7s0dx2wmOIDIA==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-slot": "1.0.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-compose-refs": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.0.1.tgz", + "integrity": "sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw==", + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-context": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.0.1.tgz", + "integrity": "sha512-ebbrdFoYTcuZ0v4wG5tedGnp9tzcV8awzsxYph7gXUyvnNLuTIcCk1q17JEbnVhXAKG9oX3KtchwiMIAYp9NLg==", + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-direction": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.0.1.tgz", + "integrity": "sha512-RXcvnXgyvYvBEOhCBuddKecVkoMiI10Jcm5cTI7abJRAHYfFxeu+FBQs/DvdxSYucxR5mna0dNsL6QFlds5TMA==", + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dismissable-layer": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.0.4.tgz", + "integrity": "sha512-7UpBa/RKMoHJYjie1gkF1DlK8l1fdU/VKDpoS3rCCo8YBJR294GwcEHyxHw72yvphJ7ld0AXEcSLAzY2F/WyCg==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-use-callback-ref": "1.0.1", + "@radix-ui/react-use-escape-keydown": "1.0.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dropdown-menu": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.0.5.tgz", + "integrity": "sha512-xdOrZzOTocqqkCkYo8yRPCib5OkTkqN7lqNCdxwPOdE466DOaNl4N8PkUIlsXthQvW5Wwkd+aEmWpfWlBoDPEw==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-id": "1.0.1", + "@radix-ui/react-menu": "2.0.5", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-use-controllable-state": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-focus-guards": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.0.1.tgz", + "integrity": "sha512-Rect2dWbQ8waGzhMavsIbmSVCgYxkXLxxR3ZvCX79JOglzdEy4JXMb98lq4hPxUbLr77nP0UOGf4rcMU+s1pUA==", + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-focus-scope": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.0.3.tgz", + "integrity": "sha512-upXdPfqI4islj2CslyfUBNlaJCPybbqRHAi1KER7Isel9Q2AtSJ0zRBZv8mWQiFXD2nyAJ4BhC3yXgZ6kMBSrQ==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-use-callback-ref": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-id": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.0.1.tgz", + "integrity": "sha512-tI7sT/kqYp8p96yGWY1OAnLHrqDgzHefRBKQ2YAkBS5ja7QLcZ9Z/uY7bEjPUatf8RomoXM8/1sMj1IJaE5UzQ==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-use-layout-effect": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-menu": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.0.5.tgz", + "integrity": "sha512-Gw4f9pwdH+w5w+49k0gLjN0PfRDHvxmAgG16AbyJZ7zhwZ6PBHKtWohvnSwfusfnK3L68dpBREHpVkj8wEM7ZA==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-collection": "1.0.3", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-direction": "1.0.1", + "@radix-ui/react-dismissable-layer": "1.0.4", + "@radix-ui/react-focus-guards": "1.0.1", + "@radix-ui/react-focus-scope": "1.0.3", + "@radix-ui/react-id": "1.0.1", + "@radix-ui/react-popper": "1.1.2", + "@radix-ui/react-portal": "1.0.3", + "@radix-ui/react-presence": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-roving-focus": "1.0.4", + "@radix-ui/react-slot": "1.0.2", + "@radix-ui/react-use-callback-ref": "1.0.1", + "aria-hidden": "^1.1.1", + "react-remove-scroll": "2.5.5" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-popper": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.1.2.tgz", + "integrity": "sha512-1CnGGfFi/bbqtJZZ0P/NQY20xdG3E0LALJaLUEoKwPLwl6PPPfbeiCqMVQnhoFRAxjJj4RpBRJzDmUgsex2tSg==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@floating-ui/react-dom": "^2.0.0", + "@radix-ui/react-arrow": "1.0.3", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-use-callback-ref": "1.0.1", + "@radix-ui/react-use-layout-effect": "1.0.1", + "@radix-ui/react-use-rect": "1.0.1", + "@radix-ui/react-use-size": "1.0.1", + "@radix-ui/rect": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-portal": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.0.3.tgz", + "integrity": "sha512-xLYZeHrWoPmA5mEKEfZZevoVRK/Q43GfzRXkWV6qawIWWK8t6ifIiLQdd7rmQ4Vk1bmI21XhqF9BN3jWf+phpA==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-primitive": "1.0.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-presence": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.0.1.tgz", + "integrity": "sha512-UXLW4UAbIY5ZjcvzjfRFo5gxva8QirC9hF7wRE4U5gz+TP0DbRk+//qyuAQ1McDxBt1xNMBTaciFGvEmJvAZCg==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-use-layout-effect": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-primitive": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-1.0.3.tgz", + "integrity": "sha512-yi58uVyoAcK/Nq1inRY56ZSjKypBNKTa/1mcL8qdl6oJeEaDbOldlzrGn7P6Q3Id5d+SYNGc5AJgc4vGhjs5+g==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-slot": "1.0.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-roving-focus": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.0.4.tgz", + "integrity": "sha512-2mUg5Mgcu001VkGy+FfzZyzbmuUWzgWkj3rvv4yu+mLw03+mTzbxZHvfcGyFp2b8EkQeMkpRQ5FiA2Vr2O6TeQ==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-collection": "1.0.3", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-direction": "1.0.1", + "@radix-ui/react-id": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-use-callback-ref": "1.0.1", + "@radix-ui/react-use-controllable-state": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-slot": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.2.tgz", + "integrity": "sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-callback-ref": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.0.1.tgz", + "integrity": "sha512-D94LjX4Sp0xJFVaoQOd3OO9k7tpBYNOXdVhkltUbGv2Qb9OXdrg/CpsjlZv7ia14Sylv398LswWBVVu5nqKzAQ==", + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-controllable-state": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.0.1.tgz", + "integrity": "sha512-Svl5GY5FQeN758fWKrjM6Qb7asvXeiZltlT4U2gVfl8Gx5UAv2sMR0LWo8yhsIZh2oQ0eFdZ59aoOOMV7b47VA==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-use-callback-ref": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-escape-keydown": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.0.3.tgz", + "integrity": "sha512-vyL82j40hcFicA+M4Ex7hVkB9vHgSse1ZWomAqV2Je3RleKGO5iM8KMOEtfoSB0PnIelMd2lATjTGMYqN5ylTg==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-use-callback-ref": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-layout-effect": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.0.1.tgz", + "integrity": "sha512-v/5RegiJWYdoCvMnITBkNNx6bCj20fiaJnWtRkU18yITptraXjffz5Qbn05uOiQnOvi+dbkznkoaMltz1GnszQ==", + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-rect": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.0.1.tgz", + "integrity": "sha512-Cq5DLuSiuYVKNU8orzJMbl15TXilTnJKUCltMVQg53BQOF1/C5toAaGrowkgksdBQ9H+SRL23g0HDmg9tvmxXw==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/rect": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-size": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.0.1.tgz", + "integrity": "sha512-ibay+VqrgcaI6veAojjofPATwledXiSmX+C0KrBk/xgpX9rBzPV3OsfwlhQdUOFbh+LKQorLYT+xTXW9V8yd0g==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-use-layout-effect": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/rect": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.0.1.tgz", + "integrity": "sha512-fyrgCaedtvMg9NK3en0pnOYJdtfwxUcNolezkNPUsoX57X8oQk+NkqcvzHXD2uKNij6GXmWU9NDru2IWjrO4BQ==", + "dependencies": { + "@babel/runtime": "^7.13.10" + } + }, + "node_modules/@remix-run/router": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.5.0.tgz", + "integrity": "sha512-bkUDCp8o1MvFO+qxkODcbhSqRa6P2GXgrGZVpt0dCXNW2HCSCqYI0ZoAqEOSAjRWmmlKcYgFvN4B4S+zo/f8kg==", + "engines": { + "node": ">=14" + } + }, + "node_modules/@rollup/pluginutils": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.2.1.tgz", + "integrity": "sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==", + "dev": true, + "dependencies": { + "estree-walker": "^2.0.1", + "picomatch": "^2.2.2" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/@tanstack/query-core": { + "version": "4.29.1", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-4.29.1.tgz", + "integrity": "sha512-vkPewLEG8ua0efo3SsVT0BcBtkq5RZX8oPhDAyKL+k/rdOYSQTEocfGEXSaBwIwsXeOGBUpfKqI+UmHvNqdWXg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/react-query": { + "version": "4.29.3", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-4.29.3.tgz", + "integrity": "sha512-FPQrMu7PbCgBcVzoRJm7WmQnAFv+LUgZM9KBZ7Vk/+yERH2BDLvQRuAgczQd5Tb1s3HbOktECRDaOkUxdyBAjw==", + "dependencies": { + "@tanstack/query-core": "4.29.1", + "use-sync-external-store": "^1.2.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-native": "*" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + }, + "react-native": { + "optional": true + } + } + }, + "node_modules/@types/eslint": { + "version": "8.37.0", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.37.0.tgz", + "integrity": "sha512-Piet7dG2JBuDIfohBngQ3rCt7MgO9xCO4xIMKxBThCq5PNRB91IjlJ10eJVwfoNtvTErmxLzwBZ7rHZtbOMmFQ==", + "dev": true, + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", + "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==", + "dev": true + }, + "node_modules/@types/json-schema": { + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", + "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==" + }, + "node_modules/@types/prop-types": { + "version": "15.7.5", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", + "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==", + "devOptional": true + }, + "node_modules/@types/react": { + "version": "18.0.38", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.38.tgz", + "integrity": "sha512-ExsidLLSzYj4cvaQjGnQCk4HFfVT9+EZ9XZsQ8Hsrcn8QNgXtpZ3m9vSIC2MWtx7jHictK6wYhQgGh6ic58oOw==", + "devOptional": true, + "dependencies": { + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "18.0.11", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.0.11.tgz", + "integrity": "sha512-O38bPbI2CWtgw/OoQoY+BRelw7uysmXbWvw3nLWO21H1HSh+GOlqPuXshJfjmpNlKiiSDG9cc1JZAaMmVdcTlw==", + "devOptional": true, + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/scheduler": { + "version": "0.16.3", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.3.tgz", + "integrity": "sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==", + "devOptional": true + }, + "node_modules/@vitejs/plugin-react": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-3.1.0.tgz", + "integrity": "sha512-AfgcRL8ZBhAlc3BFdigClmTUMISmmzHn7sB2h9U1odvc5U/MjWXsAaz18b/WoppUTDBzxOJwo2VdClfUcItu9g==", + "dev": true, + "dependencies": { + "@babel/core": "^7.20.12", + "@babel/plugin-transform-react-jsx-self": "^7.18.6", + "@babel/plugin-transform-react-jsx-source": "^7.19.6", + "magic-string": "^0.27.0", + "react-refresh": "^0.14.0" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "vite": "^4.1.0-beta.0" + } + }, + "node_modules/acorn": { + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", + "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==" + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/aria-hidden": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.3.tgz", + "integrity": "sha512-xcLxITLe2HYa1cnYnwCjkOO1PqUHQpozB8x9AR0OgWN2woOBi5kSDVxKfd0b7sb1hw5qFeJhXm9H1nu3xSfLeQ==", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz", + "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "is-array-buffer": "^3.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-includes": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.6.tgz", + "integrity": "sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "get-intrinsic": "^1.1.3", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz", + "integrity": "sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.tosorted": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.1.tgz", + "integrity": "sha512-pZYPXPRl2PqWcsUs6LOMn+1f1532nEoPTYowBtqLwAW+W8vSVhkIGnmOX1t/UQjD6YGI0vcD2B1U7ZFGQH9jnQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "es-shim-unscopables": "^1.0.0", + "get-intrinsic": "^1.1.3" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "node_modules/autoprefixer": { + "version": "10.4.14", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.14.tgz", + "integrity": "sha512-FQzyfOsTlwVzjHxKEqRIAdJx9niO6VCBCoEwax/VLSoQF29ggECcPuBqUMZ+u8jCZOPSy8b8/8KnuFbp0SaFZQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + } + ], + "dependencies": { + "browserslist": "^4.21.5", + "caniuse-lite": "^1.0.30001464", + "fraction.js": "^4.2.0", + "normalize-range": "^0.1.2", + "picocolors": "^1.0.0", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", + "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/axios": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.3.6.tgz", + "integrity": "sha512-PEcdkk7JcdPiMDkvM4K6ZBRYq9keuVJsToxm2zQIM70Qqo2WHTdJZMXcG9X+RmRp2VPNUQC8W1RAGbgt6b1yMg==", + "dependencies": { + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "engines": { + "node": ">=8" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.21.5", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz", + "integrity": "sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001449", + "electron-to-chromium": "^1.4.284", + "node-releases": "^2.0.8", + "update-browserslist-db": "^1.0.10" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001481", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001481.tgz", + "integrity": "sha512-KCqHwRnaa1InZBtqXzP98LPg0ajCVujMKjqKDhZEthIpAsJl/YEIa3YvXjGXPVqzZVguccuu7ga9KOE1J9rKPQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/clsx": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", + "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/color": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", + "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", + "dependencies": { + "color-convert": "^2.0.1", + "color-string": "^1.9.0" + }, + "engines": { + "node": ">=12.5.0" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "node_modules/color/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/css-selector-tokenizer": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.8.0.tgz", + "integrity": "sha512-Jd6Ig3/pe62/qe5SBPTN8h8LeUg/pT4lLgtavPf7updwwHpvFzxvOQBHYj2LZDMjUnBzgvIUSjRcf6oT5HzHFg==", + "dependencies": { + "cssesc": "^3.0.0", + "fastparse": "^1.1.2" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/csstype": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", + "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==", + "devOptional": true + }, + "node_modules/daisyui": { + "version": "2.51.5", + "resolved": "https://registry.npmjs.org/daisyui/-/daisyui-2.51.5.tgz", + "integrity": "sha512-L05dRw0tasmz2Ha+10LhftEGLq4kaA8vRR/T0wDaXfHwqcgsf81jfXDJ6NlZ63Z7Rl1k3rj7UHs0l0p7CM3aYA==", + "dependencies": { + "color": "^4.2", + "css-selector-tokenizer": "^0.8.0", + "postcss-js": "^4.0.0", + "tailwindcss": "^3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/daisyui" + }, + "peerDependencies": { + "autoprefixer": "^10.0.2", + "postcss": "^8.1.6" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/deep-rename-keys": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/deep-rename-keys/-/deep-rename-keys-0.2.1.tgz", + "integrity": "sha512-RHd9ABw4Fvk+gYDWqwOftG849x0bYOySl/RgX0tLI9i27ZIeSO91mLZJEp7oPHOMFqHvpgu21YptmDt0FYD/0A==", + "dependencies": { + "kind-of": "^3.0.2", + "rename-keys": "^1.1.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-properties": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz", + "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==", + "dev": true, + "dependencies": { + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/detect-node-es": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", + "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==" + }, + "node_modules/didyoumean": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==" + }, + "node_modules/dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.4.369", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.369.tgz", + "integrity": "sha512-LfxbHXdA/S+qyoTEA4EbhxGjrxx7WK2h6yb5K2v0UCOufUKX+VZaHbl3svlzZfv9sGseym/g3Ne4DpsgRULmqg==" + }, + "node_modules/es-abstract": { + "version": "1.21.2", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.21.2.tgz", + "integrity": "sha512-y/B5POM2iBnIxCiernH1G7rC9qQoM77lLIMQLuob0zhp8C56Po81+2Nj0WFKnd0pNReDTnkYryc+zhOzpEIROg==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "es-set-tostringtag": "^2.0.1", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.5", + "get-intrinsic": "^1.2.0", + "get-symbol-description": "^1.0.0", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has": "^1.0.3", + "has-property-descriptors": "^1.0.0", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.5", + "is-array-buffer": "^3.0.2", + "is-callable": "^1.2.7", + "is-negative-zero": "^2.0.2", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.10", + "is-weakref": "^1.0.2", + "object-inspect": "^1.12.3", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.4.3", + "safe-regex-test": "^1.0.0", + "string.prototype.trim": "^1.2.7", + "string.prototype.trimend": "^1.0.6", + "string.prototype.trimstart": "^1.0.6", + "typed-array-length": "^1.0.4", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz", + "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.3", + "has": "^1.0.3", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", + "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/esbuild": { + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.17.tgz", + "integrity": "sha512-/jUywtAymR8jR4qsa2RujlAF7Krpt5VWi72Q2yuLD4e/hvtNcFQ0I1j8m/bxq238pf3/0KO5yuXNpuLx8BE1KA==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.17.17", + "@esbuild/android-arm64": "0.17.17", + "@esbuild/android-x64": "0.17.17", + "@esbuild/darwin-arm64": "0.17.17", + "@esbuild/darwin-x64": "0.17.17", + "@esbuild/freebsd-arm64": "0.17.17", + "@esbuild/freebsd-x64": "0.17.17", + "@esbuild/linux-arm": "0.17.17", + "@esbuild/linux-arm64": "0.17.17", + "@esbuild/linux-ia32": "0.17.17", + "@esbuild/linux-loong64": "0.17.17", + "@esbuild/linux-mips64el": "0.17.17", + "@esbuild/linux-ppc64": "0.17.17", + "@esbuild/linux-riscv64": "0.17.17", + "@esbuild/linux-s390x": "0.17.17", + "@esbuild/linux-x64": "0.17.17", + "@esbuild/netbsd-x64": "0.17.17", + "@esbuild/openbsd-x64": "0.17.17", + "@esbuild/sunos-x64": "0.17.17", + "@esbuild/win32-arm64": "0.17.17", + "@esbuild/win32-ia32": "0.17.17", + "@esbuild/win32-x64": "0.17.17" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/eslint": { + "version": "8.41.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.41.0.tgz", + "integrity": "sha512-WQDQpzGBOP5IrXPo4Hc0814r4/v2rrIsB0rhT7jtunIalgg6gYXWhRMOejVO8yH21T/FGaxjmFjBMNqcIlmH1Q==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.4.0", + "@eslint/eslintrc": "^2.0.3", + "@eslint/js": "8.41.0", + "@humanwhocodes/config-array": "^0.11.8", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.0", + "eslint-visitor-keys": "^3.4.1", + "espree": "^9.5.2", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "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.1", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-plugin-react": { + "version": "7.32.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.32.2.tgz", + "integrity": "sha512-t2fBMa+XzonrrNkyVirzKlvn5RXzzPwRHtMvLAtVZrt8oxgnTQaYbU6SXTOO1mwQgp1y5+toMSKInnzGr0Knqg==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.flatmap": "^1.3.1", + "array.prototype.tosorted": "^1.1.1", + "doctrine": "^2.1.0", + "estraverse": "^5.3.0", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.1.2", + "object.entries": "^1.1.6", + "object.fromentries": "^2.0.6", + "object.hasown": "^1.1.2", + "object.values": "^1.1.6", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.4", + "semver": "^6.3.0", + "string.prototype.matchall": "^4.0.8" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz", + "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==", + "dev": true, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0" + } + }, + "node_modules/eslint-plugin-react/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-react/node_modules/resolve": { + "version": "2.0.0-next.4", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.4.tgz", + "integrity": "sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ==", + "dev": true, + "dependencies": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/eslint-scope": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz", + "integrity": "sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", + "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/eslint/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/eslint/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/eslint/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/eslint/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/globals": { + "version": "13.20.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", + "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/espree": { + "version": "9.5.2", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.2.tgz", + "integrity": "sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw==", + "dev": true, + "dependencies": { + "acorn": "^8.8.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eventemitter3": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-2.0.3.tgz", + "integrity": "sha512-jLN68Dx5kyFHaePoXWPsCGW5qdyZQtLYHkxkg02/Mz6g0kYpDx4FyP6XfArhQdlOC4b8Mv+EMxPo/8La7Tzghg==" + }, + "node_modules/exenv": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/exenv/-/exenv-1.2.2.tgz", + "integrity": "sha512-Z+ktTxTwv9ILfgKCk32OX3n/doe+OcLTRtqK9pcL+JsP3J1/VW8Uvl4ZjLlKqeW4rzK4oesDOGMEMRIZqtP4Iw==" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.2.12", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "node_modules/fastparse": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.2.tgz", + "integrity": "sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==" + }, + "node_modules/fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "dependencies": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", + "dev": true + }, + "node_modules/follow-redirects": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.3" + } + }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fraction.js": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz", + "integrity": "sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==", + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://www.patreon.com/infusion" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "node_modules/function.prototype.name": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", + "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.0", + "functions-have-names": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", + "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-nonce": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", + "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==", + "engines": { + "node": ">=6" + } + }, + "node_modules/get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/globalthis": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", + "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", + "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==", + "dependencies": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-value/node_modules/isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==", + "dependencies": { + "isarray": "1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ignore": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/internal-slot": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", + "integrity": "sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", + "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.0", + "is-typed-array": "^1.1.10" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + }, + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.0.tgz", + "integrity": "sha512-RECHCBCd/viahWmwj6enj19sKbHfJrddi/6cBDsNTKbNq0f7VeaUkBo60BqzvPqo/W54ChS62Z5qyun7cfOMqQ==", + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", + "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz", + "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jiti": { + "version": "1.18.2", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.18.2.tgz", + "integrity": "sha512-QAdOptna2NYiSSpv0O/BwoHBSmz4YhpzJHyi+fnMRTXFjp7B8i/YG5Z8IfusxB1ufjcD2Sre1F3R+nX3fvy7gg==", + "bin": { + "jiti": "bin/jiti.js" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsx-ast-utils": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.3.tgz", + "integrity": "sha512-fYQHZTZ8jSfmWZ0iyzfwiU4WDX4HpHbMCZ3gPlWYiCl3BoeOTsqKBqnTVfH2rYT7eP5c3sVbeSPHnnJOaTrWiw==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.5", + "object.assign": "^4.1.3" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lilconfig": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", + "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", + "engines": { + "node": ">=10" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/magic-string": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.27.0.tgz", + "integrity": "sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==", + "dev": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.13" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", + "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node_modules/node-releases": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz", + "integrity": "sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==" + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/object-inspect": { + "version": "1.12.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", + "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", + "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.entries": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.6.tgz", + "integrity": "sha512-leTPzo4Zvg3pmbQ3rDK69Rl8GQvIqMWubrkxONG9/ojtFE2rD9fjMKfSI5BxW3osRH1m6VdzmqK8oAY9aT4x5w==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.6.tgz", + "integrity": "sha512-VciD13dswC4j1Xt5394WR4MzmAQmlgN72phd/riNp9vtD7tp4QQWJ0R4wvclXcafgcYK8veHRed2W6XeGBvcfg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.hasown": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.2.tgz", + "integrity": "sha512-B5UIT3J1W+WuWIU55h0mjlwaqxiE5vYENJXIXZ4VFe05pNYrkKuK0U/6aFcb0pKywYJh7IhfoqUfKVmrJJHZHw==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.values": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.6.tgz", + "integrity": "sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/omit-deep": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/omit-deep/-/omit-deep-0.3.0.tgz", + "integrity": "sha512-Lbl/Ma59sss2b15DpnWnGmECBRL8cRl/PjPbPMVW+Y8zIQzRrwMaI65Oy6HvxyhYeILVKBJb2LWeG81bj5zbMg==", + "dependencies": { + "is-plain-object": "^2.0.1", + "unset-value": "^0.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pirates": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", + "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/postcss": { + "version": "8.4.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.23.tgz", + "integrity": "sha512-bQ3qMcpF6A/YjR55xtoTr0jGOlnPOKAIMdOWiv0EIT6HVPEaJiJB4NLljSbiHoC2RX7DN5Uvjtpbg1NPdwv1oA==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-import": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-14.1.0.tgz", + "integrity": "sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw==", + "dependencies": { + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + }, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-js": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", + "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", + "dependencies": { + "camelcase-css": "^2.0.1" + }, + "engines": { + "node": "^12 || ^14 || >= 16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.4.21" + } + }, + "node_modules/postcss-load-config": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-3.1.4.tgz", + "integrity": "sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==", + "dependencies": { + "lilconfig": "^2.0.5", + "yaml": "^1.10.2" + }, + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": ">=8.0.9", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "postcss": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/postcss-nested": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.0.tgz", + "integrity": "sha512-0DkamqrPcmkBDsLn+vQDIrtkSbNkv5AD/M322ySo9kqFkCIYklym2xEmWkwo+Y3/qZo34tzEPNUw4y7yMCdv5w==", + "dependencies": { + "postcss-selector-parser": "^6.0.10" + }, + "engines": { + "node": ">=12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.2.14" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.0.11", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.11.tgz", + "integrity": "sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g==", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dev": true, + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, + "node_modules/punycode": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/pure-color": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/pure-color/-/pure-color-1.3.0.tgz", + "integrity": "sha512-QFADYnsVoBMw1srW7OVKEYjG+MbIa49s54w1MA1EDY6r2r/sTcKKYqRX1f4GYvnXP7eN/Pe9HFcX+hwzmrXRHA==" + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/react": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", + "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", + "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.0" + }, + "peerDependencies": { + "react": "^18.2.0" + } + }, + "node_modules/react-from-dom": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/react-from-dom/-/react-from-dom-0.6.2.tgz", + "integrity": "sha512-qvWWTL/4xw4k/Dywd41RBpLQUSq97csuv15qrxN+izNeLYlD9wn5W8LspbfYe5CWbaSdkZ72BsaYBPQf2x4VbQ==", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/react-inlinesvg": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/react-inlinesvg/-/react-inlinesvg-3.0.2.tgz", + "integrity": "sha512-BEzkpMGQwEY68fgaouY7ZWvAUPb8jbj7dE9iDbWZxstDhMuz9qfpxNgvGSENKcDMdpq/XHduSk/LAmNKin4nKw==", + "dependencies": { + "exenv": "^1.2.2", + "react-from-dom": "^0.6.2" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "dev": true + }, + "node_modules/react-refresh": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.0.tgz", + "integrity": "sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-remove-scroll": { + "version": "2.5.5", + "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.5.5.tgz", + "integrity": "sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw==", + "dependencies": { + "react-remove-scroll-bar": "^2.3.3", + "react-style-singleton": "^2.2.1", + "tslib": "^2.1.0", + "use-callback-ref": "^1.3.0", + "use-sidecar": "^1.1.2" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-remove-scroll-bar": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.4.tgz", + "integrity": "sha512-63C4YQBUt0m6ALadE9XV56hV8BgJWDmmTPY758iIJjfQKt2nYwoUrPk0LXRXcB/yIj82T1/Ixfdpdk68LwIB0A==", + "dependencies": { + "react-style-singleton": "^2.2.1", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-router": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.10.0.tgz", + "integrity": "sha512-Nrg0BWpQqrC3ZFFkyewrflCud9dio9ME3ojHCF/WLsprJVzkq3q3UeEhMCAW1dobjeGbWgjNn/PVF6m46ANxXQ==", + "dependencies": { + "@remix-run/router": "1.5.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "react": ">=16.8" + } + }, + "node_modules/react-router-dom": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.10.0.tgz", + "integrity": "sha512-E5dfxRPuXKJqzwSe/qGcqdwa18QiWC6f3H3cWXM24qj4N0/beCIf/CWTipop2xm7mR0RCS99NnaqPNjHtrAzCg==", + "dependencies": { + "@remix-run/router": "1.5.0", + "react-router": "6.10.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "react": ">=16.8", + "react-dom": ">=16.8" + } + }, + "node_modules/react-style-singleton": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.1.tgz", + "integrity": "sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==", + "dependencies": { + "get-nonce": "^1.0.0", + "invariant": "^2.2.4", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-use-draggable-scroll": { + "version": "0.4.7", + "resolved": "https://registry.npmjs.org/react-use-draggable-scroll/-/react-use-draggable-scroll-0.4.7.tgz", + "integrity": "sha512-6gCxGPO9WV5dIsBaDrgUKBaac8CY07PkygcArfajijYSNDwAq0girDRjaBuF1+lRqQryoLFQfpVaV2u/Yh6CrQ==", + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "react": ">=16" + } + }, + "node_modules/read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "dependencies": { + "pify": "^2.3.0" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.13.11", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz", + "integrity": "sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "functions-have-names": "^1.2.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/rename-keys": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/rename-keys/-/rename-keys-1.2.0.tgz", + "integrity": "sha512-U7XpAktpbSgHTRSNRrjKSrjYkZKuhUukfoBlXWXUExCAqhzh1TU3BDRAfJmarcl5voKS+pbKU9MvyLWKZ4UEEg==", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/resolve": { + "version": "1.22.2", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz", + "integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==", + "dependencies": { + "is-core-module": "^2.11.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rollup": { + "version": "3.20.7", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.20.7.tgz", + "integrity": "sha512-P7E2zezKSLhWnTz46XxjSmInrbOCiul1yf+kJccMxT56vxjHwCbDfoLbiqFgu+WQoo9ij2PkraYaBstgB2prBA==", + "dev": true, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=14.18.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-regex-test": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", + "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "is-regex": "^1.1.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/scheduler": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", + "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, + "node_modules/source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/string.prototype.matchall": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.8.tgz", + "integrity": "sha512-6zOCOcJ+RJAQshcTvXPHoxoQGONa3e/Lqx90wUA+wEzX78sg5Bo+1tQo4N0pohS0erG9qtCqJDjNCQBjeWVxyg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "get-intrinsic": "^1.1.3", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.3", + "regexp.prototype.flags": "^1.4.3", + "side-channel": "^1.0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz", + "integrity": "sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz", + "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz", + "integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/sucrase": { + "version": "3.32.0", + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.32.0.tgz", + "integrity": "sha512-ydQOU34rpSyj2TGyz4D2p8rbktIOZ8QY9s+DGLvFU1i5pWJE8vkpruCjGCMHsdXwnD7JDcS+noSwM/a7zyNFDQ==", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "glob": "7.1.6", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "ts-interface-checker": "^0.1.9" + }, + "bin": { + "sucrase": "bin/sucrase", + "sucrase-node": "bin/sucrase-node" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/svgson": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/svgson/-/svgson-5.2.1.tgz", + "integrity": "sha512-nbM6QuyZiKzQ0Uo51VDta93YJAr96ikyT40PsgJRrzynOGsOlnmJ6zAK5hUFyE5gnxcg7yuOPUWbUlmV9K0+Dg==", + "dependencies": { + "deep-rename-keys": "^0.2.1", + "omit-deep": "0.3.0", + "xml-reader": "2.4.3" + } + }, + "node_modules/tailwind-merge": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-1.12.0.tgz", + "integrity": "sha512-Y17eDp7FtN1+JJ4OY0Bqv9OA41O+MS8c1Iyr3T6JFLnOgLg3EvcyMKZAnQ8AGyvB5Nxm3t9Xb5Mhe139m8QT/g==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/dcastil" + } + }, + "node_modules/tailwind-scrollbar-hide": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/tailwind-scrollbar-hide/-/tailwind-scrollbar-hide-1.1.7.tgz", + "integrity": "sha512-X324n9OtpTmOMqEgDUEA/RgLrNfBF/jwJdctaPZDzB3mppxJk7TLIDmOreEDm1Bq4R9LSPu4Epf8VSdovNU+iA==" + }, + "node_modules/tailwindcss": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.3.1.tgz", + "integrity": "sha512-Vkiouc41d4CEq0ujXl6oiGFQ7bA3WEhUZdTgXAhtKxSy49OmKs8rEfQmupsfF0IGW8fv2iQkp1EVUuapCFrZ9g==", + "dependencies": { + "arg": "^5.0.2", + "chokidar": "^3.5.3", + "color-name": "^1.1.4", + "didyoumean": "^1.2.2", + "dlv": "^1.1.3", + "fast-glob": "^3.2.12", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "jiti": "^1.17.2", + "lilconfig": "^2.0.6", + "micromatch": "^4.0.5", + "normalize-path": "^3.0.0", + "object-hash": "^3.0.0", + "picocolors": "^1.0.0", + "postcss": "^8.0.9", + "postcss-import": "^14.1.0", + "postcss-js": "^4.0.0", + "postcss-load-config": "^3.1.4", + "postcss-nested": "6.0.0", + "postcss-selector-parser": "^6.0.11", + "postcss-value-parser": "^4.2.0", + "quick-lru": "^5.1.1", + "resolve": "^1.22.1", + "sucrase": "^3.29.0" + }, + "bin": { + "tailwind": "lib/cli.js", + "tailwindcss": "lib/cli.js" + }, + "engines": { + "node": ">=12.13.0" + }, + "peerDependencies": { + "postcss": "^8.0.9" + } + }, + "node_modules/tailwindcss/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/tmp": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", + "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "dependencies": { + "rimraf": "^3.0.0" + }, + "engines": { + "node": ">=8.17.0" + } + }, + "node_modules/tmp-promise": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/tmp-promise/-/tmp-promise-3.0.3.tgz", + "integrity": "sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ==", + "dependencies": { + "tmp": "^0.2.0" + } + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/ts-interface-checker": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==" + }, + "node_modules/tslib": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz", + "integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==" + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", + "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "is-typed-array": "^1.1.9" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typescript": { + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/unset-value": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-0.1.2.tgz", + "integrity": "sha512-yhv5I4TsldLdE3UcVQn0hD2T5sNCPv4+qm/CTUpRKIpwthYRIipsAPdsrNpOI79hPQa0rTTeW22Fq6JWRcTgNg==", + "dependencies": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", + "integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/use-callback-ref": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.0.tgz", + "integrity": "sha512-3FT9PRuRdbB9HfXhEq35u4oZkvpJ5kuYbpqhCfmiZyReuRgpnhDlbr2ZEnnuS0RrJAPn6l23xjFg9kpDM+Ms7w==", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/use-sidecar": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.2.tgz", + "integrity": "sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==", + "dependencies": { + "detect-node-es": "^1.1.0", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "^16.9.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/use-sync-external-store": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", + "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "node_modules/vite": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.3.1.tgz", + "integrity": "sha512-EPmfPLAI79Z/RofuMvkIS0Yr091T2ReUoXQqc5ppBX/sjFRhHKiPPF/R46cTdoci/XgeQpB23diiJxq5w30vdg==", + "dev": true, + "dependencies": { + "esbuild": "^0.17.5", + "postcss": "^8.4.21", + "rollup": "^3.20.2" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + }, + "peerDependencies": { + "@types/node": ">= 14", + "less": "*", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vite-plugin-eslint": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/vite-plugin-eslint/-/vite-plugin-eslint-1.8.1.tgz", + "integrity": "sha512-PqdMf3Y2fLO9FsNPmMX+//2BF5SF8nEWspZdgl4kSt7UvHDRHVVfHvxsD7ULYzZrJDGRxR81Nq7TOFgwMnUang==", + "dev": true, + "dependencies": { + "@rollup/pluginutils": "^4.2.1", + "@types/eslint": "^8.4.5", + "rollup": "^2.77.2" + }, + "peerDependencies": { + "eslint": ">=7", + "vite": ">=2" + } + }, + "node_modules/vite-plugin-eslint/node_modules/rollup": { + "version": "2.79.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", + "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==", + "dev": true, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=10.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz", + "integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "node_modules/xml-lexer": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/xml-lexer/-/xml-lexer-0.2.2.tgz", + "integrity": "sha512-G0i98epIwiUEiKmMcavmVdhtymW+pCAohMRgybyIME9ygfVu8QheIi+YoQh3ngiThsT0SQzJT4R0sKDEv8Ou0w==", + "dependencies": { + "eventemitter3": "^2.0.0" + } + }, + "node_modules/xml-reader": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/xml-reader/-/xml-reader-2.4.3.tgz", + "integrity": "sha512-xWldrIxjeAMAu6+HSf9t50ot1uL5M+BtOidRCWHXIeewvSeIpscWCsp4Zxjk8kHHhdqFBrfK8U0EJeCcnyQ/gA==", + "dependencies": { + "eventemitter3": "^2.0.0", + "xml-lexer": "^0.2.2" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zustand": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-4.3.7.tgz", + "integrity": "sha512-dY8ERwB9Nd21ellgkBZFhudER8KVlelZm8388B5nDAXhO/+FZDhYMuRnqDgu5SYyRgz/iaf8RKnbUs/cHfOGlQ==", + "dependencies": { + "use-sync-external-store": "1.2.0" + }, + "engines": { + "node": ">=12.7.0" + }, + "peerDependencies": { + "immer": ">=9.0", + "react": ">=16.8" + }, + "peerDependenciesMeta": { + "immer": { + "optional": true + }, + "react": { + "optional": true + } + } + } + } +} diff --git a/04-poke-battle-with-prisma/frontend/package.json b/04-poke-battle-with-prisma/frontend/package.json new file mode 100644 index 0000000..32773dc --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/package.json @@ -0,0 +1,45 @@ +{ + "name": "expressots-with-prisma-orm-fronted", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "tsc && vite build", + "preview": "vite preview" + }, + "dependencies": { + "@dicebear/avatars": "^4.10.8", + "@dicebear/collection": "^6.0.3", + "@dicebear/core": "^6.0.3", + "@heroicons/react": "^2.0.18", + "@radix-ui/react-dropdown-menu": "^2.0.5", + "@radix-ui/react-slot": "^1.0.1", + "@tanstack/react-query": "^4.29.3", + "axios": "^1.3.6", + "clsx": "^1.2.1", + "daisyui": "^2.51.5", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-inlinesvg": "^3.0.2", + "react-router-dom": "^6.10.0", + "react-use-draggable-scroll": "^0.4.7", + "tailwind-merge": "^1.12.0", + "tailwind-scrollbar-hide": "^1.1.7", + "zustand": "^4.3.7" + }, + "devDependencies": { + "@types/react": "^18.0.28", + "@types/react-dom": "^18.0.11", + "@vitejs/plugin-react": "^3.1.0", + "autoprefixer": "^10.4.14", + "eslint": "^8.41.0", + "eslint-plugin-react": "^7.32.2", + "eslint-plugin-react-hooks": "^4.6.0", + "postcss": "^8.4.23", + "tailwindcss": "^3.3.1", + "typescript": "^4.9.3", + "vite": "^4.2.0", + "vite-plugin-eslint": "^1.8.1" + } +} diff --git a/04-poke-battle-with-prisma/frontend/postcss.config.js b/04-poke-battle-with-prisma/frontend/postcss.config.js new file mode 100644 index 0000000..2e7af2b --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/postcss.config.js @@ -0,0 +1,6 @@ +export default { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +} diff --git a/04-poke-battle-with-prisma/frontend/public/vite.svg b/04-poke-battle-with-prisma/frontend/public/vite.svg new file mode 100644 index 0000000..e7b8dfb --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/public/vite.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/04-poke-battle-with-prisma/frontend/src/api/requester.ts b/04-poke-battle-with-prisma/frontend/src/api/requester.ts new file mode 100644 index 0000000..b61aefc --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/src/api/requester.ts @@ -0,0 +1,64 @@ +import axios, { AxiosRequestConfig, AxiosResponse } from "axios"; + +export const requester = ( + config?: AxiosRequestConfig, + contentType?: string, +) => { + const service = axios.create({ + baseURL: import.meta.env.VITE_BACKEND_URL || config?.baseURL, + ...config, + }); + + service.interceptors.request.use( + (req) => { + // @ts-expect-error + req.headers = { + "Content-Type": contentType || "application/json", + ...config?.headers, + }; + + return req; + }, + (error) => Promise.reject(error), + ); + + service.interceptors.response.use( + (res) => res, + (error) => { + const url = window.location.pathname; + + if ( + error.response.status === 401 && + url !== "/logout" && + url.includes("/trainer") + ) { + window.location.href = "/logout"; + } + + return Promise.reject(error); + }, + ); + + return { + async get(uri: string): Promise> { + const response = await service.get(uri); + return response; + }, + async post(uri: string, data: unknown): Promise> { + const response = await service.post(uri, data); + return response; + }, + async put(uri: string, data: unknown): Promise> { + const response = await service.put(uri, data); + return response; + }, + async patch(uri: string, data: unknown): Promise> { + const response = await service.patch(uri, data); + return response; + }, + async delete(uri: string, data: unknown): Promise> { + const response = await service.delete(uri, { data }); + return response; + }, + }; +}; diff --git a/04-poke-battle-with-prisma/frontend/src/assets/expressoicon.svg b/04-poke-battle-with-prisma/frontend/src/assets/expressoicon.svg new file mode 100644 index 0000000..627b79f --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/src/assets/expressoicon.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/04-poke-battle-with-prisma/frontend/src/components/Atoms/AvatarOptions/index.tsx b/04-poke-battle-with-prisma/frontend/src/components/Atoms/AvatarOptions/index.tsx new file mode 100644 index 0000000..40a3781 --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/src/components/Atoms/AvatarOptions/index.tsx @@ -0,0 +1,50 @@ +import { useCallback, useEffect, useMemo } from "react"; + +import Svg from "react-inlinesvg"; +import clsx from "clsx"; + +// icons +import { ArrowLeftIcon, ArrowRightIcon } from "@heroicons/react/24/outline"; + +// types +import type { TAvatarOptionsSelector } from "./types"; +import DraggableItems from "../../Molecules/DragabbleItems"; + +const AvatarOptionSelector = ({ + currentOption, + label, + options, + setCurrentOption, + preview, + optionKey, + disabled, +}: TAvatarOptionsSelector) => { + return ( +
+ {label &&

{label}

} + + {options.map((option) => { + return ( + + ); + })} + +
+ ); +}; + +export default AvatarOptionSelector; diff --git a/04-poke-battle-with-prisma/frontend/src/components/Atoms/AvatarOptions/types.ts b/04-poke-battle-with-prisma/frontend/src/components/Atoms/AvatarOptions/types.ts new file mode 100644 index 0000000..a9bf616 --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/src/components/Atoms/AvatarOptions/types.ts @@ -0,0 +1,11 @@ +import { Dispatch, SetStateAction } from "react"; + +export type TAvatarOptionsSelector = { + options: T[]; + label?: string; + currentOption: string[]; + setCurrentOption: Dispatch>; + preview: any; + optionKey: string; + disabled?: boolean; +}; diff --git a/04-poke-battle-with-prisma/frontend/src/components/Atoms/Button/index.tsx b/04-poke-battle-with-prisma/frontend/src/components/Atoms/Button/index.tsx new file mode 100644 index 0000000..a9324ef --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/src/components/Atoms/Button/index.tsx @@ -0,0 +1,29 @@ +import { forwardRef } from "react"; +import { twMerge } from "tailwind-merge"; +import { Slot } from "@radix-ui/react-slot"; + +// types +import type { TButton } from "./types"; + +// :: +const Button = forwardRef( + ({ children, asChild = false, className, ...rest }, ref) => { + const Component = asChild ? Slot : "button"; + return ( + + {children} + + ); + }, +); + +Button.displayName = "Button"; + +export default Button; diff --git a/04-poke-battle-with-prisma/frontend/src/components/Atoms/Button/types.ts b/04-poke-battle-with-prisma/frontend/src/components/Atoms/Button/types.ts new file mode 100644 index 0000000..f0ad43b --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/src/components/Atoms/Button/types.ts @@ -0,0 +1,6 @@ +import { ButtonHTMLAttributes, ReactNode } from "react"; + +export type TButton = { + children?: ReactNode; + asChild?: boolean +} & ButtonHTMLAttributes; diff --git a/04-poke-battle-with-prisma/frontend/src/components/Atoms/CollapseRow/index.tsx b/04-poke-battle-with-prisma/frontend/src/components/Atoms/CollapseRow/index.tsx new file mode 100644 index 0000000..c2a8387 --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/src/components/Atoms/CollapseRow/index.tsx @@ -0,0 +1,102 @@ +import { useRef, useState } from "react"; +import { useOnClickOutside } from "../../../hooks/useOnClickOutside"; +import { THistoryBattleResponse } from "../../../service/types"; +import { clsxm } from "../../../utils/clsxm"; + +const CollapseRow = ({ + isDraw, + log, + pokemon1, + pokemon2, + winner, + isOpen = false, +}: { isOpen?: boolean } & Omit< + THistoryBattleResponse, + "loserName" | "playerId" | "userName" | "winnerName" | "id" +>) => { + const [collapseToggle, setCollapseToggle] = useState(isOpen); + const ref = useRef(null); + useOnClickOutside(ref, () => setCollapseToggle(false)); + + return ( +
+
setCollapseToggle(!collapseToggle)} + className={clsxm( + "cursor-pointer w-full flex items-start justify-between", + )} + > +
+

+ {pokemon1.name}{" "} + VS{" "} + {pokemon2.name} +

+
+ {pokemon1.name} + {pokemon2.name} +
+
+
+

+ {isDraw ? "Draw" : `${!winner ? "Defeat" : "Winner"}`} +

+

Turns: {Math.floor((log.length + 1) / 2)}

+
+
+
+
+ {log.map((log) => ( +
+

Turn: {log.turn}

+

{`${log.attacker} used ${log.attack}`}

+

{`${log.defender} received ${log.damage} damage!`}

+
+ ))} +
+
+
+ ); +}; + +export default CollapseRow; diff --git a/04-poke-battle-with-prisma/frontend/src/components/Atoms/Header/index.tsx b/04-poke-battle-with-prisma/frontend/src/components/Atoms/Header/index.tsx new file mode 100644 index 0000000..84b69a7 --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/src/components/Atoms/Header/index.tsx @@ -0,0 +1,11 @@ +import { THeaderProps } from "./types"; + +const Header = ({ children }: THeaderProps) => { + return ( +
+
{children}
+
+ ); +}; + +export default Header; diff --git a/04-poke-battle-with-prisma/frontend/src/components/Atoms/Header/types.ts b/04-poke-battle-with-prisma/frontend/src/components/Atoms/Header/types.ts new file mode 100644 index 0000000..52345c9 --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/src/components/Atoms/Header/types.ts @@ -0,0 +1,5 @@ +import { ReactNode } from "react"; + +export type THeaderProps = { + children: ReactNode; +}; diff --git a/04-poke-battle-with-prisma/frontend/src/components/Atoms/Input/index.tsx b/04-poke-battle-with-prisma/frontend/src/components/Atoms/Input/index.tsx new file mode 100644 index 0000000..74c52bd --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/src/components/Atoms/Input/index.tsx @@ -0,0 +1,47 @@ +import { useId, useRef } from "react"; +import { twMerge } from "tailwind-merge"; + +// types +import type { TInput } from "./types"; +import { clsxm } from "../../../utils/clsxm"; + +// :: +const Input = ({ label, classLabel, className, ...rest }: TInput) => { + const inputRef = useRef(null); + const inputId = useId(); + + const handleInputClick = () => { + inputRef.current?.focus(); + }; + + return ( +
+ + {label && ( + + )} +
+ ); +}; + +export default Input; diff --git a/04-poke-battle-with-prisma/frontend/src/components/Atoms/Input/types.ts b/04-poke-battle-with-prisma/frontend/src/components/Atoms/Input/types.ts new file mode 100644 index 0000000..48af255 --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/src/components/Atoms/Input/types.ts @@ -0,0 +1,6 @@ +import { InputHTMLAttributes } from "react"; + +export type TInput = { + label?: string; + classLabel?: string; +} & InputHTMLAttributes; diff --git a/04-poke-battle-with-prisma/frontend/src/components/Atoms/LoadingStatus/index.tsx b/04-poke-battle-with-prisma/frontend/src/components/Atoms/LoadingStatus/index.tsx new file mode 100644 index 0000000..62c3eca --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/src/components/Atoms/LoadingStatus/index.tsx @@ -0,0 +1,30 @@ +// types +import type { TLoadingStatus } from "./types"; + +// :: +const LoadingStatus = ({ size = 20 }: TLoadingStatus) => { + return ( + + + + + ); +}; + +export default LoadingStatus; diff --git a/04-poke-battle-with-prisma/frontend/src/components/Atoms/LoadingStatus/types.ts b/04-poke-battle-with-prisma/frontend/src/components/Atoms/LoadingStatus/types.ts new file mode 100644 index 0000000..6ff1825 --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/src/components/Atoms/LoadingStatus/types.ts @@ -0,0 +1,3 @@ +export type TLoadingStatus = { + size?: number; +}; diff --git a/04-poke-battle-with-prisma/frontend/src/components/Atoms/PokemonCard/index.tsx b/04-poke-battle-with-prisma/frontend/src/components/Atoms/PokemonCard/index.tsx new file mode 100644 index 0000000..876e03f --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/src/components/Atoms/PokemonCard/index.tsx @@ -0,0 +1,76 @@ +import { KeyboardEvent } from "react"; +import { TCardPokemonProps } from "./type"; +import { clsxm } from "../../../utils/clsxm"; + +const PokemonCard = ({ + name, + player1Selected, + player2Selected, + sprite, + states, + type, + handleClickPokemon, +}: TCardPokemonProps) => { + const handleKeyDown = (event: KeyboardEvent) => { + if (event.key === "Enter") { + handleClickPokemon(); + } + }; + + return ( +
+
+

{name}

+
+
+ {`pokemon +
+

Type

+
+ {type.map((item) => ( +

+ {item.type.name} +

+ ))} +
+

Status

+
+ {states.map((stat) => ( +

+ {stat.stat.name}-{stat.base_stat} +

+ ))} +
+
+ ); +}; + +export default PokemonCard; diff --git a/04-poke-battle-with-prisma/frontend/src/components/Atoms/PokemonCard/type.ts b/04-poke-battle-with-prisma/frontend/src/components/Atoms/PokemonCard/type.ts new file mode 100644 index 0000000..ae6d202 --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/src/components/Atoms/PokemonCard/type.ts @@ -0,0 +1,12 @@ +import { PokemonStats, TPokemonContentEndpoint } from "../../../types"; +import { PokemonTypes } from "../../../types"; + +export type TCardPokemonProps = { + player1Selected: boolean; + player2Selected: boolean; + name: string; + sprite: string; + type: PokemonTypes[]; + states: PokemonStats[]; + handleClickPokemon: () => void; +}; diff --git a/04-poke-battle-with-prisma/frontend/src/components/Atoms/Sidebar/index.tsx b/04-poke-battle-with-prisma/frontend/src/components/Atoms/Sidebar/index.tsx new file mode 100644 index 0000000..7a97db5 --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/src/components/Atoms/Sidebar/index.tsx @@ -0,0 +1,28 @@ +import { TSidebarProps } from "./type"; +import { twMerge } from "tailwind-merge"; + +const Sidebar = ({ children, className }: TSidebarProps) => { + return ( +
+
+ {children} +
+
+

+ This app made with{" "} + + ExpressoTS + +

+
+
+ ); +}; + +export default Sidebar; diff --git a/04-poke-battle-with-prisma/frontend/src/components/Atoms/Sidebar/type.ts b/04-poke-battle-with-prisma/frontend/src/components/Atoms/Sidebar/type.ts new file mode 100644 index 0000000..0d835c8 --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/src/components/Atoms/Sidebar/type.ts @@ -0,0 +1,6 @@ +import { ReactNode } from "react"; + +export type TSidebarProps = { + children: ReactNode; + className?: string; +}; diff --git a/04-poke-battle-with-prisma/frontend/src/components/Atoms/StatusCard/index.tsx b/04-poke-battle-with-prisma/frontend/src/components/Atoms/StatusCard/index.tsx new file mode 100644 index 0000000..5d0d861 --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/src/components/Atoms/StatusCard/index.tsx @@ -0,0 +1,40 @@ +import clsx from "clsx"; +import { useMemo } from "react"; +import { TCardStatus } from "./types"; +import { + CheckCircleIcon, + ExclamationCircleIcon, + InformationCircleIcon, + XCircleIcon, +} from "@heroicons/react/24/outline"; + +const StatusCard = ({ description, type, title }: TCardStatus) => { + const icon = { + error: XCircleIcon, + warning: ExclamationCircleIcon, + success: CheckCircleIcon, + info: InformationCircleIcon, + }; + + const RenderIcon = useMemo(() => icon[type], [type]); + + return ( +
+
+ +

{title}

+
+

{description}

+
+ ); +}; + +export default StatusCard; diff --git a/04-poke-battle-with-prisma/frontend/src/components/Atoms/StatusCard/types.ts b/04-poke-battle-with-prisma/frontend/src/components/Atoms/StatusCard/types.ts new file mode 100644 index 0000000..77860ce --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/src/components/Atoms/StatusCard/types.ts @@ -0,0 +1,5 @@ +export type TCardStatus = { + type: "error" | "info" | "warning" | "success"; + description: string; + title?: string; +}; diff --git a/04-poke-battle-with-prisma/frontend/src/components/Atoms/ThemeSelector/index.tsx b/04-poke-battle-with-prisma/frontend/src/components/Atoms/ThemeSelector/index.tsx new file mode 100644 index 0000000..5e8dba6 --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/src/components/Atoms/ThemeSelector/index.tsx @@ -0,0 +1,50 @@ +import React from "react"; +import { SwatchIcon } from "@heroicons/react/24/outline"; +import * as DropdownMenu from "@radix-ui/react-dropdown-menu"; +import { twMerge } from "tailwind-merge"; +import { themes } from "../../../themes"; +import { useTheme, useThemeActions } from "../../../store"; + +const ThemeSelector = () => { + const selectedTheme = useTheme(); + const { setTheme } = useThemeActions(); + + return ( + + + + + + + + {themes.map((theme) => ( + + + + ))} + + + + ); +}; + +export default ThemeSelector; diff --git a/04-poke-battle-with-prisma/frontend/src/components/Molecules/BattleHistory/index.tsx b/04-poke-battle-with-prisma/frontend/src/components/Molecules/BattleHistory/index.tsx new file mode 100644 index 0000000..a9429c8 --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/src/components/Molecules/BattleHistory/index.tsx @@ -0,0 +1,56 @@ +import { useMemo } from "react"; +import { TBattleHistory } from "./types"; +import { CollapseRow, StatusCard } from "../../"; + +const BattleHistory = ({ error, history, loading }: TBattleHistory) => { + const isEmpty = useMemo(() => history?.length === 0, [history]); + + if (loading) { + return ( +
+ {Array.from({ length: 5 }).map((_, index) => ( +
+ ))} +
+ ); + } + + if (error) { + return ( + + ); + } + if (isEmpty) { + return ( + + ); + } + return ( +
+ {history?.map((match) => ( + + ))} +
+ ); +}; + +export default BattleHistory; diff --git a/04-poke-battle-with-prisma/frontend/src/components/Molecules/BattleHistory/types.ts b/04-poke-battle-with-prisma/frontend/src/components/Molecules/BattleHistory/types.ts new file mode 100644 index 0000000..154ded0 --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/src/components/Molecules/BattleHistory/types.ts @@ -0,0 +1,7 @@ +import { THistoryBattleResponse } from "../../../service/types"; + +export type TBattleHistory = { + history: THistoryBattleResponse[] | undefined; + loading: boolean; + error: boolean; +}; diff --git a/04-poke-battle-with-prisma/frontend/src/components/Molecules/CustomAvatar/index.tsx b/04-poke-battle-with-prisma/frontend/src/components/Molecules/CustomAvatar/index.tsx new file mode 100644 index 0000000..95c9db3 --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/src/components/Molecules/CustomAvatar/index.tsx @@ -0,0 +1,344 @@ +import { useCallback, useEffect, useMemo, useState } from "react"; +import { stringify } from "qs"; +import { createAvatar } from "@dicebear/core"; +import * as style from "@dicebear/adventurer"; +import Svg from "react-inlinesvg"; + +// types + +// zustand: hooks +import { useUser } from "../../../store"; + +// recoil: atoms +import AvatarOptionSelector from "../../Atoms/AvatarOptions"; + +// constants +import { + AVATAR_EYES, + AVATAR_FEATURES, + AVATAR_GLASSES, + AVATAR_HAIR, + AVATAR_HAIR_COLOR, + AVATAR_MOUTH, + AVATAR_SKIN_COLOR, + AVATAR_BACKGROUNDCOLOR, + AVATAR_EARRINGS, + AVATAR_EYEBROWS, +} from "./options"; + +import { + TAvatarBackgroundColor, + TAvatarEarrings, + TAvatarEyebrows, + TAvatarEyes, + TAvatarFeatures, + TAvatarGlasses, + TAvatarHair, + TAvatarHairColor, + TAvatarMouth, + TAvatarSkinColor, +} from "../../../types"; +import { TCustomAvatarProps } from "./types"; +import { ChevronUpDownIcon, HandRaisedIcon } from "@heroicons/react/24/outline"; +import clsx from "clsx"; +import { defaultAvatarEnum } from "../../../utils/enums"; + +// :: +const CustomAvatar = ({ + seed = "ExpressoTS", + setConstructAvatar, +}: TCustomAvatarProps) => { + // CONSTANTS + const AVATAR_BASE_URL = "https://api.dicebear.com/6.x/adventurer"; + + // local: states + const [eyes, setEyes] = useState(defaultAvatarEnum.eyes); + const [eyebrows, setEyesBrows] = useState( + defaultAvatarEnum.eyebrows, + ); + const [mouth, setMouth] = useState(defaultAvatarEnum.mouth); + const [skinColor, setSkinColor] = useState( + defaultAvatarEnum.skinColor, + ); + const [earrings, setEarrings] = useState( + defaultAvatarEnum.earrings, + ); + const [backgroundColor, setBackgroundColor] = + useState(defaultAvatarEnum.backgroundColor); + const [features, setFeatures] = useState( + defaultAvatarEnum.features, + ); + const [glasses, setGlasses] = useState( + defaultAvatarEnum.glasses, + ); + const [hair, setHair] = useState(defaultAvatarEnum.hair); + const [hairColor, setHairColor] = useState( + defaultAvatarEnum.hairColor, + ); + const [earringsProbability, setEarringsProbability] = useState<0 | 100>( + defaultAvatarEnum.earringsProbability, + ); + const [glassesProbability, setGlassesProbability] = useState<0 | 100>( + defaultAvatarEnum.glassesProbability, + ); + const [featuresProbability, setFeaturesProbability] = useState<0 | 100>( + defaultAvatarEnum.featuresProbability, + ); + const [customToggle, setCustomToggle] = useState(false); + + // zustand: states + const user = useUser(); + + const handleToggleCheck = (bool: boolean) => { + return bool ? 100 : (0 as 0 | 100); + }; + + const avatarOptions = useMemo( + () => ({ + backgroundColor: [backgroundColor], + earrings: [earrings], + earringsProbability, + glassesProbability, + featuresProbability, + hairProbability: 100, + eyebrows: [eyebrows], + eyes: [eyes], + features: [features], + glasses: [glasses], + hair: [hair], + hairColor: [hairColor], + mouth: [mouth], + seed, + skinColor: [skinColor], + flip: true, + }), + [ + backgroundColor, + earrings, + earringsProbability, + eyebrows, + eyes, + features, + featuresProbability, + glasses, + glassesProbability, + hair, + hairColor, + mouth, + seed, + skinColor, + ], + ); + + const avatar = useCallback(() => { + return createAvatar(style, avatarOptions); + }, [avatarOptions]); + + function setKeyValuePair(key: K, value: V) { + // eslint-disable-next-line no-unused-vars + return { [key]: value } as { [key in K]: V }; + } + + const avatarPreview = useCallback( + (key: K, value: V) => { + const avatarOptionsWithKeyValue = setKeyValuePair(key, value); + return createAvatar(style, { + ...avatarOptions, + ...avatarOptionsWithKeyValue, + }); + }, + [avatarOptions], + ); + + useEffect(() => { + if (user?.avatar) { + setSkinColor(user?.avatar?.skinColor); + setEyes(user?.avatar?.eyes); + setEyesBrows(user?.avatar?.eyebrows); + setMouth(user?.avatar?.mouth); + setEarrings(user?.avatar?.earrings || "variant01"); + setGlasses(user?.avatar?.glasses || "variant01"); + setHair(user?.avatar?.hair); + setHairColor(user?.avatar?.hairColor); + setBackgroundColor(user?.avatar?.backgroundColor); + setFeatures(user?.avatar?.features || "birthmark"); + setEarringsProbability(user?.avatar?.earringsProbability); + setGlassesProbability(user?.avatar.glassesProbability); + setFeaturesProbability(user?.avatar.featuresProbability); + } + }, [user]); + + useEffect(() => { + setConstructAvatar({ + backgroundColor, + earrings, + earringsProbability, + eyebrows, + eyes, + features, + featuresProbability, + flip: true, + glasses, + glassesProbability, + hair, + hairColor, + hairProbability: 100, + mouth, + seed, + skinColor, + }); + }, [avatarOptions]); + + return ( +
+
+
+ + +
+
+

+ + Drag to the side +

+ + + + + + + + +
+ +
+ +
+ +
+ +
+ +
+ +
+
+
+ ); +}; + +export default CustomAvatar; diff --git a/04-poke-battle-with-prisma/frontend/src/components/Molecules/CustomAvatar/options.ts b/04-poke-battle-with-prisma/frontend/src/components/Molecules/CustomAvatar/options.ts new file mode 100644 index 0000000..ddaa95d --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/src/components/Molecules/CustomAvatar/options.ts @@ -0,0 +1,198 @@ +import { + TAvatarBackgroundColor, + TAvatarEarrings, + TAvatarEyebrows, + TAvatarEyes, + TAvatarFeatures, + TAvatarGlasses, + TAvatarHair, + TAvatarHairColor, + TAvatarMouth, + TAvatarSkinColor, +} from "../../../types"; + +export const AVATAR_EYES: TAvatarEyes[] = [ + "variant01", + "variant02", + "variant03", + "variant04", + "variant05", + "variant06", + "variant07", + "variant08", + "variant09", + "variant10", + "variant11", + "variant12", + "variant13", + "variant14", + "variant15", + "variant16", + "variant17", + "variant18", + "variant19", + "variant20", + "variant21", + "variant22", + "variant23", + "variant24", + "variant25", + "variant26", +]; + +export const AVATAR_BACKGROUNDCOLOR: TAvatarBackgroundColor[] = [ + "b6e3f4", + "c0aede", + "d1d4f9", + "ffd5dc", + "ffdfbf", +]; + +export const AVATAR_EARRINGS: TAvatarEarrings[] = [ + "variant01", + "variant02", + "variant03", + "variant04", + "variant05", + "variant06", +]; + +export const AVATAR_EYEBROWS: TAvatarEyebrows[] = [ + "variant01", + "variant02", + "variant03", + "variant04", + "variant05", + "variant06", + "variant07", + "variant08", + "variant09", + "variant10", + "variant11", + "variant12", + "variant13", + "variant14", + "variant15", +]; + +export const AVATAR_FEATURES: TAvatarFeatures[] = [ + "birthmark", + "blush", + "freckles", + "mustache", +]; + +export const AVATAR_GLASSES: TAvatarGlasses[] = [ + "variant01", + "variant02", + "variant03", + "variant04", + "variant05", +]; + +export const AVATAR_HAIR: TAvatarHair[] = [ + "long01", + "long02", + "long03", + "long04", + "long05", + "long06", + "long07", + "long08", + "long09", + "long10", + "long11", + "long12", + "long13", + "long14", + "long15", + "long16", + "long17", + "long18", + "long19", + "long20", + "long21", + "long22", + "long23", + "long24", + "long25", + "long26", + "short01", + "short02", + "short03", + "short04", + "short05", + "short06", + "short07", + "short08", + "short09", + "short10", + "short11", + "short12", + "short13", + "short14", + "short15", + "short16", + "short17", + "short18", + "short19", +]; + +export const AVATAR_HAIR_COLOR: TAvatarHairColor[] = [ + "0e0e0e", + "3eac2c", + "6a4e35", + "85c2c6", + "796a45", + "562306", + "592454", + "ab2a18", + "ac6511", + "afafaf", + "b9a05f", + "cb6820", + "dba3be", + "e5d7a3", + "f3f4f6", + "fde68a", +]; + +export const AVATAR_MOUTH: TAvatarMouth[] = [ + "variant01", + "variant02", + "variant03", + "variant04", + "variant05", + "variant06", + "variant07", + "variant08", + "variant09", + "variant10", + "variant11", + "variant12", + "variant13", + "variant14", + "variant15", + "variant16", + "variant17", + "variant18", + "variant19", + "variant20", + "variant21", + "variant22", + "variant23", + "variant24", + "variant25", + "variant26", + "variant27", + "variant28", + "variant29", + "variant30", +]; + +export const AVATAR_SKIN_COLOR: TAvatarSkinColor[] = [ + "9e5622", + "763900", + "ecad80", + "f2d3b1", +]; diff --git a/04-poke-battle-with-prisma/frontend/src/components/Molecules/CustomAvatar/types.ts b/04-poke-battle-with-prisma/frontend/src/components/Molecules/CustomAvatar/types.ts new file mode 100644 index 0000000..d0a49ef --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/src/components/Molecules/CustomAvatar/types.ts @@ -0,0 +1,7 @@ +import { Dispatch, SetStateAction } from "react"; +import { IUserAvatar } from "../../../service/types"; + +export type TCustomAvatarProps = { + seed?: string; + setConstructAvatar: Dispatch>; +}; diff --git a/04-poke-battle-with-prisma/frontend/src/components/Molecules/DragabbleItems/index.tsx b/04-poke-battle-with-prisma/frontend/src/components/Molecules/DragabbleItems/index.tsx new file mode 100644 index 0000000..ab7dfd8 --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/src/components/Molecules/DragabbleItems/index.tsx @@ -0,0 +1,25 @@ +import { FC, useRef } from "react"; +import { useDraggable } from "react-use-draggable-scroll"; + +// types +import type { TDraggableItems } from "./types"; + +// :: +const DraggableItems: FC = ({ children }) => { + // We will use React useRef hook to reference the wrapping div: + const ref = + useRef() as React.MutableRefObject; + const { events } = useDraggable(ref); // Now we pass the reference to the useDraggable hook: + + return ( +
+ {children} +
+ ); +}; + +export default DraggableItems; diff --git a/04-poke-battle-with-prisma/frontend/src/components/Molecules/DragabbleItems/types.ts b/04-poke-battle-with-prisma/frontend/src/components/Molecules/DragabbleItems/types.ts new file mode 100644 index 0000000..23a62ed --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/src/components/Molecules/DragabbleItems/types.ts @@ -0,0 +1,5 @@ +import { ReactNode } from "react"; + +export type TDraggableItems = { + children: ReactNode; +}; diff --git a/04-poke-battle-with-prisma/frontend/src/components/Molecules/InlineLoading/index.tsx b/04-poke-battle-with-prisma/frontend/src/components/Molecules/InlineLoading/index.tsx new file mode 100644 index 0000000..447d28e --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/src/components/Molecules/InlineLoading/index.tsx @@ -0,0 +1,21 @@ +import { FC } from "react"; + +// components +import { LoadingStatus } from "../.."; + +// types +import type { TInlineLoadingProps } from "./types"; + +// :: +const InlineLoading: FC = ({ text, isLoading }) => { + if (!isLoading) return null; + + return ( +
+ +

{text}

+
+ ); +}; + +export default InlineLoading; diff --git a/04-poke-battle-with-prisma/frontend/src/components/Molecules/InlineLoading/types.ts b/04-poke-battle-with-prisma/frontend/src/components/Molecules/InlineLoading/types.ts new file mode 100644 index 0000000..fb847cf --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/src/components/Molecules/InlineLoading/types.ts @@ -0,0 +1,4 @@ +export type TInlineLoadingProps = { + text: string, + isLoading: boolean, +} diff --git a/04-poke-battle-with-prisma/frontend/src/components/index.ts b/04-poke-battle-with-prisma/frontend/src/components/index.ts new file mode 100644 index 0000000..ba38509 --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/src/components/index.ts @@ -0,0 +1,28 @@ +// atoms +import Button from "./Atoms/Button"; +import CollapseRow from "./Atoms/CollapseRow"; +import Header from "./Atoms/Header"; +import Input from "./Atoms/Input"; +import LoadingStatus from "./Atoms/LoadingStatus"; +import PokemonCard from "./Atoms/PokemonCard"; +import Sidebar from "./Atoms/Sidebar"; +import StatusCard from "./Atoms/StatusCard"; +import ThemeSelector from "./Atoms/ThemeSelector"; + +// molecules +import BattleHistory from "./Molecules/BattleHistory"; +import InlineLoading from "./Molecules/InlineLoading"; + +export { + PokemonCard, + BattleHistory, + Button, + CollapseRow, + Header, + InlineLoading, + Input, + LoadingStatus, + Sidebar, + StatusCard, + ThemeSelector, +}; diff --git a/04-poke-battle-with-prisma/frontend/src/container/BattlePokemon/index.tsx b/04-poke-battle-with-prisma/frontend/src/container/BattlePokemon/index.tsx new file mode 100644 index 0000000..4e2367e --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/src/container/BattlePokemon/index.tsx @@ -0,0 +1,160 @@ +import { useMemo } from "react"; +import { useGetSinglePokemonQuery } from "../../queries/useGetSinglePokemonQuery"; +import { useStartPokemonBattleMutation } from "../../queries/useStartPokemonBattleMutation"; +import { TBattlePokemonProps } from "./types"; +import clsx from "clsx"; +import { + BattleHistory, + Button, + CollapseRow, + StatusCard, +} from "../../components"; +import { + ArrowUturnLeftIcon, + ShieldExclamationIcon, +} from "@heroicons/react/24/outline"; + +const searchChallenger = (): number => { + const min = 1; + const max = 281; + + const challengerId = Math.floor(Math.random() * (max - min + 1)) + min; + + return challengerId; +}; + +const BattlePokemon = ({ + pokemon, + handleClickExitBattle, +}: TBattlePokemonProps) => { + const { + mutate: startBattle, + isLoading: battleLoading, + isError: battleError, + data: battleResult, + } = useStartPokemonBattleMutation(); + + const challengerId = useMemo( + () => searchChallenger(), + [pokemon, searchChallenger], + ); + const { data: challenger, isFetching } = + useGetSinglePokemonQuery(challengerId); + + if (battleError) + return ( +
+ + + +
+ ); + + if (isFetching) + return ( +

+ Looking for opponent +

+ ); + + if (!challenger) return null; + + return ( +
+
+ {pokemon.name} + {challenger.name} +
+ {battleLoading && ( +

+ The pokemons are battling wildly! +

+ )} + {!battleResult && !battleLoading && ( +
+

+ You found{" "} + + {challenger.name} + {" "} + opponent +

+ +
+ + +
+
+ )} + {battleResult && ( +
+

+ {battleResult.winner && "Congratulations you won this battle!"} + {!battleResult.winner && + "Opponent was too strong, will do better next time"} + {battleResult.isDraw && + "This battle was amazing, both are unconscious!"} +

+ + +
+ )} +
+ ); +}; + +export default BattlePokemon; diff --git a/04-poke-battle-with-prisma/frontend/src/container/BattlePokemon/types.ts b/04-poke-battle-with-prisma/frontend/src/container/BattlePokemon/types.ts new file mode 100644 index 0000000..1bfd8cb --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/src/container/BattlePokemon/types.ts @@ -0,0 +1,6 @@ +import { TPokemonContentEndpoint } from "../../types"; + +export type TBattlePokemonProps = { + pokemon: TPokemonContentEndpoint; + handleClickExitBattle: () => void; +}; diff --git a/04-poke-battle-with-prisma/frontend/src/container/SinglePokemon/index.tsx b/04-poke-battle-with-prisma/frontend/src/container/SinglePokemon/index.tsx new file mode 100644 index 0000000..5c4899e --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/src/container/SinglePokemon/index.tsx @@ -0,0 +1,27 @@ +import { PokemonCard } from "../../components"; +import { useGetPokemonQuery } from "../../queries/useGetPokemonQuery"; +import { TSinglePokemonProps } from "./types"; + +const SinglePokemon = ({ + uri, + selected, + handleClickPokemon, +}: TSinglePokemonProps) => { + const { data } = useGetPokemonQuery(uri); + + if (!data) return null; + + return ( + handleClickPokemon(data)} + /> + ); +}; + +export default SinglePokemon; diff --git a/04-poke-battle-with-prisma/frontend/src/container/SinglePokemon/types.ts b/04-poke-battle-with-prisma/frontend/src/container/SinglePokemon/types.ts new file mode 100644 index 0000000..84a6541 --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/src/container/SinglePokemon/types.ts @@ -0,0 +1,7 @@ +import { TPokemonContentEndpoint } from "../../types"; + +export type TSinglePokemonProps = { + uri: string; + selected: boolean; + handleClickPokemon: (pokemon: TPokemonContentEndpoint) => void; +}; diff --git a/04-poke-battle-with-prisma/frontend/src/container/UniquePokemon/index.tsx b/04-poke-battle-with-prisma/frontend/src/container/UniquePokemon/index.tsx new file mode 100644 index 0000000..8ddd587 --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/src/container/UniquePokemon/index.tsx @@ -0,0 +1,42 @@ +import { PokemonCard, StatusCard } from "../../components"; +import { useGetSinglePokemonQuery } from "../../queries/useGetSinglePokemonQuery"; +import { TSinglePokemonProps } from "../SinglePokemon/types"; + +const UniquePokemon = ({ + uri, + selected, + handleClickPokemon, +}: TSinglePokemonProps) => { + const { data, isError, isFetching } = useGetSinglePokemonQuery(uri); + + if (isFetching) { + return ( +
+ ); + } + + if (isError) + return ( + + ); + + if (!data?.name) return null; + + return ( + handleClickPokemon(data)} + /> + ); +}; + +export default UniquePokemon; diff --git a/04-poke-battle-with-prisma/frontend/src/container/index.ts b/04-poke-battle-with-prisma/frontend/src/container/index.ts new file mode 100644 index 0000000..92e482d --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/src/container/index.ts @@ -0,0 +1,5 @@ +import BattlePokemon from "./BattlePokemon"; +import SinglePokemon from "./SinglePokemon"; +import UniquePokemon from "./UniquePokemon"; + +export { BattlePokemon, SinglePokemon, UniquePokemon }; diff --git a/04-poke-battle-with-prisma/frontend/src/context/auth.tsx b/04-poke-battle-with-prisma/frontend/src/context/auth.tsx new file mode 100644 index 0000000..98693ba --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/src/context/auth.tsx @@ -0,0 +1,31 @@ +import { ReactElement, createContext, useContext, useState } from "react"; +import { useAuthActions, useUser } from "../store"; + +type TAuthProviderProps = { + children: ReactElement; +}; + +const AuthContext = createContext({}); + +function AuthProvider({ children }: TAuthProviderProps) { + const { logout } = useAuthActions(); + const user = useUser(); + + return ( + + {children} + + ); +} + +function useAuth() { + const context = useContext(AuthContext); + + if (!context) { + throw new Error("useAuth must be used within an AuthProvider"); + } + + return context; +} + +export { AuthProvider, useAuth }; diff --git a/04-poke-battle-with-prisma/frontend/src/core/AppRouter.routes.tsx b/04-poke-battle-with-prisma/frontend/src/core/AppRouter.routes.tsx new file mode 100644 index 0000000..8a7d268 --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/src/core/AppRouter.routes.tsx @@ -0,0 +1,28 @@ +import { Routes, Route } from "react-router-dom"; +import { ROUTE } from "../routes"; + +import * as Page from "../pages"; +import AuthRoute from "./AuthRoute.routes"; +import { useLayoutEffect } from "react"; +import { useTheme } from "../store"; + +export const AppRouter = () => { + const currentTheme = useTheme(); + + useLayoutEffect(() => { + document.documentElement.setAttribute("data-theme", currentTheme); + }, [currentTheme]); + + return ( + + 404} /> + } /> + } /> + }> + } /> + } /> + user} /> + + + ); +}; diff --git a/04-poke-battle-with-prisma/frontend/src/core/AuthRoute.routes.tsx b/04-poke-battle-with-prisma/frontend/src/core/AuthRoute.routes.tsx new file mode 100644 index 0000000..071fb02 --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/src/core/AuthRoute.routes.tsx @@ -0,0 +1,57 @@ +import { Link, Navigate, Outlet, useNavigate } from "react-router-dom"; + +// store +import { useUser } from "../store"; + +// routes +import { ROUTE } from "../routes"; + +// components +import { Button, Header, ThemeSelector } from "../components"; +import { mountAuthRoute } from "../utils/mountAuthRoute"; +import { ArrowLeftOnRectangleIcon } from "@heroicons/react/24/outline"; + +// :: +const AuthRoute = () => { + const user = useUser(); + const navigate = useNavigate(); + + if (!user) return ; + + return ( + <> +
+
+ + {`custom +
+

sign in as

+

{user.name}

+
+ +
+ + +
+
+
+ + + ); +}; + +export default AuthRoute; diff --git a/04-poke-battle-with-prisma/frontend/src/endpoints/index.ts b/04-poke-battle-with-prisma/frontend/src/endpoints/index.ts new file mode 100644 index 0000000..926cef6 --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/src/endpoints/index.ts @@ -0,0 +1,10 @@ +export const ENDPOINT = { + createUser: "/user/create", + getUser: "/user", + signInUser: "/user/login", + createBattle: "/pokebattle/battle", + userBattleHistory: "/pokebattle/history", + listOfPokemons: "/pokemon", + pokemon: "/pokemon/", // recebe parametro id. + history: "/pokebattle/history", // recebe parametro id. +}; diff --git a/04-poke-battle-with-prisma/frontend/src/globals.css b/04-poke-battle-with-prisma/frontend/src/globals.css new file mode 100644 index 0000000..b5c61c9 --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/src/globals.css @@ -0,0 +1,3 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; diff --git a/04-poke-battle-with-prisma/frontend/src/hooks/useDebounce.tsx b/04-poke-battle-with-prisma/frontend/src/hooks/useDebounce.tsx new file mode 100644 index 0000000..7074c05 --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/src/hooks/useDebounce.tsx @@ -0,0 +1,18 @@ +import React from "react"; + +export default function useDebounce(value: string, delay = 500) { + const [debouncedValue, setDebouncedValue] = React.useState(value); + + React.useEffect(() => { + const handler: ReturnType = setTimeout(() => { + setDebouncedValue(value); + }, delay); + + // Cancel the timeout if value changes (also on delay change or unmount) + return () => { + clearTimeout(handler); + }; + }, [value, delay]); + + return debouncedValue; +} \ No newline at end of file diff --git a/04-poke-battle-with-prisma/frontend/src/hooks/useOnClickOutside.tsx b/04-poke-battle-with-prisma/frontend/src/hooks/useOnClickOutside.tsx new file mode 100644 index 0000000..e4b46d3 --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/src/hooks/useOnClickOutside.tsx @@ -0,0 +1,24 @@ +import { RefObject, useEffect } from "react"; + +export function useOnClickOutside( + ref: RefObject, + handler: (event: MouseEvent | TouchEvent) => void, +): void { + useEffect(() => { + const listener = (event: MouseEvent | TouchEvent) => { + if (!ref.current || ref.current.contains(event.target as Node)) { + return; + } + + handler(event); + }; + + document.addEventListener("mousedown", listener); + document.addEventListener("touchstart", listener); + + return () => { + document.removeEventListener("mousedown", listener); + document.removeEventListener("touchstart", listener); + }; + }, [ref, handler]); +} diff --git a/04-poke-battle-with-prisma/frontend/src/main.tsx b/04-poke-battle-with-prisma/frontend/src/main.tsx new file mode 100644 index 0000000..432de3a --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/src/main.tsx @@ -0,0 +1,18 @@ +import React from "react"; +import ReactDOM from "react-dom/client"; +import "./globals.css"; +import { BrowserRouter } from "react-router-dom"; +import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; +import { AppRouter } from "./core/AppRouter.routes"; + +const queryClient = new QueryClient(); + +ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render( + + + + + + + , +); diff --git a/04-poke-battle-with-prisma/frontend/src/pages/Arena/index.tsx b/04-poke-battle-with-prisma/frontend/src/pages/Arena/index.tsx new file mode 100644 index 0000000..9f16a7b --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/src/pages/Arena/index.tsx @@ -0,0 +1,109 @@ +import { useState } from "react"; +import { Button, Input, LoadingStatus, StatusCard } from "../../components"; +import { BattlePokemon, SinglePokemon, UniquePokemon } from "../../container"; +import { useGetPokemonListQuery } from "../../queries/useGetPokemonListQuery"; +import { TPokemonContentEndpoint } from "../../types"; +import { PlayIcon } from "@heroicons/react/24/solid"; +import useDebounce from "../../hooks/useDebounce"; + +const Arena = () => { + const [screen, setScreen] = useState<"selection" | "battle">("selection"); + const [searchPokemon, setSearchPokemon] = useState(""); + const debounceSearchPokemon = useDebounce(searchPokemon, 1200); + const [selectedPokemon, setSelectedPokemon] = useState< + TPokemonContentEndpoint | undefined + >(undefined); + + const { + data: pokemonList, + isError: pokemonListError, + isFetching: pokemonListLoading, + fetchNextPage, + hasNextPage, + } = useGetPokemonListQuery(); + + if (screen !== "selection" && selectedPokemon) { + return ( +
+ setScreen("selection")} + pokemon={selectedPokemon} + /> +
+ ); + } + + return ( +
+ + setSearchPokemon(e.target.value)} + /> + {searchPokemon && ( + setSelectedPokemon(pokemon)} + selected={ + searchPokemon.trim().toLowerCase() === selectedPokemon?.name + } + uri={debounceSearchPokemon.trim().toLowerCase()} + /> + )} + {pokemonListError && ( + + )} + {pokemonList?.pages && ( +
+ {pokemonList?.pages?.map((page) => + page.results.map((pokemon) => ( + setSelectedPokemon(pokemon)} + selected={pokemon.name === selectedPokemon?.name} + uri={pokemon.url} + /> + )), + )} +
+ )} +
+ {pokemonListLoading && ( +
+ +

Loading pokemons

+
+ )} +
+ {pokemonList?.pages && ( +
+ +
+ )} + {selectedPokemon && ( +
+ +
+ )} +
+ ); +}; + +export default Arena; diff --git a/04-poke-battle-with-prisma/frontend/src/pages/Home/index.tsx b/04-poke-battle-with-prisma/frontend/src/pages/Home/index.tsx new file mode 100644 index 0000000..aa3b1aa --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/src/pages/Home/index.tsx @@ -0,0 +1,50 @@ +import { useGetUserHistoryQuery } from "../../queries/useGetUserHistoryQuery"; +import { useUser } from "../../store"; +import { useNavigate } from "react-router-dom"; +import { ROUTE } from "../../routes"; +import { + BattleHistory, + Button, + CollapseRow, + StatusCard, +} from "../../components"; + +const Home = () => { + const user = useUser(); + const navigate = useNavigate(); + const { + data: historyData, + isFetching: historyLoading, + isError: historyError, + } = useGetUserHistoryQuery(`${user?.id}`); + + return ( +
+
+
+ + +
+

Your matchs

+
+ +
+
+
+ ); +}; + +export default Home; diff --git a/04-poke-battle-with-prisma/frontend/src/pages/Login/index.tsx b/04-poke-battle-with-prisma/frontend/src/pages/Login/index.tsx new file mode 100644 index 0000000..85681c4 --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/src/pages/Login/index.tsx @@ -0,0 +1,189 @@ +import { FormEvent, useEffect, useRef, useState } from "react"; +import expressoTSIcon from "../../assets/expressoicon.svg"; +import useCreateUserMutation from "../../queries/useCreateUserMutation"; +import useSignInUserMutation from "../../queries/useSignInUserMutation"; +import { Button, InlineLoading, Input, ThemeSelector } from "../../components"; +import axios from "axios"; +import { twMerge } from "tailwind-merge"; +import { IUserAvatar, TCreateRequest } from "../../service/types"; +import CustomAvatar from "../../components/Molecules/CustomAvatar"; +import { CubeIcon } from "@heroicons/react/24/outline"; +import { defaultAvatarEnum } from "../../utils/enums"; +import { useUser } from "../../store"; +import { useNavigate } from "react-router-dom"; +import { mountAuthRoute } from "../../utils/mountAuthRoute"; +import { ROUTE } from "../../routes"; + +type TLoginTabs = "login" | "create"; + +const defaultAvatar: IUserAvatar = { + ...defaultAvatarEnum, + earringsProbability: defaultAvatarEnum.earringsProbability, + featuresProbability: defaultAvatarEnum.featuresProbability, + glassesProbability: defaultAvatarEnum.glassesProbability, + hairProbability: defaultAvatarEnum.hairProbability, + flip: !!defaultAvatarEnum.flip, +}; + +const Login = () => { + const navigation = useNavigate(); + + const user = useUser(); + const [tab, setTab] = useState("login"); + const [avatar, setAvatar] = useState(defaultAvatar); + const { + mutate: createUser, + isLoading: createUserLoading, + error: createUserError, + } = useCreateUserMutation(); + + const { + mutate: signInUser, + isLoading: signInUserLoading, + error: signInUserError, + } = useSignInUserMutation(); + + const actionRef = useRef(""); + + function handleFormSubmit(e: FormEvent) { + e.preventDefault(); + + const form = e.currentTarget; + const formData = new FormData(form); + const formJson = Object.fromEntries(formData.entries()); + + if (actionRef.current === "create") { + const body = formJson as unknown as TCreateRequest; + return createUser({ ...body, avatar }); + } + + return signInUser(formJson); + } + + useEffect(() => { + if (user) { + navigation(mountAuthRoute(ROUTE.home)); + } + }, []); + + return ( +
+

+ PokeBattle +

+
+
+
+ + +
+
+ {tab === "create" && ( +
+ +
+ )} +
+
+ {tab === "create" && ( + + )} + + +
+
+
+ {axios.isAxiosError(signInUserError) && ( +

+ {signInUserError.response?.data?.error} +

+ )} + {axios.isAxiosError(createUserError) && ( +

+ {createUserError.response?.data?.error} +

+ )} +
+ +
+
+ {tab === "create" ? ( + + ) : ( + + )} +
+
+
+
+

+ Made with{" "} + + ExpressoTS + + +

+ +
+
+ ); +}; + +export default Login; diff --git a/04-poke-battle-with-prisma/frontend/src/pages/Logout/index.tsx b/04-poke-battle-with-prisma/frontend/src/pages/Logout/index.tsx new file mode 100644 index 0000000..c67dc6a --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/src/pages/Logout/index.tsx @@ -0,0 +1,28 @@ +import { useEffect } from "react"; +import { useAuthActions, useUser } from "../../store"; +import { useNavigate } from "react-router-dom"; +import { ROUTE } from "../../routes"; +import { LoadingStatus } from "../../components"; + +const Logout = () => { + const navigate = useNavigate(); + const user = useUser(); + const { logout } = useAuthActions(); + + useEffect(() => { + logout(); + }, []); + + useEffect(() => { + if (!user) navigate(ROUTE.login); + }, [user]); + + return ( +
+ +

Logout...

+
+ ); +}; + +export default Logout; diff --git a/04-poke-battle-with-prisma/frontend/src/pages/index.ts b/04-poke-battle-with-prisma/frontend/src/pages/index.ts new file mode 100644 index 0000000..8aafce4 --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/src/pages/index.ts @@ -0,0 +1,6 @@ +import Arena from "./Arena"; +import Home from "./Home"; +import Login from "./Login"; +import Logout from "./Logout"; + +export { Arena, Home, Login, Logout }; diff --git a/04-poke-battle-with-prisma/frontend/src/queries/useCreateUserMutation.ts b/04-poke-battle-with-prisma/frontend/src/queries/useCreateUserMutation.ts new file mode 100644 index 0000000..811185f --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/src/queries/useCreateUserMutation.ts @@ -0,0 +1,28 @@ +import { useMutation } from "@tanstack/react-query"; +import { createUser } from "../service/createUser"; +import { useNavigate } from "react-router-dom"; +import { ROUTE } from "../routes"; +import { useAuthActions } from "../store"; +import { TCreateRequest } from "../service/types"; +import { mountAuthRoute } from "../utils/mountAuthRoute"; + +const useCreateUserMutation = () => { + const navigation = useNavigate(); + const { setToken, setUser } = useAuthActions(); + + return useMutation({ + mutationFn: (body: TCreateRequest) => createUser(body), + onSuccess: (res) => { + setUser({ + email: res.email, + id: res.id, + name: res.name, + avatar: res.avatar, + }); + setToken(res.token); + navigation(mountAuthRoute(ROUTE.home)); + }, + }); +}; + +export default useCreateUserMutation; diff --git a/04-poke-battle-with-prisma/frontend/src/queries/useGetPokemonListQuery.tsx b/04-poke-battle-with-prisma/frontend/src/queries/useGetPokemonListQuery.tsx new file mode 100644 index 0000000..7e69b71 --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/src/queries/useGetPokemonListQuery.tsx @@ -0,0 +1,18 @@ +import { useInfiniteQuery } from "@tanstack/react-query"; + +// end-points +import { ENDPOINT } from "../endpoints"; + +// services +import { getPokemonList } from "../service/getPokemonList"; + +// :: +export const useGetPokemonListQuery = () => { + return useInfiniteQuery({ + queryKey: ["list", ENDPOINT.listOfPokemons], + queryFn: ({ pageParam }) => getPokemonList(pageParam), + getPreviousPageParam: (firstPage) => firstPage.next ?? undefined, + getNextPageParam: (lastPage) => lastPage.next ?? undefined, + refetchOnWindowFocus: false, + }); +}; diff --git a/04-poke-battle-with-prisma/frontend/src/queries/useGetPokemonQuery.ts b/04-poke-battle-with-prisma/frontend/src/queries/useGetPokemonQuery.ts new file mode 100644 index 0000000..d05459c --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/src/queries/useGetPokemonQuery.ts @@ -0,0 +1,23 @@ +import { useQuery } from "@tanstack/react-query"; + +// api: requester +import { requester } from "../api/requester"; + +// types +import type { TPokemonContentEndpoint } from "../types"; + +// :: +export const useGetPokemonQuery = (uri: string) => { + const dynamicRequest = async (): Promise => { + const { data } = await requester().get(uri); + + return data; + }; + + return useQuery({ + queryKey: [uri], + queryFn: () => dynamicRequest(), + refetchOnWindowFocus: false, + enabled: !!uri, + }); +}; diff --git a/04-poke-battle-with-prisma/frontend/src/queries/useGetSinglePokemonQuery.ts b/04-poke-battle-with-prisma/frontend/src/queries/useGetSinglePokemonQuery.ts new file mode 100644 index 0000000..38877dc --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/src/queries/useGetSinglePokemonQuery.ts @@ -0,0 +1,13 @@ +import { useQuery } from "@tanstack/react-query"; + +// service +import { getSinglePokemon } from "../service/getSinglePokemon"; + +// :: +export const useGetSinglePokemonQuery = (pokemon: string | number) => { + return useQuery({ + queryKey: [`single-pokemon-${pokemon}`], + queryFn: () => getSinglePokemon(pokemon), + refetchOnWindowFocus: false, + }); +}; diff --git a/04-poke-battle-with-prisma/frontend/src/queries/useGetUserHistoryQuery.ts b/04-poke-battle-with-prisma/frontend/src/queries/useGetUserHistoryQuery.ts new file mode 100644 index 0000000..614f76a --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/src/queries/useGetUserHistoryQuery.ts @@ -0,0 +1,13 @@ +import { useQuery } from "@tanstack/react-query"; + +// service +import { getUserHistory } from "../service/getUserHistory"; + +// :: +export const useGetUserHistoryQuery = (id: string) => { + return useQuery({ + queryKey: [`user-history-${id}`], + queryFn: () => getUserHistory(id), + refetchOnWindowFocus: false, + }); +}; diff --git a/04-poke-battle-with-prisma/frontend/src/queries/useSignInUserMutation.ts b/04-poke-battle-with-prisma/frontend/src/queries/useSignInUserMutation.ts new file mode 100644 index 0000000..fe91c2d --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/src/queries/useSignInUserMutation.ts @@ -0,0 +1,27 @@ +import { useMutation } from "@tanstack/react-query"; +import { signInUser } from "../service/signInUser"; +import { useNavigate } from "react-router-dom"; +import { useAuthActions } from "../store"; +import { ROUTE } from "../routes"; +import { mountAuthRoute } from "../utils/mountAuthRoute"; + +const useSignInUserMutation = () => { + const navigation = useNavigate(); + const { setUser, setToken } = useAuthActions(); + + return useMutation({ + mutationFn: (body: any) => signInUser(body), + onSuccess: (res) => { + setUser({ + email: res.email, + id: res.id, + name: res.name, + avatar: res.avatar, + }); + setToken(res.token); + navigation(mountAuthRoute(ROUTE.home)); + }, + }); +}; + +export default useSignInUserMutation; diff --git a/04-poke-battle-with-prisma/frontend/src/queries/useStartPokemonBattleMutation.tsx b/04-poke-battle-with-prisma/frontend/src/queries/useStartPokemonBattleMutation.tsx new file mode 100644 index 0000000..e9f35e3 --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/src/queries/useStartPokemonBattleMutation.tsx @@ -0,0 +1,16 @@ +import { useMutation } from "@tanstack/react-query"; +import { TPokemonContentEndpoint } from "../types"; +import { createBattle } from "../service/createBattle"; +import { useToken } from "../store"; + +export const useStartPokemonBattleMutation = () => { + const token = useToken(); + + // Queries + return useMutation({ + mutationFn: (body: { + pokemon1: TPokemonContentEndpoint; + pokemon2: TPokemonContentEndpoint; + }) => createBattle(body, token), + }); +}; diff --git a/04-poke-battle-with-prisma/frontend/src/routes/index.ts b/04-poke-battle-with-prisma/frontend/src/routes/index.ts new file mode 100644 index 0000000..23991fe --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/src/routes/index.ts @@ -0,0 +1,8 @@ +export enum ROUTE { + auth = "/trainer/", + arena = "arena", + home = "home", + login = "/", + user = "user", + logout = "/logout", +} diff --git a/04-poke-battle-with-prisma/frontend/src/service/createBattle.ts b/04-poke-battle-with-prisma/frontend/src/service/createBattle.ts new file mode 100644 index 0000000..2550744 --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/src/service/createBattle.ts @@ -0,0 +1,20 @@ +import { requester } from "../api/requester"; +import { ENDPOINT } from "../endpoints"; +import { TPokemonContentEndpoint } from "../types"; +import { THistoryBattleResponse } from "./types"; + +export const createBattle = async ( + body: { + pokemon1: TPokemonContentEndpoint; + pokemon2: TPokemonContentEndpoint; + }, + token: string, +): Promise => { + const { data } = await requester({ + headers: { + Authorization: token, + }, + }).post(ENDPOINT.createBattle, body); + + return data; +}; diff --git a/04-poke-battle-with-prisma/frontend/src/service/createUser.ts b/04-poke-battle-with-prisma/frontend/src/service/createUser.ts new file mode 100644 index 0000000..24f9372 --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/src/service/createUser.ts @@ -0,0 +1,14 @@ +import { requester } from "../api/requester"; +import { ENDPOINT } from "../endpoints"; +import { TAuthResponse, TCreateRequest } from "./types"; + +export const createUser = async ( + body: TCreateRequest, +): Promise => { + const { data } = await requester().post( + ENDPOINT.createUser, + body, + ); + + return data; +}; diff --git a/04-poke-battle-with-prisma/frontend/src/service/getPokemonList.ts b/04-poke-battle-with-prisma/frontend/src/service/getPokemonList.ts new file mode 100644 index 0000000..80be42a --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/src/service/getPokemonList.ts @@ -0,0 +1,18 @@ +// api: requesters +import { requester } from "../api/requester"; + +// end-poins +import { ENDPOINT } from "../endpoints"; + +// types +import type { TPokemonListEndpoint } from "../types"; + +export const getPokemonList = async ( + offSet: string, +): Promise => { + const { data } = await requester({ + baseURL: import.meta.env.VITE_POKEAPI_URL, + }).get(offSet || `${ENDPOINT.listOfPokemons}`); + + return data; +}; diff --git a/04-poke-battle-with-prisma/frontend/src/service/getSinglePokemon.ts b/04-poke-battle-with-prisma/frontend/src/service/getSinglePokemon.ts new file mode 100644 index 0000000..6ac9e9b --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/src/service/getSinglePokemon.ts @@ -0,0 +1,16 @@ +// api: requesters +import { requester } from "../api/requester"; + +// end-poins +import { ENDPOINT } from "../endpoints"; +import { TPokemonContentEndpoint } from "../types"; + +export const getSinglePokemon = async ( + pokemon: string | number, +): Promise => { + const { data } = await requester({ + baseURL: import.meta.env.VITE_POKEAPI_URL, + }).get(`${ENDPOINT.pokemon}${pokemon}`); + + return data; +}; diff --git a/04-poke-battle-with-prisma/frontend/src/service/getUserHistory.ts b/04-poke-battle-with-prisma/frontend/src/service/getUserHistory.ts new file mode 100644 index 0000000..1efbb84 --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/src/service/getUserHistory.ts @@ -0,0 +1,18 @@ +// api: requesters +import { requester } from "../api/requester"; + +// end-poins +import { ENDPOINT } from "../endpoints"; + +// types +import { THistoryBattleResponse } from "./types"; + +export const getUserHistory = async ( + id: string, +): Promise => { + const { data } = await requester().get( + `${ENDPOINT.userBattleHistory}?id=${id}`, + ); + + return data; +}; diff --git a/04-poke-battle-with-prisma/frontend/src/service/signInUser.ts b/04-poke-battle-with-prisma/frontend/src/service/signInUser.ts new file mode 100644 index 0000000..19b4d01 --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/src/service/signInUser.ts @@ -0,0 +1,14 @@ +import { requester } from "../api/requester"; +import { ENDPOINT } from "../endpoints"; +import { TAuthResponse, TLoginRequest } from "./types"; + +export const signInUser = async ( + body: TLoginRequest, +): Promise => { + const { data } = await requester().post( + ENDPOINT.signInUser, + body, + ); + + return data; +}; diff --git a/04-poke-battle-with-prisma/frontend/src/service/types/index.ts b/04-poke-battle-with-prisma/frontend/src/service/types/index.ts new file mode 100644 index 0000000..22a58af --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/src/service/types/index.ts @@ -0,0 +1,85 @@ +import { + TAvatarBackgroundColor, + TAvatarEarrings, + TAvatarEyebrows, + TAvatarEyes, + TAvatarFeatures, + TAvatarGlasses, + TAvatarHair, + TAvatarHairColor, + TAvatarMouth, + TAvatarSkinColor, +} from "../../types"; + +export interface IUserAvatar { + backgroundColor: TAvatarBackgroundColor; + earrings: TAvatarEarrings; + earringsProbability: 0 | 100; + glassesProbability: 0 | 100; + featuresProbability: 0 | 100; + hairProbability: 100; + eyebrows: TAvatarEyebrows; + eyes: TAvatarEyes; + features: TAvatarFeatures; + glasses: TAvatarGlasses; + hair: TAvatarHair; + hairColor: TAvatarHairColor; + mouth: TAvatarMouth; + seed: string; + skinColor: TAvatarSkinColor; + flip: boolean; + url?: string; +} + +export type TUser = { + id: string; + name: string; + email: string; + avatar: IUserAvatar; +}; + +export type TLoginRequest = { + email: string; + password: string; +}; + +export type TCreateRequest = { + name: string; + avatar: IUserAvatar; +} & TLoginRequest; + +export type TAuthResponse = { + token: string; +} & TUser; + +export type THistoryBattleRequest = { + id: string; +}; + +export type THistoryBattleLog = { + turn: number; + attacker: string; + defender: string; + attack: string; + attackType: string; + damage: number; +}; + +export type THistoryBattlePokemon = { + name: string; + sprites: string[]; + types: string[]; +}; + +export type THistoryBattleResponse = { + id?: string; + userName: string; + playerId: string; + pokemon1: THistoryBattlePokemon; + pokemon2: THistoryBattlePokemon; + log: THistoryBattleLog[]; + winner: boolean; + winnerName: string; + loserName: string; + isDraw: boolean; +}; diff --git a/04-poke-battle-with-prisma/frontend/src/store/index.ts b/04-poke-battle-with-prisma/frontend/src/store/index.ts new file mode 100644 index 0000000..cfbb42b --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/src/store/index.ts @@ -0,0 +1,68 @@ +import { create } from "zustand"; +import { persist } from "zustand/middleware"; +import { TUser } from "../service/types"; + +type AuthStore = { + user: TUser | null; + token: string; + actions: { + setUser: (user: TUser) => void; + setToken: (token: string) => void; + logout: () => void; + }; +}; + +type TThemeStore = { + theme: string; + actions: { + setTheme: (theme: string) => void; + }; +}; + +const initialState = { + user: null, + token: "", +}; + +export const useAuthStore = create()( + persist( + (set) => ({ + ...initialState, + actions: { + setUser: (user) => set({ user }), + setToken: (token) => set({ token }), + logout: () => set({ ...initialState }), + }, + }), + { + name: "auth", + partialize: (state) => ({ + user: state.user, + token: state.token, + }), + }, + ), +); + +export const useThemeStore = create()( + persist( + (set) => ({ + theme: "dracula", + actions: { + setTheme: (theme) => set({ theme }), + }, + }), + { + name: "theme", + partialize: (state) => ({ + theme: state.theme, + }), + }, + ), +); + +export const useTheme = () => useThemeStore((state) => state.theme); +export const useThemeActions = () => useThemeStore((state) => state.actions); +export const useUser = () => useAuthStore((state) => state.user); +export const useToken = () => useAuthStore((state) => state.token); +export const useAuthActions = () => useAuthStore((state) => state.actions); diff --git a/04-poke-battle-with-prisma/frontend/src/themes/index.ts b/04-poke-battle-with-prisma/frontend/src/themes/index.ts new file mode 100644 index 0000000..67635bf --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/src/themes/index.ts @@ -0,0 +1,31 @@ +export const themes = [ + "acid", + "aqua", + "autumn", + "black", + "bumblebee", + "business", + "cmyk", + "coffee", + "corporate", + "cupcake", + "cyberpunk", + "dark", + "dracula", + "emerald", + "fantasy", + "forest", + "garden", + "halloween", + "lemonade", + "light", + "lofi", + "luxury", + "night", + "pastel", + "retro", + "synthwave", + "valentine", + "winter", + "wireframe", +]; diff --git a/04-poke-battle-with-prisma/frontend/src/types/index.ts b/04-poke-battle-with-prisma/frontend/src/types/index.ts new file mode 100644 index 0000000..fb08622 --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/src/types/index.ts @@ -0,0 +1,517 @@ +export type TAvatarBackgroundColor = + | "b6e3f4" + | "c0aede" + | "d1d4f9" + | "ffd5dc" + | "ffdfbf"; + +export type TAvatarEarrings = + | "variant01" + | "variant02" + | "variant03" + | "variant04" + | "variant05" + | "variant06"; + +export type TAvatarEyebrows = + | "variant01" + | "variant02" + | "variant03" + | "variant04" + | "variant05" + | "variant06" + | "variant07" + | "variant08" + | "variant09" + | "variant10" + | "variant11" + | "variant12" + | "variant13" + | "variant14" + | "variant15"; + +export type TAvatarEyes = + | "variant01" + | "variant02" + | "variant03" + | "variant04" + | "variant05" + | "variant06" + | "variant07" + | "variant08" + | "variant09" + | "variant10" + | "variant11" + | "variant12" + | "variant13" + | "variant14" + | "variant15" + | "variant16" + | "variant17" + | "variant18" + | "variant19" + | "variant20" + | "variant21" + | "variant22" + | "variant23" + | "variant24" + | "variant25" + | "variant26"; + +export type TAvatarFeatures = "birthmark" | "blush" | "freckles" | "mustache"; + +export type TAvatarGlasses = + | "variant01" + | "variant02" + | "variant03" + | "variant04" + | "variant05"; + +export type TAvatarHair = + | "long01" + | "long02" + | "long03" + | "long04" + | "long05" + | "long06" + | "long07" + | "long08" + | "long09" + | "long10" + | "long11" + | "long12" + | "long13" + | "long14" + | "long15" + | "long16" + | "long17" + | "long18" + | "long19" + | "long20" + | "long21" + | "long22" + | "long23" + | "long24" + | "long25" + | "long26" + | "short01" + | "short02" + | "short03" + | "short04" + | "short05" + | "short06" + | "short07" + | "short08" + | "short09" + | "short10" + | "short11" + | "short12" + | "short13" + | "short14" + | "short15" + | "short16" + | "short17" + | "short18" + | "short19"; + +export type TAvatarHairColor = + | "0e0e0e" + | "3eac2c" + | "6a4e35" + | "85c2c6" + | "796a45" + | "562306" + | "592454" + | "ab2a18" + | "ac6511" + | "afafaf" + | "b9a05f" + | "cb6820" + | "dba3be" + | "e5d7a3" + | "f3f4f6" + | "fde68a"; + +export type TAvatarMouth = + | "variant01" + | "variant02" + | "variant03" + | "variant04" + | "variant05" + | "variant06" + | "variant07" + | "variant08" + | "variant09" + | "variant10" + | "variant11" + | "variant12" + | "variant13" + | "variant14" + | "variant15" + | "variant16" + | "variant17" + | "variant18" + | "variant19" + | "variant20" + | "variant21" + | "variant22" + | "variant23" + | "variant24" + | "variant25" + | "variant26" + | "variant27" + | "variant28" + | "variant29" + | "variant30"; + +export type TAvatarSkinColor = "9e5622" | "763900" | "ecad80" | "f2d3b1"; + +export type TPokemonListEndpoint = { + count: number; + next: string; + previous: any; + results: TPokemonListEndpointResult[]; +}; + +export type TPokemonListEndpointResult = { + name: string; + url: string; +}; + +export type TPokemonContentEndpoint = { + abilities: PokemonAbilities[]; + base_experience: number; + forms: PokemonForm[]; + game_indices: GameIndices[]; + height: number; + held_items: any[]; + id: number; + is_default: boolean; + location_area_encounters: string; + moves: PokemonMoves[]; + name: string; + order: number; + past_types: any[]; + species: PokemonSpecies; + sprites: PokemonSprites; + stats: PokemonStats[]; + types: PokemonTypes[]; + weight: number; +}; + +export type PokemonAbilities = { + ability: PokemonAbility; + is_hidden: boolean; + slot: number; +}; + +export type PokemonAbility = { + name: string; + url: string; +}; + +export type PokemonForm = { + name: string; + url: string; +}; + +export type GameIndices = { + game_index: number; + version: PokemonVersion; +}; + +export type PokemonVersion = { + name: string; + url: string; +}; + +export type PokemonMoves = { + move: Move; + version_group_details: PokemonVersionGroupDetail[]; +}; + +export type Move = { + name: string; + url: string; +}; + +export type PokemonVersionGroupDetail = { + level_learned_at: number; + move_learn_method: PokemonMoveLearnMethod; + version_group: PokemonVersionGroup; +}; + +export type PokemonMoveLearnMethod = { + name: string; + url: string; +}; + +export type PokemonVersionGroup = { + name: string; + url: string; +}; + +export type PokemonSpecies = { + name: string; + url: string; +}; + +export type PokemonSprites = { + back_default: string; + back_female: any; + back_shiny: string; + back_shiny_female: any; + front_default: string; + front_female: any; + front_shiny: string; + front_shiny_female: any; + other: PokemonOtherSprites; + versions: PokemonVersions; +}; + +export type PokemonOtherSprites = { + dream_world: PokemonDreamWorldSprites; + home: PokemonHomeSprites; + "official-artwork": PokemonOfficialArtworkSprites; +}; + +export type PokemonDreamWorldSprites = { + front_default: string; + front_female: any; +}; + +export type PokemonHomeSprites = { + front_default: string; + front_female: any; + front_shiny: string; + front_shiny_female: any; +}; + +export type PokemonOfficialArtworkSprites = { + front_default: string; + front_shiny: string; +}; + +export type PokemonVersions = { + "generation-i": PokemonGenerationI; + "generation-ii": PokemonGenerationIi; + "generation-iii": PokemonGenerationIii; + "generation-iv": PokemonGenerationIv; + "generation-v": PokemonGenerationV; + "generation-vi": PokemonGenerationVi; + "generation-vii": PokemonGenerationVii; + "generation-viii": PokemonGenerationViii; +}; + +export type PokemonGenerationI = { + "red-blue": PokemonRedBlue; + yellow: PokemonYellow; +}; + +export type PokemonRedBlue = { + back_default: string; + back_gray: string; + back_transparent: string; + front_default: string; + front_gray: string; + front_transparent: string; +}; + +export type PokemonYellow = { + back_default: string; + back_gray: string; + back_transparent: string; + front_default: string; + front_gray: string; + front_transparent: string; +}; + +export type PokemonGenerationIi = { + crystal: PokemonCrystal; + gold: PokemonGold; + silver: PokemonSilver; +}; + +export type PokemonCrystal = { + back_default: string; + back_shiny: string; + back_shiny_transparent: string; + back_transparent: string; + front_default: string; + front_shiny: string; + front_shiny_transparent: string; + front_transparent: string; +}; + +export type PokemonGold = { + back_default: string; + back_shiny: string; + front_default: string; + front_shiny: string; + front_transparent: string; +}; + +export type PokemonSilver = { + back_default: string; + back_shiny: string; + front_default: string; + front_shiny: string; + front_transparent: string; +}; + +export type PokemonGenerationIii = { + emerald: PokemonEmerald; + "firered-leafgreen": PokemonFireredLeafgreen; + "ruby-sapphire": PokemonRubySapphire; +}; + +export type PokemonEmerald = { + front_default: string; + front_shiny: string; +}; + +export type PokemonFireredLeafgreen = { + back_default: string; + back_shiny: string; + front_default: string; + front_shiny: string; +}; + +export type PokemonRubySapphire = { + back_default: string; + back_shiny: string; + front_default: string; + front_shiny: string; +}; + +export type PokemonGenerationIv = { + "diamond-pearl": PokemonDiamondPearl; + "heartgold-soulsilver": PokemonHeartgoldSoulsilver; + platinum: PokemonPlatinum; +}; + +export type PokemonDiamondPearl = { + back_default: string; + back_female: any; + back_shiny: string; + back_shiny_female: any; + front_default: string; + front_female: any; + front_shiny: string; + front_shiny_female: any; +}; + +export type PokemonHeartgoldSoulsilver = { + back_default: string; + back_female: any; + back_shiny: string; + back_shiny_female: any; + front_default: string; + front_female: any; + front_shiny: string; + front_shiny_female: any; +}; + +export type PokemonPlatinum = { + back_default: string; + back_female: any; + back_shiny: string; + back_shiny_female: any; + front_default: string; + front_female: any; + front_shiny: string; + front_shiny_female: any; +}; + +export type PokemonGenerationV = { + "black-white": PokemonBlackWhite; +}; + +export type PokemonBlackWhite = { + animated: PokemonAnimated; + back_default: string; + back_female: any; + back_shiny: string; + back_shiny_female: any; + front_default: string; + front_female: any; + front_shiny: string; + front_shiny_female: any; +}; + +export type PokemonAnimated = { + back_default: string; + back_female: any; + back_shiny: string; + back_shiny_female: any; + front_default: string; + front_female: any; + front_shiny: string; + front_shiny_female: any; +}; + +export type PokemonGenerationVi = { + "omegaruby-alphasapphire": PokemonOmegarubyAlphasapphire; + "x-y": PokemonXY; +}; + +export type PokemonOmegarubyAlphasapphire = { + front_default: string; + front_female: any; + front_shiny: string; + front_shiny_female: any; +}; + +export type PokemonXY = { + front_default: string; + front_female: any; + front_shiny: string; + front_shiny_female: any; +}; + +export type PokemonGenerationVii = { + icons: PokemonIcons; + "ultra-sun-ultra-moon": PokemonUltraSunUltraMoon; +}; + +export type PokemonIcons = { + front_default: string; + front_female: any; +}; + +export type PokemonUltraSunUltraMoon = { + front_default: string; + front_female: any; + front_shiny: string; + front_shiny_female: any; +}; + +export type PokemonGenerationViii = { + icons: PokemonIcons2; +}; + +export type PokemonIcons2 = { + front_default: string; + front_female: any; +}; + +export type PokemonStats = { + base_stat: number; + effort: number; + stat: PokemonStat; +}; + +export type PokemonStat = { + name: string; + url: string; +}; + +export type PokemonTypes = { + slot: number; + type: PokemonType; +}; + +export type PokemonType = { + name: string; + url: string; +}; diff --git a/04-poke-battle-with-prisma/frontend/src/utils/clsxm.ts b/04-poke-battle-with-prisma/frontend/src/utils/clsxm.ts new file mode 100644 index 0000000..97440a6 --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/src/utils/clsxm.ts @@ -0,0 +1,3 @@ +import clsx, { ClassValue } from "clsx"; +import { twMerge } from "tailwind-merge"; +export const clsxm = (...classes: ClassValue[]) => twMerge(clsx(...classes)); diff --git a/04-poke-battle-with-prisma/frontend/src/utils/enums/index.ts b/04-poke-battle-with-prisma/frontend/src/utils/enums/index.ts new file mode 100644 index 0000000..36c4a48 --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/src/utils/enums/index.ts @@ -0,0 +1,18 @@ +export enum defaultAvatarEnum { + backgroundColor = "c0aede", + earrings = "variant03", + earringsProbability = 0, + eyebrows = "variant10", + eyes = "variant17", + features = "birthmark", + featuresProbability = 0, + flip = 1, + glasses = "variant04", + glassesProbability = 0, + hair = "short07", + hairColor = "6a4e35", + hairProbability = 100, + mouth = "variant10", + seed = "ExpressoTS", + skinColor = "ecad80", +} diff --git a/04-poke-battle-with-prisma/frontend/src/utils/mountAuthRoute.ts b/04-poke-battle-with-prisma/frontend/src/utils/mountAuthRoute.ts new file mode 100644 index 0000000..056e43f --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/src/utils/mountAuthRoute.ts @@ -0,0 +1,3 @@ +import { ROUTE } from "../routes"; + +export const mountAuthRoute = (route: string) => `${ROUTE.auth}${route}`; diff --git a/04-poke-battle-with-prisma/frontend/src/vite-env.d.ts b/04-poke-battle-with-prisma/frontend/src/vite-env.d.ts new file mode 100644 index 0000000..11f02fe --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/src/vite-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/04-poke-battle-with-prisma/frontend/tailwind.config.js b/04-poke-battle-with-prisma/frontend/tailwind.config.js new file mode 100644 index 0000000..8123426 --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/tailwind.config.js @@ -0,0 +1,35 @@ +/** @type {import('tailwindcss').Config} */ +export default { + content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"], + theme: { + extend: { + keyframes: { + fadeIn: { + "0%, 100%": { + transform: "translateY(50px)", + opacity: 0, + }, + "100%": { + transform: "translateY(0px)", + opacity: 1, + }, + }, + leftSlide: { + "0%, 100%": { + transform: "translateX(-20px)", + opacity: 0, + }, + "100%": { + transform: "translateX(0px)", + opacity: 1, + }, + }, + }, + animation: { + fadeIn: "fadeIn 0.5s ease forwards", + leftSlide: "leftSlide 0.6s ease forwards", + }, + }, + }, + plugins: [require("daisyui"), require("tailwind-scrollbar-hide")], +}; diff --git a/04-poke-battle-with-prisma/frontend/tsconfig.json b/04-poke-battle-with-prisma/frontend/tsconfig.json new file mode 100644 index 0000000..3d0a51a --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/tsconfig.json @@ -0,0 +1,21 @@ +{ + "compilerOptions": { + "target": "ESNext", + "useDefineForClassFields": true, + "lib": ["DOM", "DOM.Iterable", "ESNext"], + "allowJs": false, + "skipLibCheck": true, + "esModuleInterop": false, + "allowSyntheticDefaultImports": true, + "strict": true, + "forceConsistentCasingInFileNames": true, + "module": "ESNext", + "moduleResolution": "Node", + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "react-jsx" + }, + "include": ["src"], + "references": [{ "path": "./tsconfig.node.json" }] +} diff --git a/04-poke-battle-with-prisma/frontend/tsconfig.node.json b/04-poke-battle-with-prisma/frontend/tsconfig.node.json new file mode 100644 index 0000000..9d31e2a --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/tsconfig.node.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "composite": true, + "module": "ESNext", + "moduleResolution": "Node", + "allowSyntheticDefaultImports": true + }, + "include": ["vite.config.ts"] +} diff --git a/04-poke-battle-with-prisma/frontend/vite.config.ts b/04-poke-battle-with-prisma/frontend/vite.config.ts new file mode 100644 index 0000000..96b9117 --- /dev/null +++ b/04-poke-battle-with-prisma/frontend/vite.config.ts @@ -0,0 +1,15 @@ +import { defineConfig } from "vite"; +import react from "@vitejs/plugin-react"; +import eslintPlugin from "vite-plugin-eslint"; + +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [ + react(), + eslintPlugin({ + cache: false, + include: ["./src/**/*.js", "./src/**/*.jsx"], + exclude: [], + }), + ], +}); diff --git a/04-poke-battle-with-prisma/package-lock.json b/04-poke-battle-with-prisma/package-lock.json index df30e58..0f92339 100644 --- a/04-poke-battle-with-prisma/package-lock.json +++ b/04-poke-battle-with-prisma/package-lock.json @@ -14,17 +14,20 @@ "bcrypt": "^5.1.0", "body-parser": "^1.20.2", "compression": "^1.7.4", + "cors": "^2.8.5", "dotenv": "^16.0.3", "inversify": "^6.0.1", "inversify-binding-decorators": "^4.0.0", "inversify-express-utils": "^6.3.2", "jsonwebtoken": "^9.0.0", + "qs": "^6.11.2", "reflect-metadata": "^0.1.13", "tsconfig-paths": "^4.1.2" }, "devDependencies": { "@types/bcrypt": "^5.0.0", "@types/compression": "^1.7.2", + "@types/cors": "^2.8.13", "@types/express": "^4.17.17", "@types/jest": "^29.4.0", "@types/jsonwebtoken": "^9.0.1", @@ -1895,6 +1898,15 @@ "@types/node": "*" } }, + "node_modules/@types/cors": { + "version": "2.8.13", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.13.tgz", + "integrity": "sha512-RG8AStHlUiV5ysZQKq97copd2UmVYw3/pRMLefISZ3S1hK104Cwm7iLQ3fTKx+lsUH2CE8FlLaYeEA2LSeqYUA==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/express": { "version": "4.17.17", "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.17.tgz", @@ -2725,6 +2737,20 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, + "node_modules/body-parser/node_modules/qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/boxen": { "version": "7.0.2", "resolved": "https://registry.npmjs.org/boxen/-/boxen-7.0.2.tgz", @@ -3703,6 +3729,18 @@ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, "node_modules/cosmiconfig": { "version": "8.1.3", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.1.3.tgz", @@ -4843,6 +4881,20 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, + "node_modules/express/node_modules/qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/express/node_modules/raw-body": { "version": "2.5.1", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", @@ -9081,9 +9133,9 @@ } }, "node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "version": "6.11.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz", + "integrity": "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==", "dependencies": { "side-channel": "^1.0.4" }, @@ -12796,6 +12848,15 @@ "@types/node": "*" } }, + "@types/cors": { + "version": "2.8.13", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.13.tgz", + "integrity": "sha512-RG8AStHlUiV5ysZQKq97copd2UmVYw3/pRMLefISZ3S1hK104Cwm7iLQ3fTKx+lsUH2CE8FlLaYeEA2LSeqYUA==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/express": { "version": "4.17.17", "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.17.tgz", @@ -13416,6 +13477,14 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "requires": { + "side-channel": "^1.0.4" + } } } }, @@ -14129,6 +14198,15 @@ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" }, + "cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "requires": { + "object-assign": "^4", + "vary": "^1" + } + }, "cosmiconfig": { "version": "8.1.3", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.1.3.tgz", @@ -14938,6 +15016,14 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, + "qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "requires": { + "side-channel": "^1.0.4" + } + }, "raw-body": { "version": "2.5.1", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", @@ -17992,9 +18078,9 @@ "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==" }, "qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "version": "6.11.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz", + "integrity": "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==", "requires": { "side-channel": "^1.0.4" } diff --git a/04-poke-battle-with-prisma/package.json b/04-poke-battle-with-prisma/package.json index 7cb36e7..f901437 100644 --- a/04-poke-battle-with-prisma/package.json +++ b/04-poke-battle-with-prisma/package.json @@ -20,6 +20,7 @@ "devDependencies": { "@types/bcrypt": "^5.0.0", "@types/compression": "^1.7.2", + "@types/cors": "^2.8.13", "@types/express": "^4.17.17", "@types/jest": "^29.4.0", "@types/jsonwebtoken": "^9.0.1", @@ -42,11 +43,13 @@ "bcrypt": "^5.1.0", "body-parser": "^1.20.2", "compression": "^1.7.4", + "cors": "^2.8.5", "dotenv": "^16.0.3", "inversify": "^6.0.1", "inversify-binding-decorators": "^4.0.0", "inversify-express-utils": "^6.3.2", "jsonwebtoken": "^9.0.0", + "qs": "^6.11.2", "reflect-metadata": "^0.1.13", "tsconfig-paths": "^4.1.2" } diff --git a/04-poke-battle-with-prisma/prisma/migrations/20230416144936_init/migration.sql b/04-poke-battle-with-prisma/prisma/migrations/20230416144936_init/migration.sql deleted file mode 100644 index 7039b31..0000000 --- a/04-poke-battle-with-prisma/prisma/migrations/20230416144936_init/migration.sql +++ /dev/null @@ -1,28 +0,0 @@ --- CreateTable -CREATE TABLE "User" ( - "id" TEXT NOT NULL, - "email" TEXT NOT NULL, - "name" TEXT NOT NULL, - "password" TEXT NOT NULL, - - CONSTRAINT "User_pkey" PRIMARY KEY ("id") -); - --- CreateTable -CREATE TABLE "History" ( - "id" TEXT NOT NULL, - "log" JSONB[], - "playerId" TEXT NOT NULL, - "userName" TEXT NOT NULL, - "winner" BOOLEAN NOT NULL, - "pokemon1" TEXT NOT NULL, - "pokemon2" TEXT NOT NULL, - "winnerName" TEXT NOT NULL, - "loserName" TEXT NOT NULL, - "isDraw" BOOLEAN NOT NULL, - - CONSTRAINT "History_pkey" PRIMARY KEY ("id") -); - --- CreateIndex -CREATE UNIQUE INDEX "User_email_key" ON "User"("email"); diff --git a/04-poke-battle-with-prisma/prisma/migrations/20230521182847_init/migration.sql b/04-poke-battle-with-prisma/prisma/migrations/20230521182847_init/migration.sql new file mode 100644 index 0000000..c5741e9 --- /dev/null +++ b/04-poke-battle-with-prisma/prisma/migrations/20230521182847_init/migration.sql @@ -0,0 +1,56 @@ +-- CreateTable +CREATE TABLE "User" ( + "id" TEXT NOT NULL, + "email" TEXT NOT NULL, + "name" TEXT NOT NULL, + "password" TEXT NOT NULL, + + CONSTRAINT "User_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "Avatar" ( + "id" TEXT NOT NULL, + "backgroundColor" TEXT NOT NULL, + "earrings" TEXT NOT NULL, + "earringsProbability" INTEGER NOT NULL, + "glassesProbability" INTEGER NOT NULL, + "featuresProbability" INTEGER NOT NULL, + "hairProbability" INTEGER NOT NULL, + "eyebrows" TEXT NOT NULL, + "eyes" TEXT NOT NULL, + "features" TEXT NOT NULL, + "glasses" TEXT NOT NULL, + "hair" TEXT NOT NULL, + "hairColor" TEXT NOT NULL, + "mouth" TEXT NOT NULL, + "seed" TEXT NOT NULL, + "skinColor" TEXT NOT NULL, + "flip" BOOLEAN NOT NULL, + "userId" TEXT NOT NULL, + "url" TEXT NOT NULL, + + CONSTRAINT "Avatar_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "Battle" ( + "id" TEXT NOT NULL, + "log" JSONB[], + "playerId" TEXT NOT NULL, + "userName" TEXT NOT NULL, + "winner" BOOLEAN NOT NULL, + "pokemon1" JSONB NOT NULL, + "pokemon2" JSONB NOT NULL, + "winnerName" TEXT NOT NULL, + "loserName" TEXT NOT NULL, + "isDraw" BOOLEAN NOT NULL, + + CONSTRAINT "Battle_pkey" PRIMARY KEY ("id") +); + +-- CreateIndex +CREATE UNIQUE INDEX "User_email_key" ON "User"("email"); + +-- CreateIndex +CREATE UNIQUE INDEX "Avatar_userId_key" ON "Avatar"("userId"); diff --git a/04-poke-battle-with-prisma/prisma/schema.prisma b/04-poke-battle-with-prisma/prisma/schema.prisma index 5e0c51b..5df7391 100644 --- a/04-poke-battle-with-prisma/prisma/schema.prisma +++ b/04-poke-battle-with-prisma/prisma/schema.prisma @@ -12,22 +12,46 @@ datasource db { } model User { - id String @id @default(uuid()) - email String @unique + id String @id @default(uuid()) + email String @unique name String password String - History History[] + avatar Avatar? + Battle Battle[] } -model History { - id String @id @default(uuid()) - player User @relation(fields: [playerId], references: [id]) +model Avatar { + id String @id @default(uuid()) + backgroundColor String + earrings String + earringsProbability Int + glassesProbability Int + featuresProbability Int + hairProbability Int + eyebrows String + eyes String + features String + glasses String + hair String + hairColor String + mouth String + seed String + skinColor String + flip Boolean + user User @relation(fields: [userId], references: [id]) + userId String @unique + url String +} + +model Battle { + id String @id @default(uuid()) + player User @relation(fields: [playerId], references: [id]) log Json[] playerId String // relation scalar field (used in the `@relation` attribute above) userName String winner Boolean - pokemon1 String - pokemon2 String + pokemon1 Json + pokemon2 Json winnerName String loserName String isDraw Boolean diff --git a/04-poke-battle-with-prisma/src/entities/history.entity.ts b/04-poke-battle-with-prisma/src/entities/battle.entity.ts similarity index 70% rename from 04-poke-battle-with-prisma/src/entities/history.entity.ts rename to 04-poke-battle-with-prisma/src/entities/battle.entity.ts index dea8314..6cb790d 100644 --- a/04-poke-battle-with-prisma/src/entities/history.entity.ts +++ b/04-poke-battle-with-prisma/src/entities/battle.entity.ts @@ -1,8 +1,9 @@ +import { IPokeBattleHistoryEndpoint } from "@providers/types/battle"; import { randomUUID } from "crypto"; import { provide } from "inversify-binding-decorators"; -@provide(History) -class History { +@provide(Battle) +class Battle { private _id: string; private _playerId: string; public log: { @@ -15,8 +16,16 @@ class History { }[]; public userName: string; public winner: boolean; - public pokemon1: string; - public pokemon2: string; + public pokemon1: { + name: string; + sprites: string[]; + types: string[]; + }; + public pokemon2: { + name: string; + sprites: string[]; + types: string[]; + }; public winnerName: string; public loserName: string; public isDraw: boolean; @@ -33,8 +42,16 @@ class History { userName: string, playerId: string, winner: boolean, - pokemon1: string, - pokemon2: string, + pokemon1: { + name: string; + sprites: string[]; + types: string[]; + }, + pokemon2: { + name: string; + sprites: string[]; + types: string[]; + }, id: string, winnerName: string, loserName: string, @@ -61,4 +78,4 @@ class History { } } -export { History }; +export { Battle }; diff --git a/04-poke-battle-with-prisma/src/entities/user.entity.ts b/04-poke-battle-with-prisma/src/entities/user.entity.ts index d613921..a619a04 100644 --- a/04-poke-battle-with-prisma/src/entities/user.entity.ts +++ b/04-poke-battle-with-prisma/src/entities/user.entity.ts @@ -1,19 +1,27 @@ +import { IUserAvatarDTO } from "@repositories/user/user.dto"; import { randomUUID } from "crypto"; import { provide } from "inversify-binding-decorators"; @provide(User) class User { private _id: string; - private _password: string; public name: string; public email: string; + public avatar: IUserAvatarDTO; - constructor(name: string, email: string, password: string, id?: string) { + constructor( + name: string, + email: string, + password: string, + avatar: IUserAvatarDTO, + id?: string, + ) { this._id = id ?? randomUUID(); this.name = name; this.email = email; this._password = password; + this.avatar = avatar; } get id(): string { diff --git a/04-poke-battle-with-prisma/src/main.ts b/04-poke-battle-with-prisma/src/main.ts index a9223a1..c11e557 100644 --- a/04-poke-battle-with-prisma/src/main.ts +++ b/04-poke-battle-with-prisma/src/main.ts @@ -6,11 +6,15 @@ import { ServerEnvironment } from "@expressots/core"; import ENV from "./env"; import express from "express"; import compression from "compression"; +import cors from "cors"; async function Bootstrap() { const app = App.create(container, [ express.json({ limit: "50mb" }), compression(), + cors({ + origin: "*", + }), ]); app.listen( ENV.Application.PORT, diff --git a/04-poke-battle-with-prisma/src/providers/database/orm/prisma/prisma-client.provider.ts b/04-poke-battle-with-prisma/src/providers/database/orm/prisma/prisma-client.provider.ts index c300a5e..c327d04 100644 --- a/04-poke-battle-with-prisma/src/providers/database/orm/prisma/prisma-client.provider.ts +++ b/04-poke-battle-with-prisma/src/providers/database/orm/prisma/prisma-client.provider.ts @@ -1,12 +1,6 @@ -import { History } from "@entities/history.entity"; -import { User } from "@entities/user.entity"; import { PrismaClient } from "@prisma/client"; -import { IHistoryDTO } from "@repositories/history/history.dto"; -import { IUserDTO } from "@repositories/user/user.dto"; import { provide } from "inversify-binding-decorators"; -type PrismaType = User | History; -type DTOType = IUserDTO | IHistoryDTO | History; export const prismaClient: PrismaClient = new PrismaClient(); @provide(PrismaClientProvider) diff --git a/04-poke-battle-with-prisma/src/providers/database/prismaClient.ts b/04-poke-battle-with-prisma/src/providers/database/prismaClient.ts new file mode 100644 index 0000000..11bbdfe --- /dev/null +++ b/04-poke-battle-with-prisma/src/providers/database/prismaClient.ts @@ -0,0 +1,3 @@ +import { PrismaClient } from "@prisma/client"; + +export const prismaClient = new PrismaClient(); diff --git a/04-poke-battle-with-prisma/src/providers/types/avatar/index.tsx b/04-poke-battle-with-prisma/src/providers/types/avatar/index.tsx new file mode 100644 index 0000000..6fd5152 --- /dev/null +++ b/04-poke-battle-with-prisma/src/providers/types/avatar/index.tsx @@ -0,0 +1,167 @@ +export type TAvatarBackgroundColor = + | "b6e3f4" + | "c0aede" + | "d1d4f9" + | "ffd5dc" + | "ffdfbf"; + +export type TAvatarEarrings = + | "variant01" + | "variant02" + | "variant03" + | "variant04" + | "variant05" + | "variant06"; + +export type TAvatarEyebrows = + | "variant01" + | "variant02" + | "variant03" + | "variant04" + | "variant05" + | "variant06" + | "variant07" + | "variant08" + | "variant09" + | "variant10" + | "variant11" + | "variant12" + | "variant13" + | "variant14" + | "variant15"; + +export type TAvatarEyes = + | "variant01" + | "variant02" + | "variant03" + | "variant04" + | "variant05" + | "variant06" + | "variant07" + | "variant08" + | "variant09" + | "variant10" + | "variant11" + | "variant12" + | "variant13" + | "variant14" + | "variant15" + | "variant16" + | "variant17" + | "variant18" + | "variant19" + | "variant20" + | "variant21" + | "variant22" + | "variant23" + | "variant24" + | "variant25" + | "variant26"; + +export type TAvatarFeatures = "birthmark" | "blush" | "freckles" | "mustache"; + +export type TAvatarGlasses = + | "variant01" + | "variant02" + | "variant03" + | "variant04" + | "variant05"; + +export type TAvatarHair = + | "long01" + | "long02" + | "long03" + | "long04" + | "long05" + | "long06" + | "long07" + | "long08" + | "long09" + | "long10" + | "long11" + | "long12" + | "long13" + | "long14" + | "long15" + | "long16" + | "long17" + | "long18" + | "long19" + | "long20" + | "long21" + | "long22" + | "long23" + | "long24" + | "long25" + | "long26" + | "short01" + | "short02" + | "short03" + | "short04" + | "short05" + | "short06" + | "short07" + | "short08" + | "short09" + | "short10" + | "short11" + | "short12" + | "short13" + | "short14" + | "short15" + | "short16" + | "short17" + | "short18" + | "short19"; + +export type TAvatarHairColor = + | "0e0e0e" + | "3eac2c" + | "6a4e35" + | "85c2c6" + | "796a45" + | "562306" + | "592454" + | "ab2a18" + | "ac6511" + | "afafaf" + | "b9a05f" + | "cb6820" + | "dba3be" + | "e5d7a3" + | "f3f4f6" + | "fde68a"; + +export type TAvatarMouth = + | "variant01" + | "variant02" + | "variant03" + | "variant04" + | "variant05" + | "variant06" + | "variant07" + | "variant08" + | "variant09" + | "variant10" + | "variant11" + | "variant12" + | "variant13" + | "variant14" + | "variant15" + | "variant16" + | "variant17" + | "variant18" + | "variant19" + | "variant20" + | "variant21" + | "variant22" + | "variant23" + | "variant24" + | "variant25" + | "variant26" + | "variant27" + | "variant28" + | "variant29" + | "variant30"; + +export type TAvatarSkinColor = "9e5622" | "763900" | "ecad80" | "f2d3b1"; diff --git a/04-poke-battle-with-prisma/src/providers/types/battle/index.ts b/04-poke-battle-with-prisma/src/providers/types/battle/index.ts index 23e5ccb..d128115 100644 --- a/04-poke-battle-with-prisma/src/providers/types/battle/index.ts +++ b/04-poke-battle-with-prisma/src/providers/types/battle/index.ts @@ -19,6 +19,12 @@ export type TPokemonContentEndpoint = { weight: number; }; +export interface IPokeBattleHistoryEndpoint { + name: string; + sprites: string[]; + types: string[]; +} + export type PokemonAbilities = { ability: PokemonAbility; is_hidden: boolean; diff --git a/04-poke-battle-with-prisma/src/repositories/battle/battle-repository.interface.ts b/04-poke-battle-with-prisma/src/repositories/battle/battle-repository.interface.ts new file mode 100644 index 0000000..09b2aa3 --- /dev/null +++ b/04-poke-battle-with-prisma/src/repositories/battle/battle-repository.interface.ts @@ -0,0 +1,8 @@ +import { IBattleDTO } from "./battle.dto"; + +interface IBattleRepository { + findAll(id: string): Promise; + create(user: IBattleDTO): Promise; +} + +export { IBattleRepository }; diff --git a/04-poke-battle-with-prisma/src/repositories/history/history.dto.ts b/04-poke-battle-with-prisma/src/repositories/battle/battle.dto.ts similarity index 58% rename from 04-poke-battle-with-prisma/src/repositories/history/history.dto.ts rename to 04-poke-battle-with-prisma/src/repositories/battle/battle.dto.ts index 14e2bf7..ac0b22a 100644 --- a/04-poke-battle-with-prisma/src/repositories/history/history.dto.ts +++ b/04-poke-battle-with-prisma/src/repositories/battle/battle.dto.ts @@ -1,9 +1,11 @@ -interface IHistoryDTO { +import { IPokeBattleHistoryEndpoint } from "@providers/types/battle"; + +interface IBattleDTO { id?: string; userName: string; playerId: string; - pokemon1: string; - pokemon2: string; + pokemon1: IPokeBattleHistoryEndpoint; + pokemon2: IPokeBattleHistoryEndpoint; log: { turn: number; attacker: string; @@ -18,4 +20,4 @@ interface IHistoryDTO { isDraw: boolean; } -export { IHistoryDTO }; +export { IBattleDTO }; diff --git a/04-poke-battle-with-prisma/src/repositories/battle/battle.repository.ts b/04-poke-battle-with-prisma/src/repositories/battle/battle.repository.ts new file mode 100644 index 0000000..7c4bfa4 --- /dev/null +++ b/04-poke-battle-with-prisma/src/repositories/battle/battle.repository.ts @@ -0,0 +1,75 @@ +import { Battle } from "@entities/battle.entity"; +import { + PrismaClientProvider, + prismaClient, +} from "@providers/database/orm/prisma/prisma-client.provider"; +import { provide } from "inversify-binding-decorators"; +import { IBattleRepository } from "./battle-repository.interface"; +import { IBattleDTO } from "./battle.dto"; +import { randomUUID } from "crypto"; +import { IPokeBattleHistoryEndpoint } from "@providers/types/battle"; + +@provide(BattleRepository) +class BattleRepository implements IBattleRepository { + constructor(private prismaProvider: PrismaClientProvider) {} + + async findAll(id: string): Promise { + this.prismaProvider.mapToPrisma; + const battles = await prismaClient.battle.findMany({ + where: { + playerId: id, + }, + }); + + return battles.map((battle) => { + const log = battle.log as { + turn: number; + attacker: string; + defender: string; + attack: string; + attackType: string; + damage: number; + }[]; + + const pokemon1 = battle.pokemon1 as unknown as IPokeBattleHistoryEndpoint; + const pokemon2 = battle.pokemon2 as unknown as IPokeBattleHistoryEndpoint; + return this.mapToDTO({ ...battle, log, pokemon1, pokemon2 }); + }); + } + + async create(battle: IBattleDTO): Promise { + const createHistory = await prismaClient.battle.create({ + data: this.prismaProvider.mapToPrisma(battle), + }); + + const log = createHistory.log as { + turn: number; + attacker: string; + defender: string; + attack: string; + attackType: string; + damage: number; + }[]; + const pokemon1 = battle.pokemon1 as IPokeBattleHistoryEndpoint; + const pokemon2 = battle.pokemon2 as IPokeBattleHistoryEndpoint; + return this.mapToDTO({ ...createHistory, log, pokemon1, pokemon2 }); + } + + private mapToDTO(battle: IBattleDTO): Battle { + const newHistory = new Battle( + battle.log, + battle.userName, + battle.playerId, + battle.winner, + battle.pokemon1, + battle.pokemon2, + battle.id || randomUUID(), + battle.winnerName, + battle.loserName, + battle.isDraw, + ); + return newHistory; + } +} + +export { BattleRepository }; diff --git a/04-poke-battle-with-prisma/src/repositories/history/history-repository.interface.ts b/04-poke-battle-with-prisma/src/repositories/history/history-repository.interface.ts deleted file mode 100644 index 7baff79..0000000 --- a/04-poke-battle-with-prisma/src/repositories/history/history-repository.interface.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { IHistoryDTO } from "./history.dto"; - -interface IHistoryRepository { - findAll(id: string): Promise; - create(user: IHistoryDTO): Promise; -} - -export { IHistoryRepository }; diff --git a/04-poke-battle-with-prisma/src/repositories/history/history.repository.ts b/04-poke-battle-with-prisma/src/repositories/history/history.repository.ts deleted file mode 100644 index 5b86737..0000000 --- a/04-poke-battle-with-prisma/src/repositories/history/history.repository.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { History } from "@entities/history.entity"; -import { PrismaClientProvider } from "@providers/database/orm/prisma/prisma-client.provider"; -import { provide } from "inversify-binding-decorators"; -import { IHistoryRepository } from "./history-repository.interface"; -import { IHistoryDTO } from "./history.dto"; -import { randomUUID } from "crypto"; - -@provide(HistoryRepository) -class HistoryRepository implements IHistoryRepository { - constructor(private prismaClient: PrismaClientProvider) {} - - async findAll(id: string): Promise { - const historys = await this.prismaClient.client.history.findMany({ - where: { - playerId: id, - }, - }); - - return historys.map((history) => { - const log = history.log as { - turn: number; - attacker: string; - defender: string; - attack: string; - attackType: string; - damage: number; - }[]; - return this.mapToDTO({ ...history, log }); - }); - } - - async create(history: IHistoryDTO): Promise { - const createHistory = await this.prismaClient.client.history.create({ - data: this.prismaClient.mapToPrisma(history), - }); - - const log = createHistory.log as { - turn: number; - attacker: string; - defender: string; - attack: string; - attackType: string; - damage: number; - }[]; - - return this.mapToDTO({ ...createHistory, log }); - } - - private mapToDTO(history: IHistoryDTO): History { - const newHistory = new History( - history.log, - history.userName, - history.playerId, - history.winner, - history.pokemon1, - history.pokemon2, - history.id || randomUUID(), - history.winnerName, - history.loserName, - history.isDraw, - ); - return newHistory; - } -} - -export { HistoryRepository }; diff --git a/04-poke-battle-with-prisma/src/repositories/user/user.dto.ts b/04-poke-battle-with-prisma/src/repositories/user/user.dto.ts index dfcfc77..8273156 100644 --- a/04-poke-battle-with-prisma/src/repositories/user/user.dto.ts +++ b/04-poke-battle-with-prisma/src/repositories/user/user.dto.ts @@ -1,8 +1,42 @@ +import { + TAvatarBackgroundColor, + TAvatarEarrings, + TAvatarEyebrows, + TAvatarEyes, + TAvatarFeatures, + TAvatarGlasses, + TAvatarHair, + TAvatarHairColor, + TAvatarMouth, + TAvatarSkinColor, +} from "@providers/types/avatar"; + interface IUserDTO { id?: string; password: string; email: string; name: string; + avatar: IUserAvatarDTO; +} + +interface IUserAvatarDTO { + backgroundColor: TAvatarBackgroundColor; + earrings: TAvatarEarrings; + earringsProbability: 0 | 100; + glassesProbability: 0 | 100; + featuresProbability: 0 | 100; + hairProbability: 100; + eyebrows: TAvatarEyebrows; + eyes: TAvatarEyes; + features: TAvatarFeatures; + glasses: TAvatarGlasses; + hair: TAvatarHair; + hairColor: TAvatarHairColor; + mouth: TAvatarMouth; + seed: string; + skinColor: TAvatarSkinColor; + flip: boolean; + url: string; } -export { IUserDTO }; +export { IUserDTO, IUserAvatarDTO }; diff --git a/04-poke-battle-with-prisma/src/repositories/user/user.repository.ts b/04-poke-battle-with-prisma/src/repositories/user/user.repository.ts index ca70598..265e1c6 100644 --- a/04-poke-battle-with-prisma/src/repositories/user/user.repository.ts +++ b/04-poke-battle-with-prisma/src/repositories/user/user.repository.ts @@ -1,3 +1,4 @@ +import * as PrismaModelType from "@prisma/client"; import { User } from "@entities/user.entity"; import { PrismaClientProvider, @@ -6,7 +7,7 @@ import { import bcrypt from "bcrypt"; import { provide } from "inversify-binding-decorators"; import { IUserRepository } from "./user-repository.interface"; -import { IUserDTO } from "./user.dto"; +import { IUserAvatarDTO, IUserDTO } from "./user.dto"; @provide(UserRepository) class UserRepository implements IUserRepository { @@ -15,44 +16,84 @@ class UserRepository implements IUserRepository { async find(id: string): Promise<{ name: string; email: string } | null> { const user = await prismaClient.user.findUnique({ where: { id }, + include: { + avatar: true, + }, }); - return user ? this.mapToDTOWithoutPassword(user) : null; + const avatar = user?.avatar as unknown as IUserAvatarDTO; + + return user ? this.mapToDTOWithoutPassword({ ...user, avatar }) : null; } async findByEmail(email: string): Promise { const user = await prismaClient.user.findUnique({ where: { email }, + include: { + avatar: true, + }, }); - return user ? this.mapToDTO(user) : null; + + const avatar = user?.avatar as unknown as IUserAvatarDTO; + + return user ? this.mapToDTO({ ...user, avatar }) : null; } async findAll(): Promise<{ name: string; email: string }[]> { - const users = await prismaClient.user.findMany(); + const users = await prismaClient.user.findMany({ + include: { + avatar: true, + }, + }); + + return users.map((user) => { + const avatar = user?.avatar as unknown as IUserAvatarDTO; - return users.map((user) => this.mapToFindAllDTO(user)); + return this.mapToFindAllDTO({ ...user, avatar }); + }); } async create(user: IUserDTO): Promise { const password = await bcrypt.hash(user.password, 10); + const prismaObject = this.prismaProvider.mapToPrisma< + IUserDTO, + PrismaModelType.User + >({ + ...user, + password, + }); const createdUser = await prismaClient.user.create({ - data: this.prismaProvider.mapToPrisma({ - ...user, - password, - }), + include: { + avatar: true, + }, + data: { + ...prismaObject, + avatar: { + create: { + ...user.avatar, + }, + }, + }, }); - return this.mapToDTO(createdUser); + const avatar = createdUser.avatar as unknown as IUserAvatarDTO; + + return this.mapToDTO({ + ...createdUser, + avatar, + }); } async update(id: string, user: IUserDTO): Promise { const updatedUser = await prismaClient.user.update({ where: { id }, - data: user, + data: this.prismaProvider.mapToPrisma( + user, + ), }); - return this.mapToDTO(updatedUser); + return this.mapToDTO({ ...updatedUser, avatar: user.avatar }); } async delete(id: string): Promise { @@ -61,25 +102,45 @@ class UserRepository implements IUserRepository { } private mapToDTO(user: IUserDTO): User { - const newUser = new User(user.name, user.email, user.password, user.id); + const newUser = new User( + user.name, + user.email, + user.password, + user.avatar, + user.id, + ); return newUser; } private mapToDTOWithoutPassword(user: IUserDTO): { name: string; + avatar: IUserAvatarDTO; email: string; id: string; } { - const newUser = new User(user.name, user.email, user.password, user.id); + const newUser = new User( + user.name, + user.email, + user.password, + user.avatar, + user.id, + ); return { name: newUser.name, email: newUser.email, + avatar: newUser.avatar, id: newUser.id, }; } private mapToFindAllDTO(user: IUserDTO): { name: string; email: string } { - const newUser = new User(user.name, user.email, user.password, user.id); + const newUser = new User( + user.name, + user.email, + user.password, + user.avatar, + user.id, + ); return { name: newUser.name, email: newUser.email, diff --git a/04-poke-battle-with-prisma/src/useCases/pokebattle/battle/pokebattle-battle.dto.ts b/04-poke-battle-with-prisma/src/useCases/pokebattle/battle/pokebattle-battle.dto.ts index bfed543..4819e59 100644 --- a/04-poke-battle-with-prisma/src/useCases/pokebattle/battle/pokebattle-battle.dto.ts +++ b/04-poke-battle-with-prisma/src/useCases/pokebattle/battle/pokebattle-battle.dto.ts @@ -1,4 +1,7 @@ -import { TPokemonContentEndpoint } from "@providers/types/battle"; +import { + IPokeBattleHistoryEndpoint, + TPokemonContentEndpoint, +} from "@providers/types/battle"; interface IPokebattleBattleRequestDTO { pokemon1: TPokemonContentEndpoint; @@ -18,8 +21,8 @@ interface IPokebattleBattleResponseDTO { id?: string; userName: string; playerId: string; - pokemon1: string; - pokemon2: string; + pokemon1: IPokeBattleHistoryEndpoint; + pokemon2: IPokeBattleHistoryEndpoint; log: IPokebattleBattleLogResponseDTO[]; winner: boolean; winnerName: string; diff --git a/04-poke-battle-with-prisma/src/useCases/pokebattle/battle/pokebattle-battle.usecase.ts b/04-poke-battle-with-prisma/src/useCases/pokebattle/battle/pokebattle-battle.usecase.ts index 161c2ad..65afebd 100644 --- a/04-poke-battle-with-prisma/src/useCases/pokebattle/battle/pokebattle-battle.usecase.ts +++ b/04-poke-battle-with-prisma/src/useCases/pokebattle/battle/pokebattle-battle.usecase.ts @@ -4,7 +4,7 @@ import { IPokebattleBattleRequestDTO, IPokebattleBattleResponseDTO, } from "./pokebattle-battle.dto"; -import { HistoryRepository } from "@repositories/history/history.repository"; +import { BattleRepository } from "@repositories/battle/battle.repository"; import { TYPE_CHART } from "@providers/battle/typechart"; import { @@ -19,7 +19,7 @@ import { @provide(PokebattleBattleUseCase) class PokebattleBattleUseCase { - constructor(private historyRepository: HistoryRepository) {} + constructor(private historyRepository: BattleRepository) {} async execute({ body, @@ -30,6 +30,29 @@ class PokebattleBattleUseCase { }): Promise { const { name, id } = token; const { pokemon1, pokemon2 } = body; + + const challenger = { + name: pokemon1.name, + sprites: [ + pokemon1.sprites.versions["generation-v"]["black-white"].animated + .front_default, + pokemon1.sprites.front_default, + pokemon1.sprites.other["official-artwork"].front_default, + ], + types: pokemon1.types.map((item) => item.type.name), + }; + + const challenged = { + name: pokemon2.name, + sprites: [ + pokemon2.sprites.versions["generation-v"]["black-white"].animated + .front_default, + pokemon2.sprites.front_default, + pokemon2.sprites.other["official-artwork"].front_default, + ], + types: pokemon2.types.map((item) => item.type.name), + }; + const onFight = async (): Promise => { // Log da batalha const battleLog = [] as IPokebattleBattleLogResponseDTO[]; @@ -142,12 +165,12 @@ class PokebattleBattleUseCase { return { log: battleLog, playerId: id, - pokemon1: pokemon1.name, - pokemon2: pokemon2.name, + pokemon1: challenger, + pokemon2: challenged, userName: name, winner: true, - winnerName: pokemon1.name, - loserName: pokemon2.name, + winnerName: challenger.name, + loserName: challenged.name, isDraw: false, }; } @@ -159,30 +182,33 @@ class PokebattleBattleUseCase { return { log: battleLog, playerId: id, - pokemon1: pokemon1.name, - pokemon2: pokemon2.name, + pokemon1: challenger, + pokemon2: challenged, userName: name, winner: false, - winnerName: pokemon2.name, - loserName: pokemon1.name, + winnerName: challenged.name, + loserName: challenger.name, isDraw: false, }; } } + return { log: battleLog, playerId: id, - pokemon1: pokemon1.name, - pokemon2: pokemon2.name, + pokemon1: challenger, + pokemon2: challenged, userName: name, winner: false, - loserName: pokemon1.name, - winnerName: pokemon2.name, + loserName: challenger.name, + winnerName: challenged.name, isDraw: true, }; }; - const userHistory = await this.historyRepository.create(await onFight()); + const battle = await onFight(); + + const userHistory = await this.historyRepository.create(battle); return userHistory; } diff --git a/04-poke-battle-with-prisma/src/useCases/pokebattle/history/pokebattle.dto.ts b/04-poke-battle-with-prisma/src/useCases/pokebattle/history/pokebattle.dto.ts index 5e8c101..750a3eb 100644 --- a/04-poke-battle-with-prisma/src/useCases/pokebattle/history/pokebattle.dto.ts +++ b/04-poke-battle-with-prisma/src/useCases/pokebattle/history/pokebattle.dto.ts @@ -1,3 +1,5 @@ +import { IPokeBattleHistoryEndpoint } from "@providers/types/battle"; + interface IPokebattleHistoryRequestDTO { id: string; } @@ -6,8 +8,8 @@ interface IPokebattleHistoryResponseDTO { id?: string; userName: string; playerId: string; - pokemon1: string; - pokemon2: string; + pokemon1: IPokeBattleHistoryEndpoint; + pokemon2: IPokeBattleHistoryEndpoint; log: IPokebattleHistoryBattleLogResponseDTO[]; winner: boolean; winnerName: string; diff --git a/04-poke-battle-with-prisma/src/useCases/pokebattle/history/pokebattle.usecase.ts b/04-poke-battle-with-prisma/src/useCases/pokebattle/history/pokebattle.usecase.ts index 7c8fa7e..eed04ea 100644 --- a/04-poke-battle-with-prisma/src/useCases/pokebattle/history/pokebattle.usecase.ts +++ b/04-poke-battle-with-prisma/src/useCases/pokebattle/history/pokebattle.usecase.ts @@ -3,11 +3,11 @@ import { IPokebattleHistoryRequestDTO, IPokebattleHistoryResponseDTO, } from "./pokebattle.dto"; -import { HistoryRepository } from "@repositories/history/history.repository"; +import { BattleRepository } from "@repositories/battle/battle.repository"; @provide(PokebattleUseCase) class PokebattleUseCase { - constructor(private historyRepository: HistoryRepository) {} + constructor(private historyRepository: BattleRepository) {} async execute( params: IPokebattleHistoryRequestDTO, diff --git a/04-poke-battle-with-prisma/src/useCases/user/create/create-user.dto.ts b/04-poke-battle-with-prisma/src/useCases/user/create/create-user.dto.ts index 20e6da4..c4e53b4 100644 --- a/04-poke-battle-with-prisma/src/useCases/user/create/create-user.dto.ts +++ b/04-poke-battle-with-prisma/src/useCases/user/create/create-user.dto.ts @@ -1,6 +1,9 @@ +import { IUserAvatarDTO } from "@repositories/user/user.dto"; + interface ICreateUserDTO { name: string; email: string; + avatar: IUserAvatarDTO; password: string; } @@ -9,6 +12,8 @@ interface ICreateUserResponseDTO { email: string; token: string; status: string; + avatar: IUserAvatarDTO; + id: string; } export { ICreateUserDTO, ICreateUserResponseDTO }; diff --git a/04-poke-battle-with-prisma/src/useCases/user/create/create-user.usecase.ts b/04-poke-battle-with-prisma/src/useCases/user/create/create-user.usecase.ts index 724c227..6c0b829 100644 --- a/04-poke-battle-with-prisma/src/useCases/user/create/create-user.usecase.ts +++ b/04-poke-battle-with-prisma/src/useCases/user/create/create-user.usecase.ts @@ -3,8 +3,9 @@ import { provide } from "inversify-binding-decorators"; import { ICreateUserDTO, ICreateUserResponseDTO } from "./create-user.dto"; import { UserRepository } from "@repositories/user/user.repository"; import { User } from "@entities/user.entity"; -import { IUserDTO } from "@repositories/user/user.dto"; +import { IUserAvatarDTO, IUserDTO } from "@repositories/user/user.dto"; import { JWTProvider } from "@providers/encrypt/jwt/jwt.provider"; +import { stringify } from "qs"; @provide(CreateUserUseCase) class CreateUserUseCase { @@ -13,9 +14,26 @@ class CreateUserUseCase { private jwtProvider: JWTProvider, ) {} + getAvatarUrl = (avatar: Omit) => { + const AVATAR_BASE_URL = "https://api.dicebear.com/6.x/adventurer"; + const params = stringify( + { + ...avatar, + }, + { + encodeValuesOnly: true, + arrayFormat: "brackets", + }, + ); + + return `${AVATAR_BASE_URL}/svg?seed=${encodeURIComponent(avatar.seed)}${ + params ? `&${params}` : null + }`; + }; + async execute(data: ICreateUserDTO): Promise { try { - const { name, email, password } = data; + const { name, email, password, avatar } = data; const findUser = await this.userRepository.findByEmail(email); @@ -29,8 +47,10 @@ class CreateUserUseCase { ); } + const avatarObject = { ...avatar, url: this.getAvatarUrl(avatar) }; + const user: IUserDTO = await this.userRepository.create( - new User(name, email, password), + new User(name, email, password, avatarObject), ); if (!user) { @@ -53,9 +73,11 @@ class CreateUserUseCase { }); response = { + id: `${user.id}`, token, name: user.name, email: user.email, + avatar: user.avatar, status: "success", }; return response; diff --git a/04-poke-battle-with-prisma/src/useCases/user/login/login-user.dto.ts b/04-poke-battle-with-prisma/src/useCases/user/login/login-user.dto.ts index 36ec122..7cc95e4 100644 --- a/04-poke-battle-with-prisma/src/useCases/user/login/login-user.dto.ts +++ b/04-poke-battle-with-prisma/src/useCases/user/login/login-user.dto.ts @@ -1,6 +1,9 @@ +import { IUserAvatarDTO } from "@repositories/user/user.dto"; + interface ILoginUserDTO { email: string; password: string; + id: string; } interface ILoginUserResponseDTO { @@ -8,6 +11,8 @@ interface ILoginUserResponseDTO { email: string; token: string; status: string; + id: string; + avatar: IUserAvatarDTO; } export { ILoginUserDTO, ILoginUserResponseDTO }; diff --git a/04-poke-battle-with-prisma/src/useCases/user/login/login-user.usecase.ts b/04-poke-battle-with-prisma/src/useCases/user/login/login-user.usecase.ts index 9ee47cd..2869dd8 100644 --- a/04-poke-battle-with-prisma/src/useCases/user/login/login-user.usecase.ts +++ b/04-poke-battle-with-prisma/src/useCases/user/login/login-user.usecase.ts @@ -55,6 +55,8 @@ class LoginUserUsecase { name: findUser.name, email: findUser.email, status: "success", + id: findUser.id, + avatar: findUser.avatar, }; return response;