diff --git a/.dockerignore b/.dockerignore index 3c3629e6..6f2a3352 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1 +1,6 @@ node_modules +dist +buid +.github +.husky +.env* diff --git a/.env b/.env new file mode 100644 index 00000000..0f4af620 --- /dev/null +++ b/.env @@ -0,0 +1 @@ +VITE_API_HOST='' diff --git a/.eslintrc.json b/.eslintrc.json index b7ef4622..b812ba5c 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -13,6 +13,7 @@ "plugin:import/recommended", "plugin:import/warnings", "plugin:import/typescript", + "plugin:boundaries/recommended", "airbnb", "prettier" ], @@ -56,8 +57,63 @@ ], "no-restricted-exports": "off", "prefer-arrow-callback": "off", - "no-shadow": "warn", + "no-shadow": "off", "default-param-last": "warn", + "no-restricted-imports": [ + "error", + { + "patterns": [ + { + "message": "Private imports are prohibited, use public imports instead", + "group": ["@/app/**"] + }, + { + "message": "Private imports are prohibited, use public imports instead", + "group": ["@/pages/*/**"] + }, + { + "message": "Private imports are prohibited, use public imports instead", + "group": ["@/widgets/*/**"] + }, + { + "message": "Private imports are prohibited, use public imports instead", + "group": ["@/features/*/**"] + }, + { + "message": "Private imports are prohibited, use public imports instead", + "group": ["@/entities/*/**"] + }, + { + "message": "Private imports are prohibited, use public imports instead", + "group": ["@/shared/*/*/**"] + }, + { + "message": "Prefer absolute imports instead of relatives (for root modules)", + "group": ["../**/app"] + }, + { + "message": "Prefer absolute imports instead of relatives (for root modules)", + "group": ["../**/pages"] + }, + { + "message": "Prefer absolute imports instead of relatives (for root modules)", + "group": ["../**/widgets"] + }, + { + "message": "Prefer absolute imports instead of relatives (for root modules)", + "group": ["../**/features"] + }, + { + "message": "Prefer absolute imports instead of relatives (for root modules)", + "group": ["../**/entities"] + }, + { + "message": "Prefer absolute imports instead of relatives (for root modules)", + "group": ["../**/shared"] + } + ] + } + ], /* REACT */ "react/jsx-filename-extension": [1, { "extensions": [".tsx", ".ts"] }], @@ -69,8 +125,44 @@ "react/function-component-definition": "off", "react/no-unused-prop-types": "off", "react/no-array-index-key": "off", + "react/react-in-jsx-scope": "off", /* IMPORT */ + "import/order": [ + "error", + { + "alphabetize": { "order": "asc", "caseInsensitive": true }, + "newlines-between": "always", + "pathGroups": [ + { "group": "internal", "position": "after", "pattern": "@/pages/**" }, + { + "group": "internal", + "position": "after", + "pattern": "@/widgets/**" + }, + { + "group": "internal", + "position": "after", + "pattern": "@/features/**" + }, + { + "group": "internal", + "position": "after", + "pattern": "@/entities/**" + }, + { "group": "internal", "position": "after", "pattern": "@/shared/**" } + ], + "pathGroupsExcludedImportTypes": ["builtin"], + "groups": [ + "builtin", + "external", + "internal", + "parent", + "sibling", + "index" + ] + } + ], "import/extensions": [ "error", "never", @@ -87,9 +179,41 @@ "import/no-unresolved": 0, "import/prefer-default-export": "off", + /* BOUNDARIES */ + "boundaries/element-types": [ + "warn", + { + "default": "disallow", + "rules": [ + { + "from": "@/app", + "allow": [ + "@/pages", + "@/widgets", + "@/features", + "@/entities", + "@/shared" + ] + }, + { + "from": "@/pages", + "allow": ["@/widgets", "@/features", "@/entities", "@/shared"] + }, + { + "from": "@/widgets", + "allow": ["@/features", "@/entities", "@/shared"] + }, + { "from": "@/features", "allow": ["@/entities", "@/shared"] }, + { "from": "@/entities", "allow": ["@/shared"] }, + { "from": "@/shared", "allow": ["@/shared"] } + ] + } + ], + /* TS */ "@typescript-eslint/no-unused-vars": ["error"], - "@typescript-eslint/no-empty-interface": ["off"] + "@typescript-eslint/no-empty-interface": ["off"], + "@typescript-eslint/no-explicit-any": "warn" }, "ignorePatterns": ["templates/**/*", "*.css.d.ts", "configs/*"] } diff --git a/.github/workflows/publish-docker-image.yml b/.github/workflows/publish-docker-image.yml new file mode 100644 index 00000000..c07b3651 --- /dev/null +++ b/.github/workflows/publish-docker-image.yml @@ -0,0 +1,39 @@ +name: Docker + +on: + push: + tags: [ 'v*.*.*' ] + pull_request: + branches: [ "main", "develop" ] + release: + types: [ published ] + + +jobs: + push_to_registry: + name: Push Docker image to Docker Hub + runs-on: ubuntu-latest + steps: + - name: Check out the repo + uses: actions/checkout@v4 + + - name: Log in to Docker Hub + uses: docker/login-action@f4ef78c080cd8ba55a85445d5b36e214a81df20a + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7 + with: + images: bricks667/abctasks-client + + - name: Build and push Docker image + uses: docker/build-push-action@3b5e8027fcad23fda98b2e3ac259d8d67585f671 + with: + context: . + file: ./Dockerfile + push: ${{ github.event_name != 'pull_request' }} + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} diff --git a/.gitignore b/.gitignore index 4d29575d..9caf334e 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ # production /build +dist # misc .DS_Store diff --git a/Dockerfile b/Dockerfile index 90eb3772..168e1f7d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,10 +1,26 @@ -FROM node:18-alpine as build +FROM node:lts-alpine as build + WORKDIR /app -COPY package.json /app/package.json -RUN npm i --omit=dev --ignore-scripts --force && npm i -D typescript --force -COPY . /app + +COPY package*.json /app/ +RUN npm ci --ignore-scripts + +COPY . /app/ + RUN npm run build -FROM nginx:1.23.0-alpine -COPY --from=build /app/dist /usr/share/nginx/html -EXPOSE 80 -CMD ["nginx", "-g", "daemon off;"] + +FROM nginx:alpine + +WORKDIR /app + +COPY --from=build /app/dist/ /usr/share/nginx/html +COPY ./deploy/nginx/ /etc/nginx/ + +EXPOSE 80 443 + +ENV SERVER_NAME="localhost" + +ENV API_PROXY_PASS="" +ENV DOCS_PROXY_PASS="" + +CMD [ "nginx", "-g", "daemon off;" ] diff --git a/configs/.browserslistrc b/configs/.browserslistrc deleted file mode 100644 index 3234204b..00000000 --- a/configs/.browserslistrc +++ /dev/null @@ -1,6 +0,0 @@ -not dead -last 15 Chrome versions -last 3 Safari versions -last 15 versions -last 3 Edge versions -last 3 Opera versions diff --git a/configs/postcss.config.js b/configs/postcss.config.js deleted file mode 100644 index f4bf68ce..00000000 --- a/configs/postcss.config.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - plugin: ["postcss-preset-env"], -}; diff --git a/deploy/nginx/nginx.conf b/deploy/nginx/nginx.conf new file mode 100644 index 00000000..40098184 --- /dev/null +++ b/deploy/nginx/nginx.conf @@ -0,0 +1,36 @@ +user nginx; +worker_processes auto; + +error_log /var/log/nginx/error.log notice; +pid /var/run/nginx.pid; + + +events { + worker_connections 1024; +} + + +http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + + access_log /var/log/nginx/access.log main; + + sendfile on; + #tcp_nopush on; + + keepalive_timeout 65; + + gzip on; + gzip_disable "MSIE [1-6]\.(?!.*SV1)"; + gzip_proxied any; + gzip_buffers 16 8k; + gzip_types in application/javascript application/x-javascript text/javascript text/xml text/css; + gzip_vary on; + + include /etc/nginx/conf.d/*.conf; +} diff --git a/deploy/nginx/templates/default.conf.template b/deploy/nginx/templates/default.conf.template new file mode 100644 index 00000000..65c2aceb --- /dev/null +++ b/deploy/nginx/templates/default.conf.template @@ -0,0 +1,33 @@ +server { + listen 80 default_server; + server_name ${SERVER_NAME} www.${SERVER_NAME}; + + access_log /var/log/nginx/${SERVER_NAME}.access.log; + error_log /var/log/nginx/${SERVER_NAME}.error.log; + + root /usr/share/nginx/html; + + location / { + try_files $uri /index.html; + } + + location /api { + proxy_pass ${API_PROXY_PASS}; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-NginX-Proxy true; + proxy_ssl_session_reuse off; + proxy_set_header Host $http_host; + proxy_redirect off; + } + + location /api/docs { + proxy_pass ${DOCS_PROXY_PASS}; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-NginX-Proxy true; + proxy_ssl_session_reuse off; + proxy_set_header Host $http_host; + proxy_redirect off; + } +} diff --git a/generate-react-cli.json b/generate-react-cli.json deleted file mode 100644 index d67d2f90..00000000 --- a/generate-react-cli.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "usesTypeScript": true, - "usesCssModule": true, - "cssPreprocessor": "css", - "testLibrary": "None", - "component": { - "default": { - "customTemplates": { - "index": "templates/component/index.ts", - "component": "templates/component/TemplateName.tsx", - "style": "templates/component/TemplateName.module.css", - "styletsd": "templates/component/TemplateName.module.css.d.ts" - }, - "path": "src/components", - "withStyle": true, - "withTest": false, - "withStory": false, - "withLazy": false, - "withIndex": true, - "withStyletsd": true - }, - "page": { - "customTemplates": { - "component": "templates/page/TemplateNamePage.tsx", - "index": "templates/page/index.ts", - "style": "templates/page/TemplateNamePage.module.css", - "styletsd": "templates/page/TemplateNamePage.module.css.d.ts" - }, - "path": "src/pages", - "withStyle": true, - "withTest": false, - "withStory": false, - "withLazy": false, - "withIndex": true, - "withStyletsd": true - } - } -} diff --git a/package-lock.json b/package-lock.json index d9e01e79..94ca53ea 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,69 +8,81 @@ "name": "task-manager", "version": "0.1.0", "dependencies": { - "@emotion/react": "^11.10.4", - "@emotion/styled": "^11.10.4", - "@farfetched/core": "^0.4.1", - "@farfetched/react": "^0.4.1", - "@farfetched/runtypes": "^0.4.1", - "@hookform/resolvers": "^2.8.8", - "@mui/icons-material": "^5.10.16", + "@emotion/react": "^11.11.1", + "@emotion/styled": "^11.11.0", + "@farfetched/core": "^0.10.4", + "@farfetched/runtypes": "^0.10.4", + "@fontsource/roboto": "^5.0.8", + "@mui/icons-material": "^5.14.14", "@mui/lab": "^5.0.0-alpha.108", - "@mui/material": "^5.10.17", + "@mui/material": "^5.14.14", + "@mui/x-date-pickers": "^6.16.2", + "@withease/web-api": "^1.0.1", "atomic-router": "^0.8.0", - "atomic-router-react": "^0.8.1", - "axios": "^1.2.1", + "atomic-router-react": "^0.8.5", "classnames": "^2.3.1", - "dayjs": "^1.11.7", - "effector": "^22.4.0", - "effector-react": "^22.3.3", + "compose-function": "^3.0.3", + "dayjs": "^1.11.10", + "effector": "^22.8.7", + "effector-forms": "^1.3.4", + "effector-localstorage": "^1.0.0", + "effector-mui-snacks": "^1.0.0", + "effector-react": "^22.5.4", "history": "^5.3.0", - "i18next": "^22.1.5", - "i18next-browser-languagedetector": "^7.0.1", - "i18next-http-backend": "^2.0.2", - "joi": "^17.5.0", + "i18next": "^23.6.0", + "i18next-browser-languagedetector": "^7.1.0", + "i18next-http-backend": "^2.2.2", + "joi": "^17.11.0", + "ky": "^1.1.0", + "patronum": "^1.20.0", "react": "^18.2.0", "react-dom": "^18.2.0", - "react-hook-form": "^7.40.0", - "react-i18next": "^12.1.1", - "runtypes": "^6.6.0", - "socket.io-client": "^4.5.4" + "react-i18next": "^13.3.1", + "runtypes": "^6.7.0" }, "devDependencies": { - "@babel/cli": "^7.17.3", - "@babel/core": "^7.20.5", - "@babel/preset-env": "^7.16.11", - "@babel/preset-react": "^7.16.7", - "@babel/preset-typescript": "^7.16.7", - "@rollup/plugin-babel": "^6.0.3", - "@types/babel__core": "^7.1.20", - "@types/node": "^18.11.12", - "@types/react": "^18.0.26", - "@types/react-dom": "^18.0.6", - "@typescript-eslint/eslint-plugin": "^5.46.0", - "@typescript-eslint/parser": "^5.46.0", - "@vitejs/plugin-legacy": "^3.0.1", - "@vitejs/plugin-react": "^3.0.0", - "browserslist": "^4.21.4", - "effector-logger": "^0.13.4", - "eslint": "^8.29.0", + "@babel/cli": "^7.23.0", + "@babel/core": "^7.23.2", + "@babel/preset-env": "^7.23.2", + "@babel/preset-react": "^7.22.15", + "@babel/preset-typescript": "^7.23.2", + "@rollup/plugin-babel": "^6.0.4", + "@types/compose-function": "^0.0.32", + "@types/node": "^20.8.7", + "@types/react": "^18.2.31", + "@types/react-dom": "^18.2.14", + "@typescript-eslint/eslint-plugin": "^6.8.0", + "@typescript-eslint/parser": "^6.8.0", + "@vitejs/plugin-react": "^4.1.0", + "eslint": "^8.51.0", "eslint-config-airbnb": "^19.0.4", - "eslint-config-prettier": "^8.5.0", - "eslint-plugin-effector": "^0.10.3", - "eslint-plugin-import": "^2.26.0", - "eslint-plugin-sonarjs": "^0.17.0", - "generate-react-cli": "^8.0.1", - "husky": "^8.0.1", - "lint-staged": "^13.1.0", - "typed-css-modules": "^0.7.2", - "typescript": "^4.9.4", - "vite": "^4.0.0" + "eslint-config-prettier": "^9.0.0", + "eslint-plugin-boundaries": "^3.4.0", + "eslint-plugin-effector": "^0.11.0", + "eslint-plugin-import": "^2.28.1", + "eslint-plugin-sonarjs": "^0.21.0", + "husky": "^8.0.3", + "lint-staged": "^15.0.2", + "typed-css-modules": "^0.8.0", + "typescript": "^5.2.2", + "vite": "^4.5.0", + "vite-plugin-static-copy": "^0.17.0" + } + }, + "node_modules/@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" } }, "node_modules/@ampproject/remapping": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", + "dev": true, "dependencies": { "@jridgewell/gen-mapping": "^0.1.0", "@jridgewell/trace-mapping": "^0.3.9" @@ -80,14 +92,14 @@ } }, "node_modules/@babel/cli": { - "version": "7.19.3", - "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.19.3.tgz", - "integrity": "sha512-643/TybmaCAe101m2tSVHi9UKpETXP9c/Ff4mD2tAwkdP6esKIfaauZFc67vGEM6r9fekbEGid+sZhbEnSe3dg==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.23.0.tgz", + "integrity": "sha512-17E1oSkGk2IwNILM4jtfAvgjt+ohmpfBky8aLerUfYZhiPNg7ca+CRCxZn8QDxwNhV/upsc2VHBCqGFIR+iBfA==", "dev": true, "dependencies": { - "@jridgewell/trace-mapping": "^0.3.8", + "@jridgewell/trace-mapping": "^0.3.17", "commander": "^4.0.1", - "convert-source-map": "^1.1.0", + "convert-source-map": "^2.0.0", "fs-readdir-recursive": "^1.1.0", "glob": "^7.2.0", "make-dir": "^2.1.0", @@ -108,45 +120,54 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/cli/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, "node_modules/@babel/code-frame": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", - "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", + "version": "7.22.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", + "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", "dependencies": { - "@babel/highlight": "^7.18.6" + "@babel/highlight": "^7.22.13", + "chalk": "^2.4.2" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/compat-data": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.1.tgz", - "integrity": "sha512-EWZ4mE2diW3QALKvDMiXnbZpRvlj+nayZ112nK93SnhqOtpdsbVD4W+2tEoT3YNBAG9RBR0ISY758ZkOgsn6pQ==", + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.2.tgz", + "integrity": "sha512-0S9TQMmDHlqAZ2ITT95irXKfxN9bncq8ZCoJhun3nHL/lLUxd2NKBJYoNGWH7S0hz6fRQwWlAWn/ILM0C70KZQ==", + "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.5.tgz", - "integrity": "sha512-UdOWmk4pNWTm/4DlPUl/Pt4Gz4rcEMb7CY0Y3eJl5Yz1vI8ZJGmHWaVE55LoxRjdpx0z259GE9U5STA9atUinQ==", - "dependencies": { - "@ampproject/remapping": "^2.1.0", - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.20.5", - "@babel/helper-compilation-targets": "^7.20.0", - "@babel/helper-module-transforms": "^7.20.2", - "@babel/helpers": "^7.20.5", - "@babel/parser": "^7.20.5", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.20.5", - "@babel/types": "^7.20.5", - "convert-source-map": "^1.7.0", + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.2.tgz", + "integrity": "sha512-n7s51eWdaWZ3vGT2tD4T7J6eJs3QoBXydv7vkUM06Bf1cbVD2Kc2UrkzhiQwobfV7NwOnQXYL7UBJ5VPU+RGoQ==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.23.0", + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-module-transforms": "^7.23.0", + "@babel/helpers": "^7.23.2", + "@babel/parser": "^7.23.0", + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.2", + "@babel/types": "^7.23.0", + "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", - "json5": "^2.2.1", - "semver": "^6.3.0" + "json5": "^2.2.3", + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" @@ -156,13 +177,21 @@ "url": "https://opencollective.com/babel" } }, + "node_modules/@babel/core/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, "node_modules/@babel/generator": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.5.tgz", - "integrity": "sha512-jl7JY2Ykn9S0yj4DQP82sYvPU+T3g0HFcWTqDLqiuA9tGRNIj9VfbtXGAYTTkyNEnQk1jkMGOdYka8aG/lulCA==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz", + "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==", + "dev": true, "dependencies": { - "@babel/types": "^7.20.5", + "@babel/types": "^7.23.0", "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" }, "engines": { @@ -170,9 +199,10 @@ } }, "node_modules/@babel/generator/node_modules/@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "dev": true, "dependencies": { "@jridgewell/set-array": "^1.0.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -183,60 +213,60 @@ } }, "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz", - "integrity": "sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", + "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", "dev": true, "dependencies": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.18.9.tgz", - "integrity": "sha512-yFQ0YCHoIqarl8BCRwBL8ulYUaZpz3bNsA7oFepAzee+8/+ImtADXNOmO5vJvsPff3qi+hvpkY/NYBTrBQgdNw==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.15.tgz", + "integrity": "sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw==", "dev": true, "dependencies": { - "@babel/helper-explode-assignable-expression": "^7.18.6", - "@babel/types": "^7.18.9" + "@babel/types": "^7.22.15" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.0.tgz", - "integrity": "sha512-0jp//vDGp9e8hZzBc6N/KwA5ZK3Wsm/pfm4CrY7vzegkVxc65SgSn6wYOnwHe9Js9HRQ1YTCKLGPzDtaS3RoLQ==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz", + "integrity": "sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==", + "dev": true, "dependencies": { - "@babel/compat-data": "^7.20.0", - "@babel/helper-validator-option": "^7.18.6", - "browserslist": "^4.21.3", - "semver": "^6.3.0" + "@babel/compat-data": "^7.22.9", + "@babel/helper-validator-option": "^7.22.15", + "browserslist": "^4.21.9", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" } }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.20.2.tgz", - "integrity": "sha512-k22GoYRAHPYr9I+Gvy2ZQlAe5mGy8BqWst2wRt8cwIufWTxrsVshhIBvYNqC80N0GSFWTsqRVexOtfzlgOEDvA==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.15.tgz", + "integrity": "sha512-jKkwA59IXcvSaiK2UN45kKwSC9o+KuoXsBDvHvU/7BecYIp8GQ2UwrVvFgJASUT+hBnwJx6MhvMCuMzwZZ7jlg==", "dev": true, "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", - "@babel/helper-member-expression-to-functions": "^7.18.9", - "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/helper-replace-supers": "^7.19.1", - "@babel/helper-split-export-declaration": "^7.18.6" + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-function-name": "^7.22.5", + "@babel/helper-member-expression-to-functions": "^7.22.15", + "@babel/helper-optimise-call-expression": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" @@ -246,13 +276,14 @@ } }, "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.19.0.tgz", - "integrity": "sha512-htnV+mHX32DF81amCDrwIDr8nrp1PTm+3wfBN9/v8QJOLEioOCOG7qNyq0nHeFiWbT3Eb7gsPwEmV64UCQ1jzw==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.15.tgz", + "integrity": "sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w==", "dev": true, "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "regexpu-core": "^5.1.0" + "@babel/helper-annotate-as-pure": "^7.22.5", + "regexpu-core": "^5.3.1", + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" @@ -262,136 +293,127 @@ } }, "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz", - "integrity": "sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==", + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.3.tgz", + "integrity": "sha512-WBrLmuPP47n7PNwsZ57pqam6G/RGo1vw/87b0Blc53tZNGZ4x7YvZ6HgQe2vo1W/FR20OgjeZuGXzudPiXHFug==", "dev": true, "dependencies": { - "@babel/helper-compilation-targets": "^7.17.7", - "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-plugin-utils": "^7.22.5", "debug": "^4.1.1", "lodash.debounce": "^4.0.8", - "resolve": "^1.14.2", - "semver": "^6.1.2" + "resolve": "^1.14.2" }, "peerDependencies": { - "@babel/core": "^7.4.0-0" + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.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==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-explode-assignable-expression": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.18.6.tgz", - "integrity": "sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", "dev": true, - "dependencies": { - "@babel/types": "^7.18.6" - }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-function-name": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", - "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", + "dev": true, "dependencies": { - "@babel/template": "^7.18.10", - "@babel/types": "^7.19.0" + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.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==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", + "dev": true, "dependencies": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.18.9.tgz", - "integrity": "sha512-RxifAh2ZoVU67PyKIO4AMi1wTenGfMR/O/ae0CCRqwgBAt5v7xjdtRw7UoSbsreKrQn5t7r89eruK/9JjYHuDg==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.22.15.tgz", + "integrity": "sha512-qLNsZbgrNh0fDQBCPocSL8guki1hcPvltGDv/NxvUoABwFq7GkKSu1nRXeJkVZc+wJvne2E0RKQz+2SQrz6eAA==", "dev": true, "dependencies": { - "@babel/types": "^7.18.9" + "@babel/types": "^7.22.15" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", - "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", + "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", "dependencies": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.15" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.2.tgz", - "integrity": "sha512-zvBKyJXRbmK07XhMuujYoJ48B5yvvmM6+wcpv6Ivj4Yg6qO7NOZOSnvZN9CRl1zz1Z4cKf8YejmCMh8clOoOeA==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.0.tgz", + "integrity": "sha512-WhDWw1tdrlT0gMgUJSlX0IQvoO1eN279zrAUbVB+KpV2c3Tylz8+GnKOLllCS6Z/iZQEyVYxhZVUdPTqs2YYPw==", + "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.18.10", - "@babel/traverse": "^7.20.1", - "@babel/types": "^7.20.2" + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-simple-access": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/helper-validator-identifier": "^7.22.20" }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz", - "integrity": "sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz", + "integrity": "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==", "dev": true, "dependencies": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.5" }, "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==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", + "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", + "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-remap-async-to-generator": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz", - "integrity": "sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.20.tgz", + "integrity": "sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw==", "dev": true, "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-wrap-function": "^7.18.9", - "@babel/types": "^7.18.9" + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-wrap-function": "^7.22.20" }, "engines": { "node": ">=6.9.0" @@ -401,114 +423,118 @@ } }, "node_modules/@babel/helper-replace-supers": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.19.1.tgz", - "integrity": "sha512-T7ahH7wV0Hfs46SFh5Jz3s0B6+o8g3c+7TMxu7xKfmHikg7EAZ3I2Qk9LFhjxXq8sL7UkP5JflezNwoZa8WvWw==", + "version": "7.22.9", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.22.9.tgz", + "integrity": "sha512-LJIKvvpgPOPUThdYqcX6IXRuIcTkcAub0IaDRGCZH0p5GPUp7PhRU9QVgFcDDd51BaPkk77ZjqFwh6DZTAEmGg==", "dev": true, "dependencies": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-member-expression-to-functions": "^7.18.9", - "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/traverse": "^7.19.1", - "@babel/types": "^7.19.0" + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-member-expression-to-functions": "^7.22.5", + "@babel/helper-optimise-call-expression": "^7.22.5" }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.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==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", + "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", + "dev": true, "dependencies": { - "@babel/types": "^7.20.2" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.20.0.tgz", - "integrity": "sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz", + "integrity": "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==", "dev": true, "dependencies": { - "@babel/types": "^7.20.0" + "@babel/types": "^7.22.5" }, "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==", + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "dev": true, "dependencies": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.5" }, "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==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", + "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", "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==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", - "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz", + "integrity": "sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA==", + "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-wrap-function": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.19.0.tgz", - "integrity": "sha512-txX8aN8CZyYGTwcLhlk87KRqncAzhh5TpQamZUa0/u3an36NtDpUP6bQgBCBcLeBs09R/OwQu3OjK0k/HwfNDg==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.22.20.tgz", + "integrity": "sha512-pms/UwkOpnQe/PDAEdV/d7dVCoBbB+R4FvYoHGZz+4VPcg7RtYy2KP7S2lbuWM6FCSgob5wshfGESbC/hzNXZw==", "dev": true, "dependencies": { - "@babel/helper-function-name": "^7.19.0", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.19.0", - "@babel/types": "^7.19.0" + "@babel/helper-function-name": "^7.22.5", + "@babel/template": "^7.22.15", + "@babel/types": "^7.22.19" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.20.6", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.6.tgz", - "integrity": "sha512-Pf/OjgfgFRW5bApskEz5pvidpim7tEDPlFtKcNRXWmfHGn9IEI2W2flqRQXTFb7gIPTyK++N6rVHuwKut4XK6w==", + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.2.tgz", + "integrity": "sha512-lzchcp8SjTSVe/fPmLwtWVBFC7+Tbn8LGHDVfDp9JGxpAY5opSaEFgt8UQvrnECWOTdji2mOWMz1rOhkHscmGQ==", + "dev": true, "dependencies": { - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.20.5", - "@babel/types": "^7.20.5" + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.2", + "@babel/types": "^7.23.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==", + "version": "7.22.13", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.13.tgz", + "integrity": "sha512-C/BaXcnnvBCmHTpz/VGZ8jgtE2aYlW4hxDhseJAWZb7gqGM/qtCK6iZUb0TyKFf7BOUsBH7Q7fkRsDRhg1XklQ==", "dependencies": { - "@babel/helper-validator-identifier": "^7.18.6", - "chalk": "^2.0.0", + "@babel/helper-validator-identifier": "^7.22.5", + "chalk": "^2.4.2", "js-tokens": "^4.0.0" }, "engines": { @@ -516,9 +542,10 @@ } }, "node_modules/@babel/parser": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.5.tgz", - "integrity": "sha512-r27t/cy/m9uKLXQNWWebeCUHgnAZq0CpG1OwKRxzJMP1vpSU4bSIK2hq+/cp0bQxetkXx38n09rNu8jVkcK/zA==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz", + "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==", + "dev": true, "bin": { "parser": "bin/babel-parser.js" }, @@ -527,12 +554,12 @@ } }, "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.18.6.tgz", - "integrity": "sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.22.15.tgz", + "integrity": "sha512-FB9iYlz7rURmRJyXRKEnalYPPdn87H5no108cyuQQyMwlpJ2SJtpIUBI27kdTin956pz+LPypkPVPUTlxOmrsg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -542,14 +569,14 @@ } }, "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.18.9.tgz", - "integrity": "sha512-AHrP9jadvH7qlOj6PINbgSuphjQUAK7AOT7DPjBo9EHoLhQTnnK5u45e1Hd4DbSQEO9nqPWtQ89r+XEOWFScKg==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.22.15.tgz", + "integrity": "sha512-Hyph9LseGvAeeXzikV88bczhsrLrIZqDPxO+sSmAunMPaGrBGhfMWzCPYTtiW9t+HzSE2wtV8e5cc5P6r1xMDQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9", - "@babel/plugin-proposal-optional-chaining": "^7.18.9" + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/plugin-transform-optional-chaining": "^7.22.15" }, "engines": { "node": ">=6.9.0" @@ -558,232 +585,11 @@ "@babel/core": "^7.13.0" } }, - "node_modules/@babel/plugin-proposal-async-generator-functions": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.20.1.tgz", - "integrity": "sha512-Gh5rchzSwE4kC+o/6T8waD0WHEQIsDmjltY8WnWRXHUdH8axZhuH86Ov9M72YhJfDrZseQwuuWaaIT/TmePp3g==", - "dev": true, - "dependencies": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/helper-remap-async-to-generator": "^7.18.9", - "@babel/plugin-syntax-async-generators": "^7.8.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-class-properties": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz", - "integrity": "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==", - "dev": true, - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-class-static-block": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.18.6.tgz", - "integrity": "sha512-+I3oIiNxrCpup3Gi8n5IGMwj0gOCAjcJUSQEcotNnCCPMEnixawOQ+KeJPlgfjzx+FKQ1QSyZOWe7wmoJp7vhw==", - "dev": true, - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-class-static-block": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.12.0" - } - }, - "node_modules/@babel/plugin-proposal-dynamic-import": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.18.6.tgz", - "integrity": "sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-dynamic-import": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-export-namespace-from": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.9.tgz", - "integrity": "sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-json-strings": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.18.6.tgz", - "integrity": "sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-json-strings": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-logical-assignment-operators": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.18.9.tgz", - "integrity": "sha512-128YbMpjCrP35IOExw2Fq+x55LMP42DzhOhX2aNNIdI9avSWl2PI0yuBWarr3RYpZBSPtabfadkH2yeRiMD61Q==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz", - "integrity": "sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-numeric-separator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz", - "integrity": "sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-numeric-separator": "^7.10.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-object-rest-spread": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.2.tgz", - "integrity": "sha512-Ks6uej9WFK+fvIMesSqbAto5dD8Dz4VuuFvGJFKgIGSkJuRGcrwGECPA1fDgQK3/DbExBJpEkTeYeB8geIFCSQ==", - "dev": true, - "dependencies": { - "@babel/compat-data": "^7.20.1", - "@babel/helper-compilation-targets": "^7.20.0", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.20.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-optional-catch-binding": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz", - "integrity": "sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-optional-chaining": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.18.9.tgz", - "integrity": "sha512-v5nwt4IqBXihxGsW2QmCWMDS3B3bzGIk/EQVZz2ei7f3NJl8NzAJVvUmpDW5q1CRNY+Beb/k58UAH1Km1N411w==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-private-methods": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz", - "integrity": "sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==", - "dev": true, - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, "node_modules/@babel/plugin-proposal-private-property-in-object": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.18.6.tgz", - "integrity": "sha512-9Rysx7FOctvT5ouj5JODjAFAkgGoudQuLPamZb0v1TGLpapdNaftzifU8NTWQm0IRjqoYypdrSmyWgkocDQ8Dw==", + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5" - }, "engines": { "node": ">=6.9.0" }, @@ -791,22 +597,6 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-proposal-unicode-property-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz", - "integrity": "sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==", - "dev": true, - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, "node_modules/@babel/plugin-syntax-async-generators": { "version": "7.8.4", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", @@ -871,12 +661,27 @@ } }, "node_modules/@babel/plugin-syntax-import-assertions": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.20.0.tgz", - "integrity": "sha512-IUh1vakzNoWalR8ch/areW7qFopR2AEw03JlG7BbrDqmQ4X3q9uuipQwSGrUn7oGiemKjtSLDhNtQHzMHr1JdQ==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.22.5.tgz", + "integrity": "sha512-rdV97N7KqsRzeNGoWUOK6yUsWarLjE5Su/Snk9IYPU9CwkWHs4t+rTGOvffTR8XGkJMTAdLfO0xVnXm8wugIJg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.22.5.tgz", + "integrity": "sha512-KwvoWDeNKPETmozyFE0P2rOLqh39EoQHNjqizrI5B8Vt0ZNS7M56s7dAiAqbYfiAYOuIzIh96z3iR2ktgu3tEg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.19.0" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -885,6 +690,18 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/plugin-syntax-json-strings": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", @@ -898,11 +715,12 @@ } }, "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz", - "integrity": "sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.22.5.tgz", + "integrity": "sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==", + "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1014,12 +832,12 @@ } }, "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.20.0.tgz", - "integrity": "sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.22.5.tgz", + "integrity": "sha512-1mS2o03i7t1c6VzH6fdQ3OA8tcEIxwG18zIPRp+UY1Ihv6W+XZzBCVxExF9upussPXJ0xE9XRHwMoNs1ep/nRQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.19.0" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1028,30 +846,64 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-arrow-functions": { + "node_modules/@babel/plugin-syntax-unicode-sets-regex": { "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.18.6.tgz", - "integrity": "sha512-9S9X9RUefzrsHZmKMbDXxweEH+YlE8JJEuat9FdvW9Qh1cw7W64jELCtWNkPBPX5En45uy28KGvA/AySqUh8CQ==", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", "dev": true, "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.0.0" } }, - "node_modules/@babel/plugin-transform-async-to-generator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.18.6.tgz", - "integrity": "sha512-ARE5wZLKnTgPW7/1ftQmSi1CmkqqHo2DNmtztFhvgtOWSDfq0Cq9/9L+KnZNYSNrydBekhW3rwShduf59RoXag==", + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.22.5.tgz", + "integrity": "sha512-26lTNXoVRdAnsaDXPpvCNUq+OVWEVC6bx7Vvz9rC53F2bagUWW4u4ii2+h8Fejfh7RYqPxn+libeFBBck9muEw==", "dev": true, "dependencies": { - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-remap-async-to-generator": "^7.18.6" + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-generator-functions": { + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.23.2.tgz", + "integrity": "sha512-BBYVGxbDVHfoeXbOwcagAkOQAm9NxoTdMGfTqghu1GrvadSaw6iW3Je6IcL5PNOw8VwjxqBECXy50/iCQSY/lQ==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-remap-async-to-generator": "^7.22.20", + "@babel/plugin-syntax-async-generators": "^7.8.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.22.5.tgz", + "integrity": "sha512-b1A8D8ZzE/VhNDoV1MSJTnpKkCG5bJo+19R4o4oy03zM7ws8yEMK755j61Dc3EyvdysbqH5BOOTquJ7ZX9C6vQ==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-remap-async-to-generator": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1061,12 +913,12 @@ } }, "node_modules/@babel/plugin-transform-block-scoped-functions": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz", - "integrity": "sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.22.5.tgz", + "integrity": "sha512-tdXZ2UdknEKQWKJP1KMNmuF5Lx3MymtMN/pvA+p/VEkhK8jVcQ1fzSy8KM9qRYhAf2/lV33hoMPKI/xaI9sADA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1076,12 +928,28 @@ } }, "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.20.2.tgz", - "integrity": "sha512-y5V15+04ry69OV2wULmwhEA6jwSWXO1TwAtIwiPXcvHcoOQUqpyMVd2bDsQJMW8AurjulIyUV8kDqtjSwHy1uQ==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.23.0.tgz", + "integrity": "sha512-cOsrbmIOXmf+5YbL99/S49Y3j46k/T16b9ml8bm9lP6N9US5iQ2yBK7gpui1pg0V/WMcXdkfKbTb7HXq9u+v4g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-properties": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.22.5.tgz", + "integrity": "sha512-nDkQ0NfkOhPTq8YCLiWNxp1+f9fCobEjCb0n8WdbNUBc4IB5V7P1QnX9IjpSoquKrXF5SKojHleVNs2vGeHCHQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2" + "@babel/helper-create-class-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1090,20 +958,37 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.22.11.tgz", + "integrity": "sha512-GMM8gGmqI7guS/llMFk1bJDkKfn3v3C4KHK9Yg1ey5qcHcOlKb0QvcMrgzvxo+T03/4szNh5lghY+fEC98Kq9g==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.22.11", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-class-static-block": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, "node_modules/@babel/plugin-transform-classes": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.20.2.tgz", - "integrity": "sha512-9rbPp0lCVVoagvtEyQKSo5L8oo0nQS/iif+lwlAz29MccX2642vWDlSZK+2T2buxbopotId2ld7zZAzRfz9j1g==", - "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-compilation-targets": "^7.20.0", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", - "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-replace-supers": "^7.19.1", - "@babel/helper-split-export-declaration": "^7.18.6", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.22.15.tgz", + "integrity": "sha512-VbbC3PGjBdE0wAWDdHM9G8Gm977pnYI0XpqMd6LrKISj8/DJXEsWqgRuTYaNE9Bv0JGhTZUzHDlMk18IpOuoqw==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-function-name": "^7.22.5", + "@babel/helper-optimise-call-expression": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.9", + "@babel/helper-split-export-declaration": "^7.22.6", "globals": "^11.1.0" }, "engines": { @@ -1114,12 +999,13 @@ } }, "node_modules/@babel/plugin-transform-computed-properties": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.18.9.tgz", - "integrity": "sha512-+i0ZU1bCDymKakLxn5srGHrsAPRELC2WIbzwjLhHW9SIE1cPYkLCL0NlnXMZaM1vhfgA2+M7hySk42VBvrkBRw==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.22.5.tgz", + "integrity": "sha512-4GHWBgRf0krxPX+AaPtgBAlTgTeZmqDynokHOX7aqqAB4tHs3U2Y02zH6ETFdLZGcg9UQSD1WCmkVrE9ErHeOg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/template": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1129,12 +1015,12 @@ } }, "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.20.2.tgz", - "integrity": "sha512-mENM+ZHrvEgxLTBXUiQ621rRXZes3KWUv6NdQlrnr1TkWVw+hUjQBZuP2X32qKlrlG2BzgR95gkuCRSkJl8vIw==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.23.0.tgz", + "integrity": "sha512-vaMdgNXFkYrB+8lbgniSYWHsgqK5gjaMNcc84bMIOMRLH0L9AqYq3hwMdvnyqj1OPqea8UtjPEuS/DCenah1wg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1144,13 +1030,13 @@ } }, "node_modules/@babel/plugin-transform-dotall-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.18.6.tgz", - "integrity": "sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.22.5.tgz", + "integrity": "sha512-5/Yk9QxCQCl+sOIB1WelKnVRxTJDSAIxtJLL2/pqL14ZVlbH0fUQUZa/T5/UnQtBNgghR7mfB8ERBKyKPCi7Vw==", "dev": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1160,12 +1046,28 @@ } }, "node_modules/@babel/plugin-transform-duplicate-keys": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.18.9.tgz", - "integrity": "sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.22.5.tgz", + "integrity": "sha512-dEnYD+9BBgld5VBXHnF/DbYGp3fqGMsyxKbtD1mDyIA7AkTSpKXFhCVuj/oQVOoALfBs77DudA0BE4d5mcpmqw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dynamic-import": { + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.22.11.tgz", + "integrity": "sha512-g/21plo58sfteWjaO0ZNVb+uEOkJNjAaHhbejrnBmu011l/eNDScmkbjCC3l4FKb10ViaGU4aOkFznSu2zRHgA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" }, "engines": { "node": ">=6.9.0" @@ -1175,13 +1077,29 @@ } }, "node_modules/@babel/plugin-transform-exponentiation-operator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.18.6.tgz", - "integrity": "sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.22.5.tgz", + "integrity": "sha512-vIpJFNM/FjZ4rh1myqIya9jXwrwwgFRHPjT3DkUA9ZLHuzox8jiXkOLvwm1H+PQIP3CqfC++WPKeuDi0Sjdj1g==", "dev": true, "dependencies": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-export-namespace-from": { + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.22.11.tgz", + "integrity": "sha512-xa7aad7q7OiT8oNZ1mU7NrISjlSkVdMbNxn9IuLZyL9AJEhs1Apba3I+u5riX1dIkdptP5EKDG5XDPByWxtehw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" }, "engines": { "node": ">=6.9.0" @@ -1191,12 +1109,12 @@ } }, "node_modules/@babel/plugin-transform-for-of": { - "version": "7.18.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.18.8.tgz", - "integrity": "sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.22.15.tgz", + "integrity": "sha512-me6VGeHsx30+xh9fbDLLPi0J1HzmeIIyenoOQHuw2D4m2SAU3NrspX5XxJLBpqn5yrLzrlw2Iy3RA//Bx27iOA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1206,14 +1124,30 @@ } }, "node_modules/@babel/plugin-transform-function-name": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.9.tgz", - "integrity": "sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.22.5.tgz", + "integrity": "sha512-UIzQNMS0p0HHiQm3oelztj+ECwFnj+ZRV4KnguvlsD2of1whUeM6o7wGNj6oLwcDoAXQ8gEqfgC24D+VdIcevg==", + "dev": true, + "dependencies": { + "@babel/helper-compilation-targets": "^7.22.5", + "@babel/helper-function-name": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-json-strings": { + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.22.11.tgz", + "integrity": "sha512-CxT5tCqpA9/jXFlme9xIBCc5RPtdDq3JpkkhgHQqtDdiTnTI0jtZ0QzXhr5DILeYifDPp2wvY2ad+7+hLMW5Pw==", "dev": true, "dependencies": { - "@babel/helper-compilation-targets": "^7.18.9", - "@babel/helper-function-name": "^7.18.9", - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-json-strings": "^7.8.3" }, "engines": { "node": ">=6.9.0" @@ -1223,12 +1157,28 @@ } }, "node_modules/@babel/plugin-transform-literals": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.9.tgz", - "integrity": "sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.22.5.tgz", + "integrity": "sha512-fTLj4D79M+mepcw3dgFBTIDYpbcB9Sm0bpm4ppXPaO+U+PKFFyV9MGRvS0gvGw62sd10kT5lRMKXAADb9pWy8g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-logical-assignment-operators": { + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.22.11.tgz", + "integrity": "sha512-qQwRTP4+6xFCDV5k7gZBF3C31K34ut0tbEcTKxlX/0KXxm9GLcO14p570aWxFvVzx6QAfPgq7gaeIHXJC8LswQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" }, "engines": { "node": ">=6.9.0" @@ -1238,12 +1188,12 @@ } }, "node_modules/@babel/plugin-transform-member-expression-literals": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.18.6.tgz", - "integrity": "sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.22.5.tgz", + "integrity": "sha512-RZEdkNtzzYCFl9SE9ATaUMTj2hqMb4StarOJLrZRbqqU4HSBE7UlBw9WBWQiDzrJZJdUWiMTVDI6Gv/8DPvfew==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1253,13 +1203,13 @@ } }, "node_modules/@babel/plugin-transform-modules-amd": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.19.6.tgz", - "integrity": "sha512-uG3od2mXvAtIFQIh0xrpLH6r5fpSQN04gIVovl+ODLdUMANokxQLZnPBHcjmv3GxRjnqwLuHvppjjcelqUFZvg==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.23.0.tgz", + "integrity": "sha512-xWT5gefv2HGSm4QHtgc1sYPbseOyf+FFDo2JbpE25GWl5BqTGO9IMwTYJRoIdjsF85GE+VegHxSCUt5EvoYTAw==", "dev": true, "dependencies": { - "@babel/helper-module-transforms": "^7.19.6", - "@babel/helper-plugin-utils": "^7.19.0" + "@babel/helper-module-transforms": "^7.23.0", + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1269,14 +1219,14 @@ } }, "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.19.6.tgz", - "integrity": "sha512-8PIa1ym4XRTKuSsOUXqDG0YaOlEuTVvHMe5JCfgBMOtHvJKw/4NGovEGN33viISshG/rZNVrACiBmPQLvWN8xQ==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.23.0.tgz", + "integrity": "sha512-32Xzss14/UVc7k9g775yMIvkVK8xwKE0DPdP5JTapr3+Z9w4tzeOuLNY6BXDQR6BdnzIlXnCGAzsk/ICHBLVWQ==", "dev": true, "dependencies": { - "@babel/helper-module-transforms": "^7.19.6", - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/helper-simple-access": "^7.19.4" + "@babel/helper-module-transforms": "^7.23.0", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-simple-access": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1286,15 +1236,15 @@ } }, "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.19.6.tgz", - "integrity": "sha512-fqGLBepcc3kErfR9R3DnVpURmckXP7gj7bAlrTQyBxrigFqszZCkFkcoxzCp2v32XmwXLvbw+8Yq9/b+QqksjQ==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.23.0.tgz", + "integrity": "sha512-qBej6ctXZD2f+DhlOC9yO47yEYgUh5CZNz/aBoH4j/3NOlRfJXJbY7xDQCqQVf9KbrqGzIWER1f23doHGrIHFg==", "dev": true, "dependencies": { - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-module-transforms": "^7.19.6", - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/helper-validator-identifier": "^7.19.1" + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-module-transforms": "^7.23.0", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.20" }, "engines": { "node": ">=6.9.0" @@ -1304,13 +1254,13 @@ } }, "node_modules/@babel/plugin-transform-modules-umd": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.18.6.tgz", - "integrity": "sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.22.5.tgz", + "integrity": "sha512-+S6kzefN/E1vkSsKx8kmQuqeQsvCKCd1fraCM7zXm4SFoggI099Tr4G8U81+5gtMdUeMQ4ipdQffbKLX0/7dBQ==", "dev": true, "dependencies": { - "@babel/helper-module-transforms": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-module-transforms": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1320,13 +1270,13 @@ } }, "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.19.1.tgz", - "integrity": "sha512-oWk9l9WItWBQYS4FgXD4Uyy5kq898lvkXpXQxoJEY1RnvPk4R/Dvu2ebXU9q8lP+rlMwUQTFf2Ok6d78ODa0kw==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.22.5.tgz", + "integrity": "sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==", "dev": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.19.0", - "@babel/helper-plugin-utils": "^7.19.0" + "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1336,12 +1286,63 @@ } }, "node_modules/@babel/plugin-transform-new-target": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.18.6.tgz", - "integrity": "sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.22.5.tgz", + "integrity": "sha512-AsF7K0Fx/cNKVyk3a+DW0JLo+Ua598/NxMRvxDnkpCIGFh43+h/v2xyhRUYf6oD8gE4QtL83C7zZVghMjHd+iw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.22.11.tgz", + "integrity": "sha512-YZWOw4HxXrotb5xsjMJUDlLgcDXSfO9eCmdl1bgW4+/lAGdkjaEvOnQ4p5WKKdUgSzO39dgPl0pTnfxm0OAXcg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-numeric-separator": { + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.22.11.tgz", + "integrity": "sha512-3dzU4QGPsILdJbASKhF/V2TVP+gJya1PsueQCxIPCEcerqF21oEcrob4mzjsp2Py/1nLfF5m+xYNMDpmA8vffg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-rest-spread": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.22.15.tgz", + "integrity": "sha512-fEB+I1+gAmfAyxZcX1+ZUwLeAuuf8VIg67CTznZE0MqVFumWkh8xWtn58I4dxdVf080wn7gzWoF8vndOViJe9Q==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.22.9", + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.22.15" }, "engines": { "node": ">=6.9.0" @@ -1351,13 +1352,46 @@ } }, "node_modules/@babel/plugin-transform-object-super": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz", - "integrity": "sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.22.5.tgz", + "integrity": "sha512-klXqyaT9trSjIUrcsYIfETAzmOEZL3cBYqOYLJxBHfMFFggmXOv+NYSX/Jbs9mzMVESw/WycLFPRx8ba/b2Ipw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-catch-binding": { + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.22.11.tgz", + "integrity": "sha512-rli0WxesXUeCJnMYhzAglEjLWVDF6ahb45HuprcmQuLidBJFWjNnOzssk2kuc6e33FlLaiZhG/kUIzUMWdBKaQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.23.0.tgz", + "integrity": "sha512-sBBGXbLJjxTzLBF5rFWaikMnOGOk/BmK6vVByIdEggZ7Vn6CvWXZyRkkLFK6WE0IF8jSliyOkUN6SScFgzCM0g==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-replace-supers": "^7.18.6" + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" }, "engines": { "node": ">=6.9.0" @@ -1367,12 +1401,46 @@ } }, "node_modules/@babel/plugin-transform-parameters": { - "version": "7.20.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.20.3.tgz", - "integrity": "sha512-oZg/Fpx0YDrj13KsLyO8I/CX3Zdw7z0O9qOd95SqcoIzuqy/WTGWvePeHAnZCN54SfdyjHcb1S30gc8zlzlHcA==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.22.15.tgz", + "integrity": "sha512-hjk7qKIqhyzhhUvRT683TYQOFa/4cQKwQy7ALvTpODswN40MljzNDa0YldevS6tGbxwaEKVn502JmY0dP7qEtQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-methods": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.22.5.tgz", + "integrity": "sha512-PPjh4gyrQnGe97JTalgRGMuU4icsZFnWkzicB/fUtzlKUqvsWBKEpPPfr5a2JiyirZkHxnAqkQMO5Z5B2kK3fA==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.22.11.tgz", + "integrity": "sha512-sSCbqZDBKHetvjSwpyWzhuHkmW5RummxJBVbYLkGkaiTOWGxml7SXt0iWa03bzxFIx7wOj3g/ILRd0RcJKBeSQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2" + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-create-class-features-plugin": "^7.22.11", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" }, "engines": { "node": ">=6.9.0" @@ -1382,12 +1450,12 @@ } }, "node_modules/@babel/plugin-transform-property-literals": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.18.6.tgz", - "integrity": "sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.22.5.tgz", + "integrity": "sha512-TiOArgddK3mK/x1Qwf5hay2pxI6wCZnvQqrFSqbtg1GLl2JcNMitVH/YnqjP+M31pLUeTfzY1HAXFDnUBV30rQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1397,12 +1465,12 @@ } }, "node_modules/@babel/plugin-transform-react-display-name": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.18.6.tgz", - "integrity": "sha512-TV4sQ+T013n61uMoygyMRm+xf04Bd5oqFpv2jAEQwSZ8NwQA7zeRPg1LMVg2PWi3zWBz+CLKD+v5bcpZ/BS0aA==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.22.5.tgz", + "integrity": "sha512-PVk3WPYudRF5z4GKMEYUrLjPl38fJSKNaEOkFuoprioowGuWN6w2RKznuFNSlJx7pzzXXStPUnNSOEO0jL5EVw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1412,16 +1480,16 @@ } }, "node_modules/@babel/plugin-transform-react-jsx": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.19.0.tgz", - "integrity": "sha512-UVEvX3tXie3Szm3emi1+G63jyw1w5IcMY0FSKM+CRnKRI5Mr1YbCNgsSTwoTwKphQEG9P+QqmuRFneJPZuHNhg==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.22.15.tgz", + "integrity": "sha512-oKckg2eZFa8771O/5vi7XeTvmM6+O9cxZu+kanTU7tD4sin5nO/G8jGJhq8Hvt2Z0kUoEDRayuZLaUlYl8QuGA==", "dev": true, "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/plugin-syntax-jsx": "^7.18.6", - "@babel/types": "^7.19.0" + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-jsx": "^7.22.5", + "@babel/types": "^7.22.15" }, "engines": { "node": ">=6.9.0" @@ -1431,12 +1499,12 @@ } }, "node_modules/@babel/plugin-transform-react-jsx-development": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.18.6.tgz", - "integrity": "sha512-SA6HEjwYFKF7WDjWcMcMGUimmw/nhNRDWxr+KaLSCrkD/LMDBvWRmHAYgE1HDeF8KUuI8OAu+RT6EOtKxSW2qA==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.22.5.tgz", + "integrity": "sha512-bDhuzwWMuInwCYeDeMzyi7TaBgRQei6DqxhbyniL7/VG4RSS7HtSL2QbY4eESy1KJqlWt8g3xeEBGPuo+XqC8A==", "dev": true, "dependencies": { - "@babel/plugin-transform-react-jsx": "^7.18.6" + "@babel/plugin-transform-react-jsx": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1446,12 +1514,12 @@ } }, "node_modules/@babel/plugin-transform-react-jsx-self": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.18.6.tgz", - "integrity": "sha512-A0LQGx4+4Jv7u/tWzoJF7alZwnBDQd6cGLh9P+Ttk4dpiL+J5p7NSNv/9tlEFFJDq3kjxOavWmbm6t0Gk+A3Ig==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.22.5.tgz", + "integrity": "sha512-nTh2ogNUtxbiSbxaT4Ds6aXnXEipHweN9YRgOX/oNXdf0cCrGn/+2LozFa3lnPV5D90MkjhgckCPBrsoSc1a7g==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1461,12 +1529,12 @@ } }, "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==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.22.5.tgz", + "integrity": "sha512-yIiRO6yobeEIaI0RTbIr8iAK9FcBHLtZq0S89ZPjDLQXBA4xvghaKqI0etp/tF3htTM0sazJKKLz9oEiGRtu7w==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.19.0" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1476,13 +1544,13 @@ } }, "node_modules/@babel/plugin-transform-react-pure-annotations": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.18.6.tgz", - "integrity": "sha512-I8VfEPg9r2TRDdvnHgPepTKvuRomzA8+u+nhY7qSI1fR2hRNebasZEETLyM5mAUr0Ku56OkXJ0I7NHJnO6cJiQ==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.22.5.tgz", + "integrity": "sha512-gP4k85wx09q+brArVinTXhWiyzLl9UpmGva0+mWyKxk6JZequ05x3eUcIUE+FyttPKJFRRVtAvQaJ6YF9h1ZpA==", "dev": true, "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1492,13 +1560,13 @@ } }, "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.18.6.tgz", - "integrity": "sha512-poqRI2+qiSdeldcz4wTSTXBRryoq3Gc70ye7m7UD5Ww0nE29IXqMl6r7Nd15WBgRd74vloEMlShtH6CKxVzfmQ==", + "version": "7.22.10", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.22.10.tgz", + "integrity": "sha512-F28b1mDt8KcT5bUyJc/U9nwzw6cV+UmTeRlXYIl2TNqMMJif0Jeey9/RQ3C4NOd2zp0/TRsDns9ttj2L523rsw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "regenerator-transform": "^0.15.0" + "@babel/helper-plugin-utils": "^7.22.5", + "regenerator-transform": "^0.15.2" }, "engines": { "node": ">=6.9.0" @@ -1508,12 +1576,12 @@ } }, "node_modules/@babel/plugin-transform-reserved-words": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.18.6.tgz", - "integrity": "sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.22.5.tgz", + "integrity": "sha512-DTtGKFRQUDm8svigJzZHzb/2xatPc6TzNvAIJ5GqOKDsGFYgAskjRulbR/vGsPKq3OPqtexnz327qYpP57RFyA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1523,12 +1591,12 @@ } }, "node_modules/@babel/plugin-transform-shorthand-properties": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.18.6.tgz", - "integrity": "sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.22.5.tgz", + "integrity": "sha512-vM4fq9IXHscXVKzDv5itkO1X52SmdFBFcMIBZ2FRn2nqVYqw6dBexUgMvAjHW+KXpPPViD/Yo3GrDEBaRC0QYA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1538,13 +1606,13 @@ } }, "node_modules/@babel/plugin-transform-spread": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.19.0.tgz", - "integrity": "sha512-RsuMk7j6n+r752EtzyScnWkQyuJdli6LdO5Klv8Yx0OfPVTcQkIUfS8clx5e9yHXzlnhOZF3CbQ8C2uP5j074w==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.22.5.tgz", + "integrity": "sha512-5ZzDQIGyvN4w8+dMmpohL6MBo+l2G7tfC/O2Dg7/hjpgeWvUx8FzfeOKxGog9IimPa4YekaQ9PlDqTLOljkcxg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9" + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1554,12 +1622,12 @@ } }, "node_modules/@babel/plugin-transform-sticky-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.18.6.tgz", - "integrity": "sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.22.5.tgz", + "integrity": "sha512-zf7LuNpHG0iEeiyCNwX4j3gDg1jgt1k3ZdXBKbZSoA3BbGQGvMiSvfbZRR3Dr3aeJe3ooWFZxOOG3IRStYp2Bw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1569,12 +1637,12 @@ } }, "node_modules/@babel/plugin-transform-template-literals": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.9.tgz", - "integrity": "sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.22.5.tgz", + "integrity": "sha512-5ciOehRNf+EyUeewo8NkbQiUs4d6ZxiHo6BcBcnFlgiJfu16q0bQUw9Jvo0b0gBKFG1SMhDSjeKXSYuJLeFSMA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1584,12 +1652,12 @@ } }, "node_modules/@babel/plugin-transform-typeof-symbol": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.18.9.tgz", - "integrity": "sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.22.5.tgz", + "integrity": "sha512-bYkI5lMzL4kPii4HHEEChkD0rkc+nvnlR6+o/qdqR6zrm0Sv/nodmyLhlq2DO0YKLUNd2VePmPRjJXSBh9OIdA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1599,14 +1667,15 @@ } }, "node_modules/@babel/plugin-transform-typescript": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.20.2.tgz", - "integrity": "sha512-jvS+ngBfrnTUBfOQq8NfGnSbF9BrqlR6hjJ2yVxMkmO5nL/cdifNbI30EfjRlN4g5wYWNnMPyj5Sa6R1pbLeag==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.22.15.tgz", + "integrity": "sha512-1uirS0TnijxvQLnlv5wQBwOX3E1wCFX7ITv+9pBV2wKEk4K+M5tqDaoNXnTH8tjEIYHLO98MwiTWO04Ggz4XuA==", "dev": true, "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.20.2", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/plugin-syntax-typescript": "^7.20.0" + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-create-class-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-typescript": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1616,12 +1685,28 @@ } }, "node_modules/@babel/plugin-transform-unicode-escapes": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.10.tgz", - "integrity": "sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ==", + "version": "7.22.10", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.22.10.tgz", + "integrity": "sha512-lRfaRKGZCBqDlRU3UIFovdp9c9mEvlylmpod0/OatICsSfuQ9YFthRo1tpTkGsklEefZdqlEFdY4A2dwTb6ohg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-property-regex": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.22.5.tgz", + "integrity": "sha512-HCCIb+CbJIAE6sXn5CjFQXMwkCClcOfPCzTlilJ8cUatfzwHlWQkbtV0zD338u9dZskwvuOYTuuaMaA8J5EI5A==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1631,13 +1716,13 @@ } }, "node_modules/@babel/plugin-transform-unicode-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.18.6.tgz", - "integrity": "sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.22.5.tgz", + "integrity": "sha512-028laaOKptN5vHJf9/Arr/HiJekMd41hOEZYvNsrsXqJ7YPYuX2bQxh31fkZzGmq3YqHRJzYFFAVYvKfMPKqyg==", "dev": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1646,39 +1731,43 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-transform-unicode-sets-regex": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.22.5.tgz", + "integrity": "sha512-lhMfi4FC15j13eKrh3DnYHjpGj6UKQHtNKTbtc1igvAhRy4+kLhV07OpLcsN0VgDEw/MjAvJO4BdMJsHwMhzCg==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, "node_modules/@babel/preset-env": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.20.2.tgz", - "integrity": "sha512-1G0efQEWR1EHkKvKHqbG+IN/QdgwfByUpM5V5QroDzGV2t3S/WXNQd693cHiHTlCFMpr9B6FkPFXDA2lQcKoDg==", - "dev": true, - "dependencies": { - "@babel/compat-data": "^7.20.1", - "@babel/helper-compilation-targets": "^7.20.0", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-validator-option": "^7.18.6", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.18.6", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.18.9", - "@babel/plugin-proposal-async-generator-functions": "^7.20.1", - "@babel/plugin-proposal-class-properties": "^7.18.6", - "@babel/plugin-proposal-class-static-block": "^7.18.6", - "@babel/plugin-proposal-dynamic-import": "^7.18.6", - "@babel/plugin-proposal-export-namespace-from": "^7.18.9", - "@babel/plugin-proposal-json-strings": "^7.18.6", - "@babel/plugin-proposal-logical-assignment-operators": "^7.18.9", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6", - "@babel/plugin-proposal-numeric-separator": "^7.18.6", - "@babel/plugin-proposal-object-rest-spread": "^7.20.2", - "@babel/plugin-proposal-optional-catch-binding": "^7.18.6", - "@babel/plugin-proposal-optional-chaining": "^7.18.9", - "@babel/plugin-proposal-private-methods": "^7.18.6", - "@babel/plugin-proposal-private-property-in-object": "^7.18.6", - "@babel/plugin-proposal-unicode-property-regex": "^7.18.6", + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.23.2.tgz", + "integrity": "sha512-BW3gsuDD+rvHL2VO2SjAUNTBe5YrjsTiDyqamPDWY723na3/yPQ65X5oQkFVJZ0o50/2d+svm1rkPoJeR1KxVQ==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.23.2", + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-option": "^7.22.15", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.22.15", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.22.15", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-class-properties": "^7.12.13", "@babel/plugin-syntax-class-static-block": "^7.14.5", "@babel/plugin-syntax-dynamic-import": "^7.8.3", "@babel/plugin-syntax-export-namespace-from": "^7.8.3", - "@babel/plugin-syntax-import-assertions": "^7.20.0", + "@babel/plugin-syntax-import-assertions": "^7.22.5", + "@babel/plugin-syntax-import-attributes": "^7.22.5", + "@babel/plugin-syntax-import-meta": "^7.10.4", "@babel/plugin-syntax-json-strings": "^7.8.3", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", @@ -1688,45 +1777,62 @@ "@babel/plugin-syntax-optional-chaining": "^7.8.3", "@babel/plugin-syntax-private-property-in-object": "^7.14.5", "@babel/plugin-syntax-top-level-await": "^7.14.5", - "@babel/plugin-transform-arrow-functions": "^7.18.6", - "@babel/plugin-transform-async-to-generator": "^7.18.6", - "@babel/plugin-transform-block-scoped-functions": "^7.18.6", - "@babel/plugin-transform-block-scoping": "^7.20.2", - "@babel/plugin-transform-classes": "^7.20.2", - "@babel/plugin-transform-computed-properties": "^7.18.9", - "@babel/plugin-transform-destructuring": "^7.20.2", - "@babel/plugin-transform-dotall-regex": "^7.18.6", - "@babel/plugin-transform-duplicate-keys": "^7.18.9", - "@babel/plugin-transform-exponentiation-operator": "^7.18.6", - "@babel/plugin-transform-for-of": "^7.18.8", - "@babel/plugin-transform-function-name": "^7.18.9", - "@babel/plugin-transform-literals": "^7.18.9", - "@babel/plugin-transform-member-expression-literals": "^7.18.6", - "@babel/plugin-transform-modules-amd": "^7.19.6", - "@babel/plugin-transform-modules-commonjs": "^7.19.6", - "@babel/plugin-transform-modules-systemjs": "^7.19.6", - "@babel/plugin-transform-modules-umd": "^7.18.6", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.19.1", - "@babel/plugin-transform-new-target": "^7.18.6", - "@babel/plugin-transform-object-super": "^7.18.6", - "@babel/plugin-transform-parameters": "^7.20.1", - "@babel/plugin-transform-property-literals": "^7.18.6", - "@babel/plugin-transform-regenerator": "^7.18.6", - "@babel/plugin-transform-reserved-words": "^7.18.6", - "@babel/plugin-transform-shorthand-properties": "^7.18.6", - "@babel/plugin-transform-spread": "^7.19.0", - "@babel/plugin-transform-sticky-regex": "^7.18.6", - "@babel/plugin-transform-template-literals": "^7.18.9", - "@babel/plugin-transform-typeof-symbol": "^7.18.9", - "@babel/plugin-transform-unicode-escapes": "^7.18.10", - "@babel/plugin-transform-unicode-regex": "^7.18.6", - "@babel/preset-modules": "^0.1.5", - "@babel/types": "^7.20.2", - "babel-plugin-polyfill-corejs2": "^0.3.3", - "babel-plugin-polyfill-corejs3": "^0.6.0", - "babel-plugin-polyfill-regenerator": "^0.4.1", - "core-js-compat": "^3.25.1", - "semver": "^6.3.0" + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.22.5", + "@babel/plugin-transform-async-generator-functions": "^7.23.2", + "@babel/plugin-transform-async-to-generator": "^7.22.5", + "@babel/plugin-transform-block-scoped-functions": "^7.22.5", + "@babel/plugin-transform-block-scoping": "^7.23.0", + "@babel/plugin-transform-class-properties": "^7.22.5", + "@babel/plugin-transform-class-static-block": "^7.22.11", + "@babel/plugin-transform-classes": "^7.22.15", + "@babel/plugin-transform-computed-properties": "^7.22.5", + "@babel/plugin-transform-destructuring": "^7.23.0", + "@babel/plugin-transform-dotall-regex": "^7.22.5", + "@babel/plugin-transform-duplicate-keys": "^7.22.5", + "@babel/plugin-transform-dynamic-import": "^7.22.11", + "@babel/plugin-transform-exponentiation-operator": "^7.22.5", + "@babel/plugin-transform-export-namespace-from": "^7.22.11", + "@babel/plugin-transform-for-of": "^7.22.15", + "@babel/plugin-transform-function-name": "^7.22.5", + "@babel/plugin-transform-json-strings": "^7.22.11", + "@babel/plugin-transform-literals": "^7.22.5", + "@babel/plugin-transform-logical-assignment-operators": "^7.22.11", + "@babel/plugin-transform-member-expression-literals": "^7.22.5", + "@babel/plugin-transform-modules-amd": "^7.23.0", + "@babel/plugin-transform-modules-commonjs": "^7.23.0", + "@babel/plugin-transform-modules-systemjs": "^7.23.0", + "@babel/plugin-transform-modules-umd": "^7.22.5", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.22.5", + "@babel/plugin-transform-new-target": "^7.22.5", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.22.11", + "@babel/plugin-transform-numeric-separator": "^7.22.11", + "@babel/plugin-transform-object-rest-spread": "^7.22.15", + "@babel/plugin-transform-object-super": "^7.22.5", + "@babel/plugin-transform-optional-catch-binding": "^7.22.11", + "@babel/plugin-transform-optional-chaining": "^7.23.0", + "@babel/plugin-transform-parameters": "^7.22.15", + "@babel/plugin-transform-private-methods": "^7.22.5", + "@babel/plugin-transform-private-property-in-object": "^7.22.11", + "@babel/plugin-transform-property-literals": "^7.22.5", + "@babel/plugin-transform-regenerator": "^7.22.10", + "@babel/plugin-transform-reserved-words": "^7.22.5", + "@babel/plugin-transform-shorthand-properties": "^7.22.5", + "@babel/plugin-transform-spread": "^7.22.5", + "@babel/plugin-transform-sticky-regex": "^7.22.5", + "@babel/plugin-transform-template-literals": "^7.22.5", + "@babel/plugin-transform-typeof-symbol": "^7.22.5", + "@babel/plugin-transform-unicode-escapes": "^7.22.10", + "@babel/plugin-transform-unicode-property-regex": "^7.22.5", + "@babel/plugin-transform-unicode-regex": "^7.22.5", + "@babel/plugin-transform-unicode-sets-regex": "^7.22.5", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "@babel/types": "^7.23.0", + "babel-plugin-polyfill-corejs2": "^0.4.6", + "babel-plugin-polyfill-corejs3": "^0.8.5", + "babel-plugin-polyfill-regenerator": "^0.5.3", + "core-js-compat": "^3.31.0", + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" @@ -1736,33 +1842,31 @@ } }, "node_modules/@babel/preset-modules": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.5.tgz", - "integrity": "sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==", + "version": "0.1.6-no-external-plugins", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", + "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", - "@babel/plugin-transform-dotall-regex": "^7.4.4", "@babel/types": "^7.4.4", "esutils": "^2.0.2" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" } }, "node_modules/@babel/preset-react": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.18.6.tgz", - "integrity": "sha512-zXr6atUmyYdiWRVLOZahakYmOBHtWc2WGCkP8PYTgZi0iJXDY2CN180TdrIW4OGOAdLc7TifzDIvtx6izaRIzg==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.22.15.tgz", + "integrity": "sha512-Csy1IJ2uEh/PecCBXXoZGAZBeCATTuePzCSB7dLYWS0vOEj6CNpjxIhW4duWwZodBNueH7QO14WbGn8YyeuN9w==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-validator-option": "^7.18.6", - "@babel/plugin-transform-react-display-name": "^7.18.6", - "@babel/plugin-transform-react-jsx": "^7.18.6", - "@babel/plugin-transform-react-jsx-development": "^7.18.6", - "@babel/plugin-transform-react-pure-annotations": "^7.18.6" + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-option": "^7.22.15", + "@babel/plugin-transform-react-display-name": "^7.22.5", + "@babel/plugin-transform-react-jsx": "^7.22.15", + "@babel/plugin-transform-react-jsx-development": "^7.22.5", + "@babel/plugin-transform-react-pure-annotations": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1772,14 +1876,16 @@ } }, "node_modules/@babel/preset-typescript": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.18.6.tgz", - "integrity": "sha512-s9ik86kXBAnD760aybBucdpnLsAt0jK1xqJn2juOn9lkOvSHV60os5hxoVJsPzMQxvnUJFAlkont2DvvaYEBtQ==", + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.23.2.tgz", + "integrity": "sha512-u4UJc1XsS1GhIGteM8rnGiIvf9rJpiVgMEeCnwlLA7WJPC+jcXWJAGxYmeqs5hOZD8BbAfnV5ezBOxQbb4OUxA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-validator-option": "^7.18.6", - "@babel/plugin-transform-typescript": "^7.18.6" + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-option": "^7.22.15", + "@babel/plugin-syntax-jsx": "^7.22.5", + "@babel/plugin-transform-modules-commonjs": "^7.23.0", + "@babel/plugin-transform-typescript": "^7.22.15" }, "engines": { "node": ">=6.9.0" @@ -1788,12 +1894,18 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==", + "dev": true + }, "node_modules/@babel/runtime": { - "version": "7.20.6", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.6.tgz", - "integrity": "sha512-Q+8MqP7TiHMWzSfwiJwXCjyf4GYA4Dgw3emg/7xmwsdLJOZUp+nMqcOwOzzYheuM1rhDu8FSj2l0aoMygEuXuA==", + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.2.tgz", + "integrity": "sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg==", "dependencies": { - "regenerator-runtime": "^0.13.11" + "regenerator-runtime": "^0.14.0" }, "engines": { "node": ">=6.9.0" @@ -1813,41 +1925,39 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/standalone": { - "version": "7.20.6", - "resolved": "https://registry.npmjs.org/@babel/standalone/-/standalone-7.20.6.tgz", - "integrity": "sha512-u5at/CbBLETf7kx2LOY4XdhseD79Y099WZKAOMXeT8qvd9OSR515my2UNBBLY4qIht/Qi9KySeQHQwQwxJN4Sw==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } + "node_modules/@babel/runtime/node_modules/regenerator-runtime": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", + "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==" }, "node_modules/@babel/template": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", - "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", + "dev": true, "dependencies": { - "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.18.10", - "@babel/types": "^7.18.10" + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.5.tgz", - "integrity": "sha512-WM5ZNN3JITQIq9tFZaw1ojLU3WgWdtkxnhM1AegMS+PvHjkM5IXjmYEGY7yukz5XS4sJyEf2VzWjI8uAavhxBQ==", - "dependencies": { - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.20.5", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.20.5", - "@babel/types": "^7.20.5", + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz", + "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.23.0", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.23.0", + "@babel/types": "^7.23.0", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -1856,12 +1966,12 @@ } }, "node_modules/@babel/types": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.5.tgz", - "integrity": "sha512-c9fst/h2/dcF7H+MJKZ2T0KjEQ8hY/BNnDk/H3XY8C4Aw/eWQXWn/lWntHF9ooUBnGmEvbfGrTgLWc+um0YDUg==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz", + "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==", "dependencies": { - "@babel/helper-string-parser": "^7.19.4", - "@babel/helper-validator-identifier": "^7.19.1", + "@babel/helper-string-parser": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.20", "to-fast-properties": "^2.0.0" }, "engines": { @@ -1869,154 +1979,142 @@ } }, "node_modules/@emotion/babel-plugin": { - "version": "11.10.5", - "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.10.5.tgz", - "integrity": "sha512-xE7/hyLHJac7D2Ve9dKroBBZqBT7WuPQmWcq7HSGb84sUuP4mlOWoB8dvVfD9yk5DHkU1m6RW7xSoDtnQHNQeA==", + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz", + "integrity": "sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==", "dependencies": { "@babel/helper-module-imports": "^7.16.7", - "@babel/plugin-syntax-jsx": "^7.17.12", "@babel/runtime": "^7.18.3", - "@emotion/hash": "^0.9.0", - "@emotion/memoize": "^0.8.0", - "@emotion/serialize": "^1.1.1", + "@emotion/hash": "^0.9.1", + "@emotion/memoize": "^0.8.1", + "@emotion/serialize": "^1.1.2", "babel-plugin-macros": "^3.1.0", "convert-source-map": "^1.5.0", "escape-string-regexp": "^4.0.0", "find-root": "^1.1.0", "source-map": "^0.5.7", - "stylis": "4.1.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" + "stylis": "4.2.0" } }, "node_modules/@emotion/cache": { - "version": "11.10.5", - "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.10.5.tgz", - "integrity": "sha512-dGYHWyzTdmK+f2+EnIGBpkz1lKc4Zbj2KHd4cX3Wi8/OWr5pKslNjc3yABKH4adRGCvSX4VDC0i04mrrq0aiRA==", + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.11.0.tgz", + "integrity": "sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ==", "dependencies": { - "@emotion/memoize": "^0.8.0", - "@emotion/sheet": "^1.2.1", - "@emotion/utils": "^1.2.0", - "@emotion/weak-memoize": "^0.3.0", - "stylis": "4.1.3" + "@emotion/memoize": "^0.8.1", + "@emotion/sheet": "^1.2.2", + "@emotion/utils": "^1.2.1", + "@emotion/weak-memoize": "^0.3.1", + "stylis": "4.2.0" } }, "node_modules/@emotion/hash": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.0.tgz", - "integrity": "sha512-14FtKiHhy2QoPIzdTcvh//8OyBlknNs2nXRwIhG904opCby3l+9Xaf/wuPvICBF0rc1ZCNBd3nKe9cd2mecVkQ==" + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.1.tgz", + "integrity": "sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ==" }, "node_modules/@emotion/is-prop-valid": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.0.tgz", - "integrity": "sha512-3aDpDprjM0AwaxGE09bOPkNxHpBd+kA6jty3RnaEXdweX1DF1U3VQpPYb0g1IStAuK7SVQ1cy+bNBBKp4W3Fjg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.1.tgz", + "integrity": "sha512-61Mf7Ufx4aDxx1xlDeOm8aFFigGHE4z+0sKCa+IHCeZKiyP9RLD0Mmx7m8b9/Cf37f7NAvQOOJAbQQGVr5uERw==", "dependencies": { - "@emotion/memoize": "^0.8.0" + "@emotion/memoize": "^0.8.1" } }, "node_modules/@emotion/memoize": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.0.tgz", - "integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==" + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz", + "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==" }, "node_modules/@emotion/react": { - "version": "11.10.5", - "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.10.5.tgz", - "integrity": "sha512-TZs6235tCJ/7iF6/rvTaOH4oxQg2gMAcdHemjwLKIjKz4rRuYe1HJ2TQJKnAcRAfOUDdU8XoDadCe1rl72iv8A==", + "version": "11.11.1", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.11.1.tgz", + "integrity": "sha512-5mlW1DquU5HaxjLkfkGN1GA/fvVGdyHURRiX/0FHl2cfIfRxSOfmxEH5YS43edp0OldZrZ+dkBKbngxcNCdZvA==", "dependencies": { "@babel/runtime": "^7.18.3", - "@emotion/babel-plugin": "^11.10.5", - "@emotion/cache": "^11.10.5", - "@emotion/serialize": "^1.1.1", - "@emotion/use-insertion-effect-with-fallbacks": "^1.0.0", - "@emotion/utils": "^1.2.0", - "@emotion/weak-memoize": "^0.3.0", + "@emotion/babel-plugin": "^11.11.0", + "@emotion/cache": "^11.11.0", + "@emotion/serialize": "^1.1.2", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", + "@emotion/utils": "^1.2.1", + "@emotion/weak-memoize": "^0.3.1", "hoist-non-react-statics": "^3.3.1" }, "peerDependencies": { - "@babel/core": "^7.0.0", "react": ">=16.8.0" }, "peerDependenciesMeta": { - "@babel/core": { - "optional": true - }, "@types/react": { "optional": true } } }, "node_modules/@emotion/serialize": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.1.tgz", - "integrity": "sha512-Zl/0LFggN7+L1liljxXdsVSVlg6E/Z/olVWpfxUTxOAmi8NU7YoeWeLfi1RmnB2TATHoaWwIBRoL+FvAJiTUQA==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.2.tgz", + "integrity": "sha512-zR6a/fkFP4EAcCMQtLOhIgpprZOwNmCldtpaISpvz348+DP4Mz8ZoKaGGCQpbzepNIUWbq4w6hNZkwDyKoS+HA==", "dependencies": { - "@emotion/hash": "^0.9.0", - "@emotion/memoize": "^0.8.0", - "@emotion/unitless": "^0.8.0", - "@emotion/utils": "^1.2.0", + "@emotion/hash": "^0.9.1", + "@emotion/memoize": "^0.8.1", + "@emotion/unitless": "^0.8.1", + "@emotion/utils": "^1.2.1", "csstype": "^3.0.2" } }, "node_modules/@emotion/sheet": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.1.tgz", - "integrity": "sha512-zxRBwl93sHMsOj4zs+OslQKg/uhF38MB+OMKoCrVuS0nyTkqnau+BM3WGEoOptg9Oz45T/aIGs1qbVAsEFo3nA==" + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.2.tgz", + "integrity": "sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==" }, "node_modules/@emotion/styled": { - "version": "11.10.5", - "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.10.5.tgz", - "integrity": "sha512-8EP6dD7dMkdku2foLoruPCNkRevzdcBaY6q0l0OsbyJK+x8D9HWjX27ARiSIKNF634hY9Zdoedh8bJCiva8yZw==", + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.11.0.tgz", + "integrity": "sha512-hM5Nnvu9P3midq5aaXj4I+lnSfNi7Pmd4EWk1fOZ3pxookaQTNew6bp4JaCBYM4HVFZF9g7UjJmsUmC2JlxOng==", "dependencies": { "@babel/runtime": "^7.18.3", - "@emotion/babel-plugin": "^11.10.5", - "@emotion/is-prop-valid": "^1.2.0", - "@emotion/serialize": "^1.1.1", - "@emotion/use-insertion-effect-with-fallbacks": "^1.0.0", - "@emotion/utils": "^1.2.0" + "@emotion/babel-plugin": "^11.11.0", + "@emotion/is-prop-valid": "^1.2.1", + "@emotion/serialize": "^1.1.2", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", + "@emotion/utils": "^1.2.1" }, "peerDependencies": { - "@babel/core": "^7.0.0", "@emotion/react": "^11.0.0-rc.0", "react": ">=16.8.0" }, "peerDependenciesMeta": { - "@babel/core": { - "optional": true - }, "@types/react": { "optional": true } } }, "node_modules/@emotion/unitless": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.0.tgz", - "integrity": "sha512-VINS5vEYAscRl2ZUDiT3uMPlrFQupiKgHz5AA4bCH1miKBg4qtwkim1qPmJj/4WG6TreYMY111rEFsjupcOKHw==" + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz", + "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==" }, "node_modules/@emotion/use-insertion-effect-with-fallbacks": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.0.tgz", - "integrity": "sha512-1eEgUGmkaljiBnRMTdksDV1W4kUnmwgp7X9G8B++9GYwl1lUdqSndSriIrTJ0N7LQaoauY9JJ2yhiOYK5+NI4A==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz", + "integrity": "sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==", "peerDependencies": { "react": ">=16.8.0" } }, "node_modules/@emotion/utils": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.0.tgz", - "integrity": "sha512-sn3WH53Kzpw8oQ5mgMmIzzyAaH2ZqFEbozVVBSYp538E06OSE6ytOp7pRAjNQR+Q/orwqdQYJSe2m3hCOeznkw==" + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.1.tgz", + "integrity": "sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg==" }, "node_modules/@emotion/weak-memoize": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.0.tgz", - "integrity": "sha512-AHPmaAx+RYfZz0eYu6Gviiagpmiyw98ySSlQvCUhVGDRtDFe4DBS0x1bSjdF3gqUDYOczB+yYvBTtEylYSdRhg==" + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz", + "integrity": "sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==" }, "node_modules/@esbuild/android-arm": { - "version": "0.16.3", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.16.3.tgz", - "integrity": "sha512-mueuEoh+s1eRbSJqq9KNBQwI4QhQV6sRXIfTyLXSHGMpyew61rOK4qY21uKbXl1iBoMb0AdL1deWFCQVlN2qHA==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", + "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", "cpu": [ "arm" ], @@ -2030,9 +2128,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.16.3", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.16.3.tgz", - "integrity": "sha512-RolFVeinkeraDvN/OoRf1F/lP0KUfGNb5jxy/vkIMeRRChkrX/HTYN6TYZosRJs3a1+8wqpxAo5PI5hFmxyPRg==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", + "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", "cpu": [ "arm64" ], @@ -2046,9 +2144,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.16.3", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.16.3.tgz", - "integrity": "sha512-SFpTUcIT1bIJuCCBMCQWq1bL2gPTjWoLZdjmIhjdcQHaUfV41OQfho6Ici5uvvkMmZRXIUGpM3GxysP/EU7ifQ==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", + "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", "cpu": [ "x64" ], @@ -2062,9 +2160,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.16.3", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.16.3.tgz", - "integrity": "sha512-DO8WykMyB+N9mIDfI/Hug70Dk1KipavlGAecxS3jDUwAbTpDXj0Lcwzw9svkhxfpCagDmpaTMgxWK8/C/XcXvw==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", + "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", "cpu": [ "arm64" ], @@ -2078,9 +2176,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.16.3", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.16.3.tgz", - "integrity": "sha512-uEqZQ2omc6BvWqdCiyZ5+XmxuHEi1SPzpVxXCSSV2+Sh7sbXbpeNhHIeFrIpRjAs0lI1FmA1iIOxFozKBhKgRQ==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", + "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", "cpu": [ "x64" ], @@ -2094,9 +2192,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.16.3", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.16.3.tgz", - "integrity": "sha512-nJansp3sSXakNkOD5i5mIz2Is/HjzIhFs49b1tjrPrpCmwgBmH9SSzhC/Z1UqlkivqMYkhfPwMw1dGFUuwmXhw==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", + "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", "cpu": [ "arm64" ], @@ -2110,9 +2208,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.16.3", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.16.3.tgz", - "integrity": "sha512-TfoDzLw+QHfc4a8aKtGSQ96Wa+6eimljjkq9HKR0rHlU83vw8aldMOUSJTUDxbcUdcgnJzPaX8/vGWm7vyV7ug==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", + "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", "cpu": [ "x64" ], @@ -2126,9 +2224,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.16.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.16.3.tgz", - "integrity": "sha512-VwswmSYwVAAq6LysV59Fyqk3UIjbhuc6wb3vEcJ7HEJUtFuLK9uXWuFoH1lulEbE4+5GjtHi3MHX+w1gNHdOWQ==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", + "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", "cpu": [ "arm" ], @@ -2142,9 +2240,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.16.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.16.3.tgz", - "integrity": "sha512-7I3RlsnxEFCHVZNBLb2w7unamgZ5sVwO0/ikE2GaYvYuUQs9Qte/w7TqWcXHtCwxvZx/2+F97ndiUQAWs47ZfQ==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", + "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", "cpu": [ "arm64" ], @@ -2158,9 +2256,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.16.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.16.3.tgz", - "integrity": "sha512-X8FDDxM9cqda2rJE+iblQhIMYY49LfvW4kaEjoFbTTQ4Go8G96Smj2w3BRTwA8IHGoi9dPOPGAX63dhuv19UqA==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", + "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", "cpu": [ "ia32" ], @@ -2174,9 +2272,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.16.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.16.3.tgz", - "integrity": "sha512-hIbeejCOyO0X9ujfIIOKjBjNAs9XD/YdJ9JXAy1lHA+8UXuOqbFe4ErMCqMr8dhlMGBuvcQYGF7+kO7waj2KHw==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", + "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", "cpu": [ "loong64" ], @@ -2190,9 +2288,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.16.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.16.3.tgz", - "integrity": "sha512-znFRzICT/V8VZQMt6rjb21MtAVJv/3dmKRMlohlShrbVXdBuOdDrGb+C2cZGQAR8RFyRe7HS6klmHq103WpmVw==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", + "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", "cpu": [ "mips64el" ], @@ -2206,9 +2304,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.16.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.16.3.tgz", - "integrity": "sha512-EV7LuEybxhXrVTDpbqWF2yehYRNz5e5p+u3oQUS2+ZFpknyi1NXxr8URk4ykR8Efm7iu04//4sBg249yNOwy5Q==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", + "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", "cpu": [ "ppc64" ], @@ -2222,9 +2320,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.16.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.16.3.tgz", - "integrity": "sha512-uDxqFOcLzFIJ+r/pkTTSE9lsCEaV/Y6rMlQjUI9BkzASEChYL/aSQjZjchtEmdnVxDKETnUAmsaZ4pqK1eE5BQ==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", + "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", "cpu": [ "riscv64" ], @@ -2238,9 +2336,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.16.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.16.3.tgz", - "integrity": "sha512-NbeREhzSxYwFhnCAQOQZmajsPYtX71Ufej3IQ8W2Gxskfz9DK58ENEju4SbpIj48VenktRASC52N5Fhyf/aliQ==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", + "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", "cpu": [ "s390x" ], @@ -2254,9 +2352,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.16.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.16.3.tgz", - "integrity": "sha512-SDiG0nCixYO9JgpehoKgScwic7vXXndfasjnD5DLbp1xltANzqZ425l7LSdHynt19UWOcDjG9wJJzSElsPvk0w==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", + "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", "cpu": [ "x64" ], @@ -2270,9 +2368,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.16.3", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.16.3.tgz", - "integrity": "sha512-AzbsJqiHEq1I/tUvOfAzCY15h4/7Ivp3ff/o1GpP16n48JMNAtbW0qui2WCgoIZArEHD0SUQ95gvR0oSO7ZbdA==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", + "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", "cpu": [ "x64" ], @@ -2286,9 +2384,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.16.3", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.16.3.tgz", - "integrity": "sha512-gSABi8qHl8k3Cbi/4toAzHiykuBuWLZs43JomTcXkjMZVkp0gj3gg9mO+9HJW/8GB5H89RX/V0QP4JGL7YEEVg==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", + "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", "cpu": [ "x64" ], @@ -2302,9 +2400,9 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.16.3", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.16.3.tgz", - "integrity": "sha512-SF9Kch5Ete4reovvRO6yNjMxrvlfT0F0Flm+NPoUw5Z4Q3r1d23LFTgaLwm3Cp0iGbrU/MoUI+ZqwCv5XJijCw==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", + "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", "cpu": [ "x64" ], @@ -2318,9 +2416,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.16.3", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.16.3.tgz", - "integrity": "sha512-u5aBonZIyGopAZyOnoPAA6fGsDeHByZ9CnEzyML9NqntK6D/xl5jteZUKm/p6nD09+v3pTM6TuUIqSPcChk5gg==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", + "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", "cpu": [ "arm64" ], @@ -2334,9 +2432,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.16.3", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.16.3.tgz", - "integrity": "sha512-GlgVq1WpvOEhNioh74TKelwla9KDuAaLZrdxuuUgsP2vayxeLgVc+rbpIv0IYF4+tlIzq2vRhofV+KGLD+37EQ==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", + "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", "cpu": [ "ia32" ], @@ -2350,9 +2448,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.16.3", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.16.3.tgz", - "integrity": "sha512-5/JuTd8OWW8UzEtyf19fbrtMJENza+C9JoPIkvItgTBQ1FO2ZLvjbPO6Xs54vk0s5JB5QsfieUEshRQfu7ZHow==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", + "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", "cpu": [ "x64" ], @@ -2365,16 +2463,40 @@ "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.8.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.8.0.tgz", + "integrity": "sha512-JylOEEzDiOryeUnFbQz+oViCXS0KsvR1mvHkoMiu5+UiBvy+RYX7tzlIIIEstF/gVa2tj9AQXk3dgnxv6KxhFg==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, "node_modules/@eslint/eslintrc": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.3.tgz", - "integrity": "sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz", + "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==", "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.4.0", - "globals": "^13.15.0", + "espree": "^9.6.0", + "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", @@ -2389,9 +2511,9 @@ } }, "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "13.18.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.18.0.tgz", - "integrity": "sha512-/mR4KI8Ps2spmoc0Ulu9L7agOF0du1CZNQ3dke8yItYlyKNmGrkONemBbd6V8UTc1Wgcqn21t3WYB7dbRmh6/A==", + "version": "13.21.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.21.0.tgz", + "integrity": "sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -2403,44 +2525,71 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@eslint/eslintrc/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==", + "node_modules/@eslint/js": { + "version": "8.51.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.51.0.tgz", + "integrity": "sha512-HxjQ8Qn+4SI3/AFv6sOrDB+g6PpUTDwSJiQqOrnneEk8L71161srI9gjzzZvYVbzHiVg/BvcH95+cK/zfIt4pg==", "dev": true, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, "node_modules/@farfetched/core": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@farfetched/core/-/core-0.4.1.tgz", - "integrity": "sha512-tGiL2O+3SFaIl9E2MKRV4GRhRqIMI3uGBkDtlyyz6s6jKyiznQc43GeEy/0CE34Xd5Twm+LvwXd9CJ338H2hcA==", + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/@farfetched/core/-/core-0.10.4.tgz", + "integrity": "sha512-sNhsuTL5/DPrpgp7JLN3rKJRxX6PHHG0h2Xlq4JjS2BzOGoJC/SB5iEr3kJyZLN4tjdXa2C0G/L7awf6sPh/4g==", "peerDependencies": { - "effector": "^22.4.0" + "effector": "^22.5.0" } }, - "node_modules/@farfetched/react": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@farfetched/react/-/react-0.4.1.tgz", - "integrity": "sha512-FuF+oBiVrUZOHTycwOgN7FwuNX3y97UnoMkl58gLLSyz4OR1ufAv6qHG7jxsFyRyW4xAvyYPgIra2OTcPU8y6w==", + "node_modules/@farfetched/runtypes": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/@farfetched/runtypes/-/runtypes-0.10.4.tgz", + "integrity": "sha512-TRT6AfgFnwBQG3pjjMRC6UBlJ4DbNSvKILajINIJVhgt/9mmxlc8Mt+PObhpm9r0hhscPuLvsmBDKNIUk6UhnA==", "peerDependencies": { - "@farfetched/core": "0.4.1", - "effector-react": "^22.3.0" + "@farfetched/core": "0.10.4", + "runtypes": "^6.6.0" } }, - "node_modules/@farfetched/runtypes": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@farfetched/runtypes/-/runtypes-0.4.1.tgz", - "integrity": "sha512-LNx4hiC2Yjeo2JtKRJ/AnMfTuV4sEMLYH+dgGYcwQV7rjKQSpNtvReo5wW8JjnDnwnxpV0dC7o3KLuXap5ecZg==", + "node_modules/@floating-ui/core": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.5.0.tgz", + "integrity": "sha512-kK1h4m36DQ0UHGj5Ah4db7R0rHemTqqO0QLvUqi1/mUUp3LuAWbWxdxSIf/XsnH9VS6rRVPLJCncjRzUvyCLXg==", + "dependencies": { + "@floating-ui/utils": "^0.1.3" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.5.3.tgz", + "integrity": "sha512-ClAbQnEqJAKCJOEbbLo5IUlZHkNszqhuxS4fHAVxRPXPya6Ysf2G8KypnYcOTpx6I8xcgF9bbHb6g/2KpbV8qA==", + "dependencies": { + "@floating-ui/core": "^1.4.2", + "@floating-ui/utils": "^0.1.3" + } + }, + "node_modules/@floating-ui/react-dom": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.0.2.tgz", + "integrity": "sha512-5qhlDvjaLmAst/rKb3VdlCinwTF4EYMiVxuuc/HVUjs46W0zgtbMmAZ1UTsDrRTxRmUEzl92mOtWbeeXL26lSQ==", + "dependencies": { + "@floating-ui/dom": "^1.5.1" + }, "peerDependencies": { - "@farfetched/core": "0.4.1", - "runtypes": "^6.6.0" + "react": ">=16.8.0", + "react-dom": ">=16.8.0" } }, + "node_modules/@floating-ui/utils": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.1.6.tgz", + "integrity": "sha512-OfX7E2oUDYxtBvsuS4e/jSn4Q9Qb6DzgeYtsAdkPZ47znpoNsMgZw0+tVijiv3uGNR6dgNlty6r9rzIzHjtd/A==" + }, + "node_modules/@fontsource/roboto": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/@fontsource/roboto/-/roboto-5.0.8.tgz", + "integrity": "sha512-XxPltXs5R31D6UZeLIV1td3wTXU3jzd3f2DLsXI8tytMGBkIsGcc9sIyiupRtA8y73HAhuSCeweOoBqf6DbWCA==" + }, "node_modules/@hapi/hoek": { "version": "9.3.0", "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", @@ -2454,18 +2603,10 @@ "@hapi/hoek": "^9.0.0" } }, - "node_modules/@hookform/resolvers": { - "version": "2.9.10", - "resolved": "https://registry.npmjs.org/@hookform/resolvers/-/resolvers-2.9.10.tgz", - "integrity": "sha512-JIL1DgJIlH9yuxcNGtyhsWX/PgNltz+5Gr6+8SX9fhXc/hPbEIk6wPI82nhgvp3uUb6ZfAM5mqg/x7KR7NAb+A==", - "peerDependencies": { - "react-hook-form": "^7.0.0" - } - }, "node_modules/@humanwhocodes/config-array": { - "version": "0.11.7", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.7.tgz", - "integrity": "sha512-kBbPWzN8oVMLb0hOUYXhmxggL/1cJE6ydvjDIGi9EnAGUyA7cLVKQg+d/Dsm+KZwx2czGHrCmMVLiyg8s5JPKw==", + "version": "0.11.11", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.11.tgz", + "integrity": "sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA==", "dev": true, "dependencies": { "@humanwhocodes/object-schema": "^1.2.1", @@ -2495,10 +2636,55 @@ "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", "dev": true }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, "node_modules/@jridgewell/gen-mapping": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", + "dev": true, "dependencies": { "@jridgewell/set-array": "^1.0.0", "@jridgewell/sourcemap-codec": "^1.4.10" @@ -2511,6 +2697,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "dev": true, "engines": { "node": ">=6.0.0" } @@ -2519,6 +2706,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "dev": true, "engines": { "node": ">=6.0.0" } @@ -2528,6 +2716,7 @@ "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz", "integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==", "dev": true, + "optional": true, "peer": true, "dependencies": { "@jridgewell/gen-mapping": "^0.3.0", @@ -2539,6 +2728,7 @@ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", "dev": true, + "optional": true, "peer": true, "dependencies": { "@jridgewell/set-array": "^1.0.1", @@ -2552,12 +2742,14 @@ "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==" + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "dev": true }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.17", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", + "dev": true, "dependencies": { "@jridgewell/resolve-uri": "3.1.0", "@jridgewell/sourcemap-codec": "1.4.14" @@ -2596,20 +2788,20 @@ } }, "node_modules/@mui/core-downloads-tracker": { - "version": "5.10.17", - "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.10.17.tgz", - "integrity": "sha512-iNwUuMA30nrN0tiEkeD3zaczv7Tk2jlZIDbXRnijAsYXkZtl/xEzQsVRIPYRDuyEz6D18vQJhV8h7gPUXEubTg==", + "version": "5.14.14", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.14.14.tgz", + "integrity": "sha512-Rw/xKiTOUgXD8hdKqj60aC6QcGprMipG7ne2giK6Mz7b4PlhL/xog9xLeclY3BxsRLkZQ05egFnIEY1CSibTbw==", "funding": { "type": "opencollective", "url": "https://opencollective.com/mui" } }, "node_modules/@mui/icons-material": { - "version": "5.10.16", - "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.10.16.tgz", - "integrity": "sha512-jjCc0IF6iyLiucQCu5igg3fOscSqbbvRCmyRxXgzOcLR56B0sg2L8o+ZfJ0dAg59+wvgtXaxvjze/mJg0B4iWA==", + "version": "5.14.14", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.14.14.tgz", + "integrity": "sha512-vwuaMsKvI7AWTeYqR8wYbpXijuU8PzMAJWRAq2DDIuOZPxjKyHlr8WQ25+azZYkIXtJ7AqnVb1ZmHdEyB4/kug==", "dependencies": { - "@babel/runtime": "^7.20.1" + "@babel/runtime": "^7.23.1" }, "engines": { "node": ">=12.0.0" @@ -2671,19 +2863,19 @@ } }, "node_modules/@mui/material": { - "version": "5.10.17", - "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.10.17.tgz", - "integrity": "sha512-Kuqgv1qI5HXnc/Xu426xhCGYBSKzplb+xFNLitbnIb92Qx8jmcpfNpFlDJa2kD2H6qP66rr/m4c/zMUfGX/xBQ==", - "dependencies": { - "@babel/runtime": "^7.20.1", - "@mui/base": "5.0.0-alpha.109", - "@mui/core-downloads-tracker": "^5.10.17", - "@mui/system": "^5.10.17", - "@mui/types": "^7.2.2", - "@mui/utils": "^5.10.16", - "@types/react-transition-group": "^4.4.5", - "clsx": "^1.2.1", - "csstype": "^3.1.1", + "version": "5.14.14", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.14.14.tgz", + "integrity": "sha512-cAmCwAHFQXxb44kWbVFkhKATN8tACgMsFwrXo8ro6WzYW73U/qsR5AcCiJIhCyYYg+gcftfkmNcpRaV3JjhHCg==", + "dependencies": { + "@babel/runtime": "^7.23.1", + "@mui/base": "5.0.0-beta.20", + "@mui/core-downloads-tracker": "^5.14.14", + "@mui/system": "^5.14.14", + "@mui/types": "^7.2.6", + "@mui/utils": "^5.14.13", + "@types/react-transition-group": "^4.4.7", + "clsx": "^2.0.0", + "csstype": "^3.1.2", "prop-types": "^15.8.1", "react-is": "^18.2.0", "react-transition-group": "^4.4.5" @@ -2715,18 +2907,17 @@ } }, "node_modules/@mui/material/node_modules/@mui/base": { - "version": "5.0.0-alpha.109", - "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-alpha.109.tgz", - "integrity": "sha512-UQxoONPI3ntzxcD/cbFHl+Lp2xsVj6HpKmU9QhUZ2kZ2K2yej2QJyU1gnADoWl/Hu94VrvwSSRnjTjR3HvXO/g==", - "dependencies": { - "@babel/runtime": "^7.20.1", - "@emotion/is-prop-valid": "^1.2.0", - "@mui/types": "^7.2.2", - "@mui/utils": "^5.10.16", - "@popperjs/core": "^2.11.6", - "clsx": "^1.2.1", - "prop-types": "^15.8.1", - "react-is": "^18.2.0" + "version": "5.0.0-beta.20", + "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.20.tgz", + "integrity": "sha512-CS2pUuqxST7ch9VNDCklRYDbJ3rru20Tx7na92QvVVKfu3RL4z/QLuVIc8jYGsdCnauMaeUSlFNLAJNb0yXe6w==", + "dependencies": { + "@babel/runtime": "^7.23.1", + "@floating-ui/react-dom": "^2.0.2", + "@mui/types": "^7.2.6", + "@mui/utils": "^5.14.13", + "@popperjs/core": "^2.11.8", + "clsx": "^2.0.0", + "prop-types": "^15.8.1" }, "engines": { "node": ">=12.0.0" @@ -2746,13 +2937,21 @@ } } }, + "node_modules/@mui/material/node_modules/clsx": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.0.0.tgz", + "integrity": "sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==", + "engines": { + "node": ">=6" + } + }, "node_modules/@mui/private-theming": { - "version": "5.10.16", - "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.10.16.tgz", - "integrity": "sha512-0MArkJaOHRCKqL/GWjngGZmyOeRz+uxffhx82bKcewr8swqV7xx7EFP02pk0L/gLdfcvYdqwH4YTVjG/+TaKrg==", + "version": "5.14.14", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.14.14.tgz", + "integrity": "sha512-n77au3CQj9uu16hak2Y+rvbGSBaJKxziG/gEbOLVGrAuqZ+ycVSkorCfN6Y/4XgYOpG/xvmuiY3JwhAEOzY3iA==", "dependencies": { - "@babel/runtime": "^7.20.1", - "@mui/utils": "^5.10.16", + "@babel/runtime": "^7.23.1", + "@mui/utils": "^5.14.13", "prop-types": "^15.8.1" }, "engines": { @@ -2773,13 +2972,13 @@ } }, "node_modules/@mui/styled-engine": { - "version": "5.10.16", - "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.10.16.tgz", - "integrity": "sha512-ZMSjXvtiGwGDKqrSlXhpxK2voUaF2/lpC/pSTfFmZvKH9j9a9h1/iwo3ybgjFVYGgbfNeW4h0xEchiRohu9xsw==", + "version": "5.14.14", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.14.14.tgz", + "integrity": "sha512-sF3DS2PVG+cFWvkVHQQaGFpL1h6gSwOW3L91pdxPLQDHDZ5mZ/X0SlXU5XA+WjypoysG4urdAQC7CH/BRvUiqg==", "dependencies": { - "@babel/runtime": "^7.20.1", - "@emotion/cache": "^11.10.5", - "csstype": "^3.1.1", + "@babel/runtime": "^7.23.1", + "@emotion/cache": "^11.11.0", + "csstype": "^3.1.2", "prop-types": "^15.8.1" }, "engines": { @@ -2804,17 +3003,17 @@ } }, "node_modules/@mui/system": { - "version": "5.10.17", - "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.10.17.tgz", - "integrity": "sha512-UYzAOSK7uxkMsUssqrIUW3lnOuQpU8vqh4hLwfSw+GYAnQo3qjK4m4NhlDx+pFpsjjiGnr3K+vrSH+aIAMbcLg==", - "dependencies": { - "@babel/runtime": "^7.20.1", - "@mui/private-theming": "^5.10.16", - "@mui/styled-engine": "^5.10.16", - "@mui/types": "^7.2.2", - "@mui/utils": "^5.10.16", - "clsx": "^1.2.1", - "csstype": "^3.1.1", + "version": "5.14.14", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.14.14.tgz", + "integrity": "sha512-y4InFmCgGGWXnz+iK4jRTWVikY0HgYnABjz4wgiUgEa2W1H8M4ow+27BegExUWPkj4TWthQ2qG9FOGSMtI+PKA==", + "dependencies": { + "@babel/runtime": "^7.23.1", + "@mui/private-theming": "^5.14.14", + "@mui/styled-engine": "^5.14.13", + "@mui/types": "^7.2.6", + "@mui/utils": "^5.14.13", + "clsx": "^2.0.0", + "csstype": "^3.1.2", "prop-types": "^15.8.1" }, "engines": { @@ -2842,12 +3041,20 @@ } } }, + "node_modules/@mui/system/node_modules/clsx": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.0.0.tgz", + "integrity": "sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==", + "engines": { + "node": ">=6" + } + }, "node_modules/@mui/types": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.2.tgz", - "integrity": "sha512-siex8cZDtWeC916cXOoUOnEQQejuMYmHtc4hM6VkKVYaBICz3VIiqyiAomRboTQHt2jchxQ5Q5ATlbcDekTxDA==", + "version": "7.2.6", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.6.tgz", + "integrity": "sha512-7sjLQrUmBwufm/M7jw/quNiPK/oor2+pGUQP2CULRcFCArYTq78oJ3D5esTaL0UMkXKJvDqXn6Ike69yAOBQng==", "peerDependencies": { - "@types/react": "*" + "@types/react": "^17.0.0 || ^18.0.0" }, "peerDependenciesMeta": { "@types/react": { @@ -2856,13 +3063,12 @@ } }, "node_modules/@mui/utils": { - "version": "5.10.16", - "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.10.16.tgz", - "integrity": "sha512-3MB/SGsgiiu9Z55CFmAfiONUoR7AAue/H4F6w3mc2LnhFQCsoVvXhioDPcsiRpUMIQr34jDPzGXdCuqWooPCXQ==", + "version": "5.14.14", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.14.14.tgz", + "integrity": "sha512-3AKp8uksje5sRfVrtgG9Q/2TBsHWVBUtA0NaXliZqGcXo8J+A+Agp0qUW2rJ+ivgPWTCCubz9FZVT2IQZ3bGsw==", "dependencies": { - "@babel/runtime": "^7.20.1", - "@types/prop-types": "^15.7.5", - "@types/react-is": "^16.7.1 || ^17.0.0", + "@babel/runtime": "^7.23.1", + "@types/prop-types": "^15.7.7", "prop-types": "^15.8.1", "react-is": "^18.2.0" }, @@ -2874,7 +3080,117 @@ "url": "https://opencollective.com/mui" }, "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0", "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/x-date-pickers": { + "version": "6.16.2", + "resolved": "https://registry.npmjs.org/@mui/x-date-pickers/-/x-date-pickers-6.16.2.tgz", + "integrity": "sha512-JFrDUeBkiKtfJ0WqwyPBICEP1U+Ujfsily3ZQ/Hv4zAOleG/5769EgS7TOO4cVgnuhtvQ/pqx2gmuCn8/gcC5w==", + "dependencies": { + "@babel/runtime": "^7.23.1", + "@mui/base": "^5.0.0-beta.17", + "@mui/utils": "^5.14.11", + "@types/react-transition-group": "^4.4.7", + "clsx": "^2.0.0", + "prop-types": "^15.8.1", + "react-transition-group": "^4.4.5" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "peerDependencies": { + "@emotion/react": "^11.9.0", + "@emotion/styled": "^11.8.1", + "@mui/material": "^5.8.6", + "@mui/system": "^5.8.0", + "date-fns": "^2.25.0", + "date-fns-jalali": "^2.13.0-0", + "dayjs": "^1.10.7", + "luxon": "^3.0.2", + "moment": "^2.29.4", + "moment-hijri": "^2.1.2", + "moment-jalaali": "^0.7.4 || ^0.8.0 || ^0.9.0 || ^0.10.0", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "date-fns": { + "optional": true + }, + "date-fns-jalali": { + "optional": true + }, + "dayjs": { + "optional": true + }, + "luxon": { + "optional": true + }, + "moment": { + "optional": true + }, + "moment-hijri": { + "optional": true + }, + "moment-jalaali": { + "optional": true + } + } + }, + "node_modules/@mui/x-date-pickers/node_modules/@mui/base": { + "version": "5.0.0-beta.20", + "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.20.tgz", + "integrity": "sha512-CS2pUuqxST7ch9VNDCklRYDbJ3rru20Tx7na92QvVVKfu3RL4z/QLuVIc8jYGsdCnauMaeUSlFNLAJNb0yXe6w==", + "dependencies": { + "@babel/runtime": "^7.23.1", + "@floating-ui/react-dom": "^2.0.2", + "@mui/types": "^7.2.6", + "@mui/utils": "^5.14.13", + "@popperjs/core": "^2.11.8", + "clsx": "^2.0.0", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/x-date-pickers/node_modules/clsx": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.0.0.tgz", + "integrity": "sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==", + "engines": { + "node": ">=6" } }, "node_modules/@nicolo-ribaudo/chokidar-2": { @@ -2919,19 +3235,29 @@ "node": ">= 8" } }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=14" + } + }, "node_modules/@popperjs/core": { - "version": "2.11.6", - "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.6.tgz", - "integrity": "sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw==", + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", "funding": { "type": "opencollective", "url": "https://opencollective.com/popperjs" } }, "node_modules/@rollup/plugin-babel": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-6.0.3.tgz", - "integrity": "sha512-fKImZKppa1A/gX73eg4JGo+8kQr/q1HBQaCGKECZ0v4YBBv3lFqi14+7xyApECzvkLTHCifx+7ntcrvtBIRcpg==", + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-6.0.4.tgz", + "integrity": "sha512-YF7Y52kFdFT/xVSuVdjkV5ZdX/3YtmX0QulG+x0taQOtJdHYzVU61aSSkAgVJ7NOv6qPkIYiJSgSWWN/DM5sGw==", "dev": true, "dependencies": { "@babel/helper-module-imports": "^7.18.6", @@ -2943,7 +3269,7 @@ "peerDependencies": { "@babel/core": "^7.0.0", "@types/babel__core": "^7.1.9", - "rollup": "^1.20.0||^2.0.0||^3.0.0" + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" }, "peerDependenciesMeta": { "@types/babel__core": { @@ -2985,28 +3311,23 @@ } }, "node_modules/@sideway/formula": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.0.tgz", - "integrity": "sha512-vHe7wZ4NOXVfkoRb8T5otiENVlT7a3IAiw7H5M2+GO+9CDgcVUUsX1zalAztCmwyOr2RUTGJdgB+ZvSVqmdHmg==" + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz", + "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==" }, "node_modules/@sideway/pinpoint": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==" }, - "node_modules/@socket.io/component-emitter": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz", - "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==" - }, "node_modules/@types/babel__core": { - "version": "7.1.20", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.20.tgz", - "integrity": "sha512-PVb6Bg2QuscZ30FvOU7z4guG6c926D9YRvOxEaelzndpMsvP+YM74Q/dAFASpg2l6+XLalxSGxcq/lrgYWZtyQ==", + "version": "7.20.3", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.3.tgz", + "integrity": "sha512-54fjTSeSHwfan8AyHWrKbfBWiEUrNTZsUwPTDSNaaP1QDQIZbeNUg3a59E9D+375MzUw/x1vx2/0F5LBz+AeYA==", "dev": true, "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0", + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", "@types/babel__generator": "*", "@types/babel__template": "*", "@types/babel__traverse": "*" @@ -3040,47 +3361,12 @@ "@babel/types": "^7.3.0" } }, - "node_modules/@types/css-modules-loader-core": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@types/css-modules-loader-core/-/css-modules-loader-core-1.1.0.tgz", - "integrity": "sha512-LMbyf7THPqLCPHIXAj79v9Pa193MeOHgp1fBFRR6s6VvEVHUFIcM5bc/WttslOf+lao4TURNN1X1zfW5wr2CHQ==", - "dev": true, - "dependencies": { - "postcss": "7.x.x" - } - }, - "node_modules/@types/css-modules-loader-core/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==", + "node_modules/@types/compose-function": { + "version": "0.0.32", + "resolved": "https://registry.npmjs.org/@types/compose-function/-/compose-function-0.0.32.tgz", + "integrity": "sha512-eolBu32OsVG1Rk0Vq84TDAuVl8v4NAkb0QtmuD3en08lv8Uy8el1NoS3hGTRTaLaQfaL8GRUiBT1aZhoH5bWNg==", "dev": true }, - "node_modules/@types/css-modules-loader-core/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dev": true, - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/@types/css-modules-loader-core/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/@types/estree": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.0.tgz", @@ -3088,9 +3374,9 @@ "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==", + "version": "7.0.14", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.14.tgz", + "integrity": "sha512-U3PUjAudAdJBeC2pgN8uTIKgxrb4nlDF3SF0++EldXQvQBGkpFZMSnwQiIoDU77tv45VgNkl/L4ouD+rEomujw==", "dev": true }, "node_modules/@types/json5": { @@ -3100,10 +3386,13 @@ "dev": true }, "node_modules/@types/node": { - "version": "18.11.12", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.12.tgz", - "integrity": "sha512-FgD3NtTAKvyMmD44T07zz2fEf+OKwutgBCEVM8GcvMGVGaDktiLNTDvPwC/LUe3PinMW+X6CuLOF2Ui1mAlSXg==", - "dev": true + "version": "20.8.7", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.7.tgz", + "integrity": "sha512-21TKHHh3eUHIi2MloeptJWALuCu5H7HQTdTrWIFReA8ad+aggoX+lRes3ex7/FtpC+sVUpFMQ+QTfYr74mruiQ==", + "dev": true, + "dependencies": { + "undici-types": "~5.25.1" + } }, "node_modules/@types/parse-json": { "version": "4.0.0", @@ -3111,14 +3400,14 @@ "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==" }, "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==" + "version": "15.7.9", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.9.tgz", + "integrity": "sha512-n1yyPsugYNSmHgxDFjicaI2+gCNjsBck8UX9kuofAKlc0h1bL+20oSF72KeNaW2DUlesbEVCFgyV2dPGTiY42g==" }, "node_modules/@types/react": { - "version": "18.0.26", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.26.tgz", - "integrity": "sha512-hCR3PJQsAIXyxhTNSiDFY//LhnMZWpNNr5etoCqx/iUfGc5gXWtQR2Phl908jVR6uPXacojQWTg4qRpkxTuGug==", + "version": "18.2.31", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.31.tgz", + "integrity": "sha512-c2UnPv548q+5DFh03y8lEDeMfDwBn9G3dRwfkrxQMo/dOtRHUUO57k6pHvBIfH/VF4Nh+98mZ5aaSe+2echD5g==", "dependencies": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -3126,26 +3415,18 @@ } }, "node_modules/@types/react-dom": { - "version": "18.0.9", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.0.9.tgz", - "integrity": "sha512-qnVvHxASt/H7i+XG1U1xMiY5t+IHcPGUK7TDMDzom08xa7e86eCeKOiLZezwCKVxJn6NEiiy2ekgX8aQssjIKg==", + "version": "18.2.14", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.14.tgz", + "integrity": "sha512-V835xgdSVmyQmI1KLV2BEIUgqEuinxp9O4G6g3FqO/SqLac049E53aysv0oEFD2kHfejeKU+ZqL2bcFWj9gLAQ==", "dev": true, "dependencies": { "@types/react": "*" } }, - "node_modules/@types/react-is": { - "version": "17.0.3", - "resolved": "https://registry.npmjs.org/@types/react-is/-/react-is-17.0.3.tgz", - "integrity": "sha512-aBTIWg1emtu95bLTLx0cpkxwGW3ueZv71nE2YFBpL8k/z5czEW8yYpOo8Dp+UUAFAtKwNaOsh/ioSeQnWlZcfw==", - "dependencies": { - "@types/react": "*" - } - }, "node_modules/@types/react-transition-group": { - "version": "4.4.5", - "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.5.tgz", - "integrity": "sha512-juKD/eiSM3/xZYzjuzH6ZwpP+/lejltmiS3QEzV/vmb/Q8+HfDmxu+Baga8UEMGBqV88Nbg4l2hY/K2DkyaLLA==", + "version": "4.4.8", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.8.tgz", + "integrity": "sha512-QmQ22q+Pb+HQSn04NL3HtrqHwYMf4h3QKArOy5F8U5nEVMaihBs3SR10WiOM1iwPz5jIo8x/u11al+iEGZZrvg==", "dependencies": { "@types/react": "*" } @@ -3156,37 +3437,39 @@ "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==" }, "node_modules/@types/semver": { - "version": "7.3.13", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz", - "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-MMzuxN3GdFwskAnb6fz0orFvhfqi752yjaXylr0Rp4oDg5H0Zn1IuyRhDVvYOwAXoJirx2xuS16I3WjxnAIHiQ==", "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.46.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.46.0.tgz", - "integrity": "sha512-QrZqaIOzJAjv0sfjY4EjbXUi3ZOFpKfzntx22gPGr9pmFcTjcFw/1sS1LJhEubfAGwuLjNrPV0rH+D1/XZFy7Q==", + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.8.0.tgz", + "integrity": "sha512-GosF4238Tkes2SHPQ1i8f6rMtG6zlKwMEB0abqSJ3Npvos+doIlc/ATG+vX1G9coDF3Ex78zM3heXHLyWEwLUw==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.46.0", - "@typescript-eslint/type-utils": "5.46.0", - "@typescript-eslint/utils": "5.46.0", + "@eslint-community/regexpp": "^4.5.1", + "@typescript-eslint/scope-manager": "6.8.0", + "@typescript-eslint/type-utils": "6.8.0", + "@typescript-eslint/utils": "6.8.0", + "@typescript-eslint/visitor-keys": "6.8.0", "debug": "^4.3.4", - "ignore": "^5.2.0", - "natural-compare-lite": "^1.4.0", - "regexpp": "^3.2.0", - "semver": "^7.3.7", - "tsutils": "^3.21.0" + "graphemer": "^1.4.0", + "ignore": "^5.2.4", + "natural-compare": "^1.4.0", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^16.0.0 || >=18.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^5.0.0", - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha", + "eslint": "^7.0.0 || ^8.0.0" }, "peerDependenciesMeta": { "typescript": { @@ -3194,10 +3477,22 @@ } } }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -3209,26 +3504,33 @@ "node": ">=10" } }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, "node_modules/@typescript-eslint/parser": { - "version": "5.46.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.46.0.tgz", - "integrity": "sha512-joNO6zMGUZg+C73vwrKXCd8usnsmOYmgW/w5ZW0pG0RGvqeznjtGDk61EqqTpNrFLUYBW2RSBFrxdAZMqA4OZA==", + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.8.0.tgz", + "integrity": "sha512-5tNs6Bw0j6BdWuP8Fx+VH4G9fEPDxnVI7yH1IAPkQH5RUtvKwRoqdecAPdQXv4rSOADAaz1LFBZvZG7VbXivSg==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.46.0", - "@typescript-eslint/types": "5.46.0", - "@typescript-eslint/typescript-estree": "5.46.0", + "@typescript-eslint/scope-manager": "6.8.0", + "@typescript-eslint/types": "6.8.0", + "@typescript-eslint/typescript-estree": "6.8.0", + "@typescript-eslint/visitor-keys": "6.8.0", "debug": "^4.3.4" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^16.0.0 || >=18.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + "eslint": "^7.0.0 || ^8.0.0" }, "peerDependenciesMeta": { "typescript": { @@ -3237,16 +3539,16 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "5.46.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.46.0.tgz", - "integrity": "sha512-7wWBq9d/GbPiIM6SqPK9tfynNxVbfpihoY5cSFMer19OYUA3l4powA2uv0AV2eAZV6KoAh6lkzxv4PoxOLh1oA==", + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.8.0.tgz", + "integrity": "sha512-xe0HNBVwCph7rak+ZHcFD6A+q50SMsFwcmfdjs9Kz4qDh5hWhaPhFjRs/SODEhroBI5Ruyvyz9LfwUJ624O40g==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.46.0", - "@typescript-eslint/visitor-keys": "5.46.0" + "@typescript-eslint/types": "6.8.0", + "@typescript-eslint/visitor-keys": "6.8.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^16.0.0 || >=18.0.0" }, "funding": { "type": "opencollective", @@ -3254,25 +3556,25 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "5.46.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.46.0.tgz", - "integrity": "sha512-dwv4nimVIAsVS2dTA0MekkWaRnoYNXY26dKz8AN5W3cBFYwYGFQEqm/cG+TOoooKlncJS4RTbFKgcFY/pOiBCg==", + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.8.0.tgz", + "integrity": "sha512-RYOJdlkTJIXW7GSldUIHqc/Hkto8E+fZN96dMIFhuTJcQwdRoGN2rEWA8U6oXbLo0qufH7NPElUb+MceHtz54g==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "5.46.0", - "@typescript-eslint/utils": "5.46.0", + "@typescript-eslint/typescript-estree": "6.8.0", + "@typescript-eslint/utils": "6.8.0", "debug": "^4.3.4", - "tsutils": "^3.21.0" + "ts-api-utils": "^1.0.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^16.0.0 || >=18.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "*" + "eslint": "^7.0.0 || ^8.0.0" }, "peerDependenciesMeta": { "typescript": { @@ -3281,12 +3583,12 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "5.46.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.46.0.tgz", - "integrity": "sha512-wHWgQHFB+qh6bu0IAPAJCdeCdI0wwzZnnWThlmHNY01XJ9Z97oKqKOzWYpR2I83QmshhQJl6LDM9TqMiMwJBTw==", + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.8.0.tgz", + "integrity": "sha512-p5qOxSum7W3k+llc7owEStXlGmSl8FcGvhYt8Vjy7FqEnmkCVlM3P57XQEGj58oqaBWDQXbJDZxwUWMS/EAPNQ==", "dev": true, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^16.0.0 || >=18.0.0" }, "funding": { "type": "opencollective", @@ -3294,21 +3596,21 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.46.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.46.0.tgz", - "integrity": "sha512-kDLNn/tQP+Yp8Ro2dUpyyVV0Ksn2rmpPpB0/3MO874RNmXtypMwSeazjEN/Q6CTp8D7ExXAAekPEcCEB/vtJkw==", + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.8.0.tgz", + "integrity": "sha512-ISgV0lQ8XgW+mvv5My/+iTUdRmGspducmQcDw5JxznasXNnZn3SKNrTRuMsEXv+V/O+Lw9AGcQCfVaOPCAk/Zg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.46.0", - "@typescript-eslint/visitor-keys": "5.46.0", + "@typescript-eslint/types": "6.8.0", + "@typescript-eslint/visitor-keys": "6.8.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^16.0.0 || >=18.0.0" }, "funding": { "type": "opencollective", @@ -3320,10 +3622,22 @@ } } }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -3335,36 +3649,53 @@ "node": ">=10" } }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, "node_modules/@typescript-eslint/utils": { - "version": "5.46.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.46.0.tgz", - "integrity": "sha512-4O+Ps1CRDw+D+R40JYh5GlKLQERXRKW5yIQoNDpmXPJ+C7kaPF9R7GWl+PxGgXjB3PQCqsaaZUpZ9dG4U6DO7g==", + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.8.0.tgz", + "integrity": "sha512-dKs1itdE2qFG4jr0dlYLQVppqTE+Itt7GmIf/vX6CSvsW+3ov8PbWauVKyyfNngokhIO9sKZeRGCUo1+N7U98Q==", "dev": true, "dependencies": { - "@types/json-schema": "^7.0.9", - "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.46.0", - "@typescript-eslint/types": "5.46.0", - "@typescript-eslint/typescript-estree": "5.46.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0", - "semver": "^7.3.7" + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.12", + "@types/semver": "^7.5.0", + "@typescript-eslint/scope-manager": "6.8.0", + "@typescript-eslint/types": "6.8.0", + "@typescript-eslint/typescript-estree": "6.8.0", + "semver": "^7.5.4" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^16.0.0 || >=18.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + "eslint": "^7.0.0 || ^8.0.0" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" } }, "node_modules/@typescript-eslint/utils/node_modules/semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -3376,66 +3707,60 @@ "node": ">=10" } }, + "node_modules/@typescript-eslint/utils/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.46.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.46.0.tgz", - "integrity": "sha512-E13gBoIXmaNhwjipuvQg1ByqSAu/GbEpP/qzFihugJ+MomtoJtFAJG/+2DRPByf57B863m0/q7Zt16V9ohhANw==", + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.8.0.tgz", + "integrity": "sha512-oqAnbA7c+pgOhW2OhGvxm0t1BULX5peQI/rLsNDpGM78EebV3C9IGbX5HNZabuZ6UQrYveCLjKo8Iy/lLlBkkg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.46.0", - "eslint-visitor-keys": "^3.3.0" + "@typescript-eslint/types": "6.8.0", + "eslint-visitor-keys": "^3.4.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^16.0.0 || >=18.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@vitejs/plugin-legacy": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-legacy/-/plugin-legacy-3.0.1.tgz", - "integrity": "sha512-XCtEjxoR3rmy000ujYRBp5kggWqzHz9+F20/yIMUWOzbvu0+KW1e14Fvb8h7SpNn+bfjGW1RiAs1Vrgb7Js+iQ==", + "node_modules/@vitejs/plugin-react": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.1.0.tgz", + "integrity": "sha512-rM0SqazU9iqPUraQ2JlIvReeaxOoRj6n+PzB1C0cBzIbd8qP336nC39/R9yPi3wVcah7E7j/kdU1uCUqMEU4OQ==", "dev": true, "dependencies": { - "@babel/standalone": "^7.20.6", - "core-js": "^3.26.1", - "magic-string": "^0.27.0", - "regenerator-runtime": "^0.13.11", - "systemjs": "^6.13.0" + "@babel/core": "^7.22.20", + "@babel/plugin-transform-react-jsx-self": "^7.22.5", + "@babel/plugin-transform-react-jsx-source": "^7.22.5", + "@types/babel__core": "^7.20.2", + "react-refresh": "^0.14.0" }, "engines": { "node": "^14.18.0 || >=16.0.0" }, "peerDependencies": { - "terser": "^5.4.0", - "vite": "^4.0.0" + "vite": "^4.2.0" } }, - "node_modules/@vitejs/plugin-react": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-3.0.0.tgz", - "integrity": "sha512-1mvyPc0xYW5G8CHQvJIJXLoMjl5Ct3q2g5Y2s6Ccfgwm45y48LBvsla7az+GkkAtYikWQ4Lxqcsq5RHLcZgtNQ==", - "dev": true, - "dependencies": { - "@babel/core": "^7.20.5", - "@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" - }, + "node_modules/@withease/web-api": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@withease/web-api/-/web-api-1.0.1.tgz", + "integrity": "sha512-KC+6ueVd1rEpLvMN7uXHa7E5TKdv7MxIhEAAs8tjAgmKxkUgranpsrjU2ZlwHGimuc98Z428/n+zgldZE3nIMg==", "peerDependencies": { - "vite": "^4.0.0" + "effector": "^22.5.0" } }, "node_modules/acorn": { - "version": "8.8.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", - "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", + "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -3453,19 +3778,6 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "dev": true, - "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -3483,15 +3795,27 @@ } }, "node_modules/ansi-escapes": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-6.0.0.tgz", - "integrity": "sha512-IG23inYII3dWlU2EyiAiGj6Bwal5GzsgPMwjYGvc1HPE2dgbj4ZB5ToWBKSquKw74nB3TIuOwaI6/jSULzfgrw==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-5.0.0.tgz", + "integrity": "sha512-5GFMVX8HqE/TB+FuBJGuO5XG0WrsA6ptUqoODaT/n9mmUaZFkqnBueB4leqGBCmrUHnCnC4PCZTCd0E7QQ83bA==", "dev": true, "dependencies": { - "type-fest": "^3.0.0" + "type-fest": "^1.0.2" + }, + "engines": { + "node": ">=12" }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", + "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", + "dev": true, "engines": { - "node": ">=14.16" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -3550,6 +3874,24 @@ "node": ">=6.0" } }, + "node_modules/arity-n": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/arity-n/-/arity-n-1.0.4.tgz", + "integrity": "sha512-fExL2kFDC1Q2DUOx3whE/9KoN66IzkY4b4zUHUBFM1ojEYjZZYDcUW3bek/ufGionX9giIKDC5redH2IlGqcQQ==" + }, + "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", @@ -3578,6 +3920,25 @@ "node": ">=8" } }, + "node_modules/array.prototype.findlastindex": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.3.tgz", + "integrity": "sha512-LzLoiOMAxvy+Gd3BAq3B7VeIgPdo+Q8hthvKtXybMvRV0jrXfJM/t8mw7nNlpEcVlVUnCnM2KSX4XU5HmpodOA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0", + "get-intrinsic": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/array.prototype.flat": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz", @@ -3601,7 +3962,6 @@ "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz", "integrity": "sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.1.4", @@ -3615,6 +3975,27 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz", + "integrity": "sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", + "is-array-buffer": "^3.0.2", + "is-shared-array-buffer": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/ast-types-flow": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", @@ -3622,20 +4003,6 @@ "dev": true, "peer": true }, - "node_modules/astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "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/atomic-router": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/atomic-router/-/atomic-router-0.8.0.tgz", @@ -3652,9 +4019,9 @@ } }, "node_modules/atomic-router-react": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/atomic-router-react/-/atomic-router-react-0.8.1.tgz", - "integrity": "sha512-zD8MrolFnPhQLOvBmDl6scur3fDCPGavC04WMK2b532q4+5NDk9Eo9mPZvJFvq/Z21UDR7jWOo7Gjzl0AVKRFQ==", + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/atomic-router-react/-/atomic-router-react-0.8.5.tgz", + "integrity": "sha512-XI+L5Kt+NSbVyZ8rc2M+9i4VslETv+ASNuR3wUm537p83mkXWVqZ37taNCsVDnX2D4vLGkfj8Fl6b/hw/tBqeQ==", "dependencies": { "clsx": "^1.1.1" }, @@ -3668,37 +4035,16 @@ "react": "^17 || ^18" } }, - "node_modules/autoprefixer": { - "version": "10.4.13", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.13.tgz", - "integrity": "sha512-49vKpMqcZYsJjwotvt4+h/BCjJVnhGwcLpDt5xkcaOG3eLrG/HUYLagrihYsQ+qrIBgIzX1Rw7a6L8I/ZA1Atg==", + "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, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/autoprefixer" - } - ], - "dependencies": { - "browserslist": "^4.21.4", - "caniuse-lite": "^1.0.30001426", - "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" + "node": ">= 0.4" }, - "peerDependencies": { - "postcss": "^8.1.0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/axe-core": { @@ -3711,16 +4057,6 @@ "node": ">=4" } }, - "node_modules/axios": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.2.1.tgz", - "integrity": "sha512-I88cFiGu9ryt/tfVEi4kX2SITsvDddTajXTOFmt2uK1ZVA8LytjtdeyefdQWEf5PU8w+4SSJDoYnggflB5tW4A==", - "dependencies": { - "follow-redirects": "^1.15.0", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - }, "node_modules/axobject-query": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", @@ -3743,42 +4079,42 @@ } }, "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz", - "integrity": "sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==", + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.6.tgz", + "integrity": "sha512-jhHiWVZIlnPbEUKSSNb9YoWcQGdlTLq7z1GHL4AjFxaoOUMuuEVJ+Y4pAaQUGOGk93YsVCKPbqbfw3m0SM6H8Q==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.17.7", - "@babel/helper-define-polyfill-provider": "^0.3.3", - "semver": "^6.1.1" + "@babel/compat-data": "^7.22.6", + "@babel/helper-define-polyfill-provider": "^0.4.3", + "semver": "^6.3.1" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.6.0.tgz", - "integrity": "sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA==", + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.5.tgz", + "integrity": "sha512-Q6CdATeAvbScWPNLB8lzSO7fgUVBkQt6zLgNlfyeCr/EQaEQR+bWiBYYPYAFyE528BMjRhL+1QBMOI4jc/c5TA==", "dev": true, "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.3.3", - "core-js-compat": "^3.25.1" + "@babel/helper-define-polyfill-provider": "^0.4.3", + "core-js-compat": "^3.32.2" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.1.tgz", - "integrity": "sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw==", + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.3.tgz", + "integrity": "sha512-8sHeDOmXC8csczMrYEOf0UTNa4yE2SxV5JGeT/LP1n0OYVDUUFPxG9vdk2AlDlIit4t+Kf0xCtpgXPBwnn/9pw==", "dev": true, "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.3.3" + "@babel/helper-define-polyfill-provider": "^0.4.3" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "node_modules/balanced-match": { @@ -3787,26 +4123,6 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true, - "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/binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", @@ -3816,17 +4132,6 @@ "node": ">=8" } }, - "node_modules/bl": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-5.1.0.tgz", - "integrity": "sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==", - "dev": true, - "dependencies": { - "buffer": "^6.0.3", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -3850,9 +4155,10 @@ } }, "node_modules/browserslist": { - "version": "4.21.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", - "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", + "version": "4.22.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.1.tgz", + "integrity": "sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==", + "dev": true, "funding": [ { "type": "opencollective", @@ -3861,13 +4167,17 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ], "dependencies": { - "caniuse-lite": "^1.0.30001400", - "electron-to-chromium": "^1.4.251", - "node-releases": "^2.0.6", - "update-browserslist-db": "^1.0.9" + "caniuse-lite": "^1.0.30001541", + "electron-to-chromium": "^1.4.535", + "node-releases": "^2.0.13", + "update-browserslist-db": "^1.0.13" }, "bin": { "browserslist": "cli.js" @@ -3876,35 +4186,12 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "node_modules/buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "dev": true, - "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": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true, + "optional": true, "peer": true }, "node_modules/call-bind": { @@ -3941,9 +4228,10 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001431", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001431.tgz", - "integrity": "sha512-zBUoFU0ZcxpvSt9IU66dXVT/3ctO1cy4y9cscs1szkPlcWb6pasYM144GqrUygUbT+k7cmUCW61cvskjcv0enQ==", + "version": "1.0.30001551", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001551.tgz", + "integrity": "sha512-vtBAez47BoGMMzlbYhfXrMV1kvRF2WP/lqiMuDu1Sb4EE4LKEgjopFDSRtZfdVnslNRpOqV/woE+Xgrwj6VQlg==", + "dev": true, "funding": [ { "type": "opencollective", @@ -3952,6 +4240,10 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ] }, @@ -3976,12 +4268,6 @@ "node": ">=0.8.0" } }, - "node_modules/chardet": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", - "dev": true - }, "node_modules/chokidar": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", @@ -4014,15 +4300,6 @@ "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz", "integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==" }, - "node_modules/clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/cli-cursor": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", @@ -4038,18 +4315,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/cli-spinners": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.7.0.tgz", - "integrity": "sha512-qu3pN8Y3qHNgE2AFweciB1IfMnmZ/fsNTEE+NOFjmGB2F/7rLhnhzppvpCnN4FovtP26k8lHyy9ptEbNwWFLzw==", - "dev": true, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/cli-truncate": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-3.1.0.tgz", @@ -4066,24 +4331,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/cli-width": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.0.0.tgz", - "integrity": "sha512-ZksGS2xpa/bYkNzN3BAw1wEjsLV/ZKOf/CCrJ/QOBsxx6fOARIkwTutxp1XIOIohi6HKmOFjMoK/XaqDVUpEEw==", - "dev": true, - "engines": { - "node": ">= 12" - } - }, "node_modules/cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "dev": true, "dependencies": { "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" } }, "node_modules/cliui/node_modules/ansi-styles": { @@ -4125,6 +4384,15 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, + "node_modules/cliui/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/cliui/node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -4140,9 +4408,9 @@ } }, "node_modules/cliui/node_modules/wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "dependencies": { "ansi-styles": "^4.0.0", @@ -4150,16 +4418,10 @@ "strip-ansi": "^6.0.0" }, "engines": { - "node": ">=8" - } - }, - "node_modules/clone": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", - "dev": true, - "engines": { - "node": ">=0.8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, "node_modules/clsx": { @@ -4184,22 +4446,11 @@ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" }, "node_modules/colorette": { - "version": "2.0.19", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz", - "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==", + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", "dev": true }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "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", @@ -4209,6 +4460,14 @@ "node": ">= 6" } }, + "node_modules/compose-function": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/compose-function/-/compose-function-3.0.3.tgz", + "integrity": "sha512-xzhzTJ5eC+gmIzvZq+C3kCJHsp9os6tJkrigDRZclyGtOKINbZtE8n1Tzmeh32jW+BUDPbvZpibwvJHBLGMVwg==", + "dependencies": { + "arity-n": "^1.0.4" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -4226,24 +4485,13 @@ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" }, - "node_modules/core-js": { - "version": "3.26.1", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.26.1.tgz", - "integrity": "sha512-21491RRQVzUn0GGM9Z1Jrpr6PNPxPi+Za8OM9q4tksTSnlbXXGKK1nXNg/QvwFYettXvSX6zWKCtHHfjN4puyA==", - "dev": true, - "hasInstallScript": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, "node_modules/core-js-compat": { - "version": "3.26.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.26.1.tgz", - "integrity": "sha512-622/KzTudvXCDLRw70iHW4KKs1aGpcRcowGWyYJr2DEBfRrd6hNJybxSWJFuZYD4ma86xhrwDDHxmDaIq4EA8A==", + "version": "3.33.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.33.1.tgz", + "integrity": "sha512-6pYKNOgD/j/bkC5xS5IIg6bncid3rfrI42oBH1SQJbsmYPKF7rhzcFzYCcxYMmNQQ0rCEB8WqpW7QHndOggaeQ==", "dev": true, "dependencies": { - "browserslist": "^4.21.4" + "browserslist": "^4.22.1" }, "funding": { "type": "opencollective", @@ -4278,11 +4526,11 @@ } }, "node_modules/cross-fetch": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz", - "integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==", + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.6.tgz", + "integrity": "sha512-riRvo06crlE8HiqOwIpQhxwdOk4fOeR7FVM/wXoxchFEqMNUjvbs3bfo4OTgMEMHzppd4DxFBDbyySj8Cv781g==", "dependencies": { - "node-fetch": "2.6.7" + "node-fetch": "^2.6.11" } }, "node_modules/cross-spawn": { @@ -4299,151 +4547,6 @@ "node": ">= 8" } }, - "node_modules/css-modules-loader-core": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/css-modules-loader-core/-/css-modules-loader-core-1.1.0.tgz", - "integrity": "sha512-XWOBwgy5nwBn76aA+6ybUGL/3JBnCtBX9Ay9/OWIpzKYWlVHMazvJ+WtHumfi+xxdPF440cWK7JCYtt8xDifew==", - "dev": true, - "dependencies": { - "icss-replace-symbols": "1.1.0", - "postcss": "6.0.1", - "postcss-modules-extract-imports": "1.1.0", - "postcss-modules-local-by-default": "1.2.0", - "postcss-modules-scope": "1.1.0", - "postcss-modules-values": "1.3.0" - } - }, - "node_modules/css-modules-loader-core/node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/css-modules-loader-core/node_modules/ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/css-modules-loader-core/node_modules/chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", - "dev": true, - "dependencies": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/css-modules-loader-core/node_modules/chalk/node_modules/supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/css-modules-loader-core/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/css-modules-loader-core/node_modules/has-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha512-DyYHfIYwAJmjAjSSPKANxI8bFY9YtFrgkAfinBojQ8YJTOuOuav64tMUJv584SES4xl74PmuaevIyaLESHdTAA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/css-modules-loader-core/node_modules/postcss": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.1.tgz", - "integrity": "sha512-VbGX1LQgQbf9l3cZ3qbUuC3hGqIEOGQFHAEHQ/Diaeo0yLgpgK5Rb8J+OcamIfQ9PbAU/fzBjVtQX3AhJHUvZw==", - "dev": true, - "dependencies": { - "chalk": "^1.1.3", - "source-map": "^0.5.6", - "supports-color": "^3.2.3" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/css-modules-loader-core/node_modules/strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", - "dev": true, - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/css-modules-loader-core/node_modules/supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha512-Jds2VIYDrlp5ui7t8abHN2bjAu4LV/q4N2KivFPpGH0lrka0BMq/33AmECUXlKPcHigkNaqfXRENFju+rlcy+A==", - "dev": true, - "dependencies": { - "has-flag": "^1.0.0" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/css-selector-tokenizer": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7.3.tgz", - "integrity": "sha512-jWQv3oCEL5kMErj4wRnK/OPoBi0D+P1FR2cDCKYPaMeD2eW3/mttav8HT4hT1CKopiJI/psEULjkClhvJo4Lvg==", - "dev": true, - "dependencies": { - "cssesc": "^3.0.0", - "fastparse": "^1.1.2" - } - }, - "node_modules/css-tree": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", - "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", - "dev": true, - "dependencies": { - "mdn-data": "2.0.14", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/css-tree/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/cssesc": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", @@ -4456,22 +4559,10 @@ "node": ">=4" } }, - "node_modules/csso": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", - "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", - "dev": true, - "dependencies": { - "css-tree": "^1.1.2" - }, - "engines": { - "node": ">=8.0.0" - } - }, "node_modules/csstype": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz", - "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==" + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", + "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==" }, "node_modules/damerau-levenshtein": { "version": "1.0.8", @@ -4481,14 +4572,15 @@ "peer": true }, "node_modules/dayjs": { - "version": "1.11.7", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.7.tgz", - "integrity": "sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ==" + "version": "1.11.10", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz", + "integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==" }, "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" }, @@ -4501,46 +4593,16 @@ } } }, - "node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "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-keys": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/deep-keys/-/deep-keys-0.5.0.tgz", - "integrity": "sha512-/80a4+9lbLj1hRxG0ULtEOGtbM4hN/5u1Vu6kc6ZkYePUq+ZhtboRIsWTVKplc2ET1xY2FMVwhyt46w9vPf9Rg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/defaults": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", - "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", - "dev": true, - "dependencies": { - "clone": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/define-properties": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", - "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", + "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", @@ -4553,20 +4615,6 @@ "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": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.4.tgz", - "integrity": "sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==", - "dev": true - }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -4607,9 +4655,9 @@ "dev": true }, "node_modules/effector": { - "version": "22.4.0", - "resolved": "https://registry.npmjs.org/effector/-/effector-22.4.0.tgz", - "integrity": "sha512-WQ0rboUp1fvkzo2rPymtWzR9isUl8v9McGvBA4g8zvQaTgZnXQ1iCbNj2S54bADGpSNl1CYv1/61vvdbc5Goyw==", + "version": "22.8.7", + "resolved": "https://registry.npmjs.org/effector/-/effector-22.8.7.tgz", + "integrity": "sha512-vCevjxmFwnZJuRGtqjwfi+sHtu+7gK3qdbv4fxi/AsMdDtoMeoz9C3/28pjNABviZeEARj6ZfAHbNAq5i9d7RQ==", "funding": [ { "type": "patreon", @@ -4624,38 +4672,43 @@ "node": ">=11.0.0" } }, - "node_modules/effector-inspector": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/effector-inspector/-/effector-inspector-0.8.2.tgz", - "integrity": "sha512-7pYH+S8APeiD6KYtHbVCE0YK0XXM0ug9z+izzbHulaiqIEahFbtWxl+cte3VOj7H54+hr+188qaTdQMW4aE8RA==", - "dev": true, - "dependencies": { - "foliage": "^0.201.0", - "forest": "^0.20.2" - }, + "node_modules/effector-forms": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/effector-forms/-/effector-forms-1.3.4.tgz", + "integrity": "sha512-m/Swvhf6eDyEgYINULCXLZf9uhMMicYQs4Te3bg5Hx2WdUeq5Cts18QwHU+YxoTTJh06rptWbHk0QHHmI4uPuA==", "peerDependencies": { - "effector": "^22.1.0" + "effector": ">=22.0.0 <23.0.0", + "effector-react": ">=22.2.0 <23.0.0" } }, - "node_modules/effector-logger": { - "version": "0.13.4", - "resolved": "https://registry.npmjs.org/effector-logger/-/effector-logger-0.13.4.tgz", - "integrity": "sha512-qswlayMgY+kH5FO/ttTWZgHEsMUhD67KHoh5ORlSRWxVR3CutdE0qQnfPcsBNrUTbzahEjPmLsdEICz3lhW2uw==", - "dev": true, + "node_modules/effector-localstorage": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/effector-localstorage/-/effector-localstorage-1.0.0.tgz", + "integrity": "sha512-SyJiKCHv05GPcWAC/lupQJWvp2EwY2QRfMuiy/JmuXxw++WUi5ozvxKrPT9ntRndn3AgD3S+LOPPwl7GWi/rzw==", + "peerDependencies": { + "effector": ">=22.0.0" + } + }, + "node_modules/effector-mui-snacks": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/effector-mui-snacks/-/effector-mui-snacks-1.0.0.tgz", + "integrity": "sha512-AY1ZlkV5/3yVoErF/8QDX95KjotygFWHh7GgxM5p5/cD/LsV/p7HYGy2rvTxqLrlKVxNtUGEvnzux3jwHYaNzg==", "dependencies": { - "detect-node": "2.0.4", - "effector-inspector": "^0.8.2", - "just-debounce-it": "^1.1.0", - "set-value": "4.0.1" + "classnames": "^2.3.2", + "patronum": "^1.18.0" }, "peerDependencies": { - "effector": "^22.1.0" + "@mui/material": "^5.13.6", + "effector": "^22.8.6", + "effector-react": "^22.5.3", + "react": "^18.2.0", + "react-dom": "^18.2.0" } }, "node_modules/effector-react": { - "version": "22.3.4", - "resolved": "https://registry.npmjs.org/effector-react/-/effector-react-22.3.4.tgz", - "integrity": "sha512-iyPMjnIW7pUoSuvxumAu4oRan4d8sbXmYPTlRXR75HOag2aH805m+xElyhyXCsQMXxQebjk7/GSC8Caeriv/+A==", + "version": "22.5.4", + "resolved": "https://registry.npmjs.org/effector-react/-/effector-react-22.5.4.tgz", + "integrity": "sha512-7HmtfD/vqmqvGnu6jMojmns9cxIW45JPBkGgHrwvbXGpbm0bz2fmVj6PIttv+Bamfmrf9FAy2bZhs+Rwj+3Mxw==", "funding": [ { "type": "patreon", @@ -4678,9 +4731,10 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.284", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz", - "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==" + "version": "1.4.562", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.562.tgz", + "integrity": "sha512-kMGVZLP65O2/oH7zzaoIA5hcr4/xPYO6Sa83FrIpWcd7YPPtSlxqwxTd8lJIwKxaiXM6FGsYK4ukyJ40XkW7jg==", + "dev": true }, "node_modules/emoji-regex": { "version": "9.2.2", @@ -4688,26 +4742,6 @@ "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", "dev": true }, - "node_modules/engine.io-client": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.2.3.tgz", - "integrity": "sha512-aXPtgF1JS3RuuKcpSrBtimSjYvrbhKW9froICH4s0F3XQWLxsKNxqzG39nnvQZQnva4CMvUK63T7shevxRyYHw==", - "dependencies": { - "@socket.io/component-emitter": "~3.1.0", - "debug": "~4.3.1", - "engine.io-parser": "~5.0.3", - "ws": "~8.2.3", - "xmlhttprequest-ssl": "~2.0.0" - } - }, - "node_modules/engine.io-parser": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.4.tgz", - "integrity": "sha512-+nVFp+5z1E3HcToEnO7ZIj3g+3k9389DvWtvJZz0T6/eOCPIyyxehFcedoYrZQrp0LgQbD9pPXhpMBKMd5QURg==", - "engines": { - "node": ">=10.0.0" - } - }, "node_modules/error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -4717,35 +4751,50 @@ } }, "node_modules/es-abstract": { - "version": "1.20.4", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.4.tgz", - "integrity": "sha512-0UtvRN79eMe2L+UNEF1BwRe364sj/DXhQ/k5FmivgoSdpM90b8Jc0mDzKMGo7QS0BVbOP/bTwBKNnDc9rNzaPA==", + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.1.tgz", + "integrity": "sha512-ioRRcXMO6OFyRpyzV3kE1IIBd4WG5/kltnzdxSCqoP8CMGs/Li+M1uF5o7lOkZVFjDs+NLesthnF66Pg/0q0Lw==", "dev": true, "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "arraybuffer.prototype.slice": "^1.0.1", + "available-typed-arrays": "^1.0.5", "call-bind": "^1.0.2", + "es-set-tostringtag": "^2.0.1", "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", "function.prototype.name": "^1.1.5", - "get-intrinsic": "^1.1.3", + "get-intrinsic": "^1.2.1", "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.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.2", + "object-inspect": "^1.12.3", "object-keys": "^1.1.1", "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.4.3", + "regexp.prototype.flags": "^1.5.0", + "safe-array-concat": "^1.0.0", "safe-regex-test": "^1.0.0", - "string.prototype.trimend": "^1.0.5", - "string.prototype.trimstart": "^1.0.5", - "unbox-primitive": "^1.0.2" + "string.prototype.trim": "^1.2.7", + "string.prototype.trimend": "^1.0.6", + "string.prototype.trimstart": "^1.0.6", + "typed-array-buffer": "^1.0.0", + "typed-array-byte-length": "^1.0.0", + "typed-array-byte-offset": "^1.0.0", + "typed-array-length": "^1.0.4", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.10" }, "engines": { "node": ">= 0.4" @@ -4754,6 +4803,20 @@ "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", @@ -4781,9 +4844,9 @@ } }, "node_modules/esbuild": { - "version": "0.16.3", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.16.3.tgz", - "integrity": "sha512-71f7EjPWTiSguen8X/kxEpkAS7BFHwtQKisCDDV3Y4GLGWBaoSCyD5uXkaUew6JDzA9FEN1W23mdnSwW9kqCeg==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", + "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", "dev": true, "hasInstallScript": true, "bin": { @@ -4793,34 +4856,35 @@ "node": ">=12" }, "optionalDependencies": { - "@esbuild/android-arm": "0.16.3", - "@esbuild/android-arm64": "0.16.3", - "@esbuild/android-x64": "0.16.3", - "@esbuild/darwin-arm64": "0.16.3", - "@esbuild/darwin-x64": "0.16.3", - "@esbuild/freebsd-arm64": "0.16.3", - "@esbuild/freebsd-x64": "0.16.3", - "@esbuild/linux-arm": "0.16.3", - "@esbuild/linux-arm64": "0.16.3", - "@esbuild/linux-ia32": "0.16.3", - "@esbuild/linux-loong64": "0.16.3", - "@esbuild/linux-mips64el": "0.16.3", - "@esbuild/linux-ppc64": "0.16.3", - "@esbuild/linux-riscv64": "0.16.3", - "@esbuild/linux-s390x": "0.16.3", - "@esbuild/linux-x64": "0.16.3", - "@esbuild/netbsd-x64": "0.16.3", - "@esbuild/openbsd-x64": "0.16.3", - "@esbuild/sunos-x64": "0.16.3", - "@esbuild/win32-arm64": "0.16.3", - "@esbuild/win32-ia32": "0.16.3", - "@esbuild/win32-x64": "0.16.3" + "@esbuild/android-arm": "0.18.20", + "@esbuild/android-arm64": "0.18.20", + "@esbuild/android-x64": "0.18.20", + "@esbuild/darwin-arm64": "0.18.20", + "@esbuild/darwin-x64": "0.18.20", + "@esbuild/freebsd-arm64": "0.18.20", + "@esbuild/freebsd-x64": "0.18.20", + "@esbuild/linux-arm": "0.18.20", + "@esbuild/linux-arm64": "0.18.20", + "@esbuild/linux-ia32": "0.18.20", + "@esbuild/linux-loong64": "0.18.20", + "@esbuild/linux-mips64el": "0.18.20", + "@esbuild/linux-ppc64": "0.18.20", + "@esbuild/linux-riscv64": "0.18.20", + "@esbuild/linux-s390x": "0.18.20", + "@esbuild/linux-x64": "0.18.20", + "@esbuild/netbsd-x64": "0.18.20", + "@esbuild/openbsd-x64": "0.18.20", + "@esbuild/sunos-x64": "0.18.20", + "@esbuild/win32-arm64": "0.18.20", + "@esbuild/win32-ia32": "0.18.20", + "@esbuild/win32-x64": "0.18.20" } }, "node_modules/escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, "engines": { "node": ">=6" } @@ -4837,49 +4901,47 @@ } }, "node_modules/eslint": { - "version": "8.29.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.29.0.tgz", - "integrity": "sha512-isQ4EEiyUjZFbEKvEGJKKGBwXtvXX+zJbkVKCgTuB9t/+jUBcy8avhkEwWJecI15BkRkOYmvIM5ynbhRjEkoeg==", + "version": "8.51.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.51.0.tgz", + "integrity": "sha512-2WuxRZBrlwnXi+/vFSJyjMqrNjtJqiasMzehF0shoLaW7DzS3/9Yvrmq5JiT66+pNjiX4UBnLDiKHcWAr/OInA==", "dev": true, "dependencies": { - "@eslint/eslintrc": "^1.3.3", - "@humanwhocodes/config-array": "^0.11.6", + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.2", + "@eslint/js": "8.51.0", + "@humanwhocodes/config-array": "^0.11.11", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", - "ajv": "^6.10.0", + "ajv": "^6.12.4", "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.1.1", - "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.3.0", - "espree": "^9.4.0", - "esquery": "^1.4.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "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.15.0", - "grapheme-splitter": "^1.0.4", + "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-sdsl": "^4.1.4", "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", - "regexpp": "^3.2.0", + "optionator": "^0.9.3", "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", "text-table": "^0.2.0" }, "bin": { @@ -4933,9 +4995,9 @@ } }, "node_modules/eslint-config-prettier": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz", - "integrity": "sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.0.0.tgz", + "integrity": "sha512-IcJsTkJae2S35pRsRAwoCE+925rJJStOdkKnLVgtE+tEpqU0EVVM7OqrwxqgptKdX29NUwC82I5pXsGFIgSevw==", "dev": true, "bin": { "eslint-config-prettier": "bin/cli.js" @@ -4945,13 +5007,14 @@ } }, "node_modules/eslint-import-resolver-node": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", - "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", "dev": true, "dependencies": { "debug": "^3.2.7", - "resolve": "^1.20.0" + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" } }, "node_modules/eslint-import-resolver-node/node_modules/debug": { @@ -4964,9 +5027,9 @@ } }, "node_modules/eslint-module-utils": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.4.tgz", - "integrity": "sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==", + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz", + "integrity": "sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==", "dev": true, "dependencies": { "debug": "^3.2.7" @@ -4989,16 +5052,105 @@ "ms": "^2.1.1" } }, + "node_modules/eslint-plugin-boundaries": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-boundaries/-/eslint-plugin-boundaries-3.4.0.tgz", + "integrity": "sha512-bKB/XMu+zx14DCVkxe2yzkKgAoJQn+J7p0kmZm53/JzADbOdK5irhXG1THs92iCpgmTKtoQPjrGg3PA2FUwq6A==", + "dev": true, + "dependencies": { + "chalk": "4.1.2", + "eslint-import-resolver-node": "0.3.9", + "eslint-module-utils": "2.8.0", + "is-core-module": "2.13.0", + "micromatch": "4.0.5" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "eslint": ">=6.0.0" + } + }, + "node_modules/eslint-plugin-boundaries/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-plugin-boundaries/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-plugin-boundaries/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-plugin-boundaries/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-plugin-boundaries/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-plugin-boundaries/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/eslint-plugin-effector": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-effector/-/eslint-plugin-effector-0.10.3.tgz", - "integrity": "sha512-ELDEwYSERD4eHRWEthlQilNfIrYZwQ2poeGBfX05YVy1vIc9ZhIDa8jP7v9djnvRSSJ4gFu4qQQOoau7O33kaw==", + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-effector/-/eslint-plugin-effector-0.11.0.tgz", + "integrity": "sha512-iujBwqh8z09lxrnTF3jAj2WHwxdKYWzf2DXn6ambdBjx3wgHgLt2vjpzctXxWR1+PPyoj3GyQYY7tsnc/RTNTw==", "dev": true, "dependencies": { "prettier": "^2.3.2" }, "engines": { - "node": "^14 || ^15 || ^16 || ^17 || ^18" + "node": "^14 || ^15 || ^16 || ^17 || ^18 || ^19 || ^20" }, "peerDependencies": { "effector": "*", @@ -5006,24 +5158,28 @@ } }, "node_modules/eslint-plugin-import": { - "version": "2.26.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz", - "integrity": "sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==", + "version": "2.28.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.28.1.tgz", + "integrity": "sha512-9I9hFlITvOV55alzoKBI+K9q74kv0iKMeY6av5+umsNwayt59fz692daGyjR+oStBQgx6nwR9rXldDev3Clw+A==", "dev": true, "dependencies": { - "array-includes": "^3.1.4", - "array.prototype.flat": "^1.2.5", - "debug": "^2.6.9", + "array-includes": "^3.1.6", + "array.prototype.findlastindex": "^1.2.2", + "array.prototype.flat": "^1.3.1", + "array.prototype.flatmap": "^1.3.1", + "debug": "^3.2.7", "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.6", - "eslint-module-utils": "^2.7.3", + "eslint-import-resolver-node": "^0.3.7", + "eslint-module-utils": "^2.8.0", "has": "^1.0.3", - "is-core-module": "^2.8.1", + "is-core-module": "^2.13.0", "is-glob": "^4.0.3", "minimatch": "^3.1.2", - "object.values": "^1.1.5", - "resolve": "^1.22.0", - "tsconfig-paths": "^3.14.1" + "object.fromentries": "^2.0.6", + "object.groupby": "^1.0.0", + "object.values": "^1.1.6", + "semver": "^6.3.1", + "tsconfig-paths": "^3.14.2" }, "engines": { "node": ">=4" @@ -5033,12 +5189,12 @@ } }, "node_modules/eslint-plugin-import/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "dependencies": { - "ms": "2.0.0" + "ms": "^2.1.1" } }, "node_modules/eslint-plugin-import/node_modules/doctrine": { @@ -5053,12 +5209,6 @@ "node": ">=0.10.0" } }, - "node_modules/eslint-plugin-import/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, "node_modules/eslint-plugin-jsx-a11y": { "version": "6.6.1", "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.6.1.tgz", @@ -5161,9 +5311,9 @@ } }, "node_modules/eslint-plugin-sonarjs": { - "version": "0.17.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-sonarjs/-/eslint-plugin-sonarjs-0.17.0.tgz", - "integrity": "sha512-jtGtxI49UbJJeJj7CVRLI3+LLH+y+hkR3GOOwM7vBbci9DEFIRGCWvEd2BJScrzltZ6D6iubukTAfc9cyG7sdw==", + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-sonarjs/-/eslint-plugin-sonarjs-0.21.0.tgz", + "integrity": "sha512-oezUDfFT5S6j3rQheZ4DLPrbetPmMS7zHIKWGHr0CM3g5JgyZroz1FpIKa4jV83NsGpmgIeagpokWDKIJzRQmw==", "dev": true, "engines": { "node": ">=14" @@ -5173,61 +5323,31 @@ } }, "node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, "dependencies": { "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/eslint-scope/node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^2.0.0" + "estraverse": "^5.2.0" }, "engines": { - "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=5" - } - }, - "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true, - "engines": { - "node": ">=10" + "url": "https://opencollective.com/eslint" } }, "node_modules/eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/eslint/node_modules/ansi-styles": { @@ -5279,19 +5399,6 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "node_modules/eslint/node_modules/eslint-scope": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", - "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, "node_modules/eslint/node_modules/glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", @@ -5305,9 +5412,9 @@ } }, "node_modules/eslint/node_modules/globals": { - "version": "13.18.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.18.0.tgz", - "integrity": "sha512-/mR4KI8Ps2spmoc0Ulu9L7agOF0du1CZNQ3dke8yItYlyKNmGrkONemBbd6V8UTc1Wgcqn21t3WYB7dbRmh6/A==", + "version": "13.19.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.19.0.tgz", + "integrity": "sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -5340,27 +5447,15 @@ "node": ">=8" } }, - "node_modules/eslint/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/espree": { - "version": "9.4.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz", - "integrity": "sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==", + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, "dependencies": { - "acorn": "^8.8.0", + "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.3.0" + "eslint-visitor-keys": "^3.4.1" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -5370,9 +5465,9 @@ } }, "node_modules/esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "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" @@ -5417,70 +5512,35 @@ "node": ">=0.10.0" } }, + "node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "dev": true + }, "node_modules/execa": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-6.1.0.tgz", - "integrity": "sha512-QVWlX2e50heYJcCPG0iWtf8r0xjEYfz/OYLGDYH+IyjWezzPNxz63qNFOu0l4YftGWuizFVZHHs8PrLU5p2IDA==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", "dev": true, "dependencies": { "cross-spawn": "^7.0.3", - "get-stream": "^6.0.1", - "human-signals": "^3.0.1", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", "is-stream": "^3.0.0", "merge-stream": "^2.0.0", "npm-run-path": "^5.1.0", "onetime": "^6.0.0", - "signal-exit": "^3.0.7", + "signal-exit": "^4.1.0", "strip-final-newline": "^3.0.0" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=16.17" }, "funding": { "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/execa/node_modules/mimic-fn": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", - "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/execa/node_modules/onetime": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", - "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", - "dev": true, - "dependencies": { - "mimic-fn": "^4.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/external-editor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", - "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", - "dev": true, - "dependencies": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -5488,9 +5548,9 @@ "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==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", + "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", "dev": true, "dependencies": { "@nodelib/fs.stat": "^2.0.2", @@ -5515,12 +5575,6 @@ "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==", - "dev": true - }, "node_modules/fastq": { "version": "1.13.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", @@ -5530,34 +5584,6 @@ "reusify": "^1.0.4" } }, - "node_modules/figures": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-5.0.0.tgz", - "integrity": "sha512-ej8ksPF4x6e5wvK9yevct0UCXh8TTFlWGVLlgjZuoBH1HwjIfKE/IdL5mq89sFA7zELi1VhKpmtDnrs7zWyeyg==", - "dev": true, - "dependencies": { - "escape-string-regexp": "^5.0.0", - "is-unicode-supported": "^1.2.0" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/figures/node_modules/escape-string-regexp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -5622,93 +5648,35 @@ "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", "dev": true }, - "node_modules/foliage": { - "version": "0.201.0", - "resolved": "https://registry.npmjs.org/foliage/-/foliage-0.201.0.tgz", - "integrity": "sha512-RkgGPf0If28rHVfgbjFUHINpMyba0RfiDdtSl0AYED4QGe3il2Y/m/G4+dvI5A9y5EFdBYdfqNZbtoJJiyC4pg==", + "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": { - "autoprefixer": "^10.2.4", - "csso": "^4.2.0", - "postcss": "^8.2.6", - "postcss-nested": "^5.0.3" - }, - "peerDependencies": { - "effector": "^22.1.0", - "forest": "^0.20.2" - } - }, - "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 - } + "is-callable": "^1.1.3" } }, - "node_modules/forest": { - "version": "0.20.3", - "resolved": "https://registry.npmjs.org/forest/-/forest-0.20.3.tgz", - "integrity": "sha512-gyZAzoDhxRwYEcRIF8TJ2dqQaHWCwZU2Bq8FzSifqPvje+eLAISnd7QEvKlmwINftQFbrjgyESIIeCk7Vr7k7Q==", + "node_modules/foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", "dev": true, - "funding": [ - { - "type": "patreon", - "url": "https://www.patreon.com/zero_bias" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/effector" - } - ], - "engines": { - "node": ">=11.0.0" - }, - "peerDependencies": { - "effector": "^22.2.0" - } - }, - "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" + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" }, "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==", - "dev": true, - "engines": { - "node": "*" + "node": ">=14" }, "funding": { - "type": "patreon", - "url": "https://www.patreon.com/infusion" + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.1.1.tgz", + "integrity": "sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==", "dev": true, "dependencies": { "graceful-fs": "^4.2.0", @@ -5716,7 +5684,7 @@ "universalify": "^2.0.0" }, "engines": { - "node": ">=12" + "node": ">=14.14" } }, "node_modules/fs-readdir-recursive": { @@ -5777,53 +5745,11 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/generate-react-cli": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/generate-react-cli/-/generate-react-cli-8.0.1.tgz", - "integrity": "sha512-7M7lk1nPsO5sukPeQvZeXfFeRuy5BNtmjiRBkExhr4LgpsSpxCpzydfWeWxYyWdxXM2cZX+aWwml+exLfs6nRw==", - "dev": true, - "dependencies": { - "chalk": "5.1.2", - "commander": "9.4.1", - "deep-keys": "0.5.0", - "fs-extra": "10.1.0", - "inquirer": "9.1.4", - "lodash": "4.17.21", - "replace": "1.2.2" - }, - "bin": { - "generate-react": "bin/generate-react.js" - }, - "engines": { - "node": ">=10.x", - "npm": ">= 6.x" - } - }, - "node_modules/generate-react-cli/node_modules/chalk": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.1.2.tgz", - "integrity": "sha512-E5CkT4jWURs1Vy5qGJye+XwCkNj7Od3Af7CP6SujMetSMkLs8Do2RWJK5yx1wamHV/op8Rz+9rltjaTQWDnEFQ==", - "dev": true, - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/generate-react-cli/node_modules/commander": { - "version": "9.4.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-9.4.1.tgz", - "integrity": "sha512-5EEkTNyHNGFPD2H+c/dXXfQZYa/scCKasxWcXJaWnNJ99pnQN9Vnmqow+p+PlFPE63Q6mThaZws1T+HxfpgtPw==", - "dev": true, - "engines": { - "node": "^12.20.0 || >=14" - } - }, "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" } @@ -5838,13 +5764,14 @@ } }, "node_modules/get-intrinsic": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", - "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", + "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": { @@ -5852,12 +5779,12 @@ } }, "node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", "dev": true, "engines": { - "node": ">=10" + "node": ">=16" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -5915,10 +5842,26 @@ "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/globby": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", @@ -5948,16 +5891,28 @@ "node": ">=8" } }, + "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/graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "dev": true }, - "node_modules/grapheme-splitter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", - "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "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": { @@ -5971,27 +5926,6 @@ "node": ">= 0.4.0" } }, - "node_modules/has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==", - "dev": true, - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-ansi/node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/has-bigints": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", @@ -6021,6 +5955,18 @@ "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", @@ -6078,18 +6024,18 @@ } }, "node_modules/human-signals": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-3.0.1.tgz", - "integrity": "sha512-rQLskxnM/5OCldHo+wNXbpVgDn5A17CUoKX+7Sokwaknlq7CdSnphy0W39GU8dw59XiCXmFXDg4fRuckQRKewQ==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", "dev": true, "engines": { - "node": ">=12.20.0" + "node": ">=16.17.0" } }, "node_modules/husky": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/husky/-/husky-8.0.2.tgz", - "integrity": "sha512-Tkv80jtvbnkK3mYWxPZePGFpQ/tT3HNSs/sasF9P2YfkMezDl3ON37YN6jUUI4eTg5LcyVynlb6r4eyvOmspvg==", + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/husky/-/husky-8.0.3.tgz", + "integrity": "sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg==", "dev": true, "bin": { "husky": "lib/bin.js" @@ -6102,9 +6048,9 @@ } }, "node_modules/i18next": { - "version": "22.1.5", - "resolved": "https://registry.npmjs.org/i18next/-/i18next-22.1.5.tgz", - "integrity": "sha512-Mjj45PbpZByE+c6ddLEkkj0LUyzJP1cRGeC/+O6mvp1+GAwW7rIx6aOPW9+Zxe+JO3EcJCAkibwbZrgBRF/qRA==", + "version": "23.6.0", + "resolved": "https://registry.npmjs.org/i18next/-/i18next-23.6.0.tgz", + "integrity": "sha512-z0Cxr0MGkt+kli306WS4nNNM++9cgt2b2VCMprY92j+AIab/oclgPxdwtTZVLP1zn5t5uo8M6uLsZmYrcjr3HA==", "funding": [ { "type": "individual", @@ -6120,35 +6066,23 @@ } ], "dependencies": { - "@babel/runtime": "^7.20.6" + "@babel/runtime": "^7.22.5" } }, "node_modules/i18next-browser-languagedetector": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/i18next-browser-languagedetector/-/i18next-browser-languagedetector-7.0.1.tgz", - "integrity": "sha512-Pa5kFwaczXJAeHE56CHG2aWzFBMJNUNghf0Pm4SwSrEMps/PTKqW90EYWlIvhuYStf3Sn1K0vw+gH3+TLdkH1g==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/i18next-browser-languagedetector/-/i18next-browser-languagedetector-7.1.0.tgz", + "integrity": "sha512-cr2k7u1XJJ4HTOjM9GyOMtbOA47RtUoWRAtt52z43r3AoMs2StYKyjS3URPhzHaf+mn10hY9dZWamga5WPQjhA==", "dependencies": { "@babel/runtime": "^7.19.4" } }, "node_modules/i18next-http-backend": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/i18next-http-backend/-/i18next-http-backend-2.0.2.tgz", - "integrity": "sha512-TFiIqitZEc8+jyca31EW5ef5PjUYtUGGfL8c8FJwiiHguq5OQTqoR3mxpKqaCPiikg+cxSgXtNA2gZPCu0aryQ==", - "dependencies": { - "cross-fetch": "3.1.5" - } - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/i18next-http-backend/-/i18next-http-backend-2.2.2.tgz", + "integrity": "sha512-mJu4ZqzDtBiU3O4GV9AbK5ekEqoDMdMnCl3pkdXmb5b8yoIH//u8FsmIe6C5qXb3teZu+j6VMi20tjUgzeABiw==", "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" + "cross-fetch": "3.1.6" } }, "node_modules/icss-replace-symbols": { @@ -6157,30 +6091,22 @@ "integrity": "sha512-chIaY3Vh2mh2Q3RGXttaDIzeiPvaVXJ+C4DAh/w3c37SKZ/U6PGMmuicR2EQQp9bKG8zLMCl7I+PtIoOOPp8Gg==", "dev": true }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "node_modules/icss-utils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", + "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } }, "node_modules/ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", "dev": true, "engines": { "node": ">= 4" @@ -6210,15 +6136,6 @@ "node": ">=0.8.19" } }, - "node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -6235,83 +6152,32 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, - "node_modules/inquirer": { - "version": "9.1.4", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-9.1.4.tgz", - "integrity": "sha512-9hiJxE5gkK/cM2d1mTEnuurGTAoHebbkX0BYl3h7iEg7FYfuNIom+nDfBCSWtvSnoSrWCeBxqqBZu26xdlJlXA==", + "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": { - "ansi-escapes": "^6.0.0", - "chalk": "^5.1.2", - "cli-cursor": "^4.0.0", - "cli-width": "^4.0.0", - "external-editor": "^3.0.3", - "figures": "^5.0.0", - "lodash": "^4.17.21", - "mute-stream": "0.0.8", - "ora": "^6.1.2", - "run-async": "^2.4.0", - "rxjs": "^7.5.7", - "string-width": "^5.1.2", - "strip-ansi": "^7.0.1", - "through": "^2.3.6", - "wrap-ansi": "^8.0.1" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/inquirer/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true, - "engines": { - "node": ">=12" + "get-intrinsic": "^1.2.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/inquirer/node_modules/chalk": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.1.2.tgz", - "integrity": "sha512-E5CkT4jWURs1Vy5qGJye+XwCkNj7Od3Af7CP6SujMetSMkLs8Do2RWJK5yx1wamHV/op8Rz+9rltjaTQWDnEFQ==", - "dev": true, "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "node": ">= 0.4" } }, - "node_modules/inquirer/node_modules/strip-ansi": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz", - "integrity": "sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==", + "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": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.0", + "is-typed-array": "^1.1.10" }, "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/internal-slot": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", - "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", - "dev": true, - "dependencies": { - "get-intrinsic": "^1.1.0", - "has": "^1.0.3", - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">= 0.4" + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-arrayish": { @@ -6372,9 +6238,9 @@ } }, "node_modules/is-core-module": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", - "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz", + "integrity": "sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==", "dependencies": { "has": "^1.0.3" }, @@ -6407,12 +6273,15 @@ } }, "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", + "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", "dev": true, "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/is-glob": { @@ -6427,18 +6296,6 @@ "node": ">=0.10.0" } }, - "node_modules/is-interactive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz", - "integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/is-negative-zero": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", @@ -6484,18 +6341,6 @@ "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==", - "dev": true, - "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", @@ -6572,16 +6417,19 @@ "integrity": "sha512-vIZ7HTXAoRoIwYSsTnxb0sg9L6rth+JOulNcavsbskQkCIWoSM2cjFOWZs4wGziGZER+Xgs/HXiCQZgiL8ppxQ==", "dev": true }, - "node_modules/is-unicode-supported": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", - "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==", + "node_modules/is-typed-array": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", + "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", "dev": true, + "dependencies": { + "which-typed-array": "^1.1.11" + }, "engines": { - "node": ">=12" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-weakref": { @@ -6596,39 +6444,48 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, "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==", + "node_modules/jackspeak": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", + "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", "dev": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, "engines": { - "node": ">=0.10.0" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" } }, "node_modules/joi": { - "version": "17.7.0", - "resolved": "https://registry.npmjs.org/joi/-/joi-17.7.0.tgz", - "integrity": "sha512-1/ugc8djfn93rTE3WRKdCzGGt/EtiYKxITMO4Wiv6q5JL1gl9ePt4kBsl1S499nbosspfctIQTpYIhSmHA3WAg==", + "version": "17.11.0", + "resolved": "https://registry.npmjs.org/joi/-/joi-17.11.0.tgz", + "integrity": "sha512-NgB+lZLNoqISVy1rZocE9PZI36bL/77ie924Ri43yEvi9GUUMPeyVIr8KdFTMUlby1p0PBYMk9spIxEUQYqrJQ==", "dependencies": { "@hapi/hoek": "^9.0.0", "@hapi/topo": "^5.0.0", "@sideway/address": "^4.1.3", - "@sideway/formula": "^3.0.0", + "@sideway/formula": "^3.0.1", "@sideway/pinpoint": "^2.0.0" } }, - "node_modules/js-sdsl": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.5.tgz", - "integrity": "sha512-08bOAKweV2NUC1wqTtf3qZlnpOX/R2DU9ikpjOHs0H+ibQv3zpncVQg6um4uYtRtrwIX8M4Nh3ytK4HGlYAq7Q==", - "dev": true - }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -6650,6 +6507,7 @@ "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" }, @@ -6675,9 +6533,10 @@ "dev": true }, "node_modules/json5": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", - "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", + "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" }, @@ -6711,11 +6570,16 @@ "node": ">=4.0" } }, - "node_modules/just-debounce-it": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/just-debounce-it/-/just-debounce-it-1.5.0.tgz", - "integrity": "sha512-itSWJS5d2DTSCizVJ2Z0Djx/dGmUGfZe7WNfUfVP23+htGcIcPHbEjL4eB8ljojTs/+oYwLexImRRCP0A2WXjA==", - "dev": true + "node_modules/ky": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ky/-/ky-1.1.0.tgz", + "integrity": "sha512-n/rS/Yw+pc/j61kl353yIhxpM/FN0VidhPeiMv6Y/QyyCUpSJtHtHlX655wYolZ/Wc3BKO4Q5syWKfzJ5CT7Bg==", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sindresorhus/ky?sponsor=1" + } }, "node_modules/language-subtag-registry": { "version": "0.3.22", @@ -6748,9 +6612,9 @@ } }, "node_modules/lilconfig": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.6.tgz", - "integrity": "sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", + "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", "dev": true, "engines": { "node": ">=10" @@ -6762,178 +6626,77 @@ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" }, "node_modules/lint-staged": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-13.1.0.tgz", - "integrity": "sha512-pn/sR8IrcF/T0vpWLilih8jmVouMlxqXxKuAojmbiGX5n/gDnz+abdPptlj0vYnbfE0SQNl3CY/HwtM0+yfOVQ==", - "dev": true, - "dependencies": { - "cli-truncate": "^3.1.0", - "colorette": "^2.0.19", - "commander": "^9.4.1", - "debug": "^4.3.4", - "execa": "^6.1.0", - "lilconfig": "2.0.6", - "listr2": "^5.0.5", - "micromatch": "^4.0.5", - "normalize-path": "^3.0.0", - "object-inspect": "^1.12.2", - "pidtree": "^0.6.0", - "string-argv": "^0.3.1", - "yaml": "^2.1.3" + "version": "15.0.2", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-15.0.2.tgz", + "integrity": "sha512-vnEy7pFTHyVuDmCAIFKR5QDO8XLVlPFQQyujQ/STOxe40ICWqJ6knS2wSJ/ffX/Lw0rz83luRDh+ET7toN+rOw==", + "dev": true, + "dependencies": { + "chalk": "5.3.0", + "commander": "11.1.0", + "debug": "4.3.4", + "execa": "8.0.1", + "lilconfig": "2.1.0", + "listr2": "7.0.2", + "micromatch": "4.0.5", + "pidtree": "0.6.0", + "string-argv": "0.3.2", + "yaml": "2.3.3" }, "bin": { "lint-staged": "bin/lint-staged.js" }, "engines": { - "node": "^14.13.1 || >=16.0.0" + "node": ">=18.12.0" }, "funding": { "url": "https://opencollective.com/lint-staged" } }, - "node_modules/lint-staged/node_modules/commander": { - "version": "9.4.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-9.4.1.tgz", - "integrity": "sha512-5EEkTNyHNGFPD2H+c/dXXfQZYa/scCKasxWcXJaWnNJ99pnQN9Vnmqow+p+PlFPE63Q6mThaZws1T+HxfpgtPw==", - "dev": true, - "engines": { - "node": "^12.20.0 || >=14" - } - }, - "node_modules/lint-staged/node_modules/yaml": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.1.3.tgz", - "integrity": "sha512-AacA8nRULjKMX2DvWvOAdBZMOfQlypSFkjcOcu9FalllIDJ1kvlREzcdIZmidQUqqeMv7jorHjq2HlLv/+c2lg==", - "dev": true, - "engines": { - "node": ">= 14" - } - }, - "node_modules/listr2": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-5.0.6.tgz", - "integrity": "sha512-u60KxKBy1BR2uLJNTWNptzWQ1ob/gjMzIJPZffAENzpZqbMZ/5PrXXOomDcevIS/+IB7s1mmCEtSlT2qHWMqag==", - "dev": true, - "dependencies": { - "cli-truncate": "^2.1.0", - "colorette": "^2.0.19", - "log-update": "^4.0.0", - "p-map": "^4.0.0", - "rfdc": "^1.3.0", - "rxjs": "^7.5.7", - "through": "^2.3.8", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": "^14.13.1 || >=16.0.0" - }, - "peerDependencies": { - "enquirer": ">= 2.3.0 < 3" - }, - "peerDependenciesMeta": { - "enquirer": { - "optional": true - } - } - }, - "node_modules/listr2/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/listr2/node_modules/cli-truncate": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", - "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", + "node_modules/lint-staged/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", "dev": true, - "dependencies": { - "slice-ansi": "^3.0.0", - "string-width": "^4.2.0" - }, "engines": { - "node": ">=8" + "node": "^12.17.0 || ^14.13 || >=16.0.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/listr2/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" + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/listr2/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/listr2/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/listr2/node_modules/slice-ansi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", - "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", + "node_modules/lint-staged/node_modules/commander": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", + "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, "engines": { - "node": ">=8" + "node": ">=16" } }, - "node_modules/listr2/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "node_modules/lint-staged/node_modules/yaml": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.3.tgz", + "integrity": "sha512-zw0VAJxgeZ6+++/su5AFoqBbZbrEakwu+X0M5HmcwUiBL7AzcuPKjj5we4xfQLp78LkEMpD0cOnUhmgOVy3KdQ==", "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, "engines": { - "node": ">=8" + "node": ">= 14" } }, - "node_modules/listr2/node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "node_modules/listr2": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-7.0.2.tgz", + "integrity": "sha512-rJysbR9GKIalhTbVL2tYbF2hVyDnrf7pFUZBwjPaMIdadYHmeT+EVi/Bu3qd7ETQPahTotg2WRCatXwRBW554g==", "dev": true, "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" + "cli-truncate": "^3.1.0", + "colorette": "^2.0.20", + "eventemitter3": "^5.0.1", + "log-update": "^5.0.1", + "rfdc": "^1.3.0", + "wrap-ansi": "^8.1.0" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + "node": ">=16.0.0" } }, "node_modules/locate-path": { @@ -6951,12 +6714,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, "node_modules/lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", @@ -6969,186 +6726,50 @@ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, - "node_modules/log-symbols": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-5.1.0.tgz", - "integrity": "sha512-l0x2DvrW294C9uDCoQe1VSU4gf529FkSZ6leBl4TiqZH/e+0R7hSfHQBNut2mNygDgHwvYHfFLn6Oxb3VWj2rA==", + "node_modules/log-update": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-5.0.1.tgz", + "integrity": "sha512-5UtUDQ/6edw4ofyljDNcOVJQ4c7OjDro4h3y8e1GQL5iYElYclVHJ3zeWchylvMaKnDbDilC8irOVyexnA/Slw==", "dev": true, "dependencies": { - "chalk": "^5.0.0", - "is-unicode-supported": "^1.1.0" + "ansi-escapes": "^5.0.0", + "cli-cursor": "^4.0.0", + "slice-ansi": "^5.0.0", + "strip-ansi": "^7.0.1", + "wrap-ansi": "^8.0.1" }, "engines": { - "node": ">=12" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/log-symbols/node_modules/chalk": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.1.2.tgz", - "integrity": "sha512-E5CkT4jWURs1Vy5qGJye+XwCkNj7Od3Af7CP6SujMetSMkLs8Do2RWJK5yx1wamHV/op8Rz+9rltjaTQWDnEFQ==", + "node_modules/log-update/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", "dev": true, "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" + "node": ">=12" }, "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, - "node_modules/log-update": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", - "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", + "node_modules/log-update/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dev": true, "dependencies": { - "ansi-escapes": "^4.3.0", - "cli-cursor": "^3.1.0", - "slice-ansi": "^4.0.0", - "wrap-ansi": "^6.2.0" + "ansi-regex": "^6.0.1" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/log-update/node_modules/ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, - "dependencies": { - "type-fest": "^0.21.3" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/log-update/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/log-update/node_modules/cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "dev": true, - "dependencies": { - "restore-cursor": "^3.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/log-update/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/log-update/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/log-update/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/log-update/node_modules/restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "dev": true, - "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/log-update/node_modules/slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" - } - }, - "node_modules/log-update/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/log-update/node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true, - "engines": { - "node": ">=10" + "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/log-update/node_modules/wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, "node_modules/loose-envify": { @@ -7163,27 +6784,12 @@ } }, "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "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==", + "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": { - "@jridgewell/sourcemap-codec": "^1.4.13" - }, - "engines": { - "node": ">=12" + "yallist": "^3.0.2" } }, "node_modules/make-dir": { @@ -7208,12 +6814,6 @@ "semver": "bin/semver" } }, - "node_modules/mdn-data": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", - "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", - "dev": true - }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -7242,32 +6842,16 @@ "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/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", "dev": true, "engines": { - "node": ">=6" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/minimatch": { @@ -7283,42 +6867,55 @@ } }, "node_modules/minimist": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", - "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/minipass": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, "node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", + "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", "dev": true, "bin": { - "mkdirp": "bin/cmd.js" + "mkdirp": "dist/cjs/src/bin.js" }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "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==" - }, - "node_modules/mute-stream": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", - "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, "node_modules/nanoid": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", - "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", + "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -7332,16 +6929,10 @@ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, - "node_modules/natural-compare-lite": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", - "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", - "dev": true - }, "node_modules/node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", "dependencies": { "whatwg-url": "^5.0.0" }, @@ -7358,9 +6949,10 @@ } }, "node_modules/node-releases": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", - "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==" + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", + "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==", + "dev": true }, "node_modules/normalize-path": { "version": "3.0.0", @@ -7371,15 +6963,6 @@ "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==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/npm-run-path": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz", @@ -7416,9 +6999,9 @@ } }, "node_modules/object-inspect": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", - "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", + "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" @@ -7470,7 +7053,6 @@ "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.6.tgz", "integrity": "sha512-VciD13dswC4j1Xt5394WR4MzmAQmlgN72phd/riNp9vtD7tp4QQWJ0R4wvclXcafgcYK8veHRed2W6XeGBvcfg==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.1.4", @@ -7483,6 +7065,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/object.groupby": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.1.tgz", + "integrity": "sha512-HqaQtqLnp/8Bn4GL16cj+CUYbnpe1bh0TtEaWvybszDG4tgxCJuRpV8VGuvNaI1fAnI4lUJzDG55MXcOH4JZcQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1" + } + }, "node_modules/object.hasown": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.2.tgz", @@ -7524,108 +7118,37 @@ } }, "node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", "dev": true, "dependencies": { - "mimic-fn": "^2.1.0" + "mimic-fn": "^4.0.0" }, "engines": { - "node": ">=6" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", "dev": true, "dependencies": { + "@aashutoshrathi/word-wrap": "^1.2.3", "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" + "type-check": "^0.4.0" }, "engines": { "node": ">= 0.8.0" } }, - "node_modules/ora": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/ora/-/ora-6.1.2.tgz", - "integrity": "sha512-EJQ3NiP5Xo94wJXIzAyOtSb0QEIAUu7m8t6UZ9krbz0vAJqr92JpcK/lEXg91q6B9pEGqrykkd2EQplnifDSBw==", - "dev": true, - "dependencies": { - "bl": "^5.0.0", - "chalk": "^5.0.0", - "cli-cursor": "^4.0.0", - "cli-spinners": "^2.6.1", - "is-interactive": "^2.0.0", - "is-unicode-supported": "^1.1.0", - "log-symbols": "^5.1.0", - "strip-ansi": "^7.0.1", - "wcwidth": "^1.0.1" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ora/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/ora/node_modules/chalk": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.1.2.tgz", - "integrity": "sha512-E5CkT4jWURs1Vy5qGJye+XwCkNj7Od3Af7CP6SujMetSMkLs8Do2RWJK5yx1wamHV/op8Rz+9rltjaTQWDnEFQ==", - "dev": true, - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/ora/node_modules/strip-ansi": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz", - "integrity": "sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==", - "dev": true, - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -7656,39 +7179,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "dev": true, + "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==", "dependencies": { - "aggregate-error": "^3.0.0" + "callsites": "^3.0.0" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "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==", - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" + "node": ">=6" } }, "node_modules/parse-json": { @@ -7740,6 +7239,31 @@ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, + "node_modules/path-scurry": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", + "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", + "dev": true, + "dependencies": { + "lru-cache": "^9.1.1 || ^10.0.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.0.1.tgz", + "integrity": "sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==", + "dev": true, + "engines": { + "node": "14 || >=16.14" + } + }, "node_modules/path-to-regexp": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.1.tgz", @@ -7753,10 +7277,19 @@ "node": ">=8" } }, + "node_modules/patronum": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/patronum/-/patronum-1.20.0.tgz", + "integrity": "sha512-UsUR8nUbSPJ0kEQPNorZ/0+Rwlk+c45O4BfqlLHAdRQvx1C7ZSfC9txfPwJo+fajRtzVLebZm1m+67+Ke9SgdA==", + "peerDependencies": { + "effector": "^22.1.2" + } + }, "node_modules/picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true }, "node_modules/picomatch": { "version": "2.3.1", @@ -7792,9 +7325,9 @@ } }, "node_modules/postcss": { - "version": "8.4.19", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.19.tgz", - "integrity": "sha512-h+pbPsyhlYj6N2ozBmHhHrs9DzGmbaarbLvWipMRO7RLS+v4onj26MPFXA5OBYFxyqYhUJK456SwDcY9H2/zsA==", + "version": "8.4.29", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.29.tgz", + "integrity": "sha512-cbI+jaqIeu/VGqXEarWkRCCffhjgXc0qjBtXpqJhTBohMUjUQnbBr0xqX3vEKudc4iviTewcJo5ajcec5+wdJw==", "dev": true, "funding": [ { @@ -7804,10 +7337,14 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ], "dependencies": { - "nanoid": "^3.3.4", + "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" }, @@ -7816,159 +7353,68 @@ } }, "node_modules/postcss-modules-extract-imports": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.1.0.tgz", - "integrity": "sha512-zF9+UIEvtpeqMGxhpeT9XaIevQSrBBCz9fi7SwfkmjVacsSj8DY5eFVgn+wY8I9vvdDDwK5xC8Myq4UkoLFIkA==", - "dev": true, - "dependencies": { - "postcss": "^6.0.1" - } - }, - "node_modules/postcss-modules-extract-imports/node_modules/postcss": { - "version": "6.0.23", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", - "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", - "dev": true, - "dependencies": { - "chalk": "^2.4.1", - "source-map": "^0.6.1", - "supports-color": "^5.4.0" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/postcss-modules-extract-imports/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", + "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" } }, "node_modules/postcss-modules-local-by-default": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-1.2.0.tgz", - "integrity": "sha512-X4cquUPIaAd86raVrBwO8fwRfkIdbwFu7CTfEOjiZQHVQwlHRSkTgH5NLDmMm5+1hQO8u6dZ+TOOJDbay1hYpA==", - "dev": true, - "dependencies": { - "css-selector-tokenizer": "^0.7.0", - "postcss": "^6.0.1" - } - }, - "node_modules/postcss-modules-local-by-default/node_modules/postcss": { - "version": "6.0.23", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", - "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.3.tgz", + "integrity": "sha512-2/u2zraspoACtrbFRnTijMiQtb4GW4BvatjaG/bCjYQo8kLTdevCUlwuBHx2sCnSyrI3x3qj4ZK1j5LQBgzmwA==", "dev": true, "dependencies": { - "chalk": "^2.4.1", - "source-map": "^0.6.1", - "supports-color": "^5.4.0" + "icss-utils": "^5.0.0", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.1.0" }, "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/postcss-modules-local-by-default/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" } }, "node_modules/postcss-modules-scope": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-1.1.0.tgz", - "integrity": "sha512-LTYwnA4C1He1BKZXIx1CYiHixdSe9LWYVKadq9lK5aCCMkoOkFyZ7aigt+srfjlRplJY3gIol6KUNefdMQJdlw==", - "dev": true, - "dependencies": { - "css-selector-tokenizer": "^0.7.0", - "postcss": "^6.0.1" - } - }, - "node_modules/postcss-modules-scope/node_modules/postcss": { - "version": "6.0.23", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", - "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz", + "integrity": "sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==", "dev": true, "dependencies": { - "chalk": "^2.4.1", - "source-map": "^0.6.1", - "supports-color": "^5.4.0" + "postcss-selector-parser": "^6.0.4" }, "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/postcss-modules-scope/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-modules-values": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-1.3.0.tgz", - "integrity": "sha512-i7IFaR9hlQ6/0UgFuqM6YWaCfA1Ej8WMg8A5DggnH1UGKJvTV/ugqq/KaULixzzOi3T/tF6ClBXcHGCzdd5unA==", - "dev": true, - "dependencies": { - "icss-replace-symbols": "^1.1.0", - "postcss": "^6.0.1" - } - }, - "node_modules/postcss-modules-values/node_modules/postcss": { - "version": "6.0.23", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", - "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", - "dev": true, - "dependencies": { - "chalk": "^2.4.1", - "source-map": "^0.6.1", - "supports-color": "^5.4.0" + "node": "^10 || ^12 || >= 14" }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/postcss-modules-values/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" + "peerDependencies": { + "postcss": "^8.1.0" } }, - "node_modules/postcss-nested": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-5.0.6.tgz", - "integrity": "sha512-rKqm2Fk0KbA8Vt3AdGN0FB9OBOMDVajMG6ZCf/GoHgdxUJ4sBFp0A/uMIRm+MJUdo33YXEtjqIz8u7DAp8B7DA==", + "node_modules/postcss-modules-values": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", + "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", "dev": true, "dependencies": { - "postcss-selector-parser": "^6.0.6" + "icss-utils": "^5.0.0" }, "engines": { - "node": ">=12.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" + "node": "^10 || ^12 || >= 14" }, "peerDependencies": { - "postcss": "^8.2.14" + "postcss": "^8.1.0" } }, "node_modules/postcss-selector-parser": { - "version": "6.0.10", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", - "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz", + "integrity": "sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==", "dev": true, "dependencies": { "cssesc": "^3.0.0", @@ -8023,15 +7469,10 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, - "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.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "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" @@ -8080,31 +7521,16 @@ "react": "^18.2.0" } }, - "node_modules/react-hook-form": { - "version": "7.40.0", - "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.40.0.tgz", - "integrity": "sha512-0rokdxMPJs0k9bvFtY6dbcSydyNhnZNXCR49jgDr/aR03FDHFOK6gfh8ccqB3fl696Mk7lqh04xdm+agqWXKSw==", - "engines": { - "node": ">=12.22.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/react-hook-form" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17 || ^18" - } - }, "node_modules/react-i18next": { - "version": "12.1.1", - "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-12.1.1.tgz", - "integrity": "sha512-mFdieOI0LDy84q3JuZU6Aou1DoWW2fhapcTGeBS8+vWSJuViuoCLQAMYSb0QoHhXS8B0WKUOPpx4cffAP7r/aA==", + "version": "13.3.1", + "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-13.3.1.tgz", + "integrity": "sha512-JAtYREK879JXaN9GdzfBI4yJeo/XyLeXWUsRABvYXiFUakhZJ40l+kaTo+i+A/3cKIED41kS/HAbZ5BzFtq/Og==", "dependencies": { - "@babel/runtime": "^7.14.5", + "@babel/runtime": "^7.22.5", "html-parse-stringify": "^3.0.1" }, "peerDependencies": { - "i18next": ">= 19.0.0", + "i18next": ">= 23.2.3", "react": ">= 16.8.0" }, "peerDependenciesMeta": { @@ -8145,20 +7571,6 @@ "react-dom": ">=16.6.0" } }, - "node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -8192,26 +7604,28 @@ "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==" + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", + "dev": true, + "peer": true }, "node_modules/regenerator-transform": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.0.tgz", - "integrity": "sha512-LsrGtPmbYg19bcPHwdtmXwbW+TqNvtY4riE3P83foeHRroMbH6/2ddFBfab3t7kbzc7v7p4wbkIecHImqt0QNg==", + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", + "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", "dev": true, "dependencies": { "@babel/runtime": "^7.8.4" } }, "node_modules/regexp.prototype.flags": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", - "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", + "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.1.3", - "functions-have-names": "^1.2.2" + "define-properties": "^1.2.0", + "functions-have-names": "^1.2.3" }, "engines": { "node": ">= 0.4" @@ -8220,27 +7634,15 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - } - }, "node_modules/regexpu-core": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.2.2.tgz", - "integrity": "sha512-T0+1Zp2wjF/juXMrMxHxidqGYn8U4R+zleSJhX9tQ1PUsS8a9UtYfbsF9LdiVgNX3kiX8RNaKM42nfSgvFJjmw==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", + "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", "dev": true, "dependencies": { + "@babel/regjsgen": "^0.8.0", "regenerate": "^1.4.2", "regenerate-unicode-properties": "^10.1.0", - "regjsgen": "^0.7.1", "regjsparser": "^0.9.1", "unicode-match-property-ecmascript": "^2.0.0", "unicode-match-property-value-ecmascript": "^2.1.0" @@ -8249,12 +7651,6 @@ "node": ">=4" } }, - "node_modules/regjsgen": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.7.1.tgz", - "integrity": "sha512-RAt+8H2ZEzHeYWxZ3H2z6tF18zyyOnlcdaafLrm21Bguj7uZy6ULibiAFdXEtKQY4Sy7wDTwDiOazasMLc4KPA==", - "dev": true - }, "node_modules/regjsparser": { "version": "0.9.1", "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", @@ -8276,36 +7672,6 @@ "jsesc": "bin/jsesc" } }, - "node_modules/replace": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/replace/-/replace-1.2.2.tgz", - "integrity": "sha512-C4EDifm22XZM2b2JOYe6Mhn+lBsLBAvLbK8drfUQLTfD1KYl/n3VaW/CDju0Ny4w3xTtegBpg8YNSpFJPUDSjA==", - "dev": true, - "dependencies": { - "chalk": "2.4.2", - "minimatch": "3.0.5", - "yargs": "^15.3.1" - }, - "bin": { - "replace": "bin/replace.js", - "search": "bin/search.js" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/replace/node_modules/minimatch": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.5.tgz", - "integrity": "sha512-tUpxzX0VAzJHjLu0xUfFv1gwVp9ba3IOuRAVH2EGuRW8a5emA2FlACLqiT/lDVtS1W+TGNwqz3sWaNyLgDJWuw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -8315,18 +7681,12 @@ "node": ">=0.10.0" } }, - "node_modules/require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, "node_modules/resolve": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", - "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "version": "1.22.4", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.4.tgz", + "integrity": "sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg==", "dependencies": { - "is-core-module": "^2.9.0", + "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, @@ -8361,6 +7721,36 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/restore-cursor/node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/restore-cursor/node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/restore-cursor/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, "node_modules/reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -8393,9 +7783,9 @@ } }, "node_modules/rollup": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.7.0.tgz", - "integrity": "sha512-FIJe0msW9P7L9BTfvaJyvn1U1BVCNTL3w8O+PKIrCyiMLg+rIUGb4MbcgVZ10Lnm1uWXOTOWRNARjfXC1+M12Q==", + "version": "3.29.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.0.tgz", + "integrity": "sha512-nszM8DINnx1vSS+TpbWKMkxem0CDWk3cSit/WWCBVs9/JZ1I/XLwOsiUglYuYReaeWWSsW9kge5zE5NZtf/a4w==", "dev": true, "bin": { "rollup": "dist/bin/rollup" @@ -8408,15 +7798,6 @@ "fsevents": "~2.3.2" } }, - "node_modules/run-async": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", - "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -8441,39 +7822,28 @@ } }, "node_modules/runtypes": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/runtypes/-/runtypes-6.6.0.tgz", - "integrity": "sha512-ddM7sgB3fyboDlBzEYFQ04L674sKjbs4GyW2W32N/5Ae47NRd/GyMASPC2PFw8drPHYGEcZ0mZ26r5RcB8msfQ==" + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/runtypes/-/runtypes-6.7.0.tgz", + "integrity": "sha512-3TLdfFX8YHNFOhwHrSJza6uxVBmBrEjnNQlNXvXCdItS0Pdskfg5vVXUTWIN+Y23QR09jWpSl99UHkA83m4uWA==" }, - "node_modules/rxjs": { - "version": "7.5.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.7.tgz", - "integrity": "sha512-z9MzKh/UcOqB3i20H6rtrlaE/CgjLOvheWK/9ILrbhROGTweAi1BaFsTT9FbwZi5Trr1qNRs+MXkhmR06awzQA==", + "node_modules/safe-array-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.1.tgz", + "integrity": "sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q==", "dev": true, "dependencies": { - "tslib": "^2.1.0" + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, - "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/safe-regex-test": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", @@ -8488,12 +7858,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, "node_modules/scheduler": { "version": "0.23.0", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", @@ -8503,36 +7867,14 @@ } }, "node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, "bin": { "semver": "bin/semver.js" } }, - "node_modules/set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", - "dev": true - }, - "node_modules/set-value": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-4.0.1.tgz", - "integrity": "sha512-ayATicCYPVnlNpFmjq2/VmVwhoCQA9+13j8qWp044fmFE3IFphosPtRM+0CJ5xoIx5Uy52fCcwg3XeH2pHbbPQ==", - "dev": true, - "funding": [ - "https://github.com/sponsors/jonschlinkert", - "https://paypal.me/jonathanschlinkert", - "https://jonschlinkert.dev/sponsor" - ], - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=11.0" - } - }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -8569,15 +7911,21 @@ } }, "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, - "node_modules/slash": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", "dev": true, "engines": { "node": ">=6" @@ -8611,44 +7959,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/slice-ansi/node_modules/is-fullwidth-code-point": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", - "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/socket.io-client": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.5.4.tgz", - "integrity": "sha512-ZpKteoA06RzkD32IbqILZ+Cnst4xewU7ZYK12aS1mzHftFFjpoMz69IuhP/nL25pJfao/amoPI527KnuhFm01g==", - "dependencies": { - "@socket.io/component-emitter": "~3.1.0", - "debug": "~4.3.2", - "engine.io-client": "~6.2.3", - "socket.io-parser": "~4.2.1" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/socket.io-parser": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.1.tgz", - "integrity": "sha512-V4GrkLy+HeF1F/en3SpUaM+7XxYXpuMUWLGde1kSSh5nQMN4hLrbPIkD+otwh6q9R6NOQBN4AMaOZ2zVjui82g==", - "dependencies": { - "@socket.io/component-emitter": "~3.1.0", - "debug": "~4.3.1" - }, - "engines": { - "node": ">=10.0.0" - } - }, "node_modules/source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -8671,6 +7981,7 @@ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", "dev": true, + "optional": true, "peer": true, "dependencies": { "buffer-from": "^1.0.0", @@ -8682,24 +7993,16 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, + "optional": true, "peer": true, "engines": { "node": ">=0.10.0" } }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, "node_modules/string-argv": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz", - "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==", + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", + "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", "dev": true, "engines": { "node": ">=0.6.19" @@ -8722,6 +8025,36 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/string-width-cjs/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/string-width/node_modules/ansi-regex": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", @@ -8735,9 +8068,9 @@ } }, "node_modules/string-width/node_modules/strip-ansi": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz", - "integrity": "sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dev": true, "dependencies": { "ansi-regex": "^6.0.1" @@ -8769,6 +8102,23 @@ "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", @@ -8809,6 +8159,19 @@ "node": ">=8" } }, + "node_modules/strip-ansi-cjs": { + "name": "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-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", @@ -8843,9 +8206,9 @@ } }, "node_modules/stylis": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.1.3.tgz", - "integrity": "sha512-GP6WDNWf+o403jrEp9c5jibKavrtLW+/qYGhFxFrG8maXhwTBI7gLLhiBb0o7uFccWN+EOS9aMO6cGHWAO07OA==" + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==" }, "node_modules/supports-color": { "version": "5.5.0", @@ -8869,17 +8232,12 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/systemjs": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/systemjs/-/systemjs-6.13.0.tgz", - "integrity": "sha512-P3cgh2bpaPvAO2NE3uRp/n6hmk4xPX4DQf+UzTlCAycssKdqhp6hjw+ENWe+aUS7TogKRFtptMosTSFeC6R55g==", - "dev": true - }, "node_modules/terser": { "version": "5.16.0", "resolved": "https://registry.npmjs.org/terser/-/terser-5.16.0.tgz", "integrity": "sha512-KjTV81QKStSfwbNiwlBXfcgMcOloyuRdb62/iLFPGBcVNF4EXjhdYBhYHmbJpiBrVxZhDvltE11j+LBQUxEEJg==", "dev": true, + "optional": true, "peer": true, "dependencies": { "@jridgewell/source-map": "^0.3.2", @@ -8899,6 +8257,7 @@ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true, + "optional": true, "peer": true }, "node_modules/text-table": { @@ -8907,24 +8266,6 @@ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, - "node_modules/through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "dev": true - }, - "node_modules/tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, - "dependencies": { - "os-tmpdir": "~1.0.2" - }, - "engines": { - "node": ">=0.6.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", @@ -8950,22 +8291,34 @@ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" }, + "node_modules/ts-api-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.2.tgz", + "integrity": "sha512-Cbu4nIqnEdd+THNEsBdkolnOXhg0I8XteoHaEKgvsxpsbWda4IsUut2c187HxywQCvveojow0Dgw/amxtSKVkQ==", + "dev": true, + "engines": { + "node": ">=16.13.0" + }, + "peerDependencies": { + "typescript": ">=4.2.0" + } + }, "node_modules/tsconfig-paths": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", - "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==", + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz", + "integrity": "sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==", "dev": true, "dependencies": { "@types/json5": "^0.0.29", - "json5": "^1.0.1", + "json5": "^1.0.2", "minimist": "^1.2.6", "strip-bom": "^3.0.0" } }, "node_modules/tsconfig-paths/node_modules/json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "dev": true, "dependencies": { "minimist": "^1.2.0" @@ -8974,33 +8327,6 @@ "json5": "lib/cli.js" } }, - "node_modules/tslib": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", - "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==", - "dev": true - }, - "node_modules/tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "dev": true, - "dependencies": { - "tslib": "^1.8.1" - }, - "engines": { - "node": ">= 6" - }, - "peerDependencies": { - "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" - } - }, - "node_modules/tsutils/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -9014,38 +8340,107 @@ } }, "node_modules/type-fest": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.2.0.tgz", - "integrity": "sha512-Il3wdLRzWvbAEtocgxGQA9YOoRVeVUGOMBtel5LdEpNeEAol6GJTLw8GbX6Z8EIMfvfhoOXs2bwOijtAZdK5og==", + "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": ">=14.16" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/typed-array-buffer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz", + "integrity": "sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz", + "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "has-proto": "^1.0.1", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz", + "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "has-proto": "^1.0.1", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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/typed-css-modules": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/typed-css-modules/-/typed-css-modules-0.7.2.tgz", - "integrity": "sha512-R3guXrQ8ry/yhlfvNmkVY4J3+FtKaEdwqrvgSvFpVY0ieYQHqhhBW0RwfE4hnG4m29Ef/4IE0tBsk/UKplmJkA==", + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/typed-css-modules/-/typed-css-modules-0.8.0.tgz", + "integrity": "sha512-zX9n45IYv27B/85W/b7o+PLmSiLHKSGI/loE8etbIrkVPqB60S7Le7Bkcxl7KR1/visRJRPC/DDFiwx4370FEg==", "dev": true, "dependencies": { - "@types/css-modules-loader-core": "^1.1.0", "camelcase": "^6.0.0", "chalk": "^4.0.0", "chokidar": "^3.4.0", - "css-modules-loader-core": "^1.1.0", - "glob": "^7.1.2", + "glob": "^10.3.10", + "icss-replace-symbols": "^1.1.0", "is-there": "^4.4.2", - "mkdirp": "^1.0.0", - "yargs": "^15.4.1" + "mkdirp": "^3.0.0", + "postcss": "^8.0.0", + "postcss-modules-extract-imports": "^3.0.0", + "postcss-modules-local-by-default": "^4.0.0", + "postcss-modules-scope": "^3.0.0", + "postcss-modules-values": "^4.0.0", + "yargs": "^17.7.2" }, "bin": { "tcm": "lib/cli.js" }, "engines": { - "node": ">=12.0.0" + "node": ">=18.0.0" } }, "node_modules/typed-css-modules/node_modules/ansi-styles": { @@ -9063,6 +8458,15 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/typed-css-modules/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, "node_modules/typed-css-modules/node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -9097,6 +8501,28 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "node_modules/typed-css-modules/node_modules/glob": { + "version": "10.3.10", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", + "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.5", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/typed-css-modules/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -9106,6 +8532,21 @@ "node": ">=8" } }, + "node_modules/typed-css-modules/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/typed-css-modules/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -9119,16 +8560,16 @@ } }, "node_modules/typescript": { - "version": "4.9.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz", - "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", + "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" }, "engines": { - "node": ">=4.2.0" + "node": ">=14.17" } }, "node_modules/unbox-primitive": { @@ -9146,6 +8587,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/undici-types": { + "version": "5.25.3", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.25.3.tgz", + "integrity": "sha512-Ga1jfYwRn7+cP9v8auvEXN1rX3sWqlayd4HP7OKk4mZWylEmu3KzXDUGrQUN6Ol7qo1gPvB2e5gX6udnyEPgdA==", + "dev": true + }, "node_modules/unicode-canonical-property-names-ecmascript": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", @@ -9196,9 +8643,10 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", - "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", + "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "dev": true, "funding": [ { "type": "opencollective", @@ -9207,6 +8655,10 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ], "dependencies": { @@ -9214,7 +8666,7 @@ "picocolors": "^1.0.0" }, "bin": { - "browserslist-lint": "cli.js" + "update-browserslist-db": "cli.js" }, "peerDependencies": { "browserslist": ">= 4.21.0" @@ -9244,15 +8696,14 @@ "dev": true }, "node_modules/vite": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.0.0.tgz", - "integrity": "sha512-ynad+4kYs8Jcnn8J7SacS9vAbk7eMy0xWg6E7bAhS1s79TK+D7tVFGXVZ55S7RNLRROU1rxoKlvZ/qjaB41DGA==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.0.tgz", + "integrity": "sha512-ulr8rNLA6rkyFAlVWw2q5YJ91v098AFQ2R0PRFwPzREXOUJQPtFUG0t+/ZikhaOCDqFoDhN6/v8Sq0o4araFAw==", "dev": true, "dependencies": { - "esbuild": "^0.16.3", - "postcss": "^8.4.19", - "resolve": "^1.22.1", - "rollup": "^3.7.0" + "esbuild": "^0.18.10", + "postcss": "^8.4.27", + "rollup": "^3.27.1" }, "bin": { "vite": "bin/vite.js" @@ -9260,12 +8711,16 @@ "engines": { "node": "^14.18.0 || >=16.0.0" }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, "optionalDependencies": { "fsevents": "~2.3.2" }, "peerDependencies": { "@types/node": ">= 14", "less": "*", + "lightningcss": "^1.21.0", "sass": "*", "stylus": "*", "sugarss": "*", @@ -9278,6 +8733,9 @@ "less": { "optional": true }, + "lightningcss": { + "optional": true + }, "sass": { "optional": true }, @@ -9292,6 +8750,24 @@ } } }, + "node_modules/vite-plugin-static-copy": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/vite-plugin-static-copy/-/vite-plugin-static-copy-0.17.0.tgz", + "integrity": "sha512-2HpNbHfDt8SDy393AGXh9llHkc8FJMQkI8s3T5WsH3SWLMO+f5cFIyPErl4yGKU9Uh3Vaqsd4lHZYTf042fQ2A==", + "dev": true, + "dependencies": { + "chokidar": "^3.5.3", + "fast-glob": "^3.2.11", + "fs-extra": "^11.1.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "vite": "^3.0.0 || ^4.0.0" + } + }, "node_modules/void-elements": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", @@ -9300,15 +8776,6 @@ "node": ">=0.10.0" } }, - "node_modules/wcwidth": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", - "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", - "dev": true, - "dependencies": { - "defaults": "^1.0.3" - } - }, "node_modules/webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", @@ -9354,25 +8821,29 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==", - "dev": true - }, - "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==", + "node_modules/which-typed-array": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.11.tgz", + "integrity": "sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==", "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.10.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/wrap-ansi": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.0.1.tgz", - "integrity": "sha512-QFF+ufAqhoYHvoHdajT/Po7KoXVBPXS2bgjIam5isfWJPfIOnQZ50JtUiVvCv/sjgacf3yRrt2ZKUZ/V4itN4g==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", "dev": true, "dependencies": { "ansi-styles": "^6.1.0", @@ -9386,13 +8857,93 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/wrap-ansi/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, - "engines": { - "node": ">=12" + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/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/wrap-ansi-cjs/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/wrap-ansi-cjs/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/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/wrap-ansi-cjs/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" }, "funding": { "url": "https://github.com/chalk/ansi-regex?sponsor=1" @@ -9411,9 +8962,9 @@ } }, "node_modules/wrap-ansi/node_modules/strip-ansi": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz", - "integrity": "sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dev": true, "dependencies": { "ansi-regex": "^6.0.1" @@ -9431,44 +8982,19 @@ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dev": true }, - "node_modules/ws": { - "version": "8.2.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz", - "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/xmlhttprequest-ssl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz", - "integrity": "sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A==", + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, "engines": { - "node": ">=0.4.0" + "node": ">=10" } }, - "node_modules/y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true - }, "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true }, "node_modules/yaml": { @@ -9480,47 +9006,30 @@ } }, "node_modules/yargs": { - "version": "15.4.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", - "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dev": true, "dependencies": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.2" + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" }, "engines": { - "node": ">=8" + "node": ">=12" } }, "node_modules/yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "dev": true, - "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - }, "engines": { - "node": ">=6" - } - }, - "node_modules/yargs-parser/node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, - "engines": { - "node": ">=6" + "node": ">=12" } }, "node_modules/yargs/node_modules/emoji-regex": { @@ -9529,54 +9038,11 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, - "node_modules/yargs/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/yargs/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "node_modules/yargs/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, "engines": { "node": ">=8" } @@ -9609,81 +9075,110 @@ } }, "dependencies": { + "@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true + }, "@ampproject/remapping": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", + "dev": true, "requires": { "@jridgewell/gen-mapping": "^0.1.0", "@jridgewell/trace-mapping": "^0.3.9" } }, "@babel/cli": { - "version": "7.19.3", - "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.19.3.tgz", - "integrity": "sha512-643/TybmaCAe101m2tSVHi9UKpETXP9c/Ff4mD2tAwkdP6esKIfaauZFc67vGEM6r9fekbEGid+sZhbEnSe3dg==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.23.0.tgz", + "integrity": "sha512-17E1oSkGk2IwNILM4jtfAvgjt+ohmpfBky8aLerUfYZhiPNg7ca+CRCxZn8QDxwNhV/upsc2VHBCqGFIR+iBfA==", "dev": true, "requires": { - "@jridgewell/trace-mapping": "^0.3.8", + "@jridgewell/trace-mapping": "^0.3.17", "@nicolo-ribaudo/chokidar-2": "2.1.8-no-fsevents.3", "chokidar": "^3.4.0", "commander": "^4.0.1", - "convert-source-map": "^1.1.0", + "convert-source-map": "^2.0.0", "fs-readdir-recursive": "^1.1.0", "glob": "^7.2.0", "make-dir": "^2.1.0", "slash": "^2.0.0" + }, + "dependencies": { + "convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + } } }, "@babel/code-frame": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", - "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", + "version": "7.22.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", + "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", "requires": { - "@babel/highlight": "^7.18.6" + "@babel/highlight": "^7.22.13", + "chalk": "^2.4.2" } }, "@babel/compat-data": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.1.tgz", - "integrity": "sha512-EWZ4mE2diW3QALKvDMiXnbZpRvlj+nayZ112nK93SnhqOtpdsbVD4W+2tEoT3YNBAG9RBR0ISY758ZkOgsn6pQ==" + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.2.tgz", + "integrity": "sha512-0S9TQMmDHlqAZ2ITT95irXKfxN9bncq8ZCoJhun3nHL/lLUxd2NKBJYoNGWH7S0hz6fRQwWlAWn/ILM0C70KZQ==", + "dev": true }, "@babel/core": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.5.tgz", - "integrity": "sha512-UdOWmk4pNWTm/4DlPUl/Pt4Gz4rcEMb7CY0Y3eJl5Yz1vI8ZJGmHWaVE55LoxRjdpx0z259GE9U5STA9atUinQ==", - "requires": { - "@ampproject/remapping": "^2.1.0", - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.20.5", - "@babel/helper-compilation-targets": "^7.20.0", - "@babel/helper-module-transforms": "^7.20.2", - "@babel/helpers": "^7.20.5", - "@babel/parser": "^7.20.5", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.20.5", - "@babel/types": "^7.20.5", - "convert-source-map": "^1.7.0", + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.2.tgz", + "integrity": "sha512-n7s51eWdaWZ3vGT2tD4T7J6eJs3QoBXydv7vkUM06Bf1cbVD2Kc2UrkzhiQwobfV7NwOnQXYL7UBJ5VPU+RGoQ==", + "dev": true, + "requires": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.23.0", + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-module-transforms": "^7.23.0", + "@babel/helpers": "^7.23.2", + "@babel/parser": "^7.23.0", + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.2", + "@babel/types": "^7.23.0", + "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", - "json5": "^2.2.1", - "semver": "^6.3.0" + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "dependencies": { + "convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + } } }, "@babel/generator": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.5.tgz", - "integrity": "sha512-jl7JY2Ykn9S0yj4DQP82sYvPU+T3g0HFcWTqDLqiuA9tGRNIj9VfbtXGAYTTkyNEnQk1jkMGOdYka8aG/lulCA==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz", + "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==", + "dev": true, "requires": { - "@babel/types": "^7.20.5", + "@babel/types": "^7.23.0", "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" }, "dependencies": { "@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "dev": true, "requires": { "@jridgewell/set-array": "^1.0.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -9693,432 +9188,277 @@ } }, "@babel/helper-annotate-as-pure": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz", - "integrity": "sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", + "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", "dev": true, "requires": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.5" } }, "@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.18.9.tgz", - "integrity": "sha512-yFQ0YCHoIqarl8BCRwBL8ulYUaZpz3bNsA7oFepAzee+8/+ImtADXNOmO5vJvsPff3qi+hvpkY/NYBTrBQgdNw==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.15.tgz", + "integrity": "sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw==", "dev": true, "requires": { - "@babel/helper-explode-assignable-expression": "^7.18.6", - "@babel/types": "^7.18.9" + "@babel/types": "^7.22.15" } }, "@babel/helper-compilation-targets": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.0.tgz", - "integrity": "sha512-0jp//vDGp9e8hZzBc6N/KwA5ZK3Wsm/pfm4CrY7vzegkVxc65SgSn6wYOnwHe9Js9HRQ1YTCKLGPzDtaS3RoLQ==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz", + "integrity": "sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==", + "dev": true, "requires": { - "@babel/compat-data": "^7.20.0", - "@babel/helper-validator-option": "^7.18.6", - "browserslist": "^4.21.3", - "semver": "^6.3.0" + "@babel/compat-data": "^7.22.9", + "@babel/helper-validator-option": "^7.22.15", + "browserslist": "^4.21.9", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" } }, "@babel/helper-create-class-features-plugin": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.20.2.tgz", - "integrity": "sha512-k22GoYRAHPYr9I+Gvy2ZQlAe5mGy8BqWst2wRt8cwIufWTxrsVshhIBvYNqC80N0GSFWTsqRVexOtfzlgOEDvA==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.15.tgz", + "integrity": "sha512-jKkwA59IXcvSaiK2UN45kKwSC9o+KuoXsBDvHvU/7BecYIp8GQ2UwrVvFgJASUT+hBnwJx6MhvMCuMzwZZ7jlg==", "dev": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", - "@babel/helper-member-expression-to-functions": "^7.18.9", - "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/helper-replace-supers": "^7.19.1", - "@babel/helper-split-export-declaration": "^7.18.6" + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-function-name": "^7.22.5", + "@babel/helper-member-expression-to-functions": "^7.22.15", + "@babel/helper-optimise-call-expression": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "semver": "^6.3.1" } }, "@babel/helper-create-regexp-features-plugin": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.19.0.tgz", - "integrity": "sha512-htnV+mHX32DF81amCDrwIDr8nrp1PTm+3wfBN9/v8QJOLEioOCOG7qNyq0nHeFiWbT3Eb7gsPwEmV64UCQ1jzw==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.15.tgz", + "integrity": "sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w==", "dev": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "regexpu-core": "^5.1.0" + "@babel/helper-annotate-as-pure": "^7.22.5", + "regexpu-core": "^5.3.1", + "semver": "^6.3.1" } }, "@babel/helper-define-polyfill-provider": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz", - "integrity": "sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==", + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.3.tgz", + "integrity": "sha512-WBrLmuPP47n7PNwsZ57pqam6G/RGo1vw/87b0Blc53tZNGZ4x7YvZ6HgQe2vo1W/FR20OgjeZuGXzudPiXHFug==", "dev": true, "requires": { - "@babel/helper-compilation-targets": "^7.17.7", - "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-plugin-utils": "^7.22.5", "debug": "^4.1.1", "lodash.debounce": "^4.0.8", - "resolve": "^1.14.2", - "semver": "^6.1.2" + "resolve": "^1.14.2" } }, "@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==" - }, - "@babel/helper-explode-assignable-expression": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.18.6.tgz", - "integrity": "sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg==", - "dev": true, - "requires": { - "@babel/types": "^7.18.6" - } + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", + "dev": true }, "@babel/helper-function-name": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", - "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", + "dev": true, "requires": { - "@babel/template": "^7.18.10", - "@babel/types": "^7.19.0" + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" } }, "@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==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", + "dev": true, "requires": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.5" } }, "@babel/helper-member-expression-to-functions": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.18.9.tgz", - "integrity": "sha512-RxifAh2ZoVU67PyKIO4AMi1wTenGfMR/O/ae0CCRqwgBAt5v7xjdtRw7UoSbsreKrQn5t7r89eruK/9JjYHuDg==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.22.15.tgz", + "integrity": "sha512-qLNsZbgrNh0fDQBCPocSL8guki1hcPvltGDv/NxvUoABwFq7GkKSu1nRXeJkVZc+wJvne2E0RKQz+2SQrz6eAA==", "dev": true, "requires": { - "@babel/types": "^7.18.9" + "@babel/types": "^7.22.15" } }, "@babel/helper-module-imports": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", - "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", + "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", "requires": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.15" } }, "@babel/helper-module-transforms": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.2.tgz", - "integrity": "sha512-zvBKyJXRbmK07XhMuujYoJ48B5yvvmM6+wcpv6Ivj4Yg6qO7NOZOSnvZN9CRl1zz1Z4cKf8YejmCMh8clOoOeA==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.0.tgz", + "integrity": "sha512-WhDWw1tdrlT0gMgUJSlX0IQvoO1eN279zrAUbVB+KpV2c3Tylz8+GnKOLllCS6Z/iZQEyVYxhZVUdPTqs2YYPw==", + "dev": true, "requires": { - "@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.18.10", - "@babel/traverse": "^7.20.1", - "@babel/types": "^7.20.2" + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-simple-access": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/helper-validator-identifier": "^7.22.20" } }, "@babel/helper-optimise-call-expression": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz", - "integrity": "sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz", + "integrity": "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==", "dev": true, "requires": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.5" } }, "@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==" + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", + "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", + "dev": true }, "@babel/helper-remap-async-to-generator": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz", - "integrity": "sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.20.tgz", + "integrity": "sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw==", "dev": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-wrap-function": "^7.18.9", - "@babel/types": "^7.18.9" + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-wrap-function": "^7.22.20" } }, "@babel/helper-replace-supers": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.19.1.tgz", - "integrity": "sha512-T7ahH7wV0Hfs46SFh5Jz3s0B6+o8g3c+7TMxu7xKfmHikg7EAZ3I2Qk9LFhjxXq8sL7UkP5JflezNwoZa8WvWw==", + "version": "7.22.9", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.22.9.tgz", + "integrity": "sha512-LJIKvvpgPOPUThdYqcX6IXRuIcTkcAub0IaDRGCZH0p5GPUp7PhRU9QVgFcDDd51BaPkk77ZjqFwh6DZTAEmGg==", "dev": true, "requires": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-member-expression-to-functions": "^7.18.9", - "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/traverse": "^7.19.1", - "@babel/types": "^7.19.0" + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-member-expression-to-functions": "^7.22.5", + "@babel/helper-optimise-call-expression": "^7.22.5" } }, "@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==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", + "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", + "dev": true, "requires": { - "@babel/types": "^7.20.2" + "@babel/types": "^7.22.5" } }, "@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.20.0.tgz", - "integrity": "sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz", + "integrity": "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==", "dev": true, "requires": { - "@babel/types": "^7.20.0" + "@babel/types": "^7.22.5" } }, "@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==", + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "dev": true, "requires": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.5" } }, "@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==" + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", + "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==" }, "@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==" + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==" }, "@babel/helper-validator-option": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", - "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==" - }, - "@babel/helper-wrap-function": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.19.0.tgz", - "integrity": "sha512-txX8aN8CZyYGTwcLhlk87KRqncAzhh5TpQamZUa0/u3an36NtDpUP6bQgBCBcLeBs09R/OwQu3OjK0k/HwfNDg==", - "dev": true, - "requires": { - "@babel/helper-function-name": "^7.19.0", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.19.0", - "@babel/types": "^7.19.0" - } - }, - "@babel/helpers": { - "version": "7.20.6", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.6.tgz", - "integrity": "sha512-Pf/OjgfgFRW5bApskEz5pvidpim7tEDPlFtKcNRXWmfHGn9IEI2W2flqRQXTFb7gIPTyK++N6rVHuwKut4XK6w==", - "requires": { - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.20.5", - "@babel/types": "^7.20.5" - } - }, - "@babel/highlight": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", - "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", - "requires": { - "@babel/helper-validator-identifier": "^7.18.6", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - } - }, - "@babel/parser": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.5.tgz", - "integrity": "sha512-r27t/cy/m9uKLXQNWWebeCUHgnAZq0CpG1OwKRxzJMP1vpSU4bSIK2hq+/cp0bQxetkXx38n09rNu8jVkcK/zA==" - }, - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.18.6.tgz", - "integrity": "sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.18.9.tgz", - "integrity": "sha512-AHrP9jadvH7qlOj6PINbgSuphjQUAK7AOT7DPjBo9EHoLhQTnnK5u45e1Hd4DbSQEO9nqPWtQ89r+XEOWFScKg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9", - "@babel/plugin-proposal-optional-chaining": "^7.18.9" - } - }, - "@babel/plugin-proposal-async-generator-functions": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.20.1.tgz", - "integrity": "sha512-Gh5rchzSwE4kC+o/6T8waD0WHEQIsDmjltY8WnWRXHUdH8axZhuH86Ov9M72YhJfDrZseQwuuWaaIT/TmePp3g==", - "dev": true, - "requires": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/helper-remap-async-to-generator": "^7.18.9", - "@babel/plugin-syntax-async-generators": "^7.8.4" - } - }, - "@babel/plugin-proposal-class-properties": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz", - "integrity": "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==", - "dev": true, - "requires": { - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-proposal-class-static-block": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.18.6.tgz", - "integrity": "sha512-+I3oIiNxrCpup3Gi8n5IGMwj0gOCAjcJUSQEcotNnCCPMEnixawOQ+KeJPlgfjzx+FKQ1QSyZOWe7wmoJp7vhw==", - "dev": true, - "requires": { - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-class-static-block": "^7.14.5" - } - }, - "@babel/plugin-proposal-dynamic-import": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.18.6.tgz", - "integrity": "sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-dynamic-import": "^7.8.3" - } - }, - "@babel/plugin-proposal-export-namespace-from": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.9.tgz", - "integrity": "sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3" - } - }, - "@babel/plugin-proposal-json-strings": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.18.6.tgz", - "integrity": "sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-json-strings": "^7.8.3" - } - }, - "@babel/plugin-proposal-logical-assignment-operators": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.18.9.tgz", - "integrity": "sha512-128YbMpjCrP35IOExw2Fq+x55LMP42DzhOhX2aNNIdI9avSWl2PI0yuBWarr3RYpZBSPtabfadkH2yeRiMD61Q==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" - } - }, - "@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz", - "integrity": "sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" - } - }, - "@babel/plugin-proposal-numeric-separator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz", - "integrity": "sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-numeric-separator": "^7.10.4" - } - }, - "@babel/plugin-proposal-object-rest-spread": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.2.tgz", - "integrity": "sha512-Ks6uej9WFK+fvIMesSqbAto5dD8Dz4VuuFvGJFKgIGSkJuRGcrwGECPA1fDgQK3/DbExBJpEkTeYeB8geIFCSQ==", - "dev": true, - "requires": { - "@babel/compat-data": "^7.20.1", - "@babel/helper-compilation-targets": "^7.20.0", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.20.1" - } + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz", + "integrity": "sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA==", + "dev": true }, - "@babel/plugin-proposal-optional-catch-binding": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz", - "integrity": "sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==", + "@babel/helper-wrap-function": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.22.20.tgz", + "integrity": "sha512-pms/UwkOpnQe/PDAEdV/d7dVCoBbB+R4FvYoHGZz+4VPcg7RtYy2KP7S2lbuWM6FCSgob5wshfGESbC/hzNXZw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + "@babel/helper-function-name": "^7.22.5", + "@babel/template": "^7.22.15", + "@babel/types": "^7.22.19" } }, - "@babel/plugin-proposal-optional-chaining": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.18.9.tgz", - "integrity": "sha512-v5nwt4IqBXihxGsW2QmCWMDS3B3bzGIk/EQVZz2ei7f3NJl8NzAJVvUmpDW5q1CRNY+Beb/k58UAH1Km1N411w==", + "@babel/helpers": { + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.2.tgz", + "integrity": "sha512-lzchcp8SjTSVe/fPmLwtWVBFC7+Tbn8LGHDVfDp9JGxpAY5opSaEFgt8UQvrnECWOTdji2mOWMz1rOhkHscmGQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.2", + "@babel/types": "^7.23.0" } }, - "@babel/plugin-proposal-private-methods": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz", - "integrity": "sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==", - "dev": true, + "@babel/highlight": { + "version": "7.22.13", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.13.tgz", + "integrity": "sha512-C/BaXcnnvBCmHTpz/VGZ8jgtE2aYlW4hxDhseJAWZb7gqGM/qtCK6iZUb0TyKFf7BOUsBH7Q7fkRsDRhg1XklQ==", "requires": { - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-validator-identifier": "^7.22.5", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0" } }, - "@babel/plugin-proposal-private-property-in-object": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.18.6.tgz", - "integrity": "sha512-9Rysx7FOctvT5ouj5JODjAFAkgGoudQuLPamZb0v1TGLpapdNaftzifU8NTWQm0IRjqoYypdrSmyWgkocDQ8Dw==", + "@babel/parser": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz", + "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==", + "dev": true + }, + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.22.15.tgz", + "integrity": "sha512-FB9iYlz7rURmRJyXRKEnalYPPdn87H5no108cyuQQyMwlpJ2SJtpIUBI27kdTin956pz+LPypkPVPUTlxOmrsg==", "dev": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + "@babel/helper-plugin-utils": "^7.22.5" } }, - "@babel/plugin-proposal-unicode-property-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz", - "integrity": "sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.22.15.tgz", + "integrity": "sha512-Hyph9LseGvAeeXzikV88bczhsrLrIZqDPxO+sSmAunMPaGrBGhfMWzCPYTtiW9t+HzSE2wtV8e5cc5P6r1xMDQ==", "dev": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/plugin-transform-optional-chaining": "^7.22.15" } }, + "@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", + "dev": true, + "requires": {} + }, "@babel/plugin-syntax-async-generators": { "version": "7.8.4", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", @@ -10165,12 +9505,30 @@ } }, "@babel/plugin-syntax-import-assertions": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.20.0.tgz", - "integrity": "sha512-IUh1vakzNoWalR8ch/areW7qFopR2AEw03JlG7BbrDqmQ4X3q9uuipQwSGrUn7oGiemKjtSLDhNtQHzMHr1JdQ==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.22.5.tgz", + "integrity": "sha512-rdV97N7KqsRzeNGoWUOK6yUsWarLjE5Su/Snk9IYPU9CwkWHs4t+rTGOvffTR8XGkJMTAdLfO0xVnXm8wugIJg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-syntax-import-attributes": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.22.5.tgz", + "integrity": "sha512-KwvoWDeNKPETmozyFE0P2rOLqh39EoQHNjqizrI5B8Vt0ZNS7M56s7dAiAqbYfiAYOuIzIh96z3iR2ktgu3tEg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.19.0" + "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-syntax-json-strings": { @@ -10183,11 +9541,12 @@ } }, "@babel/plugin-syntax-jsx": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz", - "integrity": "sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.22.5.tgz", + "integrity": "sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==", + "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.22.5" } }, "@babel/plugin-syntax-logical-assignment-operators": { @@ -10263,431 +9622,600 @@ } }, "@babel/plugin-syntax-typescript": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.20.0.tgz", - "integrity": "sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.22.5.tgz", + "integrity": "sha512-1mS2o03i7t1c6VzH6fdQ3OA8tcEIxwG18zIPRp+UY1Ihv6W+XZzBCVxExF9upussPXJ0xE9XRHwMoNs1ep/nRQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.19.0" + "@babel/helper-plugin-utils": "^7.22.5" } }, - "@babel/plugin-transform-arrow-functions": { + "@babel/plugin-syntax-unicode-sets-regex": { "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.18.6.tgz", - "integrity": "sha512-9S9X9RUefzrsHZmKMbDXxweEH+YlE8JJEuat9FdvW9Qh1cw7W64jELCtWNkPBPX5En45uy28KGvA/AySqUh8CQ==", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", "dev": true, "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" } }, + "@babel/plugin-transform-arrow-functions": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.22.5.tgz", + "integrity": "sha512-26lTNXoVRdAnsaDXPpvCNUq+OVWEVC6bx7Vvz9rC53F2bagUWW4u4ii2+h8Fejfh7RYqPxn+libeFBBck9muEw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-async-generator-functions": { + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.23.2.tgz", + "integrity": "sha512-BBYVGxbDVHfoeXbOwcagAkOQAm9NxoTdMGfTqghu1GrvadSaw6iW3Je6IcL5PNOw8VwjxqBECXy50/iCQSY/lQ==", + "dev": true, + "requires": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-remap-async-to-generator": "^7.22.20", + "@babel/plugin-syntax-async-generators": "^7.8.4" + } + }, "@babel/plugin-transform-async-to-generator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.18.6.tgz", - "integrity": "sha512-ARE5wZLKnTgPW7/1ftQmSi1CmkqqHo2DNmtztFhvgtOWSDfq0Cq9/9L+KnZNYSNrydBekhW3rwShduf59RoXag==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.22.5.tgz", + "integrity": "sha512-b1A8D8ZzE/VhNDoV1MSJTnpKkCG5bJo+19R4o4oy03zM7ws8yEMK755j61Dc3EyvdysbqH5BOOTquJ7ZX9C6vQ==", "dev": true, "requires": { - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-remap-async-to-generator": "^7.18.6" + "@babel/helper-module-imports": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-remap-async-to-generator": "^7.22.5" } }, "@babel/plugin-transform-block-scoped-functions": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz", - "integrity": "sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.22.5.tgz", + "integrity": "sha512-tdXZ2UdknEKQWKJP1KMNmuF5Lx3MymtMN/pvA+p/VEkhK8jVcQ1fzSy8KM9qRYhAf2/lV33hoMPKI/xaI9sADA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.22.5" } }, "@babel/plugin-transform-block-scoping": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.20.2.tgz", - "integrity": "sha512-y5V15+04ry69OV2wULmwhEA6jwSWXO1TwAtIwiPXcvHcoOQUqpyMVd2bDsQJMW8AurjulIyUV8kDqtjSwHy1uQ==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.23.0.tgz", + "integrity": "sha512-cOsrbmIOXmf+5YbL99/S49Y3j46k/T16b9ml8bm9lP6N9US5iQ2yBK7gpui1pg0V/WMcXdkfKbTb7HXq9u+v4g==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-class-properties": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.22.5.tgz", + "integrity": "sha512-nDkQ0NfkOhPTq8YCLiWNxp1+f9fCobEjCb0n8WdbNUBc4IB5V7P1QnX9IjpSoquKrXF5SKojHleVNs2vGeHCHQ==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-class-static-block": { + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.22.11.tgz", + "integrity": "sha512-GMM8gGmqI7guS/llMFk1bJDkKfn3v3C4KHK9Yg1ey5qcHcOlKb0QvcMrgzvxo+T03/4szNh5lghY+fEC98Kq9g==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.20.2" + "@babel/helper-create-class-features-plugin": "^7.22.11", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-class-static-block": "^7.14.5" } }, "@babel/plugin-transform-classes": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.20.2.tgz", - "integrity": "sha512-9rbPp0lCVVoagvtEyQKSo5L8oo0nQS/iif+lwlAz29MccX2642vWDlSZK+2T2buxbopotId2ld7zZAzRfz9j1g==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-compilation-targets": "^7.20.0", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", - "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-replace-supers": "^7.19.1", - "@babel/helper-split-export-declaration": "^7.18.6", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.22.15.tgz", + "integrity": "sha512-VbbC3PGjBdE0wAWDdHM9G8Gm977pnYI0XpqMd6LrKISj8/DJXEsWqgRuTYaNE9Bv0JGhTZUzHDlMk18IpOuoqw==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-function-name": "^7.22.5", + "@babel/helper-optimise-call-expression": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.9", + "@babel/helper-split-export-declaration": "^7.22.6", "globals": "^11.1.0" } }, "@babel/plugin-transform-computed-properties": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.18.9.tgz", - "integrity": "sha512-+i0ZU1bCDymKakLxn5srGHrsAPRELC2WIbzwjLhHW9SIE1cPYkLCL0NlnXMZaM1vhfgA2+M7hySk42VBvrkBRw==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.22.5.tgz", + "integrity": "sha512-4GHWBgRf0krxPX+AaPtgBAlTgTeZmqDynokHOX7aqqAB4tHs3U2Y02zH6ETFdLZGcg9UQSD1WCmkVrE9ErHeOg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/template": "^7.22.5" } }, "@babel/plugin-transform-destructuring": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.20.2.tgz", - "integrity": "sha512-mENM+ZHrvEgxLTBXUiQ621rRXZes3KWUv6NdQlrnr1TkWVw+hUjQBZuP2X32qKlrlG2BzgR95gkuCRSkJl8vIw==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.23.0.tgz", + "integrity": "sha512-vaMdgNXFkYrB+8lbgniSYWHsgqK5gjaMNcc84bMIOMRLH0L9AqYq3hwMdvnyqj1OPqea8UtjPEuS/DCenah1wg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.20.2" + "@babel/helper-plugin-utils": "^7.22.5" } }, "@babel/plugin-transform-dotall-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.18.6.tgz", - "integrity": "sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.22.5.tgz", + "integrity": "sha512-5/Yk9QxCQCl+sOIB1WelKnVRxTJDSAIxtJLL2/pqL14ZVlbH0fUQUZa/T5/UnQtBNgghR7mfB8ERBKyKPCi7Vw==", "dev": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" } }, "@babel/plugin-transform-duplicate-keys": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.18.9.tgz", - "integrity": "sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.22.5.tgz", + "integrity": "sha512-dEnYD+9BBgld5VBXHnF/DbYGp3fqGMsyxKbtD1mDyIA7AkTSpKXFhCVuj/oQVOoALfBs77DudA0BE4d5mcpmqw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-dynamic-import": { + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.22.11.tgz", + "integrity": "sha512-g/21plo58sfteWjaO0ZNVb+uEOkJNjAaHhbejrnBmu011l/eNDScmkbjCC3l4FKb10ViaGU4aOkFznSu2zRHgA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" } }, "@babel/plugin-transform-exponentiation-operator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.18.6.tgz", - "integrity": "sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.22.5.tgz", + "integrity": "sha512-vIpJFNM/FjZ4rh1myqIya9jXwrwwgFRHPjT3DkUA9ZLHuzox8jiXkOLvwm1H+PQIP3CqfC++WPKeuDi0Sjdj1g==", "dev": true, "requires": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-export-namespace-from": { + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.22.11.tgz", + "integrity": "sha512-xa7aad7q7OiT8oNZ1mU7NrISjlSkVdMbNxn9IuLZyL9AJEhs1Apba3I+u5riX1dIkdptP5EKDG5XDPByWxtehw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" } }, "@babel/plugin-transform-for-of": { - "version": "7.18.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.18.8.tgz", - "integrity": "sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.22.15.tgz", + "integrity": "sha512-me6VGeHsx30+xh9fbDLLPi0J1HzmeIIyenoOQHuw2D4m2SAU3NrspX5XxJLBpqn5yrLzrlw2Iy3RA//Bx27iOA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.22.5" } }, "@babel/plugin-transform-function-name": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.9.tgz", - "integrity": "sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.22.5.tgz", + "integrity": "sha512-UIzQNMS0p0HHiQm3oelztj+ECwFnj+ZRV4KnguvlsD2of1whUeM6o7wGNj6oLwcDoAXQ8gEqfgC24D+VdIcevg==", + "dev": true, + "requires": { + "@babel/helper-compilation-targets": "^7.22.5", + "@babel/helper-function-name": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-json-strings": { + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.22.11.tgz", + "integrity": "sha512-CxT5tCqpA9/jXFlme9xIBCc5RPtdDq3JpkkhgHQqtDdiTnTI0jtZ0QzXhr5DILeYifDPp2wvY2ad+7+hLMW5Pw==", "dev": true, "requires": { - "@babel/helper-compilation-targets": "^7.18.9", - "@babel/helper-function-name": "^7.18.9", - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-json-strings": "^7.8.3" } }, "@babel/plugin-transform-literals": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.9.tgz", - "integrity": "sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.22.5.tgz", + "integrity": "sha512-fTLj4D79M+mepcw3dgFBTIDYpbcB9Sm0bpm4ppXPaO+U+PKFFyV9MGRvS0gvGw62sd10kT5lRMKXAADb9pWy8g==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-logical-assignment-operators": { + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.22.11.tgz", + "integrity": "sha512-qQwRTP4+6xFCDV5k7gZBF3C31K34ut0tbEcTKxlX/0KXxm9GLcO14p570aWxFvVzx6QAfPgq7gaeIHXJC8LswQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" } }, "@babel/plugin-transform-member-expression-literals": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.18.6.tgz", - "integrity": "sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.22.5.tgz", + "integrity": "sha512-RZEdkNtzzYCFl9SE9ATaUMTj2hqMb4StarOJLrZRbqqU4HSBE7UlBw9WBWQiDzrJZJdUWiMTVDI6Gv/8DPvfew==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.22.5" } }, "@babel/plugin-transform-modules-amd": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.19.6.tgz", - "integrity": "sha512-uG3od2mXvAtIFQIh0xrpLH6r5fpSQN04gIVovl+ODLdUMANokxQLZnPBHcjmv3GxRjnqwLuHvppjjcelqUFZvg==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.23.0.tgz", + "integrity": "sha512-xWT5gefv2HGSm4QHtgc1sYPbseOyf+FFDo2JbpE25GWl5BqTGO9IMwTYJRoIdjsF85GE+VegHxSCUt5EvoYTAw==", "dev": true, "requires": { - "@babel/helper-module-transforms": "^7.19.6", - "@babel/helper-plugin-utils": "^7.19.0" + "@babel/helper-module-transforms": "^7.23.0", + "@babel/helper-plugin-utils": "^7.22.5" } }, "@babel/plugin-transform-modules-commonjs": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.19.6.tgz", - "integrity": "sha512-8PIa1ym4XRTKuSsOUXqDG0YaOlEuTVvHMe5JCfgBMOtHvJKw/4NGovEGN33viISshG/rZNVrACiBmPQLvWN8xQ==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.23.0.tgz", + "integrity": "sha512-32Xzss14/UVc7k9g775yMIvkVK8xwKE0DPdP5JTapr3+Z9w4tzeOuLNY6BXDQR6BdnzIlXnCGAzsk/ICHBLVWQ==", "dev": true, "requires": { - "@babel/helper-module-transforms": "^7.19.6", - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/helper-simple-access": "^7.19.4" + "@babel/helper-module-transforms": "^7.23.0", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-simple-access": "^7.22.5" } }, "@babel/plugin-transform-modules-systemjs": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.19.6.tgz", - "integrity": "sha512-fqGLBepcc3kErfR9R3DnVpURmckXP7gj7bAlrTQyBxrigFqszZCkFkcoxzCp2v32XmwXLvbw+8Yq9/b+QqksjQ==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.23.0.tgz", + "integrity": "sha512-qBej6ctXZD2f+DhlOC9yO47yEYgUh5CZNz/aBoH4j/3NOlRfJXJbY7xDQCqQVf9KbrqGzIWER1f23doHGrIHFg==", "dev": true, "requires": { - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-module-transforms": "^7.19.6", - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/helper-validator-identifier": "^7.19.1" + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-module-transforms": "^7.23.0", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.20" } }, "@babel/plugin-transform-modules-umd": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.18.6.tgz", - "integrity": "sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.22.5.tgz", + "integrity": "sha512-+S6kzefN/E1vkSsKx8kmQuqeQsvCKCd1fraCM7zXm4SFoggI099Tr4G8U81+5gtMdUeMQ4ipdQffbKLX0/7dBQ==", "dev": true, "requires": { - "@babel/helper-module-transforms": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-module-transforms": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" } }, "@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.19.1.tgz", - "integrity": "sha512-oWk9l9WItWBQYS4FgXD4Uyy5kq898lvkXpXQxoJEY1RnvPk4R/Dvu2ebXU9q8lP+rlMwUQTFf2Ok6d78ODa0kw==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.22.5.tgz", + "integrity": "sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==", "dev": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.19.0", - "@babel/helper-plugin-utils": "^7.19.0" + "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" } }, "@babel/plugin-transform-new-target": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.18.6.tgz", - "integrity": "sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.22.5.tgz", + "integrity": "sha512-AsF7K0Fx/cNKVyk3a+DW0JLo+Ua598/NxMRvxDnkpCIGFh43+h/v2xyhRUYf6oD8gE4QtL83C7zZVghMjHd+iw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.22.11.tgz", + "integrity": "sha512-YZWOw4HxXrotb5xsjMJUDlLgcDXSfO9eCmdl1bgW4+/lAGdkjaEvOnQ4p5WKKdUgSzO39dgPl0pTnfxm0OAXcg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + } + }, + "@babel/plugin-transform-numeric-separator": { + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.22.11.tgz", + "integrity": "sha512-3dzU4QGPsILdJbASKhF/V2TVP+gJya1PsueQCxIPCEcerqF21oEcrob4mzjsp2Py/1nLfF5m+xYNMDpmA8vffg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + } + }, + "@babel/plugin-transform-object-rest-spread": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.22.15.tgz", + "integrity": "sha512-fEB+I1+gAmfAyxZcX1+ZUwLeAuuf8VIg67CTznZE0MqVFumWkh8xWtn58I4dxdVf080wn7gzWoF8vndOViJe9Q==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.22.9", + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.22.15" } }, "@babel/plugin-transform-object-super": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz", - "integrity": "sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.22.5.tgz", + "integrity": "sha512-klXqyaT9trSjIUrcsYIfETAzmOEZL3cBYqOYLJxBHfMFFggmXOv+NYSX/Jbs9mzMVESw/WycLFPRx8ba/b2Ipw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.5" + } + }, + "@babel/plugin-transform-optional-catch-binding": { + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.22.11.tgz", + "integrity": "sha512-rli0WxesXUeCJnMYhzAglEjLWVDF6ahb45HuprcmQuLidBJFWjNnOzssk2kuc6e33FlLaiZhG/kUIzUMWdBKaQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + } + }, + "@babel/plugin-transform-optional-chaining": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.23.0.tgz", + "integrity": "sha512-sBBGXbLJjxTzLBF5rFWaikMnOGOk/BmK6vVByIdEggZ7Vn6CvWXZyRkkLFK6WE0IF8jSliyOkUN6SScFgzCM0g==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-replace-supers": "^7.18.6" + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" } }, "@babel/plugin-transform-parameters": { - "version": "7.20.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.20.3.tgz", - "integrity": "sha512-oZg/Fpx0YDrj13KsLyO8I/CX3Zdw7z0O9qOd95SqcoIzuqy/WTGWvePeHAnZCN54SfdyjHcb1S30gc8zlzlHcA==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.22.15.tgz", + "integrity": "sha512-hjk7qKIqhyzhhUvRT683TYQOFa/4cQKwQy7ALvTpODswN40MljzNDa0YldevS6tGbxwaEKVn502JmY0dP7qEtQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-private-methods": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.22.5.tgz", + "integrity": "sha512-PPjh4gyrQnGe97JTalgRGMuU4icsZFnWkzicB/fUtzlKUqvsWBKEpPPfr5a2JiyirZkHxnAqkQMO5Z5B2kK3fA==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-private-property-in-object": { + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.22.11.tgz", + "integrity": "sha512-sSCbqZDBKHetvjSwpyWzhuHkmW5RummxJBVbYLkGkaiTOWGxml7SXt0iWa03bzxFIx7wOj3g/ILRd0RcJKBeSQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.20.2" + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-create-class-features-plugin": "^7.22.11", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" } }, "@babel/plugin-transform-property-literals": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.18.6.tgz", - "integrity": "sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.22.5.tgz", + "integrity": "sha512-TiOArgddK3mK/x1Qwf5hay2pxI6wCZnvQqrFSqbtg1GLl2JcNMitVH/YnqjP+M31pLUeTfzY1HAXFDnUBV30rQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.22.5" } }, "@babel/plugin-transform-react-display-name": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.18.6.tgz", - "integrity": "sha512-TV4sQ+T013n61uMoygyMRm+xf04Bd5oqFpv2jAEQwSZ8NwQA7zeRPg1LMVg2PWi3zWBz+CLKD+v5bcpZ/BS0aA==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.22.5.tgz", + "integrity": "sha512-PVk3WPYudRF5z4GKMEYUrLjPl38fJSKNaEOkFuoprioowGuWN6w2RKznuFNSlJx7pzzXXStPUnNSOEO0jL5EVw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.22.5" } }, "@babel/plugin-transform-react-jsx": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.19.0.tgz", - "integrity": "sha512-UVEvX3tXie3Szm3emi1+G63jyw1w5IcMY0FSKM+CRnKRI5Mr1YbCNgsSTwoTwKphQEG9P+QqmuRFneJPZuHNhg==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.22.15.tgz", + "integrity": "sha512-oKckg2eZFa8771O/5vi7XeTvmM6+O9cxZu+kanTU7tD4sin5nO/G8jGJhq8Hvt2Z0kUoEDRayuZLaUlYl8QuGA==", "dev": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/plugin-syntax-jsx": "^7.18.6", - "@babel/types": "^7.19.0" + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-jsx": "^7.22.5", + "@babel/types": "^7.22.15" } }, "@babel/plugin-transform-react-jsx-development": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.18.6.tgz", - "integrity": "sha512-SA6HEjwYFKF7WDjWcMcMGUimmw/nhNRDWxr+KaLSCrkD/LMDBvWRmHAYgE1HDeF8KUuI8OAu+RT6EOtKxSW2qA==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.22.5.tgz", + "integrity": "sha512-bDhuzwWMuInwCYeDeMzyi7TaBgRQei6DqxhbyniL7/VG4RSS7HtSL2QbY4eESy1KJqlWt8g3xeEBGPuo+XqC8A==", "dev": true, "requires": { - "@babel/plugin-transform-react-jsx": "^7.18.6" + "@babel/plugin-transform-react-jsx": "^7.22.5" } }, "@babel/plugin-transform-react-jsx-self": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.18.6.tgz", - "integrity": "sha512-A0LQGx4+4Jv7u/tWzoJF7alZwnBDQd6cGLh9P+Ttk4dpiL+J5p7NSNv/9tlEFFJDq3kjxOavWmbm6t0Gk+A3Ig==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.22.5.tgz", + "integrity": "sha512-nTh2ogNUtxbiSbxaT4Ds6aXnXEipHweN9YRgOX/oNXdf0cCrGn/+2LozFa3lnPV5D90MkjhgckCPBrsoSc1a7g==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.22.5" } }, "@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==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.22.5.tgz", + "integrity": "sha512-yIiRO6yobeEIaI0RTbIr8iAK9FcBHLtZq0S89ZPjDLQXBA4xvghaKqI0etp/tF3htTM0sazJKKLz9oEiGRtu7w==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.19.0" + "@babel/helper-plugin-utils": "^7.22.5" } }, "@babel/plugin-transform-react-pure-annotations": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.18.6.tgz", - "integrity": "sha512-I8VfEPg9r2TRDdvnHgPepTKvuRomzA8+u+nhY7qSI1fR2hRNebasZEETLyM5mAUr0Ku56OkXJ0I7NHJnO6cJiQ==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.22.5.tgz", + "integrity": "sha512-gP4k85wx09q+brArVinTXhWiyzLl9UpmGva0+mWyKxk6JZequ05x3eUcIUE+FyttPKJFRRVtAvQaJ6YF9h1ZpA==", "dev": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" } }, "@babel/plugin-transform-regenerator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.18.6.tgz", - "integrity": "sha512-poqRI2+qiSdeldcz4wTSTXBRryoq3Gc70ye7m7UD5Ww0nE29IXqMl6r7Nd15WBgRd74vloEMlShtH6CKxVzfmQ==", + "version": "7.22.10", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.22.10.tgz", + "integrity": "sha512-F28b1mDt8KcT5bUyJc/U9nwzw6cV+UmTeRlXYIl2TNqMMJif0Jeey9/RQ3C4NOd2zp0/TRsDns9ttj2L523rsw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.18.6", - "regenerator-transform": "^0.15.0" + "@babel/helper-plugin-utils": "^7.22.5", + "regenerator-transform": "^0.15.2" } }, "@babel/plugin-transform-reserved-words": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.18.6.tgz", - "integrity": "sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.22.5.tgz", + "integrity": "sha512-DTtGKFRQUDm8svigJzZHzb/2xatPc6TzNvAIJ5GqOKDsGFYgAskjRulbR/vGsPKq3OPqtexnz327qYpP57RFyA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.22.5" } }, "@babel/plugin-transform-shorthand-properties": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.18.6.tgz", - "integrity": "sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.22.5.tgz", + "integrity": "sha512-vM4fq9IXHscXVKzDv5itkO1X52SmdFBFcMIBZ2FRn2nqVYqw6dBexUgMvAjHW+KXpPPViD/Yo3GrDEBaRC0QYA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.22.5" } }, "@babel/plugin-transform-spread": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.19.0.tgz", - "integrity": "sha512-RsuMk7j6n+r752EtzyScnWkQyuJdli6LdO5Klv8Yx0OfPVTcQkIUfS8clx5e9yHXzlnhOZF3CbQ8C2uP5j074w==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.22.5.tgz", + "integrity": "sha512-5ZzDQIGyvN4w8+dMmpohL6MBo+l2G7tfC/O2Dg7/hjpgeWvUx8FzfeOKxGog9IimPa4YekaQ9PlDqTLOljkcxg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9" + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" } }, "@babel/plugin-transform-sticky-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.18.6.tgz", - "integrity": "sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.22.5.tgz", + "integrity": "sha512-zf7LuNpHG0iEeiyCNwX4j3gDg1jgt1k3ZdXBKbZSoA3BbGQGvMiSvfbZRR3Dr3aeJe3ooWFZxOOG3IRStYp2Bw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.22.5" } }, "@babel/plugin-transform-template-literals": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.9.tgz", - "integrity": "sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.22.5.tgz", + "integrity": "sha512-5ciOehRNf+EyUeewo8NkbQiUs4d6ZxiHo6BcBcnFlgiJfu16q0bQUw9Jvo0b0gBKFG1SMhDSjeKXSYuJLeFSMA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-plugin-utils": "^7.22.5" } }, "@babel/plugin-transform-typeof-symbol": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.18.9.tgz", - "integrity": "sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.22.5.tgz", + "integrity": "sha512-bYkI5lMzL4kPii4HHEEChkD0rkc+nvnlR6+o/qdqR6zrm0Sv/nodmyLhlq2DO0YKLUNd2VePmPRjJXSBh9OIdA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-plugin-utils": "^7.22.5" } }, "@babel/plugin-transform-typescript": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.20.2.tgz", - "integrity": "sha512-jvS+ngBfrnTUBfOQq8NfGnSbF9BrqlR6hjJ2yVxMkmO5nL/cdifNbI30EfjRlN4g5wYWNnMPyj5Sa6R1pbLeag==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.22.15.tgz", + "integrity": "sha512-1uirS0TnijxvQLnlv5wQBwOX3E1wCFX7ITv+9pBV2wKEk4K+M5tqDaoNXnTH8tjEIYHLO98MwiTWO04Ggz4XuA==", "dev": true, "requires": { - "@babel/helper-create-class-features-plugin": "^7.20.2", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/plugin-syntax-typescript": "^7.20.0" + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-create-class-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-typescript": "^7.22.5" } }, "@babel/plugin-transform-unicode-escapes": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.10.tgz", - "integrity": "sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ==", + "version": "7.22.10", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.22.10.tgz", + "integrity": "sha512-lRfaRKGZCBqDlRU3UIFovdp9c9mEvlylmpod0/OatICsSfuQ9YFthRo1tpTkGsklEefZdqlEFdY4A2dwTb6ohg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-unicode-property-regex": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.22.5.tgz", + "integrity": "sha512-HCCIb+CbJIAE6sXn5CjFQXMwkCClcOfPCzTlilJ8cUatfzwHlWQkbtV0zD338u9dZskwvuOYTuuaMaA8J5EI5A==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" } }, "@babel/plugin-transform-unicode-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.18.6.tgz", - "integrity": "sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.22.5.tgz", + "integrity": "sha512-028laaOKptN5vHJf9/Arr/HiJekMd41hOEZYvNsrsXqJ7YPYuX2bQxh31fkZzGmq3YqHRJzYFFAVYvKfMPKqyg==", "dev": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-unicode-sets-regex": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.22.5.tgz", + "integrity": "sha512-lhMfi4FC15j13eKrh3DnYHjpGj6UKQHtNKTbtc1igvAhRy4+kLhV07OpLcsN0VgDEw/MjAvJO4BdMJsHwMhzCg==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" } }, "@babel/preset-env": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.20.2.tgz", - "integrity": "sha512-1G0efQEWR1EHkKvKHqbG+IN/QdgwfByUpM5V5QroDzGV2t3S/WXNQd693cHiHTlCFMpr9B6FkPFXDA2lQcKoDg==", - "dev": true, - "requires": { - "@babel/compat-data": "^7.20.1", - "@babel/helper-compilation-targets": "^7.20.0", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-validator-option": "^7.18.6", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.18.6", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.18.9", - "@babel/plugin-proposal-async-generator-functions": "^7.20.1", - "@babel/plugin-proposal-class-properties": "^7.18.6", - "@babel/plugin-proposal-class-static-block": "^7.18.6", - "@babel/plugin-proposal-dynamic-import": "^7.18.6", - "@babel/plugin-proposal-export-namespace-from": "^7.18.9", - "@babel/plugin-proposal-json-strings": "^7.18.6", - "@babel/plugin-proposal-logical-assignment-operators": "^7.18.9", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6", - "@babel/plugin-proposal-numeric-separator": "^7.18.6", - "@babel/plugin-proposal-object-rest-spread": "^7.20.2", - "@babel/plugin-proposal-optional-catch-binding": "^7.18.6", - "@babel/plugin-proposal-optional-chaining": "^7.18.9", - "@babel/plugin-proposal-private-methods": "^7.18.6", - "@babel/plugin-proposal-private-property-in-object": "^7.18.6", - "@babel/plugin-proposal-unicode-property-regex": "^7.18.6", + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.23.2.tgz", + "integrity": "sha512-BW3gsuDD+rvHL2VO2SjAUNTBe5YrjsTiDyqamPDWY723na3/yPQ65X5oQkFVJZ0o50/2d+svm1rkPoJeR1KxVQ==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.23.2", + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-option": "^7.22.15", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.22.15", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.22.15", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-class-properties": "^7.12.13", "@babel/plugin-syntax-class-static-block": "^7.14.5", "@babel/plugin-syntax-dynamic-import": "^7.8.3", "@babel/plugin-syntax-export-namespace-from": "^7.8.3", - "@babel/plugin-syntax-import-assertions": "^7.20.0", + "@babel/plugin-syntax-import-assertions": "^7.22.5", + "@babel/plugin-syntax-import-attributes": "^7.22.5", + "@babel/plugin-syntax-import-meta": "^7.10.4", "@babel/plugin-syntax-json-strings": "^7.8.3", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", @@ -10697,91 +10225,121 @@ "@babel/plugin-syntax-optional-chaining": "^7.8.3", "@babel/plugin-syntax-private-property-in-object": "^7.14.5", "@babel/plugin-syntax-top-level-await": "^7.14.5", - "@babel/plugin-transform-arrow-functions": "^7.18.6", - "@babel/plugin-transform-async-to-generator": "^7.18.6", - "@babel/plugin-transform-block-scoped-functions": "^7.18.6", - "@babel/plugin-transform-block-scoping": "^7.20.2", - "@babel/plugin-transform-classes": "^7.20.2", - "@babel/plugin-transform-computed-properties": "^7.18.9", - "@babel/plugin-transform-destructuring": "^7.20.2", - "@babel/plugin-transform-dotall-regex": "^7.18.6", - "@babel/plugin-transform-duplicate-keys": "^7.18.9", - "@babel/plugin-transform-exponentiation-operator": "^7.18.6", - "@babel/plugin-transform-for-of": "^7.18.8", - "@babel/plugin-transform-function-name": "^7.18.9", - "@babel/plugin-transform-literals": "^7.18.9", - "@babel/plugin-transform-member-expression-literals": "^7.18.6", - "@babel/plugin-transform-modules-amd": "^7.19.6", - "@babel/plugin-transform-modules-commonjs": "^7.19.6", - "@babel/plugin-transform-modules-systemjs": "^7.19.6", - "@babel/plugin-transform-modules-umd": "^7.18.6", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.19.1", - "@babel/plugin-transform-new-target": "^7.18.6", - "@babel/plugin-transform-object-super": "^7.18.6", - "@babel/plugin-transform-parameters": "^7.20.1", - "@babel/plugin-transform-property-literals": "^7.18.6", - "@babel/plugin-transform-regenerator": "^7.18.6", - "@babel/plugin-transform-reserved-words": "^7.18.6", - "@babel/plugin-transform-shorthand-properties": "^7.18.6", - "@babel/plugin-transform-spread": "^7.19.0", - "@babel/plugin-transform-sticky-regex": "^7.18.6", - "@babel/plugin-transform-template-literals": "^7.18.9", - "@babel/plugin-transform-typeof-symbol": "^7.18.9", - "@babel/plugin-transform-unicode-escapes": "^7.18.10", - "@babel/plugin-transform-unicode-regex": "^7.18.6", - "@babel/preset-modules": "^0.1.5", - "@babel/types": "^7.20.2", - "babel-plugin-polyfill-corejs2": "^0.3.3", - "babel-plugin-polyfill-corejs3": "^0.6.0", - "babel-plugin-polyfill-regenerator": "^0.4.1", - "core-js-compat": "^3.25.1", - "semver": "^6.3.0" + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.22.5", + "@babel/plugin-transform-async-generator-functions": "^7.23.2", + "@babel/plugin-transform-async-to-generator": "^7.22.5", + "@babel/plugin-transform-block-scoped-functions": "^7.22.5", + "@babel/plugin-transform-block-scoping": "^7.23.0", + "@babel/plugin-transform-class-properties": "^7.22.5", + "@babel/plugin-transform-class-static-block": "^7.22.11", + "@babel/plugin-transform-classes": "^7.22.15", + "@babel/plugin-transform-computed-properties": "^7.22.5", + "@babel/plugin-transform-destructuring": "^7.23.0", + "@babel/plugin-transform-dotall-regex": "^7.22.5", + "@babel/plugin-transform-duplicate-keys": "^7.22.5", + "@babel/plugin-transform-dynamic-import": "^7.22.11", + "@babel/plugin-transform-exponentiation-operator": "^7.22.5", + "@babel/plugin-transform-export-namespace-from": "^7.22.11", + "@babel/plugin-transform-for-of": "^7.22.15", + "@babel/plugin-transform-function-name": "^7.22.5", + "@babel/plugin-transform-json-strings": "^7.22.11", + "@babel/plugin-transform-literals": "^7.22.5", + "@babel/plugin-transform-logical-assignment-operators": "^7.22.11", + "@babel/plugin-transform-member-expression-literals": "^7.22.5", + "@babel/plugin-transform-modules-amd": "^7.23.0", + "@babel/plugin-transform-modules-commonjs": "^7.23.0", + "@babel/plugin-transform-modules-systemjs": "^7.23.0", + "@babel/plugin-transform-modules-umd": "^7.22.5", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.22.5", + "@babel/plugin-transform-new-target": "^7.22.5", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.22.11", + "@babel/plugin-transform-numeric-separator": "^7.22.11", + "@babel/plugin-transform-object-rest-spread": "^7.22.15", + "@babel/plugin-transform-object-super": "^7.22.5", + "@babel/plugin-transform-optional-catch-binding": "^7.22.11", + "@babel/plugin-transform-optional-chaining": "^7.23.0", + "@babel/plugin-transform-parameters": "^7.22.15", + "@babel/plugin-transform-private-methods": "^7.22.5", + "@babel/plugin-transform-private-property-in-object": "^7.22.11", + "@babel/plugin-transform-property-literals": "^7.22.5", + "@babel/plugin-transform-regenerator": "^7.22.10", + "@babel/plugin-transform-reserved-words": "^7.22.5", + "@babel/plugin-transform-shorthand-properties": "^7.22.5", + "@babel/plugin-transform-spread": "^7.22.5", + "@babel/plugin-transform-sticky-regex": "^7.22.5", + "@babel/plugin-transform-template-literals": "^7.22.5", + "@babel/plugin-transform-typeof-symbol": "^7.22.5", + "@babel/plugin-transform-unicode-escapes": "^7.22.10", + "@babel/plugin-transform-unicode-property-regex": "^7.22.5", + "@babel/plugin-transform-unicode-regex": "^7.22.5", + "@babel/plugin-transform-unicode-sets-regex": "^7.22.5", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "@babel/types": "^7.23.0", + "babel-plugin-polyfill-corejs2": "^0.4.6", + "babel-plugin-polyfill-corejs3": "^0.8.5", + "babel-plugin-polyfill-regenerator": "^0.5.3", + "core-js-compat": "^3.31.0", + "semver": "^6.3.1" } }, "@babel/preset-modules": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.5.tgz", - "integrity": "sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==", + "version": "0.1.6-no-external-plugins", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", + "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", - "@babel/plugin-transform-dotall-regex": "^7.4.4", "@babel/types": "^7.4.4", "esutils": "^2.0.2" } }, "@babel/preset-react": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.18.6.tgz", - "integrity": "sha512-zXr6atUmyYdiWRVLOZahakYmOBHtWc2WGCkP8PYTgZi0iJXDY2CN180TdrIW4OGOAdLc7TifzDIvtx6izaRIzg==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.22.15.tgz", + "integrity": "sha512-Csy1IJ2uEh/PecCBXXoZGAZBeCATTuePzCSB7dLYWS0vOEj6CNpjxIhW4duWwZodBNueH7QO14WbGn8YyeuN9w==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-validator-option": "^7.18.6", - "@babel/plugin-transform-react-display-name": "^7.18.6", - "@babel/plugin-transform-react-jsx": "^7.18.6", - "@babel/plugin-transform-react-jsx-development": "^7.18.6", - "@babel/plugin-transform-react-pure-annotations": "^7.18.6" + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-option": "^7.22.15", + "@babel/plugin-transform-react-display-name": "^7.22.5", + "@babel/plugin-transform-react-jsx": "^7.22.15", + "@babel/plugin-transform-react-jsx-development": "^7.22.5", + "@babel/plugin-transform-react-pure-annotations": "^7.22.5" } }, "@babel/preset-typescript": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.18.6.tgz", - "integrity": "sha512-s9ik86kXBAnD760aybBucdpnLsAt0jK1xqJn2juOn9lkOvSHV60os5hxoVJsPzMQxvnUJFAlkont2DvvaYEBtQ==", + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.23.2.tgz", + "integrity": "sha512-u4UJc1XsS1GhIGteM8rnGiIvf9rJpiVgMEeCnwlLA7WJPC+jcXWJAGxYmeqs5hOZD8BbAfnV5ezBOxQbb4OUxA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-validator-option": "^7.18.6", - "@babel/plugin-transform-typescript": "^7.18.6" + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-option": "^7.22.15", + "@babel/plugin-syntax-jsx": "^7.22.5", + "@babel/plugin-transform-modules-commonjs": "^7.23.0", + "@babel/plugin-transform-typescript": "^7.22.15" } }, + "@babel/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==", + "dev": true + }, "@babel/runtime": { - "version": "7.20.6", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.6.tgz", - "integrity": "sha512-Q+8MqP7TiHMWzSfwiJwXCjyf4GYA4Dgw3emg/7xmwsdLJOZUp+nMqcOwOzzYheuM1rhDu8FSj2l0aoMygEuXuA==", + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.2.tgz", + "integrity": "sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg==", "requires": { - "regenerator-runtime": "^0.13.11" + "regenerator-runtime": "^0.14.0" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", + "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==" + } } }, "@babel/runtime-corejs3": { @@ -10795,328 +10353,338 @@ "regenerator-runtime": "^0.13.10" } }, - "@babel/standalone": { - "version": "7.20.6", - "resolved": "https://registry.npmjs.org/@babel/standalone/-/standalone-7.20.6.tgz", - "integrity": "sha512-u5at/CbBLETf7kx2LOY4XdhseD79Y099WZKAOMXeT8qvd9OSR515my2UNBBLY4qIht/Qi9KySeQHQwQwxJN4Sw==", - "dev": true - }, "@babel/template": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", - "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", + "dev": true, "requires": { - "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.18.10", - "@babel/types": "^7.18.10" + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" } }, "@babel/traverse": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.5.tgz", - "integrity": "sha512-WM5ZNN3JITQIq9tFZaw1ojLU3WgWdtkxnhM1AegMS+PvHjkM5IXjmYEGY7yukz5XS4sJyEf2VzWjI8uAavhxBQ==", - "requires": { - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.20.5", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.20.5", - "@babel/types": "^7.20.5", + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz", + "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.23.0", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.23.0", + "@babel/types": "^7.23.0", "debug": "^4.1.0", "globals": "^11.1.0" } }, "@babel/types": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.5.tgz", - "integrity": "sha512-c9fst/h2/dcF7H+MJKZ2T0KjEQ8hY/BNnDk/H3XY8C4Aw/eWQXWn/lWntHF9ooUBnGmEvbfGrTgLWc+um0YDUg==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz", + "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==", "requires": { - "@babel/helper-string-parser": "^7.19.4", - "@babel/helper-validator-identifier": "^7.19.1", + "@babel/helper-string-parser": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.20", "to-fast-properties": "^2.0.0" } }, "@emotion/babel-plugin": { - "version": "11.10.5", - "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.10.5.tgz", - "integrity": "sha512-xE7/hyLHJac7D2Ve9dKroBBZqBT7WuPQmWcq7HSGb84sUuP4mlOWoB8dvVfD9yk5DHkU1m6RW7xSoDtnQHNQeA==", + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz", + "integrity": "sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==", "requires": { "@babel/helper-module-imports": "^7.16.7", - "@babel/plugin-syntax-jsx": "^7.17.12", "@babel/runtime": "^7.18.3", - "@emotion/hash": "^0.9.0", - "@emotion/memoize": "^0.8.0", - "@emotion/serialize": "^1.1.1", + "@emotion/hash": "^0.9.1", + "@emotion/memoize": "^0.8.1", + "@emotion/serialize": "^1.1.2", "babel-plugin-macros": "^3.1.0", "convert-source-map": "^1.5.0", "escape-string-regexp": "^4.0.0", "find-root": "^1.1.0", "source-map": "^0.5.7", - "stylis": "4.1.3" + "stylis": "4.2.0" } }, "@emotion/cache": { - "version": "11.10.5", - "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.10.5.tgz", - "integrity": "sha512-dGYHWyzTdmK+f2+EnIGBpkz1lKc4Zbj2KHd4cX3Wi8/OWr5pKslNjc3yABKH4adRGCvSX4VDC0i04mrrq0aiRA==", + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.11.0.tgz", + "integrity": "sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ==", "requires": { - "@emotion/memoize": "^0.8.0", - "@emotion/sheet": "^1.2.1", - "@emotion/utils": "^1.2.0", - "@emotion/weak-memoize": "^0.3.0", - "stylis": "4.1.3" + "@emotion/memoize": "^0.8.1", + "@emotion/sheet": "^1.2.2", + "@emotion/utils": "^1.2.1", + "@emotion/weak-memoize": "^0.3.1", + "stylis": "4.2.0" } }, "@emotion/hash": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.0.tgz", - "integrity": "sha512-14FtKiHhy2QoPIzdTcvh//8OyBlknNs2nXRwIhG904opCby3l+9Xaf/wuPvICBF0rc1ZCNBd3nKe9cd2mecVkQ==" + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.1.tgz", + "integrity": "sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ==" }, "@emotion/is-prop-valid": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.0.tgz", - "integrity": "sha512-3aDpDprjM0AwaxGE09bOPkNxHpBd+kA6jty3RnaEXdweX1DF1U3VQpPYb0g1IStAuK7SVQ1cy+bNBBKp4W3Fjg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.1.tgz", + "integrity": "sha512-61Mf7Ufx4aDxx1xlDeOm8aFFigGHE4z+0sKCa+IHCeZKiyP9RLD0Mmx7m8b9/Cf37f7NAvQOOJAbQQGVr5uERw==", "requires": { - "@emotion/memoize": "^0.8.0" + "@emotion/memoize": "^0.8.1" } }, "@emotion/memoize": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.0.tgz", - "integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==" + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz", + "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==" }, "@emotion/react": { - "version": "11.10.5", - "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.10.5.tgz", - "integrity": "sha512-TZs6235tCJ/7iF6/rvTaOH4oxQg2gMAcdHemjwLKIjKz4rRuYe1HJ2TQJKnAcRAfOUDdU8XoDadCe1rl72iv8A==", + "version": "11.11.1", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.11.1.tgz", + "integrity": "sha512-5mlW1DquU5HaxjLkfkGN1GA/fvVGdyHURRiX/0FHl2cfIfRxSOfmxEH5YS43edp0OldZrZ+dkBKbngxcNCdZvA==", "requires": { "@babel/runtime": "^7.18.3", - "@emotion/babel-plugin": "^11.10.5", - "@emotion/cache": "^11.10.5", - "@emotion/serialize": "^1.1.1", - "@emotion/use-insertion-effect-with-fallbacks": "^1.0.0", - "@emotion/utils": "^1.2.0", - "@emotion/weak-memoize": "^0.3.0", + "@emotion/babel-plugin": "^11.11.0", + "@emotion/cache": "^11.11.0", + "@emotion/serialize": "^1.1.2", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", + "@emotion/utils": "^1.2.1", + "@emotion/weak-memoize": "^0.3.1", "hoist-non-react-statics": "^3.3.1" } }, "@emotion/serialize": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.1.tgz", - "integrity": "sha512-Zl/0LFggN7+L1liljxXdsVSVlg6E/Z/olVWpfxUTxOAmi8NU7YoeWeLfi1RmnB2TATHoaWwIBRoL+FvAJiTUQA==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.2.tgz", + "integrity": "sha512-zR6a/fkFP4EAcCMQtLOhIgpprZOwNmCldtpaISpvz348+DP4Mz8ZoKaGGCQpbzepNIUWbq4w6hNZkwDyKoS+HA==", "requires": { - "@emotion/hash": "^0.9.0", - "@emotion/memoize": "^0.8.0", - "@emotion/unitless": "^0.8.0", - "@emotion/utils": "^1.2.0", + "@emotion/hash": "^0.9.1", + "@emotion/memoize": "^0.8.1", + "@emotion/unitless": "^0.8.1", + "@emotion/utils": "^1.2.1", "csstype": "^3.0.2" } }, "@emotion/sheet": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.1.tgz", - "integrity": "sha512-zxRBwl93sHMsOj4zs+OslQKg/uhF38MB+OMKoCrVuS0nyTkqnau+BM3WGEoOptg9Oz45T/aIGs1qbVAsEFo3nA==" + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.2.tgz", + "integrity": "sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==" }, "@emotion/styled": { - "version": "11.10.5", - "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.10.5.tgz", - "integrity": "sha512-8EP6dD7dMkdku2foLoruPCNkRevzdcBaY6q0l0OsbyJK+x8D9HWjX27ARiSIKNF634hY9Zdoedh8bJCiva8yZw==", + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.11.0.tgz", + "integrity": "sha512-hM5Nnvu9P3midq5aaXj4I+lnSfNi7Pmd4EWk1fOZ3pxookaQTNew6bp4JaCBYM4HVFZF9g7UjJmsUmC2JlxOng==", "requires": { "@babel/runtime": "^7.18.3", - "@emotion/babel-plugin": "^11.10.5", - "@emotion/is-prop-valid": "^1.2.0", - "@emotion/serialize": "^1.1.1", - "@emotion/use-insertion-effect-with-fallbacks": "^1.0.0", - "@emotion/utils": "^1.2.0" + "@emotion/babel-plugin": "^11.11.0", + "@emotion/is-prop-valid": "^1.2.1", + "@emotion/serialize": "^1.1.2", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", + "@emotion/utils": "^1.2.1" } }, "@emotion/unitless": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.0.tgz", - "integrity": "sha512-VINS5vEYAscRl2ZUDiT3uMPlrFQupiKgHz5AA4bCH1miKBg4qtwkim1qPmJj/4WG6TreYMY111rEFsjupcOKHw==" + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz", + "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==" }, "@emotion/use-insertion-effect-with-fallbacks": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.0.tgz", - "integrity": "sha512-1eEgUGmkaljiBnRMTdksDV1W4kUnmwgp7X9G8B++9GYwl1lUdqSndSriIrTJ0N7LQaoauY9JJ2yhiOYK5+NI4A==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz", + "integrity": "sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==", "requires": {} }, "@emotion/utils": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.0.tgz", - "integrity": "sha512-sn3WH53Kzpw8oQ5mgMmIzzyAaH2ZqFEbozVVBSYp538E06OSE6ytOp7pRAjNQR+Q/orwqdQYJSe2m3hCOeznkw==" + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.1.tgz", + "integrity": "sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg==" }, "@emotion/weak-memoize": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.0.tgz", - "integrity": "sha512-AHPmaAx+RYfZz0eYu6Gviiagpmiyw98ySSlQvCUhVGDRtDFe4DBS0x1bSjdF3gqUDYOczB+yYvBTtEylYSdRhg==" + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz", + "integrity": "sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==" }, "@esbuild/android-arm": { - "version": "0.16.3", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.16.3.tgz", - "integrity": "sha512-mueuEoh+s1eRbSJqq9KNBQwI4QhQV6sRXIfTyLXSHGMpyew61rOK4qY21uKbXl1iBoMb0AdL1deWFCQVlN2qHA==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", + "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", "dev": true, "optional": true }, "@esbuild/android-arm64": { - "version": "0.16.3", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.16.3.tgz", - "integrity": "sha512-RolFVeinkeraDvN/OoRf1F/lP0KUfGNb5jxy/vkIMeRRChkrX/HTYN6TYZosRJs3a1+8wqpxAo5PI5hFmxyPRg==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", + "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", "dev": true, "optional": true }, "@esbuild/android-x64": { - "version": "0.16.3", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.16.3.tgz", - "integrity": "sha512-SFpTUcIT1bIJuCCBMCQWq1bL2gPTjWoLZdjmIhjdcQHaUfV41OQfho6Ici5uvvkMmZRXIUGpM3GxysP/EU7ifQ==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", + "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", "dev": true, "optional": true }, "@esbuild/darwin-arm64": { - "version": "0.16.3", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.16.3.tgz", - "integrity": "sha512-DO8WykMyB+N9mIDfI/Hug70Dk1KipavlGAecxS3jDUwAbTpDXj0Lcwzw9svkhxfpCagDmpaTMgxWK8/C/XcXvw==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", + "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", "dev": true, "optional": true }, "@esbuild/darwin-x64": { - "version": "0.16.3", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.16.3.tgz", - "integrity": "sha512-uEqZQ2omc6BvWqdCiyZ5+XmxuHEi1SPzpVxXCSSV2+Sh7sbXbpeNhHIeFrIpRjAs0lI1FmA1iIOxFozKBhKgRQ==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", + "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", "dev": true, "optional": true }, "@esbuild/freebsd-arm64": { - "version": "0.16.3", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.16.3.tgz", - "integrity": "sha512-nJansp3sSXakNkOD5i5mIz2Is/HjzIhFs49b1tjrPrpCmwgBmH9SSzhC/Z1UqlkivqMYkhfPwMw1dGFUuwmXhw==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", + "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", "dev": true, "optional": true }, "@esbuild/freebsd-x64": { - "version": "0.16.3", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.16.3.tgz", - "integrity": "sha512-TfoDzLw+QHfc4a8aKtGSQ96Wa+6eimljjkq9HKR0rHlU83vw8aldMOUSJTUDxbcUdcgnJzPaX8/vGWm7vyV7ug==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", + "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", "dev": true, "optional": true }, "@esbuild/linux-arm": { - "version": "0.16.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.16.3.tgz", - "integrity": "sha512-VwswmSYwVAAq6LysV59Fyqk3UIjbhuc6wb3vEcJ7HEJUtFuLK9uXWuFoH1lulEbE4+5GjtHi3MHX+w1gNHdOWQ==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", + "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", "dev": true, "optional": true }, "@esbuild/linux-arm64": { - "version": "0.16.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.16.3.tgz", - "integrity": "sha512-7I3RlsnxEFCHVZNBLb2w7unamgZ5sVwO0/ikE2GaYvYuUQs9Qte/w7TqWcXHtCwxvZx/2+F97ndiUQAWs47ZfQ==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", + "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", "dev": true, "optional": true }, "@esbuild/linux-ia32": { - "version": "0.16.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.16.3.tgz", - "integrity": "sha512-X8FDDxM9cqda2rJE+iblQhIMYY49LfvW4kaEjoFbTTQ4Go8G96Smj2w3BRTwA8IHGoi9dPOPGAX63dhuv19UqA==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", + "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", "dev": true, "optional": true }, "@esbuild/linux-loong64": { - "version": "0.16.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.16.3.tgz", - "integrity": "sha512-hIbeejCOyO0X9ujfIIOKjBjNAs9XD/YdJ9JXAy1lHA+8UXuOqbFe4ErMCqMr8dhlMGBuvcQYGF7+kO7waj2KHw==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", + "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", "dev": true, "optional": true }, "@esbuild/linux-mips64el": { - "version": "0.16.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.16.3.tgz", - "integrity": "sha512-znFRzICT/V8VZQMt6rjb21MtAVJv/3dmKRMlohlShrbVXdBuOdDrGb+C2cZGQAR8RFyRe7HS6klmHq103WpmVw==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", + "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", "dev": true, "optional": true }, "@esbuild/linux-ppc64": { - "version": "0.16.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.16.3.tgz", - "integrity": "sha512-EV7LuEybxhXrVTDpbqWF2yehYRNz5e5p+u3oQUS2+ZFpknyi1NXxr8URk4ykR8Efm7iu04//4sBg249yNOwy5Q==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", + "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", "dev": true, "optional": true }, "@esbuild/linux-riscv64": { - "version": "0.16.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.16.3.tgz", - "integrity": "sha512-uDxqFOcLzFIJ+r/pkTTSE9lsCEaV/Y6rMlQjUI9BkzASEChYL/aSQjZjchtEmdnVxDKETnUAmsaZ4pqK1eE5BQ==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", + "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", "dev": true, "optional": true }, "@esbuild/linux-s390x": { - "version": "0.16.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.16.3.tgz", - "integrity": "sha512-NbeREhzSxYwFhnCAQOQZmajsPYtX71Ufej3IQ8W2Gxskfz9DK58ENEju4SbpIj48VenktRASC52N5Fhyf/aliQ==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", + "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", "dev": true, "optional": true }, "@esbuild/linux-x64": { - "version": "0.16.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.16.3.tgz", - "integrity": "sha512-SDiG0nCixYO9JgpehoKgScwic7vXXndfasjnD5DLbp1xltANzqZ425l7LSdHynt19UWOcDjG9wJJzSElsPvk0w==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", + "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", "dev": true, "optional": true }, "@esbuild/netbsd-x64": { - "version": "0.16.3", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.16.3.tgz", - "integrity": "sha512-AzbsJqiHEq1I/tUvOfAzCY15h4/7Ivp3ff/o1GpP16n48JMNAtbW0qui2WCgoIZArEHD0SUQ95gvR0oSO7ZbdA==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", + "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", "dev": true, "optional": true }, "@esbuild/openbsd-x64": { - "version": "0.16.3", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.16.3.tgz", - "integrity": "sha512-gSABi8qHl8k3Cbi/4toAzHiykuBuWLZs43JomTcXkjMZVkp0gj3gg9mO+9HJW/8GB5H89RX/V0QP4JGL7YEEVg==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", + "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", "dev": true, "optional": true }, "@esbuild/sunos-x64": { - "version": "0.16.3", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.16.3.tgz", - "integrity": "sha512-SF9Kch5Ete4reovvRO6yNjMxrvlfT0F0Flm+NPoUw5Z4Q3r1d23LFTgaLwm3Cp0iGbrU/MoUI+ZqwCv5XJijCw==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", + "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", "dev": true, "optional": true }, "@esbuild/win32-arm64": { - "version": "0.16.3", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.16.3.tgz", - "integrity": "sha512-u5aBonZIyGopAZyOnoPAA6fGsDeHByZ9CnEzyML9NqntK6D/xl5jteZUKm/p6nD09+v3pTM6TuUIqSPcChk5gg==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", + "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", "dev": true, "optional": true }, "@esbuild/win32-ia32": { - "version": "0.16.3", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.16.3.tgz", - "integrity": "sha512-GlgVq1WpvOEhNioh74TKelwla9KDuAaLZrdxuuUgsP2vayxeLgVc+rbpIv0IYF4+tlIzq2vRhofV+KGLD+37EQ==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", + "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", "dev": true, "optional": true }, "@esbuild/win32-x64": { - "version": "0.16.3", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.16.3.tgz", - "integrity": "sha512-5/JuTd8OWW8UzEtyf19fbrtMJENza+C9JoPIkvItgTBQ1FO2ZLvjbPO6Xs54vk0s5JB5QsfieUEshRQfu7ZHow==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", + "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", "dev": true, "optional": true }, + "@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, + "requires": { + "eslint-visitor-keys": "^3.3.0" + } + }, + "@eslint-community/regexpp": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.8.0.tgz", + "integrity": "sha512-JylOEEzDiOryeUnFbQz+oViCXS0KsvR1mvHkoMiu5+UiBvy+RYX7tzlIIIEstF/gVa2tj9AQXk3dgnxv6KxhFg==", + "dev": true + }, "@eslint/eslintrc": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.3.tgz", - "integrity": "sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz", + "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==", "dev": true, "requires": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.4.0", - "globals": "^13.15.0", + "espree": "^9.6.0", + "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", @@ -11125,40 +10693,69 @@ }, "dependencies": { "globals": { - "version": "13.18.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.18.0.tgz", - "integrity": "sha512-/mR4KI8Ps2spmoc0Ulu9L7agOF0du1CZNQ3dke8yItYlyKNmGrkONemBbd6V8UTc1Wgcqn21t3WYB7dbRmh6/A==", + "version": "13.21.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.21.0.tgz", + "integrity": "sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==", "dev": true, "requires": { "type-fest": "^0.20.2" } - }, - "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 } } }, - "@farfetched/core": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@farfetched/core/-/core-0.4.1.tgz", - "integrity": "sha512-tGiL2O+3SFaIl9E2MKRV4GRhRqIMI3uGBkDtlyyz6s6jKyiznQc43GeEy/0CE34Xd5Twm+LvwXd9CJ338H2hcA==", - "requires": {} + "@eslint/js": { + "version": "8.51.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.51.0.tgz", + "integrity": "sha512-HxjQ8Qn+4SI3/AFv6sOrDB+g6PpUTDwSJiQqOrnneEk8L71161srI9gjzzZvYVbzHiVg/BvcH95+cK/zfIt4pg==", + "dev": true }, - "@farfetched/react": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@farfetched/react/-/react-0.4.1.tgz", - "integrity": "sha512-FuF+oBiVrUZOHTycwOgN7FwuNX3y97UnoMkl58gLLSyz4OR1ufAv6qHG7jxsFyRyW4xAvyYPgIra2OTcPU8y6w==", + "@farfetched/core": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/@farfetched/core/-/core-0.10.4.tgz", + "integrity": "sha512-sNhsuTL5/DPrpgp7JLN3rKJRxX6PHHG0h2Xlq4JjS2BzOGoJC/SB5iEr3kJyZLN4tjdXa2C0G/L7awf6sPh/4g==", "requires": {} }, "@farfetched/runtypes": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@farfetched/runtypes/-/runtypes-0.4.1.tgz", - "integrity": "sha512-LNx4hiC2Yjeo2JtKRJ/AnMfTuV4sEMLYH+dgGYcwQV7rjKQSpNtvReo5wW8JjnDnwnxpV0dC7o3KLuXap5ecZg==", + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/@farfetched/runtypes/-/runtypes-0.10.4.tgz", + "integrity": "sha512-TRT6AfgFnwBQG3pjjMRC6UBlJ4DbNSvKILajINIJVhgt/9mmxlc8Mt+PObhpm9r0hhscPuLvsmBDKNIUk6UhnA==", "requires": {} }, + "@floating-ui/core": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.5.0.tgz", + "integrity": "sha512-kK1h4m36DQ0UHGj5Ah4db7R0rHemTqqO0QLvUqi1/mUUp3LuAWbWxdxSIf/XsnH9VS6rRVPLJCncjRzUvyCLXg==", + "requires": { + "@floating-ui/utils": "^0.1.3" + } + }, + "@floating-ui/dom": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.5.3.tgz", + "integrity": "sha512-ClAbQnEqJAKCJOEbbLo5IUlZHkNszqhuxS4fHAVxRPXPya6Ysf2G8KypnYcOTpx6I8xcgF9bbHb6g/2KpbV8qA==", + "requires": { + "@floating-ui/core": "^1.4.2", + "@floating-ui/utils": "^0.1.3" + } + }, + "@floating-ui/react-dom": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.0.2.tgz", + "integrity": "sha512-5qhlDvjaLmAst/rKb3VdlCinwTF4EYMiVxuuc/HVUjs46W0zgtbMmAZ1UTsDrRTxRmUEzl92mOtWbeeXL26lSQ==", + "requires": { + "@floating-ui/dom": "^1.5.1" + } + }, + "@floating-ui/utils": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.1.6.tgz", + "integrity": "sha512-OfX7E2oUDYxtBvsuS4e/jSn4Q9Qb6DzgeYtsAdkPZ47znpoNsMgZw0+tVijiv3uGNR6dgNlty6r9rzIzHjtd/A==" + }, + "@fontsource/roboto": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/@fontsource/roboto/-/roboto-5.0.8.tgz", + "integrity": "sha512-XxPltXs5R31D6UZeLIV1td3wTXU3jzd3f2DLsXI8tytMGBkIsGcc9sIyiupRtA8y73HAhuSCeweOoBqf6DbWCA==" + }, "@hapi/hoek": { "version": "9.3.0", "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", @@ -11172,16 +10769,10 @@ "@hapi/hoek": "^9.0.0" } }, - "@hookform/resolvers": { - "version": "2.9.10", - "resolved": "https://registry.npmjs.org/@hookform/resolvers/-/resolvers-2.9.10.tgz", - "integrity": "sha512-JIL1DgJIlH9yuxcNGtyhsWX/PgNltz+5Gr6+8SX9fhXc/hPbEIk6wPI82nhgvp3uUb6ZfAM5mqg/x7KR7NAb+A==", - "requires": {} - }, "@humanwhocodes/config-array": { - "version": "0.11.7", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.7.tgz", - "integrity": "sha512-kBbPWzN8oVMLb0hOUYXhmxggL/1cJE6ydvjDIGi9EnAGUyA7cLVKQg+d/Dsm+KZwx2czGHrCmMVLiyg8s5JPKw==", + "version": "0.11.11", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.11.tgz", + "integrity": "sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA==", "dev": true, "requires": { "@humanwhocodes/object-schema": "^1.2.1", @@ -11201,10 +10792,42 @@ "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", "dev": true }, + "@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "requires": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true + }, + "strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "requires": { + "ansi-regex": "^6.0.1" + } + } + } + }, "@jridgewell/gen-mapping": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", + "dev": true, "requires": { "@jridgewell/set-array": "^1.0.0", "@jridgewell/sourcemap-codec": "^1.4.10" @@ -11213,18 +10836,21 @@ "@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==" + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "dev": true }, "@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==" + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "dev": true }, "@jridgewell/source-map": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz", "integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==", "dev": true, + "optional": true, "peer": true, "requires": { "@jridgewell/gen-mapping": "^0.3.0", @@ -11236,6 +10862,7 @@ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", "dev": true, + "optional": true, "peer": true, "requires": { "@jridgewell/set-array": "^1.0.1", @@ -11248,12 +10875,14 @@ "@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==" + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "dev": true }, "@jridgewell/trace-mapping": { "version": "0.3.17", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", + "dev": true, "requires": { "@jridgewell/resolve-uri": "3.1.0", "@jridgewell/sourcemap-codec": "1.4.14" @@ -11275,16 +10904,16 @@ } }, "@mui/core-downloads-tracker": { - "version": "5.10.17", - "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.10.17.tgz", - "integrity": "sha512-iNwUuMA30nrN0tiEkeD3zaczv7Tk2jlZIDbXRnijAsYXkZtl/xEzQsVRIPYRDuyEz6D18vQJhV8h7gPUXEubTg==" + "version": "5.14.14", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.14.14.tgz", + "integrity": "sha512-Rw/xKiTOUgXD8hdKqj60aC6QcGprMipG7ne2giK6Mz7b4PlhL/xog9xLeclY3BxsRLkZQ05egFnIEY1CSibTbw==" }, "@mui/icons-material": { - "version": "5.10.16", - "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.10.16.tgz", - "integrity": "sha512-jjCc0IF6iyLiucQCu5igg3fOscSqbbvRCmyRxXgzOcLR56B0sg2L8o+ZfJ0dAg59+wvgtXaxvjze/mJg0B4iWA==", + "version": "5.14.14", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.14.14.tgz", + "integrity": "sha512-vwuaMsKvI7AWTeYqR8wYbpXijuU8PzMAJWRAq2DDIuOZPxjKyHlr8WQ25+azZYkIXtJ7AqnVb1ZmHdEyB4/kug==", "requires": { - "@babel/runtime": "^7.20.1" + "@babel/runtime": "^7.23.1" } }, "@mui/lab": { @@ -11303,95 +10932,140 @@ } }, "@mui/material": { - "version": "5.10.17", - "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.10.17.tgz", - "integrity": "sha512-Kuqgv1qI5HXnc/Xu426xhCGYBSKzplb+xFNLitbnIb92Qx8jmcpfNpFlDJa2kD2H6qP66rr/m4c/zMUfGX/xBQ==", - "requires": { - "@babel/runtime": "^7.20.1", - "@mui/base": "5.0.0-alpha.109", - "@mui/core-downloads-tracker": "^5.10.17", - "@mui/system": "^5.10.17", - "@mui/types": "^7.2.2", - "@mui/utils": "^5.10.16", - "@types/react-transition-group": "^4.4.5", - "clsx": "^1.2.1", - "csstype": "^3.1.1", + "version": "5.14.14", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.14.14.tgz", + "integrity": "sha512-cAmCwAHFQXxb44kWbVFkhKATN8tACgMsFwrXo8ro6WzYW73U/qsR5AcCiJIhCyYYg+gcftfkmNcpRaV3JjhHCg==", + "requires": { + "@babel/runtime": "^7.23.1", + "@mui/base": "5.0.0-beta.20", + "@mui/core-downloads-tracker": "^5.14.14", + "@mui/system": "^5.14.14", + "@mui/types": "^7.2.6", + "@mui/utils": "^5.14.13", + "@types/react-transition-group": "^4.4.7", + "clsx": "^2.0.0", + "csstype": "^3.1.2", "prop-types": "^15.8.1", "react-is": "^18.2.0", "react-transition-group": "^4.4.5" }, "dependencies": { "@mui/base": { - "version": "5.0.0-alpha.109", - "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-alpha.109.tgz", - "integrity": "sha512-UQxoONPI3ntzxcD/cbFHl+Lp2xsVj6HpKmU9QhUZ2kZ2K2yej2QJyU1gnADoWl/Hu94VrvwSSRnjTjR3HvXO/g==", + "version": "5.0.0-beta.20", + "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.20.tgz", + "integrity": "sha512-CS2pUuqxST7ch9VNDCklRYDbJ3rru20Tx7na92QvVVKfu3RL4z/QLuVIc8jYGsdCnauMaeUSlFNLAJNb0yXe6w==", "requires": { - "@babel/runtime": "^7.20.1", - "@emotion/is-prop-valid": "^1.2.0", - "@mui/types": "^7.2.2", - "@mui/utils": "^5.10.16", - "@popperjs/core": "^2.11.6", - "clsx": "^1.2.1", - "prop-types": "^15.8.1", - "react-is": "^18.2.0" + "@babel/runtime": "^7.23.1", + "@floating-ui/react-dom": "^2.0.2", + "@mui/types": "^7.2.6", + "@mui/utils": "^5.14.13", + "@popperjs/core": "^2.11.8", + "clsx": "^2.0.0", + "prop-types": "^15.8.1" } + }, + "clsx": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.0.0.tgz", + "integrity": "sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==" } } }, "@mui/private-theming": { - "version": "5.10.16", - "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.10.16.tgz", - "integrity": "sha512-0MArkJaOHRCKqL/GWjngGZmyOeRz+uxffhx82bKcewr8swqV7xx7EFP02pk0L/gLdfcvYdqwH4YTVjG/+TaKrg==", + "version": "5.14.14", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.14.14.tgz", + "integrity": "sha512-n77au3CQj9uu16hak2Y+rvbGSBaJKxziG/gEbOLVGrAuqZ+ycVSkorCfN6Y/4XgYOpG/xvmuiY3JwhAEOzY3iA==", "requires": { - "@babel/runtime": "^7.20.1", - "@mui/utils": "^5.10.16", + "@babel/runtime": "^7.23.1", + "@mui/utils": "^5.14.13", "prop-types": "^15.8.1" } }, "@mui/styled-engine": { - "version": "5.10.16", - "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.10.16.tgz", - "integrity": "sha512-ZMSjXvtiGwGDKqrSlXhpxK2voUaF2/lpC/pSTfFmZvKH9j9a9h1/iwo3ybgjFVYGgbfNeW4h0xEchiRohu9xsw==", + "version": "5.14.14", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.14.14.tgz", + "integrity": "sha512-sF3DS2PVG+cFWvkVHQQaGFpL1h6gSwOW3L91pdxPLQDHDZ5mZ/X0SlXU5XA+WjypoysG4urdAQC7CH/BRvUiqg==", "requires": { - "@babel/runtime": "^7.20.1", - "@emotion/cache": "^11.10.5", - "csstype": "^3.1.1", + "@babel/runtime": "^7.23.1", + "@emotion/cache": "^11.11.0", + "csstype": "^3.1.2", "prop-types": "^15.8.1" } }, "@mui/system": { - "version": "5.10.17", - "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.10.17.tgz", - "integrity": "sha512-UYzAOSK7uxkMsUssqrIUW3lnOuQpU8vqh4hLwfSw+GYAnQo3qjK4m4NhlDx+pFpsjjiGnr3K+vrSH+aIAMbcLg==", - "requires": { - "@babel/runtime": "^7.20.1", - "@mui/private-theming": "^5.10.16", - "@mui/styled-engine": "^5.10.16", - "@mui/types": "^7.2.2", - "@mui/utils": "^5.10.16", - "clsx": "^1.2.1", - "csstype": "^3.1.1", + "version": "5.14.14", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.14.14.tgz", + "integrity": "sha512-y4InFmCgGGWXnz+iK4jRTWVikY0HgYnABjz4wgiUgEa2W1H8M4ow+27BegExUWPkj4TWthQ2qG9FOGSMtI+PKA==", + "requires": { + "@babel/runtime": "^7.23.1", + "@mui/private-theming": "^5.14.14", + "@mui/styled-engine": "^5.14.13", + "@mui/types": "^7.2.6", + "@mui/utils": "^5.14.13", + "clsx": "^2.0.0", + "csstype": "^3.1.2", "prop-types": "^15.8.1" + }, + "dependencies": { + "clsx": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.0.0.tgz", + "integrity": "sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==" + } } }, "@mui/types": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.2.tgz", - "integrity": "sha512-siex8cZDtWeC916cXOoUOnEQQejuMYmHtc4hM6VkKVYaBICz3VIiqyiAomRboTQHt2jchxQ5Q5ATlbcDekTxDA==", + "version": "7.2.6", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.6.tgz", + "integrity": "sha512-7sjLQrUmBwufm/M7jw/quNiPK/oor2+pGUQP2CULRcFCArYTq78oJ3D5esTaL0UMkXKJvDqXn6Ike69yAOBQng==", "requires": {} }, "@mui/utils": { - "version": "5.10.16", - "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.10.16.tgz", - "integrity": "sha512-3MB/SGsgiiu9Z55CFmAfiONUoR7AAue/H4F6w3mc2LnhFQCsoVvXhioDPcsiRpUMIQr34jDPzGXdCuqWooPCXQ==", + "version": "5.14.14", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.14.14.tgz", + "integrity": "sha512-3AKp8uksje5sRfVrtgG9Q/2TBsHWVBUtA0NaXliZqGcXo8J+A+Agp0qUW2rJ+ivgPWTCCubz9FZVT2IQZ3bGsw==", "requires": { - "@babel/runtime": "^7.20.1", - "@types/prop-types": "^15.7.5", - "@types/react-is": "^16.7.1 || ^17.0.0", + "@babel/runtime": "^7.23.1", + "@types/prop-types": "^15.7.7", "prop-types": "^15.8.1", "react-is": "^18.2.0" } }, + "@mui/x-date-pickers": { + "version": "6.16.2", + "resolved": "https://registry.npmjs.org/@mui/x-date-pickers/-/x-date-pickers-6.16.2.tgz", + "integrity": "sha512-JFrDUeBkiKtfJ0WqwyPBICEP1U+Ujfsily3ZQ/Hv4zAOleG/5769EgS7TOO4cVgnuhtvQ/pqx2gmuCn8/gcC5w==", + "requires": { + "@babel/runtime": "^7.23.1", + "@mui/base": "^5.0.0-beta.17", + "@mui/utils": "^5.14.11", + "@types/react-transition-group": "^4.4.7", + "clsx": "^2.0.0", + "prop-types": "^15.8.1", + "react-transition-group": "^4.4.5" + }, + "dependencies": { + "@mui/base": { + "version": "5.0.0-beta.20", + "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.20.tgz", + "integrity": "sha512-CS2pUuqxST7ch9VNDCklRYDbJ3rru20Tx7na92QvVVKfu3RL4z/QLuVIc8jYGsdCnauMaeUSlFNLAJNb0yXe6w==", + "requires": { + "@babel/runtime": "^7.23.1", + "@floating-ui/react-dom": "^2.0.2", + "@mui/types": "^7.2.6", + "@mui/utils": "^5.14.13", + "@popperjs/core": "^2.11.8", + "clsx": "^2.0.0", + "prop-types": "^15.8.1" + } + }, + "clsx": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.0.0.tgz", + "integrity": "sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==" + } + } + }, "@nicolo-ribaudo/chokidar-2": { "version": "2.1.8-no-fsevents.3", "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/chokidar-2/-/chokidar-2-2.1.8-no-fsevents.3.tgz", @@ -11425,15 +11099,22 @@ "fastq": "^1.6.0" } }, + "@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true + }, "@popperjs/core": { - "version": "2.11.6", - "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.6.tgz", - "integrity": "sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw==" + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==" }, "@rollup/plugin-babel": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-6.0.3.tgz", - "integrity": "sha512-fKImZKppa1A/gX73eg4JGo+8kQr/q1HBQaCGKECZ0v4YBBv3lFqi14+7xyApECzvkLTHCifx+7ntcrvtBIRcpg==", + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-6.0.4.tgz", + "integrity": "sha512-YF7Y52kFdFT/xVSuVdjkV5ZdX/3YtmX0QulG+x0taQOtJdHYzVU61aSSkAgVJ7NOv6qPkIYiJSgSWWN/DM5sGw==", "dev": true, "requires": { "@babel/helper-module-imports": "^7.18.6", @@ -11460,28 +11141,23 @@ } }, "@sideway/formula": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.0.tgz", - "integrity": "sha512-vHe7wZ4NOXVfkoRb8T5otiENVlT7a3IAiw7H5M2+GO+9CDgcVUUsX1zalAztCmwyOr2RUTGJdgB+ZvSVqmdHmg==" + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz", + "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==" }, "@sideway/pinpoint": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==" }, - "@socket.io/component-emitter": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz", - "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==" - }, "@types/babel__core": { - "version": "7.1.20", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.20.tgz", - "integrity": "sha512-PVb6Bg2QuscZ30FvOU7z4guG6c926D9YRvOxEaelzndpMsvP+YM74Q/dAFASpg2l6+XLalxSGxcq/lrgYWZtyQ==", + "version": "7.20.3", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.3.tgz", + "integrity": "sha512-54fjTSeSHwfan8AyHWrKbfBWiEUrNTZsUwPTDSNaaP1QDQIZbeNUg3a59E9D+375MzUw/x1vx2/0F5LBz+AeYA==", "dev": true, "requires": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0", + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", "@types/babel__generator": "*", "@types/babel__template": "*", "@types/babel__traverse": "*" @@ -11515,38 +11191,11 @@ "@babel/types": "^7.3.0" } }, - "@types/css-modules-loader-core": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@types/css-modules-loader-core/-/css-modules-loader-core-1.1.0.tgz", - "integrity": "sha512-LMbyf7THPqLCPHIXAj79v9Pa193MeOHgp1fBFRR6s6VvEVHUFIcM5bc/WttslOf+lao4TURNN1X1zfW5wr2CHQ==", - "dev": true, - "requires": { - "postcss": "7.x.x" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==", - "dev": true - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dev": true, - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } + "@types/compose-function": { + "version": "0.0.32", + "resolved": "https://registry.npmjs.org/@types/compose-function/-/compose-function-0.0.32.tgz", + "integrity": "sha512-eolBu32OsVG1Rk0Vq84TDAuVl8v4NAkb0QtmuD3en08lv8Uy8el1NoS3hGTRTaLaQfaL8GRUiBT1aZhoH5bWNg==", + "dev": true }, "@types/estree": { "version": "1.0.0", @@ -11555,9 +11204,9 @@ "dev": true }, "@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==", + "version": "7.0.14", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.14.tgz", + "integrity": "sha512-U3PUjAudAdJBeC2pgN8uTIKgxrb4nlDF3SF0++EldXQvQBGkpFZMSnwQiIoDU77tv45VgNkl/L4ouD+rEomujw==", "dev": true }, "@types/json5": { @@ -11567,10 +11216,13 @@ "dev": true }, "@types/node": { - "version": "18.11.12", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.12.tgz", - "integrity": "sha512-FgD3NtTAKvyMmD44T07zz2fEf+OKwutgBCEVM8GcvMGVGaDktiLNTDvPwC/LUe3PinMW+X6CuLOF2Ui1mAlSXg==", - "dev": true + "version": "20.8.7", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.7.tgz", + "integrity": "sha512-21TKHHh3eUHIi2MloeptJWALuCu5H7HQTdTrWIFReA8ad+aggoX+lRes3ex7/FtpC+sVUpFMQ+QTfYr74mruiQ==", + "dev": true, + "requires": { + "undici-types": "~5.25.1" + } }, "@types/parse-json": { "version": "4.0.0", @@ -11578,14 +11230,14 @@ "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==" }, "@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==" + "version": "15.7.9", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.9.tgz", + "integrity": "sha512-n1yyPsugYNSmHgxDFjicaI2+gCNjsBck8UX9kuofAKlc0h1bL+20oSF72KeNaW2DUlesbEVCFgyV2dPGTiY42g==" }, "@types/react": { - "version": "18.0.26", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.26.tgz", - "integrity": "sha512-hCR3PJQsAIXyxhTNSiDFY//LhnMZWpNNr5etoCqx/iUfGc5gXWtQR2Phl908jVR6uPXacojQWTg4qRpkxTuGug==", + "version": "18.2.31", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.31.tgz", + "integrity": "sha512-c2UnPv548q+5DFh03y8lEDeMfDwBn9G3dRwfkrxQMo/dOtRHUUO57k6pHvBIfH/VF4Nh+98mZ5aaSe+2echD5g==", "requires": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -11593,26 +11245,18 @@ } }, "@types/react-dom": { - "version": "18.0.9", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.0.9.tgz", - "integrity": "sha512-qnVvHxASt/H7i+XG1U1xMiY5t+IHcPGUK7TDMDzom08xa7e86eCeKOiLZezwCKVxJn6NEiiy2ekgX8aQssjIKg==", + "version": "18.2.14", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.14.tgz", + "integrity": "sha512-V835xgdSVmyQmI1KLV2BEIUgqEuinxp9O4G6g3FqO/SqLac049E53aysv0oEFD2kHfejeKU+ZqL2bcFWj9gLAQ==", "dev": true, "requires": { "@types/react": "*" } }, - "@types/react-is": { - "version": "17.0.3", - "resolved": "https://registry.npmjs.org/@types/react-is/-/react-is-17.0.3.tgz", - "integrity": "sha512-aBTIWg1emtu95bLTLx0cpkxwGW3ueZv71nE2YFBpL8k/z5czEW8yYpOo8Dp+UUAFAtKwNaOsh/ioSeQnWlZcfw==", - "requires": { - "@types/react": "*" - } - }, "@types/react-transition-group": { - "version": "4.4.5", - "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.5.tgz", - "integrity": "sha512-juKD/eiSM3/xZYzjuzH6ZwpP+/lejltmiS3QEzV/vmb/Q8+HfDmxu+Baga8UEMGBqV88Nbg4l2hY/K2DkyaLLA==", + "version": "4.4.8", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.8.tgz", + "integrity": "sha512-QmQ22q+Pb+HQSn04NL3HtrqHwYMf4h3QKArOy5F8U5nEVMaihBs3SR10WiOM1iwPz5jIo8x/u11al+iEGZZrvg==", "requires": { "@types/react": "*" } @@ -11623,172 +11267,212 @@ "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==" }, "@types/semver": { - "version": "7.3.13", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz", - "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-MMzuxN3GdFwskAnb6fz0orFvhfqi752yjaXylr0Rp4oDg5H0Zn1IuyRhDVvYOwAXoJirx2xuS16I3WjxnAIHiQ==", "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "5.46.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.46.0.tgz", - "integrity": "sha512-QrZqaIOzJAjv0sfjY4EjbXUi3ZOFpKfzntx22gPGr9pmFcTjcFw/1sS1LJhEubfAGwuLjNrPV0rH+D1/XZFy7Q==", + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.8.0.tgz", + "integrity": "sha512-GosF4238Tkes2SHPQ1i8f6rMtG6zlKwMEB0abqSJ3Npvos+doIlc/ATG+vX1G9coDF3Ex78zM3heXHLyWEwLUw==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.46.0", - "@typescript-eslint/type-utils": "5.46.0", - "@typescript-eslint/utils": "5.46.0", + "@eslint-community/regexpp": "^4.5.1", + "@typescript-eslint/scope-manager": "6.8.0", + "@typescript-eslint/type-utils": "6.8.0", + "@typescript-eslint/utils": "6.8.0", + "@typescript-eslint/visitor-keys": "6.8.0", "debug": "^4.3.4", - "ignore": "^5.2.0", - "natural-compare-lite": "^1.4.0", - "regexpp": "^3.2.0", - "semver": "^7.3.7", - "tsutils": "^3.21.0" + "graphemer": "^1.4.0", + "ignore": "^5.2.4", + "natural-compare": "^1.4.0", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" }, "dependencies": { + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, "semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, "requires": { "lru-cache": "^6.0.0" } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true } } }, "@typescript-eslint/parser": { - "version": "5.46.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.46.0.tgz", - "integrity": "sha512-joNO6zMGUZg+C73vwrKXCd8usnsmOYmgW/w5ZW0pG0RGvqeznjtGDk61EqqTpNrFLUYBW2RSBFrxdAZMqA4OZA==", + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.8.0.tgz", + "integrity": "sha512-5tNs6Bw0j6BdWuP8Fx+VH4G9fEPDxnVI7yH1IAPkQH5RUtvKwRoqdecAPdQXv4rSOADAaz1LFBZvZG7VbXivSg==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.46.0", - "@typescript-eslint/types": "5.46.0", - "@typescript-eslint/typescript-estree": "5.46.0", + "@typescript-eslint/scope-manager": "6.8.0", + "@typescript-eslint/types": "6.8.0", + "@typescript-eslint/typescript-estree": "6.8.0", + "@typescript-eslint/visitor-keys": "6.8.0", "debug": "^4.3.4" } }, "@typescript-eslint/scope-manager": { - "version": "5.46.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.46.0.tgz", - "integrity": "sha512-7wWBq9d/GbPiIM6SqPK9tfynNxVbfpihoY5cSFMer19OYUA3l4powA2uv0AV2eAZV6KoAh6lkzxv4PoxOLh1oA==", + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.8.0.tgz", + "integrity": "sha512-xe0HNBVwCph7rak+ZHcFD6A+q50SMsFwcmfdjs9Kz4qDh5hWhaPhFjRs/SODEhroBI5Ruyvyz9LfwUJ624O40g==", "dev": true, "requires": { - "@typescript-eslint/types": "5.46.0", - "@typescript-eslint/visitor-keys": "5.46.0" + "@typescript-eslint/types": "6.8.0", + "@typescript-eslint/visitor-keys": "6.8.0" } }, "@typescript-eslint/type-utils": { - "version": "5.46.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.46.0.tgz", - "integrity": "sha512-dwv4nimVIAsVS2dTA0MekkWaRnoYNXY26dKz8AN5W3cBFYwYGFQEqm/cG+TOoooKlncJS4RTbFKgcFY/pOiBCg==", + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.8.0.tgz", + "integrity": "sha512-RYOJdlkTJIXW7GSldUIHqc/Hkto8E+fZN96dMIFhuTJcQwdRoGN2rEWA8U6oXbLo0qufH7NPElUb+MceHtz54g==", "dev": true, "requires": { - "@typescript-eslint/typescript-estree": "5.46.0", - "@typescript-eslint/utils": "5.46.0", + "@typescript-eslint/typescript-estree": "6.8.0", + "@typescript-eslint/utils": "6.8.0", "debug": "^4.3.4", - "tsutils": "^3.21.0" + "ts-api-utils": "^1.0.1" } }, "@typescript-eslint/types": { - "version": "5.46.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.46.0.tgz", - "integrity": "sha512-wHWgQHFB+qh6bu0IAPAJCdeCdI0wwzZnnWThlmHNY01XJ9Z97oKqKOzWYpR2I83QmshhQJl6LDM9TqMiMwJBTw==", + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.8.0.tgz", + "integrity": "sha512-p5qOxSum7W3k+llc7owEStXlGmSl8FcGvhYt8Vjy7FqEnmkCVlM3P57XQEGj58oqaBWDQXbJDZxwUWMS/EAPNQ==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "5.46.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.46.0.tgz", - "integrity": "sha512-kDLNn/tQP+Yp8Ro2dUpyyVV0Ksn2rmpPpB0/3MO874RNmXtypMwSeazjEN/Q6CTp8D7ExXAAekPEcCEB/vtJkw==", + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.8.0.tgz", + "integrity": "sha512-ISgV0lQ8XgW+mvv5My/+iTUdRmGspducmQcDw5JxznasXNnZn3SKNrTRuMsEXv+V/O+Lw9AGcQCfVaOPCAk/Zg==", "dev": true, "requires": { - "@typescript-eslint/types": "5.46.0", - "@typescript-eslint/visitor-keys": "5.46.0", + "@typescript-eslint/types": "6.8.0", + "@typescript-eslint/visitor-keys": "6.8.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" }, "dependencies": { + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, "semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, "requires": { "lru-cache": "^6.0.0" } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true } } }, "@typescript-eslint/utils": { - "version": "5.46.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.46.0.tgz", - "integrity": "sha512-4O+Ps1CRDw+D+R40JYh5GlKLQERXRKW5yIQoNDpmXPJ+C7kaPF9R7GWl+PxGgXjB3PQCqsaaZUpZ9dG4U6DO7g==", + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.8.0.tgz", + "integrity": "sha512-dKs1itdE2qFG4jr0dlYLQVppqTE+Itt7GmIf/vX6CSvsW+3ov8PbWauVKyyfNngokhIO9sKZeRGCUo1+N7U98Q==", "dev": true, "requires": { - "@types/json-schema": "^7.0.9", - "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.46.0", - "@typescript-eslint/types": "5.46.0", - "@typescript-eslint/typescript-estree": "5.46.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0", - "semver": "^7.3.7" + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.12", + "@types/semver": "^7.5.0", + "@typescript-eslint/scope-manager": "6.8.0", + "@typescript-eslint/types": "6.8.0", + "@typescript-eslint/typescript-estree": "6.8.0", + "semver": "^7.5.4" }, "dependencies": { + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, "semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, "requires": { "lru-cache": "^6.0.0" } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true } } }, "@typescript-eslint/visitor-keys": { - "version": "5.46.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.46.0.tgz", - "integrity": "sha512-E13gBoIXmaNhwjipuvQg1ByqSAu/GbEpP/qzFihugJ+MomtoJtFAJG/+2DRPByf57B863m0/q7Zt16V9ohhANw==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.46.0", - "eslint-visitor-keys": "^3.3.0" - } - }, - "@vitejs/plugin-legacy": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-legacy/-/plugin-legacy-3.0.1.tgz", - "integrity": "sha512-XCtEjxoR3rmy000ujYRBp5kggWqzHz9+F20/yIMUWOzbvu0+KW1e14Fvb8h7SpNn+bfjGW1RiAs1Vrgb7Js+iQ==", + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.8.0.tgz", + "integrity": "sha512-oqAnbA7c+pgOhW2OhGvxm0t1BULX5peQI/rLsNDpGM78EebV3C9IGbX5HNZabuZ6UQrYveCLjKo8Iy/lLlBkkg==", "dev": true, "requires": { - "@babel/standalone": "^7.20.6", - "core-js": "^3.26.1", - "magic-string": "^0.27.0", - "regenerator-runtime": "^0.13.11", - "systemjs": "^6.13.0" + "@typescript-eslint/types": "6.8.0", + "eslint-visitor-keys": "^3.4.1" } }, "@vitejs/plugin-react": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-3.0.0.tgz", - "integrity": "sha512-1mvyPc0xYW5G8CHQvJIJXLoMjl5Ct3q2g5Y2s6Ccfgwm45y48LBvsla7az+GkkAtYikWQ4Lxqcsq5RHLcZgtNQ==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.1.0.tgz", + "integrity": "sha512-rM0SqazU9iqPUraQ2JlIvReeaxOoRj6n+PzB1C0cBzIbd8qP336nC39/R9yPi3wVcah7E7j/kdU1uCUqMEU4OQ==", "dev": true, "requires": { - "@babel/core": "^7.20.5", - "@babel/plugin-transform-react-jsx-self": "^7.18.6", - "@babel/plugin-transform-react-jsx-source": "^7.19.6", - "magic-string": "^0.27.0", + "@babel/core": "^7.22.20", + "@babel/plugin-transform-react-jsx-self": "^7.22.5", + "@babel/plugin-transform-react-jsx-source": "^7.22.5", + "@types/babel__core": "^7.20.2", "react-refresh": "^0.14.0" } }, + "@withease/web-api": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@withease/web-api/-/web-api-1.0.1.tgz", + "integrity": "sha512-KC+6ueVd1rEpLvMN7uXHa7E5TKdv7MxIhEAAs8tjAgmKxkUgranpsrjU2ZlwHGimuc98Z428/n+zgldZE3nIMg==", + "requires": {} + }, "acorn": { - "version": "8.8.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", - "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", + "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", "dev": true }, "acorn-jsx": { @@ -11798,16 +11482,6 @@ "dev": true, "requires": {} }, - "aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "dev": true, - "requires": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - } - }, "ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -11821,12 +11495,20 @@ } }, "ansi-escapes": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-6.0.0.tgz", - "integrity": "sha512-IG23inYII3dWlU2EyiAiGj6Bwal5GzsgPMwjYGvc1HPE2dgbj4ZB5ToWBKSquKw74nB3TIuOwaI6/jSULzfgrw==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-5.0.0.tgz", + "integrity": "sha512-5GFMVX8HqE/TB+FuBJGuO5XG0WrsA6ptUqoODaT/n9mmUaZFkqnBueB4leqGBCmrUHnCnC4PCZTCd0E7QQ83bA==", "dev": true, "requires": { - "type-fest": "^3.0.0" + "type-fest": "^1.0.2" + }, + "dependencies": { + "type-fest": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", + "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", + "dev": true + } } }, "ansi-regex": { @@ -11870,6 +11552,21 @@ "@babel/runtime-corejs3": "^7.10.2" } }, + "arity-n": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/arity-n/-/arity-n-1.0.4.tgz", + "integrity": "sha512-fExL2kFDC1Q2DUOx3whE/9KoN66IzkY4b4zUHUBFM1ojEYjZZYDcUW3bek/ufGionX9giIKDC5redH2IlGqcQQ==" + }, + "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, + "requires": { + "call-bind": "^1.0.2", + "is-array-buffer": "^3.0.1" + } + }, "array-includes": { "version": "3.1.6", "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.6.tgz", @@ -11889,6 +11586,19 @@ "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true }, + "array.prototype.findlastindex": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.3.tgz", + "integrity": "sha512-LzLoiOMAxvy+Gd3BAq3B7VeIgPdo+Q8hthvKtXybMvRV0jrXfJM/t8mw7nNlpEcVlVUnCnM2KSX4XU5HmpodOA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0", + "get-intrinsic": "^1.2.1" + } + }, "array.prototype.flat": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz", @@ -11906,7 +11616,6 @@ "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz", "integrity": "sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==", "dev": true, - "peer": true, "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.4", @@ -11914,6 +11623,21 @@ "es-shim-unscopables": "^1.0.0" } }, + "arraybuffer.prototype.slice": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz", + "integrity": "sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==", + "dev": true, + "requires": { + "array-buffer-byte-length": "^1.0.0", + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", + "is-array-buffer": "^3.0.2", + "is-shared-array-buffer": "^1.0.2" + } + }, "ast-types-flow": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", @@ -11921,17 +11645,6 @@ "dev": true, "peer": true }, - "astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "dev": true - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" - }, "atomic-router": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/atomic-router/-/atomic-router-0.8.0.tgz", @@ -11941,26 +11654,18 @@ } }, "atomic-router-react": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/atomic-router-react/-/atomic-router-react-0.8.1.tgz", - "integrity": "sha512-zD8MrolFnPhQLOvBmDl6scur3fDCPGavC04WMK2b532q4+5NDk9Eo9mPZvJFvq/Z21UDR7jWOo7Gjzl0AVKRFQ==", + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/atomic-router-react/-/atomic-router-react-0.8.5.tgz", + "integrity": "sha512-XI+L5Kt+NSbVyZ8rc2M+9i4VslETv+ASNuR3wUm537p83mkXWVqZ37taNCsVDnX2D4vLGkfj8Fl6b/hw/tBqeQ==", "requires": { "clsx": "^1.1.1" } }, - "autoprefixer": { - "version": "10.4.13", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.13.tgz", - "integrity": "sha512-49vKpMqcZYsJjwotvt4+h/BCjJVnhGwcLpDt5xkcaOG3eLrG/HUYLagrihYsQ+qrIBgIzX1Rw7a6L8I/ZA1Atg==", - "dev": true, - "requires": { - "browserslist": "^4.21.4", - "caniuse-lite": "^1.0.30001426", - "fraction.js": "^4.2.0", - "normalize-range": "^0.1.2", - "picocolors": "^1.0.0", - "postcss-value-parser": "^4.2.0" - } + "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 }, "axe-core": { "version": "4.5.2", @@ -11969,16 +11674,6 @@ "dev": true, "peer": true }, - "axios": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.2.1.tgz", - "integrity": "sha512-I88cFiGu9ryt/tfVEi4kX2SITsvDddTajXTOFmt2uK1ZVA8LytjtdeyefdQWEf5PU8w+4SSJDoYnggflB5tW4A==", - "requires": { - "follow-redirects": "^1.15.0", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - }, "axobject-query": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", @@ -11997,33 +11692,33 @@ } }, "babel-plugin-polyfill-corejs2": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz", - "integrity": "sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==", + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.6.tgz", + "integrity": "sha512-jhHiWVZIlnPbEUKSSNb9YoWcQGdlTLq7z1GHL4AjFxaoOUMuuEVJ+Y4pAaQUGOGk93YsVCKPbqbfw3m0SM6H8Q==", "dev": true, "requires": { - "@babel/compat-data": "^7.17.7", - "@babel/helper-define-polyfill-provider": "^0.3.3", - "semver": "^6.1.1" + "@babel/compat-data": "^7.22.6", + "@babel/helper-define-polyfill-provider": "^0.4.3", + "semver": "^6.3.1" } }, "babel-plugin-polyfill-corejs3": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.6.0.tgz", - "integrity": "sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA==", + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.5.tgz", + "integrity": "sha512-Q6CdATeAvbScWPNLB8lzSO7fgUVBkQt6zLgNlfyeCr/EQaEQR+bWiBYYPYAFyE528BMjRhL+1QBMOI4jc/c5TA==", "dev": true, "requires": { - "@babel/helper-define-polyfill-provider": "^0.3.3", - "core-js-compat": "^3.25.1" + "@babel/helper-define-polyfill-provider": "^0.4.3", + "core-js-compat": "^3.32.2" } }, "babel-plugin-polyfill-regenerator": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.1.tgz", - "integrity": "sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw==", + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.3.tgz", + "integrity": "sha512-8sHeDOmXC8csczMrYEOf0UTNa4yE2SxV5JGeT/LP1n0OYVDUUFPxG9vdk2AlDlIit4t+Kf0xCtpgXPBwnn/9pw==", "dev": true, "requires": { - "@babel/helper-define-polyfill-provider": "^0.3.3" + "@babel/helper-define-polyfill-provider": "^0.4.3" } }, "balanced-match": { @@ -12032,29 +11727,12 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, - "base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true - }, "binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true }, - "bl": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-5.1.0.tgz", - "integrity": "sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==", - "dev": true, - "requires": { - "buffer": "^6.0.3", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -12075,24 +11753,15 @@ } }, "browserslist": { - "version": "4.21.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", - "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", - "requires": { - "caniuse-lite": "^1.0.30001400", - "electron-to-chromium": "^1.4.251", - "node-releases": "^2.0.6", - "update-browserslist-db": "^1.0.9" - } - }, - "buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "version": "4.22.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.1.tgz", + "integrity": "sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==", "dev": true, "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" + "caniuse-lite": "^1.0.30001541", + "electron-to-chromium": "^1.4.535", + "node-releases": "^2.0.13", + "update-browserslist-db": "^1.0.13" } }, "buffer-from": { @@ -12100,6 +11769,7 @@ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true, + "optional": true, "peer": true }, "call-bind": { @@ -12124,9 +11794,10 @@ "dev": true }, "caniuse-lite": { - "version": "1.0.30001431", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001431.tgz", - "integrity": "sha512-zBUoFU0ZcxpvSt9IU66dXVT/3ctO1cy4y9cscs1szkPlcWb6pasYM144GqrUygUbT+k7cmUCW61cvskjcv0enQ==" + "version": "1.0.30001551", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001551.tgz", + "integrity": "sha512-vtBAez47BoGMMzlbYhfXrMV1kvRF2WP/lqiMuDu1Sb4EE4LKEgjopFDSRtZfdVnslNRpOqV/woE+Xgrwj6VQlg==", + "dev": true }, "chalk": { "version": "2.4.2", @@ -12145,12 +11816,6 @@ } } }, - "chardet": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", - "dev": true - }, "chokidar": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", @@ -12172,12 +11837,6 @@ "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz", "integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==" }, - "clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "dev": true - }, "cli-cursor": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", @@ -12187,12 +11846,6 @@ "restore-cursor": "^4.0.0" } }, - "cli-spinners": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.7.0.tgz", - "integrity": "sha512-qu3pN8Y3qHNgE2AFweciB1IfMnmZ/fsNTEE+NOFjmGB2F/7rLhnhzppvpCnN4FovtP26k8lHyy9ptEbNwWFLzw==", - "dev": true - }, "cli-truncate": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-3.1.0.tgz", @@ -12203,21 +11856,15 @@ "string-width": "^5.0.0" } }, - "cli-width": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.0.0.tgz", - "integrity": "sha512-ZksGS2xpa/bYkNzN3BAw1wEjsLV/ZKOf/CCrJ/QOBsxx6fOARIkwTutxp1XIOIohi6HKmOFjMoK/XaqDVUpEEw==", - "dev": true - }, "cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "dev": true, "requires": { "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" }, "dependencies": { "ansi-styles": { @@ -12250,6 +11897,12 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, "string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -12262,9 +11915,9 @@ } }, "wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "requires": { "ansi-styles": "^4.0.0", @@ -12274,12 +11927,6 @@ } } }, - "clone": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", - "dev": true - }, "clsx": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", @@ -12299,25 +11946,25 @@ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" }, "colorette": { - "version": "2.0.19", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz", - "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==", + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", "dev": true }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { - "delayed-stream": "~1.0.0" - } - }, "commander": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", "dev": true }, + "compose-function": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/compose-function/-/compose-function-3.0.3.tgz", + "integrity": "sha512-xzhzTJ5eC+gmIzvZq+C3kCJHsp9os6tJkrigDRZclyGtOKINbZtE8n1Tzmeh32jW+BUDPbvZpibwvJHBLGMVwg==", + "requires": { + "arity-n": "^1.0.4" + } + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -12335,19 +11982,13 @@ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" }, - "core-js": { - "version": "3.26.1", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.26.1.tgz", - "integrity": "sha512-21491RRQVzUn0GGM9Z1Jrpr6PNPxPi+Za8OM9q4tksTSnlbXXGKK1nXNg/QvwFYettXvSX6zWKCtHHfjN4puyA==", - "dev": true - }, "core-js-compat": { - "version": "3.26.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.26.1.tgz", - "integrity": "sha512-622/KzTudvXCDLRw70iHW4KKs1aGpcRcowGWyYJr2DEBfRrd6hNJybxSWJFuZYD4ma86xhrwDDHxmDaIq4EA8A==", + "version": "3.33.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.33.1.tgz", + "integrity": "sha512-6pYKNOgD/j/bkC5xS5IIg6bncid3rfrI42oBH1SQJbsmYPKF7rhzcFzYCcxYMmNQQ0rCEB8WqpW7QHndOggaeQ==", "dev": true, "requires": { - "browserslist": "^4.21.4" + "browserslist": "^4.22.1" } }, "core-js-pure": { @@ -12370,140 +12011,22 @@ } }, "cross-fetch": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz", - "integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==", - "requires": { - "node-fetch": "2.6.7" - } - }, - "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, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "css-modules-loader-core": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/css-modules-loader-core/-/css-modules-loader-core-1.1.0.tgz", - "integrity": "sha512-XWOBwgy5nwBn76aA+6ybUGL/3JBnCtBX9Ay9/OWIpzKYWlVHMazvJ+WtHumfi+xxdPF440cWK7JCYtt8xDifew==", - "dev": true, - "requires": { - "icss-replace-symbols": "1.1.0", - "postcss": "6.0.1", - "postcss-modules-extract-imports": "1.1.0", - "postcss-modules-local-by-default": "1.2.0", - "postcss-modules-scope": "1.1.0", - "postcss-modules-values": "1.3.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - }, - "dependencies": { - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", - "dev": true - } - } - }, - "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 - }, - "has-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha512-DyYHfIYwAJmjAjSSPKANxI8bFY9YtFrgkAfinBojQ8YJTOuOuav64tMUJv584SES4xl74PmuaevIyaLESHdTAA==", - "dev": true - }, - "postcss": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.1.tgz", - "integrity": "sha512-VbGX1LQgQbf9l3cZ3qbUuC3hGqIEOGQFHAEHQ/Diaeo0yLgpgK5Rb8J+OcamIfQ9PbAU/fzBjVtQX3AhJHUvZw==", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "source-map": "^0.5.6", - "supports-color": "^3.2.3" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha512-Jds2VIYDrlp5ui7t8abHN2bjAu4LV/q4N2KivFPpGH0lrka0BMq/33AmECUXlKPcHigkNaqfXRENFju+rlcy+A==", - "dev": true, - "requires": { - "has-flag": "^1.0.0" - } - } - } - }, - "css-selector-tokenizer": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7.3.tgz", - "integrity": "sha512-jWQv3oCEL5kMErj4wRnK/OPoBi0D+P1FR2cDCKYPaMeD2eW3/mttav8HT4hT1CKopiJI/psEULjkClhvJo4Lvg==", - "dev": true, + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.6.tgz", + "integrity": "sha512-riRvo06crlE8HiqOwIpQhxwdOk4fOeR7FVM/wXoxchFEqMNUjvbs3bfo4OTgMEMHzppd4DxFBDbyySj8Cv781g==", "requires": { - "cssesc": "^3.0.0", - "fastparse": "^1.1.2" + "node-fetch": "^2.6.11" } }, - "css-tree": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", - "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", + "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, "requires": { - "mdn-data": "2.0.14", - "source-map": "^0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" } }, "cssesc": { @@ -12512,19 +12035,10 @@ "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", "dev": true }, - "csso": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", - "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", - "dev": true, - "requires": { - "css-tree": "^1.1.2" - } - }, "csstype": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz", - "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==" + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", + "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==" }, "damerau-levenshtein": { "version": "1.0.8", @@ -12534,66 +12048,35 @@ "peer": true }, "dayjs": { - "version": "1.11.7", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.7.tgz", - "integrity": "sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ==" + "version": "1.11.10", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz", + "integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==" }, "debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, "requires": { "ms": "2.1.2" } }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "dev": true - }, "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 }, - "deep-keys": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/deep-keys/-/deep-keys-0.5.0.tgz", - "integrity": "sha512-/80a4+9lbLj1hRxG0ULtEOGtbM4hN/5u1Vu6kc6ZkYePUq+ZhtboRIsWTVKplc2ET1xY2FMVwhyt46w9vPf9Rg==", - "dev": true - }, - "defaults": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", - "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", - "dev": true, - "requires": { - "clone": "^1.0.2" - } - }, "define-properties": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", - "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", + "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, "requires": { "has-property-descriptors": "^1.0.0", "object-keys": "^1.1.1" } }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" - }, - "detect-node": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.4.tgz", - "integrity": "sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==", - "dev": true - }, "dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -12628,44 +12111,44 @@ "dev": true }, "effector": { - "version": "22.4.0", - "resolved": "https://registry.npmjs.org/effector/-/effector-22.4.0.tgz", - "integrity": "sha512-WQ0rboUp1fvkzo2rPymtWzR9isUl8v9McGvBA4g8zvQaTgZnXQ1iCbNj2S54bADGpSNl1CYv1/61vvdbc5Goyw==" + "version": "22.8.7", + "resolved": "https://registry.npmjs.org/effector/-/effector-22.8.7.tgz", + "integrity": "sha512-vCevjxmFwnZJuRGtqjwfi+sHtu+7gK3qdbv4fxi/AsMdDtoMeoz9C3/28pjNABviZeEARj6ZfAHbNAq5i9d7RQ==" + }, + "effector-forms": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/effector-forms/-/effector-forms-1.3.4.tgz", + "integrity": "sha512-m/Swvhf6eDyEgYINULCXLZf9uhMMicYQs4Te3bg5Hx2WdUeq5Cts18QwHU+YxoTTJh06rptWbHk0QHHmI4uPuA==", + "requires": {} }, - "effector-inspector": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/effector-inspector/-/effector-inspector-0.8.2.tgz", - "integrity": "sha512-7pYH+S8APeiD6KYtHbVCE0YK0XXM0ug9z+izzbHulaiqIEahFbtWxl+cte3VOj7H54+hr+188qaTdQMW4aE8RA==", - "dev": true, - "requires": { - "foliage": "^0.201.0", - "forest": "^0.20.2" - } + "effector-localstorage": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/effector-localstorage/-/effector-localstorage-1.0.0.tgz", + "integrity": "sha512-SyJiKCHv05GPcWAC/lupQJWvp2EwY2QRfMuiy/JmuXxw++WUi5ozvxKrPT9ntRndn3AgD3S+LOPPwl7GWi/rzw==", + "requires": {} }, - "effector-logger": { - "version": "0.13.4", - "resolved": "https://registry.npmjs.org/effector-logger/-/effector-logger-0.13.4.tgz", - "integrity": "sha512-qswlayMgY+kH5FO/ttTWZgHEsMUhD67KHoh5ORlSRWxVR3CutdE0qQnfPcsBNrUTbzahEjPmLsdEICz3lhW2uw==", - "dev": true, + "effector-mui-snacks": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/effector-mui-snacks/-/effector-mui-snacks-1.0.0.tgz", + "integrity": "sha512-AY1ZlkV5/3yVoErF/8QDX95KjotygFWHh7GgxM5p5/cD/LsV/p7HYGy2rvTxqLrlKVxNtUGEvnzux3jwHYaNzg==", "requires": { - "detect-node": "2.0.4", - "effector-inspector": "^0.8.2", - "just-debounce-it": "^1.1.0", - "set-value": "4.0.1" + "classnames": "^2.3.2", + "patronum": "^1.18.0" } }, "effector-react": { - "version": "22.3.4", - "resolved": "https://registry.npmjs.org/effector-react/-/effector-react-22.3.4.tgz", - "integrity": "sha512-iyPMjnIW7pUoSuvxumAu4oRan4d8sbXmYPTlRXR75HOag2aH805m+xElyhyXCsQMXxQebjk7/GSC8Caeriv/+A==", + "version": "22.5.4", + "resolved": "https://registry.npmjs.org/effector-react/-/effector-react-22.5.4.tgz", + "integrity": "sha512-7HmtfD/vqmqvGnu6jMojmns9cxIW45JPBkGgHrwvbXGpbm0bz2fmVj6PIttv+Bamfmrf9FAy2bZhs+Rwj+3Mxw==", "requires": { "use-sync-external-store": "^1.0.0" } }, "electron-to-chromium": { - "version": "1.4.284", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz", - "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==" + "version": "1.4.562", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.562.tgz", + "integrity": "sha512-kMGVZLP65O2/oH7zzaoIA5hcr4/xPYO6Sa83FrIpWcd7YPPtSlxqwxTd8lJIwKxaiXM6FGsYK4ukyJ40XkW7jg==", + "dev": true }, "emoji-regex": { "version": "9.2.2", @@ -12673,23 +12156,6 @@ "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", "dev": true }, - "engine.io-client": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.2.3.tgz", - "integrity": "sha512-aXPtgF1JS3RuuKcpSrBtimSjYvrbhKW9froICH4s0F3XQWLxsKNxqzG39nnvQZQnva4CMvUK63T7shevxRyYHw==", - "requires": { - "@socket.io/component-emitter": "~3.1.0", - "debug": "~4.3.1", - "engine.io-parser": "~5.0.3", - "ws": "~8.2.3", - "xmlhttprequest-ssl": "~2.0.0" - } - }, - "engine.io-parser": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.4.tgz", - "integrity": "sha512-+nVFp+5z1E3HcToEnO7ZIj3g+3k9389DvWtvJZz0T6/eOCPIyyxehFcedoYrZQrp0LgQbD9pPXhpMBKMd5QURg==" - }, "error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -12699,35 +12165,61 @@ } }, "es-abstract": { - "version": "1.20.4", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.4.tgz", - "integrity": "sha512-0UtvRN79eMe2L+UNEF1BwRe364sj/DXhQ/k5FmivgoSdpM90b8Jc0mDzKMGo7QS0BVbOP/bTwBKNnDc9rNzaPA==", + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.1.tgz", + "integrity": "sha512-ioRRcXMO6OFyRpyzV3kE1IIBd4WG5/kltnzdxSCqoP8CMGs/Li+M1uF5o7lOkZVFjDs+NLesthnF66Pg/0q0Lw==", "dev": true, "requires": { + "array-buffer-byte-length": "^1.0.0", + "arraybuffer.prototype.slice": "^1.0.1", + "available-typed-arrays": "^1.0.5", "call-bind": "^1.0.2", + "es-set-tostringtag": "^2.0.1", "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", "function.prototype.name": "^1.1.5", - "get-intrinsic": "^1.1.3", + "get-intrinsic": "^1.2.1", "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.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.2", + "object-inspect": "^1.12.3", "object-keys": "^1.1.1", "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.4.3", + "regexp.prototype.flags": "^1.5.0", + "safe-array-concat": "^1.0.0", "safe-regex-test": "^1.0.0", - "string.prototype.trimend": "^1.0.5", - "string.prototype.trimstart": "^1.0.5", - "unbox-primitive": "^1.0.2" + "string.prototype.trim": "^1.2.7", + "string.prototype.trimend": "^1.0.6", + "string.prototype.trimstart": "^1.0.6", + "typed-array-buffer": "^1.0.0", + "typed-array-byte-length": "^1.0.0", + "typed-array-byte-offset": "^1.0.0", + "typed-array-length": "^1.0.4", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.10" + } + }, + "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, + "requires": { + "get-intrinsic": "^1.1.3", + "has": "^1.0.3", + "has-tostringtag": "^1.0.0" } }, "es-shim-unscopables": { @@ -12751,39 +12243,40 @@ } }, "esbuild": { - "version": "0.16.3", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.16.3.tgz", - "integrity": "sha512-71f7EjPWTiSguen8X/kxEpkAS7BFHwtQKisCDDV3Y4GLGWBaoSCyD5uXkaUew6JDzA9FEN1W23mdnSwW9kqCeg==", - "dev": true, - "requires": { - "@esbuild/android-arm": "0.16.3", - "@esbuild/android-arm64": "0.16.3", - "@esbuild/android-x64": "0.16.3", - "@esbuild/darwin-arm64": "0.16.3", - "@esbuild/darwin-x64": "0.16.3", - "@esbuild/freebsd-arm64": "0.16.3", - "@esbuild/freebsd-x64": "0.16.3", - "@esbuild/linux-arm": "0.16.3", - "@esbuild/linux-arm64": "0.16.3", - "@esbuild/linux-ia32": "0.16.3", - "@esbuild/linux-loong64": "0.16.3", - "@esbuild/linux-mips64el": "0.16.3", - "@esbuild/linux-ppc64": "0.16.3", - "@esbuild/linux-riscv64": "0.16.3", - "@esbuild/linux-s390x": "0.16.3", - "@esbuild/linux-x64": "0.16.3", - "@esbuild/netbsd-x64": "0.16.3", - "@esbuild/openbsd-x64": "0.16.3", - "@esbuild/sunos-x64": "0.16.3", - "@esbuild/win32-arm64": "0.16.3", - "@esbuild/win32-ia32": "0.16.3", - "@esbuild/win32-x64": "0.16.3" + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", + "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", + "dev": true, + "requires": { + "@esbuild/android-arm": "0.18.20", + "@esbuild/android-arm64": "0.18.20", + "@esbuild/android-x64": "0.18.20", + "@esbuild/darwin-arm64": "0.18.20", + "@esbuild/darwin-x64": "0.18.20", + "@esbuild/freebsd-arm64": "0.18.20", + "@esbuild/freebsd-x64": "0.18.20", + "@esbuild/linux-arm": "0.18.20", + "@esbuild/linux-arm64": "0.18.20", + "@esbuild/linux-ia32": "0.18.20", + "@esbuild/linux-loong64": "0.18.20", + "@esbuild/linux-mips64el": "0.18.20", + "@esbuild/linux-ppc64": "0.18.20", + "@esbuild/linux-riscv64": "0.18.20", + "@esbuild/linux-s390x": "0.18.20", + "@esbuild/linux-x64": "0.18.20", + "@esbuild/netbsd-x64": "0.18.20", + "@esbuild/openbsd-x64": "0.18.20", + "@esbuild/sunos-x64": "0.18.20", + "@esbuild/win32-arm64": "0.18.20", + "@esbuild/win32-ia32": "0.18.20", + "@esbuild/win32-x64": "0.18.20" } }, "escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true }, "escape-string-regexp": { "version": "4.0.0", @@ -12791,49 +12284,47 @@ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" }, "eslint": { - "version": "8.29.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.29.0.tgz", - "integrity": "sha512-isQ4EEiyUjZFbEKvEGJKKGBwXtvXX+zJbkVKCgTuB9t/+jUBcy8avhkEwWJecI15BkRkOYmvIM5ynbhRjEkoeg==", + "version": "8.51.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.51.0.tgz", + "integrity": "sha512-2WuxRZBrlwnXi+/vFSJyjMqrNjtJqiasMzehF0shoLaW7DzS3/9Yvrmq5JiT66+pNjiX4UBnLDiKHcWAr/OInA==", "dev": true, "requires": { - "@eslint/eslintrc": "^1.3.3", - "@humanwhocodes/config-array": "^0.11.6", + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.2", + "@eslint/js": "8.51.0", + "@humanwhocodes/config-array": "^0.11.11", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", - "ajv": "^6.10.0", + "ajv": "^6.12.4", "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.1.1", - "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.3.0", - "espree": "^9.4.0", - "esquery": "^1.4.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "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.15.0", - "grapheme-splitter": "^1.0.4", + "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-sdsl": "^4.1.4", "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", - "regexpp": "^3.2.0", + "optionator": "^0.9.3", "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", "text-table": "^0.2.0" }, "dependencies": { @@ -12871,16 +12362,6 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "eslint-scope": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", - "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - } - }, "glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", @@ -12891,9 +12372,9 @@ } }, "globals": { - "version": "13.18.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.18.0.tgz", - "integrity": "sha512-/mR4KI8Ps2spmoc0Ulu9L7agOF0du1CZNQ3dke8yItYlyKNmGrkONemBbd6V8UTc1Wgcqn21t3WYB7dbRmh6/A==", + "version": "13.19.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.19.0.tgz", + "integrity": "sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==", "dev": true, "requires": { "type-fest": "^0.20.2" @@ -12913,12 +12394,6 @@ "requires": { "has-flag": "^4.0.0" } - }, - "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 } } }, @@ -12946,20 +12421,21 @@ } }, "eslint-config-prettier": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz", - "integrity": "sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.0.0.tgz", + "integrity": "sha512-IcJsTkJae2S35pRsRAwoCE+925rJJStOdkKnLVgtE+tEpqU0EVVM7OqrwxqgptKdX29NUwC82I5pXsGFIgSevw==", "dev": true, "requires": {} }, "eslint-import-resolver-node": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", - "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", "dev": true, "requires": { "debug": "^3.2.7", - "resolve": "^1.20.0" + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" }, "dependencies": { "debug": { @@ -12974,9 +12450,9 @@ } }, "eslint-module-utils": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.4.tgz", - "integrity": "sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==", + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz", + "integrity": "sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==", "dev": true, "requires": { "debug": "^3.2.7" @@ -12993,43 +12469,111 @@ } } }, + "eslint-plugin-boundaries": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-boundaries/-/eslint-plugin-boundaries-3.4.0.tgz", + "integrity": "sha512-bKB/XMu+zx14DCVkxe2yzkKgAoJQn+J7p0kmZm53/JzADbOdK5irhXG1THs92iCpgmTKtoQPjrGg3PA2FUwq6A==", + "dev": true, + "requires": { + "chalk": "4.1.2", + "eslint-import-resolver-node": "0.3.9", + "eslint-module-utils": "2.8.0", + "is-core-module": "2.13.0", + "micromatch": "4.0.5" + }, + "dependencies": { + "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, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "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, + "requires": { + "color-name": "~1.1.4" + } + }, + "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 + }, + "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 + }, + "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, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, "eslint-plugin-effector": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-effector/-/eslint-plugin-effector-0.10.3.tgz", - "integrity": "sha512-ELDEwYSERD4eHRWEthlQilNfIrYZwQ2poeGBfX05YVy1vIc9ZhIDa8jP7v9djnvRSSJ4gFu4qQQOoau7O33kaw==", + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-effector/-/eslint-plugin-effector-0.11.0.tgz", + "integrity": "sha512-iujBwqh8z09lxrnTF3jAj2WHwxdKYWzf2DXn6ambdBjx3wgHgLt2vjpzctXxWR1+PPyoj3GyQYY7tsnc/RTNTw==", "dev": true, "requires": { "prettier": "^2.3.2" } }, "eslint-plugin-import": { - "version": "2.26.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz", - "integrity": "sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==", + "version": "2.28.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.28.1.tgz", + "integrity": "sha512-9I9hFlITvOV55alzoKBI+K9q74kv0iKMeY6av5+umsNwayt59fz692daGyjR+oStBQgx6nwR9rXldDev3Clw+A==", "dev": true, "requires": { - "array-includes": "^3.1.4", - "array.prototype.flat": "^1.2.5", - "debug": "^2.6.9", + "array-includes": "^3.1.6", + "array.prototype.findlastindex": "^1.2.2", + "array.prototype.flat": "^1.3.1", + "array.prototype.flatmap": "^1.3.1", + "debug": "^3.2.7", "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.6", - "eslint-module-utils": "^2.7.3", + "eslint-import-resolver-node": "^0.3.7", + "eslint-module-utils": "^2.8.0", "has": "^1.0.3", - "is-core-module": "^2.8.1", + "is-core-module": "^2.13.0", "is-glob": "^4.0.3", "minimatch": "^3.1.2", - "object.values": "^1.1.5", - "resolve": "^1.22.0", - "tsconfig-paths": "^3.14.1" + "object.fromentries": "^2.0.6", + "object.groupby": "^1.0.0", + "object.values": "^1.1.6", + "semver": "^6.3.1", + "tsconfig-paths": "^3.14.2" }, "dependencies": { "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "requires": { - "ms": "2.0.0" + "ms": "^2.1.1" } }, "doctrine": { @@ -13040,12 +12584,6 @@ "requires": { "esutils": "^2.0.2" } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true } } }, @@ -13127,68 +12665,43 @@ "requires": {} }, "eslint-plugin-sonarjs": { - "version": "0.17.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-sonarjs/-/eslint-plugin-sonarjs-0.17.0.tgz", - "integrity": "sha512-jtGtxI49UbJJeJj7CVRLI3+LLH+y+hkR3GOOwM7vBbci9DEFIRGCWvEd2BJScrzltZ6D6iubukTAfc9cyG7sdw==", + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-sonarjs/-/eslint-plugin-sonarjs-0.21.0.tgz", + "integrity": "sha512-oezUDfFT5S6j3rQheZ4DLPrbetPmMS7zHIKWGHr0CM3g5JgyZroz1FpIKa4jV83NsGpmgIeagpokWDKIJzRQmw==", "dev": true, "requires": {} }, "eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, "requires": { "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "dependencies": { - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - } - } - }, - "eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^2.0.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true - } + "estraverse": "^5.2.0" } }, "eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true }, "espree": { - "version": "9.4.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz", - "integrity": "sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==", + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, "requires": { - "acorn": "^8.8.0", + "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.3.0" + "eslint-visitor-keys": "^3.4.1" } }, "esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", "dev": true, "requires": { "estraverse": "^5.1.0" @@ -13221,49 +12734,27 @@ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true }, + "eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "dev": true + }, "execa": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-6.1.0.tgz", - "integrity": "sha512-QVWlX2e50heYJcCPG0iWtf8r0xjEYfz/OYLGDYH+IyjWezzPNxz63qNFOu0l4YftGWuizFVZHHs8PrLU5p2IDA==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", "dev": true, "requires": { "cross-spawn": "^7.0.3", - "get-stream": "^6.0.1", - "human-signals": "^3.0.1", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", "is-stream": "^3.0.0", "merge-stream": "^2.0.0", "npm-run-path": "^5.1.0", "onetime": "^6.0.0", - "signal-exit": "^3.0.7", + "signal-exit": "^4.1.0", "strip-final-newline": "^3.0.0" - }, - "dependencies": { - "mimic-fn": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", - "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", - "dev": true - }, - "onetime": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", - "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", - "dev": true, - "requires": { - "mimic-fn": "^4.0.0" - } - } - } - }, - "external-editor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", - "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", - "dev": true, - "requires": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" } }, "fast-deep-equal": { @@ -13273,9 +12764,9 @@ "dev": true }, "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==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", + "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", "dev": true, "requires": { "@nodelib/fs.stat": "^2.0.2", @@ -13297,12 +12788,6 @@ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, - "fastparse": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.2.tgz", - "integrity": "sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==", - "dev": true - }, "fastq": { "version": "1.13.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", @@ -13312,24 +12797,6 @@ "reusify": "^1.0.4" } }, - "figures": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-5.0.0.tgz", - "integrity": "sha512-ej8ksPF4x6e5wvK9yevct0UCXh8TTFlWGVLlgjZuoBH1HwjIfKE/IdL5mq89sFA7zELi1VhKpmtDnrs7zWyeyg==", - "dev": true, - "requires": { - "escape-string-regexp": "^5.0.0", - "is-unicode-supported": "^1.2.0" - }, - "dependencies": { - "escape-string-regexp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", - "dev": true - } - } - }, "file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -13379,50 +12846,29 @@ "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", "dev": true }, - "foliage": { - "version": "0.201.0", - "resolved": "https://registry.npmjs.org/foliage/-/foliage-0.201.0.tgz", - "integrity": "sha512-RkgGPf0If28rHVfgbjFUHINpMyba0RfiDdtSl0AYED4QGe3il2Y/m/G4+dvI5A9y5EFdBYdfqNZbtoJJiyC4pg==", + "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, "requires": { - "autoprefixer": "^10.2.4", - "csso": "^4.2.0", - "postcss": "^8.2.6", - "postcss-nested": "^5.0.3" + "is-callable": "^1.1.3" } }, - "follow-redirects": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", - "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==" - }, - "forest": { - "version": "0.20.3", - "resolved": "https://registry.npmjs.org/forest/-/forest-0.20.3.tgz", - "integrity": "sha512-gyZAzoDhxRwYEcRIF8TJ2dqQaHWCwZU2Bq8FzSifqPvje+eLAISnd7QEvKlmwINftQFbrjgyESIIeCk7Vr7k7Q==", + "foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", "dev": true, - "requires": {} - }, - "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==", "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" } }, - "fraction.js": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz", - "integrity": "sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==", - "dev": true - }, "fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.1.1.tgz", + "integrity": "sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==", "dev": true, "requires": { "graceful-fs": "^4.2.0", @@ -13472,39 +12918,11 @@ "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", "dev": true }, - "generate-react-cli": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/generate-react-cli/-/generate-react-cli-8.0.1.tgz", - "integrity": "sha512-7M7lk1nPsO5sukPeQvZeXfFeRuy5BNtmjiRBkExhr4LgpsSpxCpzydfWeWxYyWdxXM2cZX+aWwml+exLfs6nRw==", - "dev": true, - "requires": { - "chalk": "5.1.2", - "commander": "9.4.1", - "deep-keys": "0.5.0", - "fs-extra": "10.1.0", - "inquirer": "9.1.4", - "lodash": "4.17.21", - "replace": "1.2.2" - }, - "dependencies": { - "chalk": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.1.2.tgz", - "integrity": "sha512-E5CkT4jWURs1Vy5qGJye+XwCkNj7Od3Af7CP6SujMetSMkLs8Do2RWJK5yx1wamHV/op8Rz+9rltjaTQWDnEFQ==", - "dev": true - }, - "commander": { - "version": "9.4.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-9.4.1.tgz", - "integrity": "sha512-5EEkTNyHNGFPD2H+c/dXXfQZYa/scCKasxWcXJaWnNJ99pnQN9Vnmqow+p+PlFPE63Q6mThaZws1T+HxfpgtPw==", - "dev": true - } - } - }, "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==" + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true }, "get-caller-file": { "version": "2.0.5", @@ -13513,20 +12931,21 @@ "dev": true }, "get-intrinsic": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", - "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", + "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, "requires": { "function-bind": "^1.1.1", "has": "^1.0.3", + "has-proto": "^1.0.1", "has-symbols": "^1.0.3" } }, "get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", "dev": true }, "get-symbol-description": { @@ -13565,7 +12984,17 @@ "globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + }, + "globalthis": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", + "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3" + } }, "globby": { "version": "11.1.0", @@ -13589,41 +13018,33 @@ } } }, + "gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.3" + } + }, "graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "dev": true }, - "grapheme-splitter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", - "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", "dev": true }, "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", - "dev": true - } + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "^1.1.1" } }, "has-bigints": { @@ -13646,6 +13067,12 @@ "get-intrinsic": "^1.1.1" } }, + "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 + }, "has-symbols": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", @@ -13693,48 +13120,39 @@ } }, "human-signals": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-3.0.1.tgz", - "integrity": "sha512-rQLskxnM/5OCldHo+wNXbpVgDn5A17CUoKX+7Sokwaknlq7CdSnphy0W39GU8dw59XiCXmFXDg4fRuckQRKewQ==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", "dev": true }, "husky": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/husky/-/husky-8.0.2.tgz", - "integrity": "sha512-Tkv80jtvbnkK3mYWxPZePGFpQ/tT3HNSs/sasF9P2YfkMezDl3ON37YN6jUUI4eTg5LcyVynlb6r4eyvOmspvg==", + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/husky/-/husky-8.0.3.tgz", + "integrity": "sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg==", "dev": true }, "i18next": { - "version": "22.1.5", - "resolved": "https://registry.npmjs.org/i18next/-/i18next-22.1.5.tgz", - "integrity": "sha512-Mjj45PbpZByE+c6ddLEkkj0LUyzJP1cRGeC/+O6mvp1+GAwW7rIx6aOPW9+Zxe+JO3EcJCAkibwbZrgBRF/qRA==", + "version": "23.6.0", + "resolved": "https://registry.npmjs.org/i18next/-/i18next-23.6.0.tgz", + "integrity": "sha512-z0Cxr0MGkt+kli306WS4nNNM++9cgt2b2VCMprY92j+AIab/oclgPxdwtTZVLP1zn5t5uo8M6uLsZmYrcjr3HA==", "requires": { - "@babel/runtime": "^7.20.6" + "@babel/runtime": "^7.22.5" } }, "i18next-browser-languagedetector": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/i18next-browser-languagedetector/-/i18next-browser-languagedetector-7.0.1.tgz", - "integrity": "sha512-Pa5kFwaczXJAeHE56CHG2aWzFBMJNUNghf0Pm4SwSrEMps/PTKqW90EYWlIvhuYStf3Sn1K0vw+gH3+TLdkH1g==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/i18next-browser-languagedetector/-/i18next-browser-languagedetector-7.1.0.tgz", + "integrity": "sha512-cr2k7u1XJJ4HTOjM9GyOMtbOA47RtUoWRAtt52z43r3AoMs2StYKyjS3URPhzHaf+mn10hY9dZWamga5WPQjhA==", "requires": { "@babel/runtime": "^7.19.4" } }, "i18next-http-backend": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/i18next-http-backend/-/i18next-http-backend-2.0.2.tgz", - "integrity": "sha512-TFiIqitZEc8+jyca31EW5ef5PjUYtUGGfL8c8FJwiiHguq5OQTqoR3mxpKqaCPiikg+cxSgXtNA2gZPCu0aryQ==", - "requires": { - "cross-fetch": "3.1.5" - } - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/i18next-http-backend/-/i18next-http-backend-2.2.2.tgz", + "integrity": "sha512-mJu4ZqzDtBiU3O4GV9AbK5ekEqoDMdMnCl3pkdXmb5b8yoIH//u8FsmIe6C5qXb3teZu+j6VMi20tjUgzeABiw==", "requires": { - "safer-buffer": ">= 2.1.2 < 3" + "cross-fetch": "3.1.6" } }, "icss-replace-symbols": { @@ -13743,16 +13161,17 @@ "integrity": "sha512-chIaY3Vh2mh2Q3RGXttaDIzeiPvaVXJ+C4DAh/w3c37SKZ/U6PGMmuicR2EQQp9bKG8zLMCl7I+PtIoOOPp8Gg==", "dev": true }, - "ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true + "icss-utils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", + "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", + "dev": true, + "requires": {} }, "ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", "dev": true }, "import-fresh": { @@ -13770,12 +13189,6 @@ "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true }, - "indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true - }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -13792,61 +13205,26 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, - "inquirer": { - "version": "9.1.4", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-9.1.4.tgz", - "integrity": "sha512-9hiJxE5gkK/cM2d1mTEnuurGTAoHebbkX0BYl3h7iEg7FYfuNIom+nDfBCSWtvSnoSrWCeBxqqBZu26xdlJlXA==", + "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, "requires": { - "ansi-escapes": "^6.0.0", - "chalk": "^5.1.2", - "cli-cursor": "^4.0.0", - "cli-width": "^4.0.0", - "external-editor": "^3.0.3", - "figures": "^5.0.0", - "lodash": "^4.17.21", - "mute-stream": "0.0.8", - "ora": "^6.1.2", - "run-async": "^2.4.0", - "rxjs": "^7.5.7", - "string-width": "^5.1.2", - "strip-ansi": "^7.0.1", - "through": "^2.3.6", - "wrap-ansi": "^8.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true - }, - "chalk": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.1.2.tgz", - "integrity": "sha512-E5CkT4jWURs1Vy5qGJye+XwCkNj7Od3Af7CP6SujMetSMkLs8Do2RWJK5yx1wamHV/op8Rz+9rltjaTQWDnEFQ==", - "dev": true - }, - "strip-ansi": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz", - "integrity": "sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==", - "dev": true, - "requires": { - "ansi-regex": "^6.0.1" - } - } + "get-intrinsic": "^1.2.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" } }, - "internal-slot": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", - "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "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, "requires": { - "get-intrinsic": "^1.1.0", - "has": "^1.0.3", - "side-channel": "^1.0.4" + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.0", + "is-typed-array": "^1.1.10" } }, "is-arrayish": { @@ -13889,9 +13267,9 @@ "dev": true }, "is-core-module": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", - "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz", + "integrity": "sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==", "requires": { "has": "^1.0.3" } @@ -13912,9 +13290,9 @@ "dev": true }, "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", + "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", "dev": true }, "is-glob": { @@ -13926,12 +13304,6 @@ "is-extglob": "^2.1.1" } }, - "is-interactive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz", - "integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==", - "dev": true - }, "is-negative-zero": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", @@ -13959,15 +13331,6 @@ "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", "dev": true }, - "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==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, "is-regex": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", @@ -14017,11 +13380,14 @@ "integrity": "sha512-vIZ7HTXAoRoIwYSsTnxb0sg9L6rth+JOulNcavsbskQkCIWoSM2cjFOWZs4wGziGZER+Xgs/HXiCQZgiL8ppxQ==", "dev": true }, - "is-unicode-supported": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", - "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==", - "dev": true + "is-typed-array": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", + "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", + "dev": true, + "requires": { + "which-typed-array": "^1.1.11" + } }, "is-weakref": { "version": "1.0.2", @@ -14032,36 +13398,40 @@ "call-bind": "^1.0.2" } }, + "isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", - "dev": true + "jackspeak": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", + "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", + "dev": true, + "requires": { + "@isaacs/cliui": "^8.0.2", + "@pkgjs/parseargs": "^0.11.0" + } }, "joi": { - "version": "17.7.0", - "resolved": "https://registry.npmjs.org/joi/-/joi-17.7.0.tgz", - "integrity": "sha512-1/ugc8djfn93rTE3WRKdCzGGt/EtiYKxITMO4Wiv6q5JL1gl9ePt4kBsl1S499nbosspfctIQTpYIhSmHA3WAg==", + "version": "17.11.0", + "resolved": "https://registry.npmjs.org/joi/-/joi-17.11.0.tgz", + "integrity": "sha512-NgB+lZLNoqISVy1rZocE9PZI36bL/77ie924Ri43yEvi9GUUMPeyVIr8KdFTMUlby1p0PBYMk9spIxEUQYqrJQ==", "requires": { "@hapi/hoek": "^9.0.0", "@hapi/topo": "^5.0.0", "@sideway/address": "^4.1.3", - "@sideway/formula": "^3.0.0", + "@sideway/formula": "^3.0.1", "@sideway/pinpoint": "^2.0.0" } }, - "js-sdsl": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.5.tgz", - "integrity": "sha512-08bOAKweV2NUC1wqTtf3qZlnpOX/R2DU9ikpjOHs0H+ibQv3zpncVQg6um4uYtRtrwIX8M4Nh3ytK4HGlYAq7Q==", - "dev": true - }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -14079,7 +13449,8 @@ "jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true }, "json-parse-even-better-errors": { "version": "2.3.1", @@ -14099,9 +13470,10 @@ "dev": true }, "json5": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", - "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==" + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true }, "jsonfile": { "version": "6.1.0", @@ -14124,11 +13496,10 @@ "object.assign": "^4.1.3" } }, - "just-debounce-it": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/just-debounce-it/-/just-debounce-it-1.5.0.tgz", - "integrity": "sha512-itSWJS5d2DTSCizVJ2Z0Djx/dGmUGfZe7WNfUfVP23+htGcIcPHbEjL4eB8ljojTs/+oYwLexImRRCP0A2WXjA==", - "dev": true + "ky": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ky/-/ky-1.1.0.tgz", + "integrity": "sha512-n/rS/Yw+pc/j61kl353yIhxpM/FN0VidhPeiMv6Y/QyyCUpSJtHtHlX655wYolZ/Wc3BKO4Q5syWKfzJ5CT7Bg==" }, "language-subtag-registry": { "version": "0.3.22", @@ -14158,9 +13529,9 @@ } }, "lilconfig": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.6.tgz", - "integrity": "sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", + "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", "dev": true }, "lines-and-columns": { @@ -14169,129 +13540,55 @@ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" }, "lint-staged": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-13.1.0.tgz", - "integrity": "sha512-pn/sR8IrcF/T0vpWLilih8jmVouMlxqXxKuAojmbiGX5n/gDnz+abdPptlj0vYnbfE0SQNl3CY/HwtM0+yfOVQ==", + "version": "15.0.2", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-15.0.2.tgz", + "integrity": "sha512-vnEy7pFTHyVuDmCAIFKR5QDO8XLVlPFQQyujQ/STOxe40ICWqJ6knS2wSJ/ffX/Lw0rz83luRDh+ET7toN+rOw==", "dev": true, "requires": { - "cli-truncate": "^3.1.0", - "colorette": "^2.0.19", - "commander": "^9.4.1", - "debug": "^4.3.4", - "execa": "^6.1.0", - "lilconfig": "2.0.6", - "listr2": "^5.0.5", - "micromatch": "^4.0.5", - "normalize-path": "^3.0.0", - "object-inspect": "^1.12.2", - "pidtree": "^0.6.0", - "string-argv": "^0.3.1", - "yaml": "^2.1.3" + "chalk": "5.3.0", + "commander": "11.1.0", + "debug": "4.3.4", + "execa": "8.0.1", + "lilconfig": "2.1.0", + "listr2": "7.0.2", + "micromatch": "4.0.5", + "pidtree": "0.6.0", + "string-argv": "0.3.2", + "yaml": "2.3.3" }, "dependencies": { + "chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "dev": true + }, "commander": { - "version": "9.4.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-9.4.1.tgz", - "integrity": "sha512-5EEkTNyHNGFPD2H+c/dXXfQZYa/scCKasxWcXJaWnNJ99pnQN9Vnmqow+p+PlFPE63Q6mThaZws1T+HxfpgtPw==", + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", + "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", "dev": true }, "yaml": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.1.3.tgz", - "integrity": "sha512-AacA8nRULjKMX2DvWvOAdBZMOfQlypSFkjcOcu9FalllIDJ1kvlREzcdIZmidQUqqeMv7jorHjq2HlLv/+c2lg==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.3.tgz", + "integrity": "sha512-zw0VAJxgeZ6+++/su5AFoqBbZbrEakwu+X0M5HmcwUiBL7AzcuPKjj5we4xfQLp78LkEMpD0cOnUhmgOVy3KdQ==", "dev": true } } }, "listr2": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-5.0.6.tgz", - "integrity": "sha512-u60KxKBy1BR2uLJNTWNptzWQ1ob/gjMzIJPZffAENzpZqbMZ/5PrXXOomDcevIS/+IB7s1mmCEtSlT2qHWMqag==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-7.0.2.tgz", + "integrity": "sha512-rJysbR9GKIalhTbVL2tYbF2hVyDnrf7pFUZBwjPaMIdadYHmeT+EVi/Bu3qd7ETQPahTotg2WRCatXwRBW554g==", "dev": true, "requires": { - "cli-truncate": "^2.1.0", - "colorette": "^2.0.19", - "log-update": "^4.0.0", - "p-map": "^4.0.0", + "cli-truncate": "^3.1.0", + "colorette": "^2.0.20", + "eventemitter3": "^5.0.1", + "log-update": "^5.0.1", "rfdc": "^1.3.0", - "rxjs": "^7.5.7", - "through": "^2.3.8", - "wrap-ansi": "^7.0.0" - }, - "dependencies": { - "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, - "requires": { - "color-convert": "^2.0.1" - } - }, - "cli-truncate": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", - "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", - "dev": true, - "requires": { - "slice-ansi": "^3.0.0", - "string-width": "^4.2.0" - } - }, - "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, - "requires": { - "color-name": "~1.1.4" - } - }, - "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 - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "slice-ansi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", - "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - } - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - } + "wrap-ansi": "^8.1.0" } }, "locate-path": { @@ -14303,149 +13600,44 @@ "p-locate": "^5.0.0" } }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, "lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", - "dev": true - }, - "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 - }, - "log-symbols": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-5.1.0.tgz", - "integrity": "sha512-l0x2DvrW294C9uDCoQe1VSU4gf529FkSZ6leBl4TiqZH/e+0R7hSfHQBNut2mNygDgHwvYHfFLn6Oxb3VWj2rA==", - "dev": true, - "requires": { - "chalk": "^5.0.0", - "is-unicode-supported": "^1.1.0" - }, - "dependencies": { - "chalk": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.1.2.tgz", - "integrity": "sha512-E5CkT4jWURs1Vy5qGJye+XwCkNj7Od3Af7CP6SujMetSMkLs8Do2RWJK5yx1wamHV/op8Rz+9rltjaTQWDnEFQ==", - "dev": true - } - } - }, - "log-update": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", - "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", - "dev": true, - "requires": { - "ansi-escapes": "^4.3.0", - "cli-cursor": "^3.1.0", - "slice-ansi": "^4.0.0", - "wrap-ansi": "^6.2.0" - }, - "dependencies": { - "ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, - "requires": { - "type-fest": "^0.21.3" - } - }, - "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, - "requires": { - "color-convert": "^2.0.1" - } - }, - "cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "dev": true, - "requires": { - "restore-cursor": "^3.1.0" - } - }, - "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, - "requires": { - "color-name": "~1.1.4" - } - }, - "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 - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "dev": true, - "requires": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - } - }, - "slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - } - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true + }, + "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 + }, + "log-update": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-5.0.1.tgz", + "integrity": "sha512-5UtUDQ/6edw4ofyljDNcOVJQ4c7OjDro4h3y8e1GQL5iYElYclVHJ3zeWchylvMaKnDbDilC8irOVyexnA/Slw==", + "dev": true, + "requires": { + "ansi-escapes": "^5.0.0", + "cli-cursor": "^4.0.0", + "slice-ansi": "^5.0.0", + "strip-ansi": "^7.0.1", + "wrap-ansi": "^8.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", "dev": true }, - "wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dev": true, "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" + "ansi-regex": "^6.0.1" } } } @@ -14459,21 +13651,12 @@ } }, "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, - "magic-string": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.27.0.tgz", - "integrity": "sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==", + "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, "requires": { - "@jridgewell/sourcemap-codec": "^1.4.13" + "yallist": "^3.0.2" } }, "make-dir": { @@ -14494,12 +13677,6 @@ } } }, - "mdn-data": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", - "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", - "dev": true - }, "merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -14522,23 +13699,10 @@ "picomatch": "^2.3.1" } }, - "mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" - }, - "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==", - "requires": { - "mime-db": "1.52.0" - } - }, "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", "dev": true }, "minimatch": { @@ -14551,32 +13715,33 @@ } }, "minimist": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", - "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true + }, + "minipass": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", "dev": true }, "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", + "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", "dev": true }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "mute-stream": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", - "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, "nanoid": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", - "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", + "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", "dev": true }, "natural-compare": { @@ -14585,24 +13750,19 @@ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, - "natural-compare-lite": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", - "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", - "dev": true - }, "node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", "requires": { "whatwg-url": "^5.0.0" } }, "node-releases": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", - "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==" + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", + "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==", + "dev": true }, "normalize-path": { "version": "3.0.0", @@ -14610,12 +13770,6 @@ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true }, - "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==", - "dev": true - }, "npm-run-path": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz", @@ -14639,9 +13793,9 @@ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" }, "object-inspect": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", - "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", + "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 }, "object-keys": { @@ -14678,13 +13832,24 @@ "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.6.tgz", "integrity": "sha512-VciD13dswC4j1Xt5394WR4MzmAQmlgN72phd/riNp9vtD7tp4QQWJ0R4wvclXcafgcYK8veHRed2W6XeGBvcfg==", "dev": true, - "peer": true, "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.4", "es-abstract": "^1.20.4" } }, + "object.groupby": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.1.tgz", + "integrity": "sha512-HqaQtqLnp/8Bn4GL16cj+CUYbnpe1bh0TtEaWvybszDG4tgxCJuRpV8VGuvNaI1fAnI4lUJzDG55MXcOH4JZcQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1" + } + }, "object.hasown": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.2.tgz", @@ -14717,74 +13882,28 @@ } }, "onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", "dev": true, "requires": { - "mimic-fn": "^2.1.0" + "mimic-fn": "^4.0.0" } }, "optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", "dev": true, "requires": { + "@aashutoshrathi/word-wrap": "^1.2.3", "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" - } - }, - "ora": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/ora/-/ora-6.1.2.tgz", - "integrity": "sha512-EJQ3NiP5Xo94wJXIzAyOtSb0QEIAUu7m8t6UZ9krbz0vAJqr92JpcK/lEXg91q6B9pEGqrykkd2EQplnifDSBw==", - "dev": true, - "requires": { - "bl": "^5.0.0", - "chalk": "^5.0.0", - "cli-cursor": "^4.0.0", - "cli-spinners": "^2.6.1", - "is-interactive": "^2.0.0", - "is-unicode-supported": "^1.1.0", - "log-symbols": "^5.1.0", - "strip-ansi": "^7.0.1", - "wcwidth": "^1.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true - }, - "chalk": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.1.2.tgz", - "integrity": "sha512-E5CkT4jWURs1Vy5qGJye+XwCkNj7Od3Af7CP6SujMetSMkLs8Do2RWJK5yx1wamHV/op8Rz+9rltjaTQWDnEFQ==", - "dev": true - }, - "strip-ansi": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz", - "integrity": "sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==", - "dev": true, - "requires": { - "ansi-regex": "^6.0.1" - } - } + "type-check": "^0.4.0" } }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", - "dev": true - }, "p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -14803,21 +13922,6 @@ "p-limit": "^3.0.2" } }, - "p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "dev": true, - "requires": { - "aggregate-error": "^3.0.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, "parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -14860,6 +13964,24 @@ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, + "path-scurry": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", + "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", + "dev": true, + "requires": { + "lru-cache": "^9.1.1 || ^10.0.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "dependencies": { + "lru-cache": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.0.1.tgz", + "integrity": "sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==", + "dev": true + } + } + }, "path-to-regexp": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.1.tgz", @@ -14870,10 +13992,17 @@ "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==" }, + "patronum": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/patronum/-/patronum-1.20.0.tgz", + "integrity": "sha512-UsUR8nUbSPJ0kEQPNorZ/0+Rwlk+c45O4BfqlLHAdRQvx1C7ZSfC9txfPwJo+fajRtzVLebZm1m+67+Ke9SgdA==", + "requires": {} + }, "picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true }, "picomatch": { "version": "2.3.1", @@ -14894,144 +14023,56 @@ "dev": true }, "postcss": { - "version": "8.4.19", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.19.tgz", - "integrity": "sha512-h+pbPsyhlYj6N2ozBmHhHrs9DzGmbaarbLvWipMRO7RLS+v4onj26MPFXA5OBYFxyqYhUJK456SwDcY9H2/zsA==", + "version": "8.4.29", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.29.tgz", + "integrity": "sha512-cbI+jaqIeu/VGqXEarWkRCCffhjgXc0qjBtXpqJhTBohMUjUQnbBr0xqX3vEKudc4iviTewcJo5ajcec5+wdJw==", "dev": true, "requires": { - "nanoid": "^3.3.4", + "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" } }, "postcss-modules-extract-imports": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.1.0.tgz", - "integrity": "sha512-zF9+UIEvtpeqMGxhpeT9XaIevQSrBBCz9fi7SwfkmjVacsSj8DY5eFVgn+wY8I9vvdDDwK5xC8Myq4UkoLFIkA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", + "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", "dev": true, - "requires": { - "postcss": "^6.0.1" - }, - "dependencies": { - "postcss": { - "version": "6.0.23", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", - "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", - "dev": true, - "requires": { - "chalk": "^2.4.1", - "source-map": "^0.6.1", - "supports-color": "^5.4.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } + "requires": {} }, "postcss-modules-local-by-default": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-1.2.0.tgz", - "integrity": "sha512-X4cquUPIaAd86raVrBwO8fwRfkIdbwFu7CTfEOjiZQHVQwlHRSkTgH5NLDmMm5+1hQO8u6dZ+TOOJDbay1hYpA==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.3.tgz", + "integrity": "sha512-2/u2zraspoACtrbFRnTijMiQtb4GW4BvatjaG/bCjYQo8kLTdevCUlwuBHx2sCnSyrI3x3qj4ZK1j5LQBgzmwA==", "dev": true, "requires": { - "css-selector-tokenizer": "^0.7.0", - "postcss": "^6.0.1" - }, - "dependencies": { - "postcss": { - "version": "6.0.23", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", - "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", - "dev": true, - "requires": { - "chalk": "^2.4.1", - "source-map": "^0.6.1", - "supports-color": "^5.4.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } + "icss-utils": "^5.0.0", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.1.0" } }, "postcss-modules-scope": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-1.1.0.tgz", - "integrity": "sha512-LTYwnA4C1He1BKZXIx1CYiHixdSe9LWYVKadq9lK5aCCMkoOkFyZ7aigt+srfjlRplJY3gIol6KUNefdMQJdlw==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz", + "integrity": "sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==", "dev": true, "requires": { - "css-selector-tokenizer": "^0.7.0", - "postcss": "^6.0.1" - }, - "dependencies": { - "postcss": { - "version": "6.0.23", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", - "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", - "dev": true, - "requires": { - "chalk": "^2.4.1", - "source-map": "^0.6.1", - "supports-color": "^5.4.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } + "postcss-selector-parser": "^6.0.4" } }, "postcss-modules-values": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-1.3.0.tgz", - "integrity": "sha512-i7IFaR9hlQ6/0UgFuqM6YWaCfA1Ej8WMg8A5DggnH1UGKJvTV/ugqq/KaULixzzOi3T/tF6ClBXcHGCzdd5unA==", - "dev": true, - "requires": { - "icss-replace-symbols": "^1.1.0", - "postcss": "^6.0.1" - }, - "dependencies": { - "postcss": { - "version": "6.0.23", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", - "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", - "dev": true, - "requires": { - "chalk": "^2.4.1", - "source-map": "^0.6.1", - "supports-color": "^5.4.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "postcss-nested": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-5.0.6.tgz", - "integrity": "sha512-rKqm2Fk0KbA8Vt3AdGN0FB9OBOMDVajMG6ZCf/GoHgdxUJ4sBFp0A/uMIRm+MJUdo33YXEtjqIz8u7DAp8B7DA==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", + "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", "dev": true, "requires": { - "postcss-selector-parser": "^6.0.6" + "icss-utils": "^5.0.0" } }, "postcss-selector-parser": { - "version": "6.0.10", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", - "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz", + "integrity": "sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==", "dev": true, "requires": { "cssesc": "^3.0.0", @@ -15073,15 +14114,10 @@ } } }, - "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==" - }, "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", "dev": true }, "queue-microtask": { @@ -15107,18 +14143,12 @@ "scheduler": "^0.23.0" } }, - "react-hook-form": { - "version": "7.40.0", - "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.40.0.tgz", - "integrity": "sha512-0rokdxMPJs0k9bvFtY6dbcSydyNhnZNXCR49jgDr/aR03FDHFOK6gfh8ccqB3fl696Mk7lqh04xdm+agqWXKSw==", - "requires": {} - }, "react-i18next": { - "version": "12.1.1", - "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-12.1.1.tgz", - "integrity": "sha512-mFdieOI0LDy84q3JuZU6Aou1DoWW2fhapcTGeBS8+vWSJuViuoCLQAMYSb0QoHhXS8B0WKUOPpx4cffAP7r/aA==", + "version": "13.3.1", + "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-13.3.1.tgz", + "integrity": "sha512-JAtYREK879JXaN9GdzfBI4yJeo/XyLeXWUsRABvYXiFUakhZJ40l+kaTo+i+A/3cKIED41kS/HAbZ5BzFtq/Og==", "requires": { - "@babel/runtime": "^7.14.5", + "@babel/runtime": "^7.22.5", "html-parse-stringify": "^3.0.1" } }, @@ -15144,17 +14174,6 @@ "prop-types": "^15.6.2" } }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, "readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -15182,54 +14201,44 @@ "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==" + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", + "dev": true, + "peer": true }, "regenerator-transform": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.0.tgz", - "integrity": "sha512-LsrGtPmbYg19bcPHwdtmXwbW+TqNvtY4riE3P83foeHRroMbH6/2ddFBfab3t7kbzc7v7p4wbkIecHImqt0QNg==", + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", + "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", "dev": true, "requires": { "@babel/runtime": "^7.8.4" } }, "regexp.prototype.flags": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", - "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz", + "integrity": "sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==", "dev": true, "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "functions-have-names": "^1.2.2" + "define-properties": "^1.2.0", + "functions-have-names": "^1.2.3" } }, - "regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true - }, "regexpu-core": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.2.2.tgz", - "integrity": "sha512-T0+1Zp2wjF/juXMrMxHxidqGYn8U4R+zleSJhX9tQ1PUsS8a9UtYfbsF9LdiVgNX3kiX8RNaKM42nfSgvFJjmw==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", + "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", "dev": true, "requires": { + "@babel/regjsgen": "^0.8.0", "regenerate": "^1.4.2", "regenerate-unicode-properties": "^10.1.0", - "regjsgen": "^0.7.1", "regjsparser": "^0.9.1", "unicode-match-property-ecmascript": "^2.0.0", "unicode-match-property-value-ecmascript": "^2.1.0" } }, - "regjsgen": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.7.1.tgz", - "integrity": "sha512-RAt+8H2ZEzHeYWxZ3H2z6tF18zyyOnlcdaafLrm21Bguj7uZy6ULibiAFdXEtKQY4Sy7wDTwDiOazasMLc4KPA==", - "dev": true - }, "regjsparser": { "version": "0.9.1", "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", @@ -15247,46 +14256,18 @@ } } }, - "replace": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/replace/-/replace-1.2.2.tgz", - "integrity": "sha512-C4EDifm22XZM2b2JOYe6Mhn+lBsLBAvLbK8drfUQLTfD1KYl/n3VaW/CDju0Ny4w3xTtegBpg8YNSpFJPUDSjA==", - "dev": true, - "requires": { - "chalk": "2.4.2", - "minimatch": "3.0.5", - "yargs": "^15.3.1" - }, - "dependencies": { - "minimatch": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.5.tgz", - "integrity": "sha512-tUpxzX0VAzJHjLu0xUfFv1gwVp9ba3IOuRAVH2EGuRW8a5emA2FlACLqiT/lDVtS1W+TGNwqz3sWaNyLgDJWuw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - } - } - }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, "resolve": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", - "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "version": "1.22.4", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.4.tgz", + "integrity": "sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg==", "requires": { - "is-core-module": "^2.9.0", + "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" } @@ -15304,6 +14285,29 @@ "requires": { "onetime": "^5.1.0", "signal-exit": "^3.0.2" + }, + "dependencies": { + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + } } }, "reusify": { @@ -15328,20 +14332,14 @@ } }, "rollup": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.7.0.tgz", - "integrity": "sha512-FIJe0msW9P7L9BTfvaJyvn1U1BVCNTL3w8O+PKIrCyiMLg+rIUGb4MbcgVZ10Lnm1uWXOTOWRNARjfXC1+M12Q==", + "version": "3.29.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.0.tgz", + "integrity": "sha512-nszM8DINnx1vSS+TpbWKMkxem0CDWk3cSit/WWCBVs9/JZ1I/XLwOsiUglYuYReaeWWSsW9kge5zE5NZtf/a4w==", "dev": true, "requires": { "fsevents": "~2.3.2" } }, - "run-async": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", - "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", - "dev": true - }, "run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -15352,25 +14350,22 @@ } }, "runtypes": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/runtypes/-/runtypes-6.6.0.tgz", - "integrity": "sha512-ddM7sgB3fyboDlBzEYFQ04L674sKjbs4GyW2W32N/5Ae47NRd/GyMASPC2PFw8drPHYGEcZ0mZ26r5RcB8msfQ==" + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/runtypes/-/runtypes-6.7.0.tgz", + "integrity": "sha512-3TLdfFX8YHNFOhwHrSJza6uxVBmBrEjnNQlNXvXCdItS0Pdskfg5vVXUTWIN+Y23QR09jWpSl99UHkA83m4uWA==" }, - "rxjs": { - "version": "7.5.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.7.tgz", - "integrity": "sha512-z9MzKh/UcOqB3i20H6rtrlaE/CgjLOvheWK/9ILrbhROGTweAi1BaFsTT9FbwZi5Trr1qNRs+MXkhmR06awzQA==", + "safe-array-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.1.tgz", + "integrity": "sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q==", "dev": true, "requires": { - "tslib": "^2.1.0" + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" } }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true - }, "safe-regex-test": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", @@ -15379,14 +14374,8 @@ "requires": { "call-bind": "^1.0.2", "get-intrinsic": "^1.1.3", - "is-regex": "^1.1.4" - } - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true + "is-regex": "^1.1.4" + } }, "scheduler": { "version": "0.23.0", @@ -15397,25 +14386,11 @@ } }, "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true }, - "set-value": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-4.0.1.tgz", - "integrity": "sha512-ayATicCYPVnlNpFmjq2/VmVwhoCQA9+13j8qWp044fmFE3IFphosPtRM+0CJ5xoIx5Uy52fCcwg3XeH2pHbbPQ==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - }, "shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -15443,9 +14418,9 @@ } }, "signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true }, "slash": { @@ -15469,35 +14444,9 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", "dev": true - }, - "is-fullwidth-code-point": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", - "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", - "dev": true } } }, - "socket.io-client": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.5.4.tgz", - "integrity": "sha512-ZpKteoA06RzkD32IbqILZ+Cnst4xewU7ZYK12aS1mzHftFFjpoMz69IuhP/nL25pJfao/amoPI527KnuhFm01g==", - "requires": { - "@socket.io/component-emitter": "~3.1.0", - "debug": "~4.3.2", - "engine.io-client": "~6.2.3", - "socket.io-parser": "~4.2.1" - } - }, - "socket.io-parser": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.1.tgz", - "integrity": "sha512-V4GrkLy+HeF1F/en3SpUaM+7XxYXpuMUWLGde1kSSh5nQMN4hLrbPIkD+otwh6q9R6NOQBN4AMaOZ2zVjui82g==", - "requires": { - "@socket.io/component-emitter": "~3.1.0", - "debug": "~4.3.1" - } - }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -15514,6 +14463,7 @@ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", "dev": true, + "optional": true, "peer": true, "requires": { "buffer-from": "^1.0.0", @@ -15525,23 +14475,15 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, + "optional": true, "peer": true } } }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, - "requires": { - "safe-buffer": "~5.2.0" - } - }, "string-argv": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz", - "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==", + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", + "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", "dev": true }, "string-width": { @@ -15562,9 +14504,9 @@ "dev": true }, "strip-ansi": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz", - "integrity": "sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dev": true, "requires": { "ansi-regex": "^6.0.1" @@ -15572,6 +14514,31 @@ } } }, + "string-width-cjs": { + "version": "npm:string-width@4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "dependencies": { + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + } + } + }, "string.prototype.matchall": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.8.tgz", @@ -15589,6 +14556,17 @@ "side-channel": "^1.0.4" } }, + "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, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + } + }, "string.prototype.trimend": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz", @@ -15620,6 +14598,15 @@ "ansi-regex": "^5.0.1" } }, + "strip-ansi-cjs": { + "version": "npm:strip-ansi@6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, "strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", @@ -15639,9 +14626,9 @@ "dev": true }, "stylis": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.1.3.tgz", - "integrity": "sha512-GP6WDNWf+o403jrEp9c5jibKavrtLW+/qYGhFxFrG8maXhwTBI7gLLhiBb0o7uFccWN+EOS9aMO6cGHWAO07OA==" + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==" }, "supports-color": { "version": "5.5.0", @@ -15656,17 +14643,12 @@ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" }, - "systemjs": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/systemjs/-/systemjs-6.13.0.tgz", - "integrity": "sha512-P3cgh2bpaPvAO2NE3uRp/n6hmk4xPX4DQf+UzTlCAycssKdqhp6hjw+ENWe+aUS7TogKRFtptMosTSFeC6R55g==", - "dev": true - }, "terser": { "version": "5.16.0", "resolved": "https://registry.npmjs.org/terser/-/terser-5.16.0.tgz", "integrity": "sha512-KjTV81QKStSfwbNiwlBXfcgMcOloyuRdb62/iLFPGBcVNF4EXjhdYBhYHmbJpiBrVxZhDvltE11j+LBQUxEEJg==", "dev": true, + "optional": true, "peer": true, "requires": { "@jridgewell/source-map": "^0.3.2", @@ -15680,6 +14662,7 @@ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true, + "optional": true, "peer": true } } @@ -15690,21 +14673,6 @@ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "dev": true - }, - "tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, - "requires": { - "os-tmpdir": "~1.0.2" - } - }, "to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", @@ -15724,22 +14692,29 @@ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" }, + "ts-api-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.2.tgz", + "integrity": "sha512-Cbu4nIqnEdd+THNEsBdkolnOXhg0I8XteoHaEKgvsxpsbWda4IsUut2c187HxywQCvveojow0Dgw/amxtSKVkQ==", + "dev": true, + "requires": {} + }, "tsconfig-paths": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", - "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==", + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz", + "integrity": "sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==", "dev": true, "requires": { "@types/json5": "^0.0.29", - "json5": "^1.0.1", + "json5": "^1.0.2", "minimist": "^1.2.6", "strip-bom": "^3.0.0" }, "dependencies": { "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "dev": true, "requires": { "minimist": "^1.2.0" @@ -15747,29 +14722,6 @@ } } }, - "tslib": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", - "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==", - "dev": true - }, - "tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - }, - "dependencies": { - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - } - } - }, "type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -15780,26 +14732,77 @@ } }, "type-fest": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.2.0.tgz", - "integrity": "sha512-Il3wdLRzWvbAEtocgxGQA9YOoRVeVUGOMBtel5LdEpNeEAol6GJTLw8GbX6Z8EIMfvfhoOXs2bwOijtAZdK5og==", + "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 }, + "typed-array-buffer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz", + "integrity": "sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1", + "is-typed-array": "^1.1.10" + } + }, + "typed-array-byte-length": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz", + "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "has-proto": "^1.0.1", + "is-typed-array": "^1.1.10" + } + }, + "typed-array-byte-offset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz", + "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==", + "dev": true, + "requires": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "has-proto": "^1.0.1", + "is-typed-array": "^1.1.10" + } + }, + "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, + "requires": { + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "is-typed-array": "^1.1.9" + } + }, "typed-css-modules": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/typed-css-modules/-/typed-css-modules-0.7.2.tgz", - "integrity": "sha512-R3guXrQ8ry/yhlfvNmkVY4J3+FtKaEdwqrvgSvFpVY0ieYQHqhhBW0RwfE4hnG4m29Ef/4IE0tBsk/UKplmJkA==", + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/typed-css-modules/-/typed-css-modules-0.8.0.tgz", + "integrity": "sha512-zX9n45IYv27B/85W/b7o+PLmSiLHKSGI/loE8etbIrkVPqB60S7Le7Bkcxl7KR1/visRJRPC/DDFiwx4370FEg==", "dev": true, "requires": { - "@types/css-modules-loader-core": "^1.1.0", "camelcase": "^6.0.0", "chalk": "^4.0.0", "chokidar": "^3.4.0", - "css-modules-loader-core": "^1.1.0", - "glob": "^7.1.2", + "glob": "^10.3.10", + "icss-replace-symbols": "^1.1.0", "is-there": "^4.4.2", - "mkdirp": "^1.0.0", - "yargs": "^15.4.1" + "mkdirp": "^3.0.0", + "postcss": "^8.0.0", + "postcss-modules-extract-imports": "^3.0.0", + "postcss-modules-local-by-default": "^4.0.0", + "postcss-modules-scope": "^3.0.0", + "postcss-modules-values": "^4.0.0", + "yargs": "^17.7.2" }, "dependencies": { "ansi-styles": { @@ -15811,6 +14814,15 @@ "color-convert": "^2.0.1" } }, + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, "chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -15836,12 +14848,34 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "glob": { + "version": "10.3.10", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", + "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", + "dev": true, + "requires": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.5", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" + } + }, "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 }, + "minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -15854,9 +14888,9 @@ } }, "typescript": { - "version": "4.9.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz", - "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", + "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", "dev": true }, "unbox-primitive": { @@ -15871,6 +14905,12 @@ "which-boxed-primitive": "^1.0.2" } }, + "undici-types": { + "version": "5.25.3", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.25.3.tgz", + "integrity": "sha512-Ga1jfYwRn7+cP9v8auvEXN1rX3sWqlayd4HP7OKk4mZWylEmu3KzXDUGrQUN6Ol7qo1gPvB2e5gX6udnyEPgdA==", + "dev": true + }, "unicode-canonical-property-names-ecmascript": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", @@ -15906,9 +14946,10 @@ "dev": true }, "update-browserslist-db": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", - "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", + "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "dev": true, "requires": { "escalade": "^3.1.1", "picocolors": "^1.0.0" @@ -15936,16 +14977,27 @@ "dev": true }, "vite": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.0.0.tgz", - "integrity": "sha512-ynad+4kYs8Jcnn8J7SacS9vAbk7eMy0xWg6E7bAhS1s79TK+D7tVFGXVZ55S7RNLRROU1rxoKlvZ/qjaB41DGA==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.0.tgz", + "integrity": "sha512-ulr8rNLA6rkyFAlVWw2q5YJ91v098AFQ2R0PRFwPzREXOUJQPtFUG0t+/ZikhaOCDqFoDhN6/v8Sq0o4araFAw==", "dev": true, "requires": { - "esbuild": "^0.16.3", + "esbuild": "^0.18.10", "fsevents": "~2.3.2", - "postcss": "^8.4.19", - "resolve": "^1.22.1", - "rollup": "^3.7.0" + "postcss": "^8.4.27", + "rollup": "^3.27.1" + } + }, + "vite-plugin-static-copy": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/vite-plugin-static-copy/-/vite-plugin-static-copy-0.17.0.tgz", + "integrity": "sha512-2HpNbHfDt8SDy393AGXh9llHkc8FJMQkI8s3T5WsH3SWLMO+f5cFIyPErl4yGKU9Uh3Vaqsd4lHZYTf042fQ2A==", + "dev": true, + "requires": { + "chokidar": "^3.5.3", + "fast-glob": "^3.2.11", + "fs-extra": "^11.1.0", + "picocolors": "^1.0.0" } }, "void-elements": { @@ -15953,15 +15005,6 @@ "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", "integrity": "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==" }, - "wcwidth": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", - "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", - "dev": true, - "requires": { - "defaults": "^1.0.3" - } - }, "webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", @@ -15998,22 +15041,23 @@ "is-symbol": "^1.0.3" } }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==", - "dev": true - }, - "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 + "which-typed-array": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.11.tgz", + "integrity": "sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==", + "dev": true, + "requires": { + "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" + } }, "wrap-ansi": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.0.1.tgz", - "integrity": "sha512-QFF+ufAqhoYHvoHdajT/Po7KoXVBPXS2bgjIam5isfWJPfIOnQZ50JtUiVvCv/sjgacf3yRrt2ZKUZ/V4itN4g==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", "dev": true, "requires": { "ansi-styles": "^6.1.0", @@ -16034,9 +15078,9 @@ "dev": true }, "strip-ansi": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz", - "integrity": "sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dev": true, "requires": { "ansi-regex": "^6.0.1" @@ -16044,33 +15088,82 @@ } } }, + "wrap-ansi-cjs": { + "version": "npm:wrap-ansi@7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "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, + "requires": { + "color-convert": "^2.0.1" + } + }, + "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, + "requires": { + "color-name": "~1.1.4" + } + }, + "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 + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + } + } + }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dev": true }, - "ws": { - "version": "8.2.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz", - "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==", - "requires": {} - }, - "xmlhttprequest-ssl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz", - "integrity": "sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A==" - }, "y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true }, "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true }, "yaml": { @@ -16079,22 +15172,18 @@ "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==" }, "yargs": { - "version": "15.4.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", - "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dev": true, "requires": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.2" + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" }, "dependencies": { "emoji-regex": { @@ -16103,42 +15192,11 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true }, "string-width": { "version": "4.2.3", @@ -16154,22 +15212,10 @@ } }, "yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - }, - "dependencies": { - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - } - } + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true }, "yocto-queue": { "version": "0.1.0", diff --git a/package.json b/package.json index 73e59c5a..714cb3b2 100644 --- a/package.json +++ b/package.json @@ -6,73 +6,72 @@ "scripts": { "dev": "vite --host", "build": "tsc && vite build", - "b": "set API_HOST=asas npm run build", "preview": "vite preview", "lint": "eslint --ext .tsx,.ts src", "lint:fix": "eslint --ext .tsx,.ts src --fix", "prettier": "prettier --write --config ./.prettierrc src", - "gen:component": "generate-react component", - "gen:page": "generate-react component --type=page", "prepare": "husky install", "gen:css-types": "tcm src" }, "dependencies": { - "@emotion/react": "^11.10.4", - "@emotion/styled": "^11.10.4", - "@farfetched/core": "^0.4.1", - "@farfetched/react": "^0.4.1", - "@farfetched/runtypes": "^0.4.1", - "@hookform/resolvers": "^2.8.8", - "@mui/icons-material": "^5.10.16", + "@emotion/react": "^11.11.1", + "@emotion/styled": "^11.11.0", + "@farfetched/core": "^0.10.4", + "@farfetched/runtypes": "^0.10.4", + "@fontsource/roboto": "^5.0.8", + "@mui/icons-material": "^5.14.14", "@mui/lab": "^5.0.0-alpha.108", - "@mui/material": "^5.10.17", + "@mui/material": "^5.14.14", + "@mui/x-date-pickers": "^6.16.2", + "@withease/web-api": "^1.0.1", "atomic-router": "^0.8.0", - "atomic-router-react": "^0.8.1", - "axios": "^1.2.1", + "atomic-router-react": "^0.8.5", "classnames": "^2.3.1", - "dayjs": "^1.11.7", - "effector": "^22.4.0", - "effector-react": "^22.3.3", + "compose-function": "^3.0.3", + "dayjs": "^1.11.10", + "effector": "^22.8.7", + "effector-forms": "^1.3.4", + "effector-localstorage": "^1.0.0", + "effector-mui-snacks": "^1.0.0", + "effector-react": "^22.5.4", "history": "^5.3.0", - "i18next": "^22.1.5", - "i18next-browser-languagedetector": "^7.0.1", - "i18next-http-backend": "^2.0.2", - "joi": "^17.5.0", + "i18next": "^23.6.0", + "i18next-browser-languagedetector": "^7.1.0", + "i18next-http-backend": "^2.2.2", + "joi": "^17.11.0", + "ky": "^1.1.0", + "patronum": "^1.20.0", "react": "^18.2.0", "react-dom": "^18.2.0", - "react-hook-form": "^7.40.0", - "react-i18next": "^12.1.1", - "runtypes": "^6.6.0", - "socket.io-client": "^4.5.4" + "react-i18next": "^13.3.1", + "runtypes": "^6.7.0" }, "devDependencies": { - "@babel/cli": "^7.17.3", - "@babel/core": "^7.20.5", - "@babel/preset-env": "^7.16.11", - "@babel/preset-react": "^7.16.7", - "@babel/preset-typescript": "^7.16.7", - "@rollup/plugin-babel": "^6.0.3", - "@types/babel__core": "^7.1.20", - "@types/node": "^18.11.12", - "@types/react": "^18.0.26", - "@types/react-dom": "^18.0.6", - "@typescript-eslint/eslint-plugin": "^5.46.0", - "@typescript-eslint/parser": "^5.46.0", - "@vitejs/plugin-legacy": "^3.0.1", - "@vitejs/plugin-react": "^3.0.0", - "browserslist": "^4.21.4", - "effector-logger": "^0.13.4", - "eslint": "^8.29.0", + "@babel/cli": "^7.23.0", + "@babel/core": "^7.23.2", + "@babel/preset-env": "^7.23.2", + "@babel/preset-react": "^7.22.15", + "@babel/preset-typescript": "^7.23.2", + "@rollup/plugin-babel": "^6.0.4", + "@types/compose-function": "^0.0.32", + "@types/node": "^20.8.7", + "@types/react": "^18.2.31", + "@types/react-dom": "^18.2.14", + "@typescript-eslint/eslint-plugin": "^6.8.0", + "@typescript-eslint/parser": "^6.8.0", + "@vitejs/plugin-react": "^4.1.0", + "eslint": "^8.51.0", "eslint-config-airbnb": "^19.0.4", - "eslint-config-prettier": "^8.5.0", - "eslint-plugin-effector": "^0.10.3", - "eslint-plugin-import": "^2.26.0", - "eslint-plugin-sonarjs": "^0.17.0", - "generate-react-cli": "^8.0.1", - "husky": "^8.0.1", - "lint-staged": "^13.1.0", - "typed-css-modules": "^0.7.2", - "typescript": "^4.9.4", - "vite": "^4.0.0" + "eslint-config-prettier": "^9.0.0", + "eslint-plugin-boundaries": "^3.4.0", + "eslint-plugin-effector": "^0.11.0", + "eslint-plugin-import": "^2.28.1", + "eslint-plugin-sonarjs": "^0.21.0", + "husky": "^8.0.3", + "lint-staged": "^15.0.2", + "typed-css-modules": "^0.8.0", + "typescript": "^5.2.2", + "vite": "^4.5.0", + "vite-plugin-static-copy": "^0.17.0" } } diff --git a/public/index.html b/public/index.html deleted file mode 100644 index f40dfb44..00000000 --- a/public/index.html +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - TodoDrop - - - -
- - diff --git a/src/api/activities/activities.ts b/src/api/activities/activities.ts deleted file mode 100644 index 298431ad..00000000 --- a/src/api/activities/activities.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { fetcher } from '@/packages'; -import { Activity } from '@/models'; -import { StandardResponse } from '@/types'; - -const activitiesFetcher = fetcher.create({ - baseURL: 'activities', -}); - -export const getAll = async (roomId: number) => { - return activitiesFetcher.get>({ - path: { - url: roomId, - }, - }); -}; diff --git a/src/api/activities/index.ts b/src/api/activities/index.ts deleted file mode 100644 index a87aadc0..00000000 --- a/src/api/activities/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * as activitiesApi from './activities'; diff --git a/src/api/auth/auth.ts b/src/api/auth/auth.ts deleted file mode 100644 index 6bdfb2cf..00000000 --- a/src/api/auth/auth.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { fetcher } from '@/packages'; -import { AuthResponse, Tokens } from '@/models'; -import { VoidResponse, StandardResponse } from '@/types'; -import { LoginRequest, RegistrationRequest } from './types'; - -const authFetcher = fetcher.create({ - baseURL: 'auth', -}); - -export const login = async (body: LoginRequest) => { - return authFetcher.post>({ - path: { url: 'login' }, - body, - }); -}; - -export const auth = async () => { - return authFetcher.get>({ - path: { url: '' }, - }); -}; - -export const registration = async (body: RegistrationRequest) => { - return authFetcher.post>({ - path: { url: 'registration' }, - body, - }); -}; - -export const logout = async () => { - return authFetcher.delete>({ - path: { url: 'logout' }, - }); -}; - -export const refresh = async () => { - return authFetcher.get>({ - path: { url: 'refresh' }, - }); -}; diff --git a/src/api/auth/index.ts b/src/api/auth/index.ts deleted file mode 100644 index e5dbf87d..00000000 --- a/src/api/auth/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * as authApi from './auth'; -export * from './types'; diff --git a/src/api/auth/types.ts b/src/api/auth/types.ts deleted file mode 100644 index 3dfea713..00000000 --- a/src/api/auth/types.ts +++ /dev/null @@ -1,11 +0,0 @@ -export interface LoginRequest { - readonly login: string; - readonly password: string; - readonly rememberMe: boolean; -} - -export interface RegistrationRequest { - readonly login: string; - readonly password: string; - readonly repeatPassword: string; -} diff --git a/src/api/groups/groups.ts b/src/api/groups/groups.ts deleted file mode 100644 index c7c83ff7..00000000 --- a/src/api/groups/groups.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { fetcher } from '@/packages'; -import { Group } from '@/models'; -import { StandardResponse } from '@/types'; -import { - CreateGroupRequest, - UpdateGroupRequest, - RemoveGroupRequest, -} from './types'; - -const groupsFetcher = fetcher.create({ - baseURL: 'groups', -}); - -export const getAll = async (roomId: number) => { - return groupsFetcher.get>({ - path: { - url: roomId, - }, - }); -}; - -export const create = async ({ - roomId, - accessToken, - ...body -}: CreateGroupRequest) => { - return groupsFetcher.post>({ - accessToken, - path: { - url: [roomId, 'create'], - }, - body, - }); -}; - -export const update = async ({ - id, - roomId, - accessToken, - ...body -}: UpdateGroupRequest) => { - return groupsFetcher.put>({ - accessToken, - path: { - url: [roomId, id, 'update'], - }, - body, - }); -}; - -export const remove = async ({ - roomId, - accessToken, - id, -}: RemoveGroupRequest) => { - return groupsFetcher.delete>({ - accessToken, - path: { - url: [roomId, id, 'remove'], - }, - }); -}; diff --git a/src/api/groups/index.ts b/src/api/groups/index.ts deleted file mode 100644 index 30d74d21..00000000 --- a/src/api/groups/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * as groupsApi from './groups'; -export * from './types'; diff --git a/src/api/groups/types.ts b/src/api/groups/types.ts deleted file mode 100644 index 73731f9b..00000000 --- a/src/api/groups/types.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { AccessOptions } from '@/packages'; -import { HEX } from '@/types'; - -export interface CreateGroupRequest extends Required { - readonly roomId: number; - readonly name: string; - readonly mainColor: HEX; - readonly secondColor: HEX; -} - -export interface UpdateGroupRequest - extends Partial>, - Required { - readonly id: number; - readonly roomId: number; -} - -export interface RemoveGroupRequest extends Required { - readonly id: number; - readonly roomId: number; -} diff --git a/src/api/index.ts b/src/api/index.ts deleted file mode 100644 index 415c3d31..00000000 --- a/src/api/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -export * from './auth'; -export * from './rooms'; -export * from './tasks'; -export * from './groups'; -export * from './activities'; -export * from './progress'; diff --git a/src/api/progress/index.ts b/src/api/progress/index.ts deleted file mode 100644 index 27542674..00000000 --- a/src/api/progress/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * as progressApi from './progress'; diff --git a/src/api/progress/progress.ts b/src/api/progress/progress.ts deleted file mode 100644 index e4024166..00000000 --- a/src/api/progress/progress.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { fetcher } from '@/packages'; -import { Progress } from '@/models'; -import { StandardResponse } from '@/types'; - -const progressFetcher = fetcher.create({ - baseURL: 'progress', -}); - -export const getAll = async (roomId: number) => { - return progressFetcher.get>({ - path: { - url: roomId, - }, - }); -}; diff --git a/src/api/rooms/index.ts b/src/api/rooms/index.ts deleted file mode 100644 index b214f689..00000000 --- a/src/api/rooms/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * as roomsApi from './rooms'; -export * from './types'; diff --git a/src/api/rooms/rooms.ts b/src/api/rooms/rooms.ts deleted file mode 100644 index c6321355..00000000 --- a/src/api/rooms/rooms.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { AccessOptions, fetcher } from '@/packages'; -import { Room } from '@/models'; -import { StandardResponse } from '@/types'; -import { - CreateRoomRequest, - RemoveRoomRequest, - UpdateRoomRequest, -} from './types'; - -const roomsFetcher = fetcher.create({ - baseURL: 'rooms', -}); - -export const getAll = async ({ accessToken }: AccessOptions) => { - return roomsFetcher.get>({ - accessToken, - path: { - url: '', - }, - }); -}; - -export const getOne = async (id: number) => { - return roomsFetcher.get>({ - path: { - url: id, - }, - }); -}; - -export const create = async ({ accessToken, ...body }: CreateRoomRequest) => { - return roomsFetcher.post>({ - path: { - url: 'create', - }, - accessToken, - body, - }); -}; - -export const update = async ({ - id, - accessToken, - ...body -}: UpdateRoomRequest) => { - return roomsFetcher.put>({ - path: { - url: [id, 'update'], - }, - accessToken, - body, - }); -}; - -export const remove = async ({ id, accessToken }: RemoveRoomRequest) => { - return roomsFetcher.delete>({ - path: { - url: [id, 'remove'], - }, - accessToken, - }); -}; diff --git a/src/api/rooms/types.ts b/src/api/rooms/types.ts deleted file mode 100644 index b935706d..00000000 --- a/src/api/rooms/types.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { AccessOptions } from '@/packages'; - -export type GetRoomsRequest = Required; - -export interface GetRoomRequest extends AccessOptions { - readonly id: number; -} - -export interface CreateRoomRequest extends Required { - readonly name: string; - readonly description: string; -} -export interface UpdateRoomRequest - extends Omit, 'accessToken'>, - Required { - readonly id: number; -} - -export interface RemoveRoomRequest extends Required { - readonly id: number; -} diff --git a/src/api/tasks/index.ts b/src/api/tasks/index.ts deleted file mode 100644 index 6d852223..00000000 --- a/src/api/tasks/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * as tasksApi from './tasks'; -export * from './types'; diff --git a/src/api/tasks/tasks.ts b/src/api/tasks/tasks.ts deleted file mode 100644 index 0273273b..00000000 --- a/src/api/tasks/tasks.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { fetcher } from '@/packages'; -import { Task } from '@/models'; -import { StandardResponse } from '@/types'; -import { - GetTaskRequest, - CreateTaskRequest, - UpdateTaskRequest, - RemoveTaskRequest, -} from './types'; - -const tasksFetcher = fetcher.create({ - baseURL: 'tasks', -}); - -export const getAll = async (roomId: number) => { - return tasksFetcher.get>({ - path: { - url: roomId, - }, - }); -}; - -export const getOne = async ({ roomId, id }: GetTaskRequest) => { - return tasksFetcher.get>({ - path: { - url: [roomId, id], - }, - }); -}; - -export const create = async ({ - roomId, - accessToken, - ...body -}: CreateTaskRequest) => { - return tasksFetcher.post>({ - accessToken, - path: { - url: [roomId, 'create'], - }, - body, - }); -}; - -export const update = async ({ - id, - roomId, - accessToken, - ...body -}: UpdateTaskRequest) => { - return tasksFetcher.put>({ - accessToken, - path: { - url: [roomId, id, 'update'], - }, - body, - }); -}; - -export const remove = async ({ - roomId, - id, - accessToken, -}: RemoveTaskRequest) => { - return tasksFetcher.delete>({ - accessToken, - path: { - url: [roomId, id, 'remove'], - }, - }); -}; diff --git a/src/api/tasks/types.ts b/src/api/tasks/types.ts deleted file mode 100644 index 54b6647e..00000000 --- a/src/api/tasks/types.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { AccessOptions } from '@/packages'; -import { TaskStatus } from '@/models'; - -export interface GetTaskRequest { - readonly id: number; - readonly roomId: number; -} - -export interface CreateTaskRequest extends Required { - readonly roomId: number; - readonly groupId: number; - readonly content: string; - readonly status: TaskStatus; -} - -export interface UpdateTaskRequest - extends Partial>, - Required { - readonly id: number; - readonly roomId: number; -} - -export interface RemoveTaskRequest extends Required { - readonly id: number; - readonly roomId: number; -} diff --git a/src/app/App.module.css b/src/app/App.module.css deleted file mode 100644 index 26d528d9..00000000 --- a/src/app/App.module.css +++ /dev/null @@ -1,4 +0,0 @@ -.loading { - width: 100vw; - height: 100vh; -} diff --git a/src/app/App.module.css.d.ts b/src/app/App.module.css.d.ts deleted file mode 100644 index 2c7a7c59..00000000 --- a/src/app/App.module.css.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -declare const styles: { - readonly loading: string; -}; -export = styles; diff --git a/src/app/App.tsx b/src/app/App.tsx deleted file mode 100644 index 487800da..00000000 --- a/src/app/App.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import * as React from 'react'; -import { useGate, useUnit } from 'effector-react'; -import { useTranslation } from 'react-i18next'; -import { AuthGate, authQuery } from '@/models'; -import { Popups, AppRoutes } from '@/components'; -import { LoadingWrapper, LoadingIndicator } from '@/shared/components'; - -import styles from './App.module.css'; - -export const App: React.FC = () => { - const status = useUnit(authQuery.$status); - const { t } = useTranslation('common'); - useGate(AuthGate); - - const isLoading = status === 'initial' || status === 'pending'; - - return ( - }> - - - - ); -}; diff --git a/src/app/app.tsx b/src/app/app.tsx new file mode 100644 index 00000000..6e7429ec --- /dev/null +++ b/src/app/app.tsx @@ -0,0 +1,30 @@ +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { colorSchemeModel } from '@/shared/models'; +import { LoadingIndicator, Center } from '@/shared/ui'; + +import { withProviders } from './providers'; + +import { Pages } from '@/pages'; + + +import './index.css'; + +export const App = withProviders(() => { + const { t, } = useTranslation('common'); + colorSchemeModel.useSyncScheme(); + + const loadingText = t('loading'); + + return ( + + + + }> + + + ); +}); diff --git a/src/app/index.css b/src/app/index.css new file mode 100644 index 00000000..ae75fd7a --- /dev/null +++ b/src/app/index.css @@ -0,0 +1,32 @@ +*, +*::after, +*::before { + box-sizing: border-box; +} + +body { + margin: 0; + + font-family: 'Roboto', 'Oxygen', 'Ubuntu', 'Fira Sans', 'Droid Sans', + 'Helvetica Neue', sans-serif; + color: #2e2e2e; +} + +#root { + min-height: 100%; +} + +.visibility-hidden { + display: inline-block; + + position: absolute; + top: -99999px; + left: -9999px; + + width: 1px; + height: 1px; + + clip: rect(0, 0, 0, 0); + + font-size: 1px; +} diff --git a/src/index.css.d.ts b/src/app/index.css.d.ts similarity index 100% rename from src/index.css.d.ts rename to src/app/index.css.d.ts diff --git a/src/app/index.ts b/src/app/index.ts index 36d0fd85..e657810a 100644 --- a/src/app/index.ts +++ b/src/app/index.ts @@ -1 +1 @@ -export { App } from './App'; +export { App } from './app'; diff --git a/src/app/providers/index.ts b/src/app/providers/index.ts new file mode 100644 index 00000000..7c73ea15 --- /dev/null +++ b/src/app/providers/index.ts @@ -0,0 +1,17 @@ +import compose from 'compose-function'; + +import { withErrorBoundary } from './withErrorBoundary'; +import { withGlobalStyles } from './withGlobalStyles'; +import { withI18n } from './withI18n'; +import { withNotifications } from './withNotifications'; +import { withRouter } from './withRouter'; +import { withStrictMode } from './withStrictMode'; + +export const withProviders = compose( + withStrictMode, + withI18n, + withRouter, + withGlobalStyles, + withErrorBoundary, + withNotifications +); diff --git a/src/app/providers/withErrorBoundary.tsx b/src/app/providers/withErrorBoundary.tsx new file mode 100644 index 00000000..a7a30777 --- /dev/null +++ b/src/app/providers/withErrorBoundary.tsx @@ -0,0 +1,13 @@ +import * as React from 'react'; + +import { ErrorBoundary } from '@/widgets/page'; + +export const withErrorBoundary = + (Component: React.ComponentType): React.ComponentType => + () => { + return ( + + + + ); + }; diff --git a/src/app/providers/withGlobalStyles.tsx b/src/app/providers/withGlobalStyles.tsx new file mode 100644 index 00000000..46450827 --- /dev/null +++ b/src/app/providers/withGlobalStyles.tsx @@ -0,0 +1,69 @@ +import { + CssBaseline, + Experimental_CssVarsProvider as CssVarsProvider, + StyledEngineProvider, + experimental_extendTheme as extendTheme +} from '@mui/material'; +import { LocalizationProvider } from '@mui/x-date-pickers'; +import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; +import * as React from 'react'; + +import '@fontsource/roboto/300.css'; +import '@fontsource/roboto/400.css'; +import '@fontsource/roboto/500.css'; +import '@fontsource/roboto/700.css'; + +export const withGlobalStyles = + (Component: React.ComponentType): React.ComponentType => + () => { + return ( + + + + + + + + + ); + }; + +const theme = extendTheme({ + shape: { + borderRadius: 8, + }, + spacing: (tab: number) => `${tab}rem`, + colorSchemes: { + dark: { + palette: { + common: { + background: '#121212', + }, + }, + }, + }, + components: { + MuiButton: { + defaultProps: { + variant: 'contained', + disableElevation: true, + }, + }, + MuiPaper: { + defaultProps: { + variant: 'outlined', + elevation: 0, + sx: { + borderWidth: 2, + }, + }, + }, + MuiSkeleton: { + styleOverrides: { + root: { + transform: 'scale(1)', + }, + }, + }, + }, +}); diff --git a/src/app/providers/withI18n.tsx b/src/app/providers/withI18n.tsx new file mode 100644 index 00000000..7cddcf57 --- /dev/null +++ b/src/app/providers/withI18n.tsx @@ -0,0 +1,14 @@ +import * as React from 'react'; +import { I18nextProvider } from 'react-i18next'; + +import { i18n } from '@/shared/configs'; + +export const withI18n = + (Component: React.ComponentType): React.ComponentType => + () => { + return ( + + + + ); + }; diff --git a/src/app/providers/withNotifications.tsx b/src/app/providers/withNotifications.tsx new file mode 100644 index 00000000..0df07591 --- /dev/null +++ b/src/app/providers/withNotifications.tsx @@ -0,0 +1,20 @@ +import { SnackbarList } from 'effector-mui-snacks'; +import * as React from 'react'; + +import { notificationsModel } from '@/shared/models'; + +import 'effector-mui-snacks/dist/style.css'; + +export const withNotifications = + (Component: React.ComponentType): React.ComponentType => + () => { + return ( + <> + + + + ); + }; diff --git a/src/app/providers/withRouter.tsx b/src/app/providers/withRouter.tsx new file mode 100644 index 00000000..c6f682f5 --- /dev/null +++ b/src/app/providers/withRouter.tsx @@ -0,0 +1,29 @@ +import { redirect } from 'atomic-router'; +import { RouterProvider } from 'atomic-router-react'; +import { sample } from 'effector'; +import { createBrowserHistory } from 'history'; +import * as React from 'react'; + +import { router, routes } from '@/shared/configs'; +import { appModel } from '@/shared/models'; + +redirect({ + clock: router.routeNotFound, + route: routes.rooms.base, +}); + +sample({ + clock: appModel.started, + fn: () => createBrowserHistory(), + target: router.setHistory, +}); + +export const withRouter = + (Component: React.ComponentType): React.ComponentType => + () => { + return ( + + + + ); + }; diff --git a/src/app/providers/withStrictMode.tsx b/src/app/providers/withStrictMode.tsx new file mode 100644 index 00000000..07d9ffb2 --- /dev/null +++ b/src/app/providers/withStrictMode.tsx @@ -0,0 +1,11 @@ +import * as React from 'react'; + +export const withStrictMode = + (Component: React.ComponentType): React.ComponentType => + () => { + return ( + + + + ); + }; diff --git a/src/components/AppRoutes/AppRoutes.module.css b/src/components/AppRoutes/AppRoutes.module.css deleted file mode 100644 index 26d528d9..00000000 --- a/src/components/AppRoutes/AppRoutes.module.css +++ /dev/null @@ -1,4 +0,0 @@ -.loading { - width: 100vw; - height: 100vh; -} diff --git a/src/components/AppRoutes/AppRoutes.module.css.d.ts b/src/components/AppRoutes/AppRoutes.module.css.d.ts deleted file mode 100644 index 2c7a7c59..00000000 --- a/src/components/AppRoutes/AppRoutes.module.css.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -declare const styles: { - readonly loading: string; -}; -export = styles; diff --git a/src/components/AppRoutes/AppRoutes.tsx b/src/components/AppRoutes/AppRoutes.tsx deleted file mode 100644 index f44159ea..00000000 --- a/src/components/AppRoutes/AppRoutes.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import * as React from 'react'; -import { Route as AtomicRoute } from 'atomic-router-react'; -import { CommonProps } from '@/types'; -import { routes } from '@/routes'; -import { LoadingIndicator, LoadingWrapper } from '@/shared/components'; - -import styles from './AppRoutes.module.css'; - -export interface AppRoutesProps extends CommonProps {} - -export const AppRoutes: React.FC = React.memo( - function AppRoutes() { - return ( - } - isLoading - /> - }> - {routes.map((route) => ( - - ))} - - ); - } -); diff --git a/src/components/AppRoutes/index.ts b/src/components/AppRoutes/index.ts deleted file mode 100644 index 7e527bf9..00000000 --- a/src/components/AppRoutes/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { AppRoutes, type AppRoutesProps } from './AppRoutes'; diff --git a/src/components/AsideBar/AsideBar.module.css b/src/components/AsideBar/AsideBar.module.css deleted file mode 100644 index 47cb24a0..00000000 --- a/src/components/AsideBar/AsideBar.module.css +++ /dev/null @@ -1,15 +0,0 @@ -.panel { - display: grid; - grid-template-rows: max-content 1fr; - gap: 2em; - - padding: 1em 0; -} - -.panel[hidden] { - display: none; -} - -.progress { - max-height: 300px; -} diff --git a/src/components/AsideBar/AsideBar.module.css.d.ts b/src/components/AsideBar/AsideBar.module.css.d.ts deleted file mode 100644 index 3c5fcbd8..00000000 --- a/src/components/AsideBar/AsideBar.module.css.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -declare const styles: { - readonly panel: string; - readonly progress: string; -}; -export = styles; diff --git a/src/components/AsideBar/AsideBar.tsx b/src/components/AsideBar/AsideBar.tsx deleted file mode 100644 index 39c4fb01..00000000 --- a/src/components/AsideBar/AsideBar.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import * as React from 'react'; -import { Tab } from '@mui/material'; -import { TabContext, TabList, TabPanel } from '@mui/lab'; -import { CommonProps } from '@/types'; -import { TasksProgress, ActivityList, Groups } from './components'; - -import styles from './AsideBar.module.css'; - -export interface AsideBarProps extends CommonProps {} - -export const AsideBar: React.FC = React.memo(function AsideBar( - props -) { - const { className } = props; - const [openTab, setOpenTab] = React.useState('progress'); - - const onChange = React.useCallback((_evt: unknown, value: string) => { - setOpenTab(value); - }, []); - - return ( - - ); -}); diff --git a/src/components/AsideBar/components/ActivityList/ActivityList.module.css b/src/components/AsideBar/components/ActivityList/ActivityList.module.css deleted file mode 100644 index ca81b24a..00000000 --- a/src/components/AsideBar/components/ActivityList/ActivityList.module.css +++ /dev/null @@ -1,14 +0,0 @@ -.wrapper { - overflow-y: auto; -} - -.title { - font-weight: 700; - padding: 0 1em; -} - -.list { - overflow-y: scroll; - - padding: 0 1em; -} diff --git a/src/components/AsideBar/components/ActivityList/ActivityList.module.css.d.ts b/src/components/AsideBar/components/ActivityList/ActivityList.module.css.d.ts deleted file mode 100644 index 21a61d4b..00000000 --- a/src/components/AsideBar/components/ActivityList/ActivityList.module.css.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -declare const styles: { - readonly wrapper: string; - readonly title: string; - readonly list: string; -}; -export = styles; diff --git a/src/components/AsideBar/components/ActivityList/ActivityList.tsx b/src/components/AsideBar/components/ActivityList/ActivityList.tsx deleted file mode 100644 index 24dffb2e..00000000 --- a/src/components/AsideBar/components/ActivityList/ActivityList.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import * as React from 'react'; -import cn from 'classnames'; -import { Stack, Typography } from '@mui/material'; -import { useQuery } from '@farfetched/react'; -import { useTranslation } from 'react-i18next'; -import { getActivitiesQuery } from '@/models'; -import { CommonProps } from '@/types'; -import { getEmptyArray } from '@/const'; -import { SkeletonActivityCard, ActivityCard } from './components'; - -import styles from './ActivityList.module.css'; - -export const ActivityList: React.FC = ({ className }) => { - const { t } = useTranslation('room'); - const { data: activities } = useQuery(getActivitiesQuery); - const isLoading = !activities; - - return ( - - - {t('activities.title')} - - - {isLoading - ? getEmptyArray(4).map((_, i) => ) - : activities - .slice(0, 10) - .map((activity) => ( - - ))} - - - ); -}; diff --git a/src/components/AsideBar/components/ActivityList/components/ActivityCard/ActivityCard.module.css b/src/components/AsideBar/components/ActivityList/components/ActivityCard/ActivityCard.module.css deleted file mode 100644 index b7e95fc2..00000000 --- a/src/components/AsideBar/components/ActivityList/components/ActivityCard/ActivityCard.module.css +++ /dev/null @@ -1,24 +0,0 @@ -.card { - overflow: unset; -} - -.avatar { - background-color: var(--activity-card-avatar-color); -} - -.cardContent { - display: flex; - column-gap: 1.25em; -} - -.error { - --activity-card-avatar-color: var(--mui-palette-error-light); -} - -.warning { - --activity-card-avatar-color: var(--mui-palette-warning-light); -} - -.success { - --activity-card-avatar-color: var(--mui-palette-success-light); -} diff --git a/src/components/AsideBar/components/ActivityList/components/ActivityCard/ActivityCard.module.css.d.ts b/src/components/AsideBar/components/ActivityList/components/ActivityCard/ActivityCard.module.css.d.ts deleted file mode 100644 index 3029cdfe..00000000 --- a/src/components/AsideBar/components/ActivityList/components/ActivityCard/ActivityCard.module.css.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -declare const styles: { - readonly card: string; - readonly avatar: string; - readonly cardContent: string; - readonly error: string; - readonly warning: string; - readonly success: string; -}; -export = styles; diff --git a/src/components/AsideBar/components/ActivityList/components/ActivityCard/ActivityCard.tsx b/src/components/AsideBar/components/ActivityList/components/ActivityCard/ActivityCard.tsx deleted file mode 100644 index 53581656..00000000 --- a/src/components/AsideBar/components/ActivityList/components/ActivityCard/ActivityCard.tsx +++ /dev/null @@ -1,54 +0,0 @@ -import * as React from 'react'; -import cn from 'classnames'; -import { Avatar, Card, CardContent, Typography } from '@mui/material'; -import EditIcon from '@mui/icons-material/Edit'; -import DeleteIcon from '@mui/icons-material/Delete'; -import AddIcon from '@mui/icons-material/Add'; -import { useTranslation } from 'react-i18next'; -import { Activity, ActivityType } from '@/models'; -import { Color, CommonProps } from '@/types'; -import { DateTime } from '@/shared/components'; - -import styles from './ActivityCard.module.css'; - -export interface ActivityCardProps extends CommonProps, Activity {} - -const colorMap: Record< - ActivityType, - Exclude -> = { - create: 'success', - remove: 'error', - update: 'warning', -}; - -const iconMap: Record = { - create: , - remove: , - update: , -}; - -export const ActivityCard: React.FC = (props) => { - const { type, sphere, className, createdAt, } = props; - const { t, } = useTranslation('room'); - return ( - - - - {iconMap[type]} - -
- - {t('activities.text', { - type, - sphere, - })} - - -
-
-
- ); -}; diff --git a/src/components/AsideBar/components/ActivityList/components/ActivityCard/index.ts b/src/components/AsideBar/components/ActivityList/components/ActivityCard/index.ts deleted file mode 100644 index 6f135d78..00000000 --- a/src/components/AsideBar/components/ActivityList/components/ActivityCard/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { ActivityCard, type ActivityCardProps } from './ActivityCard'; diff --git a/src/components/AsideBar/components/ActivityList/components/SkeletonActivityCard/SkeletonActivityCard.module.css b/src/components/AsideBar/components/ActivityList/components/SkeletonActivityCard/SkeletonActivityCard.module.css deleted file mode 100644 index c09e9b3a..00000000 --- a/src/components/AsideBar/components/ActivityList/components/SkeletonActivityCard/SkeletonActivityCard.module.css +++ /dev/null @@ -1,16 +0,0 @@ -.card { - overflow: unset; -} - -.cardContent { - display: grid; - grid-template-columns: max-content 1fr; - grid-template-rows: max-content 1fr; - column-gap: 1.25em; -} - -.block { - grid-row: span 2; - - width: 100%; -} diff --git a/src/components/AsideBar/components/ActivityList/components/SkeletonActivityCard/SkeletonActivityCard.module.css.d.ts b/src/components/AsideBar/components/ActivityList/components/SkeletonActivityCard/SkeletonActivityCard.module.css.d.ts deleted file mode 100644 index be4f23b6..00000000 --- a/src/components/AsideBar/components/ActivityList/components/SkeletonActivityCard/SkeletonActivityCard.module.css.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -declare const styles: { - readonly card: string; - readonly cardContent: string; - readonly block: string; -}; -export = styles; diff --git a/src/components/AsideBar/components/ActivityList/components/SkeletonActivityCard/SkeletonActivityCard.tsx b/src/components/AsideBar/components/ActivityList/components/SkeletonActivityCard/SkeletonActivityCard.tsx deleted file mode 100644 index 36763066..00000000 --- a/src/components/AsideBar/components/ActivityList/components/SkeletonActivityCard/SkeletonActivityCard.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import * as React from 'react'; -import cn from 'classnames'; -import { Avatar, Card, CardContent, Skeleton } from '@mui/material'; -import { CommonProps } from '@/types'; - -import styles from './SkeletonActivityCard.module.css'; - -export interface SkeletonActivityCardProps extends CommonProps {} - -export const SkeletonActivityCard: React.FC = - React.memo(function SkeletonActivityCard(props) { - const { className } = props; - return ( - - - - - -
- - - -
-
-
- ); - }); diff --git a/src/components/AsideBar/components/ActivityList/components/SkeletonActivityCard/index.ts b/src/components/AsideBar/components/ActivityList/components/SkeletonActivityCard/index.ts deleted file mode 100644 index 124b53f5..00000000 --- a/src/components/AsideBar/components/ActivityList/components/SkeletonActivityCard/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export { - SkeletonActivityCard, - type SkeletonActivityCardProps, -} from './SkeletonActivityCard'; diff --git a/src/components/AsideBar/components/ActivityList/components/index.ts b/src/components/AsideBar/components/ActivityList/components/index.ts deleted file mode 100644 index f5ee576e..00000000 --- a/src/components/AsideBar/components/ActivityList/components/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './ActivityCard'; -export * from './SkeletonActivityCard'; diff --git a/src/components/AsideBar/components/ActivityList/index.ts b/src/components/AsideBar/components/ActivityList/index.ts deleted file mode 100644 index e2275ce1..00000000 --- a/src/components/AsideBar/components/ActivityList/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { ActivityList } from './ActivityList'; diff --git a/src/components/AsideBar/components/Groups/Groups.module.css b/src/components/AsideBar/components/Groups/Groups.module.css deleted file mode 100644 index 0ecc8828..00000000 --- a/src/components/AsideBar/components/Groups/Groups.module.css +++ /dev/null @@ -1,8 +0,0 @@ -.groups { - display: grid; - gap: 1em; -} - -.button { - width: 100%; -} diff --git a/src/components/AsideBar/components/Groups/Groups.module.css.d.ts b/src/components/AsideBar/components/Groups/Groups.module.css.d.ts deleted file mode 100644 index d4e89469..00000000 --- a/src/components/AsideBar/components/Groups/Groups.module.css.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -declare const styles: { - readonly groups: string; - readonly button: string; -}; -export = styles; diff --git a/src/components/AsideBar/components/Groups/Groups.tsx b/src/components/AsideBar/components/Groups/Groups.tsx deleted file mode 100644 index eea38cd9..00000000 --- a/src/components/AsideBar/components/Groups/Groups.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import * as React from 'react'; -import cn from 'classnames'; -import { Button } from '@mui/material'; -import { Link } from 'atomic-router-react'; -import { useUnit } from 'effector-react'; -import { useTranslation } from 'react-i18next'; -import { roomRoute } from '@/routes'; -import { getParams, popups } from '@/const'; -import { CommonProps } from '@/types'; -import { GroupsList } from './components'; - -import styles from './Groups.module.css'; - -export interface GroupsProps extends CommonProps {} - -export const Groups: React.FC = React.memo(function Groups(props) { - const { className, } = props; - const { t, } = useTranslation('common'); - const params = useUnit(roomRoute.$params); - - return ( -
- - -
- ); -}); diff --git a/src/components/AsideBar/components/Groups/components/GroupsList/GroupsList.tsx b/src/components/AsideBar/components/Groups/components/GroupsList/GroupsList.tsx deleted file mode 100644 index b6efeae8..00000000 --- a/src/components/AsideBar/components/Groups/components/GroupsList/GroupsList.tsx +++ /dev/null @@ -1,67 +0,0 @@ -import * as React from 'react'; -import cn from 'classnames'; -import { useMutation } from '@farfetched/react'; -import { - ListItem, - ListItemSecondaryAction, - IconButton, - Skeleton, - List -} from '@mui/material'; -import EditIcon from '@mui/icons-material/Edit'; -import DeleteIcon from '@mui/icons-material/Delete'; -import { Link } from 'atomic-router-react'; -import { useUnit } from 'effector-react'; -import { useTranslation } from 'react-i18next'; -import { getGroupsQuery, removeGroupMutation } from '@/models'; -import { roomRoute } from '@/routes'; -import { useParam } from '@/hooks'; -import { getEmptyArray, getParams, popups } from '@/const'; -import { CommonProps } from '@/types'; -import { GroupLabel } from '@/shared/components'; - -export interface GroupsListProps extends CommonProps {} - -export const GroupsList: React.FC = React.memo( - function GroupsList(props) { - const { className, } = props; - const { t, } = useTranslation('popups'); - const groups = useUnit(getGroupsQuery.$data); - const roomId = useParam(roomRoute, 'id'); - const removeGroup = useMutation(removeGroupMutation); - - const items = groups - ? groups.map((group) => ( - - - - - - - - removeGroup.start({ id: group.id, roomId: group.roomId, }) - } - title={t('actions.remove', { ns: 'common', })!}> - - - - - )) - : getEmptyArray(4).map((_, i) => ( - - - - )); - - return {items}; - } -); diff --git a/src/components/AsideBar/components/Groups/components/GroupsList/index.ts b/src/components/AsideBar/components/Groups/components/GroupsList/index.ts deleted file mode 100644 index d0d10368..00000000 --- a/src/components/AsideBar/components/Groups/components/GroupsList/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { GroupsList, type GroupsListProps } from './GroupsList'; diff --git a/src/components/AsideBar/components/Groups/components/index.ts b/src/components/AsideBar/components/Groups/components/index.ts deleted file mode 100644 index 5f6600af..00000000 --- a/src/components/AsideBar/components/Groups/components/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './GroupsList'; diff --git a/src/components/AsideBar/components/Groups/index.ts b/src/components/AsideBar/components/Groups/index.ts deleted file mode 100644 index c2dfd354..00000000 --- a/src/components/AsideBar/components/Groups/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { Groups, type GroupsProps } from './Groups'; diff --git a/src/components/AsideBar/components/TasksProgress/TasksProgress.module.css b/src/components/AsideBar/components/TasksProgress/TasksProgress.module.css deleted file mode 100644 index 6c3edf6f..00000000 --- a/src/components/AsideBar/components/TasksProgress/TasksProgress.module.css +++ /dev/null @@ -1,20 +0,0 @@ -.title { - padding: 0 1em; - - font-weight: 700; -} - -.list { - padding: 0 1em; - - overflow: scroll; -} - -@media (max-width: 1300px) { - .wrapper { - background-color: white; - - padding: 1rem; - border-radius: 8px; - } -} diff --git a/src/components/AsideBar/components/TasksProgress/TasksProgress.module.css.d.ts b/src/components/AsideBar/components/TasksProgress/TasksProgress.module.css.d.ts deleted file mode 100644 index fe96b93a..00000000 --- a/src/components/AsideBar/components/TasksProgress/TasksProgress.module.css.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -declare const styles: { - readonly title: string; - readonly list: string; - readonly wrapper: string; -}; -export = styles; diff --git a/src/components/AsideBar/components/TasksProgress/TasksProgress.tsx b/src/components/AsideBar/components/TasksProgress/TasksProgress.tsx deleted file mode 100644 index ab01e5df..00000000 --- a/src/components/AsideBar/components/TasksProgress/TasksProgress.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import * as React from 'react'; -import cn from 'classnames'; -import { Stack, Typography } from '@mui/material'; -import { useUnit } from 'effector-react'; -import { useQuery } from '@farfetched/react'; -import { useTranslation } from 'react-i18next'; -import { $GroupsMap, getProgressQuery } from '@/models'; -import { getEmptyArray } from '@/const'; -import { CommonProps } from '@/types'; -import { SkeletonTaskProgress, TaskProgress } from './components'; - -import styles from './TasksProgress.module.css'; - -export const TasksProgress: React.FC = ({ className }) => { - const { t } = useTranslation('room'); - const { data: progresses } = useQuery(getProgressQuery); - const groups = useUnit($GroupsMap); - - const isLoading = !groups || !progresses; - - return ( - - - {t('taskProgress.title')} - - - {isLoading - ? getEmptyArray(2).map((_, i) => ) - : progresses.map((progress) => { - const group = groups[progress.groupId]; - if (!group) { - return null; - } - return ( - - ); - })} - - - ); -}; diff --git a/src/components/AsideBar/components/TasksProgress/components/SkeletonTaskProgress/SkeletonTaskProgress.tsx b/src/components/AsideBar/components/TasksProgress/components/SkeletonTaskProgress/SkeletonTaskProgress.tsx deleted file mode 100644 index afb9d870..00000000 --- a/src/components/AsideBar/components/TasksProgress/components/SkeletonTaskProgress/SkeletonTaskProgress.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import * as React from 'react'; -import { Skeleton } from '@mui/material'; -import { CommonProps } from '@/types'; - -export interface SkeletonTaskProgressProps extends CommonProps {} - -export const SkeletonTaskProgress: React.FC = - React.memo(function SkeletonTaskProgress(props) { - const { className } = props; - return ( -
- - -
- ); - }); diff --git a/src/components/AsideBar/components/TasksProgress/components/SkeletonTaskProgress/index.ts b/src/components/AsideBar/components/TasksProgress/components/SkeletonTaskProgress/index.ts deleted file mode 100644 index ab230c63..00000000 --- a/src/components/AsideBar/components/TasksProgress/components/SkeletonTaskProgress/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export { - SkeletonTaskProgress, - type SkeletonTaskProgressProps, -} from './SkeletonTaskProgress'; diff --git a/src/components/AsideBar/components/TasksProgress/components/TaskProgress/TaskProgress.module.css b/src/components/AsideBar/components/TasksProgress/components/TaskProgress/TaskProgress.module.css deleted file mode 100644 index db8e23f0..00000000 --- a/src/components/AsideBar/components/TasksProgress/components/TaskProgress/TaskProgress.module.css +++ /dev/null @@ -1,10 +0,0 @@ -.title { - display: flex; - justify-content: space-between; -} - -.progress { - height: 10px; - - border-radius: 8px; -} diff --git a/src/components/AsideBar/components/TasksProgress/components/TaskProgress/TaskProgress.module.css.d.ts b/src/components/AsideBar/components/TasksProgress/components/TaskProgress/TaskProgress.module.css.d.ts deleted file mode 100644 index d95a3142..00000000 --- a/src/components/AsideBar/components/TasksProgress/components/TaskProgress/TaskProgress.module.css.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -declare const styles: { - readonly title: string; - readonly progress: string; -}; -export = styles; diff --git a/src/components/AsideBar/components/TasksProgress/components/TaskProgress/TaskProgress.tsx b/src/components/AsideBar/components/TasksProgress/components/TaskProgress/TaskProgress.tsx deleted file mode 100644 index e265e4e5..00000000 --- a/src/components/AsideBar/components/TasksProgress/components/TaskProgress/TaskProgress.tsx +++ /dev/null @@ -1,65 +0,0 @@ -import * as React from 'react'; -import cn from 'classnames'; -import { - LinearProgress, - linearProgressClasses, - SxProps, - Typography -} from '@mui/material'; -import { useTranslation } from 'react-i18next'; -import { Progress, Group } from '@/models'; -import { CommonProps } from '@/types'; - -import styles from './TaskProgress.module.css'; - -export interface TaskProgressComponent - extends CommonProps, - Omit, - Pick {} - -export const TaskProgress: React.FC = React.memo( - (props) => { - const { - completedCount, - totalCount, - className, - mainColor, - secondColor, - name, - } = props; - const { t, } = useTranslation('room'); - - const value = (completedCount / totalCount) * 100; - - const sx: SxProps = { - backgroundColor: secondColor, - [`& .${linearProgressClasses.bar}`]: { - backgroundColor: mainColor, - }, - }; - - return ( -
- - {name}{' '} - - {completedCount}/{totalCount} - - - -
- ); - } -); diff --git a/src/components/AsideBar/components/TasksProgress/components/TaskProgress/index.ts b/src/components/AsideBar/components/TasksProgress/components/TaskProgress/index.ts deleted file mode 100644 index 9bebdff6..00000000 --- a/src/components/AsideBar/components/TasksProgress/components/TaskProgress/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { TaskProgress, type TaskProgressComponent } from './TaskProgress'; diff --git a/src/components/AsideBar/components/TasksProgress/components/index.ts b/src/components/AsideBar/components/TasksProgress/components/index.ts deleted file mode 100644 index eabce483..00000000 --- a/src/components/AsideBar/components/TasksProgress/components/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './SkeletonTaskProgress'; -export * from './TaskProgress'; diff --git a/src/components/AsideBar/components/TasksProgress/index.ts b/src/components/AsideBar/components/TasksProgress/index.ts deleted file mode 100644 index 09f91b1c..00000000 --- a/src/components/AsideBar/components/TasksProgress/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { TasksProgress } from './TasksProgress'; diff --git a/src/components/AsideBar/components/index.ts b/src/components/AsideBar/components/index.ts deleted file mode 100644 index d720cefb..00000000 --- a/src/components/AsideBar/components/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './Groups'; -export * from './TasksProgress'; -export * from './ActivityList'; diff --git a/src/components/AsideBar/index.ts b/src/components/AsideBar/index.ts deleted file mode 100644 index 4c95fc14..00000000 --- a/src/components/AsideBar/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { AsideBar, type AsideBarProps } from './AsideBar'; diff --git a/src/components/ErrorBoundary/ErrorBoundary.tsx b/src/components/ErrorBoundary/ErrorBoundary.tsx deleted file mode 100644 index 7dfbd3eb..00000000 --- a/src/components/ErrorBoundary/ErrorBoundary.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import * as React from 'react'; -import { CommonProps } from '@/types'; - -export interface ErrorBoundaryProps extends CommonProps {} - -export class ErrorBoundary extends React.Component { - componentDidCatch(error: Error, errorInfo: React.ErrorInfo): void { - console.log(errorInfo, error); - } - - static getDerivedStateFromError() { - return
Error
; - } - - render(): React.ReactNode { - const { children } = this.props; - return children; - } -} diff --git a/src/components/ErrorBoundary/index.ts b/src/components/ErrorBoundary/index.ts deleted file mode 100644 index 729376be..00000000 --- a/src/components/ErrorBoundary/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { ErrorBoundary, type ErrorBoundaryProps } from './ErrorBoundary'; diff --git a/src/components/Header/Header.module.css b/src/components/Header/Header.module.css deleted file mode 100644 index c473b6de..00000000 --- a/src/components/Header/Header.module.css +++ /dev/null @@ -1,13 +0,0 @@ -.header { - box-shadow: none; -} - -.bar { - gap: 1em; - - padding: 0; -} - -.avatar { - margin-left: auto; -} diff --git a/src/components/Header/Header.module.css.d.ts b/src/components/Header/Header.module.css.d.ts deleted file mode 100644 index ae85adb9..00000000 --- a/src/components/Header/Header.module.css.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -declare const styles: { - readonly header: string; - readonly bar: string; - readonly avatar: string; -}; -export = styles; diff --git a/src/components/Header/Header.tsx b/src/components/Header/Header.tsx deleted file mode 100644 index bf0e8a3a..00000000 --- a/src/components/Header/Header.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import * as React from 'react'; -import cn from 'classnames'; -import { AppBar, Toolbar } from '@mui/material'; -import { CommonProps } from '@/types'; -import { NavigationBreadcrumbs, ProfileLink } from './components'; - -import styles from './Header.module.css'; - -export const Header: React.FC = ({ className }) => { - return ( - - - - - - - ); -}; diff --git a/src/components/Header/components/NavigationBreadcrumbs/NavigationBreadcrumbs.tsx b/src/components/Header/components/NavigationBreadcrumbs/NavigationBreadcrumbs.tsx deleted file mode 100644 index feedaffa..00000000 --- a/src/components/Header/components/NavigationBreadcrumbs/NavigationBreadcrumbs.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import * as React from 'react'; -import cn from 'classnames'; -import { useUnit } from 'effector-react'; -import { Breadcrumbs, Typography, Link } from '@mui/material'; -import { Link as AtomicLink } from 'atomic-router-react'; -import { router } from '@/models'; -import { CommonProps } from '@/types'; -import { breadcrumbsMap } from './data'; - -export interface NavigationBreadcrumbsProps extends CommonProps {} - -export const NavigationBreadcrumbs: React.FC = - React.memo(function NavigationBreadcrumbs(props) { - const { className } = props; - const pathname = useUnit(router.$path); - const pathnames = pathname.split('/').filter((x) => !!x); - return ( - - {pathnames.map((path, index) => { - const last = index === pathnames.length - 1; - const to = `/${pathnames.slice(0, index + 1).join('/')}`; - return last ? ( - - {breadcrumbsMap[to]} - - ) : ( - - {breadcrumbsMap[to]} - - ); - })} - - ); - }); diff --git a/src/components/Header/components/NavigationBreadcrumbs/data.ts b/src/components/Header/components/NavigationBreadcrumbs/data.ts deleted file mode 100644 index 0034e42d..00000000 --- a/src/components/Header/components/NavigationBreadcrumbs/data.ts +++ /dev/null @@ -1,4 +0,0 @@ -export const breadcrumbsMap: Record = { - '/rooms': 'Rooms', - '/settings': 'Settings', -}; diff --git a/src/components/Header/components/NavigationBreadcrumbs/index.ts b/src/components/Header/components/NavigationBreadcrumbs/index.ts deleted file mode 100644 index f84bfdc6..00000000 --- a/src/components/Header/components/NavigationBreadcrumbs/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export { - NavigationBreadcrumbs, - type NavigationBreadcrumbsProps, -} from './NavigationBreadcrumbs'; diff --git a/src/components/Header/components/ProfileLink/ProfileLink.tsx b/src/components/Header/components/ProfileLink/ProfileLink.tsx deleted file mode 100644 index 37c1cb8b..00000000 --- a/src/components/Header/components/ProfileLink/ProfileLink.tsx +++ /dev/null @@ -1,57 +0,0 @@ -import * as React from 'react'; -import { Avatar, Menu } from '@mui/material'; -import { useMutation } from '@farfetched/react'; -import { useUnit } from 'effector-react'; -import { useTranslation } from 'react-i18next'; -import { $AuthUser, logoutMutation } from '@/models'; -import { useToggle } from '@/hooks'; -import { CommonProps } from '@/types'; -import { MenuOption, MenuItem } from '@/shared/components'; - -export const ProfileLink: React.FC = ({ className }) => { - const { t } = useTranslation('header'); - const user = useUnit($AuthUser); - const [isOpen, toggle] = useToggle(false); - const [reference, setReference] = React.useState(null); - const logout = useMutation(logoutMutation); - - const options: MenuOption[] = React.useMemo( - () => [ - { - label: t('actions.settings'), - onClick: console.log, - }, - { - label: t('actions.logout'), - onClick: () => logout.start(), - }, - ], - [] - ); - - if (!user) { - return null; - } - - const { login, photo } = user; - - return ( -
- - {login[0]?.toUpperCase()} - - - {options.map((option) => ( - - ))} - -
- ); -}; diff --git a/src/components/Header/components/ProfileLink/index.ts b/src/components/Header/components/ProfileLink/index.ts deleted file mode 100644 index b75feef1..00000000 --- a/src/components/Header/components/ProfileLink/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { ProfileLink } from './ProfileLink'; diff --git a/src/components/Header/components/index.ts b/src/components/Header/components/index.ts deleted file mode 100644 index ce942eb8..00000000 --- a/src/components/Header/components/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './NavigationBreadcrumbs'; -export * from './ProfileLink'; diff --git a/src/components/Header/index.ts b/src/components/Header/index.ts deleted file mode 100644 index 29429dc9..00000000 --- a/src/components/Header/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { Header } from './Header'; diff --git a/src/components/LoginForm/LoginForm.module.css b/src/components/LoginForm/LoginForm.module.css deleted file mode 100644 index f3ceba58..00000000 --- a/src/components/LoginForm/LoginForm.module.css +++ /dev/null @@ -1,23 +0,0 @@ -.form { - display: grid; - grid-template-columns: var(--login-form-template-columns); - gap: 10px; -} - -.field { - grid-column: var(--login-form-field-column); -} - -@media (min-width: 600px) { - .form { - --login-form-template-columns: max-content 1fr; - --login-form-field-column: span 2; - } -} - -@media (max-width: 600px) { - .form { - --login-form-template-columns: 1fr; - --login-form-field-column: 1; - } -} diff --git a/src/components/LoginForm/LoginForm.module.css.d.ts b/src/components/LoginForm/LoginForm.module.css.d.ts deleted file mode 100644 index a36a8916..00000000 --- a/src/components/LoginForm/LoginForm.module.css.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -declare const styles: { - readonly form: string; - readonly field: string; -}; -export = styles; diff --git a/src/components/LoginForm/LoginForm.tsx b/src/components/LoginForm/LoginForm.tsx deleted file mode 100644 index 406bfb29..00000000 --- a/src/components/LoginForm/LoginForm.tsx +++ /dev/null @@ -1,64 +0,0 @@ -import * as React from 'react'; -import cn from 'classnames'; -import { Button } from '@mui/material'; -import { useForm } from 'react-hook-form'; -import { useMutation } from '@farfetched/react'; -import { joiResolver } from '@hookform/resolvers/joi'; -import { useTranslation } from 'react-i18next'; -import { LoginRequest } from '@/api'; -import { loginMutation } from '@/models'; -import { CommonProps } from '@/types'; -import { Checkbox, Field } from '@/shared/components'; -import { validationSchema } from './validator'; - -import styles from './LoginForm.module.css'; - -const initialValue: LoginRequest = { - login: '', - password: '', - rememberMe: false, -}; - -export const LoginForm: React.FC = ({ className }) => { - const { t } = useTranslation('login'); - const login = useMutation(loginMutation); - const { handleSubmit, formState, control } = useForm({ - defaultValues: initialValue, - resolver: joiResolver(validationSchema), - }); - const { isDirty, isSubmitting } = formState; - - return ( -
- - - - - - - ); -}; diff --git a/src/components/LoginForm/index.ts b/src/components/LoginForm/index.ts deleted file mode 100644 index ff006f50..00000000 --- a/src/components/LoginForm/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { LoginForm } from './LoginForm'; diff --git a/src/components/LoginForm/validator.ts b/src/components/LoginForm/validator.ts deleted file mode 100644 index 74baea32..00000000 --- a/src/components/LoginForm/validator.ts +++ /dev/null @@ -1,35 +0,0 @@ -import Joi from 'joi'; -import { LoginRequest } from '@/api'; -import { - allowedSymbolsRegExp, - maxLoginPasswordLength, - minLoginPasswordLength, -} from '@/const'; - -export const validationSchema = Joi.object({ - login: Joi.string() - .pattern(allowedSymbolsRegExp) - .min(minLoginPasswordLength) - .max(maxLoginPasswordLength) - .required() - .messages({ - 'string.empty': 'Login must be provided', - 'string.pattern.base': - 'Login can only contain latins alphas, numeric and !, *, (, ), _, +', - 'string.min': `Login must contain minimum ${minLoginPasswordLength} symbols`, - 'string.max': `Login must contain maximum ${maxLoginPasswordLength} symbols`, - }), - password: Joi.string() - .pattern(allowedSymbolsRegExp) - .min(minLoginPasswordLength) - .max(maxLoginPasswordLength) - .required() - .messages({ - 'string.empty': 'Password must be provided', - 'string.pattern.base': - 'Password can only contain latins alphas, numeric and !, *, (, ), _, +', - 'string.min': `Password must contain minimum ${minLoginPasswordLength} symbols`, - 'string.max': `Password must contain maximum ${maxLoginPasswordLength} symbols`, - }), - rememberMe: Joi.boolean(), -}); diff --git a/src/components/Popups/Popups.tsx b/src/components/Popups/Popups.tsx deleted file mode 100644 index 3b10627d..00000000 --- a/src/components/Popups/Popups.tsx +++ /dev/null @@ -1,43 +0,0 @@ -import * as React from 'react'; -import { popups } from '@/const'; -import { BasePopupProps } from '@/types'; -import { - CreateTaskPopup, - UpdateTaskPopup, - UpdateGroupPopup, - CreateGroupPopup, - CreateRoomPopup, - UpdateRoomPopup, -} from './components'; -import { usePopups } from './hooks'; - -const popupsMap: Record> = { - [popups.createTask]: CreateTaskPopup, - [popups.updateTask]: UpdateTaskPopup, - [popups.createGroup]: CreateGroupPopup, - [popups.updateGroup]: UpdateGroupPopup, - [popups.createRoom]: CreateRoomPopup, - [popups.updateRoom]: UpdateRoomPopup, -}; - -export const Popups = () => { - const { mountedPopups, popups } = usePopups(); - - return ( - <> - {mountedPopups.map((mountedPopup) => { - const Component = popupsMap[mountedPopup]; - - if (!Component) { - return null; - } - return ( - - ); - })} - - ); -}; diff --git a/src/components/Popups/components/CreateGroupPopup/CreateGroupPopup.module.css b/src/components/Popups/components/CreateGroupPopup/CreateGroupPopup.module.css deleted file mode 100644 index b4243be6..00000000 --- a/src/components/Popups/components/CreateGroupPopup/CreateGroupPopup.module.css +++ /dev/null @@ -1,3 +0,0 @@ -.form { - min-width: 550px; -} diff --git a/src/components/Popups/components/CreateGroupPopup/CreateGroupPopup.tsx b/src/components/Popups/components/CreateGroupPopup/CreateGroupPopup.tsx deleted file mode 100644 index 64677d2b..00000000 --- a/src/components/Popups/components/CreateGroupPopup/CreateGroupPopup.tsx +++ /dev/null @@ -1,46 +0,0 @@ -import * as React from 'react'; -import { useTranslation } from 'react-i18next'; -import { SubmitHandler } from 'react-hook-form'; -import { useUnit } from 'effector-react'; -import { useMutation } from '@farfetched/react'; -import { createGroupMutation, closeCreateGroupPopup } from '@/models'; -import { BasePopupProps, CommonProps } from '@/types'; -import { useParam } from '@/hooks'; -import { roomRoute } from '@/routes'; -import { MainPopup } from '@/shared/components'; -import { GroupForm, GroupFormValues } from '../GroupForm'; -import { defaultFormValues } from './data'; - -import styles from './CreateGroupPopup.module.css'; - -export interface CreateGroupPopupProps extends CommonProps, BasePopupProps {} - -export const CreateGroupPopup: React.FC = (props) => { - const { t, } = useTranslation('popups'); - const roomId = useParam(roomRoute, 'id'); - const onClose = useUnit(closeCreateGroupPopup); - const createGroup = useMutation(createGroupMutation); - - const onSubmit = React.useCallback>( - (values) => { - createGroup.start({ - ...values, - roomId, - }); - }, - [roomId] - ); - return ( - onClose()} - header={t('group.createTitle')}> - - - ); -}; diff --git a/src/components/Popups/components/CreateGroupPopup/data.ts b/src/components/Popups/components/CreateGroupPopup/data.ts deleted file mode 100644 index 06954305..00000000 --- a/src/components/Popups/components/CreateGroupPopup/data.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { GroupFormValues } from '../GroupForm'; - -export const defaultFormValues: GroupFormValues = { - mainColor: '#000000', - secondColor: '#ffffff', - name: 'Group name', -}; diff --git a/src/components/Popups/components/CreateGroupPopup/index.ts b/src/components/Popups/components/CreateGroupPopup/index.ts deleted file mode 100644 index 4ec77016..00000000 --- a/src/components/Popups/components/CreateGroupPopup/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { CreateGroupPopup } from './CreateGroupPopup'; diff --git a/src/components/Popups/components/CreateRoomPopup/CreateRoomPopup.module.css b/src/components/Popups/components/CreateRoomPopup/CreateRoomPopup.module.css deleted file mode 100644 index b4243be6..00000000 --- a/src/components/Popups/components/CreateRoomPopup/CreateRoomPopup.module.css +++ /dev/null @@ -1,3 +0,0 @@ -.form { - min-width: 550px; -} diff --git a/src/components/Popups/components/CreateRoomPopup/CreateRoomPopup.tsx b/src/components/Popups/components/CreateRoomPopup/CreateRoomPopup.tsx deleted file mode 100644 index 73edb29a..00000000 --- a/src/components/Popups/components/CreateRoomPopup/CreateRoomPopup.tsx +++ /dev/null @@ -1,35 +0,0 @@ -import * as React from 'react'; -import { useUnit } from 'effector-react'; -import { useMutation } from '@farfetched/react'; -import { useTranslation } from 'react-i18next'; -import { closeCreateRoomPopup, createRoomMutation } from '@/models'; -import { BasePopupProps } from '@/types'; -import { MainPopup } from '@/shared/components'; -import { RoomForm, RoomFormValues } from '../RoomForm'; - -import styles from './CreateRoomPopup.module.css'; - -const defaultValues: RoomFormValues = { - description: '', - name: '', -}; - -export const CreateRoomPopup: React.FC = (props) => { - const { t } = useTranslation('popups'); - const onClose = useUnit(closeCreateRoomPopup); - const createRoom = useMutation(createRoomMutation); - - return ( - onClose()}> - - - ); -}; diff --git a/src/components/Popups/components/CreateRoomPopup/index.ts b/src/components/Popups/components/CreateRoomPopup/index.ts deleted file mode 100644 index e264c437..00000000 --- a/src/components/Popups/components/CreateRoomPopup/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { CreateRoomPopup } from './CreateRoomPopup'; diff --git a/src/components/Popups/components/CreateTaskPopup/CreateTaskPopup.module.css b/src/components/Popups/components/CreateTaskPopup/CreateTaskPopup.module.css deleted file mode 100644 index b4243be6..00000000 --- a/src/components/Popups/components/CreateTaskPopup/CreateTaskPopup.module.css +++ /dev/null @@ -1,3 +0,0 @@ -.form { - min-width: 550px; -} diff --git a/src/components/Popups/components/CreateTaskPopup/CreateTaskPopup.tsx b/src/components/Popups/components/CreateTaskPopup/CreateTaskPopup.tsx deleted file mode 100644 index 19472e57..00000000 --- a/src/components/Popups/components/CreateTaskPopup/CreateTaskPopup.tsx +++ /dev/null @@ -1,60 +0,0 @@ -import * as React from 'react'; -import { SubmitHandler } from 'react-hook-form'; -import { useUnit } from 'effector-react'; -import { useMutation } from '@farfetched/react'; -import { useTranslation } from 'react-i18next'; -import { - $taskStatus, - closeCreateTaskPopup, - createTaskMutation, -} from '@/models'; -import { roomRoute } from '@/routes'; -import { useParam } from '@/hooks'; -import { BasePopupProps, CommonProps } from '@/types'; -import { MainPopup } from '@/shared/components'; -import { TaskForm, TaskFormValues } from '../TaskForm'; - -import styles from './CreateTaskPopup.module.css'; - -export interface CreateTaskPopupProps extends CommonProps, BasePopupProps {} - -export const CreateTaskPopup: React.FC = (props) => { - const { t } = useTranslation('popups'); - const roomId = useParam(roomRoute, 'id'); - const onClose = useUnit(closeCreateTaskPopup); - const status = useUnit($taskStatus) || 'ready'; - const createTask = useMutation(createTaskMutation); - - const onSubmit = React.useCallback>( - (values) => { - createTask.start({ - ...values, - roomId: Number(roomId), - }); - }, - [roomId] - ); - - const defaultState = React.useMemo( - () => ({ - content: '', - groupId: 0, - status, - }), - [status] - ); - - return ( - onClose()}> - - - ); -}; diff --git a/src/components/Popups/components/CreateTaskPopup/index.ts b/src/components/Popups/components/CreateTaskPopup/index.ts deleted file mode 100644 index 3a06a0cd..00000000 --- a/src/components/Popups/components/CreateTaskPopup/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { CreateTaskPopup, type CreateTaskPopupProps } from './CreateTaskPopup'; diff --git a/src/components/Popups/components/GroupForm/GroupForm.module.css b/src/components/Popups/components/GroupForm/GroupForm.module.css deleted file mode 100644 index 7812e8b0..00000000 --- a/src/components/Popups/components/GroupForm/GroupForm.module.css +++ /dev/null @@ -1,22 +0,0 @@ -.form { - display: grid; - grid-template-columns: repeat(2, 1fr); - gap: 15px; - - padding: 10px; -} - -.input { - grid-column: span 2; -} - -.colorInput { - align-self: end; - - height: 50px; -} - -.button { - grid-column: 2; - justify-self: end; -} diff --git a/src/components/Popups/components/GroupForm/GroupForm.module.css.d.ts b/src/components/Popups/components/GroupForm/GroupForm.module.css.d.ts deleted file mode 100644 index 9438674b..00000000 --- a/src/components/Popups/components/GroupForm/GroupForm.module.css.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -declare const styles: { - readonly form: string; - readonly input: string; - readonly colorInput: string; - readonly button: string; -}; -export = styles; diff --git a/src/components/Popups/components/GroupForm/GroupForm.tsx b/src/components/Popups/components/GroupForm/GroupForm.tsx deleted file mode 100644 index 3e231996..00000000 --- a/src/components/Popups/components/GroupForm/GroupForm.tsx +++ /dev/null @@ -1,64 +0,0 @@ -import * as React from 'react'; -import cn from 'classnames'; -import { Button } from '@mui/material'; -import { SubmitHandler, useForm } from 'react-hook-form'; -import { joiResolver } from '@hookform/resolvers/joi'; -import { useTranslation } from 'react-i18next'; -import { CommonProps } from '@/types'; -import { Field, GroupLabel } from '@/shared/components'; -import { validatingScheme } from './validator'; -import { GroupFormValues } from './types'; - -import styles from './GroupForm.module.css'; - -export interface GroupFormProps extends CommonProps { - readonly defaultValues: GroupFormValues; - readonly buttonText: string; - readonly onSubmit: SubmitHandler; -} - -export const GroupForm: React.FC = ({ - className, - defaultValues, - buttonText, - onSubmit, -}) => { - const { t } = useTranslation('popups'); - const { control, handleSubmit, watch, formState } = useForm({ - resolver: joiResolver(validatingScheme), - defaultValues, - }); - const state = watch(); - const { isDirty, isSubmitting } = formState; - return ( -
- {state.name && } - - - - - - ); -}; diff --git a/src/components/Popups/components/GroupForm/index.ts b/src/components/Popups/components/GroupForm/index.ts deleted file mode 100644 index 135fd630..00000000 --- a/src/components/Popups/components/GroupForm/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { GroupForm, type GroupFormProps } from './GroupForm'; -export * from './types'; diff --git a/src/components/Popups/components/GroupForm/types.ts b/src/components/Popups/components/GroupForm/types.ts deleted file mode 100644 index 4ae9355c..00000000 --- a/src/components/Popups/components/GroupForm/types.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { Group } from '@/models'; - -export interface GroupFormValues extends Omit {} diff --git a/src/components/Popups/components/GroupForm/validator.ts b/src/components/Popups/components/GroupForm/validator.ts deleted file mode 100644 index 8254ccde..00000000 --- a/src/components/Popups/components/GroupForm/validator.ts +++ /dev/null @@ -1,21 +0,0 @@ -import Joi from 'joi'; -import { allowedSymbolsRegExp } from '@/const'; -import { GroupFormValues } from './types'; - -const colorPattern = /#[0-9a-fA-F]{6}/; - -export const validatingScheme = Joi.object({ - mainColor: Joi.string().pattern(colorPattern).required().messages({ - 'string.empty': "Color can't be empty", - 'string.pattern.base': 'Color must be #XXXXXX, for example #ff00aa', - }), - secondColor: Joi.string().pattern(colorPattern).required().messages({ - 'string.empty': "Color can't be empty", - 'string.pattern.base': 'Color must be #XXXXXX, for example #ff00aa', - }), - name: Joi.string().pattern(allowedSymbolsRegExp).required().messages({ - 'string.empty': "Name can't be empty", - 'string.pattern.base': - 'Name can only contain latins alphas, numeric and !, *, (, ), _, +', - }), -}); diff --git a/src/components/Popups/components/RoomForm/RoomForm.module.css.d.ts b/src/components/Popups/components/RoomForm/RoomForm.module.css.d.ts deleted file mode 100644 index 8c006bc8..00000000 --- a/src/components/Popups/components/RoomForm/RoomForm.module.css.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -declare const styles: { - readonly form: string; - readonly button: string; -}; -export = styles; diff --git a/src/components/Popups/components/RoomForm/RoomForm.tsx b/src/components/Popups/components/RoomForm/RoomForm.tsx deleted file mode 100644 index 9cfddfa6..00000000 --- a/src/components/Popups/components/RoomForm/RoomForm.tsx +++ /dev/null @@ -1,51 +0,0 @@ -import * as React from 'react'; -import cn from 'classnames'; -import { Button, Stack } from '@mui/material'; -import { SubmitHandler, useForm } from 'react-hook-form'; -import { useTranslation } from 'react-i18next'; -import { joiResolver } from '@hookform/resolvers/joi'; -import { CommonProps } from '@/types'; -import { Field } from '@/shared/components'; -import { validatingScheme } from './validator'; -import { RoomFormValues } from './types'; - -import styles from './RoomForm.module.css'; - -export interface RoomFormProps extends CommonProps { - readonly onSubmit: SubmitHandler; - readonly buttonText: string; - readonly defaultValues: RoomFormValues; -} - -export const RoomForm: React.FC = ({ - onSubmit, - className, - defaultValues, - buttonText, -}) => { - const { t } = useTranslation('popups'); - const { formState, handleSubmit, control } = useForm({ - resolver: joiResolver(validatingScheme), - defaultValues, - }); - const { isDirty, isSubmitting } = formState; - const disabled = !isDirty || isSubmitting; - - return ( - - - - - - ); -}; diff --git a/src/components/Popups/components/RoomForm/index.ts b/src/components/Popups/components/RoomForm/index.ts deleted file mode 100644 index 9d55528c..00000000 --- a/src/components/Popups/components/RoomForm/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { RoomForm, type RoomFormProps } from './RoomForm'; -export * from './types'; diff --git a/src/components/Popups/components/RoomForm/types.ts b/src/components/Popups/components/RoomForm/types.ts deleted file mode 100644 index 004c2720..00000000 --- a/src/components/Popups/components/RoomForm/types.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { Room } from '@/models'; - -export interface RoomFormValues extends Pick {} diff --git a/src/components/Popups/components/RoomForm/validator.ts b/src/components/Popups/components/RoomForm/validator.ts deleted file mode 100644 index 85f548a3..00000000 --- a/src/components/Popups/components/RoomForm/validator.ts +++ /dev/null @@ -1,12 +0,0 @@ -import Joi from 'joi'; -import { RoomFormValues } from './types'; - -export const validatingScheme = Joi.object({ - name: Joi.string().max(32).required().messages({ - 'string.empty': "Room name can't be empty", - 'string.max': 'Room name must be less 32 characters', - }), - description: Joi.string().max(32).messages({ - 'string.max': 'Room name must be less 32 characters', - }), -}); diff --git a/src/components/Popups/components/SkeletonGroupForm/SkeletonGroupForm.module.css.d.ts b/src/components/Popups/components/SkeletonGroupForm/SkeletonGroupForm.module.css.d.ts deleted file mode 100644 index e81af766..00000000 --- a/src/components/Popups/components/SkeletonGroupForm/SkeletonGroupForm.module.css.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -declare const styles: { - readonly wrapper: string; - readonly input: string; - readonly colorInput: string; - readonly button: string; -}; -export = styles; diff --git a/src/components/Popups/components/SkeletonGroupForm/SkeletonGroupForm.tsx b/src/components/Popups/components/SkeletonGroupForm/SkeletonGroupForm.tsx deleted file mode 100644 index 79d285a9..00000000 --- a/src/components/Popups/components/SkeletonGroupForm/SkeletonGroupForm.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import * as React from 'react'; -import cn from 'classnames'; -import { Skeleton } from '@mui/material'; -import { CommonProps } from '@/types'; -import { SkeletonGroupLabel } from '@/shared/components/SkeletonGroupLabel'; - -import styles from './SkeletonGroupForm.module.css'; - -export interface SkeletonGroupFormProps extends CommonProps {} - -export const SkeletonGroupForm: React.FC = React.memo( - function SkeletonGroupForm(props) { - const { className } = props; - return ( -
- - - - - -
- ); - } -); diff --git a/src/components/Popups/components/SkeletonGroupForm/index.ts b/src/components/Popups/components/SkeletonGroupForm/index.ts deleted file mode 100644 index 7f78ec87..00000000 --- a/src/components/Popups/components/SkeletonGroupForm/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export { - SkeletonGroupForm, - type SkeletonGroupFormProps, -} from './SkeletonGroupForm'; diff --git a/src/components/Popups/components/SkeletonTaskForm/SkeletonTaskForm.module.css b/src/components/Popups/components/SkeletonTaskForm/SkeletonTaskForm.module.css deleted file mode 100644 index 9c3c1442..00000000 --- a/src/components/Popups/components/SkeletonTaskForm/SkeletonTaskForm.module.css +++ /dev/null @@ -1,24 +0,0 @@ -.form { - display: grid; - grid-template-columns: repeat(2, 1fr); - gap: 1em; - - width: 100%; -} - -.select { - width: 100%; - height: 4em; -} - -.field { - grid-column: span 2; - height: 6em; -} - -.button { - grid-column: 2; - justify-self: end; - width: 7em; - height: 3em; -} diff --git a/src/components/Popups/components/SkeletonTaskForm/SkeletonTaskForm.module.css.d.ts b/src/components/Popups/components/SkeletonTaskForm/SkeletonTaskForm.module.css.d.ts deleted file mode 100644 index e882febf..00000000 --- a/src/components/Popups/components/SkeletonTaskForm/SkeletonTaskForm.module.css.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -declare const styles: { - readonly form: string; - readonly select: string; - readonly field: string; - readonly button: string; -}; -export = styles; diff --git a/src/components/Popups/components/SkeletonTaskForm/SkeletonTaskForm.tsx b/src/components/Popups/components/SkeletonTaskForm/SkeletonTaskForm.tsx deleted file mode 100644 index 3b9d5e5a..00000000 --- a/src/components/Popups/components/SkeletonTaskForm/SkeletonTaskForm.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import * as React from 'react'; -import cn from 'classnames'; -import { Skeleton } from '@mui/material'; -import { CommonProps } from '@/types'; - -import styles from './SkeletonTaskForm.module.css'; - -export interface SkeletonTaskFormProps extends CommonProps {} - -export const SkeletonTaskForm: React.FC = React.memo( - function SkeletonTaskForm(props) { - const { className } = props; - return ( -
- - - - -
- ); - } -); diff --git a/src/components/Popups/components/SkeletonTaskForm/index.ts b/src/components/Popups/components/SkeletonTaskForm/index.ts deleted file mode 100644 index e2f1cad0..00000000 --- a/src/components/Popups/components/SkeletonTaskForm/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export { - SkeletonTaskForm, - type SkeletonTaskFormProps, -} from './SkeletonTaskForm'; diff --git a/src/components/Popups/components/TaskForm/TaskForm.module.css b/src/components/Popups/components/TaskForm/TaskForm.module.css deleted file mode 100644 index 6a916a6e..00000000 --- a/src/components/Popups/components/TaskForm/TaskForm.module.css +++ /dev/null @@ -1,16 +0,0 @@ -.form { - display: grid; - grid-template-columns: repeat(2, 1fr); - gap: 1em; - - padding: 0.5em; -} - -.field { - grid-column: span 2; -} - -.button { - grid-column: 2; - justify-self: end; -} diff --git a/src/components/Popups/components/TaskForm/TaskForm.module.css.d.ts b/src/components/Popups/components/TaskForm/TaskForm.module.css.d.ts deleted file mode 100644 index 2fbf0a73..00000000 --- a/src/components/Popups/components/TaskForm/TaskForm.module.css.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -declare const styles: { - readonly form: string; - readonly field: string; - readonly button: string; -}; -export = styles; diff --git a/src/components/Popups/components/TaskForm/TaskForm.tsx b/src/components/Popups/components/TaskForm/TaskForm.tsx deleted file mode 100644 index b9cc0f67..00000000 --- a/src/components/Popups/components/TaskForm/TaskForm.tsx +++ /dev/null @@ -1,70 +0,0 @@ -import * as React from 'react'; -import cn from 'classnames'; -import { Button, MenuItem, Skeleton } from '@mui/material'; -import { SubmitHandler, useForm } from 'react-hook-form'; -import { useTranslation } from 'react-i18next'; -import { useQuery } from '@farfetched/react'; -import { joiResolver } from '@hookform/resolvers/joi'; -import { getGroupsQuery, statuses } from '@/models'; -import { CommonProps } from '@/types'; -import { Field, GroupLabel } from '@/shared/components'; -import { validationScheme } from './validator'; -import { TaskFormValues } from './types'; - -import styles from './TaskForm.module.css'; - -export interface TaskFormProps extends CommonProps { - readonly defaultValues: TaskFormValues; - readonly buttonText: string; - readonly onSubmit: SubmitHandler; -} - -export const TaskForm: React.FC = React.memo((props) => { - const { buttonText, defaultValues, onSubmit, className } = props; - const { data: groups } = useQuery(getGroupsQuery); - const { t } = useTranslation('popups'); - const { handleSubmit, formState, control } = useForm({ - resolver: joiResolver(validationScheme), - defaultValues, - }); - const groupsLoading = !groups; - - const { isDirty, isSubmitting } = formState; - const disableButton = !isDirty || isSubmitting; - - return ( -
- {groupsLoading ? ( - - ) : ( - - {groups?.map((group) => ( - - - - ))} - - )} - - {statuses.map((name) => ( - - {t(`statuses.${name}`, { ns: 'task' })} - - ))} - - - - - ); -}); diff --git a/src/components/Popups/components/TaskForm/index.ts b/src/components/Popups/components/TaskForm/index.ts deleted file mode 100644 index 4e5ca1dd..00000000 --- a/src/components/Popups/components/TaskForm/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { TaskForm, type TaskFormProps } from './TaskForm'; -export * from './types'; diff --git a/src/components/Popups/components/TaskForm/types.ts b/src/components/Popups/components/TaskForm/types.ts deleted file mode 100644 index d4b4005a..00000000 --- a/src/components/Popups/components/TaskForm/types.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { Task } from '@/models'; - -export interface TaskFormValues - extends Pick {} diff --git a/src/components/Popups/components/TaskForm/validator.ts b/src/components/Popups/components/TaskForm/validator.ts deleted file mode 100644 index 96d03f54..00000000 --- a/src/components/Popups/components/TaskForm/validator.ts +++ /dev/null @@ -1,21 +0,0 @@ -import Joi from 'joi'; -import { allowedSymbolsRegExp } from '@/const'; -import { TaskFormValues } from './types'; - -export const validationScheme = Joi.object({ - groupId: Joi.number().required().messages({ - 'number.empty': 'Group must be choose', - 'number.positive': 'Group must be choose', - }), - status: Joi.string().required(), - content: Joi.string() - .pattern(allowedSymbolsRegExp) - .max(128) - .required() - .messages({ - 'string.empty': "Content can't be empty", - 'string.max': 'Content can be less than 128', - 'string.pattern.base': - 'Content can only contain latins alphas, numeric and !, *, (, ), _, +', - }), -}); diff --git a/src/components/Popups/components/UpdateGroupPopup/UpdateGroupPopup.module.css b/src/components/Popups/components/UpdateGroupPopup/UpdateGroupPopup.module.css deleted file mode 100644 index b4243be6..00000000 --- a/src/components/Popups/components/UpdateGroupPopup/UpdateGroupPopup.module.css +++ /dev/null @@ -1,3 +0,0 @@ -.form { - min-width: 550px; -} diff --git a/src/components/Popups/components/UpdateGroupPopup/UpdateGroupPopup.tsx b/src/components/Popups/components/UpdateGroupPopup/UpdateGroupPopup.tsx deleted file mode 100644 index 9d38844b..00000000 --- a/src/components/Popups/components/UpdateGroupPopup/UpdateGroupPopup.tsx +++ /dev/null @@ -1,66 +0,0 @@ -import * as React from 'react'; -import { useUnit } from 'effector-react'; -import { useMutation } from '@farfetched/react'; -import { useTranslation } from 'react-i18next'; -import { SubmitHandler } from 'react-hook-form'; -import { $groupId, closeUpdateGroupPopup, updateGroupMutation } from '@/models'; -import { roomRoute } from '@/routes'; -import { useGroup, useParam } from '@/hooks'; -import { BasePopupProps, CommonProps } from '@/types'; -import { MainPopup } from '@/shared/components'; -import { GroupForm, GroupFormValues } from '../GroupForm'; -import { SkeletonGroupForm } from '../SkeletonGroupForm'; - -import styles from './UpdateGroupPopup.module.css'; - -export interface UpdateGroupPopupProps extends CommonProps, BasePopupProps {} - -export const UpdateGroupPopup: React.FC< - React.PropsWithChildren -> = (props) => { - const { t, } = useTranslation('popups'); - const roomId = useParam(roomRoute, 'id'); - const id = useUnit($groupId); - const onClose = useUnit(closeUpdateGroupPopup); - const group = useGroup(Number(id)); - const updateGroup = useMutation(updateGroupMutation); - const isLoading = !group && id !== null; - - const onSubmit = React.useCallback>( - (values) => { - updateGroup.start({ - ...values, - roomId: Number(roomId), - id: Number(id), - }); - }, - [id, roomId] - ); - - const changeGroup = React.useMemo( - () => ({ - mainColor: group?.mainColor || '', - name: group?.name || '', - secondColor: group?.secondColor || '', - }), - [group] - ); - - return ( - onClose()} - header={t('group.updateTitle')}> - {isLoading ? ( - - ) : ( - - )} - - ); -}; diff --git a/src/components/Popups/components/UpdateGroupPopup/index.ts b/src/components/Popups/components/UpdateGroupPopup/index.ts deleted file mode 100644 index b1bd8177..00000000 --- a/src/components/Popups/components/UpdateGroupPopup/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export { - UpdateGroupPopup, - type UpdateGroupPopupProps, -} from './UpdateGroupPopup'; diff --git a/src/components/Popups/components/UpdateRoomPopup/UpdateRoomPopup.module.css b/src/components/Popups/components/UpdateRoomPopup/UpdateRoomPopup.module.css deleted file mode 100644 index b4243be6..00000000 --- a/src/components/Popups/components/UpdateRoomPopup/UpdateRoomPopup.module.css +++ /dev/null @@ -1,3 +0,0 @@ -.form { - min-width: 550px; -} diff --git a/src/components/Popups/components/UpdateRoomPopup/UpdateRoomPopup.tsx b/src/components/Popups/components/UpdateRoomPopup/UpdateRoomPopup.tsx deleted file mode 100644 index 60dc39ac..00000000 --- a/src/components/Popups/components/UpdateRoomPopup/UpdateRoomPopup.tsx +++ /dev/null @@ -1,60 +0,0 @@ -import * as React from 'react'; -import { useGate, useUnit } from 'effector-react'; -import { useMutation } from '@farfetched/react'; -import { SubmitHandler } from 'react-hook-form'; -import { useTranslation } from 'react-i18next'; -import { - getRoomQuery, - RoomGate, - updateRoomMutation, - $roomId, - closeUpdateRoomPopup, -} from '@/models'; -import { BasePopupProps } from '@/types'; -import { MainPopup, LoadingIndicator } from '@/shared/components'; -import { RoomForm, RoomFormValues } from '../RoomForm'; - -import styles from './UpdateRoomPopup.module.css'; - -export const UpdateRoomPopup: React.FC = (props) => { - const { t } = useTranslation('popups'); - const roomId = useUnit($roomId); - const room = useUnit(getRoomQuery.$data); - const onClose = useUnit(closeUpdateRoomPopup); - const updateRoom = useMutation(updateRoomMutation); - useGate(RoomGate, { roomId: Number(roomId) }); - - const loading = !room; - const onSubmit = React.useCallback>( - (values) => { - updateRoom.start({ ...values, id: Number(roomId) }); - }, - [roomId] - ); - - const defaultValues = React.useMemo( - () => ({ - description: room?.description || '', - name: room?.name || '', - }), - [room] - ); - - return ( - onClose()}> - {loading ? ( - - ) : ( - - )} - - ); -}; diff --git a/src/components/Popups/components/UpdateRoomPopup/index.ts b/src/components/Popups/components/UpdateRoomPopup/index.ts deleted file mode 100644 index 86317879..00000000 --- a/src/components/Popups/components/UpdateRoomPopup/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { UpdateRoomPopup } from './UpdateRoomPopup'; diff --git a/src/components/Popups/components/UpdateTaskPopup/UpdateTaskPopup.tsx b/src/components/Popups/components/UpdateTaskPopup/UpdateTaskPopup.tsx deleted file mode 100644 index 97b90618..00000000 --- a/src/components/Popups/components/UpdateTaskPopup/UpdateTaskPopup.tsx +++ /dev/null @@ -1,68 +0,0 @@ -import * as React from 'react'; -import { useMutation } from '@farfetched/react'; -import { useGate, useUnit } from 'effector-react'; -import { SubmitHandler } from 'react-hook-form'; -import { useTranslation } from 'react-i18next'; -import { - $taskId, - closeUpdateTaskPopup, - getTaskQuery, - TaskGate, - updateTaskMutation, -} from '@/models'; -import { BasePopupProps, CommonProps } from '@/types'; -import { roomRoute } from '@/routes'; -import { useParam } from '@/hooks'; -import { MainPopup } from '@/shared/components'; -import { TaskForm, TaskFormValues } from '../TaskForm'; -import { SkeletonTaskForm } from '../SkeletonTaskForm'; - -import styles from './UpdateTaskPopup.module.css'; - -export interface UpdateTaskPopupProps extends CommonProps, BasePopupProps {} - -export const UpdateTaskPopup: React.FC = (props) => { - const { t } = useTranslation('popups'); - const roomId = useParam(roomRoute, 'id'); - const id = useUnit($taskId)!; - const onClose = useUnit(closeUpdateTaskPopup); - const task = useUnit(getTaskQuery.$data); - const updateTask = useMutation(updateTaskMutation); - useGate(TaskGate, { id, roomId: Number(roomId) }); - - const onSubmit = React.useCallback>( - (values) => { - updateTask.start({ - ...values, - id, - roomId: Number(roomId), - }); - }, - [roomId, id] - ); - - const defaultValues = React.useMemo( - () => ({ - content: task?.content || '', - groupId: task?.groupId || 0, - status: task?.status || 'ready', - }), - [task] - ); - const loading = !task; - - return ( - - {loading ? ( - - ) : ( - - )} - - ); -}; diff --git a/src/components/Popups/components/UpdateTaskPopup/index.ts b/src/components/Popups/components/UpdateTaskPopup/index.ts deleted file mode 100644 index 1ed65feb..00000000 --- a/src/components/Popups/components/UpdateTaskPopup/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { UpdateTaskPopup, type UpdateTaskPopupProps } from './UpdateTaskPopup'; diff --git a/src/components/Popups/components/index.ts b/src/components/Popups/components/index.ts deleted file mode 100644 index 0e285569..00000000 --- a/src/components/Popups/components/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -export * from './CreateGroupPopup'; -export * from './CreateRoomPopup'; -export * from './CreateTaskPopup'; -export * from './UpdateGroupPopup'; -export * from './UpdateRoomPopup'; -export * from './UpdateTaskPopup'; diff --git a/src/components/Popups/hooks/index.ts b/src/components/Popups/hooks/index.ts deleted file mode 100644 index 557bf73e..00000000 --- a/src/components/Popups/hooks/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { usePopups } from './usePopups'; diff --git a/src/components/Popups/hooks/usePopups.ts b/src/components/Popups/hooks/usePopups.ts deleted file mode 100644 index 5d48f73c..00000000 --- a/src/components/Popups/hooks/usePopups.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { useEffect, useMemo, useState } from 'react'; -import { useUnit } from 'effector-react'; -import { $popups } from '@/models'; - -const parsePopups = (popups: string | null) => { - return popups ? popups.split(',') : []; -}; - -let timeoutId: null | number = null; - -export const usePopups = () => { - const rawPopups = useUnit($popups); - const [mountedPopups, setMountedPopups] = useState(() => - parsePopups(rawPopups) - ); - - useEffect(() => { - if (timeoutId) { - clearTimeout(timeoutId); - } - timeoutId = setTimeout( - () => setMountedPopups(parsePopups(rawPopups)), - 210 - ) as unknown as number; - }, [rawPopups]); - - const popups = useMemo(() => parsePopups(rawPopups), [rawPopups]); - - return { mountedPopups, popups }; -}; diff --git a/src/components/Popups/index.ts b/src/components/Popups/index.ts deleted file mode 100644 index 49437a27..00000000 --- a/src/components/Popups/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { Popups } from './Popups'; diff --git a/src/components/RegistrationForm/RegistrationForm.module.css b/src/components/RegistrationForm/RegistrationForm.module.css deleted file mode 100644 index 2bf9fede..00000000 --- a/src/components/RegistrationForm/RegistrationForm.module.css +++ /dev/null @@ -1,4 +0,0 @@ -.form { - display: grid; - row-gap: 1rem; -} diff --git a/src/components/RegistrationForm/RegistrationForm.tsx b/src/components/RegistrationForm/RegistrationForm.tsx deleted file mode 100644 index 665b5899..00000000 --- a/src/components/RegistrationForm/RegistrationForm.tsx +++ /dev/null @@ -1,65 +0,0 @@ -import * as React from 'react'; -import cn from 'classnames'; -import { useForm } from 'react-hook-form'; -import { Button } from '@mui/material'; -import { joiResolver } from '@hookform/resolvers/joi'; -import { useTranslation } from 'react-i18next'; -import { useMutation } from '@farfetched/react'; -import { RegistrationRequest } from '@/api'; -import { registrationMutation } from '@/models'; -import { CommonProps } from '@/types'; -import { Field } from '@/shared/components'; -import { validationSchema } from './validator'; - -import styles from './RegistrationForm.module.css'; - -const initialValues: RegistrationRequest = { - login: '', - password: '', - repeatPassword: '', -}; - -export const RegistrationForm: React.FC = ({ className }) => { - const { t } = useTranslation('registration'); - const registration = useMutation(registrationMutation); - const { control, handleSubmit, formState } = useForm({ - defaultValues: initialValues, - resolver: joiResolver(validationSchema), - }); - const { isSubmitting, isDirty } = formState; - return ( -
- - - - - - ); -}; diff --git a/src/components/RegistrationForm/index.ts b/src/components/RegistrationForm/index.ts deleted file mode 100644 index 4c551445..00000000 --- a/src/components/RegistrationForm/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { RegistrationForm } from './RegistrationForm'; diff --git a/src/components/RegistrationForm/validator.ts b/src/components/RegistrationForm/validator.ts deleted file mode 100644 index 6f00dd93..00000000 --- a/src/components/RegistrationForm/validator.ts +++ /dev/null @@ -1,37 +0,0 @@ -import Joi from 'joi'; -import { RegistrationRequest } from '@/api'; -import { - allowedSymbolsRegExp, - maxLoginPasswordLength, - minLoginPasswordLength, -} from '@/const'; - -export const validationSchema = Joi.object({ - login: Joi.string() - .pattern(allowedSymbolsRegExp) - .min(minLoginPasswordLength) - .max(maxLoginPasswordLength) - .required() - .messages({ - 'string.empty': 'Login must be provided', - 'string.pattern.base': - 'Login can only contain latins alphas, numeric and !, *, (, ), _, +', - 'string.min': `Login must contain minimum ${minLoginPasswordLength} symbols`, - 'string.max': `Login must contain maximum ${maxLoginPasswordLength} symbols`, - }), - password: Joi.string() - .pattern(allowedSymbolsRegExp) - .min(minLoginPasswordLength) - .max(maxLoginPasswordLength) - .required() - .messages({ - 'string.empty': 'Password must be provided', - 'string.pattern.base': - 'Password can only contain latins alphas, numeric and !, *, (, ), _, +', - 'string.min': `Password must contain minimum ${minLoginPasswordLength} symbols`, - 'string.max': `Password must contain maximum ${maxLoginPasswordLength} symbols`, - }), - repeatPassword: Joi.string().valid(Joi.ref('password')).messages({ - 'any.only': 'Password must be equal', - }), -}); diff --git a/src/components/RoomHeader/RoomHeader.module.css b/src/components/RoomHeader/RoomHeader.module.css deleted file mode 100644 index 3561a7cf..00000000 --- a/src/components/RoomHeader/RoomHeader.module.css +++ /dev/null @@ -1,12 +0,0 @@ -.header { - display: grid; - grid-template-columns: 1fr max-content; - column-gap: 1em; - align-items: center; - - padding: 2rem 0; -} - -.title { - font-weight: 700; -} diff --git a/src/components/RoomHeader/RoomHeader.tsx b/src/components/RoomHeader/RoomHeader.tsx deleted file mode 100644 index d293ebef..00000000 --- a/src/components/RoomHeader/RoomHeader.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import * as React from 'react'; -import cn from 'classnames'; -import { Skeleton, Typography } from '@mui/material'; -import { useUnit } from 'effector-react'; -import { getRoomQuery } from '@/models'; -import { CommonProps } from '@/types'; - -import styles from './RoomHeader.module.css'; - -export const RoomHeader: React.FC = (props) => { - const { className } = props; - const room = useUnit(getRoomQuery.$data); - const isLoading = !room; - - return ( -
- - {isLoading ? : room!.name} - -
- ); -}; diff --git a/src/components/RoomHeader/index.ts b/src/components/RoomHeader/index.ts deleted file mode 100644 index 6f73461c..00000000 --- a/src/components/RoomHeader/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { RoomHeader } from './RoomHeader'; diff --git a/src/components/RoomList/RoomList.module.css b/src/components/RoomList/RoomList.module.css deleted file mode 100644 index 06001e5c..00000000 --- a/src/components/RoomList/RoomList.module.css +++ /dev/null @@ -1,8 +0,0 @@ -.list { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(auto, 300px)); - gap: 1em; -} - -.card { -} diff --git a/src/components/RoomList/RoomList.module.css.d.ts b/src/components/RoomList/RoomList.module.css.d.ts deleted file mode 100644 index 3d566480..00000000 --- a/src/components/RoomList/RoomList.module.css.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -declare const styles: { - readonly list: string; - readonly card: string; -}; -export = styles; diff --git a/src/components/RoomList/RoomList.tsx b/src/components/RoomList/RoomList.tsx deleted file mode 100644 index e97106ba..00000000 --- a/src/components/RoomList/RoomList.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import * as React from 'react'; -import { useQuery } from '@farfetched/react'; -import { getRoomsQuery } from '@/models'; -import { getEmptyArray } from '@/const'; -import { RoomCard, SkeletonRoomCard } from './components'; - -import styles from './RoomList.module.css'; - -export const RoomList: React.FC = () => { - const { data } = useQuery(getRoomsQuery); - const isLoading = !data; - const items = isLoading - ? getEmptyArray(15).map((_, i) => ( - - )) - : data.map((room) => ( - - )); - - return
{items}
; -}; diff --git a/src/components/RoomList/components/RoomCard/RoomCard.module.css b/src/components/RoomList/components/RoomCard/RoomCard.module.css deleted file mode 100644 index 152376a5..00000000 --- a/src/components/RoomList/components/RoomCard/RoomCard.module.css +++ /dev/null @@ -1,16 +0,0 @@ -.card { - min-width: 200px; - height: min(max-content, 300px); - - padding: 1em; - - overflow-y: scroll; -} - -.header { - font-weight: 700; -} - -.content { - overflow-y: scroll; -} diff --git a/src/components/RoomList/components/RoomCard/RoomCard.module.css.d.ts b/src/components/RoomList/components/RoomCard/RoomCard.module.css.d.ts deleted file mode 100644 index 8faba931..00000000 --- a/src/components/RoomList/components/RoomCard/RoomCard.module.css.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -declare const styles: { - readonly card: string; - readonly header: string; - readonly content: string; -}; -export = styles; diff --git a/src/components/RoomList/components/RoomCard/RoomCard.tsx b/src/components/RoomList/components/RoomCard/RoomCard.tsx deleted file mode 100644 index fb329750..00000000 --- a/src/components/RoomList/components/RoomCard/RoomCard.tsx +++ /dev/null @@ -1,73 +0,0 @@ -import * as React from 'react'; -import cn from 'classnames'; -import { - Button, - Card, - CardActions, - CardContent, - CardHeader, - Typography -} from '@mui/material'; -import { Link } from 'atomic-router-react'; -import { useMutation } from '@farfetched/react'; -import { useTranslation } from 'react-i18next'; -import { removeRoomMutation, Room } from '@/models'; -import { roomRoute, roomsRoute } from '@/routes'; -import { getParams, popups } from '@/const'; -import { CommonProps } from '@/types'; -import { EditMenu, MenuOption } from '@/shared/components'; - -import styles from './RoomCard.module.css'; - -export interface RoomCardProps extends CommonProps, Room {} - -export const RoomCard: React.FC = ({ - id, - name, - className, - description, -}) => { - const { t, } = useTranslation('rooms'); - const removeRoom = useMutation(removeRoomMutation); - const options = React.useMemo[]>( - () => [ - { - label: t('actions.update', { ns: 'common', }), - to: roomsRoute, - params: {}, - query: { - [getParams.popup]: popups.updateRoom, - [getParams.roomId]: id, - }, - }, - { - label: t('actions.remove', { ns: 'common', }), - onClick: () => removeRoom.start({ id, }), - } - ], - [id] - ); - return ( - - } - title={name} - /> - - - {t('card.description')}: {description} - - - - - - - ); -}; diff --git a/src/components/RoomList/components/RoomCard/index.ts b/src/components/RoomList/components/RoomCard/index.ts deleted file mode 100644 index 3bfae548..00000000 --- a/src/components/RoomList/components/RoomCard/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { RoomCard, type RoomCardProps } from './RoomCard'; diff --git a/src/components/RoomList/components/SkeletonRoomCard/SkeletonRoomCard.module.css b/src/components/RoomList/components/SkeletonRoomCard/SkeletonRoomCard.module.css deleted file mode 100644 index 6aeb567a..00000000 --- a/src/components/RoomList/components/SkeletonRoomCard/SkeletonRoomCard.module.css +++ /dev/null @@ -1,6 +0,0 @@ -.card { - min-width: 200px; - height: min(max-content, 300px); - - padding: 1em; -} diff --git a/src/components/RoomList/components/SkeletonRoomCard/SkeletonRoomCard.tsx b/src/components/RoomList/components/SkeletonRoomCard/SkeletonRoomCard.tsx deleted file mode 100644 index 6df2fb12..00000000 --- a/src/components/RoomList/components/SkeletonRoomCard/SkeletonRoomCard.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import * as React from 'react'; -import cn from 'classnames'; -import { - Card, - CardActions, - CardContent, - CardHeader, - Skeleton, -} from '@mui/material'; -import { CommonProps } from '@/types'; - -import styles from './SkeletonRoomCard.module.css'; - -export interface SkeletonRoomCardProps extends CommonProps {} - -export const SkeletonRoomCard: React.FC = React.memo( - function SkeletonRoomCard(props) { - const { className } = props; - return ( - - } /> - - - - - - - - ); - } -); diff --git a/src/components/RoomList/components/SkeletonRoomCard/index.ts b/src/components/RoomList/components/SkeletonRoomCard/index.ts deleted file mode 100644 index 3fb7d3e7..00000000 --- a/src/components/RoomList/components/SkeletonRoomCard/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export { - SkeletonRoomCard, - type SkeletonRoomCardProps, -} from './SkeletonRoomCard'; diff --git a/src/components/RoomList/components/index.ts b/src/components/RoomList/components/index.ts deleted file mode 100644 index 92585c7b..00000000 --- a/src/components/RoomList/components/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './RoomCard'; -export * from './SkeletonRoomCard'; diff --git a/src/components/RoomList/index.ts b/src/components/RoomList/index.ts deleted file mode 100644 index 047c5163..00000000 --- a/src/components/RoomList/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { RoomList } from './RoomList'; diff --git a/src/components/RoomsHeader/RoomsHeader.module.css b/src/components/RoomsHeader/RoomsHeader.module.css deleted file mode 100644 index afb8ed90..00000000 --- a/src/components/RoomsHeader/RoomsHeader.module.css +++ /dev/null @@ -1,8 +0,0 @@ -.header { - display: grid; - grid-template-columns: 1fr max-content; - column-gap: 1em; - align-items: center; - - padding: 2rem 0; -} diff --git a/src/components/RoomsHeader/RoomsHeader.module.css.d.ts b/src/components/RoomsHeader/RoomsHeader.module.css.d.ts deleted file mode 100644 index e18b5266..00000000 --- a/src/components/RoomsHeader/RoomsHeader.module.css.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -declare const styles: { - readonly header: string; -}; -export = styles; diff --git a/src/components/RoomsHeader/RoomsHeader.tsx b/src/components/RoomsHeader/RoomsHeader.tsx deleted file mode 100644 index eb3b0908..00000000 --- a/src/components/RoomsHeader/RoomsHeader.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import * as React from 'react'; -import cn from 'classnames'; -import { Typography } from '@mui/material'; -import { useTranslation } from 'react-i18next'; -import { roomsRoute } from '@/routes'; -import { getParams, popups } from '@/const'; -import { CommonProps } from '@/types'; -import { EditMenu, MenuOption } from '@/shared/components'; - -import styles from './RoomsHeader.module.css'; - -export const RoomsHeader: React.FC = ({ className }) => { - const { t } = useTranslation('rooms'); - - const options = React.useMemo[]>( - () => [ - { - label: t('actions.create', { ns: 'common' }), - to: roomsRoute, - params: {}, - query: { - [getParams.popup]: popups.createRoom, - }, - }, - ], - [] - ); - return ( -
- - {t('title')} - - -
- ); -}; diff --git a/src/components/RoomsHeader/index.ts b/src/components/RoomsHeader/index.ts deleted file mode 100644 index 6699903b..00000000 --- a/src/components/RoomsHeader/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { RoomsHeader } from './RoomsHeader'; diff --git a/src/components/Tasks/Tasks.module.css b/src/components/Tasks/Tasks.module.css deleted file mode 100644 index cebe1420..00000000 --- a/src/components/Tasks/Tasks.module.css +++ /dev/null @@ -1,8 +0,0 @@ -.wrapper { - display: grid; - grid-template-columns: repeat(4, 1fr); - gap: 1.5rem; - - height: 100%; - width: 100%; -} diff --git a/src/components/Tasks/Tasks.tsx b/src/components/Tasks/Tasks.tsx deleted file mode 100644 index 53bbc060..00000000 --- a/src/components/Tasks/Tasks.tsx +++ /dev/null @@ -1,63 +0,0 @@ -/* eslint-disable sonarjs/no-duplicate-string */ -import * as React from 'react'; -import cn from 'classnames'; -import { useTranslation } from 'react-i18next'; -import { TaskStatus, Task } from '@/models'; -import { useGroupedTasks } from '@/hooks'; -import { CommonProps } from '@/types'; -import { TaskList } from './components'; - -import styles from './Tasks.module.css'; - -export interface Column { - readonly headerCode: string; - readonly tasks: Task[] | null; - readonly status: TaskStatus; -} - -export const Tasks: React.FC = (props) => { - const { className } = props; - const { t } = useTranslation('task'); - const { data: tasks } = useGroupedTasks(); - /* - TODO: Пересмотреть распределение на колонки - */ - const columns = React.useMemo( - () => [ - { - headerCode: 'ready', - tasks: tasks?.ready || null, - status: 'ready', - }, - { - headerCode: 'in progress', - tasks: tasks?.['in progress'] || null, - status: 'in progress', - }, - { - headerCode: 'review', - tasks: tasks?.needReview || null, - status: 'review', - }, - { - headerCode: 'done', - tasks: tasks?.done || null, - status: 'done', - }, - ], - [tasks] - ); - - return ( -
- {columns.map(({ headerCode, status, tasks }) => ( - - ))} -
- ); -}; diff --git a/src/components/Tasks/components/TaskList/TaskList.module.css.d.ts b/src/components/Tasks/components/TaskList/TaskList.module.css.d.ts deleted file mode 100644 index 90ef6add..00000000 --- a/src/components/Tasks/components/TaskList/TaskList.module.css.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -declare const styles: { - readonly wrapper: string; - readonly innerWrapper: string; - readonly list: string; -}; -export = styles; diff --git a/src/components/Tasks/components/TaskList/TaskList.tsx b/src/components/Tasks/components/TaskList/TaskList.tsx deleted file mode 100644 index bf3df66d..00000000 --- a/src/components/Tasks/components/TaskList/TaskList.tsx +++ /dev/null @@ -1,63 +0,0 @@ -import * as React from 'react'; -import cn from 'classnames'; -import { Stack } from '@mui/material'; -import { useMutation } from '@farfetched/react'; -import { TaskStatus, Task, updateTaskMutation } from '@/models'; -import { useParam } from '@/hooks'; -import { roomRoute } from '@/routes'; -import { getEmptyArray } from '@/const'; -import { CommonProps } from '@/types'; -import { SkeletonTaskCard, TaskCard, TaskListHeader } from './components'; - -import styles from './TaskList.module.css'; - -export interface TaskListProps extends CommonProps { - readonly tasks: Task[] | null; - readonly columnStatus: TaskStatus; - readonly header?: string | null; -} -const onDragOver: React.DragEventHandler = (evt) => - evt.preventDefault(); - -export const TaskList: React.FC = ({ - tasks, - className, - columnStatus, - header, -}) => { - const roomId = useParam(roomRoute, 'id'); - const moveTask = useMutation(updateTaskMutation); - const onDrop = React.useCallback( - (evt) => { - const id = +evt.dataTransfer.getData('taskId'); - const status = evt.dataTransfer.getData('status'); - if (status !== columnStatus && roomId != null) { - moveTask.start({ - status: columnStatus as TaskStatus, - roomId: Number(roomId), - id, - }); - } - }, - [roomId, columnStatus] - ); - - const loading = !tasks; - - return ( - - - {header} - - - {loading - ? getEmptyArray(4).map((_, i) => ) - : tasks.map((task) => )} - - - ); -}; diff --git a/src/components/Tasks/components/TaskList/components/SkeletonTaskCard/SkeletonTaskCard.tsx b/src/components/Tasks/components/TaskList/components/SkeletonTaskCard/SkeletonTaskCard.tsx deleted file mode 100644 index 46a882b5..00000000 --- a/src/components/Tasks/components/TaskList/components/SkeletonTaskCard/SkeletonTaskCard.tsx +++ /dev/null @@ -1,34 +0,0 @@ -/* eslint-disable react/no-array-index-key */ -import * as React from 'react'; -import { - Card, - CardContent, - CardHeader, - Skeleton, - Typography, -} from '@mui/material'; -import { CommonProps } from '@/types'; -import { SkeletonGroupLabel } from '@/shared/components/SkeletonGroupLabel'; - -export interface SkeletonTaskCardProps extends CommonProps { - readonly contentLinesCount?: number; -} - -export const SkeletonTaskCard: React.FC = React.memo( - function SkeletonTaskCard(props) { - const { className, contentLinesCount = 2 } = props; - const lines = Array(contentLinesCount).fill(0); - return ( - - } /> - - {lines.map((_, i) => ( - - - - ))} - - - ); - } -); diff --git a/src/components/Tasks/components/TaskList/components/SkeletonTaskCard/index.ts b/src/components/Tasks/components/TaskList/components/SkeletonTaskCard/index.ts deleted file mode 100644 index 75c2addf..00000000 --- a/src/components/Tasks/components/TaskList/components/SkeletonTaskCard/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export { - SkeletonTaskCard, - type SkeletonTaskCardProps, -} from './SkeletonTaskCard'; diff --git a/src/components/Tasks/components/TaskList/components/TaskCard/TaskCard.module.css b/src/components/Tasks/components/TaskList/components/TaskCard/TaskCard.module.css deleted file mode 100644 index ddc6e6d4..00000000 --- a/src/components/Tasks/components/TaskList/components/TaskCard/TaskCard.module.css +++ /dev/null @@ -1,19 +0,0 @@ -.card { - width: 100%; - - box-shadow: rgba(99, 99, 99, 0.1) 0px 2px 8px 0px; - - cursor: move; -} - -.card:hover { - box-shadow: rgba(99, 99, 99, 0.3) 0px 2px 8px 0px; -} - -.drag { - opacity: 0.1; -} - -.content { - word-break: break-all; -} diff --git a/src/components/Tasks/components/TaskList/components/TaskCard/TaskCard.module.css.d.ts b/src/components/Tasks/components/TaskList/components/TaskCard/TaskCard.module.css.d.ts deleted file mode 100644 index 707d6200..00000000 --- a/src/components/Tasks/components/TaskList/components/TaskCard/TaskCard.module.css.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -declare const styles: { - readonly card: string; - readonly drag: string; - readonly content: string; -}; -export = styles; diff --git a/src/components/Tasks/components/TaskList/components/TaskCard/TaskCard.tsx b/src/components/Tasks/components/TaskList/components/TaskCard/TaskCard.tsx deleted file mode 100644 index 57981922..00000000 --- a/src/components/Tasks/components/TaskList/components/TaskCard/TaskCard.tsx +++ /dev/null @@ -1,105 +0,0 @@ -import * as React from 'react'; -import cn from 'classnames'; -import { Card, CardContent, CardHeader, Typography } from '@mui/material'; -import EditIcon from '@mui/icons-material/Edit'; -import DeleteIcon from '@mui/icons-material/Delete'; -import { useTranslation } from 'react-i18next'; -import { useMutation } from '@farfetched/react'; -import { removeTaskMutation, Task } from '@/models'; -import { roomRoute } from '@/routes'; -import { useGroup } from '@/hooks'; -import { CommonProps } from '@/types'; -import { getParams, popups } from '@/const'; -import { - GroupLabel, - MenuOption, - DateTime, - EditMenu, - SkeletonGroupLabel, -} from '@/shared/components'; - -import styles from './TaskCard.module.css'; - -export interface TaskCardProps extends CommonProps, Task {} - -export const TaskCard: React.FC = React.memo((props) => { - const { className, content, createdAt, id, status, roomId, groupId } = props; - const { t } = useTranslation('common'); - const [isDrag, setIsDrag] = React.useState(false); - const group = useGroup(groupId); - const removeTask = useMutation(removeTaskMutation); - - const onDragStart = React.useCallback( - (evt) => { - evt.dataTransfer.clearData(); - evt.dataTransfer.setData('status', status.toString()); - evt.dataTransfer.setData('taskId', id.toString()); - setIsDrag(true); - }, - [status, id] - ); - - const onDragEnd = React.useCallback((evt) => { - setIsDrag(false); - evt.dataTransfer.clearData(); - }, []); - - const options = React.useMemo[]>( - () => [ - { - icon: , - label: t('actions.update'), - to: roomRoute, - params: { - id: roomId, - }, - query: { - [getParams.popup]: popups.updateTask, - [getParams.taskId]: id, - }, - }, - { - icon: , - label: t('actions.remove'), - onClick: () => removeTask.start({ id, roomId }), - }, - ], - [id, roomId] - ); - - if (group === null) { - return null; - } - - const title = group ? : ; - - return ( - - - } - title={title} - titleTypographyProps={{ component: 'div' }} - /> - - {content} -
- - - 0 - -
-
-
- ); -}); diff --git a/src/components/Tasks/components/TaskList/components/TaskCard/index.ts b/src/components/Tasks/components/TaskList/components/TaskCard/index.ts deleted file mode 100644 index ded095f1..00000000 --- a/src/components/Tasks/components/TaskList/components/TaskCard/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { TaskCard, type TaskCardProps } from './TaskCard'; diff --git a/src/components/Tasks/components/TaskList/components/TaskListHeader/TaskListHeader.module.css.d.ts b/src/components/Tasks/components/TaskList/components/TaskListHeader/TaskListHeader.module.css.d.ts deleted file mode 100644 index 51b8a012..00000000 --- a/src/components/Tasks/components/TaskList/components/TaskListHeader/TaskListHeader.module.css.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -declare const styles: { - readonly header: string; - readonly title: string; -}; -export = styles; diff --git a/src/components/Tasks/components/TaskList/components/TaskListHeader/TaskListHeader.tsx b/src/components/Tasks/components/TaskList/components/TaskListHeader/TaskListHeader.tsx deleted file mode 100644 index 4b685dbe..00000000 --- a/src/components/Tasks/components/TaskList/components/TaskListHeader/TaskListHeader.tsx +++ /dev/null @@ -1,49 +0,0 @@ -import * as React from 'react'; -import cn from 'classnames'; -import { Typography } from '@mui/material'; -import AddIcon from '@mui/icons-material/Add'; -import { useTranslation } from 'react-i18next'; -import { TaskStatus } from '@/models'; -import { roomRoute } from '@/routes'; -import { CommonProps } from '@/types'; -import { getParams, popups } from '@/const'; -import { EditMenu, MenuOption } from '@/shared/components'; - -import styles from './TaskListHeader.module.css'; - -export interface TaskListHeaderComponent extends CommonProps { - readonly columnStatus: TaskStatus; - readonly roomId: number; -} - -export const TaskListHeader: React.FC< - React.PropsWithChildren -> = (props) => { - const { children, className, columnStatus, roomId } = props; - const { t } = useTranslation('common'); - - const options = React.useMemo[]>( - () => [ - { - icon: , - label: t('actions.create'), - to: roomRoute, - params: { id: roomId }, - query: { - [getParams.popup]: popups.createTask, - [getParams.taskStatus]: columnStatus, - }, - }, - ], - [columnStatus] - ); - - return ( -
- - {children} - - -
- ); -}; diff --git a/src/components/Tasks/components/TaskList/components/TaskListHeader/index.ts b/src/components/Tasks/components/TaskList/components/TaskListHeader/index.ts deleted file mode 100644 index d753a7f4..00000000 --- a/src/components/Tasks/components/TaskList/components/TaskListHeader/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { TaskListHeader, type TaskListHeaderComponent } from './TaskListHeader'; diff --git a/src/components/Tasks/components/TaskList/components/index.ts b/src/components/Tasks/components/TaskList/components/index.ts deleted file mode 100644 index 581e728e..00000000 --- a/src/components/Tasks/components/TaskList/components/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './SkeletonTaskCard'; -export * from './TaskCard'; -export * from './TaskListHeader'; diff --git a/src/components/Tasks/components/TaskList/index.ts b/src/components/Tasks/components/TaskList/index.ts deleted file mode 100644 index 08bb3071..00000000 --- a/src/components/Tasks/components/TaskList/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { TaskList, type TaskListProps } from './TaskList'; diff --git a/src/components/Tasks/components/index.ts b/src/components/Tasks/components/index.ts deleted file mode 100644 index adcd4d61..00000000 --- a/src/components/Tasks/components/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './TaskList'; diff --git a/src/components/Tasks/index.ts b/src/components/Tasks/index.ts deleted file mode 100644 index ef693b54..00000000 --- a/src/components/Tasks/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { Tasks, type Column } from './Tasks'; diff --git a/src/components/index.ts b/src/components/index.ts deleted file mode 100644 index a2660da3..00000000 --- a/src/components/index.ts +++ /dev/null @@ -1,11 +0,0 @@ -export * from './AppRoutes'; -export * from './AsideBar'; -export * from './ErrorBoundary'; -export * from './Header'; -export * from './LoginForm'; -export * from './Popups'; -export * from './RegistrationForm'; -export * from './RoomHeader'; -export * from './RoomList'; -export * from './RoomsHeader'; -export * from './Tasks'; diff --git a/src/const/api.ts b/src/const/api.ts deleted file mode 100644 index d4ff7ea1..00000000 --- a/src/const/api.ts +++ /dev/null @@ -1,2 +0,0 @@ -export const base = import.meta.env.VITE_API_HOST; -export const api = `${base}/api`; diff --git a/src/const/forms.ts b/src/const/forms.ts deleted file mode 100644 index f34b603d..00000000 --- a/src/const/forms.ts +++ /dev/null @@ -1,4 +0,0 @@ -export const allowedSymbolsRegExp = /[a-zA-Z0-9_\- !*+()]/; - -export const minLoginPasswordLength = 6; -export const maxLoginPasswordLength = 32; diff --git a/src/const/routes.ts b/src/const/routes.ts deleted file mode 100644 index 2896c417..00000000 --- a/src/const/routes.ts +++ /dev/null @@ -1,26 +0,0 @@ -export const getParams = { - popup: 'popup', - taskStatus: 'task-status', - taskId: 'task-id', - groupId: 'group-id', - roomId: 'room-id', - tab: 'tab', -} as const; - -export const popups = { - createTask: 'create-task', - updateTask: 'update-task', - groups: 'groups', - createGroup: 'create-group', - updateGroup: 'update-group', - createRoom: 'create-room', - updateRoom: 'update-room', -} as const; - -export const paths = { - rooms: '/rooms', - room: '/rooms/:id', - login: '/login', - registration: '/registration', - settings: '/settings/:tab', -} as const; diff --git a/src/entities/activities/index.ts b/src/entities/activities/index.ts new file mode 100644 index 00000000..1f437247 --- /dev/null +++ b/src/entities/activities/index.ts @@ -0,0 +1,3 @@ +export * from './ui'; +export * from './model'; +export * from './lib'; diff --git a/src/entities/activities/lib/index.ts b/src/entities/activities/lib/index.ts new file mode 100644 index 00000000..924bc97d --- /dev/null +++ b/src/entities/activities/lib/index.ts @@ -0,0 +1,3 @@ +export * from './useActivitiesInRoom'; +export * from './use-activity-actions'; +export * from './use-activity-spheres'; diff --git a/src/entities/activities/lib/use-activity-actions.ts b/src/entities/activities/lib/use-activity-actions.ts new file mode 100644 index 00000000..03b41c40 --- /dev/null +++ b/src/entities/activities/lib/use-activity-actions.ts @@ -0,0 +1,7 @@ +import { useUnit } from 'effector-react'; + +import { activityActionsModel } from '../model'; + +export const useActivityActions = () => { + return useUnit(activityActionsModel.query); +}; diff --git a/src/entities/activities/lib/use-activity-spheres.ts b/src/entities/activities/lib/use-activity-spheres.ts new file mode 100644 index 00000000..a0db1c05 --- /dev/null +++ b/src/entities/activities/lib/use-activity-spheres.ts @@ -0,0 +1,7 @@ +import { useUnit } from 'effector-react'; + +import { activitySpheresModel } from '../model'; + +export const useActivitySpheres = () => { + return useUnit(activitySpheresModel.query); +}; diff --git a/src/entities/activities/lib/useActivitiesInRoom.ts b/src/entities/activities/lib/useActivitiesInRoom.ts new file mode 100644 index 00000000..2dac649b --- /dev/null +++ b/src/entities/activities/lib/useActivitiesInRoom.ts @@ -0,0 +1,7 @@ +import { useUnit } from 'effector-react'; + +import { activitiesInRoomModel } from '../model'; + +export const useActivitiesInRoom = () => { + return useUnit(activitiesInRoomModel.query); +}; diff --git a/src/entities/activities/model/activities-in-room.ts b/src/entities/activities/model/activities-in-room.ts new file mode 100644 index 00000000..036d0377 --- /dev/null +++ b/src/entities/activities/model/activities-in-room.ts @@ -0,0 +1,45 @@ +import { cache, createQuery } from '@farfetched/core'; +import { runtypeContract } from '@farfetched/runtypes'; +import { createDomain } from 'effector'; + +import { + Activity, + activity, + GetActivitiesInRoomParams, + activitiesApi +} from '@/shared/api'; +import { dataExtractor } from '@/shared/lib'; +import { + StandardResponse, + getStandardResponse, + PaginationResponse, + getPaginationResponse +} from '@/shared/types'; + +const activitiesDomain = createDomain(); +const handlerFx = activitiesDomain.effect< + GetActivitiesInRoomParams, + StandardResponse> +>(activitiesApi.getAll); + +export const query = createQuery< + GetActivitiesInRoomParams, + StandardResponse>, + Error, + StandardResponse>, + PaginationResponse +>({ + initialData: { items: [], totalCount: 0, limit: 50, }, + effect: handlerFx, + contract: runtypeContract( + getStandardResponse(getPaginationResponse(activity)) + ), + mapData: dataExtractor, +}); + +export const $hasItems = query.$data.map((data) => !!data.totalCount); +export const $pageCount = query.$data.map((data) => + Math.ceil(data.totalCount / data.limit) +); + +cache(query); diff --git a/src/entities/activities/model/activity-actions.ts b/src/entities/activities/model/activity-actions.ts new file mode 100644 index 00000000..e8d1741d --- /dev/null +++ b/src/entities/activities/model/activity-actions.ts @@ -0,0 +1,27 @@ +import { cache, createQuery } from '@farfetched/core'; +import { runtypeContract } from '@farfetched/runtypes'; +import { createDomain } from 'effector'; +import { Array } from 'runtypes'; + +import { activitiesApi, ActivityAction, activityAction } from '@/shared/api'; +import { dataExtractor } from '@/shared/lib'; +import { getStandardResponse, StandardResponse } from '@/shared/types'; + +const activityActions = createDomain(); + +const handlerFx = activityActions.effect(activitiesApi.getActions); + +export const query = createQuery< + void, + StandardResponse, + Error, + StandardResponse, + ActivityAction[] +>({ + initialData: [], + effect: handlerFx, + contract: runtypeContract(getStandardResponse(Array(activityAction))), + mapData: dataExtractor, +}); + +cache(query); diff --git a/src/entities/activities/model/activity-spheres.ts b/src/entities/activities/model/activity-spheres.ts new file mode 100644 index 00000000..e6e54ade --- /dev/null +++ b/src/entities/activities/model/activity-spheres.ts @@ -0,0 +1,27 @@ +import { cache, createQuery } from '@farfetched/core'; +import { runtypeContract } from '@farfetched/runtypes'; +import { createDomain } from 'effector'; +import { Array } from 'runtypes'; + +import { activitiesApi, ActivitySphere, activitySphere } from '@/shared/api'; +import { dataExtractor } from '@/shared/lib'; +import { getStandardResponse, StandardResponse } from '@/shared/types'; + +const activitySpheres = createDomain(); + +const handlerFx = activitySpheres.effect(activitiesApi.getSpheres); + +export const query = createQuery< + void, + StandardResponse, + Error, + StandardResponse, + ActivitySphere[] +>({ + initialData: [], + effect: handlerFx, + contract: runtypeContract(getStandardResponse(Array(activitySphere))), + mapData: dataExtractor, +}); + +cache(query); diff --git a/src/entities/activities/model/index.ts b/src/entities/activities/model/index.ts new file mode 100644 index 00000000..f0866299 --- /dev/null +++ b/src/entities/activities/model/index.ts @@ -0,0 +1,3 @@ +export * as activitiesInRoomModel from './activities-in-room'; +export * as activityActionsModel from './activity-actions'; +export * as activitySpheresModel from './activity-spheres'; diff --git a/src/entities/activities/ui/activities-actions-picker/activities-actions-picker.tsx b/src/entities/activities/ui/activities-actions-picker/activities-actions-picker.tsx new file mode 100644 index 00000000..8268ce9b --- /dev/null +++ b/src/entities/activities/ui/activities-actions-picker/activities-actions-picker.tsx @@ -0,0 +1,80 @@ +import { + Autocomplete, + Chip, + ListItem, + ListItemAvatar, + ListItemText +} from '@mui/material'; +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { ActivityAction } from '@/shared/api'; +import { preparePickerHandler, preparePickerSelectedValue } from '@/shared/lib'; +import { CommonProps, PickerProps } from '@/shared/types'; +import { Field, FieldProps } from '@/shared/ui'; + +import { useActivityActions } from '../../lib'; +import { ActivityActionPicture } from '../activity-action-picture'; + +export type ActivitiesActionsPickerProps = CommonProps & + PickerProps & + Omit; + +export const ActivitiesActionsPicker: React.FC = + React.memo((props) => { + const { value, onChange, className, multiple, limitTags, ...rest } = props; + const actions = useActivityActions(); + const { t, } = useTranslation('activities'); + + const changeHandler = preparePickerHandler( + { multiple, onChange, }, + 'id' + ); + + const selected = preparePickerSelectedValue( + { value, multiple, }, + actions.data, + 'id' + ); + + const translate = (name: string) => { + return t(`type.${name}`); + }; + + return ( + actions.name} + renderOption={(props, option) => { + const activity = translate(option.name); + + return ( + + + + + {activity} + + ); + }} + renderInput={(params) => { + return ; + }} + renderTags={(value, getTagProps) => { + return value.map((option, index) => ( + + )); + }} + limitTags={limitTags} + multiple={multiple} + /> + ); + }); diff --git a/src/entities/activities/ui/activities-actions-picker/index.ts b/src/entities/activities/ui/activities-actions-picker/index.ts new file mode 100644 index 00000000..7061639c --- /dev/null +++ b/src/entities/activities/ui/activities-actions-picker/index.ts @@ -0,0 +1,4 @@ +export { + ActivitiesActionsPicker, + type ActivitiesActionsPickerProps +} from './activities-actions-picker'; diff --git a/src/entities/activities/ui/activities-spheres-picker/activities-spheres-picker.tsx b/src/entities/activities/ui/activities-spheres-picker/activities-spheres-picker.tsx new file mode 100644 index 00000000..f06216d0 --- /dev/null +++ b/src/entities/activities/ui/activities-spheres-picker/activities-spheres-picker.tsx @@ -0,0 +1,70 @@ +import { Autocomplete, Chip, ListItem, ListItemText } from '@mui/material'; +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { ActivitySphere } from '@/shared/api'; +import { preparePickerHandler, preparePickerSelectedValue } from '@/shared/lib'; +import { CommonProps, PickerProps } from '@/shared/types'; +import { Field, FieldProps } from '@/shared/ui'; + +import { useActivitySpheres } from '../../lib'; + +export type ActivitiesSpheresPickerProps = CommonProps & + PickerProps & + Omit; + +export const ActivitiesSpheresPicker: React.FC = + React.memo((props) => { + const { value, onChange, multiple, limitTags, className, ...rest } = props; + const spheres = useActivitySpheres(); + const { t, } = useTranslation('activities'); + + const changeHandler = preparePickerHandler( + { multiple, onChange, }, + 'id' + ); + + const selected = preparePickerSelectedValue( + { value, multiple, }, + spheres.data, + 'id' + ); + + const translate = (name: string) => { + return t(`spheres.${name}`); + }; + + return ( + sphere.name} + renderInput={(params) => { + return ; + }} + renderTags={(value, getTagProps) => { + return value.map((option, index) => ( + + )); + }} + renderOption={(props, option) => { + const activity = translate(option.name); + + return ( + + {activity} + + ); + }} + limitTags={limitTags} + multiple={multiple} + /> + ); + }); diff --git a/src/entities/activities/ui/activities-spheres-picker/index.ts b/src/entities/activities/ui/activities-spheres-picker/index.ts new file mode 100644 index 00000000..e8044722 --- /dev/null +++ b/src/entities/activities/ui/activities-spheres-picker/index.ts @@ -0,0 +1,4 @@ +export { + ActivitiesSpheresPicker, + type ActivitiesSpheresPickerProps +} from './activities-spheres-picker'; diff --git a/src/entities/activities/ui/activity-action-picture/activity-action-picture.module.css b/src/entities/activities/ui/activity-action-picture/activity-action-picture.module.css new file mode 100644 index 00000000..b4a27cc2 --- /dev/null +++ b/src/entities/activities/ui/activity-action-picture/activity-action-picture.module.css @@ -0,0 +1,15 @@ +.avatar { + background-color: var(--activity-card-avatar-color); +} + +.error { + --activity-card-avatar-color: var(--mui-palette-error-light); +} + +.warning { + --activity-card-avatar-color: var(--mui-palette-warning-light); +} + +.success { + --activity-card-avatar-color: var(--mui-palette-success-light); +} diff --git a/src/entities/activities/ui/activity-action-picture/activity-action-picture.module.css.d.ts b/src/entities/activities/ui/activity-action-picture/activity-action-picture.module.css.d.ts new file mode 100644 index 00000000..bbad13bb --- /dev/null +++ b/src/entities/activities/ui/activity-action-picture/activity-action-picture.module.css.d.ts @@ -0,0 +1,7 @@ +declare const styles: { + readonly avatar: string; + readonly error: string; + readonly success: string; + readonly warning: string; +}; +export = styles; diff --git a/src/entities/activities/ui/activity-action-picture/activity-action-picture.tsx b/src/entities/activities/ui/activity-action-picture/activity-action-picture.tsx new file mode 100644 index 00000000..5955440b --- /dev/null +++ b/src/entities/activities/ui/activity-action-picture/activity-action-picture.tsx @@ -0,0 +1,42 @@ +import AddIcon from '@mui/icons-material/Add'; +import DeleteIcon from '@mui/icons-material/Delete'; +import EditIcon from '@mui/icons-material/Edit'; +import { Avatar } from '@mui/material'; +import cn from 'classnames'; +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { ActivityAction } from '@/shared/api'; +import { CommonProps } from '@/shared/types'; + +import styles from './activity-action-picture.module.css'; + +export interface ActivityActionPictureProps + extends CommonProps, + ActivityAction {} + +const colorMap: Record = { + create: 'success', + remove: 'error', + update: 'warning', +}; + +const iconMap: Record = { + create: , + remove: , + update: , +}; + +export const ActivityActionPicture: React.FC = + React.memo((props) => { + const { name, className, } = props; + const { t, } = useTranslation('room'); + + return ( + + {iconMap[name]} + + ); + }); diff --git a/src/entities/activities/ui/activity-action-picture/index.ts b/src/entities/activities/ui/activity-action-picture/index.ts new file mode 100644 index 00000000..8f7ad465 --- /dev/null +++ b/src/entities/activities/ui/activity-action-picture/index.ts @@ -0,0 +1,4 @@ +export { + ActivityActionPicture, + type ActivityActionPictureProps +} from './activity-action-picture'; diff --git a/src/entities/activities/ui/activity-list-item/activity-list-item.module.css b/src/entities/activities/ui/activity-list-item/activity-list-item.module.css new file mode 100644 index 00000000..e89302c1 --- /dev/null +++ b/src/entities/activities/ui/activity-list-item/activity-list-item.module.css @@ -0,0 +1,8 @@ +.item { + overflow: unset; +} + +.content { + display: flex; + column-gap: 1.25em; +} diff --git a/src/entities/activities/ui/activity-list-item/activity-list-item.module.css.d.ts b/src/entities/activities/ui/activity-list-item/activity-list-item.module.css.d.ts new file mode 100644 index 00000000..964c2400 --- /dev/null +++ b/src/entities/activities/ui/activity-list-item/activity-list-item.module.css.d.ts @@ -0,0 +1,5 @@ +declare const styles: { + readonly content: string; + readonly item: string; +}; +export = styles; diff --git a/src/entities/activities/ui/activity-list-item/activity-list-item.tsx b/src/entities/activities/ui/activity-list-item/activity-list-item.tsx new file mode 100644 index 00000000..8406fb0f --- /dev/null +++ b/src/entities/activities/ui/activity-list-item/activity-list-item.tsx @@ -0,0 +1,53 @@ +import { + ListItem, + ListItemAvatar, + ListItemProps, + ListItemText +} from '@mui/material'; +import cn from 'classnames'; +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { Activity } from '@/shared/api'; +import { CommonProps } from '@/shared/types'; +import { DateTime } from '@/shared/ui'; + +import { ActivityActionPicture } from '../activity-action-picture'; + +import styles from './activity-list-item.module.css'; + +export interface ActivityListItemProps + extends CommonProps, + Activity, + Omit {} + +export const ActivityListItem: React.FC = (props) => { + const { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + id: _, + action, + sphere, + className, + createdAt, + activist, + ...rest + } = props; + const { t, } = useTranslation('activities'); + const activityText = t('card.text', { + type: action.name, + sphere: sphere.name, + activist: activist.username, + }); + + return ( + + + + + } + /> + + ); +}; diff --git a/src/entities/activities/ui/activity-list-item/index.ts b/src/entities/activities/ui/activity-list-item/index.ts new file mode 100644 index 00000000..0580ecc4 --- /dev/null +++ b/src/entities/activities/ui/activity-list-item/index.ts @@ -0,0 +1,4 @@ +export { + ActivityListItem, + type ActivityListItemProps +} from './activity-list-item'; diff --git a/src/entities/activities/ui/index.ts b/src/entities/activities/ui/index.ts new file mode 100644 index 00000000..09da7399 --- /dev/null +++ b/src/entities/activities/ui/index.ts @@ -0,0 +1,4 @@ +export * from './activity-list-item'; +export * from './skeleton-activity-list-item'; +export * from './activities-actions-picker'; +export * from './activities-spheres-picker'; diff --git a/src/entities/activities/ui/skeleton-activity-list-item/index.ts b/src/entities/activities/ui/skeleton-activity-list-item/index.ts new file mode 100644 index 00000000..5c8a449a --- /dev/null +++ b/src/entities/activities/ui/skeleton-activity-list-item/index.ts @@ -0,0 +1,4 @@ +export { + SkeletonActivityListItem, + type SkeletonActivityListItemProps +} from './skeleton-activity-list-item'; diff --git a/src/entities/activities/ui/skeleton-activity-list-item/skeleton-activity-list-item.module.css b/src/entities/activities/ui/skeleton-activity-list-item/skeleton-activity-list-item.module.css new file mode 100644 index 00000000..3765ef01 --- /dev/null +++ b/src/entities/activities/ui/skeleton-activity-list-item/skeleton-activity-list-item.module.css @@ -0,0 +1,16 @@ +.item { + overflow: unset; +} + +.content { + display: grid; + grid-template-columns: max-content 1fr; + grid-template-rows: max-content 1fr; + column-gap: 1.25em; +} + +.block { + grid-row: span 2; + + width: 100%; +} diff --git a/src/entities/activities/ui/skeleton-activity-list-item/skeleton-activity-list-item.module.css.d.ts b/src/entities/activities/ui/skeleton-activity-list-item/skeleton-activity-list-item.module.css.d.ts new file mode 100644 index 00000000..0dac9c34 --- /dev/null +++ b/src/entities/activities/ui/skeleton-activity-list-item/skeleton-activity-list-item.module.css.d.ts @@ -0,0 +1,6 @@ +declare const styles: { + readonly block: string; + readonly content: string; + readonly item: string; +}; +export = styles; diff --git a/src/entities/activities/ui/skeleton-activity-list-item/skeleton-activity-list-item.tsx b/src/entities/activities/ui/skeleton-activity-list-item/skeleton-activity-list-item.tsx new file mode 100644 index 00000000..0764b567 --- /dev/null +++ b/src/entities/activities/ui/skeleton-activity-list-item/skeleton-activity-list-item.tsx @@ -0,0 +1,36 @@ +import { + Avatar, + ListItem, + ListItemAvatar, + ListItemProps, + ListItemText, + Skeleton +} from '@mui/material'; +import cn from 'classnames'; +import * as React from 'react'; + +import { CommonProps } from '@/shared/types'; + +import styles from './skeleton-activity-list-item.module.css'; + +export interface SkeletonActivityListItemProps + extends CommonProps, + ListItemProps {} + +export const SkeletonActivityListItem: React.FC = + React.memo(function SkeletonActivityCard(props) { + const { className, ...rest } = props; + return ( + + + + + + + } + secondary={} + /> + + ); + }); diff --git a/src/entities/comments/index.ts b/src/entities/comments/index.ts new file mode 100644 index 00000000..1f437247 --- /dev/null +++ b/src/entities/comments/index.ts @@ -0,0 +1,3 @@ +export * from './ui'; +export * from './model'; +export * from './lib'; diff --git a/src/entities/comments/lib/index.ts b/src/entities/comments/lib/index.ts new file mode 100644 index 00000000..8f69ffd2 --- /dev/null +++ b/src/entities/comments/lib/index.ts @@ -0,0 +1 @@ +export * from './use-comments'; diff --git a/src/entities/comments/lib/use-comments.ts b/src/entities/comments/lib/use-comments.ts new file mode 100644 index 00000000..758a1a62 --- /dev/null +++ b/src/entities/comments/lib/use-comments.ts @@ -0,0 +1,7 @@ +import { useUnit } from 'effector-react'; + +import { commentsModel } from '../model'; + +export const useComments = () => { + return useUnit(commentsModel.query); +}; diff --git a/src/entities/comments/model/comments.ts b/src/entities/comments/model/comments.ts new file mode 100644 index 00000000..17abd196 --- /dev/null +++ b/src/entities/comments/model/comments.ts @@ -0,0 +1,21 @@ +import { cache, createQuery } from '@farfetched/core'; +import { runtypeContract } from '@farfetched/runtypes'; +import { createDomain } from 'effector'; +import { Array } from 'runtypes'; + +import { Comment, comment, commentsApi } from '@/shared/api'; +import { dataExtractor } from '@/shared/lib'; +import { getStandardResponse } from '@/shared/types'; + +const commentsDomain = createDomain(); + +const handlerFx = commentsDomain.effect(commentsApi.getAll); + +export const query = createQuery({ + initialData: [] as Comment[], + effect: handlerFx, + contract: runtypeContract(getStandardResponse(Array(comment))), + mapData: dataExtractor, +}); + +cache(query); diff --git a/src/entities/comments/model/index.ts b/src/entities/comments/model/index.ts new file mode 100644 index 00000000..578defde --- /dev/null +++ b/src/entities/comments/model/index.ts @@ -0,0 +1 @@ +export * as commentsModel from './comments'; diff --git a/src/entities/comments/ui/index.ts b/src/entities/comments/ui/index.ts new file mode 100644 index 00000000..0d0f780a --- /dev/null +++ b/src/entities/comments/ui/index.ts @@ -0,0 +1 @@ +export * from './template-comment-card'; diff --git a/src/entities/comments/ui/template-comment-card/index.ts b/src/entities/comments/ui/template-comment-card/index.ts new file mode 100644 index 00000000..ef9269b4 --- /dev/null +++ b/src/entities/comments/ui/template-comment-card/index.ts @@ -0,0 +1,4 @@ +export { + TemplateCommentCard, + type TemplateCommentCardProps +} from './template-comment-card'; diff --git a/src/entities/comments/ui/template-comment-card/template-comment-card.tsx b/src/entities/comments/ui/template-comment-card/template-comment-card.tsx new file mode 100644 index 00000000..410be55c --- /dev/null +++ b/src/entities/comments/ui/template-comment-card/template-comment-card.tsx @@ -0,0 +1,23 @@ +import { Card, CardContent, Typography } from '@mui/material'; +import * as React from 'react'; + +import { Comment } from '@/shared/api'; +import { CommonProps } from '@/shared/types'; + +export interface TemplateCommentCardProps extends CommonProps, Comment { + readonly actions?: React.ReactElement | null; +} + +export const TemplateCommentCard: React.FC = ( + props +) => { + const { content, className, } = props; + + return ( + + + {content} + + + ); +}; diff --git a/src/entities/invitations/index.ts b/src/entities/invitations/index.ts new file mode 100644 index 00000000..452c4133 --- /dev/null +++ b/src/entities/invitations/index.ts @@ -0,0 +1,2 @@ +export * from './models'; +export * from './ui'; diff --git a/src/entities/invitations/models/index.ts b/src/entities/invitations/models/index.ts new file mode 100644 index 00000000..e9feb6db --- /dev/null +++ b/src/entities/invitations/models/index.ts @@ -0,0 +1,2 @@ +export * as invitationsModel from './invitations'; +export * as invitationViaTokenModel from './invitation-via-token'; diff --git a/src/entities/invitations/models/invitation-via-token.ts b/src/entities/invitations/models/invitation-via-token.ts new file mode 100644 index 00000000..83a0b60c --- /dev/null +++ b/src/entities/invitations/models/invitation-via-token.ts @@ -0,0 +1,35 @@ +import { cache, createQuery } from '@farfetched/core'; +import { runtypeContract } from '@farfetched/runtypes'; +import { combine, createEffect, sample } from 'effector'; + +import { invitation, invitationsApi } from '@/shared/api'; +import { i18n } from '@/shared/configs'; +import { notificationsModel } from '@/shared/models'; +import { getStandardResponse } from '@/shared/types'; + +const handlerFx = createEffect(invitationsApi.getViaToken); + +export const query = createQuery({ + initialData: null, + effect: handlerFx, + contract: runtypeContract(getStandardResponse(invitation)), + mapData: ({ result, }) => result.data, +}); + +export const $loaded = combine(query.$data, (data) => { + return !!data; +}); + +sample({ + clock: query.finished.failure, + fn: () => + ({ + message: i18n.t('actions.via-token.notifications.error', { + ns: 'room-invitation', + }), + color: 'error', + } as const), + target: notificationsModel.create, +}); + +cache(query); diff --git a/src/entities/invitations/models/invitations.ts b/src/entities/invitations/models/invitations.ts new file mode 100644 index 00000000..42aa9bbb --- /dev/null +++ b/src/entities/invitations/models/invitations.ts @@ -0,0 +1,18 @@ +import { cache, createQuery } from '@farfetched/core'; +import { runtypeContract } from '@farfetched/runtypes'; +import { createEffect } from 'effector'; +import { Array } from 'runtypes'; + +import { invitation, invitationsApi } from '@/shared/api'; +import { getStandardResponse } from '@/shared/types'; + +const handlerFx = createEffect(invitationsApi.getAll); + +export const query = createQuery({ + initialData: [], + effect: handlerFx, + contract: runtypeContract(getStandardResponse(Array(invitation))), + mapData: ({ result, }) => result.data, +}); + +cache(query); diff --git a/src/entities/invitations/ui/index.ts b/src/entities/invitations/ui/index.ts new file mode 100644 index 00000000..4c9f5a35 --- /dev/null +++ b/src/entities/invitations/ui/index.ts @@ -0,0 +1,4 @@ +export * from './template-invitation-list-item'; +export * from './skeleton-invitation-list-item'; +export * from './template-invitation-card'; +export * from './skeleton-invitation-card'; diff --git a/src/entities/invitations/ui/skeleton-invitation-card/index.ts b/src/entities/invitations/ui/skeleton-invitation-card/index.ts new file mode 100644 index 00000000..70cb8af8 --- /dev/null +++ b/src/entities/invitations/ui/skeleton-invitation-card/index.ts @@ -0,0 +1 @@ +export { SkeletonInvitationCard, type SkeletonInvitationCardProps } from './ui'; diff --git a/src/entities/invitations/ui/skeleton-invitation-card/ui.tsx b/src/entities/invitations/ui/skeleton-invitation-card/ui.tsx new file mode 100644 index 00000000..fab49578 --- /dev/null +++ b/src/entities/invitations/ui/skeleton-invitation-card/ui.tsx @@ -0,0 +1,36 @@ +import { Avatar, Card, CardContent, CardHeader, Skeleton } from '@mui/material'; +import * as React from 'react'; + +import { CommonProps } from '@/shared/types'; + +export interface SkeletonInvitationCardProps extends CommonProps {} + +export const SkeletonInvitationCard: React.FC = ( + props +) => { + const { className, } = props; + + return ( + + + +
+ } + title={} + disableTypography + /> + + + + + + + + + + + + ); +}; diff --git a/src/entities/invitations/ui/skeleton-invitation-list-item/index.ts b/src/entities/invitations/ui/skeleton-invitation-list-item/index.ts new file mode 100644 index 00000000..be065a81 --- /dev/null +++ b/src/entities/invitations/ui/skeleton-invitation-list-item/index.ts @@ -0,0 +1,4 @@ +export { + SkeletonInvitationListItem, + type SkeletonInvitationListItemProps +} from './skeleton-invitation-list-item'; diff --git a/src/entities/invitations/ui/skeleton-invitation-list-item/skeleton-invitation-list-item.module.css b/src/entities/invitations/ui/skeleton-invitation-list-item/skeleton-invitation-list-item.module.css new file mode 100644 index 00000000..37ffb2a4 --- /dev/null +++ b/src/entities/invitations/ui/skeleton-invitation-list-item/skeleton-invitation-list-item.module.css @@ -0,0 +1,3 @@ +.card { + width: 100%; +} diff --git a/src/components/RoomList/components/SkeletonRoomCard/SkeletonRoomCard.module.css.d.ts b/src/entities/invitations/ui/skeleton-invitation-list-item/skeleton-invitation-list-item.module.css.d.ts similarity index 100% rename from src/components/RoomList/components/SkeletonRoomCard/SkeletonRoomCard.module.css.d.ts rename to src/entities/invitations/ui/skeleton-invitation-list-item/skeleton-invitation-list-item.module.css.d.ts diff --git a/src/entities/invitations/ui/skeleton-invitation-list-item/skeleton-invitation-list-item.tsx b/src/entities/invitations/ui/skeleton-invitation-list-item/skeleton-invitation-list-item.tsx new file mode 100644 index 00000000..16c68538 --- /dev/null +++ b/src/entities/invitations/ui/skeleton-invitation-list-item/skeleton-invitation-list-item.tsx @@ -0,0 +1,43 @@ +import { + Avatar, + ListItem, + ListItemAvatar, + ListItemProps, + ListItemText, + Skeleton +} from '@mui/material'; +import cn from 'classnames'; +import * as React from 'react'; + +import { CommonProps } from '@/shared/types'; + +import styles from './skeleton-invitation-list-item.module.css'; + +export interface SkeletonInvitationListItemProps + extends CommonProps, + ListItemProps {} + +export const SkeletonInvitationListItem: React.FC< + SkeletonInvitationListItemProps +> = (props) => { + const { + className, + + ...rest + } = props; + + return ( + + + + + + + } + secondary={} + primaryTypographyProps={{ variant: 'subtitle1', component: 'p', }} + /> + + ); +}; diff --git a/src/entities/invitations/ui/template-invitation-card/index.ts b/src/entities/invitations/ui/template-invitation-card/index.ts new file mode 100644 index 00000000..b06d60bd --- /dev/null +++ b/src/entities/invitations/ui/template-invitation-card/index.ts @@ -0,0 +1 @@ +export { TemplateInvitationCard, type TemplateInvitationCardProps } from './ui'; diff --git a/src/entities/invitations/ui/template-invitation-card/ui.module.css b/src/entities/invitations/ui/template-invitation-card/ui.module.css new file mode 100644 index 00000000..59172285 --- /dev/null +++ b/src/entities/invitations/ui/template-invitation-card/ui.module.css @@ -0,0 +1,21 @@ +.card { + max-width: 560px; + +} + +.content { + display: flex; + align-items: center; + gap: 1em; +} + +.text { + max-width: 250px; + + text-align: center; +} + +.actions { + display: flex; + justify-content: space-between; +} diff --git a/src/entities/invitations/ui/template-invitation-card/ui.tsx b/src/entities/invitations/ui/template-invitation-card/ui.tsx new file mode 100644 index 00000000..f1a7985f --- /dev/null +++ b/src/entities/invitations/ui/template-invitation-card/ui.tsx @@ -0,0 +1,71 @@ +import { + Card, + CardActions, + CardContent, + CardHeader, + Typography +} from '@mui/material'; +import cn from 'classnames'; +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { CommonProps, Slots } from '@/shared/types'; + +import styles from './ui.module.css'; + + +export interface TemplateInvitationCardProps extends CommonProps { + readonly slots: Required> & + Slots<'actions'>; + readonly inviterName: string; + readonly username: string; + readonly roomName: string; +} + +export const TemplateInvitationCard: React.FC = ( + props +) => { + const { inviterName, roomName, slots, username, className, } = props; + + const { t, } = useTranslation('room-invitation'); + + const { inviterAvatar, userAvatar, actions, } = slots; + + const title = t('card.title', { + inviter_name: inviterName, + }); + + const text = t('card.text', { + inviter_name: inviterName, + user_name: username, + room_name: roomName, + returnObjects: true, + }) as Array; + + return ( + + + +
+ {inviterAvatar} + + {text[0]} + {text[1]} + {text[2]} + {text[3]} + {text[4]} + {text[5]} + + {userAvatar} +
+
+ {actions ? ( + {actions} + ) : null} +
+ ); +}; diff --git a/src/entities/invitations/ui/template-invitation-list-item/index.ts b/src/entities/invitations/ui/template-invitation-list-item/index.ts new file mode 100644 index 00000000..444e176c --- /dev/null +++ b/src/entities/invitations/ui/template-invitation-list-item/index.ts @@ -0,0 +1,4 @@ +export { + TemplateInvitationListItem, + type TemplateInvitationListItemProps +} from './template-invitation-list-item'; diff --git a/src/entities/invitations/ui/template-invitation-list-item/template-invitation-list-item.tsx b/src/entities/invitations/ui/template-invitation-list-item/template-invitation-list-item.tsx new file mode 100644 index 00000000..6e90a69c --- /dev/null +++ b/src/entities/invitations/ui/template-invitation-list-item/template-invitation-list-item.tsx @@ -0,0 +1,43 @@ +import { + ListItem, + ListItemAvatar, + ListItemProps, + ListItemSecondaryAction, + ListItemText +} from '@mui/material'; +import { FC } from 'react'; +import { useTranslation } from 'react-i18next'; + +import { CommonProps, Slots } from '@/shared/types'; + +export interface TemplateInvitationListItemProps + extends CommonProps, + Omit { + readonly slots: Required> & + Slots<'actions' | 'userAvatar'>; + readonly inviterName: string; + readonly username: string; +} + +export const TemplateInvitationListItem: FC = ( + props +) => { + const { slots, inviterName, username, ...rest } = props; + const { userAvatar, actions, } = slots; + const { t, } = useTranslation('room-invitations'); + + const secondaryLabel = t('list.item.inviter', { inviter_name: inviterName, }); + + const actionsItem = actions ? ( + {actions} + ) : null; + + return ( + + {userAvatar} + + + {actionsItem} + + ); +}; diff --git a/src/entities/popups/index.ts b/src/entities/popups/index.ts new file mode 100644 index 00000000..09131469 --- /dev/null +++ b/src/entities/popups/index.ts @@ -0,0 +1,2 @@ +export * from './model'; +export * from './lib'; diff --git a/src/entities/popups/lib/create-popup-control-model.ts b/src/entities/popups/lib/create-popup-control-model.ts new file mode 100644 index 00000000..b9845431 --- /dev/null +++ b/src/entities/popups/lib/create-popup-control-model.ts @@ -0,0 +1,35 @@ +import { createEvent, createStore, sample } from 'effector'; + +import { popupsModel } from '../model'; + +export const createPopupControlModel = (popup: string) => { + const $isOpen = createStore(false); + const close = createEvent(); + const opened = createEvent(); + + sample({ + clock: close, + fn: () => popup, + target: popupsModel.close, + }); + + sample({ + clock: popupsModel.$popups, + filter: (popups) => popups.includes(popup), + target: opened, + }); + + sample({ + clock: opened, + fn: () => true, + target: $isOpen, + }); + + sample({ + clock: close, + fn: () => false, + target: $isOpen, + }); + + return { $isOpen, close, opened, }; +}; diff --git a/src/entities/popups/lib/index.ts b/src/entities/popups/lib/index.ts new file mode 100644 index 00000000..60aa2c87 --- /dev/null +++ b/src/entities/popups/lib/index.ts @@ -0,0 +1,2 @@ +export * from './use-popups'; +export * from './create-popup-control-model'; diff --git a/src/entities/popups/lib/use-popups.ts b/src/entities/popups/lib/use-popups.ts new file mode 100644 index 00000000..e4d900a7 --- /dev/null +++ b/src/entities/popups/lib/use-popups.ts @@ -0,0 +1,31 @@ +import { useUnit } from 'effector-react'; +import { useEffect, useMemo, useState } from 'react'; + +import { popupsModel } from '../model'; + +const parsePopups = (popups: string | null) => { + return popups ? popups.split(',') : []; +}; + +let timeoutId: null | number = null; + +export const usePopups = () => { + const rawPopups = useUnit(popupsModel.$popups); + const [mountedPopups, setMountedPopups] = useState(() => + parsePopups(rawPopups) + ); + + useEffect(() => { + if (timeoutId) { + clearTimeout(timeoutId); + } + timeoutId = setTimeout( + () => setMountedPopups(parsePopups(rawPopups)), + 210 + ) as unknown as number; + }, [rawPopups]); + + const popups = useMemo(() => parsePopups(rawPopups), [rawPopups]); + + return { mountedPopups, popups, }; +}; diff --git a/src/entities/popups/model/index.ts b/src/entities/popups/model/index.ts new file mode 100644 index 00000000..ac527904 --- /dev/null +++ b/src/entities/popups/model/index.ts @@ -0,0 +1 @@ +export * as popupsModel from './popups'; diff --git a/src/entities/popups/model/popups.ts b/src/entities/popups/model/popups.ts new file mode 100644 index 00000000..2365b780 --- /dev/null +++ b/src/entities/popups/model/popups.ts @@ -0,0 +1,26 @@ +import { querySync } from 'atomic-router'; +import { createDomain, sample } from 'effector'; + +import { controls, getParams } from '@/shared/configs'; + +const popupsDomain = createDomain(); + +export const $popups = popupsDomain.store(''); + +export const close = popupsDomain.event(); + +querySync({ + controls, + source: { + [getParams.popup]: $popups, + }, +}); + +sample({ + clock: close, + source: $popups, + fn: (popups, popup) => { + return popups.replaceAll(popup, ''); + }, + target: $popups, +}); diff --git a/src/entities/progresses/index.ts b/src/entities/progresses/index.ts new file mode 100644 index 00000000..90786007 --- /dev/null +++ b/src/entities/progresses/index.ts @@ -0,0 +1,3 @@ +export * from './model'; +export * from './ui'; +export * from './lib'; diff --git a/src/entities/progresses/lib/index.ts b/src/entities/progresses/lib/index.ts new file mode 100644 index 00000000..48c23422 --- /dev/null +++ b/src/entities/progresses/lib/index.ts @@ -0,0 +1 @@ +export * from './useProgresses'; diff --git a/src/entities/progresses/lib/useProgresses.ts b/src/entities/progresses/lib/useProgresses.ts new file mode 100644 index 00000000..d36c2e7b --- /dev/null +++ b/src/entities/progresses/lib/useProgresses.ts @@ -0,0 +1,12 @@ +import { useUnit } from 'effector-react'; + +import { progressesModel } from '../model'; + +export const useProgresses = () => { + const query = useUnit(progressesModel.query); + const status = useUnit(progressesModel.query.$status); + return { + ...query, + status, + }; +}; diff --git a/src/entities/progresses/model/index.ts b/src/entities/progresses/model/index.ts new file mode 100644 index 00000000..a2c0a49a --- /dev/null +++ b/src/entities/progresses/model/index.ts @@ -0,0 +1 @@ +export * as progressesModel from './progresses'; diff --git a/src/entities/progresses/model/progresses.ts b/src/entities/progresses/model/progresses.ts new file mode 100644 index 00000000..86770715 --- /dev/null +++ b/src/entities/progresses/model/progresses.ts @@ -0,0 +1,35 @@ +import { cache, createQuery } from '@farfetched/core'; +import { runtypeContract } from '@farfetched/runtypes'; +import { createDomain } from 'effector'; +import { Array } from 'runtypes'; + +import { progress, Progress, progressApi } from '@/shared/api'; +import { dataExtractor } from '@/shared/lib'; +import { + StandardResponse, + getStandardResponse, + InRoomParams +} from '@/shared/types'; + +export const progressDomain = createDomain(); + +const handlerFx = progressDomain.effect< + InRoomParams, + StandardResponse, + Error +>(progressApi.getAll); + +export const query = createQuery< + InRoomParams, + StandardResponse, + Error, + StandardResponse, + Progress[] +>({ + initialData: [], + effect: handlerFx, + contract: runtypeContract(getStandardResponse(Array(progress))), + mapData: dataExtractor, +}); + +cache(query); diff --git a/src/entities/progresses/ui/index.ts b/src/entities/progresses/ui/index.ts new file mode 100644 index 00000000..bfdb244c --- /dev/null +++ b/src/entities/progresses/ui/index.ts @@ -0,0 +1,2 @@ +export * from './skeleton-task-progress'; +export * from './task-progress'; diff --git a/src/entities/progresses/ui/skeleton-task-progress/index.ts b/src/entities/progresses/ui/skeleton-task-progress/index.ts new file mode 100644 index 00000000..8c5fd8e7 --- /dev/null +++ b/src/entities/progresses/ui/skeleton-task-progress/index.ts @@ -0,0 +1,4 @@ +export { + SkeletonTaskProgress, + type SkeletonTaskProgressProps +} from './skeleton-task-progress'; diff --git a/src/entities/progresses/ui/skeleton-task-progress/skeleton-task-progress.module.css b/src/entities/progresses/ui/skeleton-task-progress/skeleton-task-progress.module.css new file mode 100644 index 00000000..f4ce0e69 --- /dev/null +++ b/src/entities/progresses/ui/skeleton-task-progress/skeleton-task-progress.module.css @@ -0,0 +1,5 @@ +.item { + display: grid; + grid-template-columns: 1fr; + gap: 2px; +} diff --git a/src/entities/progresses/ui/skeleton-task-progress/skeleton-task-progress.module.css.d.ts b/src/entities/progresses/ui/skeleton-task-progress/skeleton-task-progress.module.css.d.ts new file mode 100644 index 00000000..7c37031e --- /dev/null +++ b/src/entities/progresses/ui/skeleton-task-progress/skeleton-task-progress.module.css.d.ts @@ -0,0 +1,4 @@ +declare const styles: { + readonly item: string; +}; +export = styles; diff --git a/src/entities/progresses/ui/skeleton-task-progress/skeleton-task-progress.tsx b/src/entities/progresses/ui/skeleton-task-progress/skeleton-task-progress.tsx new file mode 100644 index 00000000..8da36023 --- /dev/null +++ b/src/entities/progresses/ui/skeleton-task-progress/skeleton-task-progress.tsx @@ -0,0 +1,20 @@ +import { ListItem, Skeleton } from '@mui/material'; +import cn from 'classnames'; +import * as React from 'react'; + +import { CommonProps } from '@/shared/types'; + +import styles from './skeleton-task-progress.module.css'; + +export interface SkeletonTaskProgressProps extends CommonProps {} + +export const SkeletonTaskProgress: React.FC = + React.memo(function SkeletonTaskProgress(props) { + const { className, } = props; + return ( + + + + + ); + }); diff --git a/src/entities/progresses/ui/task-progress/index.ts b/src/entities/progresses/ui/task-progress/index.ts new file mode 100644 index 00000000..bd31f2de --- /dev/null +++ b/src/entities/progresses/ui/task-progress/index.ts @@ -0,0 +1 @@ +export { TaskProgress, type TaskProgressComponent } from './task-progress'; diff --git a/src/entities/progresses/ui/task-progress/task-progress.module.css b/src/entities/progresses/ui/task-progress/task-progress.module.css new file mode 100644 index 00000000..519b5cf3 --- /dev/null +++ b/src/entities/progresses/ui/task-progress/task-progress.module.css @@ -0,0 +1,15 @@ +.item { + display: grid; + grid-template-columns: 1fr; +} + +.title { + display: flex; + justify-content: space-between; +} + +.progress { + height: 10px; + + border-radius: 8px; +} diff --git a/src/entities/progresses/ui/task-progress/task-progress.module.css.d.ts b/src/entities/progresses/ui/task-progress/task-progress.module.css.d.ts new file mode 100644 index 00000000..8a1b29f0 --- /dev/null +++ b/src/entities/progresses/ui/task-progress/task-progress.module.css.d.ts @@ -0,0 +1,6 @@ +declare const styles: { + readonly item: string; + readonly progress: string; + readonly title: string; +}; +export = styles; diff --git a/src/entities/progresses/ui/task-progress/task-progress.tsx b/src/entities/progresses/ui/task-progress/task-progress.tsx new file mode 100644 index 00000000..80492700 --- /dev/null +++ b/src/entities/progresses/ui/task-progress/task-progress.tsx @@ -0,0 +1,59 @@ +import { + LinearProgress, + linearProgressClasses, + ListItem, + SxProps, + Typography +} from '@mui/material'; +import cn from 'classnames'; +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { Progress } from '@/shared/api'; +import { CommonProps } from '@/shared/types'; + +import styles from './task-progress.module.css'; + +export interface TaskProgressComponent extends CommonProps, Progress {} + +export const TaskProgress: React.FC = React.memo( + (props) => { + const { donecount, totalcount, className, tag, } = props; + const { mainColor, secondColor, name, } = tag; + const { t, } = useTranslation('room-tasks'); + + const value = (Number(donecount) / Number(totalcount)) * 100; + + const sx: SxProps = { + backgroundColor: secondColor, + [`& .${linearProgressClasses.bar}`]: { + backgroundColor: mainColor, + }, + }; + + const ariaLabel = t('blocks.tasks_progress.aria_label', { + tag_name: name, + done_count: donecount, + total_count: totalcount, + }); + + return ( + + + {name}{' '} + + {donecount}/{totalcount} + + + + + ); + } +); diff --git a/src/entities/rooms/index.ts b/src/entities/rooms/index.ts new file mode 100644 index 00000000..90786007 --- /dev/null +++ b/src/entities/rooms/index.ts @@ -0,0 +1,3 @@ +export * from './model'; +export * from './ui'; +export * from './lib'; diff --git a/src/entities/rooms/lib/index.ts b/src/entities/rooms/lib/index.ts new file mode 100644 index 00000000..614c9cc2 --- /dev/null +++ b/src/entities/rooms/lib/index.ts @@ -0,0 +1,2 @@ +export * from './useRoom'; +export * from './useRooms'; diff --git a/src/entities/rooms/lib/useRoom.ts b/src/entities/rooms/lib/useRoom.ts new file mode 100644 index 00000000..51e6b3ff --- /dev/null +++ b/src/entities/rooms/lib/useRoom.ts @@ -0,0 +1,11 @@ +import { useUnit, useGate } from 'effector-react'; + +import { roomModel } from '../model'; + +export const useRoom = (roomId: number) => { + /* + Может стоит делать выборку из всех комнат? + */ + useGate(roomModel.Gate, { roomId, }); + return useUnit(roomModel.query); +}; diff --git a/src/entities/rooms/lib/useRooms.ts b/src/entities/rooms/lib/useRooms.ts new file mode 100644 index 00000000..31428b0c --- /dev/null +++ b/src/entities/rooms/lib/useRooms.ts @@ -0,0 +1,7 @@ +import { useUnit } from 'effector-react'; + +import { roomsModel } from '../model'; + +export const useRooms = () => { + return useUnit(roomsModel.query); +}; diff --git a/src/entities/rooms/model/index.ts b/src/entities/rooms/model/index.ts new file mode 100644 index 00000000..9ef39ffd --- /dev/null +++ b/src/entities/rooms/model/index.ts @@ -0,0 +1,2 @@ +export * as roomsModel from './rooms'; +export * as roomModel from './room'; diff --git a/src/entities/rooms/model/room.ts b/src/entities/rooms/model/room.ts new file mode 100644 index 00000000..9135d7d1 --- /dev/null +++ b/src/entities/rooms/model/room.ts @@ -0,0 +1,45 @@ +import { createQuery } from '@farfetched/core'; +import { runtypeContract } from '@farfetched/runtypes'; +import { createDomain, sample } from 'effector'; +import { createGate } from 'effector-react'; + +import { Room, roomsApi, room } from '@/shared/api'; +import { dataExtractor } from '@/shared/lib'; +import { + StandardResponse, + getStandardResponse, + InRoomParams +} from '@/shared/types'; + +const roomDomain = createDomain(); +const handlerFx = roomDomain.effect(roomsApi.getOne); + +export const query = createQuery< + InRoomParams, + StandardResponse, + Error, + StandardResponse, + Room +>({ + effect: handlerFx, + contract: runtypeContract(getStandardResponse(room)), + + mapData: dataExtractor, +}); + +export const $canChange = query.$data.map((room) => room?.canChange || false); + +export const Gate = createGate({ + domain: roomDomain, +}); + +sample({ + clock: Gate.state, + filter: ({ roomId, }) => Boolean(roomId), + target: query.start, +}); + +sample({ + clock: Gate.close, + target: query.reset, +}); diff --git a/src/entities/rooms/model/rooms.ts b/src/entities/rooms/model/rooms.ts new file mode 100644 index 00000000..79c1a956 --- /dev/null +++ b/src/entities/rooms/model/rooms.ts @@ -0,0 +1,37 @@ +import { cache, createQuery } from '@farfetched/core'; +import { runtypeContract } from '@farfetched/runtypes'; +import { querySync } from 'atomic-router'; +import { createDomain } from 'effector'; +import { Array } from 'runtypes'; + +import { room, Room, roomsApi } from '@/shared/api'; +import { controls, getParams } from '@/shared/configs'; +import { dataExtractor } from '@/shared/lib'; +import { StandardResponse, getStandardResponse } from '@/shared/types'; + +export const roomsDomain = createDomain(); +export const $id = roomsDomain.store(null); +const handlerFx = roomsDomain.effect(roomsApi.getAll); + +export const query = createQuery< + void, + StandardResponse, + Error, + StandardResponse, + Room[] +>({ + initialData: [], + effect: handlerFx, + contract: runtypeContract(getStandardResponse(Array(room))), + + mapData: dataExtractor, +}); + +cache(query); + +querySync({ + controls, + source: { + [getParams.roomId]: $id, + }, +}); diff --git a/src/entities/rooms/ui/index.ts b/src/entities/rooms/ui/index.ts new file mode 100644 index 00000000..ea2ec791 --- /dev/null +++ b/src/entities/rooms/ui/index.ts @@ -0,0 +1,3 @@ +export * from './skeleton-room-card'; +export * from './template-room-card'; +export * from './room-list-item'; diff --git a/src/entities/rooms/ui/room-list-item/index.ts b/src/entities/rooms/ui/room-list-item/index.ts new file mode 100644 index 00000000..7d362661 --- /dev/null +++ b/src/entities/rooms/ui/room-list-item/index.ts @@ -0,0 +1 @@ +export { RoomListItem, type RoomListItemProps } from './room-list-item'; diff --git a/src/entities/rooms/ui/room-list-item/room-list-item.tsx b/src/entities/rooms/ui/room-list-item/room-list-item.tsx new file mode 100644 index 00000000..a3bbda09 --- /dev/null +++ b/src/entities/rooms/ui/room-list-item/room-list-item.tsx @@ -0,0 +1,36 @@ +import { + Avatar, + ListItem, + ListItemAvatar, + ListItemButton, + ListItemText +} from '@mui/material'; +import { Link } from 'atomic-router-react'; +import * as React from 'react'; + +import { Room } from '@/shared/api'; +import { routes } from '@/shared/configs'; +import { stringToColor } from '@/shared/lib'; +import { CommonProps } from '@/shared/types'; + +export interface RoomListItemProps extends CommonProps, Room {} + +export const RoomListItem: React.FC = (props) => { + const { description, id, name, className, } = props; + const style = { + background: stringToColor(''.padEnd(15, id.toString())), + }; + return ( + + + + {name.at(0)} + + + + + ); +}; diff --git a/src/entities/rooms/ui/skeleton-room-card/index.ts b/src/entities/rooms/ui/skeleton-room-card/index.ts new file mode 100644 index 00000000..64225ddf --- /dev/null +++ b/src/entities/rooms/ui/skeleton-room-card/index.ts @@ -0,0 +1,4 @@ +export { + SkeletonRoomCard, + type SkeletonRoomCardProps +} from './skeleton-room-card'; diff --git a/src/entities/rooms/ui/skeleton-room-card/skeleton-room-card.module.css b/src/entities/rooms/ui/skeleton-room-card/skeleton-room-card.module.css new file mode 100644 index 00000000..bb003224 --- /dev/null +++ b/src/entities/rooms/ui/skeleton-room-card/skeleton-room-card.module.css @@ -0,0 +1,11 @@ +.card { + height: 300px; +} + +.actions { + padding: 1em; +} + +.content { + padding: 1em; +} diff --git a/src/entities/rooms/ui/skeleton-room-card/skeleton-room-card.module.css.d.ts b/src/entities/rooms/ui/skeleton-room-card/skeleton-room-card.module.css.d.ts new file mode 100644 index 00000000..c3debdce --- /dev/null +++ b/src/entities/rooms/ui/skeleton-room-card/skeleton-room-card.module.css.d.ts @@ -0,0 +1,6 @@ +declare const styles: { + readonly actions: string; + readonly card: string; + readonly content: string; +}; +export = styles; diff --git a/src/entities/rooms/ui/skeleton-room-card/skeleton-room-card.tsx b/src/entities/rooms/ui/skeleton-room-card/skeleton-room-card.tsx new file mode 100644 index 00000000..e7c77292 --- /dev/null +++ b/src/entities/rooms/ui/skeleton-room-card/skeleton-room-card.tsx @@ -0,0 +1,33 @@ +import { + Card, + CardActions, + CardContent, + CardHeader, + Skeleton +} from '@mui/material'; +import cn from 'classnames'; +import * as React from 'react'; + +import { CommonProps } from '@/shared/types'; + +import styles from './skeleton-room-card.module.css'; + +export interface SkeletonRoomCardProps extends CommonProps {} + +export const SkeletonRoomCard: React.FC = React.memo( + function SkeletonRoomCard(props) { + const { className, } = props; + return ( + + + } animation='wave' /> + + + + + + + + ); + } +); diff --git a/src/entities/rooms/ui/template-room-card/index.ts b/src/entities/rooms/ui/template-room-card/index.ts new file mode 100644 index 00000000..9f9052ce --- /dev/null +++ b/src/entities/rooms/ui/template-room-card/index.ts @@ -0,0 +1,4 @@ +export { + TemplateRoomCard, + type TemplateRoomCardProps +} from './template-room-card'; diff --git a/src/entities/rooms/ui/template-room-card/template-room-card.module.css b/src/entities/rooms/ui/template-room-card/template-room-card.module.css new file mode 100644 index 00000000..be643971 --- /dev/null +++ b/src/entities/rooms/ui/template-room-card/template-room-card.module.css @@ -0,0 +1,34 @@ +.card { + display: grid; + grid-template-rows: max-content max-content 1fr max-content; + + min-width: 200px; + height: 300px; + + overflow-y: scroll; + + transition: box-shadow 250ms ease-in-out; +} + +.card:hover { + box-shadow: rgba(99, 99, 99, 0.3) 0px 2px 8px 0px; +} + +.header { + font-weight: 700; +} + +.content { + padding: 1em; + + height: 100%; + + overflow-y: scroll; +} + +.actions { + display: flex; + justify-content: flex-end; + + padding: 1em; +} diff --git a/src/entities/rooms/ui/template-room-card/template-room-card.module.css.d.ts b/src/entities/rooms/ui/template-room-card/template-room-card.module.css.d.ts new file mode 100644 index 00000000..0b9fe8b7 --- /dev/null +++ b/src/entities/rooms/ui/template-room-card/template-room-card.module.css.d.ts @@ -0,0 +1,7 @@ +declare const styles: { + readonly actions: string; + readonly card: string; + readonly content: string; + readonly header: string; +}; +export = styles; diff --git a/src/entities/rooms/ui/template-room-card/template-room-card.tsx b/src/entities/rooms/ui/template-room-card/template-room-card.tsx new file mode 100644 index 00000000..81b403d2 --- /dev/null +++ b/src/entities/rooms/ui/template-room-card/template-room-card.tsx @@ -0,0 +1,46 @@ +import { + Card, + CardActions, + CardContent, + CardHeader, + CardMedia, + Typography +} from '@mui/material'; +import cn from 'classnames'; +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { Room } from '@/shared/api'; +import { stringToColor } from '@/shared/lib'; +import { CommonProps } from '@/shared/types'; + +import styles from './template-room-card.module.css'; + +export interface TemplateRoomCardProps extends CommonProps, Room { + readonly menu: React.ReactElement | null; + readonly actions: React.ReactElement | null; +} + +export const TemplateRoomCard: React.FC = (props) => { + const { name, className, description, menu, actions, id, } = props; + const { t, } = useTranslation('rooms'); + const descriptionText = t('card.description'); + + const sx = { + height: 100, + background: stringToColor(''.padEnd(15, id.toString())), + }; + + return ( + + + + + + {descriptionText}: {description} + + + {actions} + + ); +}; diff --git a/src/entities/tags/index.ts b/src/entities/tags/index.ts new file mode 100644 index 00000000..44f2f8c3 --- /dev/null +++ b/src/entities/tags/index.ts @@ -0,0 +1,3 @@ +export * from './model'; +export * from './lib'; +export * from './ui'; diff --git a/src/entities/tags/lib/index.ts b/src/entities/tags/lib/index.ts new file mode 100644 index 00000000..0df7168e --- /dev/null +++ b/src/entities/tags/lib/index.ts @@ -0,0 +1,2 @@ +export * from './use-tags'; +export * from './use-tag'; diff --git a/src/entities/tags/lib/use-tag.ts b/src/entities/tags/lib/use-tag.ts new file mode 100644 index 00000000..977a6a3b --- /dev/null +++ b/src/entities/tags/lib/use-tag.ts @@ -0,0 +1,8 @@ +import { useGate, useUnit } from 'effector-react'; + +import { tagModel } from '../model'; + +export const useTag = (tagId: number, roomId: number) => { + useGate(tagModel.Gate, { id: tagId, roomId, }); + return useUnit(tagModel.query); +}; diff --git a/src/entities/tags/lib/use-tags.ts b/src/entities/tags/lib/use-tags.ts new file mode 100644 index 00000000..232fd780 --- /dev/null +++ b/src/entities/tags/lib/use-tags.ts @@ -0,0 +1,12 @@ +import { useUnit } from 'effector-react'; + +import { tagsModel } from '../model'; + +export const useTags = () => { + const query = useUnit(tagsModel.query); + const status = useUnit(tagsModel.query.$status); + return { + ...query, + status, + }; +}; diff --git a/src/entities/tags/model/index.ts b/src/entities/tags/model/index.ts new file mode 100644 index 00000000..5ab6665d --- /dev/null +++ b/src/entities/tags/model/index.ts @@ -0,0 +1,2 @@ +export * as tagsModel from './tags'; +export * as tagModel from './tag'; diff --git a/src/entities/tags/model/tag.ts b/src/entities/tags/model/tag.ts new file mode 100644 index 00000000..429099b1 --- /dev/null +++ b/src/entities/tags/model/tag.ts @@ -0,0 +1,38 @@ +import { createQuery } from '@farfetched/core'; +import { runtypeContract } from '@farfetched/runtypes'; +import { createDomain, sample } from 'effector'; +import { createGate } from 'effector-react'; + +import { GetTagParams, Tag, tag, tagsApi } from '@/shared/api'; +import { dataExtractor } from '@/shared/lib'; +import { getStandardResponse, StandardResponse } from '@/shared/types'; + +const tagDomain = createDomain(); + +const handlerFx = tagDomain.effect, Error>( + tagsApi.getOne +); + +export const query = createQuery< + GetTagParams, + StandardResponse, + Error, + StandardResponse, + Tag +>({ + effect: handlerFx, + contract: runtypeContract(getStandardResponse(tag)), + mapData: dataExtractor, +}); + +export const Gate = createGate(); + +sample({ + clock: Gate.open, + target: query.start, +}); + +sample({ + clock: Gate.close, + target: query.reset, +}); diff --git a/src/entities/tags/model/tags.ts b/src/entities/tags/model/tags.ts new file mode 100644 index 00000000..f0a6c8e1 --- /dev/null +++ b/src/entities/tags/model/tags.ts @@ -0,0 +1,45 @@ +import { cache, createQuery } from '@farfetched/core'; +import { runtypeContract } from '@farfetched/runtypes'; +import { querySync } from 'atomic-router'; +import { createDomain } from 'effector'; +import { Array } from 'runtypes'; + +import { tag, Tag, tagsApi } from '@/shared/api'; +import { controls, routes, getParams } from '@/shared/configs'; +import { dataExtractor } from '@/shared/lib'; +import { + getStandardResponse, + InRoomParams, + StandardResponse +} from '@/shared/types'; + +export const tagsDomain = createDomain(); + +export const $id = tagsDomain.store(null); +const handlerFx = tagsDomain.effect(tagsApi.getAll); + +export const query = createQuery< + InRoomParams, + StandardResponse, + Error, + StandardResponse, + Tag[] +>({ + initialData: [], + effect: handlerFx, + contract: runtypeContract(getStandardResponse(Array(tag))), + mapData: dataExtractor, +}); + +cache(query); + +/** + * TODO: Вынести на уровень страницы + */ +querySync({ + controls, + route: routes.room.tags, + source: { + [getParams.tagId]: $id, + }, +}); diff --git a/src/entities/tags/model/types.ts b/src/entities/tags/model/types.ts new file mode 100644 index 00000000..f3d3bd10 --- /dev/null +++ b/src/entities/tags/model/types.ts @@ -0,0 +1,5 @@ +import { Tag } from '@/shared/api'; + +export interface TagsMap { + [id: number]: Tag | undefined; +} diff --git a/src/entities/tags/ui/index.ts b/src/entities/tags/ui/index.ts new file mode 100644 index 00000000..f4a13faa --- /dev/null +++ b/src/entities/tags/ui/index.ts @@ -0,0 +1,5 @@ +export * from './tag-label'; +export * from './skeleton-tag-label'; +export * from './tag-picker'; +export * from './template-tag-list-item'; +export * from './skeleton-tag-list-item'; diff --git a/src/entities/tags/ui/skeleton-tag-label/index.ts b/src/entities/tags/ui/skeleton-tag-label/index.ts new file mode 100644 index 00000000..fb37592d --- /dev/null +++ b/src/entities/tags/ui/skeleton-tag-label/index.ts @@ -0,0 +1,4 @@ +export { + SkeletonTagLabel, + type SkeletonTagLabelProps +} from './skeleton-tag-label'; diff --git a/src/entities/tags/ui/skeleton-tag-label/skeleton-tag-label.tsx b/src/entities/tags/ui/skeleton-tag-label/skeleton-tag-label.tsx new file mode 100644 index 00000000..0c283e88 --- /dev/null +++ b/src/entities/tags/ui/skeleton-tag-label/skeleton-tag-label.tsx @@ -0,0 +1,13 @@ +import { Skeleton } from '@mui/material'; +import * as React from 'react'; + +import { CommonProps } from '@/shared/types'; + +export interface SkeletonTagLabelProps extends CommonProps {} + +export const SkeletonTagLabel: React.FC = React.memo( + function SkeletonTagLabel(props) { + const { className, } = props; + return ; + } +); diff --git a/src/entities/tags/ui/skeleton-tag-list-item/index.ts b/src/entities/tags/ui/skeleton-tag-list-item/index.ts new file mode 100644 index 00000000..f1483e0a --- /dev/null +++ b/src/entities/tags/ui/skeleton-tag-list-item/index.ts @@ -0,0 +1,4 @@ +export { + SkeletonTagListItem, + type SkeletonTagListItemProps +} from './skeleton-tag-list-item'; diff --git a/src/entities/tags/ui/skeleton-tag-list-item/skeleton-tag-list-item.tsx b/src/entities/tags/ui/skeleton-tag-list-item/skeleton-tag-list-item.tsx new file mode 100644 index 00000000..7b6d70ad --- /dev/null +++ b/src/entities/tags/ui/skeleton-tag-list-item/skeleton-tag-list-item.tsx @@ -0,0 +1,16 @@ +import { ListItem, ListItemProps, Skeleton } from '@mui/material'; +import * as React from 'react'; + +import { CommonProps } from '@/shared/types'; + +export interface SkeletonTagListItemProps extends CommonProps, ListItemProps {} + +export const SkeletonTagListItem: React.FC = + React.memo(function SkeletonTagLabel(props) { + const { className, ...rest } = props; + return ( + + + + ); + }); diff --git a/src/entities/tags/ui/tag-label/index.ts b/src/entities/tags/ui/tag-label/index.ts new file mode 100644 index 00000000..4fb28bbe --- /dev/null +++ b/src/entities/tags/ui/tag-label/index.ts @@ -0,0 +1 @@ +export { TagLabel, type TagProps } from './tag-label'; diff --git a/src/entities/tags/ui/tag-label/tag-label.module.css b/src/entities/tags/ui/tag-label/tag-label.module.css new file mode 100644 index 00000000..8a5bea5d --- /dev/null +++ b/src/entities/tags/ui/tag-label/tag-label.module.css @@ -0,0 +1,12 @@ +.label { + display: inline-block; + + width: max-content; + + padding: 2px 12px; + + border-radius: 1.5rem; + + word-wrap: break-word; + word-break: break-all; +} diff --git a/src/shared/components/GroupLabel/GroupLabel.module.css.d.ts b/src/entities/tags/ui/tag-label/tag-label.module.css.d.ts similarity index 100% rename from src/shared/components/GroupLabel/GroupLabel.module.css.d.ts rename to src/entities/tags/ui/tag-label/tag-label.module.css.d.ts diff --git a/src/entities/tags/ui/tag-label/tag-label.tsx b/src/entities/tags/ui/tag-label/tag-label.tsx new file mode 100644 index 00000000..f46a7ee1 --- /dev/null +++ b/src/entities/tags/ui/tag-label/tag-label.tsx @@ -0,0 +1,26 @@ +import { SxProps, Typography } from '@mui/material'; +import cn from 'classnames'; +import * as React from 'react'; + +import { Tag } from '@/shared/api'; +import { CommonProps } from '@/shared/types'; + +import styles from './tag-label.module.css'; + +export interface TagProps extends CommonProps, Omit {} + +export const TagLabel: React.FC = React.memo(function TagLabel( + props +) { + const { className, mainColor, name, secondColor, } = props; + const sx: SxProps = { + backgroundColor: secondColor, + color: mainColor, + }; + + return ( + + {name} + + ); +}); diff --git a/src/entities/tags/ui/tag-picker/index.ts b/src/entities/tags/ui/tag-picker/index.ts new file mode 100644 index 00000000..70d90376 --- /dev/null +++ b/src/entities/tags/ui/tag-picker/index.ts @@ -0,0 +1 @@ +export { TagPicker, type TagPickerProps } from './tag-picker'; diff --git a/src/entities/tags/ui/tag-picker/tag-picker.tsx b/src/entities/tags/ui/tag-picker/tag-picker.tsx new file mode 100644 index 00000000..1e46c33f --- /dev/null +++ b/src/entities/tags/ui/tag-picker/tag-picker.tsx @@ -0,0 +1,61 @@ +import { Autocomplete, ListItem } from '@mui/material'; +import { useUnit } from 'effector-react'; +import * as React from 'react'; + +import { Tag } from '@/shared/api'; +import { CommonProps, PickerProps } from '@/shared/types'; +import { Field, FieldProps } from '@/shared/ui'; + +import { tagsModel } from '../../model'; +import { TagLabel } from '../tag-label'; + +export type TagPickerProps = CommonProps & + PickerProps & + Omit; + +export const TagPicker: React.FC = React.memo((props) => { + const { className, onChange, value, limitTags, multiple, ...rest } = props; + const tags = useUnit(tagsModel.query); + + let changeHandler; + if (multiple) { + changeHandler = (_: unknown, tags: Tag[]) => { + onChange(tags.map((tag) => tag.id)); + }; + } else { + changeHandler = (_: unknown, tag: Tag | null) => { + onChange(tag?.id || null); + }; + } + + let selected; + if (multiple) { + selected = tags.data.filter((tag) => value.includes(tag.id)); + } else { + selected = tags.data.find((tag) => tag.id === value) ?? null; + } + + return ( + tag.name} + renderOption={(props, tag) => ( + + + + )} + renderTags={(tags, getTagProps) => { + return tags.map((tag, index) => ( + + )); + }} + renderInput={(params) => } + limitTags={limitTags} + multiple={multiple} + /> + ); +}); diff --git a/src/entities/tags/ui/template-tag-list-item/index.ts b/src/entities/tags/ui/template-tag-list-item/index.ts new file mode 100644 index 00000000..a35083db --- /dev/null +++ b/src/entities/tags/ui/template-tag-list-item/index.ts @@ -0,0 +1,4 @@ +export { + TemplateTagListItem, + type TemplateTagListItemProps +} from './template-tag-list-item'; diff --git a/src/entities/tags/ui/template-tag-list-item/template-tag-list-item.tsx b/src/entities/tags/ui/template-tag-list-item/template-tag-list-item.tsx new file mode 100644 index 00000000..f19fef23 --- /dev/null +++ b/src/entities/tags/ui/template-tag-list-item/template-tag-list-item.tsx @@ -0,0 +1,45 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +import { + ListItem, + ListItemProps, + ListItemSecondaryAction, + ListItemText +} from '@mui/material'; +import * as React from 'react'; + +import { Tag } from '@/shared/api'; +import { CommonProps, Slots } from '@/shared/types'; + +import { TagLabel } from '../tag-label'; + +export interface TemplateTagListItemProps + extends CommonProps, + Tag, + Omit { + readonly slots?: Slots<'actions'>; +} + +export const TemplateTagListItem: React.FC = ( + props +) => { + const { + id: _, + mainColor, + secondColor, + name, + className, + slots, + ...rest + } = props; + + return ( + + + + + {slots?.actions ? ( + {slots.actions} + ) : null} + + ); +}; diff --git a/src/entities/tasks/index.ts b/src/entities/tasks/index.ts new file mode 100644 index 00000000..80b33de4 --- /dev/null +++ b/src/entities/tasks/index.ts @@ -0,0 +1,2 @@ +export * from './model'; +export * from './ui'; diff --git a/src/entities/tasks/model/index.ts b/src/entities/tasks/model/index.ts new file mode 100644 index 00000000..ab7c4116 --- /dev/null +++ b/src/entities/tasks/model/index.ts @@ -0,0 +1,2 @@ +export * as tasksInRoomModel from './tasks-in-room'; +export * as taskModel from './task'; diff --git a/src/entities/tasks/model/task.ts b/src/entities/tasks/model/task.ts new file mode 100644 index 00000000..6f3f4917 --- /dev/null +++ b/src/entities/tasks/model/task.ts @@ -0,0 +1,43 @@ +import { createQuery } from '@farfetched/core'; +import { runtypeContract } from '@farfetched/runtypes'; +import { createDomain, sample } from 'effector'; +import { createGate } from 'effector-react'; + +import { GetTaskParams, Task, tasksApi, task } from '@/shared/api'; +import { dataExtractor } from '@/shared/lib'; +import { StandardResponse, getStandardResponse } from '@/shared/types'; + +const taskDomain = createDomain(); + +const handlerFx = taskDomain.effect< + GetTaskParams, + StandardResponse, + Error +>(tasksApi.getOne); + +export const query = createQuery< + GetTaskParams, + StandardResponse, + Error, + StandardResponse, + Task +>({ + effect: handlerFx, + contract: runtypeContract(getStandardResponse(task)), + + mapData: dataExtractor, +}); + +export const Gate = createGate({ + domain: taskDomain, +}); + +sample({ + clock: Gate.open, + target: query.start, +}); + +sample({ + clock: Gate.close, + target: query.reset, +}); diff --git a/src/entities/tasks/model/tasks-in-room.ts b/src/entities/tasks/model/tasks-in-room.ts new file mode 100644 index 00000000..d976d80c --- /dev/null +++ b/src/entities/tasks/model/tasks-in-room.ts @@ -0,0 +1,82 @@ +import { cache, createQuery } from '@farfetched/core'; +import { runtypeContract } from '@farfetched/runtypes'; +import { querySync } from 'atomic-router'; +import { combine, createDomain } from 'effector'; +import { Array } from 'runtypes'; + +import { Task, tasksApi, task, TaskStatus, GetTasksParams } from '@/shared/api'; +import { controls, routes, getParams } from '@/shared/configs'; +import { dataExtractor, group } from '@/shared/lib'; +import { StandardResponse, getStandardResponse } from '@/shared/types'; + +const tasksInRoom = createDomain(); + +/** + * Может стоит перенести на уровень виджета(??) + */ +export const $id = tasksInRoom.store(null); +export const $status = tasksInRoom.store(null); +const handlerFx = tasksInRoom.effect< + GetTasksParams, + StandardResponse, + Error +>(tasksApi.getAll); + +export const query = createQuery< + GetTasksParams, + StandardResponse, + Error, + StandardResponse, + Task[] +>({ + initialData: [], + effect: handlerFx, + contract: runtypeContract(getStandardResponse(Array(task))), + mapData: dataExtractor, +}); + +interface Column { + readonly tasks: Task[]; + readonly status: TaskStatus; + readonly hasActions: boolean; +} + +const HAS_ACTIONS: TaskStatus[] = ['ready', 'review', 'in_progress']; + +export const $tasksColumns = combine(query.$data, (tasks) => { + const groupedTasks = group(tasks, 'status'); + + return [ + { + hasActions: HAS_ACTIONS.includes('ready'), + status: 'ready', + tasks: groupedTasks.ready ?? [], + }, + { + hasActions: HAS_ACTIONS.includes('in_progress'), + status: 'in_progress', + tasks: groupedTasks.in_progress ?? [], + }, + { + hasActions: HAS_ACTIONS.includes('review'), + status: 'review', + tasks: groupedTasks.review ?? [], + }, + { + hasActions: HAS_ACTIONS.includes('done'), + status: 'done', + tasks: groupedTasks.done ?? [], + } + ] as Column[]; +}); + +cache(query); + +querySync({ + controls, + source: { + [getParams.taskId]: $id, + [getParams.taskStatus]: $status, + }, + route: routes.room.tasks, +}); diff --git a/src/entities/tasks/ui/index.ts b/src/entities/tasks/ui/index.ts new file mode 100644 index 00000000..85656d6c --- /dev/null +++ b/src/entities/tasks/ui/index.ts @@ -0,0 +1,4 @@ +export * from './skeleton-task-card'; +export * from './template-task-card'; +export * from './task-column-header'; +export * from './status-select'; diff --git a/src/entities/tasks/ui/skeleton-task-card/index.ts b/src/entities/tasks/ui/skeleton-task-card/index.ts new file mode 100644 index 00000000..a0e6c9d8 --- /dev/null +++ b/src/entities/tasks/ui/skeleton-task-card/index.ts @@ -0,0 +1,4 @@ +export { + SkeletonTaskCard, + type SkeletonTaskCardProps +} from './skeleton-task-card'; diff --git a/src/entities/tasks/ui/skeleton-task-card/skeleton-task-card.tsx b/src/entities/tasks/ui/skeleton-task-card/skeleton-task-card.tsx new file mode 100644 index 00000000..42cb816a --- /dev/null +++ b/src/entities/tasks/ui/skeleton-task-card/skeleton-task-card.tsx @@ -0,0 +1,34 @@ +/* eslint-disable react/no-array-index-key */ +import { + Card, + CardContent, + CardHeader, + Skeleton, + Typography +} from '@mui/material'; +import * as React from 'react'; + +import { CommonProps } from '@/shared/types'; + +export interface SkeletonTaskCardProps extends CommonProps { + readonly contentLinesCount?: number; +} + +export const SkeletonTaskCard: React.FC = React.memo( + function SkeletonTaskCard(props) { + const { className, contentLinesCount = 2, } = props; + const lines = Array(contentLinesCount).fill(0); + return ( + + } /> + + {lines.map((_, i) => ( + + + + ))} + + + ); + } +); diff --git a/src/entities/tasks/ui/status-select/index.ts b/src/entities/tasks/ui/status-select/index.ts new file mode 100644 index 00000000..718385ac --- /dev/null +++ b/src/entities/tasks/ui/status-select/index.ts @@ -0,0 +1 @@ +export { StatusSelect, type StatusSelectProps } from './status-select'; diff --git a/src/entities/tasks/ui/status-select/status-select.tsx b/src/entities/tasks/ui/status-select/status-select.tsx new file mode 100644 index 00000000..cfbefc68 --- /dev/null +++ b/src/entities/tasks/ui/status-select/status-select.tsx @@ -0,0 +1,31 @@ +import { MenuItem } from '@mui/material'; +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { statuses } from '@/shared/api'; +import { CommonProps } from '@/shared/types'; +import { Field, FieldProps } from '@/shared/ui'; + +export interface StatusSelectProps + extends CommonProps, + Omit { + readonly hasEmptyOption?: boolean; + readonly emptyOptionText?: string; +} + +export const StatusSelect: React.FC = React.memo((props) => { + const { t, } = useTranslation('tasks'); + const { hasEmptyOption, emptyOptionText, ...rest } = props; + return ( + + {hasEmptyOption ? ( + {emptyOptionText} + ) : null} + {statuses.map((name) => ( + + {t(`statuses.${name}`)} + + ))} + + ); +}); diff --git a/src/entities/tasks/ui/task-column-header/index.ts b/src/entities/tasks/ui/task-column-header/index.ts new file mode 100644 index 00000000..53e42be2 --- /dev/null +++ b/src/entities/tasks/ui/task-column-header/index.ts @@ -0,0 +1,4 @@ +export { + TaskColumnHeader, + type TaskColumnHeaderComponent +} from './task-column-header'; diff --git a/src/components/Tasks/components/TaskList/components/TaskListHeader/TaskListHeader.module.css b/src/entities/tasks/ui/task-column-header/task-column-header.module.css similarity index 100% rename from src/components/Tasks/components/TaskList/components/TaskListHeader/TaskListHeader.module.css rename to src/entities/tasks/ui/task-column-header/task-column-header.module.css diff --git a/src/components/RoomHeader/RoomHeader.module.css.d.ts b/src/entities/tasks/ui/task-column-header/task-column-header.module.css.d.ts similarity index 100% rename from src/components/RoomHeader/RoomHeader.module.css.d.ts rename to src/entities/tasks/ui/task-column-header/task-column-header.module.css.d.ts diff --git a/src/entities/tasks/ui/task-column-header/task-column-header.tsx b/src/entities/tasks/ui/task-column-header/task-column-header.tsx new file mode 100644 index 00000000..b4321cd0 --- /dev/null +++ b/src/entities/tasks/ui/task-column-header/task-column-header.tsx @@ -0,0 +1,26 @@ +import { Typography } from '@mui/material'; +import cn from 'classnames'; +import * as React from 'react'; + +import { CommonProps, Slots } from '@/shared/types'; + +import styles from './task-column-header.module.css'; + +export interface TaskColumnHeaderComponent extends CommonProps { + readonly slots?: Slots<'actions'>; +} + +export const TaskColumnHeader: React.FC< + React.PropsWithChildren +> = React.memo((props) => { + const { children, className, slots, } = props; + + return ( +
+ + {children} + + {slots?.actions} +
+ ); +}); diff --git a/src/entities/tasks/ui/template-task-card/index.ts b/src/entities/tasks/ui/template-task-card/index.ts new file mode 100644 index 00000000..05ca51a6 --- /dev/null +++ b/src/entities/tasks/ui/template-task-card/index.ts @@ -0,0 +1,4 @@ +export { + TemplateTaskCard, + type TemplateTaskCardProps +} from './template-task-card'; diff --git a/src/entities/tasks/ui/template-task-card/template-task-card.module.css b/src/entities/tasks/ui/template-task-card/template-task-card.module.css new file mode 100644 index 00000000..ca4e84fe --- /dev/null +++ b/src/entities/tasks/ui/template-task-card/template-task-card.module.css @@ -0,0 +1,31 @@ +.card { + width: 100%; + + box-shadow: rgba(99, 99, 99, 0.1) 0px 2px 8px 0px; +} + +.card:hover { + box-shadow: rgba(99, 99, 99, 0.3) 0px 2px 8px 0px; +} + +.drag { + opacity: 0.1; +} + +.header { + padding-bottom: 0.5em; +} +.content { + padding-top: 0.5em; +} + +.description { + word-break: break-all; +} + +.actions { + display: flex; + justify-content: space-between; + + padding: 1em; +} diff --git a/src/entities/tasks/ui/template-task-card/template-task-card.module.css.d.ts b/src/entities/tasks/ui/template-task-card/template-task-card.module.css.d.ts new file mode 100644 index 00000000..a3d9e03a --- /dev/null +++ b/src/entities/tasks/ui/template-task-card/template-task-card.module.css.d.ts @@ -0,0 +1,9 @@ +declare const styles: { + readonly actions: string; + readonly card: string; + readonly content: string; + readonly description: string; + readonly drag: string; + readonly header: string; +}; +export = styles; diff --git a/src/entities/tasks/ui/template-task-card/template-task-card.tsx b/src/entities/tasks/ui/template-task-card/template-task-card.tsx new file mode 100644 index 00000000..06d84977 --- /dev/null +++ b/src/entities/tasks/ui/template-task-card/template-task-card.tsx @@ -0,0 +1,60 @@ +import { + Card, + CardActions, + CardContent, + CardHeader, + CardProps, + Typography +} from '@mui/material'; +import cn from 'classnames'; +import * as React from 'react'; + +import { Task } from '@/shared/api'; +import { CommonProps, Slots } from '@/shared/types'; +import { DateTime } from '@/shared/ui'; + +import styles from './template-task-card.module.css'; + +export interface TemplateTaskCardProps + extends CommonProps, + Pick, + Omit { + readonly slots: Slots<'actions' | 'tags' | 'userAvatar'>; +} + +export const TemplateTaskCard: React.FC = React.memo( + (props) => { + const { className, createdAt, slots, title, description, ...rest } = props; + + const { actions, tags, userAvatar, } = slots; + + return ( + + + {title} + + } + subheader={tags} + disableTypography + /> + + + {description} + + + + {userAvatar} + + + + ); + } +); diff --git a/src/entities/users/index.ts b/src/entities/users/index.ts new file mode 100644 index 00000000..76671b44 --- /dev/null +++ b/src/entities/users/index.ts @@ -0,0 +1,3 @@ +export * from './ui'; +export * from './lib'; +export * from './model'; diff --git a/src/entities/users/lib/index.ts b/src/entities/users/lib/index.ts new file mode 100644 index 00000000..b5390675 --- /dev/null +++ b/src/entities/users/lib/index.ts @@ -0,0 +1,2 @@ +export * from './useSearchedUsers'; +export * from './useUsersInRoom'; diff --git a/src/entities/users/lib/useSearchedUsers.ts b/src/entities/users/lib/useSearchedUsers.ts new file mode 100644 index 00000000..c8606352 --- /dev/null +++ b/src/entities/users/lib/useSearchedUsers.ts @@ -0,0 +1,7 @@ +import { useUnit } from 'effector-react'; + +import { searchUserModel } from '../model'; + +export const useSearchedUsers = () => { + return useUnit(searchUserModel.query); +}; diff --git a/src/entities/users/lib/useUsersInRoom.ts b/src/entities/users/lib/useUsersInRoom.ts new file mode 100644 index 00000000..48151d89 --- /dev/null +++ b/src/entities/users/lib/useUsersInRoom.ts @@ -0,0 +1,7 @@ +import { useUnit } from 'effector-react'; + +import { usersInRoomModel } from '../model'; + +export const useUsersInRoom = () => { + return useUnit(usersInRoomModel.query); +}; diff --git a/src/entities/users/model/index.ts b/src/entities/users/model/index.ts new file mode 100644 index 00000000..c288a623 --- /dev/null +++ b/src/entities/users/model/index.ts @@ -0,0 +1,2 @@ +export * as usersInRoomModel from './users-in-room'; +export * as searchUserModel from './search-user'; diff --git a/src/entities/users/model/search-user.ts b/src/entities/users/model/search-user.ts new file mode 100644 index 00000000..16e210dc --- /dev/null +++ b/src/entities/users/model/search-user.ts @@ -0,0 +1,43 @@ +import { createQuery } from '@farfetched/core'; +import { runtypeContract } from '@farfetched/runtypes'; +import { createDomain, createEvent, sample } from 'effector'; +import { debounce } from 'patronum'; +import { Array } from 'runtypes'; + +import { SearchUsersQuery, user, User, usersApi } from '@/shared/api'; +import { dataExtractor } from '@/shared/lib'; +import { getStandardResponse, StandardResponse } from '@/shared/types'; + +const searchUserDomain = createDomain(); + +const handlerFx = searchUserDomain.effect< + SearchUsersQuery, + StandardResponse, + Error +>(usersApi.searchUsers); + +export const query = createQuery< + SearchUsersQuery, + StandardResponse, + Error, + StandardResponse, + User[] +>({ + initialData: [], + effect: handlerFx, + contract: runtypeContract(getStandardResponse(Array(user))), + mapData: dataExtractor, +}); + +export const searchChanged = createEvent(); + +const debouncedSearchChanged = debounce({ + source: searchChanged, + timeout: 200, +}); + +sample({ + clock: debouncedSearchChanged, + fn: (username) => ({ username, }), + target: query.start, +}); diff --git a/src/entities/users/model/users-in-room.ts b/src/entities/users/model/users-in-room.ts new file mode 100644 index 00000000..218923ef --- /dev/null +++ b/src/entities/users/model/users-in-room.ts @@ -0,0 +1,33 @@ +import { createQuery } from '@farfetched/core'; +import { runtypeContract } from '@farfetched/runtypes'; +import { createDomain } from 'effector'; +import { Array } from 'runtypes'; + +import { membersApi, user, User } from '@/shared/api'; +import { dataExtractor } from '@/shared/lib'; +import { + getStandardResponse, + InRoomParams, + StandardResponse +} from '@/shared/types'; + +const usersInRoom = createDomain(); + +const handlerFx = usersInRoom.effect(membersApi.getAll); + +export const query = createQuery< + InRoomParams, + StandardResponse, + Error, + StandardResponse, + User[] +>({ + initialData: [], + effect: handlerFx, + contract: runtypeContract(getStandardResponse(Array(user))), + mapData: dataExtractor, +}); + +export const $ids = query.$data.map((users) => users.map((user) => user.id)); +export const $count = query.$data.map((users) => users.length); +export const $hasError = query.$error.map((error) => !!error); diff --git a/src/entities/users/ui/index.ts b/src/entities/users/ui/index.ts new file mode 100644 index 00000000..6f07efa6 --- /dev/null +++ b/src/entities/users/ui/index.ts @@ -0,0 +1,5 @@ +export * from './template-user-list-item'; +export * from './user-avatar'; +export * from './users-in-room-picker'; +export * from './user-search'; +export * from './skeleton-user-list-item'; diff --git a/src/entities/users/ui/skeleton-user-list-item/index.ts b/src/entities/users/ui/skeleton-user-list-item/index.ts new file mode 100644 index 00000000..db5f4ed9 --- /dev/null +++ b/src/entities/users/ui/skeleton-user-list-item/index.ts @@ -0,0 +1,4 @@ +export { + SkeletonUserListItem, + type SkeletonUserListItemProps +} from './skeleton-user-list-item'; diff --git a/src/entities/users/ui/skeleton-user-list-item/skeleton-user-list-item.module.css b/src/entities/users/ui/skeleton-user-list-item/skeleton-user-list-item.module.css new file mode 100644 index 00000000..37ffb2a4 --- /dev/null +++ b/src/entities/users/ui/skeleton-user-list-item/skeleton-user-list-item.module.css @@ -0,0 +1,3 @@ +.card { + width: 100%; +} diff --git a/src/entities/users/ui/skeleton-user-list-item/skeleton-user-list-item.module.css.d.ts b/src/entities/users/ui/skeleton-user-list-item/skeleton-user-list-item.module.css.d.ts new file mode 100644 index 00000000..7feb257b --- /dev/null +++ b/src/entities/users/ui/skeleton-user-list-item/skeleton-user-list-item.module.css.d.ts @@ -0,0 +1,4 @@ +declare const styles: { + readonly card: string; +}; +export = styles; diff --git a/src/entities/users/ui/skeleton-user-list-item/skeleton-user-list-item.tsx b/src/entities/users/ui/skeleton-user-list-item/skeleton-user-list-item.tsx new file mode 100644 index 00000000..f33f69bd --- /dev/null +++ b/src/entities/users/ui/skeleton-user-list-item/skeleton-user-list-item.tsx @@ -0,0 +1,41 @@ +import { + Avatar, + ListItem, + ListItemAvatar, + ListItemProps, + ListItemText, + Skeleton +} from '@mui/material'; +import cn from 'classnames'; +import * as React from 'react'; + +import { CommonProps } from '@/shared/types'; + +import styles from './skeleton-user-list-item.module.css'; + +export interface SkeletonUserListItemProps extends CommonProps, ListItemProps {} + +export const SkeletonUserListItem: React.FC = ( + props +) => { + const { + className, + + ...rest + } = props; + + return ( + + + + + + + } + secondary={} + primaryTypographyProps={{ variant: 'subtitle1', component: 'p', }} + /> + + ); +}; diff --git a/src/entities/users/ui/template-user-list-item/index.ts b/src/entities/users/ui/template-user-list-item/index.ts new file mode 100644 index 00000000..0bb2c865 --- /dev/null +++ b/src/entities/users/ui/template-user-list-item/index.ts @@ -0,0 +1,4 @@ +export { + TemplateUserListItem, + type TemplateUserListItemProps +} from './template-user-list-item'; diff --git a/src/entities/users/ui/template-user-list-item/template-user-list-item.module.css b/src/entities/users/ui/template-user-list-item/template-user-list-item.module.css new file mode 100644 index 00000000..37ffb2a4 --- /dev/null +++ b/src/entities/users/ui/template-user-list-item/template-user-list-item.module.css @@ -0,0 +1,3 @@ +.card { + width: 100%; +} diff --git a/src/entities/users/ui/template-user-list-item/template-user-list-item.module.css.d.ts b/src/entities/users/ui/template-user-list-item/template-user-list-item.module.css.d.ts new file mode 100644 index 00000000..7feb257b --- /dev/null +++ b/src/entities/users/ui/template-user-list-item/template-user-list-item.module.css.d.ts @@ -0,0 +1,4 @@ +declare const styles: { + readonly card: string; +}; +export = styles; diff --git a/src/entities/users/ui/template-user-list-item/template-user-list-item.tsx b/src/entities/users/ui/template-user-list-item/template-user-list-item.tsx new file mode 100644 index 00000000..297d9d13 --- /dev/null +++ b/src/entities/users/ui/template-user-list-item/template-user-list-item.tsx @@ -0,0 +1,54 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +import { + ListItem, + ListItemAvatar, + ListItemProps, + ListItemText +} from '@mui/material'; +import cn from 'classnames'; +import * as React from 'react'; + +import { User } from '@/shared/api'; +import { CommonProps, Slots } from '@/shared/types'; + +import { UserAvatar } from '../user-avatar'; + +import styles from './template-user-list-item.module.css'; + +export interface TemplateUserListItemProps + extends CommonProps, + User, + Omit { + readonly slots?: Slots<'actions' | 'extra'>; +} + +export const TemplateUserListItem: React.FC = ( + props +) => { + const { + username, + className, + photo, + email, + id: _id, + slots = {}, + ...rest + } = props; + + return ( + + + + + + {slots.extra} + + ); +}; diff --git a/src/entities/users/ui/user-avatar/index.ts b/src/entities/users/ui/user-avatar/index.ts new file mode 100644 index 00000000..82716fa6 --- /dev/null +++ b/src/entities/users/ui/user-avatar/index.ts @@ -0,0 +1 @@ +export { UserAvatar, type UserAvatarProps } from './user-avatar'; diff --git a/src/entities/users/ui/user-avatar/user-avatar.tsx b/src/entities/users/ui/user-avatar/user-avatar.tsx new file mode 100644 index 00000000..f7c7be75 --- /dev/null +++ b/src/entities/users/ui/user-avatar/user-avatar.tsx @@ -0,0 +1,33 @@ +import AccountCircleIcon from '@mui/icons-material/AccountCircle'; +import { Avatar, Tooltip } from '@mui/material'; +import * as React from 'react'; + +import { User } from '@/shared/api'; +import { stringToColor } from '@/shared/lib'; +import { CommonProps } from '@/shared/types'; + +export interface UserAvatarProps + extends CommonProps, + Pick { + readonly size?: number; + readonly disableTooltip?: boolean; +} + +export const UserAvatar: React.FC = (props) => { + const { username, photo, email, className, size, disableTooltip, } = props; + return ( + + + + + + ); +}; diff --git a/src/entities/users/ui/user-search/index.ts b/src/entities/users/ui/user-search/index.ts new file mode 100644 index 00000000..ca69807c --- /dev/null +++ b/src/entities/users/ui/user-search/index.ts @@ -0,0 +1 @@ +export { UserSearch, type UserSearchProps } from './user-search'; diff --git a/src/entities/users/ui/user-search/user-search.tsx b/src/entities/users/ui/user-search/user-search.tsx new file mode 100644 index 00000000..c86ff986 --- /dev/null +++ b/src/entities/users/ui/user-search/user-search.tsx @@ -0,0 +1,45 @@ +import { Autocomplete } from '@mui/material'; +import { useUnit } from 'effector-react'; +import * as React from 'react'; + +import { User } from '@/shared/api'; +import { CommonProps } from '@/shared/types'; +import { Field, FieldProps } from '@/shared/ui'; + +import { useSearchedUsers } from '../../lib'; +import { searchUserModel } from '../../model'; +import { TemplateUserListItem } from '../template-user-list-item'; + +export interface UserSearchProps extends CommonProps, FieldProps { + readonly onChange?: (user: User | null) => unknown; + readonly value?: User | null; +} + +export const UserSearch: React.FC = (props) => { + const { className, onChange, value, ...rest } = props; + const users = useSearchedUsers(); + const searchChanged = useUnit(searchUserModel.searchChanged); + + const handleChange = (_: unknown, user: User | null) => { + onChange?.(user); + }; + + const onInputChange = (_: unknown, value: string) => { + searchChanged(value); + }; + + return ( + option.username} + onInputChange={onInputChange} + renderOption={(props, option) => ( + + )} + renderInput={(params) => } + /> + ); +}; diff --git a/src/entities/users/ui/users-in-room-picker/index.ts b/src/entities/users/ui/users-in-room-picker/index.ts new file mode 100644 index 00000000..2bfc70fd --- /dev/null +++ b/src/entities/users/ui/users-in-room-picker/index.ts @@ -0,0 +1,4 @@ +export { + UsersInRoomPicker, + type UsersInRoomPickerProps +} from './users-in-room-picker'; diff --git a/src/entities/users/ui/users-in-room-picker/users-in-room-picker.tsx b/src/entities/users/ui/users-in-room-picker/users-in-room-picker.tsx new file mode 100644 index 00000000..35bc34ac --- /dev/null +++ b/src/entities/users/ui/users-in-room-picker/users-in-room-picker.tsx @@ -0,0 +1,51 @@ +import { Autocomplete } from '@mui/material'; +import * as React from 'react'; + +import { User } from '@/shared/api'; +import { preparePickerHandler, preparePickerSelectedValue } from '@/shared/lib'; +import { CommonProps, PickerProps } from '@/shared/types'; +import { Field, FieldProps } from '@/shared/ui'; + +import { useUsersInRoom } from '../../lib'; +import { TemplateUserListItem } from '../template-user-list-item'; + +export type UsersInRoomPickerProps = CommonProps & + PickerProps & + Omit; + +export const UsersInRoomPicker: React.FC = React.memo( + (props) => { + const { onChange, value, className, multiple, limitTags, ...rest } = props; + const users = useUsersInRoom(); + + const changeHandler = preparePickerHandler( + { multiple, onChange, }, + 'id' + ); + + const selected = preparePickerSelectedValue( + { value, multiple, }, + users.data, + 'id' + ); + + return ( + user.username} + loading={users.pending} + renderOption={(params, option) => ( + + )} + renderInput={(params) => { + return ; + }} + limitTags={limitTags} + multiple={multiple} + /> + ); + } +); diff --git a/src/features/activities/activities-filters/filters.module.css b/src/features/activities/activities-filters/filters.module.css new file mode 100644 index 00000000..af20c34b --- /dev/null +++ b/src/features/activities/activities-filters/filters.module.css @@ -0,0 +1,26 @@ +.form { + display: grid; + gap: 1em; + grid-template-columns: repeat(2, minmax(150px, 1fr)); + align-items: end; + + padding: 1em; +} + +.reset { + grid-column: 1; +} + +.submit { + grid-column: 2; +} + +@media (max-width: 720px) { + .form { + grid-template-columns: 1fr; + } + + .submit { + grid-column: 1; + } +} diff --git a/src/features/activities/activities-filters/filters.module.css.d.ts b/src/features/activities/activities-filters/filters.module.css.d.ts new file mode 100644 index 00000000..9a4c2af5 --- /dev/null +++ b/src/features/activities/activities-filters/filters.module.css.d.ts @@ -0,0 +1,6 @@ +declare const styles: { + readonly form: string; + readonly reset: string; + readonly submit: string; +}; +export = styles; diff --git a/src/features/activities/activities-filters/filters.tsx b/src/features/activities/activities-filters/filters.tsx new file mode 100644 index 00000000..e4e73d77 --- /dev/null +++ b/src/features/activities/activities-filters/filters.tsx @@ -0,0 +1,188 @@ +/* eslint-disable sonarjs/no-duplicate-string */ +import TuneIcon from '@mui/icons-material/Tune'; +import { Button } from '@mui/material'; +import cn from 'classnames'; +import { useUnit } from 'effector-react'; +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { + ActivitiesActionsPicker, + ActivitiesSpheresPicker +} from '@/entities/activities'; +import { UsersInRoomPicker } from '@/entities/users'; + +import { usePreventDefault, useToggle } from '@/shared/lib'; +import { CommonProps } from '@/shared/types'; +import { DatePicker, FiltersPopover, Show } from '@/shared/ui'; + +import styles from './filters.module.css'; +import { form } from './model'; + +export interface ActivitiesFiltersProps extends CommonProps {} + +export const ActivitiesFilters: React.FC = (props) => { + const { className, } = props; + const { t, } = useTranslation('room-activities'); + + const [open, { toggleOff, toggleOn, }] = useToggle(); + const [reset, submit] = useUnit([form.reset, form.submit]); + + const onSubmit = usePreventDefault(() => { + submit(); + toggleOff(); + }); + + const onReset = () => { + reset(); + toggleOff(); + }; + + const title = t('actions.filter_activities.title'); + const actions = t('actions.filter_activities.actions', { + returnObjects: true, + }) as Record; + + const buttons = ( + <> + + + + ); + + return ( + } + slots={{ actions: buttons, }}> + {({ isPopup, }) => ( +
+ + + + + + {buttons} + + )} +
+ ); +}; + +const Action: React.FC = () => { + const { t, } = useTranslation('room-activities'); + + const label = t('actions.filter_activities.fields.types'); + + const actionIds = useUnit(form.fields.actionIds); + + return ( + + ); +}; + +const Spheres: React.FC = () => { + const { t, } = useTranslation('room-activities'); + + const label = t('actions.filter_activities.fields.spheres'); + const sphereIds = useUnit(form.fields.sphereIds); + + return ( + + ); +}; + +const Users: React.FC = () => { + const { t, } = useTranslation('room-activities'); + + const label = t('actions.filter_activities.fields.users'); + const activistIds = useUnit(form.fields.activistIds); + + return ( + + ); +}; + +const After: React.FC = () => { + const { t, } = useTranslation('common'); + + const label = t('fields.create_after'); + const after = useUnit(form.fields.after); + + return ( + + ); +}; + +const Before: React.FC = () => { + const { t, } = useTranslation('common'); + + const label = t('fields.create_before'); + const before = useUnit(form.fields.before); + + return ( + + ); +}; diff --git a/src/features/activities/activities-filters/index.ts b/src/features/activities/activities-filters/index.ts new file mode 100644 index 00000000..31b4a7ba --- /dev/null +++ b/src/features/activities/activities-filters/index.ts @@ -0,0 +1,2 @@ +export * as activitiesFiltersModel from './model'; +export { ActivitiesFilters, type ActivitiesFiltersProps } from './filters'; diff --git a/src/features/activities/activities-filters/model.ts b/src/features/activities/activities-filters/model.ts new file mode 100644 index 00000000..e3d05c34 --- /dev/null +++ b/src/features/activities/activities-filters/model.ts @@ -0,0 +1,28 @@ +import { createDomain } from 'effector'; +import { createForm } from 'effector-forms'; + +import { GetActivitiesInRoomParams } from '@/shared/api'; + +const activitiesFiltersDomain = createDomain(); + +export interface ActivitiesFiltersForm + extends Required< + Omit + > {} + +export const form = createForm({ + fields: { + activistIds: { + init: [], + }, + after: { + init: null, + }, + before: { + init: null, + }, + sphereIds: { init: [], }, + actionIds: { init: [], }, + }, + domain: activitiesFiltersDomain, +}); diff --git a/src/features/activities/index.ts b/src/features/activities/index.ts new file mode 100644 index 00000000..d0263ee5 --- /dev/null +++ b/src/features/activities/index.ts @@ -0,0 +1,2 @@ +export * from './open-all-room-activities'; +export * from './activities-filters'; diff --git a/src/features/activities/open-all-room-activities/index.ts b/src/features/activities/open-all-room-activities/index.ts new file mode 100644 index 00000000..345b1980 --- /dev/null +++ b/src/features/activities/open-all-room-activities/index.ts @@ -0,0 +1 @@ +export { OpenAllRoomActivities } from './open-all-room-activities'; diff --git a/src/features/activities/open-all-room-activities/open-all-room-activities.tsx b/src/features/activities/open-all-room-activities/open-all-room-activities.tsx new file mode 100644 index 00000000..9cb559c9 --- /dev/null +++ b/src/features/activities/open-all-room-activities/open-all-room-activities.tsx @@ -0,0 +1,29 @@ +import { Button } from '@mui/material'; +import { Link } from 'atomic-router-react'; +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { routes } from '@/shared/configs'; +import { useParam } from '@/shared/lib'; +import { CommonProps } from '@/shared/types'; + +export const OpenAllRoomActivities: React.FC = React.memo( + (props) => { + const { className, } = props; + const roomId = useParam(routes.room.tasks, 'id'); + const { t, } = useTranslation('room-tasks'); + + const text = t('blocks.last_activities.actions.open'); + + return ( + + ); + } +); diff --git a/src/features/auth/activate/index.ts b/src/features/auth/activate/index.ts new file mode 100644 index 00000000..002a08bc --- /dev/null +++ b/src/features/auth/activate/index.ts @@ -0,0 +1 @@ +export * as activateAccountModel from './model'; diff --git a/src/features/auth/activate/model.ts b/src/features/auth/activate/model.ts new file mode 100644 index 00000000..db655e80 --- /dev/null +++ b/src/features/auth/activate/model.ts @@ -0,0 +1,21 @@ +import { createQuery } from '@farfetched/core'; +import { runtypeContract } from '@farfetched/runtypes'; +import { createEffect } from 'effector'; +import { Boolean } from 'runtypes'; + +import { authApi, ActivateParams } from '@/shared/api'; +import { dataExtractor } from '@/shared/lib'; +import { StandardResponse, getStandardResponse } from '@/shared/types'; + +const handlerFx = createEffect(authApi.activate); +export const query = createQuery< + ActivateParams, + StandardResponse, + Error, + StandardResponse, + globalThis.Boolean +>({ + effect: handlerFx, + contract: runtypeContract(getStandardResponse(Boolean)), + mapData: dataExtractor, +}); diff --git a/src/features/auth/index.ts b/src/features/auth/index.ts new file mode 100644 index 00000000..acb2db7b --- /dev/null +++ b/src/features/auth/index.ts @@ -0,0 +1,4 @@ +export * from './registration'; +export * from './login'; +export * from './logout'; +export * from './activate'; diff --git a/src/features/auth/login/index.ts b/src/features/auth/login/index.ts new file mode 100644 index 00000000..c6ec44a5 --- /dev/null +++ b/src/features/auth/login/index.ts @@ -0,0 +1,2 @@ +export * as loginModel from './model'; +export { LoginForm } from './ui'; diff --git a/src/features/auth/login/model.ts b/src/features/auth/login/model.ts new file mode 100644 index 00000000..d7df5ac4 --- /dev/null +++ b/src/features/auth/login/model.ts @@ -0,0 +1,123 @@ +import { createMutation } from '@farfetched/core'; +import { runtypeContract } from '@farfetched/runtypes'; +import { createDomain, sample } from 'effector'; +import { createForm } from 'effector-forms'; +import Joi from 'joi'; +import { splitMap } from 'patronum'; + +import { authApi, authResponse, AuthResponse, LoginParams } from '@/shared/api'; +import { + ALLOWED_SYMBOLS, + MAX_SHORT_LENGTH, + MIN_LENGTH +} from '@/shared/configs'; +import { createRuleFromSchema, isHttpErrorCode } from '@/shared/lib'; +import { sessionModel } from '@/shared/models'; +import { StandardResponse, getStandardResponse } from '@/shared/types'; + +const loginDomain = createDomain(); + +const handlerFx = loginDomain.effect< + LoginParams, + StandardResponse +>(authApi.login); + +export const mutation = createMutation< + LoginParams, + StandardResponse, + StandardResponse, + Error +>({ + effect: handlerFx, + contract: runtypeContract(getStandardResponse(authResponse)), +}); + +const schemas = { + email: Joi.string() + .email({ tlds: { allow: false, }, }) + .min(MIN_LENGTH) + .max(MAX_SHORT_LENGTH) + .required() + .messages({ + 'string.empty': 'empty', + 'string.email': 'email', + 'string.min': 'min_length', + 'string.max': 'max_length', + }), + password: Joi.string() + .pattern(ALLOWED_SYMBOLS) + .min(MIN_LENGTH) + .max(MAX_SHORT_LENGTH) + .required() + .messages({ + 'string.empty': 'empty', + 'string.pattern.base': 'pattern', + 'string.min': 'min_length', + 'string.max': 'max_length', + }), + rememberMe: Joi.boolean(), +}; + +export const form = createForm({ + fields: { + email: { + init: '', + rules: [createRuleFromSchema('email', schemas.email)], + }, + password: { + init: '', + rules: [createRuleFromSchema('password', schemas.password)], + }, + rememberMe: { + init: false, + rules: [createRuleFromSchema('remember', schemas.rememberMe)], + }, + }, + domain: loginDomain, +}); + +sample({ + clock: form.formValidated, + target: mutation.start, +}); + +sample({ + clock: mutation.finished.success, + fn: ({ result, }) => result.data.user, + target: sessionModel.query.start, +}); + +const errors = splitMap({ + source: mutation.finished.failure, + cases: { + incorrectPassword: ({ error, }) => { + if (isHttpErrorCode(error, 403)) { + return 'incorrect_password'; + } + }, + + userNotFound: ({ error, }) => { + if (isHttpErrorCode(error, 404)) { + return 'not_found'; + } + }, + }, +}); + +sample({ + clock: errors.userNotFound, + fn: (message) => ({ + rule: 'server', + errorText: message, + }), + target: form.fields.email.addError, +}); + +sample({ + clock: errors.incorrectPassword, + fn: (message) => ({ + rule: 'server', + errorText: message, + }), + target: form.fields.password.addError, +}); diff --git a/src/features/auth/login/ui.module.css b/src/features/auth/login/ui.module.css new file mode 100644 index 00000000..f0e43952 --- /dev/null +++ b/src/features/auth/login/ui.module.css @@ -0,0 +1,23 @@ +.form { + display: grid; + grid-template-columns: var(--login-form-template-columns); + gap: 1em; +} + +.field { + grid-column: var(--login-form-field-column); +} + +@media (width >= 700px) { + .form { + --login-form-template-columns: max-content 1fr; + --login-form-field-column: span 2; + } +} + +@media (width < 700px) { + .form { + --login-form-template-columns: 1fr; + --login-form-field-column: 1; + } +} diff --git a/src/features/auth/login/ui.module.css.d.ts b/src/features/auth/login/ui.module.css.d.ts new file mode 100644 index 00000000..feb5dcdc --- /dev/null +++ b/src/features/auth/login/ui.module.css.d.ts @@ -0,0 +1,5 @@ +declare const styles: { + readonly field: string; + readonly form: string; +}; +export = styles; diff --git a/src/features/auth/login/ui.tsx b/src/features/auth/login/ui.tsx new file mode 100644 index 00000000..e2a9e694 --- /dev/null +++ b/src/features/auth/login/ui.tsx @@ -0,0 +1,105 @@ +import { Button } from '@mui/material'; +import cn from 'classnames'; +import { useUnit } from 'effector-react'; +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { MAX_SHORT_LENGTH, MIN_LENGTH } from '@/shared/configs'; +import { usePreventDefault } from '@/shared/lib'; +import { CommonProps } from '@/shared/types'; +import { Checkbox, Field, Form, PasswordField } from '@/shared/ui'; + +import { form } from './model'; +import styles from './ui.module.css'; + +export const LoginForm: React.FC = (props) => { + const { className, } = props; + const { t, } = useTranslation('login'); + const loginText = t('login_form.submit'); + const submit = useUnit(form.submit); + + const onSubmit = usePreventDefault(submit); + + return ( +
+ + + + + + ); +}; + +const Email: React.FC = () => { + const { t, } = useTranslation('login'); + const email = useUnit(form.fields.email); + const { errorText, } = email; + + const label = t('login_form.fields.email'); + const error = t( + [`login_form.errors.email.${errorText}`, 'common:errors.default'], + { + min_symbols_count: MIN_LENGTH, + max_symbols_count: MAX_SHORT_LENGTH, + } + ); + const errorHelperText = email.isValid ? null : error; + + return ( + + ); +}; + +const Password: React.FC = () => { + const { t, } = useTranslation('login'); + const password = useUnit(form.fields.password); + const { errorText, } = password; + + const label = t('login_form.fields.password'); + const error = t( + [`login_form.errors.password.${errorText}`, 'common:errors.default'], + { + min_symbols_count: MIN_LENGTH, + max_symbols_count: MAX_SHORT_LENGTH, + } + ); + const errorHelperText = password.isValid ? null : error; + + return ( + + ); +}; + +const RememberMe: React.FC = () => { + const { t, } = useTranslation('login'); + const label = t('login_form.fields.remember_me'); + + const rememberMe = useUnit(form.fields.rememberMe); + + return ( + + ); +}; diff --git a/src/features/auth/logout/index.ts b/src/features/auth/logout/index.ts new file mode 100644 index 00000000..2ae3e7f7 --- /dev/null +++ b/src/features/auth/logout/index.ts @@ -0,0 +1,2 @@ +export * as logoutModel from './model'; +export { ProfileMenu } from './profile-menu'; diff --git a/src/features/auth/logout/model.ts b/src/features/auth/logout/model.ts new file mode 100644 index 00000000..6af03c0e --- /dev/null +++ b/src/features/auth/logout/model.ts @@ -0,0 +1,30 @@ +import { createMutation } from '@farfetched/core'; +import { runtypeContract } from '@farfetched/runtypes'; +import { createDomain, sample } from 'effector'; +import { Literal } from 'runtypes'; + +import { authApi } from '@/shared/api'; +import { sessionModel } from '@/shared/models'; +import { StandardResponse, getStandardResponse } from '@/shared/types'; + +const logoutDomain = createDomain(); + +const handlerFx = logoutDomain.effect>( + authApi.logout +); + +export const mutation = createMutation< + void, + StandardResponse, + StandardResponse, + Error +>({ + effect: handlerFx, + contract: runtypeContract(getStandardResponse(Literal(true))), +}); + +sample({ + clock: mutation.finished.success, + filter: ({ result, }) => globalThis.Boolean(result.data), + target: sessionModel.query.start, +}); diff --git a/src/features/auth/logout/profile-menu.tsx b/src/features/auth/logout/profile-menu.tsx new file mode 100644 index 00000000..e19b67dd --- /dev/null +++ b/src/features/auth/logout/profile-menu.tsx @@ -0,0 +1,70 @@ +import LogoutIcon from '@mui/icons-material/Logout'; +import SettingsIcon from '@mui/icons-material/Settings'; +import { IconButton, Menu, Tooltip } from '@mui/material'; +import { useUnit } from 'effector-react'; +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { UserAvatar } from '@/entities/users'; + +import { useToggle } from '@/shared/lib'; +import { sessionModel } from '@/shared/models'; +import { CommonProps } from '@/shared/types'; +import { MenuOption, MenuItem } from '@/shared/ui'; + +import { mutation } from './model'; + +export const ProfileMenu: React.FC = ({ className, }) => { + const { t, } = useTranslation('common'); + const user = useUnit(sessionModel.$user); + const [isOpen, { toggle, }] = useToggle(false); + const [reference, setReference] = React.useState(null); + const logout = useUnit(mutation); + + if (!user) { + return null; + } + + const items = t('profile_menu.items', { returnObjects: true, }) as Record< + string, + string + >; + + const options: MenuOption[] = [ + { + label: items.settings, + onClick: console.log, + icon: , + }, + { + label: items.logout, + onClick: () => logout.start(), + icon: , + } + ]; + + const { username, photo, email, } = user; + + const title = t('profile_menu.title', { username, }); + + return ( +
+ + + + + + + + {options.map((option) => ( + + ))} + +
+ ); +}; diff --git a/src/features/auth/registration/index.ts b/src/features/auth/registration/index.ts new file mode 100644 index 00000000..6fd51ea2 --- /dev/null +++ b/src/features/auth/registration/index.ts @@ -0,0 +1,2 @@ +export * as registrationModel from './model'; +export { RegistrationForm } from './ui'; diff --git a/src/features/auth/registration/model.ts b/src/features/auth/registration/model.ts new file mode 100644 index 00000000..e41e22db --- /dev/null +++ b/src/features/auth/registration/model.ts @@ -0,0 +1,140 @@ +import { createMutation } from '@farfetched/core'; +import { runtypeContract } from '@farfetched/runtypes'; +import { createDomain, sample } from 'effector'; +import { createForm } from 'effector-forms'; +import Joi from 'joi'; +import { splitMap } from 'patronum'; + +import { authApi, RegistrationParams, user, User } from '@/shared/api'; +import { + ALLOWED_SYMBOLS, + MIN_LENGTH, + MAX_SHORT_LENGTH +} from '@/shared/configs'; +import { createRuleFromSchema, isHttpErrorCode } from '@/shared/lib'; +import { StandardResponse, getStandardResponse } from '@/shared/types'; + +const registrationDomain = createDomain(); + +const handlerFx = registrationDomain.effect< + RegistrationParams, + StandardResponse +>(authApi.registration); + +export const mutation = createMutation< + RegistrationParams, + StandardResponse, + StandardResponse, + Error +>({ + effect: handlerFx, + contract: runtypeContract(getStandardResponse(user)), +}); + +interface RegistrationFormParams extends RegistrationParams { + readonly repeatPassword: string; +} + +const schemas = Joi.object({ + email: Joi.string() + .min(MIN_LENGTH) + .max(MAX_SHORT_LENGTH) + .email({ tlds: { allow: false, }, }) + .required() + .messages({ + 'string.empty': 'empty', + 'string.pattern.base': 'pattern', + 'string.email': 'email', + 'string.min': 'min_length', + 'string.max': 'max_length', + }), + username: Joi.string() + .min(MIN_LENGTH) + .max(MAX_SHORT_LENGTH) + .required() + .messages({ + 'string.empty': 'empty', + 'string.pattern.base': 'pattern', + 'string.min': 'min_length', + 'string.max': 'max_length', + }), + password: Joi.string() + .pattern(ALLOWED_SYMBOLS) + .min(MIN_LENGTH) + .max(MAX_SHORT_LENGTH) + .required() + .messages({ + 'string.empty': 'empty', + 'string.pattern.base': 'pattern', + 'string.min': 'min_length', + 'string.max': 'max_length', + }), + repeatPassword: Joi.string().messages({ + 'any.only': 'equal', + }), +}); + +export const form = createForm({ + fields: { + email: { + init: '', + rules: [createRuleFromSchema('email', schemas.extract('email'))], + }, + username: { + init: '', + rules: [createRuleFromSchema('username', schemas.extract('username'))], + }, + password: { + init: '', + rules: [createRuleFromSchema('password', schemas.extract('password'))], + }, + repeatPassword: { + init: '', + rules: [ + createRuleFromSchema( + 'repeatPassword', + schemas.extract('repeatPassword') + ) + ], + }, + }, +}); + +sample({ + clock: form.formValidated, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + fn: ({ repeatPassword: _, ...rest }) => rest, + target: mutation.start, +}); + +sample({ + clock: mutation.finished.failure, + fn: () => '', + target: [form.fields.password.$value, form.fields.repeatPassword.$value], +}); + +const errors = splitMap({ + source: mutation.finished.failure, + cases: { + userAlreadyRegistered: ({ error, }) => { + if (isHttpErrorCode(error, 409)) { + return 'exists'; + } + }, + }, +}); + +sample({ + clock: errors.userAlreadyRegistered, + fn: () => false, + target: form.fields.email.$isValid, +}); + +sample({ + clock: errors.userAlreadyRegistered, + fn: (message) => ({ + rule: 'server', + errorText: message, + }), + target: form.fields.email.addError, +}); diff --git a/src/features/auth/registration/ui.module.css b/src/features/auth/registration/ui.module.css new file mode 100644 index 00000000..649e445f --- /dev/null +++ b/src/features/auth/registration/ui.module.css @@ -0,0 +1,4 @@ +.form { + display: grid; + row-gap: 1em; +} diff --git a/src/components/Popups/components/CreateGroupPopup/CreateGroupPopup.module.css.d.ts b/src/features/auth/registration/ui.module.css.d.ts similarity index 100% rename from src/components/Popups/components/CreateGroupPopup/CreateGroupPopup.module.css.d.ts rename to src/features/auth/registration/ui.module.css.d.ts diff --git a/src/features/auth/registration/ui.tsx b/src/features/auth/registration/ui.tsx new file mode 100644 index 00000000..d5f2c430 --- /dev/null +++ b/src/features/auth/registration/ui.tsx @@ -0,0 +1,155 @@ +/* eslint-disable sonarjs/no-duplicate-string */ +import { Button } from '@mui/material'; +import cn from 'classnames'; +import { useUnit } from 'effector-react'; +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { MIN_LENGTH, MAX_SHORT_LENGTH } from '@/shared/configs'; +import { usePreventDefault } from '@/shared/lib'; +import { CommonProps } from '@/shared/types'; +import { Field, Form, PasswordField } from '@/shared/ui'; + +import { form, mutation } from './model'; +import styles from './ui.module.css'; + +export const RegistrationForm: React.FC = (props) => { + const { className, } = props; + const { t, } = useTranslation('registration'); + const submit = useUnit(form.submit); + const pending = useUnit(mutation.$pending); + const buttonText = t('registration_form.submit'); + + const onSubmit = usePreventDefault(submit); + + return ( +
+ + + + + + + ); +}; + +const Email: React.FC = () => { + const { t, } = useTranslation('registration'); + const email = useUnit(form.fields.email); + const { errorText, } = email; + + const label = t('registration_form.fields.email'); + const error = t( + [`registration_form.errors.email.${errorText}`, 'common:errors.default'], + { + min_symbols_count: MIN_LENGTH, + max_symbols_count: MAX_SHORT_LENGTH, + } + ); + const errorHelperText = email.isValid ? null : error; + + return ( + + ); +}; + +const Username: React.FC = () => { + const { t, } = useTranslation('registration'); + const username = useUnit(form.fields.username); + const { errorText, } = username; + + const label = t('registration_form.fields.username'); + const error = t( + [`registration_form.errors.username.${errorText}`, 'common:errors.default'], + { + min_symbols_count: MIN_LENGTH, + max_symbols_count: MAX_SHORT_LENGTH, + } + ); + const errorHelperText = username.isValid ? null : error; + + return ( + + ); +}; + +const Password: React.FC = () => { + const { t, } = useTranslation('registration'); + const password = useUnit(form.fields.password); + const { errorText, } = password; + + const label = t('registration_form.fields.password'); + const error = t( + [`registration_form.errors.password.${errorText}`, 'common:errors.default'], + { + min_symbols_count: MIN_LENGTH, + max_symbols_count: MAX_SHORT_LENGTH, + } + ); + const errorHelperText = password.isValid ? null : error; + + return ( + + ); +}; + +const RepeatPassword: React.FC = () => { + const { t, } = useTranslation('registration'); + const repeatPassword = useUnit(form.fields.repeatPassword); + const { errorText, } = repeatPassword; + + const label = t('registration_form.fields.repeat_password'); + const error = t( + [ + `registration_form.errors.repeat_password.${errorText}`, + 'common:errors.default' + ], + { + min_symbols_count: MIN_LENGTH, + max_symbols_count: MAX_SHORT_LENGTH, + } + ); + const errorHelperText = repeatPassword.isValid ? null : error; + + return ( + + ); +}; diff --git a/src/features/invitation/approve-invitation/index.ts b/src/features/invitation/approve-invitation/index.ts new file mode 100644 index 00000000..5a80640c --- /dev/null +++ b/src/features/invitation/approve-invitation/index.ts @@ -0,0 +1,5 @@ +export * as approveInvitationModel from './model'; +export { + ApproveInvitationButton, + type ApproveInvitationButtonProps +} from './ui'; diff --git a/src/features/invitation/approve-invitation/model.ts b/src/features/invitation/approve-invitation/model.ts new file mode 100644 index 00000000..ac7d2e2f --- /dev/null +++ b/src/features/invitation/approve-invitation/model.ts @@ -0,0 +1,40 @@ +import { createMutation } from '@farfetched/core'; +import { runtypeContract } from '@farfetched/runtypes'; +import { createEffect, sample } from 'effector'; +import { Boolean } from 'runtypes'; + +import { invitationsApi } from '@/shared/api'; +import { i18n } from '@/shared/configs'; +import { notificationsModel } from '@/shared/models'; +import { getStandardResponse } from '@/shared/types'; + +const handlerFx = createEffect(invitationsApi.approveInvitation); + +export const mutation = createMutation({ + effect: handlerFx, + contract: runtypeContract(getStandardResponse(Boolean)), +}); + +sample({ + clock: mutation.finished.success, + fn: () => + ({ + message: i18n.t('actions.approve.notifications.success', { + ns: 'room-invitation', + }), + color: 'success', + } as const), + target: notificationsModel.create, +}); + +sample({ + clock: mutation.finished.failure, + fn: () => + ({ + message: i18n.t('actions.approve.notifications.error', { + ns: 'room-invitation', + }), + color: 'error', + } as const), + target: notificationsModel.create, +}); diff --git a/src/features/invitation/approve-invitation/ui.tsx b/src/features/invitation/approve-invitation/ui.tsx new file mode 100644 index 00000000..484d4fa0 --- /dev/null +++ b/src/features/invitation/approve-invitation/ui.tsx @@ -0,0 +1,34 @@ +import { Button } from '@mui/material'; +import { useUnit } from 'effector-react'; +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { CommonProps } from '@/shared/types'; + +import { mutation } from './model'; + + +export interface ApproveInvitationButtonProps extends CommonProps { + readonly id: number; +} + +export const ApproveInvitationButton: React.FC = ( + props +) => { + const { id, className, } = props; + + const { t, } = useTranslation('room-invitation'); + const approve = useUnit(mutation); + + const onClick = () => { + approve.start({ id, }); + }; + + const text = t('actions.approve.actions.button'); + + return ( + + ); +}; diff --git a/src/features/invitation/generate-invitation-link/generate-invitation-link.module.css b/src/features/invitation/generate-invitation-link/generate-invitation-link.module.css new file mode 100644 index 00000000..161a942a --- /dev/null +++ b/src/features/invitation/generate-invitation-link/generate-invitation-link.module.css @@ -0,0 +1,6 @@ +.container { + display: grid; + grid-template-columns: 1fr max-content; + align-items: center; + gap: 1em; +} diff --git a/src/features/invitation/generate-invitation-link/generate-invitation-link.module.css.d.ts b/src/features/invitation/generate-invitation-link/generate-invitation-link.module.css.d.ts new file mode 100644 index 00000000..4a355a77 --- /dev/null +++ b/src/features/invitation/generate-invitation-link/generate-invitation-link.module.css.d.ts @@ -0,0 +1,4 @@ +declare const styles: { + readonly container: string; +}; +export = styles; diff --git a/src/features/invitation/generate-invitation-link/generate-invitation-link.tsx b/src/features/invitation/generate-invitation-link/generate-invitation-link.tsx new file mode 100644 index 00000000..d86e14e4 --- /dev/null +++ b/src/features/invitation/generate-invitation-link/generate-invitation-link.tsx @@ -0,0 +1,68 @@ +import CopyAllIcon from '@mui/icons-material/CopyAll'; +import { IconButton, Tooltip } from '@mui/material'; +import { useGate, useUnit } from 'effector-react'; +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { CommonProps } from '@/shared/types'; +import { Field, Form } from '@/shared/ui'; + +import styles from './generate-invitation-link.module.css'; +import { Gate, copyLink, form } from './model'; + +export interface GenerateInvitationLinkProps extends CommonProps { + readonly roomId: number; +} + +export const GenerateInvitationLink: React.FC = ( + props +) => { + const { className, roomId, } = props; + + useGate(Gate, { roomId, }); + + return ( +
+
+ + +
+
+ ); +}; + +const InvitationLink: React.FC = () => { + const link = useUnit(form.fields.link); + const { t, } = useTranslation('room-invitations'); + + const label = t('actions.generate_link.fields.link'); + + return ( + + ); +}; + +const CopyButton: React.FC = () => { + const { t, } = useTranslation('room-invitations'); + + const onClick = useUnit(copyLink); + + const title = t('actions.generate_link.actions.copy'); + + return ( + + + + + + ); +}; diff --git a/src/features/invitation/generate-invitation-link/index.ts b/src/features/invitation/generate-invitation-link/index.ts new file mode 100644 index 00000000..994ef26e --- /dev/null +++ b/src/features/invitation/generate-invitation-link/index.ts @@ -0,0 +1,5 @@ +export * as generateInvitationLinkModel from './generate-invitation-link'; +export { + GenerateInvitationLink, + type GenerateInvitationLinkProps +} from './generate-invitation-link'; diff --git a/src/features/invitation/generate-invitation-link/model.ts b/src/features/invitation/generate-invitation-link/model.ts new file mode 100644 index 00000000..8f47dc6c --- /dev/null +++ b/src/features/invitation/generate-invitation-link/model.ts @@ -0,0 +1,72 @@ +import { cache, createQuery } from '@farfetched/core'; +import { runtypeContract } from '@farfetched/runtypes'; +import { createEffect, createEvent, sample } from 'effector'; +import { createForm } from 'effector-forms'; +import { createGate } from 'effector-react'; +import { String } from 'runtypes'; + +import { invitationsApi } from '@/shared/api'; +import { i18n } from '@/shared/configs'; +import { notificationsModel } from '@/shared/models'; +import { InRoomParams, getStandardResponse } from '@/shared/types'; + +const handlerFx = createEffect(invitationsApi.generateLink); + +export const query = createQuery({ + initialData: null, + effect: handlerFx, + contract: runtypeContract(getStandardResponse(String)), + mapData: ({ result, }) => result.data, +}); + +export interface FormOptions { + readonly link: string; +} + +export const form = createForm({ + fields: { + link: { + init: '', + }, + }, +}); + +const copyLinkFx = createEffect((link: string) => { + return navigator.clipboard.writeText(link); +}); + +export const copyLink = createEvent(); + +export const Gate = createGate(); + +sample({ + clock: Gate.open, + target: query.start, +}); + +sample({ + clock: copyLink, + source: query.$data, + filter: Boolean, + target: copyLinkFx, +}); + +sample({ + clock: copyLinkFx.done, + fn: () => ({ + message: i18n.t('actions.generate_link.notifications.success', { + ns: 'room-invitations', + }), + color: 'info' as const, + }), + target: notificationsModel.create, +}); + +sample({ + clock: query.$data, + filter: Boolean, + fn: (link) => ({ link, }), + target: form.setInitialForm, +}); + +cache(query); diff --git a/src/features/invitation/index.ts b/src/features/invitation/index.ts new file mode 100644 index 00000000..13082ec5 --- /dev/null +++ b/src/features/invitation/index.ts @@ -0,0 +1,5 @@ +export * from './invite-user-into-room'; +export * from './generate-invitation-link'; +export * from './remove-invitation'; +export * from './approve-invitation'; +export * from './reject-invitation'; diff --git a/src/features/invitation/invite-user-into-room/index.ts b/src/features/invitation/invite-user-into-room/index.ts new file mode 100644 index 00000000..f0fd50e4 --- /dev/null +++ b/src/features/invitation/invite-user-into-room/index.ts @@ -0,0 +1,5 @@ +export * as inviteUserIntoRoomModel from './model'; +export { + InviteUserIntoRoom, + type InviteUserIntoRoomProps +} from './invite-user-into-room'; diff --git a/src/features/invitation/invite-user-into-room/invite-user-into-room.module.css b/src/features/invitation/invite-user-into-room/invite-user-into-room.module.css new file mode 100644 index 00000000..ad10f9d2 --- /dev/null +++ b/src/features/invitation/invite-user-into-room/invite-user-into-room.module.css @@ -0,0 +1,6 @@ +.form { + display: grid; + gap: 1em; + + padding: 1em; +} diff --git a/src/components/Popups/components/CreateRoomPopup/CreateRoomPopup.module.css.d.ts b/src/features/invitation/invite-user-into-room/invite-user-into-room.module.css.d.ts similarity index 100% rename from src/components/Popups/components/CreateRoomPopup/CreateRoomPopup.module.css.d.ts rename to src/features/invitation/invite-user-into-room/invite-user-into-room.module.css.d.ts diff --git a/src/features/invitation/invite-user-into-room/invite-user-into-room.tsx b/src/features/invitation/invite-user-into-room/invite-user-into-room.tsx new file mode 100644 index 00000000..af70a780 --- /dev/null +++ b/src/features/invitation/invite-user-into-room/invite-user-into-room.tsx @@ -0,0 +1,84 @@ +import CloseIcon from '@mui/icons-material/Close'; +import { LoadingButton } from '@mui/lab'; +import { Paper, IconButton } from '@mui/material'; +import cn from 'classnames'; +import { useUnit } from 'effector-react'; +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { TemplateUserListItem, UserSearch } from '@/entities/users'; + +import { usePreventDefault } from '@/shared/lib'; +import { CommonProps } from '@/shared/types'; + +import styles from './invite-user-into-room.module.css'; +import { form, mutation } from './model'; + +export interface InviteUserIntoRoomProps extends CommonProps {} + +export const InviteUserIntoRoom: React.FC = ( + props +) => { + const { className, } = props; + const { t, } = useTranslation('room-invitations'); + const submit = useUnit(form.submit); + const isLoading = useUnit(mutation.$pending); + const user = useUnit(form.fields.user.$value); + + const onSubmit: React.FormEventHandler = usePreventDefault(submit); + + const buttonText = user + ? t('actions.invite_user.actions.submit', { username: user.username, }) + : t('actions.invite_user.actions.submit', { context: 'disabled', }); + + return ( +
+ + + {buttonText} + + + ); +}; + +const User: React.FC = () => { + const user = useUnit(form.fields.user); + const { t, } = useTranslation('room-invitations'); + + if (user.value) { + return ( + + + + + ), + }} + /> + + ); + } + const label = t('actions.invite_user.fields.user'); + + return ( + + ); +}; diff --git a/src/features/invitation/invite-user-into-room/model.ts b/src/features/invitation/invite-user-into-room/model.ts new file mode 100644 index 00000000..87976aa3 --- /dev/null +++ b/src/features/invitation/invite-user-into-room/model.ts @@ -0,0 +1,83 @@ +import { createMutation, update } from '@farfetched/core'; +import { runtypeContract } from '@farfetched/runtypes'; +import { createEffect, sample } from 'effector'; +import { createForm } from 'effector-forms'; + +import { invitationsModel } from '@/entities/invitations'; + +import { invitation, invitationsApi, User } from '@/shared/api'; +import { i18n, routes } from '@/shared/configs'; +import { notificationsModel } from '@/shared/models'; +import { getStandardResponse } from '@/shared/types'; + +const handlerFx = createEffect(invitationsApi.invite); + +export const mutation = createMutation({ + effect: handlerFx, + contract: runtypeContract(getStandardResponse(invitation)), +}); + +interface AddUserFormValues { + readonly user: User | null; +} + +export const form = createForm({ + fields: { + user: { + init: null, + }, + }, +}); + +sample({ + clock: form.formValidated, + source: routes.room.users.$params, + filter: (_, values) => Boolean(values.user), + fn: (params, values) => ({ userId: values.user!.id, roomId: params.id, }), + target: mutation.start, +}); + +sample({ + clock: mutation.finished.success, + fn: () => ({ + message: i18n.t('actions.invite_user.notifications.success', { + ns: 'room-invitations', + }), + color: 'success' as const, + }), + target: notificationsModel.create, +}); + +sample({ + clock: mutation.finished.failure, + fn: () => ({ + message: i18n.t('actions.invite_user.notifications.error', { + ns: 'room-invitations', + }), + color: 'error' as const, + }), + target: notificationsModel.create, +}); + +update(invitationsModel.query, { + on: mutation, + by: { + success: ({ query, mutation, }) => { + if (!query) { + return { + result: [], + }; + } + + if ('error' in query) { + return { + error: query.error, + }; + } + + return { + result: [...query.result, mutation.result.data], + }; + }, + }, +}); diff --git a/src/features/invitation/reject-invitation/index.ts b/src/features/invitation/reject-invitation/index.ts new file mode 100644 index 00000000..86233baf --- /dev/null +++ b/src/features/invitation/reject-invitation/index.ts @@ -0,0 +1,2 @@ +export * as rejectInvitationModel from './model'; +export { RejectInvitationButton, type RejectInvitationButtonProps } from './ui'; diff --git a/src/features/invitation/reject-invitation/model.ts b/src/features/invitation/reject-invitation/model.ts new file mode 100644 index 00000000..49791f28 --- /dev/null +++ b/src/features/invitation/reject-invitation/model.ts @@ -0,0 +1,40 @@ +import { createMutation } from '@farfetched/core'; +import { runtypeContract } from '@farfetched/runtypes'; +import { createEffect, sample } from 'effector'; +import { Boolean } from 'runtypes'; + +import { invitationsApi } from '@/shared/api'; +import { i18n } from '@/shared/configs'; +import { notificationsModel } from '@/shared/models'; +import { getStandardResponse } from '@/shared/types'; + +const handlerFx = createEffect(invitationsApi.rejectInvitation); + +export const mutation = createMutation({ + effect: handlerFx, + contract: runtypeContract(getStandardResponse(Boolean)), +}); + +sample({ + clock: mutation.finished.success, + fn: () => + ({ + message: i18n.t('actions.reject.notifications.success', { + ns: 'room-invitation', + }), + color: 'success', + } as const), + target: notificationsModel.create, +}); + +sample({ + clock: mutation.finished.failure, + fn: () => + ({ + message: i18n.t('actions.reject.notifications.error', { + ns: 'room-invitation', + }), + color: 'error', + } as const), + target: notificationsModel.create, +}); diff --git a/src/features/invitation/reject-invitation/ui.tsx b/src/features/invitation/reject-invitation/ui.tsx new file mode 100644 index 00000000..9e45070e --- /dev/null +++ b/src/features/invitation/reject-invitation/ui.tsx @@ -0,0 +1,34 @@ +import { Button } from '@mui/material'; +import { useUnit } from 'effector-react'; +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { CommonProps } from '@/shared/types'; + +import { mutation } from './model'; + + +export interface RejectInvitationButtonProps extends CommonProps { + readonly id: number; +} + +export const RejectInvitationButton: React.FC = ( + props +) => { + const { id, className, } = props; + + const { t, } = useTranslation('room-invitation'); + const approve = useUnit(mutation); + + const onClick = () => { + approve.start({ id, }); + }; + + const text = t('actions.reject.actions.button'); + + return ( + + ); +}; diff --git a/src/features/invitation/remove-invitation/index.ts b/src/features/invitation/remove-invitation/index.ts new file mode 100644 index 00000000..b0f7a2cf --- /dev/null +++ b/src/features/invitation/remove-invitation/index.ts @@ -0,0 +1,5 @@ +export * as removeInvitationModel from './model'; +export { + RemoveInvitation, + type RemoveInvitationProps +} from './remove-invitation'; diff --git a/src/features/invitation/remove-invitation/model.ts b/src/features/invitation/remove-invitation/model.ts new file mode 100644 index 00000000..0d2ce78b --- /dev/null +++ b/src/features/invitation/remove-invitation/model.ts @@ -0,0 +1,69 @@ +import { createMutation, update } from '@farfetched/core'; +import { runtypeContract } from '@farfetched/runtypes'; +import { createEffect, sample } from 'effector'; +import { Boolean } from 'runtypes'; + +import { invitationsModel } from '@/entities/invitations'; + +import { invitationsApi } from '@/shared/api'; +import { i18n } from '@/shared/configs'; +import { notificationsModel } from '@/shared/models'; +import { getStandardResponse } from '@/shared/types'; + +const handlerFx = createEffect(invitationsApi.remove); + +export const mutation = createMutation({ + effect: handlerFx, + contract: runtypeContract(getStandardResponse(Boolean)), +}); + +update(invitationsModel.query, { + on: mutation, + by: { + success: ({ query, mutation, }) => { + if (!query) { + return { + result: [], + }; + } + + if ('error' in query) { + return { + error: query.error, + }; + } + + if (!mutation.result.data) { + return query; + } + + return { + result: query.result.filter( + (invitation) => invitation.id !== mutation.params.id + ), + }; + }, + }, +}); + +sample({ + clock: mutation.finished.success, + fn: () => ({ + message: i18n.t('actions.remove_invitation.notifications.success', { + ns: 'room-invitations', + }), + color: 'success' as const, + }), + target: notificationsModel.create, +}); + +sample({ + clock: mutation.finished.failure, + fn: () => ({ + message: i18n.t('actions.remove_invitation.notifications.error', { + ns: 'room-invitations', + }), + color: 'error' as const, + }), + target: notificationsModel.create, +}); diff --git a/src/features/invitation/remove-invitation/remove-invitation.tsx b/src/features/invitation/remove-invitation/remove-invitation.tsx new file mode 100644 index 00000000..d8aa9582 --- /dev/null +++ b/src/features/invitation/remove-invitation/remove-invitation.tsx @@ -0,0 +1,55 @@ +import RemoveIcon from '@mui/icons-material/Remove'; +import { IconButton, Tooltip } from '@mui/material'; +import { useUnit } from 'effector-react'; +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { useToggle } from '@/shared/lib'; +import { CommonProps } from '@/shared/types'; +import { Confirm } from '@/shared/ui'; + +import { mutation } from './model'; + +export interface RemoveInvitationProps extends CommonProps { + readonly id: number; + readonly roomId: number; +} + +export const RemoveInvitation: React.FC = (props) => { + const { className, id, roomId, } = props; + const [toggled, { toggleOff, toggleOn, }] = useToggle(false); + + const { t, } = useTranslation('room-invitations'); + const removeInvitation = useUnit(mutation); + + const onAgree = React.useCallback(() => { + removeInvitation.start({ id, roomId, }); + toggleOff(); + }, [toggleOff, id, roomId]); + + const title = t('actions.remove_invitation.title'); + const content = t('actions.remove_invitation.content'); + const open = t('actions.remove_invitation.actions.open'); + const agree = t('actions.remove_invitation.actions.agree'); + const disagree = t('actions.remove_invitation.actions.disagree'); + + return ( + <> + + + + + + + + ); +}; diff --git a/src/features/page/change-language/index.ts b/src/features/page/change-language/index.ts new file mode 100644 index 00000000..2fefd49a --- /dev/null +++ b/src/features/page/change-language/index.ts @@ -0,0 +1 @@ +export { ChangeLanguage } from './ui'; diff --git a/src/features/page/change-language/ui.tsx b/src/features/page/change-language/ui.tsx new file mode 100644 index 00000000..99f05ee8 --- /dev/null +++ b/src/features/page/change-language/ui.tsx @@ -0,0 +1,59 @@ +import { + SelectProps as MUISelectProps, + MenuItem, + TextField +} from '@mui/material'; +import { useUnit } from 'effector-react'; +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { deviceInfoModel, i18nModel } from '@/shared/models'; + +const languages = ['ru', 'en']; + +export const ChangeLanguage: React.FC = () => { + const [language, changeLanguage] = useUnit([ + i18nModel.$language, + i18nModel.changeLanguage + ]); + const isMobile = useUnit(deviceInfoModel.$isMobile); + const [t] = useTranslation('common'); + + const onChange = (event: React.ChangeEvent) => { + changeLanguage(event.target.value as any); + }; + + const context = isMobile ? 'short' : ''; + + return ( + + {languages.map((language) => ( + + {t(`languages.${language}`, { context, })} + + ))} + + ); +}; + +const SelectProps: MUISelectProps = { + MenuProps: { + MenuListProps: { + disablePadding: true, + }, + anchorOrigin: { + horizontal: 'right', + vertical: 'bottom', + }, + transformOrigin: { + horizontal: 'right', + vertical: 'top', + }, + }, +}; diff --git a/src/features/page/color-scheme-toggler/adaptive-color-scheme-toggler.tsx b/src/features/page/color-scheme-toggler/adaptive-color-scheme-toggler.tsx new file mode 100644 index 00000000..b4cfdf02 --- /dev/null +++ b/src/features/page/color-scheme-toggler/adaptive-color-scheme-toggler.tsx @@ -0,0 +1,27 @@ +import { useUnit } from 'effector-react'; +import * as React from 'react'; + +import { deviceInfoModel } from '@/shared/models'; +import { CommonProps } from '@/shared/types'; + +import { DesktopColorschemeToggler } from './desktop-color-scheme-toggler'; +import { MobileColorSchemeToggler } from './mobile-color-scheme-toggler'; + +export interface AdaptiveColorSchemeTogglerProps extends CommonProps {} + +export const AdaptiveColorSchemeToggler: React.FC< + AdaptiveColorSchemeTogglerProps +> = (props) => { + const [isMobile, isTableVertical] = useUnit([ + deviceInfoModel.$isMobile, + deviceInfoModel.$isTabletVertical + ]); + + const isMobileToggler = isMobile || isTableVertical; + + if (isMobileToggler) { + return ; + } + + return ; +}; diff --git a/src/features/page/color-scheme-toggler/config.ts b/src/features/page/color-scheme-toggler/config.ts new file mode 100644 index 00000000..a7d467cf --- /dev/null +++ b/src/features/page/color-scheme-toggler/config.ts @@ -0,0 +1,26 @@ +import DarkModeIcon from '@mui/icons-material/DarkMode'; +import LightModeIcon from '@mui/icons-material/LightMode'; +import ModeStandbyIcon from '@mui/icons-material/ModeStandby'; +import * as React from 'react'; + +import { colorSchemeModel } from '@/shared/models'; + +export const ICONS_MAP: Record< + colorSchemeModel.ColorScheme, + React.ComponentType +> = { + dark: DarkModeIcon, + system: ModeStandbyIcon, + light: LightModeIcon, +}; + +export interface Scheme { + readonly value: colorSchemeModel.ColorScheme; + readonly icon: React.ComponentType; +} + +export const SCHEMES: colorSchemeModel.ColorScheme[] = [ + 'dark', + 'system', + 'light' +]; diff --git a/src/features/page/color-scheme-toggler/desktop-color-scheme-toggler.tsx b/src/features/page/color-scheme-toggler/desktop-color-scheme-toggler.tsx new file mode 100644 index 00000000..8b13317e --- /dev/null +++ b/src/features/page/color-scheme-toggler/desktop-color-scheme-toggler.tsx @@ -0,0 +1,49 @@ +import { ToggleButton, ToggleButtonGroup, Tooltip } from '@mui/material'; +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { colorSchemeModel } from '@/shared/models'; +import { CommonProps } from '@/shared/types'; + +import { ICONS_MAP, SCHEMES } from './config'; +import { useToggleColorScheme } from './lib'; + +export interface DesktopColorSchemeTogglerProps extends CommonProps { + readonly size?: 'small' | 'medium' | 'large'; +} + +export const DesktopColorschemeToggler: React.FC< + DesktopColorSchemeTogglerProps +> = (props) => { + const { className, size = 'small', } = props; + const { t, } = useTranslation('common'); + const [colorScheme, changeColorScheme] = useToggleColorScheme(); + + const onChange = (_event: unknown, value: colorSchemeModel.ColorScheme) => { + changeColorScheme(value); + }; + + return ( + + {SCHEMES.map((scheme) => { + return ( + + + {React.createElement(ICONS_MAP[scheme])} + + + ); + })} + + ); +}; diff --git a/src/features/page/color-scheme-toggler/index.ts b/src/features/page/color-scheme-toggler/index.ts new file mode 100644 index 00000000..fbcffa52 --- /dev/null +++ b/src/features/page/color-scheme-toggler/index.ts @@ -0,0 +1,14 @@ +export { + DesktopColorschemeToggler, + type DesktopColorSchemeTogglerProps +} from './desktop-color-scheme-toggler'; + +export { + MobileColorSchemeToggler, + type MobileColorSchemeTogglerProps +} from './mobile-color-scheme-toggler'; + +export { + AdaptiveColorSchemeToggler, + type AdaptiveColorSchemeTogglerProps +} from './adaptive-color-scheme-toggler'; diff --git a/src/features/page/color-scheme-toggler/lib/index.ts b/src/features/page/color-scheme-toggler/lib/index.ts new file mode 100644 index 00000000..151c832d --- /dev/null +++ b/src/features/page/color-scheme-toggler/lib/index.ts @@ -0,0 +1 @@ +export * from './useToggleColorScheme'; diff --git a/src/features/page/color-scheme-toggler/lib/useToggleColorScheme.ts b/src/features/page/color-scheme-toggler/lib/useToggleColorScheme.ts new file mode 100644 index 00000000..23208a3d --- /dev/null +++ b/src/features/page/color-scheme-toggler/lib/useToggleColorScheme.ts @@ -0,0 +1,12 @@ +import { useUnit } from 'effector-react'; + +import { colorSchemeModel } from '@/shared/models'; + +export const useToggleColorScheme = () => { + const [scheme, changeScheme] = useUnit([ + colorSchemeModel.$scheme, + colorSchemeModel.colorSchemeChanged + ]); + + return [scheme, changeScheme] as const; +}; diff --git a/src/features/page/color-scheme-toggler/mobile-color-scheme-toggler.tsx b/src/features/page/color-scheme-toggler/mobile-color-scheme-toggler.tsx new file mode 100644 index 00000000..4f09ed05 --- /dev/null +++ b/src/features/page/color-scheme-toggler/mobile-color-scheme-toggler.tsx @@ -0,0 +1,81 @@ +import { + IconButton, + ListItemIcon, + Menu, + MenuItem, + Tooltip +} from '@mui/material'; +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { useToggle } from '@/shared/lib'; +import { colorSchemeModel } from '@/shared/models'; +import { CommonProps } from '@/shared/types'; + +import { ICONS_MAP, SCHEMES } from './config'; +import { useToggleColorScheme } from './lib'; + +export interface MobileColorSchemeTogglerProps extends CommonProps {} + +export const MobileColorSchemeToggler: React.FC< + MobileColorSchemeTogglerProps +> = (props) => { + const { className, } = props; + const [opened, handlers] = useToggle(); + const { t, } = useTranslation('common'); + const [ref, setRef] = React.useState(null); + const [colorScheme, changeColorScheme] = useToggleColorScheme(); + + const SelectedIcon = ICONS_MAP[colorScheme]; + + const createOnChange = (value: colorSchemeModel.ColorScheme) => { + return () => { + changeColorScheme(value); + handlers.toggleOff(); + }; + }; + + const activated = t('color_schemes.activated', { scheme: colorScheme, }); + + return ( + <> + + + + + + + {SCHEMES.map((scheme) => { + return ( + + + {React.createElement(ICONS_MAP[scheme])} + + {t(`color_schemes.schemes.${scheme}`)} + + ); + })} + + + ); +}; diff --git a/src/features/page/index.ts b/src/features/page/index.ts new file mode 100644 index 00000000..8b52c45a --- /dev/null +++ b/src/features/page/index.ts @@ -0,0 +1,3 @@ +export * from './navigation'; +export * from './color-scheme-toggler'; +export * from './change-language'; diff --git a/src/features/page/navigation/index.ts b/src/features/page/navigation/index.ts new file mode 100644 index 00000000..b221b93c --- /dev/null +++ b/src/features/page/navigation/index.ts @@ -0,0 +1 @@ +export { Navigation, type NavigationProps } from './navigation'; diff --git a/src/features/page/navigation/navigation.module.css b/src/features/page/navigation/navigation.module.css new file mode 100644 index 00000000..5a2676b0 --- /dev/null +++ b/src/features/page/navigation/navigation.module.css @@ -0,0 +1,5 @@ +.navigation { +} + +.list { +} diff --git a/src/features/page/navigation/navigation.module.css.d.ts b/src/features/page/navigation/navigation.module.css.d.ts new file mode 100644 index 00000000..269ee649 --- /dev/null +++ b/src/features/page/navigation/navigation.module.css.d.ts @@ -0,0 +1,5 @@ +declare const styles: { + readonly list: string; + readonly navigation: string; +}; +export = styles; diff --git a/src/features/page/navigation/navigation.tsx b/src/features/page/navigation/navigation.tsx new file mode 100644 index 00000000..7a4e133c --- /dev/null +++ b/src/features/page/navigation/navigation.tsx @@ -0,0 +1,55 @@ +import HomeIcon from '@mui/icons-material/Home'; +import { + List, + ListItem, + ListItemButton, + ListItemIcon, + ListItemText +} from '@mui/material'; +import { Link } from 'atomic-router-react'; +import cn from 'classnames'; +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { routes } from '@/shared/configs'; +import { CommonProps } from '@/shared/types'; + +import styles from './navigation.module.css'; + +export interface NavigationProps extends CommonProps {} + +export const Navigation: React.FC = (props) => { + const { className, } = props; + const { t, } = useTranslation('common'); + + const roomsText = t('navigation.items.rooms'); + + const items = [ + { + route: routes.rooms.base, + label: roomsText, + icon: , + } + ]; + + return ( + + ); +}; diff --git a/src/features/rooms/create-room/create-room.module.css b/src/features/rooms/create-room/create-room.module.css new file mode 100644 index 00000000..571f85b3 --- /dev/null +++ b/src/features/rooms/create-room/create-room.module.css @@ -0,0 +1,5 @@ +@media (min-width: 640px) { + .form { + min-width: 550px; + } +} diff --git a/src/components/Popups/components/CreateTaskPopup/CreateTaskPopup.module.css.d.ts b/src/features/rooms/create-room/create-room.module.css.d.ts similarity index 100% rename from src/components/Popups/components/CreateTaskPopup/CreateTaskPopup.module.css.d.ts rename to src/features/rooms/create-room/create-room.module.css.d.ts diff --git a/src/features/rooms/create-room/create-room.tsx b/src/features/rooms/create-room/create-room.tsx new file mode 100644 index 00000000..e0c249c8 --- /dev/null +++ b/src/features/rooms/create-room/create-room.tsx @@ -0,0 +1,52 @@ +import { Button } from '@mui/material'; +import { useUnit } from 'effector-react'; +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { deviceInfoModel } from '@/shared/models'; +import { BasePopupProps, CommonProps } from '@/shared/types'; +import { FullWidthPopup, MainPopup } from '@/shared/ui'; + +import { RoomForm } from '../form'; + +import styles from './create-room.module.css'; +import { close, form, mutation } from './model'; + +export interface CreateRoomProps extends CommonProps, BasePopupProps {} + +export const CreateRoom: React.FC = (props) => { + const { t, } = useTranslation('rooms'); + const onClose = useUnit(close); + const [isMobile, isVertical] = useUnit([ + deviceInfoModel.$isMobile, + deviceInfoModel.$isTabletVertical + ]); + + const onClick = useUnit(form.submit); + const pending = useUnit(mutation.$pending); + + const isFullscreen = isMobile || isVertical; + + const Popup = isFullscreen ? FullWidthPopup : MainPopup; + + const titleText = t('actions.create_room.title'); + const buttonText = t('actions.create', { ns: 'common', }); + + const actions = isFullscreen ? ( + + ) : null; + + return ( + + + + ); +}; diff --git a/src/features/rooms/create-room/index.ts b/src/features/rooms/create-room/index.ts new file mode 100644 index 00000000..36c17d14 --- /dev/null +++ b/src/features/rooms/create-room/index.ts @@ -0,0 +1,3 @@ +export * as createRoomModel from './model'; +export { CreateRoom, type CreateRoomProps } from './create-room'; +export { OpenCreateRoom, type OpenCreateRoomProps } from './open-create-room'; diff --git a/src/features/rooms/create-room/model.ts b/src/features/rooms/create-room/model.ts new file mode 100644 index 00000000..39d67e91 --- /dev/null +++ b/src/features/rooms/create-room/model.ts @@ -0,0 +1,91 @@ +import { createMutation, update } from '@farfetched/core'; +import { runtypeContract } from '@farfetched/runtypes'; +import { createDomain, sample } from 'effector'; + +import { createPopupControlModel } from '@/entities/popups'; +import { roomsModel } from '@/entities/rooms'; + +import { CreateRoomParams, room, Room, roomsApi } from '@/shared/api'; +import { i18n, popupsMap } from '@/shared/configs'; +import { notificationsModel } from '@/shared/models'; +import { getStandardResponse, StandardResponse } from '@/shared/types'; + +import { roomFormModel } from '../form'; + +const createRoomsDomain = createDomain(); + +const handlerFx = createRoomsDomain.effect(roomsApi.create); + +export const mutation = createMutation< + CreateRoomParams, + StandardResponse, + StandardResponse, + Error +>({ + effect: handlerFx, + contract: runtypeContract(getStandardResponse(room)), +}); + +export const form = roomFormModel.create(); + +export const { close, $isOpen, } = createPopupControlModel(popupsMap.createRoom); +const { reset, formValidated, } = form; + +sample({ + clock: close, + target: reset, +}); + +sample({ + clock: mutation.finished.success, + target: close, +}); + +sample({ + clock: formValidated, + filter: $isOpen, + target: mutation.start, +}); + +update(roomsModel.query, { + on: mutation, + by: { + success: ({ query, mutation, }) => { + if (!query) { + return { + result: [], + }; + } + + if ('error' in query) { + return { + error: query.error, + }; + } + + return { + result: [...query.result, mutation.result.data], + }; + }, + }, +}); + +sample({ + clock: mutation.finished.success, + fn: () => ({ + message: i18n.t('actions.create_room.notifications.success', { + ns: 'rooms', + }), + color: 'success' as const, + }), + target: notificationsModel.create, +}); + +sample({ + clock: mutation.finished.failure, + fn: () => ({ + message: i18n.t('actions.create_room.notifications.error', { ns: 'rooms', }), + color: 'error' as const, + }), + target: notificationsModel.create, +}); diff --git a/src/features/rooms/create-room/open-create-room.tsx b/src/features/rooms/create-room/open-create-room.tsx new file mode 100644 index 00000000..837131f0 --- /dev/null +++ b/src/features/rooms/create-room/open-create-room.tsx @@ -0,0 +1,24 @@ +import AddIcon from '@mui/icons-material/Add'; +import { IconButton } from '@mui/material'; +import { Link } from 'atomic-router-react'; +import * as React from 'react'; + +import { routes, getParams, popupsMap } from '@/shared/configs'; +import { CommonProps } from '@/shared/types'; + +export interface OpenCreateRoomProps extends CommonProps {} + +export const OpenCreateRoom: React.FC = (props) => { + const { className, } = props; + + return ( + + + + ); +}; diff --git a/src/components/Popups/components/RoomForm/RoomForm.module.css b/src/features/rooms/form/form.module.css similarity index 100% rename from src/components/Popups/components/RoomForm/RoomForm.module.css rename to src/features/rooms/form/form.module.css diff --git a/src/features/rooms/form/form.module.css.d.ts b/src/features/rooms/form/form.module.css.d.ts new file mode 100644 index 00000000..da6e2b2c --- /dev/null +++ b/src/features/rooms/form/form.module.css.d.ts @@ -0,0 +1,5 @@ +declare const styles: { + readonly button: string; + readonly form: string; +}; +export = styles; diff --git a/src/features/rooms/form/form.tsx b/src/features/rooms/form/form.tsx new file mode 100644 index 00000000..f5ab21ff --- /dev/null +++ b/src/features/rooms/form/form.tsx @@ -0,0 +1,109 @@ +import { Button, Stack } from '@mui/material'; +import cn from 'classnames'; +import { Form } from 'effector-forms'; +import { useUnit } from 'effector-react'; +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { MIN_LENGTH, MAX_SHORT_LENGTH } from '@/shared/configs'; +import { usePreventDefault } from '@/shared/lib'; +import { CommonProps } from '@/shared/types'; +import { Field, Show } from '@/shared/ui'; + +import styles from './form.module.css'; +import { RoomFormValues } from './model'; + +export interface RoomFormProps extends CommonProps { + readonly $form: Form; + readonly hideButton?: boolean; + readonly buttonText?: string; + readonly disabled?: boolean; +} + +export const RoomForm: React.FC = (props) => { + const { className, buttonText, $form, disabled, hideButton, } = props; + const submit = useUnit($form.submit); + + const onSubmit = usePreventDefault(submit); + + return ( + + + + + + + + ); +}; + +interface FieldProps { + readonly $form: Form; +} + +const Name: React.FC = (props) => { + const { $form, } = props; + const { t, } = useTranslation('rooms'); + const name = useUnit($form.fields.name); + const { errorText, } = name; + + const label = t('actions.room_form.fields.name'); + const error = t( + [`actions.room_form.errors.name.${errorText}`, 'common:errors.default'], + { + min_symbols_count: MIN_LENGTH, + max_symbols_count: MAX_SHORT_LENGTH, + } + ); + const errorHelperText = name.isValid ? null : error; + + return ( + + ); +}; + +const Description: React.FC = (props) => { + const { $form, } = props; + const { t, } = useTranslation('rooms'); + const description = useUnit($form.fields.description); + const { errorText, } = description; + + const label = t('actions.room_form.fields.description'); + const error = t( + [ + `actions.room_form.errors.description.${errorText}`, + 'common:errors.default' + ], + { + min_symbols_count: MIN_LENGTH, + max_symbols_count: MAX_SHORT_LENGTH, + } + ); + const errorHelperText = description.isValid ? null : error; + + return ( + + ); +}; diff --git a/src/features/rooms/form/index.ts b/src/features/rooms/form/index.ts new file mode 100644 index 00000000..9a386f7b --- /dev/null +++ b/src/features/rooms/form/index.ts @@ -0,0 +1,3 @@ +export * as roomFormModel from './model'; +export { RoomForm, type RoomFormProps } from './form'; +export { SkeletonRoomForm, type SkeletonRoomFormProps } from './skeleton'; diff --git a/src/features/rooms/form/model.ts b/src/features/rooms/form/model.ts new file mode 100644 index 00000000..a340c041 --- /dev/null +++ b/src/features/rooms/form/model.ts @@ -0,0 +1,34 @@ +import { createForm } from 'effector-forms'; +import Joi from 'joi'; + +import { Room } from '@/shared/api'; +import { MAX_SHORT_LENGTH, MIN_LENGTH } from '@/shared/configs'; +import { createRuleFromSchema } from '@/shared/lib'; + +export interface RoomFormValues extends Pick {} + +const schemas = { + name: Joi.string().min(MIN_LENGTH).max(MAX_SHORT_LENGTH).required().messages({ + 'string.empty': 'empty', + 'string.min': 'min_length', + 'string.max': 'max_length', + }), + description: Joi.string().max(MAX_SHORT_LENGTH).messages({ + 'string.max': 'max_length', + }), +}; + +export const create = () => { + return createForm({ + fields: { + name: { + init: '', + rules: [createRuleFromSchema('name', schemas.name)], + }, + description: { + init: '', + rules: [createRuleFromSchema('description', schemas.description)], + }, + }, + }); +}; diff --git a/src/features/rooms/form/skeleton.module.css b/src/features/rooms/form/skeleton.module.css new file mode 100644 index 00000000..e2a603b6 --- /dev/null +++ b/src/features/rooms/form/skeleton.module.css @@ -0,0 +1,3 @@ +.form { + padding: 1em; +} diff --git a/src/components/Popups/components/UpdateGroupPopup/UpdateGroupPopup.module.css.d.ts b/src/features/rooms/form/skeleton.module.css.d.ts similarity index 100% rename from src/components/Popups/components/UpdateGroupPopup/UpdateGroupPopup.module.css.d.ts rename to src/features/rooms/form/skeleton.module.css.d.ts diff --git a/src/features/rooms/form/skeleton.tsx b/src/features/rooms/form/skeleton.tsx new file mode 100644 index 00000000..dbfb0977 --- /dev/null +++ b/src/features/rooms/form/skeleton.tsx @@ -0,0 +1,21 @@ +import { Skeleton, Stack } from '@mui/material'; +import cn from 'classnames'; +import * as React from 'react'; + +import { CommonProps } from '@/shared/types'; + +import styles from './skeleton.module.css'; + +export interface SkeletonRoomFormProps extends CommonProps {} + +export const SkeletonRoomForm: React.FC = (props) => { + const { className, } = props; + + return ( + + + + + + ); +}; diff --git a/src/features/rooms/index.ts b/src/features/rooms/index.ts new file mode 100644 index 00000000..14908d2d --- /dev/null +++ b/src/features/rooms/index.ts @@ -0,0 +1,4 @@ +export * from './create-room'; +export * from './update-room'; +export * from './open-room'; +export * from './remove-room'; diff --git a/src/features/rooms/open-room/index.ts b/src/features/rooms/open-room/index.ts new file mode 100644 index 00000000..b5e10b89 --- /dev/null +++ b/src/features/rooms/open-room/index.ts @@ -0,0 +1 @@ +export { OpenRoom, type OpenRoomProps } from './open-room'; diff --git a/src/features/rooms/open-room/open-room.tsx b/src/features/rooms/open-room/open-room.tsx new file mode 100644 index 00000000..299a4db7 --- /dev/null +++ b/src/features/rooms/open-room/open-room.tsx @@ -0,0 +1,30 @@ +import { Button } from '@mui/material'; +import { Link } from 'atomic-router-react'; +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { routes } from '@/shared/configs'; +import { CommonProps } from '@/shared/types'; + +export interface OpenRoomProps extends CommonProps { + readonly id: number; +} + +export const OpenRoom: React.FC = (props) => { + const { id, className, } = props; + const { t, } = useTranslation('common'); + + const nameText = t('actions.open'); + + return ( + + ); +}; diff --git a/src/features/rooms/remove-room/index.ts b/src/features/rooms/remove-room/index.ts new file mode 100644 index 00000000..9a0f330a --- /dev/null +++ b/src/features/rooms/remove-room/index.ts @@ -0,0 +1,2 @@ +export * as removeRoomModel from './model'; +export { RemoveRoomMenuItem, type RemoveRoomMenuItemProps } from './menu-item'; diff --git a/src/features/rooms/remove-room/menu-item.tsx b/src/features/rooms/remove-room/menu-item.tsx new file mode 100644 index 00000000..f6badaa9 --- /dev/null +++ b/src/features/rooms/remove-room/menu-item.tsx @@ -0,0 +1,57 @@ +import DeleteIcon from '@mui/icons-material/Delete'; +import { ListItemIcon, MenuItem, MenuItemProps } from '@mui/material'; +import { useUnit } from 'effector-react'; +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { useToggle } from '@/shared/lib'; +import { CommonProps } from '@/shared/types'; +import { Confirm } from '@/shared/ui'; + +import { mutation } from './model'; + +export interface RemoveRoomMenuItemProps extends CommonProps, MenuItemProps { + readonly roomId: number; +} + +export const RemoveRoomMenuItem: React.FC = ( + props +) => { + const { roomId, className, } = props; + const { t, } = useTranslation('rooms'); + const removeRoom = useUnit(mutation); + const [open, handlers] = useToggle(false); + + const onAgree = React.useCallback(() => { + removeRoom.start({ roomId, }); + handlers.toggleOff(); + }, [roomId]); + + const nameText = t('actions.remove_room.name'); + const titleText = t('actions.remove_room.title'); + const contentText = t('actions.remove_room.content'); + const actions = t('actions.remove_room.actions', { + returnObjects: true, + }) as Record; + + return ( + <> + + + + + {nameText} + + + + ); +}; diff --git a/src/features/rooms/remove-room/model.ts b/src/features/rooms/remove-room/model.ts new file mode 100644 index 00000000..6854276d --- /dev/null +++ b/src/features/rooms/remove-room/model.ts @@ -0,0 +1,80 @@ +import { createMutation, update } from '@farfetched/core'; +import { runtypeContract } from '@farfetched/runtypes'; +import { createDomain, sample } from 'effector'; +import { Literal } from 'runtypes'; + +import { roomsModel } from '@/entities/rooms'; + +import { roomsApi } from '@/shared/api'; +import { i18n } from '@/shared/configs'; +import { notificationsModel } from '@/shared/models'; +import { + StandardResponse, + getStandardResponse, + InRoomParams +} from '@/shared/types'; + +const removeRoomDomain = createDomain(); + +const handlerFx = removeRoomDomain.effect< + InRoomParams, + StandardResponse, + Error +>(roomsApi.remove); + +export const mutation = createMutation< + InRoomParams, + StandardResponse, + StandardResponse, + Error +>({ + effect: handlerFx, + contract: runtypeContract(getStandardResponse(Literal(true))), +}); + +update(roomsModel.query, { + on: mutation, + by: { + success: ({ query, mutation, }) => { + if (!query) { + return { + result: [], + }; + } + + if ('error' in query) { + return { + error: query.error, + }; + } + + return { + result: query.result.filter( + (room) => room.id !== mutation.params.roomId + ), + }; + }, + }, +}); + +sample({ + clock: mutation.finished.success, + fn: () => ({ + message: i18n.t('actions.remove_room.notifications.success', { + ns: 'rooms', + }), + color: 'success' as const, + }), + target: notificationsModel.create, +}); + +sample({ + clock: mutation.finished.failure, + fn: () => ({ + message: i18n.t('actions.remove_room.notifications.error', { + ns: 'rooms', + }), + color: 'error' as const, + }), + target: notificationsModel.create, +}); diff --git a/src/features/rooms/update-room/index.ts b/src/features/rooms/update-room/index.ts new file mode 100644 index 00000000..0e1c6a76 --- /dev/null +++ b/src/features/rooms/update-room/index.ts @@ -0,0 +1,6 @@ +export * as updateRoomModel from './model'; +export { UpdateRoom } from './update-room'; +export { + OpenUpdateRoomFormMenuItem, + type OpenUpdateRoomFormMenuItemProps +} from './open-form-menu-item'; diff --git a/src/features/rooms/update-room/model.ts b/src/features/rooms/update-room/model.ts new file mode 100644 index 00000000..773dc1a2 --- /dev/null +++ b/src/features/rooms/update-room/model.ts @@ -0,0 +1,114 @@ +import { createMutation, update } from '@farfetched/core'; +import { runtypeContract } from '@farfetched/runtypes'; +import { createDomain, sample } from 'effector'; +import { and } from 'patronum'; + +import { createPopupControlModel } from '@/entities/popups'; +import { roomModel, roomsModel } from '@/entities/rooms'; + +import { UpdateRoomParams, Room, roomsApi, room } from '@/shared/api'; +import { i18n, popupsMap } from '@/shared/configs'; +import { notificationsModel } from '@/shared/models'; +import { StandardResponse, getStandardResponse } from '@/shared/types'; + +import { roomFormModel } from '../form'; + +const updateRoomDomain = createDomain(); + +const handlerFx = updateRoomDomain.effect< + UpdateRoomParams, + StandardResponse, + Error +>(roomsApi.update); + +export const mutation = createMutation< + UpdateRoomParams, + StandardResponse, + StandardResponse, + Error +>({ + effect: handlerFx, + contract: runtypeContract(getStandardResponse(room)), +}); + +export const form = roomFormModel.create(); + +export const { close, $isOpen, } = createPopupControlModel(popupsMap.updateRoom); + +const { formValidated, reset, setInitialForm, } = form; + +sample({ + clock: close, + target: roomsModel.$id.reinit!, +}); + +sample({ + clock: close, + target: reset, +}); + +sample({ + clock: mutation.finished.success, + target: close, +}); + +sample({ + clock: formValidated, + source: roomsModel.$id, + filter: and($isOpen, roomsModel.$id), + fn: (roomId, values) => { + return { ...values, roomId: Number(roomId), }; + }, + target: mutation.start, +}); + +sample({ + clock: roomModel.query.finished.success, + fn: ({ result, }) => result, + target: setInitialForm, +}); + +update(roomsModel.query, { + on: mutation, + by: { + success: ({ query, mutation, }) => { + if (!query) { + return { + result: [], + }; + } + + if ('error' in query) { + return { + error: query.error, + }; + } + + return { + result: query.result.map((room) => + room.id === mutation.result.data.id ? mutation.result.data : room + ), + }; + }, + }, +}); + +sample({ + clock: mutation.finished.success, + fn: () => ({ + message: i18n.t('actions.update_room.notifications.success', { + ns: 'rooms', + }), + color: 'success' as const, + }), + target: notificationsModel.create, +}); + +sample({ + clock: mutation.finished.failure, + fn: () => ({ + message: i18n.t('actions.update_room.notifications.error', { ns: 'rooms', }), + color: 'error' as const, + }), + target: notificationsModel.create, +}); diff --git a/src/features/rooms/update-room/open-form-menu-item.tsx b/src/features/rooms/update-room/open-form-menu-item.tsx new file mode 100644 index 00000000..ca053f14 --- /dev/null +++ b/src/features/rooms/update-room/open-form-menu-item.tsx @@ -0,0 +1,40 @@ +import EditIcon from '@mui/icons-material/Edit'; +import { ListItemIcon, MenuItem, MenuItemProps } from '@mui/material'; +import { Link } from 'atomic-router-react'; +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { getParams, popupsMap, routes } from '@/shared/configs'; +import { CommonProps } from '@/shared/types'; + +export interface OpenUpdateRoomFormMenuItemProps + extends CommonProps, + MenuItemProps { + readonly roomId: number; +} + +export const OpenUpdateRoomFormMenuItem: React.FC< + OpenUpdateRoomFormMenuItemProps +> = (props) => { + const { className, roomId, ...rest } = props; + const { t, } = useTranslation('rooms'); + const editText = t('actions.update_room.name'); + + return ( + + + + + {editText} + + ); +}; diff --git a/src/features/rooms/update-room/update-room.module.css b/src/features/rooms/update-room/update-room.module.css new file mode 100644 index 00000000..571f85b3 --- /dev/null +++ b/src/features/rooms/update-room/update-room.module.css @@ -0,0 +1,5 @@ +@media (min-width: 640px) { + .form { + min-width: 550px; + } +} diff --git a/src/components/Popups/components/UpdateRoomPopup/UpdateRoomPopup.module.css.d.ts b/src/features/rooms/update-room/update-room.module.css.d.ts similarity index 100% rename from src/components/Popups/components/UpdateRoomPopup/UpdateRoomPopup.module.css.d.ts rename to src/features/rooms/update-room/update-room.module.css.d.ts diff --git a/src/features/rooms/update-room/update-room.tsx b/src/features/rooms/update-room/update-room.tsx new file mode 100644 index 00000000..8d7c46b8 --- /dev/null +++ b/src/features/rooms/update-room/update-room.tsx @@ -0,0 +1,58 @@ +import { Button } from '@mui/material'; +import { useUnit } from 'effector-react'; +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { roomsModel, useRoom } from '@/entities/rooms'; + +import { deviceInfoModel } from '@/shared/models'; +import { BasePopupProps } from '@/shared/types'; +import { FullWidthPopup, MainPopup } from '@/shared/ui'; + +import { SkeletonRoomForm, RoomForm } from '../form'; + +import { close, mutation, form } from './model'; +import styles from './update-room.module.css'; + +export const UpdateRoom: React.FC = (props) => { + const { t, } = useTranslation('rooms'); + const roomId = useUnit(roomsModel.$id); + const { pending: loading, } = useRoom(roomId!); + const onClose = useUnit(close); + const [isMobile, isVertical] = useUnit([ + deviceInfoModel.$isMobile, + deviceInfoModel.$isTabletVertical + ]); + + const onClick = useUnit(form.submit); + const pending = useUnit(mutation.$pending); + + const isFullscreen = isMobile || isVertical; + + const Popup = isFullscreen ? FullWidthPopup : MainPopup; + + const title = t('actions.update_room.title'); + const buttonText = t('actions.save', { ns: 'common', }); + + const actions = isFullscreen ? ( + + ) : null; + + return ( + + {loading ? ( + + ) : ( + + )} + + ); +}; diff --git a/src/features/tags/create/form.module.css b/src/features/tags/create/form.module.css new file mode 100644 index 00000000..571f85b3 --- /dev/null +++ b/src/features/tags/create/form.module.css @@ -0,0 +1,5 @@ +@media (min-width: 640px) { + .form { + min-width: 550px; + } +} diff --git a/src/components/RegistrationForm/RegistrationForm.module.css.d.ts b/src/features/tags/create/form.module.css.d.ts similarity index 100% rename from src/components/RegistrationForm/RegistrationForm.module.css.d.ts rename to src/features/tags/create/form.module.css.d.ts diff --git a/src/features/tags/create/form.tsx b/src/features/tags/create/form.tsx new file mode 100644 index 00000000..0867283a --- /dev/null +++ b/src/features/tags/create/form.tsx @@ -0,0 +1,51 @@ +import { Button } from '@mui/material'; +import { useUnit } from 'effector-react'; +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { deviceInfoModel } from '@/shared/models'; +import { BasePopupProps, CommonProps } from '@/shared/types'; +import { FullWidthPopup, MainPopup } from '@/shared/ui'; + +import { TagForm } from '../form'; + +import styles from './form.module.css'; +import { close, form, mutation } from './model'; + +export interface CreateTagProps extends CommonProps, BasePopupProps {} + +export const CreateTag: React.FC = (props) => { + const { t, } = useTranslation('room-tags'); + const onClose = useUnit(close); + const pending = useUnit(mutation.$pending); + const onClick = useUnit(form.submit); + + const [isMobile, isVertical] = useUnit([ + deviceInfoModel.$isMobile, + deviceInfoModel.$isTabletVertical + ]); + const isFullscreen = isMobile || isVertical; + + const Popup = isFullscreen ? FullWidthPopup : MainPopup; + + const title = t('actions.create_tag.title'); + const buttonText = t('actions.save', { ns: 'common', }); + + const actions = isFullscreen ? ( + + ) : null; + + return ( + + + + ); +}; diff --git a/src/features/tags/create/index.ts b/src/features/tags/create/index.ts new file mode 100644 index 00000000..86053cbf --- /dev/null +++ b/src/features/tags/create/index.ts @@ -0,0 +1,3 @@ +export * as createTagModel from './model'; +export { CreateTag, type CreateTagProps } from './form'; +export { OpenCreateTagForm, type OpenCreateTagFormProps } from './open-button'; diff --git a/src/features/tags/create/model.ts b/src/features/tags/create/model.ts new file mode 100644 index 00000000..cc18b4d4 --- /dev/null +++ b/src/features/tags/create/model.ts @@ -0,0 +1,94 @@ +import { createMutation, update } from '@farfetched/core'; +import { runtypeContract } from '@farfetched/runtypes'; +import { createEffect, sample } from 'effector'; + +import { createPopupControlModel } from '@/entities/popups'; +import { tagsModel } from '@/entities/tags'; + +import { CreateTagParams, tag, Tag, tagsApi } from '@/shared/api'; +import { i18n, popupsMap, routes } from '@/shared/configs'; +import { notificationsModel } from '@/shared/models'; +import { StandardResponse, getStandardResponse } from '@/shared/types'; + +import { tagFormModel } from '../form'; + +export const { close, $isOpen, } = createPopupControlModel(popupsMap.createTag); + +export const form = tagFormModel.create(); + +const { formValidated, reset, } = form; + +const handlerFx = createEffect(tagsApi.create); + +export const mutation = createMutation< + CreateTagParams, + StandardResponse, + StandardResponse, + Error +>({ + effect: handlerFx, + contract: runtypeContract(getStandardResponse(tag)), +}); + +sample({ + clock: mutation.finished.success, + target: close, +}); + +sample({ + clock: close, + target: reset, +}); + +sample({ + clock: formValidated, + source: routes.room.tags.$params, + filter: $isOpen, + fn: (params, values) => ({ ...values, roomId: params.id, }), + target: mutation.start, +}); + +update(tagsModel.query, { + on: mutation, + by: { + success: ({ query, mutation, }) => { + if (!query) { + return { + result: [], + }; + } + + if ('error' in query) { + return { + error: query.error, + }; + } + + return { + result: [...query.result, mutation.result.data], + }; + }, + }, +}); + +sample({ + clock: mutation.finished.success, + fn: () => ({ + message: i18n.t('actions.create_tag.notifications.success', { + ns: 'room-tags', + }), + color: 'success' as const, + }), + target: notificationsModel.create, +}); + +sample({ + clock: mutation.finished.failure, + fn: () => ({ + message: i18n.t('actions.create_tag.notifications.success', { + ns: 'room-tags', + }), + color: 'error' as const, + }), + target: notificationsModel.create, +}); diff --git a/src/features/tags/create/open-button.tsx b/src/features/tags/create/open-button.tsx new file mode 100644 index 00000000..52fd6f9a --- /dev/null +++ b/src/features/tags/create/open-button.tsx @@ -0,0 +1,35 @@ +import AddIcon from '@mui/icons-material/Add'; +import { IconButton, Tooltip } from '@mui/material'; +import { RouteInstance } from 'atomic-router'; +import { Link } from 'atomic-router-react'; +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { routes, getParams, popupsMap } from '@/shared/configs'; +import { useParam } from '@/shared/lib'; +import { CommonProps } from '@/shared/types'; + +export interface OpenCreateTagFormProps extends CommonProps {} + +export const OpenCreateTagForm: React.FC = React.memo( + (props) => { + const { className, } = props; + const roomId = useParam(routes.room.tags, 'id'); + const { t, } = useTranslation('room-tags'); + + const title = t('actions.create_tag.actions.open'); + + return ( + + } + params={{ id: roomId, }} + query={{ [getParams.popup]: popupsMap.createTag, }} + component={Link}> + + + + ); + } +); diff --git a/src/features/tags/form/form.module.css b/src/features/tags/form/form.module.css new file mode 100644 index 00000000..9c7bf8ef --- /dev/null +++ b/src/features/tags/form/form.module.css @@ -0,0 +1,44 @@ +.form { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 15px; + + padding: 10px; +} + +.preview { + grid-column: span 2; +} + +.input { + grid-column: span 2; +} + +.colorInput { + align-self: end; + + height: 50px; +} + +.button { + grid-column: 2; + justify-self: end; +} + +@media (max-width: 500px) { + .form { + grid-template-columns: 1fr; + } + + .preview { + grid-column: 1; + } + + .input { + grid-column: 1; + } + + .button { + grid-column: 1; + } +} diff --git a/src/features/tags/form/form.module.css.d.ts b/src/features/tags/form/form.module.css.d.ts new file mode 100644 index 00000000..a39dbd60 --- /dev/null +++ b/src/features/tags/form/form.module.css.d.ts @@ -0,0 +1,8 @@ +declare const styles: { + readonly button: string; + readonly colorInput: string; + readonly form: string; + readonly input: string; + readonly preview: string; +}; +export = styles; diff --git a/src/features/tags/form/form.tsx b/src/features/tags/form/form.tsx new file mode 100644 index 00000000..d0fcc163 --- /dev/null +++ b/src/features/tags/form/form.tsx @@ -0,0 +1,126 @@ +import { Button } from '@mui/material'; +import cn from 'classnames'; +import { Form } from 'effector-forms'; +import { useUnit } from 'effector-react'; +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { TagLabel } from '@/entities/tags'; + +import { usePreventDefault } from '@/shared/lib'; +import { CommonProps } from '@/shared/types'; +import { Center, Field, Show } from '@/shared/ui'; + +import styles from './form.module.css'; +import { TagFormValues } from './model'; + +export interface TagFormProps extends CommonProps { + readonly $form: Form; + readonly buttonText: string; + readonly buttonDisabled?: boolean; + readonly hideButton?: boolean; +} + +export const TagForm: React.FC = (props) => { + const { className, buttonText, $form, hideButton, buttonDisabled, } = props; + const submit = useUnit($form.submit); + + const onSubmit = usePreventDefault(submit); + + return ( +
+ + + + + + + + + ); +}; + +interface FieldProps { + readonly $form: Form; +} + +const Preview: React.FC = (props) => { + const { $form, } = props; + + const values = useUnit($form.$values); + + return ( +
+ +
+ ); +}; + +const Name: React.FC = (props) => { + const { $form, } = props; + const { t, } = useTranslation('room-tags'); + + const label = t('actions.tag_form.fields.name'); + + const name = useUnit($form.fields.name); + + return ( + + ); +}; + +const MainColor: React.FC = (props) => { + const { $form, } = props; + const { t, } = useTranslation('room-tags'); + const label = t('actions.tag_form.fields.main_color'); + + const mainColor = useUnit($form.fields.mainColor); + + return ( + + ); +}; + +const SecondaryColor: React.FC = (props) => { + const { $form, } = props; + const { t, } = useTranslation('room-tags'); + const label = t('actions.tag_form.fields.second_color'); + + const secondColor = useUnit($form.fields.secondColor); + + return ( + + ); +}; diff --git a/src/features/tags/form/index.ts b/src/features/tags/form/index.ts new file mode 100644 index 00000000..f02dedc1 --- /dev/null +++ b/src/features/tags/form/index.ts @@ -0,0 +1,3 @@ +export * as tagFormModel from './model'; +export { TagForm, type TagFormProps } from './form'; +export { SkeletonTagForm, type SkeletonTagFormProps } from './skeleton'; diff --git a/src/features/tags/form/model.ts b/src/features/tags/form/model.ts new file mode 100644 index 00000000..94539be6 --- /dev/null +++ b/src/features/tags/form/model.ts @@ -0,0 +1,45 @@ +import { createForm } from 'effector-forms'; +import Joi from 'joi'; + +import { Tag } from '@/shared/api'; +import { ALLOWED_SYMBOLS } from '@/shared/configs'; +import { createRuleFromSchema } from '@/shared/lib'; + +export interface TagFormValues extends Omit {} + +const colorPattern = /#[0-9a-fA-F]{6}/; + +const schemas = { + mainColor: Joi.string().pattern(colorPattern).required().messages({ + 'string.empty': "Color can't be empty", + 'string.pattern.base': 'Color must be #XXXXXX, for example #ff00aa', + }), + secondColor: Joi.string().pattern(colorPattern).required().messages({ + 'string.empty': "Color can't be empty", + 'string.pattern.base': 'Color must be #XXXXXX, for example #ff00aa', + }), + name: Joi.string().pattern(ALLOWED_SYMBOLS).required().messages({ + 'string.empty': "Name can't be empty", + 'string.pattern.base': + 'Name can only contain latins alphas, numeric and !, *, (, ), _, +', + }), +}; + +export const create = () => { + return createForm({ + fields: { + name: { + init: 'Name', + rules: [createRuleFromSchema('name', schemas.name)], + }, + mainColor: { + init: '#ffffff', + rules: [createRuleFromSchema('mainColor', schemas.mainColor)], + }, + secondColor: { + init: '#000000', + rules: [createRuleFromSchema('secondColor', schemas.secondColor)], + }, + }, + }); +}; diff --git a/src/components/Popups/components/SkeletonGroupForm/SkeletonGroupForm.module.css b/src/features/tags/form/skeleton.module.css similarity index 100% rename from src/components/Popups/components/SkeletonGroupForm/SkeletonGroupForm.module.css rename to src/features/tags/form/skeleton.module.css diff --git a/src/features/tags/form/skeleton.module.css.d.ts b/src/features/tags/form/skeleton.module.css.d.ts new file mode 100644 index 00000000..cee3c064 --- /dev/null +++ b/src/features/tags/form/skeleton.module.css.d.ts @@ -0,0 +1,7 @@ +declare const styles: { + readonly button: string; + readonly colorInput: string; + readonly input: string; + readonly wrapper: string; +}; +export = styles; diff --git a/src/features/tags/form/skeleton.tsx b/src/features/tags/form/skeleton.tsx new file mode 100644 index 00000000..a2a6dea4 --- /dev/null +++ b/src/features/tags/form/skeleton.tsx @@ -0,0 +1,26 @@ +import { Skeleton } from '@mui/material'; +import cn from 'classnames'; +import * as React from 'react'; + +import { SkeletonTagLabel } from '@/entities/tags'; + +import { CommonProps } from '@/shared/types'; + +import styles from './skeleton.module.css'; + +export interface SkeletonTagFormProps extends CommonProps {} + +export const SkeletonTagForm: React.FC = React.memo( + function SkeletonTagForm(props) { + const { className, } = props; + return ( +
+ + + + + +
+ ); + } +); diff --git a/src/features/tags/index.ts b/src/features/tags/index.ts new file mode 100644 index 00000000..0feb9f7d --- /dev/null +++ b/src/features/tags/index.ts @@ -0,0 +1,3 @@ +export * from './create'; +export * from './update'; +export * from './tag-card-actions'; diff --git a/src/features/tags/tag-card-actions/index.ts b/src/features/tags/tag-card-actions/index.ts new file mode 100644 index 00000000..93047425 --- /dev/null +++ b/src/features/tags/tag-card-actions/index.ts @@ -0,0 +1,2 @@ +export * as removeTagModel from './model'; +export { TagCardActions, type TagCardActionsProps } from './tag-card-actions'; diff --git a/src/features/tags/tag-card-actions/model.ts b/src/features/tags/tag-card-actions/model.ts new file mode 100644 index 00000000..0d67fd1e --- /dev/null +++ b/src/features/tags/tag-card-actions/model.ts @@ -0,0 +1,74 @@ +import { createMutation, update } from '@farfetched/core'; +import { runtypeContract } from '@farfetched/runtypes'; +import { createDomain, sample } from 'effector'; +import { Literal } from 'runtypes'; + +import { tagsModel } from '@/entities/tags'; + +import { RemoveTagParams, tagsApi } from '@/shared/api'; +import { i18n } from '@/shared/configs'; +import { notificationsModel } from '@/shared/models'; +import { StandardResponse, getStandardResponse } from '@/shared/types'; + +const removeTagDomain = createDomain(); + +const handlerFx = removeTagDomain.effect< + RemoveTagParams, + StandardResponse, + Error +>(tagsApi.remove); + +export const mutation = createMutation< + RemoveTagParams, + StandardResponse, + StandardResponse, + Error +>({ + effect: handlerFx, + contract: runtypeContract(getStandardResponse(Literal(true))), +}); + +update(tagsModel.query, { + on: mutation, + by: { + success: ({ query, mutation, }) => { + if (!query) { + return { + result: [], + }; + } + + if ('error' in query) { + return { + error: query.error, + }; + } + + return { + result: query.result.filter((tag) => tag.id !== mutation.params.id), + }; + }, + }, +}); + +sample({ + clock: mutation.finished.success, + fn: () => ({ + message: i18n.t('actions.remove_tag.notifications.success', { + ns: 'room-tags', + }), + color: 'success' as const, + }), + target: notificationsModel.create, +}); + +sample({ + clock: mutation.finished.failure, + fn: () => ({ + message: i18n.t('actions.remove_tag.notifications.error', { + ns: 'room-tags', + }), + color: 'error' as const, + }), + target: notificationsModel.create, +}); diff --git a/src/features/tags/tag-card-actions/tag-card-actions.tsx b/src/features/tags/tag-card-actions/tag-card-actions.tsx new file mode 100644 index 00000000..70f2b705 --- /dev/null +++ b/src/features/tags/tag-card-actions/tag-card-actions.tsx @@ -0,0 +1,71 @@ +import DeleteIcon from '@mui/icons-material/Delete'; +import EditIcon from '@mui/icons-material/Edit'; +import { IconButton, Tooltip } from '@mui/material'; +import { Link } from 'atomic-router-react'; +import { useUnit } from 'effector-react'; +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { routes, getParams, popupsMap } from '@/shared/configs'; +import { useParam, useToggle } from '@/shared/lib'; +import { CommonProps } from '@/shared/types'; +import { Confirm } from '@/shared/ui'; + +import { mutation } from './model'; + +export interface TagCardActionsProps extends CommonProps { + readonly tagId: number; +} + +export const TagCardActions: React.FC = (props) => { + const { tagId, className, } = props; + const { t, } = useTranslation('room-tags'); + const roomId = useParam(routes.room.tags, 'id'); + const removeTag = useUnit(mutation); + const [toggled, { toggleOff, toggleOn, }] = useToggle(false); + + const onAgree = React.useCallback(() => { + removeTag.start({ id: tagId, roomId, }); + toggleOff(); + }, [toggleOff, tagId, roomId]); + + const updateTitle = t('actions.update_tag.actions.open'); + + const removeTitle = t('actions.remove_tag.title'); + const removeText = t('actions.remove_tag.text'); + const removeAgree = t('actions.remove_tag.actions.agree'); + const removeDisagree = t('actions.remove_tag.actions.disagree'); + const openRemove = t('actions.remove_tag.actions.open'); + + return ( +
+ + + + + + + + + + + +
+ ); +}; diff --git a/src/features/tags/update/index.ts b/src/features/tags/update/index.ts new file mode 100644 index 00000000..6fa41e17 --- /dev/null +++ b/src/features/tags/update/index.ts @@ -0,0 +1,2 @@ +export * as updateTagModel from './model'; +export { UpdateTag, type UpdateTagProps } from './ui'; diff --git a/src/features/tags/update/model.ts b/src/features/tags/update/model.ts new file mode 100644 index 00000000..ab225958 --- /dev/null +++ b/src/features/tags/update/model.ts @@ -0,0 +1,121 @@ +import { createMutation, update } from '@farfetched/core'; +import { runtypeContract } from '@farfetched/runtypes'; +import { createEffect, sample } from 'effector'; +import { and } from 'patronum'; + +import { createPopupControlModel } from '@/entities/popups'; +import { tagsModel, tagModel } from '@/entities/tags'; + +import { UpdateTagParams, Tag, tagsApi, tag } from '@/shared/api'; +import { i18n, popupsMap, routes } from '@/shared/configs'; +import { notificationsModel } from '@/shared/models'; +import { StandardResponse, getStandardResponse } from '@/shared/types'; + +import { tagFormModel } from '../form'; + +const handlerFx = createEffect(tagsApi.update); + +export const mutation = createMutation< + UpdateTagParams, + StandardResponse, + StandardResponse, + Error +>({ + effect: handlerFx, + contract: runtypeContract(getStandardResponse(tag)), +}); + +export const { close, $isOpen, } = createPopupControlModel(popupsMap.updateTag); +export const form = tagFormModel.create(); + +const { fields, setForm, reset, formValidated, } = form; + +sample({ + clock: close, + target: tagsModel.$id.reinit!, +}); + +sample({ + clock: close, + target: reset, +}); + +sample({ + clock: mutation.finished.success, + target: close, +}); + +sample({ + clock: formValidated, + source: { params: routes.room.tags.$params, id: tagsModel.$id, }, + filter: and($isOpen, tagsModel.$id), + fn: ({ params, id, }, values) => ({ + ...values, + id: Number(id), + roomId: params.id, + }), + target: mutation.start, +}); + +sample({ + clock: tagModel.query.finished.success, + fn: ({ result, }) => result, + target: setForm, +}); + +sample({ + clock: tagModel.query.finished.success, + fn: () => false, + target: [ + fields.name.$isDirty, + fields.mainColor.$isDirty, + fields.secondColor.$isDirty + ], +}); + +update(tagsModel.query, { + on: mutation, + by: { + success: ({ query, mutation, }) => { + if (!query) { + return { + result: [], + }; + } + + if ('error' in query) { + return { + error: query.error, + }; + } + + return { + result: query.result.map((tag) => + tag.id === mutation.result.data.id ? mutation.result.data : tag + ), + }; + }, + }, +}); + +sample({ + clock: mutation.finished.success, + fn: () => ({ + message: i18n.t('actions.update_tag.notifications.success', { + ns: 'room-tags', + }), + color: 'success' as const, + }), + target: notificationsModel.create, +}); + +sample({ + clock: mutation.finished.failure, + fn: () => ({ + message: i18n.t('actions.update_tag.notifications.error', { + ns: 'room-tags', + }), + color: 'error' as const, + }), + target: notificationsModel.create, +}); diff --git a/src/features/tags/update/ui.module.css b/src/features/tags/update/ui.module.css new file mode 100644 index 00000000..571f85b3 --- /dev/null +++ b/src/features/tags/update/ui.module.css @@ -0,0 +1,5 @@ +@media (min-width: 640px) { + .form { + min-width: 550px; + } +} diff --git a/src/features/tags/update/ui.module.css.d.ts b/src/features/tags/update/ui.module.css.d.ts new file mode 100644 index 00000000..824addc2 --- /dev/null +++ b/src/features/tags/update/ui.module.css.d.ts @@ -0,0 +1,4 @@ +declare const styles: { + readonly form: string; +}; +export = styles; diff --git a/src/features/tags/update/ui.tsx b/src/features/tags/update/ui.tsx new file mode 100644 index 00000000..9dc7b198 --- /dev/null +++ b/src/features/tags/update/ui.tsx @@ -0,0 +1,65 @@ +import { Button } from '@mui/material'; +import { useUnit } from 'effector-react'; +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { tagsModel, useTag } from '@/entities/tags'; + +import { routes } from '@/shared/configs'; +import { useParam } from '@/shared/lib'; +import { deviceInfoModel } from '@/shared/models'; +import { BasePopupProps, CommonProps } from '@/shared/types'; +import { FullWidthPopup, MainPopup } from '@/shared/ui'; + +import { SkeletonTagForm, TagForm } from '../form'; + +import { close, form, mutation } from './model'; +import styles from './ui.module.css'; + +export interface UpdateTagProps extends CommonProps, BasePopupProps {} + +export const UpdateTag: React.FC> = ( + props +) => { + const { t, } = useTranslation('room-tags'); + const roomId = useParam(routes.room.tags, 'id'); + const id = useUnit(tagsModel.$id); + const onClose = useUnit(close); + const pending = useUnit(mutation.$pending); + const onClick = useUnit(form.submit); + const tag = useTag(Number(id), roomId); + const isLoading = !tag.data; + + const [isMobile, isVertical] = useUnit([ + deviceInfoModel.$isMobile, + deviceInfoModel.$isTabletVertical + ]); + const isFullscreen = isMobile || isVertical; + + const Popup = isFullscreen ? FullWidthPopup : MainPopup; + + const title = t('actions.update_tag.title'); + const buttonText = t('actions.save', { ns: 'common', }); + + const actions = isFullscreen ? ( + + ) : null; + + return ( + + {isLoading ? ( + + ) : ( + + )} + + ); +}; diff --git a/src/features/tasks/create-task/create-task.module.css b/src/features/tasks/create-task/create-task.module.css new file mode 100644 index 00000000..571f85b3 --- /dev/null +++ b/src/features/tasks/create-task/create-task.module.css @@ -0,0 +1,5 @@ +@media (min-width: 640px) { + .form { + min-width: 550px; + } +} diff --git a/src/features/tasks/create-task/create-task.module.css.d.ts b/src/features/tasks/create-task/create-task.module.css.d.ts new file mode 100644 index 00000000..824addc2 --- /dev/null +++ b/src/features/tasks/create-task/create-task.module.css.d.ts @@ -0,0 +1,4 @@ +declare const styles: { + readonly form: string; +}; +export = styles; diff --git a/src/features/tasks/create-task/create-task.tsx b/src/features/tasks/create-task/create-task.tsx new file mode 100644 index 00000000..f4a223b8 --- /dev/null +++ b/src/features/tasks/create-task/create-task.tsx @@ -0,0 +1,52 @@ +import { Button } from '@mui/material'; +import { useUnit } from 'effector-react'; +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { deviceInfoModel } from '@/shared/models'; +import { BasePopupProps, CommonProps } from '@/shared/types'; +import { FullWidthPopup, MainPopup } from '@/shared/ui'; + +import { TaskForm } from '../form'; + +import styles from './create-task.module.css'; +import { close, form, mutation } from './model'; + +export interface CreateTaskProps extends CommonProps, BasePopupProps {} + +export const CreateTask: React.FC = (props) => { + const { t, } = useTranslation('tasks'); + const onClose = useUnit(close); + const [isMobile, isVertical] = useUnit([ + deviceInfoModel.$isMobile, + deviceInfoModel.$isTabletVertical + ]); + + const onClick = useUnit(form.submit); + const pending = useUnit(mutation.$pending); + + const isFullscreen = isMobile || isVertical; + + const Popup = isFullscreen ? FullWidthPopup : MainPopup; + + const title = t('actions.create_task.title'); + const buttonText = t('actions.create', { ns: 'common', }); + + const actions = isFullscreen ? ( + + ) : null; + + return ( + + + + ); +}; diff --git a/src/features/tasks/create-task/index.ts b/src/features/tasks/create-task/index.ts new file mode 100644 index 00000000..01aafd35 --- /dev/null +++ b/src/features/tasks/create-task/index.ts @@ -0,0 +1,6 @@ +export * as createTaskModel from './model'; +export { CreateTask, type CreateTaskProps } from './create-task'; +export { + OpenCreateTaskButton, + type OpenCreateTaskButtonProps +} from './open-button'; diff --git a/src/features/tasks/create-task/model.ts b/src/features/tasks/create-task/model.ts new file mode 100644 index 00000000..12dc1f1a --- /dev/null +++ b/src/features/tasks/create-task/model.ts @@ -0,0 +1,112 @@ +import { createMutation, update } from '@farfetched/core'; +import { runtypeContract } from '@farfetched/runtypes'; +import { createDomain, sample } from 'effector'; + +import { createPopupControlModel } from '@/entities/popups'; +import { tasksInRoomModel } from '@/entities/tasks'; + +import { CreateTaskParams, Task, tasksApi, task } from '@/shared/api'; +import { i18n, popupsMap, routes } from '@/shared/configs'; +import { notificationsModel } from '@/shared/models'; +import { StandardResponse, getStandardResponse } from '@/shared/types'; + +import { taskFormModel } from '../form'; + +const createTaskDomain = createDomain(); + +const handlerFx = createTaskDomain.effect< + CreateTaskParams, + StandardResponse, + Error +>(tasksApi.create); + +export const mutation = createMutation< + CreateTaskParams, + StandardResponse, + StandardResponse, + Error +>({ + effect: handlerFx, + contract: runtypeContract(getStandardResponse(task)), +}); + +export const form = taskFormModel.create(); + +export const { close, $isOpen, opened, } = createPopupControlModel( + popupsMap.createTask +); + +const { reset, formValidated, } = form; + +sample({ + clock: close, + target: tasksInRoomModel.$status.reinit!, +}); + +sample({ + clock: close, + target: reset, +}); + +sample({ + clock: mutation.finished.success, + target: close, +}); + +sample({ + clock: formValidated, + source: routes.room.tasks.$params, + fn: ({ id, }, values) => ({ roomId: id, ...values, }), + target: mutation.start, +}); + +sample({ + clock: opened, + source: tasksInRoomModel.$status, + filter: Boolean, + fn: (status) => ({ status, }), + target: form.setInitialForm, +}); + +update(tasksInRoomModel.query, { + on: mutation, + by: { + success: ({ query, mutation, }) => { + if (!query) { + return { + result: [], + }; + } + + if ('error' in query) { + return { + error: query.error, + }; + } + + return { + result: [...query.result, mutation.result.data], + }; + }, + }, +}); + +sample({ + clock: mutation.finished.success, + fn: () => ({ + message: i18n.t('actions.create_task.notifications.success', { + ns: 'tasks', + }), + color: 'success' as const, + }), + target: notificationsModel.create, +}); + +sample({ + clock: mutation.finished.failure, + fn: () => ({ + message: i18n.t('actions.create_task.notifications.error', { ns: 'tasks', }), + color: 'error' as const, + }), + target: notificationsModel.create, +}); diff --git a/src/features/tasks/create-task/open-button.tsx b/src/features/tasks/create-task/open-button.tsx new file mode 100644 index 00000000..74cf165b --- /dev/null +++ b/src/features/tasks/create-task/open-button.tsx @@ -0,0 +1,37 @@ +import AddIcon from '@mui/icons-material/Add'; +import { IconButton, Tooltip } from '@mui/material'; +import { Link } from 'atomic-router-react'; +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { TaskStatus } from '@/shared/api'; +import { routes, getParams, popupsMap } from '@/shared/configs'; +import { CommonProps } from '@/shared/types'; + +export interface OpenCreateTaskButtonProps extends CommonProps { + readonly roomId: number; + readonly columnStatus?: TaskStatus; +} + +export const OpenCreateTaskButton: React.FC = + React.memo((props) => { + const { className, columnStatus, roomId, } = props; + const { t, } = useTranslation('tasks'); + const label = t('actions.create_task.actions.open'); + + return ( + + + + + + ); + }); diff --git a/src/features/tasks/form/form.module.css b/src/features/tasks/form/form.module.css new file mode 100644 index 00000000..e548ca63 --- /dev/null +++ b/src/features/tasks/form/form.module.css @@ -0,0 +1,24 @@ +.form { + display: grid; + gap: 1em; + + padding: 0.5em; +} + +.button { + justify-self: end; +} + +@media (max-width: 500px) { + .form { + grid-template-columns: 1fr; + } + + .field { + grid-column: 1; + } + + .button { + grid-column: 1; + } +} diff --git a/src/features/tasks/form/form.module.css.d.ts b/src/features/tasks/form/form.module.css.d.ts new file mode 100644 index 00000000..43f6a0ec --- /dev/null +++ b/src/features/tasks/form/form.module.css.d.ts @@ -0,0 +1,6 @@ +declare const styles: { + readonly button: string; + readonly field: string; + readonly form: string; +}; +export = styles; diff --git a/src/features/tasks/form/form.tsx b/src/features/tasks/form/form.tsx new file mode 100644 index 00000000..b3a3be4d --- /dev/null +++ b/src/features/tasks/form/form.tsx @@ -0,0 +1,140 @@ +import { Button } from '@mui/material'; +import cn from 'classnames'; +import { Form } from 'effector-forms'; +import { useUnit } from 'effector-react'; +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { TagPicker } from '@/entities/tags'; +import { StatusSelect } from '@/entities/tasks'; + +import { usePreventDefault } from '@/shared/lib'; +import { CommonProps } from '@/shared/types'; +import { Field } from '@/shared/ui'; + +import styles from './form.module.css'; +import { TaskFormValues } from './lib'; + +export interface TaskFormProps extends CommonProps { + readonly buttonText: string; + readonly $form: Form; + readonly buttonDisabled?: boolean; + readonly hideButton?: boolean; +} + +export const TaskForm: React.FC = React.memo((props) => { + const { buttonText, className, $form, hideButton, buttonDisabled, } = props; + const submit = useUnit($form.submit); + + const onSubmit = usePreventDefault(submit); + + return ( +
+ + <Tags $form={$form} /> + <Status $form={$form} /> + <Description $form={$form} /> + {hideButton ? null : ( + <Button + className={styles.button} + type='submit' + disabled={buttonDisabled}> + {buttonText} + </Button> + )} + </form> + ); +}); + +interface FieldProps { + readonly $form: Form<TaskFormValues>; +} + +const Title: React.FC<FieldProps> = (props) => { + const { $form, } = props; + const { t, } = useTranslation('tasks'); + const label = t('actions.task_form.fields.title'); + + const title = useUnit($form.fields.title); + + return ( + <Field + className={styles.field} + value={title.value} + onChange={title.onChange} + onBlur={title.onBlur} + helperText={title.errorText} + isValid={title.isValid} + name='title' + label={label} + /> + ); +}; + +const Tags: React.FC<FieldProps> = (props) => { + const { $form, } = props; + + const { t, } = useTranslation('tasks'); + const label = t('actions.task_form.fields.tags'); + + const tagIds = useUnit($form.fields.tagIds); + + return ( + <TagPicker + value={tagIds.value} + onChange={tagIds.onChange} + onBlur={tagIds.onBlur} + helperText={tagIds.errorText} + isValid={tagIds.isValid} + name='tagIds' + label={label} + limitTags={1} + multiple + /> + ); +}; + +const Status: React.FC<FieldProps> = (props) => { + const { $form, } = props; + + const { t, } = useTranslation('tasks'); + const label = t('actions.task_form.fields.status'); + + const status = useUnit($form.fields.status); + + return ( + <StatusSelect + value={status.value} + onChange={status.onChange} + onBlur={status.onBlur} + helperText={status.errorText} + isValid={status.isValid} + name='status' + label={label} + /> + ); +}; + +const Description: React.FC<FieldProps> = (props) => { + const { $form, } = props; + + const { t, } = useTranslation('tasks'); + const label = t('actions.task_form.fields.description'); + + const description = useUnit($form.fields.description); + + return ( + <Field + className={styles.field} + value={description.value} + onChange={description.onChange} + onBlur={description.onBlur} + helperText={description.errorText} + isValid={description.isValid} + name='description' + label={label} + minRows={5} + multiline + /> + ); +}; diff --git a/src/features/tasks/form/index.ts b/src/features/tasks/form/index.ts new file mode 100644 index 00000000..328d3380 --- /dev/null +++ b/src/features/tasks/form/index.ts @@ -0,0 +1,3 @@ +export * as taskFormModel from './lib'; +export { SkeletonTaskForm, type SkeletonTaskFormProps } from './skeleton'; +export { TaskForm, type TaskFormProps } from './form'; diff --git a/src/features/tasks/form/lib.ts b/src/features/tasks/form/lib.ts new file mode 100644 index 00000000..06db2a9f --- /dev/null +++ b/src/features/tasks/form/lib.ts @@ -0,0 +1,48 @@ +import { createForm } from 'effector-forms'; +import Joi from 'joi'; + +import { Task } from '@/shared/api'; +import { ALLOWED_SYMBOLS } from '@/shared/configs'; +import { createRuleFromSchema } from '@/shared/lib'; + +export interface TaskFormValues + extends Pick<Task, 'title' | 'description' | 'status'> { + readonly tagIds: number[]; +} + +const schemas = { + tagIds: Joi.array().items(Joi.number()).required().messages({ + 'number.empty': 'Tag must be choose', + 'number.positive': 'Tag must be choose', + }), + status: Joi.string().required(), + title: Joi.string().pattern(ALLOWED_SYMBOLS).max(128).required().messages({ + 'string.empty': "Content can't be empty", + 'string.max': 'Content can be less than 128', + 'string.pattern.base': + 'Content can only contain latins alphas, numeric and !, *, (, ), _, +', + }), +}; + +export const create = () => { + return createForm<TaskFormValues>({ + fields: { + title: { + init: '', + rules: [createRuleFromSchema('title', schemas.title)], + }, + description: { + init: '', + rules: [createRuleFromSchema('description', schemas.title)], + }, + tagIds: { + init: [], + rules: [createRuleFromSchema('tagIds', schemas.tagIds)], + }, + status: { + init: 'ready', + rules: [createRuleFromSchema('status', schemas.status)], + }, + }, + }); +}; diff --git a/src/features/tasks/form/skeleton.module.css b/src/features/tasks/form/skeleton.module.css new file mode 100644 index 00000000..86f43d6a --- /dev/null +++ b/src/features/tasks/form/skeleton.module.css @@ -0,0 +1,38 @@ +.form { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 1em; + + width: 100%; +} + +.select { + width: 100%; + height: 4em; +} + +.field { + grid-column: span 2; + height: 6em; +} + +.button { + grid-column: 2; + justify-self: end; + width: 7em; + height: 3em; +} + +@media (max-width: 500px) { + .form { + grid-template-columns: 1fr; + } + + .field { + grid-column: 1; + } + + .button { + grid-column: 1; + } +} diff --git a/src/features/tasks/form/skeleton.module.css.d.ts b/src/features/tasks/form/skeleton.module.css.d.ts new file mode 100644 index 00000000..467ee8c3 --- /dev/null +++ b/src/features/tasks/form/skeleton.module.css.d.ts @@ -0,0 +1,7 @@ +declare const styles: { + readonly button: string; + readonly field: string; + readonly form: string; + readonly select: string; +}; +export = styles; diff --git a/src/features/tasks/form/skeleton.tsx b/src/features/tasks/form/skeleton.tsx new file mode 100644 index 00000000..dd48afef --- /dev/null +++ b/src/features/tasks/form/skeleton.tsx @@ -0,0 +1,23 @@ +import { Skeleton } from '@mui/material'; +import cn from 'classnames'; +import * as React from 'react'; + +import { CommonProps } from '@/shared/types'; + +import styles from './skeleton.module.css'; + +export interface SkeletonTaskFormProps extends CommonProps {} + +export const SkeletonTaskForm: React.FC<SkeletonTaskFormProps> = React.memo( + function SkeletonTaskForm(props) { + const { className, } = props; + return ( + <div className={cn(styles.form, className)}> + <Skeleton className={styles.select} /> + <Skeleton className={styles.select} /> + <Skeleton className={styles.field} /> + <Skeleton className={styles.button} /> + </div> + ); + } +); diff --git a/src/features/tasks/index.ts b/src/features/tasks/index.ts new file mode 100644 index 00000000..4c1dbb68 --- /dev/null +++ b/src/features/tasks/index.ts @@ -0,0 +1,4 @@ +export * from './create-task'; +export * from './update-task'; +export * from './tasks-filter'; +export * from './remove-task'; diff --git a/src/features/tasks/remove-task/index.ts b/src/features/tasks/remove-task/index.ts new file mode 100644 index 00000000..a9e4f780 --- /dev/null +++ b/src/features/tasks/remove-task/index.ts @@ -0,0 +1,2 @@ +export * as removeTaskModel from './model'; +export { RemoveTaskMenuItem, type RemoveTaskMenuItemProps } from './menu-item'; diff --git a/src/features/tasks/remove-task/menu-item.tsx b/src/features/tasks/remove-task/menu-item.tsx new file mode 100644 index 00000000..22a49db9 --- /dev/null +++ b/src/features/tasks/remove-task/menu-item.tsx @@ -0,0 +1,57 @@ +import DeleteIcon from '@mui/icons-material/Delete'; +import { ListItemIcon, MenuItem } from '@mui/material'; +import { useUnit } from 'effector-react'; +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { useToggle } from '@/shared/lib'; +import { CommonProps } from '@/shared/types'; +import { Confirm } from '@/shared/ui'; + +import { mutation } from './model'; + +export interface RemoveTaskMenuItemProps extends CommonProps { + readonly roomId: number; + readonly taskId: number; +} + +export const RemoveTaskMenuItem: React.FC<RemoveTaskMenuItemProps> = React.memo( + (props) => { + const { className, taskId, roomId, } = props; + const { t, } = useTranslation('tasks'); + const removeTask = useUnit(mutation); + const [toggled, { toggleOff, toggleOn, }] = useToggle(false); + + const onAgree = React.useCallback(() => { + removeTask.start({ id: taskId, roomId, }); + toggleOff(); + }, [toggleOff, taskId, roomId]); + + const label = t('actions.remove_task.name'); + const title = t('actions.remove_task.title'); + const content = t('actions.remove_task.content'); + const actions = t('actions.remove_task.actions', { + returnObjects: true, + }) as Record<string, string>; + + return ( + <MenuItem className={className} onClick={toggleOn}> + <ListItemIcon> + <DeleteIcon /> + </ListItemIcon> + {label} + + <Confirm + isOpen={toggled} + onClose={toggleOff} + title={title} + content={content} + agreeText={actions.agree} + onAgree={onAgree} + disagreeText={actions.disagree} + onDisagree={toggleOff} + /> + </MenuItem> + ); + } +); diff --git a/src/features/tasks/remove-task/model.ts b/src/features/tasks/remove-task/model.ts new file mode 100644 index 00000000..97758293 --- /dev/null +++ b/src/features/tasks/remove-task/model.ts @@ -0,0 +1,72 @@ +import { createMutation, update } from '@farfetched/core'; +import { runtypeContract } from '@farfetched/runtypes'; +import { createDomain, sample } from 'effector'; +import { Literal } from 'runtypes'; + +import { tasksInRoomModel } from '@/entities/tasks'; + +import { RemoveTaskParams, tasksApi } from '@/shared/api'; +import { i18n } from '@/shared/configs'; +import { notificationsModel } from '@/shared/models'; +import { StandardResponse, getStandardResponse } from '@/shared/types'; + +const removeTaskDomain = createDomain(); + +const handlerFx = removeTaskDomain.effect< + RemoveTaskParams, + StandardResponse<boolean>, + Error +>(tasksApi.remove); + +export const mutation = createMutation< + RemoveTaskParams, + StandardResponse<boolean>, + StandardResponse<boolean>, + Error +>({ + effect: handlerFx, + contract: runtypeContract(getStandardResponse(Literal(true))), +}); + +update(tasksInRoomModel.query, { + on: mutation, + by: { + success: ({ query, mutation, }) => { + if (!query) { + return { + result: [], + }; + } + + if ('error' in query) { + return { + error: query.error, + }; + } + + return { + result: query.result.filter((task) => task.id !== mutation.params.id), + }; + }, + }, +}); + +sample({ + clock: mutation.finished.success, + fn: () => ({ + message: i18n.t('actions.remove_task.notifications.success', { + ns: 'tasks', + }), + color: 'success' as const, + }), + target: notificationsModel.create, +}); + +sample({ + clock: mutation.finished.failure, + fn: () => ({ + message: i18n.t('actions.remove_task.notifications.error', { ns: 'tasks', }), + color: 'error' as const, + }), + target: notificationsModel.create, +}); diff --git a/src/features/tasks/tasks-filter/index.ts b/src/features/tasks/tasks-filter/index.ts new file mode 100644 index 00000000..7cc372fb --- /dev/null +++ b/src/features/tasks/tasks-filter/index.ts @@ -0,0 +1,2 @@ +export * as tasksFiltersModel from './model'; +export { TasksFilters, type TasksFiltersProps } from './tasks-filters'; diff --git a/src/features/tasks/tasks-filter/model.ts b/src/features/tasks/tasks-filter/model.ts new file mode 100644 index 00000000..6f73e8a9 --- /dev/null +++ b/src/features/tasks/tasks-filter/model.ts @@ -0,0 +1,26 @@ +import { createDomain } from 'effector'; +import { createForm } from 'effector-forms'; + +import { GetTasksParams } from '@/shared/api'; + +const tasksFilters = createDomain(); + +interface TasksFiltersValues extends Required<Omit<GetTasksParams, 'roomId'>> {} + +export const form = createForm<TasksFiltersValues>({ + fields: { + after: { + init: null, + }, + authorIds: { + init: [], + }, + before: { + init: null, + }, + tagIds: { + init: [], + }, + }, + domain: tasksFilters, +}); diff --git a/src/features/tasks/tasks-filter/tasks-filters.module.css b/src/features/tasks/tasks-filter/tasks-filters.module.css new file mode 100644 index 00000000..95ef1842 --- /dev/null +++ b/src/features/tasks/tasks-filter/tasks-filters.module.css @@ -0,0 +1,13 @@ +.wrapper { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 1em; + + padding: 2em; +} + +@media (max-width: 600px) { + .wrapper { + grid-template-columns: 1fr; + } +} diff --git a/src/components/Tasks/Tasks.module.css.d.ts b/src/features/tasks/tasks-filter/tasks-filters.module.css.d.ts similarity index 100% rename from src/components/Tasks/Tasks.module.css.d.ts rename to src/features/tasks/tasks-filter/tasks-filters.module.css.d.ts diff --git a/src/features/tasks/tasks-filter/tasks-filters.tsx b/src/features/tasks/tasks-filter/tasks-filters.tsx new file mode 100644 index 00000000..e7f77029 --- /dev/null +++ b/src/features/tasks/tasks-filter/tasks-filters.tsx @@ -0,0 +1,162 @@ +import TuneIcon from '@mui/icons-material/Tune'; +import { Button } from '@mui/material'; +import cn from 'classnames'; +import { useUnit } from 'effector-react'; +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { TagPicker } from '@/entities/tags'; +import { UsersInRoomPicker } from '@/entities/users'; + +import { usePreventDefault, useToggle } from '@/shared/lib'; +import { CommonProps } from '@/shared/types'; +import { DatePicker, FiltersPopover, Show } from '@/shared/ui'; + +import { form } from './model'; +import styles from './tasks-filters.module.css'; + +export interface TasksFiltersProps extends CommonProps {} + +export const TasksFilters: React.FC<TasksFiltersProps> = (props) => { + const { className, } = props; + const { t, } = useTranslation('tasks'); + + const [open, { toggleOn, toggleOff, }] = useToggle(); + const reset = useUnit(form.reset); + const submit = useUnit(form.submit); + + const onSubmit = usePreventDefault(() => { + submit(); + toggleOff(); + }); + + const onReset = () => { + reset(); + toggleOff(); + }; + + const buttonsText = t('actions.tasks_filters.actions', { + returnObjects: true, + }) as Record<string, string>; + const title = t('actions.tasks_filters.title'); + + const buttons = ( + <> + <Button onClick={onReset} type='reset' variant='text' color='primary'> + {buttonsText.reset} + </Button> + <Button + onClick={onSubmit} + type='submit' + variant='contained' + color='primary'> + {buttonsText.submit} + </Button> + </> + ); + + return ( + <FiltersPopover + title={title} + open={open} + onClose={toggleOff} + onOpen={toggleOn} + icon={<TuneIcon />} + slots={{ actions: buttons, }}> + {({ isPopup, }) => ( + <form className={cn(styles.wrapper, className)} onSubmit={onSubmit}> + <Tags /> + <Users /> + <After /> + <Before /> + <Show show={!isPopup}>{buttons}</Show> + </form> + )} + </FiltersPopover> + ); +}; + +const Tags: React.FC = () => { + const { t, } = useTranslation('tasks'); + + const tagIds = useUnit(form.fields.tagIds); + const label = t('actions.tasks_filters.fields.tags'); + + return ( + <TagPicker + value={tagIds.value} + onChange={tagIds.onChange} + onBlur={tagIds.onBlur} + helperText={tagIds.errorText} + isValid={tagIds.isValid} + name='tagIds' + label={label} + size='medium' + limitTags={1} + multiple + /> + ); +}; + +const Users: React.FC = () => { + const { t, } = useTranslation('tasks'); + + const authorIds = useUnit(form.fields.authorIds); + + const label = t('actions.tasks_filters.fields.authors'); + + return ( + <UsersInRoomPicker + value={authorIds.value} + onChange={authorIds.onChange} + onBlur={authorIds.onBlur} + helperText={authorIds.errorText} + isValid={authorIds.isValid} + name='authorIds' + label={label} + size='medium' + limitTags={1} + multiple + /> + ); +}; + +const After: React.FC = () => { + const { t, } = useTranslation('common'); + + const after = useUnit(form.fields.after); + + const label = t('fields.create_after'); + + return ( + <DatePicker + value={after.value} + onChange={after.onChange} + onBlur={after.onBlur} + label={label} + helperText={after.errorText} + isValid={after.isValid} + name='after' + /> + ); +}; + +const Before: React.FC = () => { + const { t, } = useTranslation('common'); + + const before = useUnit(form.fields.before); + + const label = t('fields.create_before'); + + return ( + <DatePicker + value={before.value} + onChange={before.onChange} + onBlur={before.onBlur} + label={label} + helperText={before.errorText} + isValid={before.isValid} + name='before' + /> + ); +}; diff --git a/src/features/tasks/update-task/index.ts b/src/features/tasks/update-task/index.ts new file mode 100644 index 00000000..291e14a8 --- /dev/null +++ b/src/features/tasks/update-task/index.ts @@ -0,0 +1,6 @@ +export * as updateTaskModel from './model'; +export { UpdateTask, type UpdateTaskProps } from './update-task'; +export { + OpenUpdateTaskFormMenuItem, + type OpenUpdateTaskFormMenuItemProps +} from './open-menu-item'; diff --git a/src/features/tasks/update-task/model.ts b/src/features/tasks/update-task/model.ts new file mode 100644 index 00000000..7e54addd --- /dev/null +++ b/src/features/tasks/update-task/model.ts @@ -0,0 +1,126 @@ +import { createMutation, update } from '@farfetched/core'; +import { runtypeContract } from '@farfetched/runtypes'; +import { combine, createDomain, sample } from 'effector'; +import { empty, not } from 'patronum'; + +import { createPopupControlModel } from '@/entities/popups'; +import { taskModel, tasksInRoomModel } from '@/entities/tasks'; + +import { UpdateTaskParams, Task, tasksApi, task } from '@/shared/api'; +import { i18n, popupsMap, routes } from '@/shared/configs'; +import { notificationsModel } from '@/shared/models'; +import { StandardResponse, getStandardResponse } from '@/shared/types'; + +import { taskFormModel } from '../form'; + +const updateTaskDomain = createDomain(); + +const handlerFx = updateTaskDomain.effect(tasksApi.update); + +export const mutation = createMutation< + UpdateTaskParams, + StandardResponse<Task>, + StandardResponse<Task>, + Error +>({ + effect: handlerFx, + contract: runtypeContract(getStandardResponse(task)), +}); + +export const { close, $isOpen, opened, } = createPopupControlModel( + popupsMap.updateTask +); + +const $routeParams = combine( + tasksInRoomModel.$id, + routes.room.tasks.$params, + (id, params) => ({ id: Number(id), roomId: params.id, }) +); + +export const form = taskFormModel.create(); + +const { formValidated, setInitialForm, reset, } = form; + +sample({ + clock: close, + target: [tasksInRoomModel.$id.reinit!, reset], +}); + +sample({ + clock: mutation.finished.success, + target: close, +}); + +sample({ + clock: opened, + source: $routeParams, + target: taskModel.query.start, +}); + +sample({ + clock: formValidated, + source: $routeParams, + filter: not(empty(tasksInRoomModel.$id)), + fn: (routeParams, values) => { + return { ...values, ...routeParams, }; + }, + target: mutation.start, +}); + +sample({ + clock: taskModel.query.finished.success, + fn: ({ result, }) => { + const { tags, ...rest } = result; + + return { + ...rest, + tagIds: tags.map((tag) => tag.id), + }; + }, + target: setInitialForm, +}); + +update(tasksInRoomModel.query, { + on: mutation, + by: { + success: ({ query, mutation, }) => { + if (!query) { + return { + result: [], + }; + } + + if ('error' in query) { + return { + error: query.error, + }; + } + + return { + result: query.result.map((task) => + task.id === mutation.result.data.id ? mutation.result.data : task + ), + }; + }, + }, +}); + +sample({ + clock: mutation.finished.success, + fn: () => ({ + message: i18n.t('actions.update_task.notifications.success', { + ns: 'tasks', + }), + color: 'success' as const, + }), + target: notificationsModel.create, +}); + +sample({ + clock: mutation.finished.failure, + fn: () => ({ + message: i18n.t('actions.update_task.notifications.error', { ns: 'tasks', }), + color: 'error' as const, + }), + target: notificationsModel.create, +}); diff --git a/src/features/tasks/update-task/open-menu-item.tsx b/src/features/tasks/update-task/open-menu-item.tsx new file mode 100644 index 00000000..59d77b07 --- /dev/null +++ b/src/features/tasks/update-task/open-menu-item.tsx @@ -0,0 +1,41 @@ +import EditIcon from '@mui/icons-material/Edit'; +import { ListItemIcon, MenuItem } from '@mui/material'; +import { RouteInstance } from 'atomic-router'; +import { Link } from 'atomic-router-react'; +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { routes, getParams, popupsMap } from '@/shared/configs'; +import { CommonProps } from '@/shared/types'; + +export interface OpenUpdateTaskFormMenuItemProps extends CommonProps { + readonly roomId: number; + readonly taskId: number; +} + +export const OpenUpdateTaskFormMenuItem: React.FC<OpenUpdateTaskFormMenuItemProps> = + React.memo((props) => { + const { className, taskId, roomId, } = props; + const { t, } = useTranslation('tasks'); + + const label = t('actions.update_task.actions.open'); + + return ( + <MenuItem + className={className} + to={routes.room.tasks as RouteInstance<any>} + params={{ + id: roomId, + }} + query={{ + [getParams.popup]: popupsMap.updateTask, + [getParams.taskId]: taskId, + }} + component={Link}> + <ListItemIcon> + <EditIcon /> + </ListItemIcon> + {label} + </MenuItem> + ); + }); diff --git a/src/components/Popups/components/UpdateTaskPopup/UpdateTaskPopup.module.css b/src/features/tasks/update-task/update-task.module.css similarity index 100% rename from src/components/Popups/components/UpdateTaskPopup/UpdateTaskPopup.module.css rename to src/features/tasks/update-task/update-task.module.css diff --git a/src/components/Popups/components/UpdateTaskPopup/UpdateTaskPopup.module.css.d.ts b/src/features/tasks/update-task/update-task.module.css.d.ts similarity index 100% rename from src/components/Popups/components/UpdateTaskPopup/UpdateTaskPopup.module.css.d.ts rename to src/features/tasks/update-task/update-task.module.css.d.ts diff --git a/src/features/tasks/update-task/update-task.tsx b/src/features/tasks/update-task/update-task.tsx new file mode 100644 index 00000000..4e88b4e8 --- /dev/null +++ b/src/features/tasks/update-task/update-task.tsx @@ -0,0 +1,61 @@ +import { Button } from '@mui/material'; +import { useUnit } from 'effector-react'; +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { taskModel } from '@/entities/tasks'; + +import { deviceInfoModel } from '@/shared/models'; +import { BasePopupProps, CommonProps } from '@/shared/types'; +import { FullWidthPopup, MainPopup } from '@/shared/ui'; + +import { SkeletonTaskForm, TaskForm } from '../form'; + +import { close, form, mutation } from './model'; +import styles from './update-task.module.css'; + +export interface UpdateTaskProps extends CommonProps, BasePopupProps {} + +export const UpdateTask: React.FC<UpdateTaskProps> = (props) => { + const { t, } = useTranslation('tasks'); + const onClose = useUnit(close); + const { data: task, } = useUnit(taskModel.query); + + const [isMobile, isVertical] = useUnit([ + deviceInfoModel.$isMobile, + deviceInfoModel.$isTabletVertical + ]); + + const onClick = useUnit(form.submit); + const pending = useUnit(mutation.$pending); + + const isFullscreen = isMobile || isVertical; + + const Popup = isFullscreen ? FullWidthPopup : MainPopup; + + const loading = !task; + + const buttonText = t('actions.save', { ns: 'common', }); + const title = t('actions.update_task.title'); + const actions = isFullscreen ? ( + <Button type='submit' onClick={onClick}> + {buttonText} + </Button> + ) : null; + + return ( + <Popup {...props} onClose={onClose} title={title} slots={{ actions, }}> + {loading ? ( + <SkeletonTaskForm className={styles.taskForm} /> + ) : ( + <TaskForm + className={styles.taskForm} + buttonText={buttonText} + $form={form} + buttonDisabled={pending} + hideButton={isFullscreen} + /> + )} + </Popup> + ); +}; diff --git a/src/features/users/exit-room-user/button.tsx b/src/features/users/exit-room-user/button.tsx new file mode 100644 index 00000000..adf7804d --- /dev/null +++ b/src/features/users/exit-room-user/button.tsx @@ -0,0 +1,59 @@ +import ExitRoomIcon from '@mui/icons-material/MeetingRoom'; +import { IconButton, Tooltip } from '@mui/material'; +import { useUnit } from 'effector-react'; +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { useToggle } from '@/shared/lib'; +import { CommonProps } from '@/shared/types'; +import { Confirm } from '@/shared/ui'; + +import { mutation } from './model'; + +export interface ExitRoomUserButtonProps extends CommonProps { + readonly roomId: number; +} + +export const ExitRoomUserButton: React.FC<ExitRoomUserButtonProps> = ( + props +) => { + const { className, roomId, } = props; + + const { t, } = useTranslation('rooms'); + + const exitRoom = useUnit(mutation); + const [opened, handlers] = useToggle(false); + + const onExitAgree = React.useCallback(() => { + exitRoom.start({ roomId, }); + handlers.toggleOff(); + }, [roomId]); + + const nameText = t('actions.exit_room.name'); + const titleText = t('actions.exit_room.title'); + const contentText = t('actions.exit_room.content'); + const actions = t('actions.exit_room.actions', { + returnObjects: true, + }) as Record<string, string>; + + return ( + <> + <Tooltip className={className} title={nameText}> + <IconButton onClick={handlers.toggleOn}> + <ExitRoomIcon /> + </IconButton> + </Tooltip> + + <Confirm + isOpen={opened} + onClose={handlers.toggleOff} + title={titleText} + content={contentText} + agreeText={actions.agree} + onAgree={onExitAgree} + disagreeText={actions.disagree} + onDisagree={handlers.toggleOff} + /> + </> + ); +}; diff --git a/src/features/users/exit-room-user/index.ts b/src/features/users/exit-room-user/index.ts new file mode 100644 index 00000000..afd5034c --- /dev/null +++ b/src/features/users/exit-room-user/index.ts @@ -0,0 +1,6 @@ +export * as exitRoomUserModel from './model'; +export { ExitRoomUserButton, type ExitRoomUserButtonProps } from './button'; +export { + ExitRoomUserMenuItem, + type ExitRoomUserMenuItemProps +} from './menu-item'; diff --git a/src/features/users/exit-room-user/menu-item.tsx b/src/features/users/exit-room-user/menu-item.tsx new file mode 100644 index 00000000..38fe7d4f --- /dev/null +++ b/src/features/users/exit-room-user/menu-item.tsx @@ -0,0 +1,58 @@ +import ExitRoomIcon from '@mui/icons-material/MeetingRoom'; +import { ListItemIcon, MenuItem } from '@mui/material'; +import { useUnit } from 'effector-react'; +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { useToggle } from '@/shared/lib'; +import { CommonProps } from '@/shared/types'; +import { Confirm } from '@/shared/ui'; + +import { mutation } from './model'; + +export interface ExitRoomUserMenuItemProps extends CommonProps { + readonly roomId: number; +} + +export const ExitRoomUserMenuItem: React.FC<ExitRoomUserMenuItemProps> = ( + props +) => { + const { className, roomId, } = props; + const { t, } = useTranslation('rooms'); + + const exitRoom = useUnit(mutation); + const [opened, handlers] = useToggle(false); + + const onExitAgree = React.useCallback(() => { + exitRoom.start({ roomId, }); + handlers.toggleOff(); + }, [roomId]); + + const nameText = t('actions.exit_room.name'); + const titleText = t('actions.exit_room.title'); + const contentText = t('actions.exit_room.content'); + const actions = t('actions.exit_room.actions', { + returnObjects: true, + }) as Record<string, string>; + + return ( + <> + <MenuItem className={className} onClick={handlers.toggleOn}> + <ListItemIcon> + <ExitRoomIcon /> + </ListItemIcon> + {nameText} + </MenuItem> + <Confirm + isOpen={opened} + onClose={handlers.toggleOff} + title={titleText} + content={contentText} + agreeText={actions.agree} + onAgree={onExitAgree} + disagreeText={actions.disagree} + onDisagree={handlers.toggleOff} + /> + </> + ); +}; diff --git a/src/features/users/exit-room-user/model.ts b/src/features/users/exit-room-user/model.ts new file mode 100644 index 00000000..e17ce628 --- /dev/null +++ b/src/features/users/exit-room-user/model.ts @@ -0,0 +1,77 @@ +import { createMutation, update } from '@farfetched/core'; +import { runtypeContract } from '@farfetched/runtypes'; +import { redirect } from 'atomic-router'; +import { createDomain, sample } from 'effector'; +import { Literal } from 'runtypes'; + +import { roomsModel } from '@/entities/rooms'; + +import { membersApi } from '@/shared/api'; +import { i18n, routes } from '@/shared/configs'; +import { notificationsModel } from '@/shared/models'; +import { + StandardResponse, + getStandardResponse, + InRoomParams +} from '@/shared/types'; + +const exitRoomDomain = createDomain(); + +const handlerFx = exitRoomDomain.effect< + InRoomParams, + StandardResponse<boolean>, + Error +>(membersApi.exit); + +export const mutation = createMutation({ + effect: handlerFx, + contract: runtypeContract(getStandardResponse(Literal(true))), +}); + +redirect({ + clock: mutation.finished.success, + route: routes.rooms.base, +}); + +update(roomsModel.query, { + on: mutation, + by: { + success: ({ query, mutation, }) => { + if (!query) { + return { + result: [], + }; + } + + if ('error' in query) { + return { + error: query.error, + }; + } + + return { + result: query.result.filter( + (room) => room.id !== mutation.params.roomId + ), + }; + }, + }, +}); + +sample({ + clock: mutation.finished.success, + fn: () => ({ + message: i18n.t('actions.exit_room.notifications.success', { ns: 'rooms', }), + color: 'success' as const, + }), + target: notificationsModel.create, +}); + +sample({ + clock: mutation.finished.failure, + fn: () => ({ + message: i18n.t('actions.exit_room.notifications.error', { ns: 'rooms', }), + color: 'error' as const, + }), + target: notificationsModel.create, +}); diff --git a/src/features/users/index.ts b/src/features/users/index.ts new file mode 100644 index 00000000..b32ce5c7 --- /dev/null +++ b/src/features/users/index.ts @@ -0,0 +1,2 @@ +export * from './remove-user-from-room'; +export * from './exit-room-user'; diff --git a/src/features/users/remove-user-from-room/index.ts b/src/features/users/remove-user-from-room/index.ts new file mode 100644 index 00000000..8f582262 --- /dev/null +++ b/src/features/users/remove-user-from-room/index.ts @@ -0,0 +1,2 @@ +export * as removeUserFromRoomModel from './model'; +export { RemoveUserFromRoom, type RemoveUserFromRoomProps } from './ui'; diff --git a/src/features/users/remove-user-from-room/model.ts b/src/features/users/remove-user-from-room/model.ts new file mode 100644 index 00000000..438b0958 --- /dev/null +++ b/src/features/users/remove-user-from-room/model.ts @@ -0,0 +1,67 @@ +import { createMutation, update } from '@farfetched/core'; +import { runtypeContract } from '@farfetched/runtypes'; +import { createEffect, sample } from 'effector'; +import { Boolean } from 'runtypes'; + +import { usersInRoomModel } from '@/entities/users'; + +import { membersApi } from '@/shared/api'; +import { i18n } from '@/shared/configs'; +import { notificationsModel } from '@/shared/models'; +import { getStandardResponse } from '@/shared/types'; + +const handlerFx = createEffect(membersApi.remove); + +export const mutation = createMutation({ + effect: handlerFx, + contract: runtypeContract(getStandardResponse(Boolean)), +}); + +update(usersInRoomModel.query, { + on: mutation, + by: { + success: ({ mutation, query, }) => { + if (!query) { + return { + result: [], + refetch: true, + }; + } + + if ('error' in query) { + return { + error: query.error, + refetch: true, + }; + } + + return { + result: query.result.filter( + (user) => user.id !== mutation.params.userId + ), + }; + }, + }, +}); + +sample({ + clock: mutation.finished.success, + fn: () => ({ + message: i18n.t('actions.remove_user.notifications.success', { + ns: 'room-users', + }), + color: 'success' as const, + }), + target: notificationsModel.create, +}); + +sample({ + clock: mutation.finished.failure, + fn: () => ({ + message: i18n.t('actions.remove_user.notifications.error', { + ns: 'room-users', + }), + color: 'error' as const, + }), + target: notificationsModel.create, +}); diff --git a/src/features/users/remove-user-from-room/ui.tsx b/src/features/users/remove-user-from-room/ui.tsx new file mode 100644 index 00000000..d00e97c9 --- /dev/null +++ b/src/features/users/remove-user-from-room/ui.tsx @@ -0,0 +1,57 @@ +import DeleteIcon from '@mui/icons-material/Delete'; +import { IconButton, Tooltip } from '@mui/material'; +import { useUnit } from 'effector-react'; +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { useToggle } from '@/shared/lib'; +import { CommonProps } from '@/shared/types'; +import { Confirm } from '@/shared/ui'; + +import { mutation } from './model'; + +export interface RemoveUserFromRoomProps extends CommonProps { + readonly userId: number; + readonly roomId: number; +} + +export const RemoveUserFromRoom: React.FC<RemoveUserFromRoomProps> = ( + props +) => { + const { userId, className, roomId, } = props; + const { t, } = useTranslation('room-users'); + const removeUser = useUnit(mutation); + + const [toggled, { toggleOff, toggleOn, }] = useToggle(false); + + const onAgree = React.useCallback(() => { + removeUser.start({ userId, roomId, }); + toggleOff(); + }, [toggleOff, userId, roomId]); + + const title = t('actions.remove_user.title'); + const content = t('actions.remove_user.content'); + const open = t('actions.remove_user.actions.open'); + const agree = t('actions.remove_user.actions.agree'); + const disagree = t('actions.remove_user.actions.disagree'); + + return ( + <> + <Tooltip title={open}> + <IconButton className={className} onClick={toggleOn}> + <DeleteIcon /> + </IconButton> + </Tooltip> + <Confirm + isOpen={toggled} + onClose={toggleOff} + title={title} + content={content} + agreeText={agree} + onAgree={onAgree} + disagreeText={disagree} + onDisagree={toggleOff} + /> + </> + ); +}; diff --git a/src/hooks/index.ts b/src/hooks/index.ts deleted file mode 100644 index 88630a00..00000000 --- a/src/hooks/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -export { usePrepareLink } from './usePrepareLink'; -export { useGetParam } from './useGetParam'; -export { usePageTitle } from './usePageTitle'; -export { useGroupedTasks } from './useGroupedTasks'; -export { useToggle } from './useToggle'; -export { useGroup } from './useGroup'; -export { useParam } from './useParam'; diff --git a/src/hooks/useGetParam.ts b/src/hooks/useGetParam.ts deleted file mode 100644 index ac8a0285..00000000 --- a/src/hooks/useGetParam.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { useStoreMap } from 'effector-react'; -import { router } from '@/models'; - -export const useGetParam = <T extends string | number = string>( - paramName: string -): T | null => { - return useStoreMap({ - store: router.$query, - fn: (state, [name]) => { - return state[name]; - }, - defaultValue: null, - keys: [paramName], - }); -}; diff --git a/src/hooks/useGroup.ts b/src/hooks/useGroup.ts deleted file mode 100644 index e74868db..00000000 --- a/src/hooks/useGroup.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { useStoreMap } from 'effector-react'; -import { $GroupsMap } from '@/models'; - -export const useGroup = (groupId: number) => { - return useStoreMap($GroupsMap, (groups) => { - return groups[groupId] ?? null; - }); -}; diff --git a/src/hooks/useGroupedTasks.ts b/src/hooks/useGroupedTasks.ts deleted file mode 100644 index 48567dce..00000000 --- a/src/hooks/useGroupedTasks.ts +++ /dev/null @@ -1,35 +0,0 @@ -import * as React from 'react'; -import { useQuery } from '@farfetched/react'; -import { - GroupedByStatusTasks, - TaskStatus, - Task, - getTasksQuery, -} from '@/models'; - -const createGrouper = (status: TaskStatus) => { - return (state: Task[]) => { - return state.filter((task) => task.status === status); - }; -}; - -export const useGroupedTasks = () => { - const { data: tasks, ...rest } = useQuery(getTasksQuery); - - const data = React.useMemo<GroupedByStatusTasks | null>(() => { - if (!tasks) { - return null; - } - return { - ready: createGrouper('ready')(tasks), - done: createGrouper('done')(tasks), - 'in progress': createGrouper('in progress')(tasks), - needReview: createGrouper('review')(tasks), - }; - }, [tasks]); - - return { - data, - ...rest, - }; -}; diff --git a/src/hooks/useParam.ts b/src/hooks/useParam.ts deleted file mode 100644 index 59c230c3..00000000 --- a/src/hooks/useParam.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { RouteInstance } from 'atomic-router'; -import { useStoreMap } from 'effector-react'; - -export const useParam = <P extends object>( - route: RouteInstance<P>, - param: keyof P -): P[keyof P] => { - return useStoreMap({ - store: route.$params, - fn: (state, [key]) => { - return state[key]; - }, - keys: [param], - }); -}; diff --git a/src/hooks/usePrepareLink.ts b/src/hooks/usePrepareLink.ts deleted file mode 100644 index dd51df78..00000000 --- a/src/hooks/usePrepareLink.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { useUnit } from 'effector-react'; -import { router } from '@/models'; -import { prepareLink, PrepareLinkParams } from '@/utils'; - -export const usePrepareLink = (options: PrepareLinkParams = {}): string => { - const path = useUnit(router.$path); - const query = useUnit(router.$query); - - return prepareLink( - { - path, - query, - }, - options - ); -}; diff --git a/src/hooks/useToggle.ts b/src/hooks/useToggle.ts deleted file mode 100644 index 96bf403c..00000000 --- a/src/hooks/useToggle.ts +++ /dev/null @@ -1,12 +0,0 @@ -import * as React from 'react'; -import { VoidFunction } from '@/types'; - -export const useToggle = (defaultValue = false): [boolean, VoidFunction] => { - const [isToggle, setIsToggle] = React.useState(defaultValue); - - const toggle = React.useCallback(() => { - setIsToggle(!isToggle); - }, [isToggle]); - - return [isToggle, toggle]; -}; diff --git a/src/i18n/index.ts b/src/i18n/index.ts deleted file mode 100644 index accc62ba..00000000 --- a/src/i18n/index.ts +++ /dev/null @@ -1,20 +0,0 @@ -import i18n from 'i18next'; -import { initReactI18next } from 'react-i18next'; -import Backend from 'i18next-http-backend'; -import LanguageDetector from 'i18next-browser-languagedetector'; -import * as resources from './locales'; - -i18n - .use(Backend) - .use(LanguageDetector) - .use(initReactI18next) - .init({ - fallbackLng: 'en', - debug: true, - interpolation: { - escapeValue: false, - }, - resources, - }); - -export { i18n }; diff --git a/src/i18n/locales/en/common.json b/src/i18n/locales/en/common.json deleted file mode 100644 index 92380ffe..00000000 --- a/src/i18n/locales/en/common.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "loading": "Loading...", - "none": "None", - "actions": { - "create": "Create", - "update": "Update", - "save": "Save", - "remove": "Remove", - "exit": "Exit", - "close": "Close" - } -} diff --git a/src/i18n/locales/en/header.json b/src/i18n/locales/en/header.json deleted file mode 100644 index c38a9d71..00000000 --- a/src/i18n/locales/en/header.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "actions": { - "settings": "Settings", - "logout": "Logout" - } -} diff --git a/src/i18n/locales/en/index.ts b/src/i18n/locales/en/index.ts deleted file mode 100644 index 8434588e..00000000 --- a/src/i18n/locales/en/index.ts +++ /dev/null @@ -1,10 +0,0 @@ -/* eslint-disable import/extensions */ -export { default as common } from './common.json'; -export { default as room } from './room.json'; -export { default as login } from './login.json'; -export { default as rooms } from './rooms.json'; -export { default as popups } from './popups.json'; -export { default as settings } from './settings.json'; -export { default as registration } from './registration.json'; -export { default as task } from './task.json'; -export { default as header } from './header.json'; diff --git a/src/i18n/locales/en/login.json b/src/i18n/locales/en/login.json deleted file mode 100644 index 4973e1f1..00000000 --- a/src/i18n/locales/en/login.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "title": "Login", - "fields": { - "login": "Login", - "password": "Password", - "remember": "Remember me" - }, - "actions": { - "submit": "Login", - "registration": "Registration" - } -} diff --git a/src/i18n/locales/en/popups.json b/src/i18n/locales/en/popups.json deleted file mode 100644 index c411d012..00000000 --- a/src/i18n/locales/en/popups.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "task": { - "createTitle": "Create task", - "updateTitle": "Update task", - "group": "Group", - "status": "Status", - "content": "Content" - }, - "group": { - "createTitle": "Create group", - "updateTitle": "Update group", - "name": "Name", - "mainColor": "Main color", - "secondaryColor": "Secondary color" - }, - "groups": { - "title": "Groups" - }, - "room": { - "createTitle": "Create room", - "updateTitle": "Update rooms", - "name": "Name", - "description": "Description" - } -} diff --git a/src/i18n/locales/en/registration.json b/src/i18n/locales/en/registration.json deleted file mode 100644 index aa21518e..00000000 --- a/src/i18n/locales/en/registration.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "title": "Registration", - "fields": { - "login": "Login", - "password": "Password", - "passwordRepeat": "Password Repeat" - }, - "actions": { - "submit": "Registration", - "login": "Login" - } -} diff --git a/src/i18n/locales/en/room.json b/src/i18n/locales/en/room.json deleted file mode 100644 index 4d201dd6..00000000 --- a/src/i18n/locales/en/room.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "title": "Комната", - "taskProgress": { - "title": "Tasks Progress", - "progressAria": "Progress of {{name}} tasks is {{completed}}" - }, - "activities": { - "title": "Activities", - "text": "{{activistId}} has $t(activities.type.{{type}}) $t(activities.spheres.{{sphere}})", - "spheres": { - "task": "task", - "group": "group" - }, - "type": { - "update": "updated", - "create": "created", - "remove": "removed" - } - }, - "actions": { - "groups": "Show groups" - } -} diff --git a/src/i18n/locales/en/rooms.json b/src/i18n/locales/en/rooms.json deleted file mode 100644 index 87497b1e..00000000 --- a/src/i18n/locales/en/rooms.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "title": "Rooms", - "card": { - "description": "Description" - } -} diff --git a/src/i18n/locales/en/settings.json b/src/i18n/locales/en/settings.json deleted file mode 100644 index 9163a987..00000000 --- a/src/i18n/locales/en/settings.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "title": "Settings", - "navigation": { - "generic": "Generic", - "profile": "Profile" - } -} diff --git a/src/i18n/locales/en/task.json b/src/i18n/locales/en/task.json deleted file mode 100644 index fe41e339..00000000 --- a/src/i18n/locales/en/task.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "statuses": { - "ready": "Ready", - "in progress": "In progress", - "review": "Need review", - "done": "Done" - } -} diff --git a/src/i18n/locales/index.ts b/src/i18n/locales/index.ts deleted file mode 100644 index ae2064c9..00000000 --- a/src/i18n/locales/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * as en from './en'; -export * as ru from './ru'; diff --git a/src/i18n/locales/ru/common.json b/src/i18n/locales/ru/common.json deleted file mode 100644 index d106523b..00000000 --- a/src/i18n/locales/ru/common.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "loading": "Загрузка...", - "none": "Пусто", - "actions": { - "create": "Добавить", - "update": "Изменить", - "save": "Сохранить", - "remove": "Удалить", - "exit": "Выйти", - "close": "Закрыть" - } -} diff --git a/src/i18n/locales/ru/header.json b/src/i18n/locales/ru/header.json deleted file mode 100644 index b3af77ea..00000000 --- a/src/i18n/locales/ru/header.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "actions": { - "settings": "Настройки", - "logout": "Выйти" - } -} diff --git a/src/i18n/locales/ru/index.ts b/src/i18n/locales/ru/index.ts deleted file mode 100644 index 8434588e..00000000 --- a/src/i18n/locales/ru/index.ts +++ /dev/null @@ -1,10 +0,0 @@ -/* eslint-disable import/extensions */ -export { default as common } from './common.json'; -export { default as room } from './room.json'; -export { default as login } from './login.json'; -export { default as rooms } from './rooms.json'; -export { default as popups } from './popups.json'; -export { default as settings } from './settings.json'; -export { default as registration } from './registration.json'; -export { default as task } from './task.json'; -export { default as header } from './header.json'; diff --git a/src/i18n/locales/ru/login.json b/src/i18n/locales/ru/login.json deleted file mode 100644 index 193fbe40..00000000 --- a/src/i18n/locales/ru/login.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "title": "Вход", - "fields": { - "login": "Логин", - "password": "Пароль", - "remember": "Запомнить меня" - }, - "actions": { - "submit": "Войти", - "registration": "Зарегистрироваться" - } -} diff --git a/src/i18n/locales/ru/popups.json b/src/i18n/locales/ru/popups.json deleted file mode 100644 index 88139cf6..00000000 --- a/src/i18n/locales/ru/popups.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "task": { - "createTitle": "Добавить задачу", - "updateTitle": "Изменить задачу", - "group": "Группа", - "status": "Статус", - "content": "Содержание" - }, - "group": { - "createTitle": "Добавить группу", - "updateTitle": "Изменить группу", - "name": "Название", - "mainColor": "Основной цвет", - "secondaryColor": "Дополнительный цвет" - }, - "groups": { - "title": "Группы" - }, - "room": { - "createTitle": "Создать комнату", - "updateTitle": "Изменить комнату", - "name": "Название", - "description": "Описание" - } -} diff --git a/src/i18n/locales/ru/registration.json b/src/i18n/locales/ru/registration.json deleted file mode 100644 index 157dfefb..00000000 --- a/src/i18n/locales/ru/registration.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "title": "Регистрация", - "fields": { - "login": "Логин", - "password": "Пароль", - "passwordRepeat": "Повторите пароль" - }, - "actions": { - "submit": "Регистрация", - "login": "Войти" - } -} diff --git a/src/i18n/locales/ru/room.json b/src/i18n/locales/ru/room.json deleted file mode 100644 index 094bbf7b..00000000 --- a/src/i18n/locales/ru/room.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "title": "Комната", - "taskProgress": { - "title": "Прогресс", - "progressAria": "Прогресс задач группы {{name}}, выполнено {{completed}}" - }, - "activities": { - "title": "Активности", - "text": "Пользователь {{activistId}} $t(activities.type.{{type}}) $t(activities.spheres.{{sphere}})", - "spheres": { - "task": "задачу", - "group": "группу" - }, - "type": { - "update": "изменил", - "create": "создал", - "remove": "удалил" - } - }, - "actions": { - "groups": "Показать группы" - } -} diff --git a/src/i18n/locales/ru/rooms.json b/src/i18n/locales/ru/rooms.json deleted file mode 100644 index 7a659936..00000000 --- a/src/i18n/locales/ru/rooms.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "title": "Комнаты", - "card": { - "description": "Описание" - } -} diff --git a/src/i18n/locales/ru/settings.json b/src/i18n/locales/ru/settings.json deleted file mode 100644 index 37309302..00000000 --- a/src/i18n/locales/ru/settings.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "title": "Настройки", - "navigation": { - "generic": "Общие", - "profile": "Профиль" - } -} diff --git a/src/i18n/locales/ru/task.json b/src/i18n/locales/ru/task.json deleted file mode 100644 index 19267088..00000000 --- a/src/i18n/locales/ru/task.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "statuses": { - "ready": "В ожидании", - "in progress": "В прогрессе", - "review": "Проверка", - "done": "Выполнено" - } -} diff --git a/src/index.css b/src/index.css deleted file mode 100644 index c34f55a8..00000000 --- a/src/index.css +++ /dev/null @@ -1,70 +0,0 @@ -*, -*::after, -*::before { - box-sizing: border-box; -} - -:root { - --background: #ebf0f7; - - --shadow: rgba(99, 99, 99, 0.5); - - --grey-lighter: rgb(227, 227, 227); - --grey: rgb(158, 154, 154); - --grey-darker: rgb(99 99 99); - - --warning-lightest: #ffebd3; - --warning-lighter: #f7bd77; - --warning: #fba63c; - --warning-darker: #f38d11; - - --error-lightest: #ffd2ca; - --error-lighter: #fc917e; - --error: #f86a51; - --error-darker: #fa4c2d; - - --success-lightest: #b9e2c7; - --success-lighter: #88e0a7; - --success: #5dc983; - --success-darker: #13854e; - - --primary-lightest: #cce3f1; - --primary-lighter: #6ac8ff; - --primary: #2e87ba; - --primary-darker: #006ead; - - --secondary-lightest: #b9a1bd; - --secondary-lighter: #ab5db9; - --secondary: #a734ba; - --secondary-darker: #9900b4; -} - -body { - min-height: 100vh; - margin: 0; - - background-color: var(--background); - - font-family: 'Roboto', 'Oxygen', 'Ubuntu', 'Fira Sans', 'Droid Sans', - 'Helvetica Neue', sans-serif; - color: #2e2e2e; -} - -#root { - min-height: 100%; -} - -.visibility-hidden { - display: inline-block; - - position: absolute; - top: -99999px; - left: -9999px; - - width: 1px; - height: 1px; - - clip: rect(0, 0, 0, 0); - - font-size: 1px; -} diff --git a/src/index.tsx b/src/index.tsx index 3574d7cc..2ed7ff76 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,38 +1,13 @@ import * as React from 'react'; -import { - Experimental_CssVarsProvider as CssVarsProvider, - StyledEngineProvider -} from '@mui/material'; import ReactDOM from 'react-dom/client'; -import { RouterProvider } from 'atomic-router-react'; -import { createBrowserHistory } from 'history'; -import { App } from '@/app'; -import { router } from '@/models'; -import { theme } from '@/types'; -import { ErrorBoundary } from '@/components'; -import '@/models/init'; -import '@/i18n'; - -import './index.css'; -const root = ReactDOM.createRoot( - document.getElementById('root') as HTMLElement -); +import { appModel } from '@/shared/models'; -const history = createBrowserHistory(); +import { App } from '@/app'; -router.setHistory(history); +const container = document.getElementById('root') as HTMLElement; -root.render( - <RouterProvider router={router}> - <CssVarsProvider theme={theme}> - <StyledEngineProvider injectFirst> - <ErrorBoundary> - <App /> - </ErrorBoundary> - </StyledEngineProvider> - </CssVarsProvider> - </RouterProvider> -); +appModel.started(); -console.debug(import.meta.env); +const root = ReactDOM.createRoot(container); +root.render(<App />); diff --git a/src/layouts/AuthLayout/AuthLayout.module.css b/src/layouts/AuthLayout/AuthLayout.module.css deleted file mode 100644 index 0f634940..00000000 --- a/src/layouts/AuthLayout/AuthLayout.module.css +++ /dev/null @@ -1,21 +0,0 @@ -.main { - display: grid; - grid-template-rows: repeat(3, min-content); - row-gap: 1.5rem; - - width: var(--auth-layout-width); - - margin: 0 auto; -} - -@media (min-width: 600px) { - .main { - --auth-layout-width: 600px; - } -} - -@media (max-width: 600px) { - .main { - --auth-layout-width: 100%; - } -} diff --git a/src/layouts/AuthLayout/AuthLayout.module.css.d.ts b/src/layouts/AuthLayout/AuthLayout.module.css.d.ts deleted file mode 100644 index af54ec7a..00000000 --- a/src/layouts/AuthLayout/AuthLayout.module.css.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -declare const styles: { - readonly main: string; -}; -export = styles; diff --git a/src/layouts/AuthLayout/AuthLayout.tsx b/src/layouts/AuthLayout/AuthLayout.tsx deleted file mode 100644 index 7712cc7d..00000000 --- a/src/layouts/AuthLayout/AuthLayout.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import * as React from 'react'; -import cn from 'classnames'; -import { Container } from '@mui/material'; -import { CommonProps } from '@/types'; - -import styles from './AuthLayout.module.css'; - -export interface AuthLayoutProps extends CommonProps {} - -export const AuthLayout: React.FC<React.PropsWithChildren<AuthLayoutProps>> = ( - props -) => { - const { className, children } = props; - return ( - <Container> - <main className={cn(styles.main, className)}>{children}</main> - </Container> - ); -}; diff --git a/src/layouts/AuthLayout/index.ts b/src/layouts/AuthLayout/index.ts deleted file mode 100644 index 3a7a3b55..00000000 --- a/src/layouts/AuthLayout/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { AuthLayout, type AuthLayoutProps } from './AuthLayout'; diff --git a/src/layouts/MainLayout/MainLayout.module.css b/src/layouts/MainLayout/MainLayout.module.css deleted file mode 100644 index f5c6d657..00000000 --- a/src/layouts/MainLayout/MainLayout.module.css +++ /dev/null @@ -1,9 +0,0 @@ -.layout { - display: grid; - gap: 2em; - - max-width: 1920px; - - margin: 0 auto; - padding: 2em; -} diff --git a/src/layouts/MainLayout/MainLayout.tsx b/src/layouts/MainLayout/MainLayout.tsx deleted file mode 100644 index ffa7afb7..00000000 --- a/src/layouts/MainLayout/MainLayout.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import * as React from 'react'; -import { CommonProps } from '@/types'; -import { Header } from '@/components'; - -import styles from './MainLayout.module.css'; - -export interface MainLayoutProps extends CommonProps {} - -export const MainLayout: React.FC<React.PropsWithChildren<MainLayoutProps>> = ( - props -) => { - const { className, children } = props; - - return ( - <section className={styles.layout}> - <Header /> - <main className={className}>{children}</main> - </section> - ); -}; diff --git a/src/layouts/MainLayout/index.ts b/src/layouts/MainLayout/index.ts deleted file mode 100644 index 721b1cfd..00000000 --- a/src/layouts/MainLayout/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { MainLayout, type MainLayoutProps } from './MainLayout'; diff --git a/src/layouts/index.ts b/src/layouts/index.ts deleted file mode 100644 index c0f473a8..00000000 --- a/src/layouts/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './AuthLayout'; -export * from './MainLayout'; diff --git a/src/models/activities/index.ts b/src/models/activities/index.ts deleted file mode 100644 index 4d92e5de..00000000 --- a/src/models/activities/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './units'; -export * from './types'; -export * from './queries'; diff --git a/src/models/activities/init.ts b/src/models/activities/init.ts deleted file mode 100644 index 50c10a89..00000000 --- a/src/models/activities/init.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { sample } from 'effector'; -import { activitiesApi } from '@/api'; -import { getActivitiesFx, ActivityGate } from './units'; -import { - createTaskMutation, - removeTaskMutation, - updateTaskMutation, -} from '../tasks'; -import { - createGroupMutation, - removeGroupMutation, - updateGroupMutation, -} from '../groups'; -import { getActivitiesQuery } from './queries'; - -getActivitiesFx.use(activitiesApi.getAll); - -sample({ - clock: [ - createTaskMutation.finished.success, - updateTaskMutation.finished.success, - removeTaskMutation.finished.success, - createGroupMutation.finished.success, - updateGroupMutation.finished.success, - removeGroupMutation.finished.success, - ], - fn: ({ params: { roomId } }) => { - return roomId; - }, - target: getActivitiesQuery.start, -}); - -sample({ - clock: ActivityGate.open, - fn: ({ roomId }) => roomId, - target: getActivitiesQuery.start, -}); diff --git a/src/models/activities/queries.ts b/src/models/activities/queries.ts deleted file mode 100644 index 98d9e4ce..00000000 --- a/src/models/activities/queries.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { createQuery } from '@farfetched/core'; -import { runtypeContract } from '@farfetched/runtypes'; -import { Array } from 'runtypes'; -import { - getStandardSuccessResponse, - StandardResponse, - StandardSuccessResponse, -} from '@/types'; -import { activity, Activity } from './types'; -import { getActivitiesFx } from './units'; -import { dataExtractor } from '../utils/dataExtractor'; - -export const getActivitiesQuery = createQuery< - number, - StandardResponse<Activity[]>, - Error, - StandardSuccessResponse<Activity[]>, - Activity[] ->({ - effect: getActivitiesFx, - contract: runtypeContract(getStandardSuccessResponse(Array(activity))), - mapData: dataExtractor, -}); diff --git a/src/models/activities/types.ts b/src/models/activities/types.ts deleted file mode 100644 index b2ecb7a7..00000000 --- a/src/models/activities/types.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { Literal, Number, Record, Static, String, Union } from 'runtypes'; - -export const activityType = Union( - Literal('update'), - Literal('create'), - Literal('remove') -); -export type ActivityType = Static<typeof activityType>; - -export const activitySphere = Union(Literal('task'), Literal('group')); -export type ActivitySphere = Static<typeof activitySphere>; - -export const activity = Record({ - id: Number, - roomId: Number, - activistId: Number, - type: activityType, - sphere: activitySphere, - createdAt: String, -}).asReadonly(); - -export interface Activity extends Static<typeof activity> {} diff --git a/src/models/activities/units.ts b/src/models/activities/units.ts deleted file mode 100644 index f39fc716..00000000 --- a/src/models/activities/units.ts +++ /dev/null @@ -1,24 +0,0 @@ -/* eslint-disable import/no-extraneous-dependencies */ -import { createDomain } from 'effector-logger'; -import { createGate } from 'effector-react'; -import { StandardResponse, InRoomRequest } from '@/types'; -import { Activity } from './types'; - -export const ActivitiesDomain = createDomain('ActivitiesDomain'); - -export const $Activities = ActivitiesDomain.store<Activity[]>([], { - name: 'ActivitiesStore', -}); - -export const getActivitiesFx = ActivitiesDomain.effect< - number, - StandardResponse<Activity[]> ->('getActivitiesFx'); - -export const getActivities = - ActivitiesDomain.event<number>('getActivitiesEvent'); - -export const ActivityGate = createGate<InRoomRequest>({ - domain: ActivitiesDomain, - name: 'activitiesGate', -}); diff --git a/src/models/auth/index.ts b/src/models/auth/index.ts deleted file mode 100644 index 018c6395..00000000 --- a/src/models/auth/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './queries'; -export * from './types'; -export * from './units'; diff --git a/src/models/auth/init.ts b/src/models/auth/init.ts deleted file mode 100644 index b9ff8762..00000000 --- a/src/models/auth/init.ts +++ /dev/null @@ -1,79 +0,0 @@ -import { sample } from 'effector'; -import { redirect } from 'atomic-router'; -import { authApi } from '@/api'; -import { loginRoute, roomsRoute } from '@/routes'; -import { - $AccessToken, - $AuthUser, - authFx, - AuthGate, - loginFx, - logoutFx, - registrationFx -} from './units'; -import { - authQuery, - loginMutation, - logoutMutation, - registrationMutation -} from './queries'; -import { goToState, saveCurrentLocation } from '../routing'; - -authFx.use(authApi.auth); -loginFx.use(authApi.login); -registrationFx.use(authApi.registration); -logoutFx.use(authApi.logout); - -sample({ - clock: [authQuery.finished.success, loginMutation.finished.success], - fn: ({ result, }) => result.data.user, - target: $AuthUser, -}); - -sample({ - clock: authQuery.finished.success, - fn: ({ result, }) => result.data.tokens.accessToken, - target: $AccessToken, -}); - -sample({ - clock: loginMutation.finished.success, - fn: ({ result, }) => result.data.user, - target: $AuthUser, -}); - -sample({ - clock: logoutMutation.finished.success, - fn: () => null, - target: [$AccessToken, $AuthUser], -}); - -sample({ - clock: AuthGate.open, - target: [authQuery.start, saveCurrentLocation], -}); - -redirect({ - clock: loginMutation.finished.success, - route: roomsRoute, -}); - -redirect({ - clock: [ - logoutMutation.finished.success, - registrationMutation.finished.success - ], - route: loginRoute, -}); - -sample({ - clock: authQuery.finished.success, - target: goToState, -}); - -redirect({ - clock: authQuery.finished.failure, - route: loginRoute, -}); - -authQuery.finished.failure.watch(console.log); diff --git a/src/models/auth/queries.ts b/src/models/auth/queries.ts deleted file mode 100644 index 71fbba3e..00000000 --- a/src/models/auth/queries.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { createQuery, createMutation } from '@farfetched/core'; -import { runtypeContract } from '@farfetched/runtypes'; -import { Boolean } from 'runtypes'; -import { LoginRequest, RegistrationRequest } from '@/api'; -import { - getStandardSuccessResponse, - StandardResponse, - StandardSuccessResponse, - voidResponse, - VoidResponse, -} from '@/types'; -import { authFx, loginFx, logoutFx, registrationFx } from './units'; -import { authResponse, AuthResponse } from './types'; -import { getIsSuccessResponseValidator } from '../utils/isSuccessResponse'; - -export const authQuery = createQuery< - void, - StandardResponse<AuthResponse>, - Error, - StandardSuccessResponse<AuthResponse>, - void ->({ - effect: authFx, - contract: runtypeContract(getStandardSuccessResponse(authResponse)), - validate: getIsSuccessResponseValidator(), -}); - -export const loginMutation = createMutation< - LoginRequest, - StandardResponse<AuthResponse>, - StandardSuccessResponse<AuthResponse>, - Error ->({ - effect: loginFx, - contract: runtypeContract(getStandardSuccessResponse(authResponse)), -}); - -export const registrationMutation = createMutation< - RegistrationRequest, - StandardResponse<VoidResponse>, - StandardSuccessResponse<VoidResponse>, - Error ->({ - effect: registrationFx, - contract: runtypeContract(getStandardSuccessResponse(voidResponse)), -}); - -export const logoutMutation = createMutation< - void, - StandardResponse<boolean>, - StandardSuccessResponse<boolean>, - Error ->({ - effect: logoutFx, - contract: runtypeContract(getStandardSuccessResponse(Boolean)), -}); diff --git a/src/models/auth/types.ts b/src/models/auth/types.ts deleted file mode 100644 index dc168c5b..00000000 --- a/src/models/auth/types.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { Record, String, Static, Number } from 'runtypes'; - -export const user = Record({ - id: Number, - login: String, - photo: String.nullable(), -}).asReadonly(); - -export type User = Static<typeof user>; - -export const tokens = Record({ - accessToken: String, - refreshToken: String, -}).asReadonly(); - -export interface Tokens extends Static<typeof tokens> {} - -export const authResponse = Record({ - tokens, - user, -}).asReadonly(); - -export interface AuthResponse extends Static<typeof authResponse> {} diff --git a/src/models/auth/units.ts b/src/models/auth/units.ts deleted file mode 100644 index fb367d60..00000000 --- a/src/models/auth/units.ts +++ /dev/null @@ -1,33 +0,0 @@ -/* eslint-disable import/no-extraneous-dependencies */ -import { combine, createDomain } from 'effector-logger'; -import { createGate } from 'effector-react'; -import { LoginRequest, RegistrationRequest } from '@/api'; -import { StandardResponse, VoidResponse } from '@/types'; -import { AuthResponse, User } from './types'; - -export const Auth = createDomain('AuthDomain'); - -export const $AuthUser = Auth.store<User | null>(null); -export const $AccessToken = Auth.store<string | null>(null); -export const $IsAuth = combine($AuthUser, (state) => !!state); - -export const loginFx = Auth.effect< - LoginRequest, - StandardResponse<AuthResponse> ->('loginFx'); - -export const authFx = Auth.effect<void, StandardResponse<AuthResponse>>( - 'authFx' -); -export const registrationFx = Auth.effect< - RegistrationRequest, - StandardResponse<VoidResponse> ->('registrationFx'); -export const logoutFx = Auth.effect<void, StandardResponse<boolean>>( - 'logoutFx' -); - -export const AuthGate = createGate({ - domain: Auth, - name: 'authGate', -}); diff --git a/src/models/fabrics/attachRemoteOperationWithAccess.ts b/src/models/fabrics/attachRemoteOperationWithAccess.ts deleted file mode 100644 index b616e0ad..00000000 --- a/src/models/fabrics/attachRemoteOperationWithAccess.ts +++ /dev/null @@ -1,85 +0,0 @@ -/* eslint-disable import/no-extraneous-dependencies */ -import { sample } from 'effector'; -import { createDomain } from 'effector-logger'; -import { InvalidDataError } from '@farfetched/core'; -import { RemoteOperation } from '@farfetched/core/src/remote_operation/type'; -import { AccessOptions, StandardFailError } from '@/packages'; -import { authApi } from '@/api'; -import { StandardResponse } from '@/types'; -import { Tokens, $AccessToken } from '../auth'; -import { WithoutAccess } from './attachWithAccessToken'; - -const AttachWithDomain = createDomain(); - -export const attachRemoteOperationWithAccess = < - Params extends Required<AccessOptions>, - Error extends StandardFailError, - MappedData, - Meta ->( - remoteOperation: RemoteOperation< - WithoutAccess<Params>, - MappedData, - Error | InvalidDataError, - Meta - > - ): void => { - // eslint-disable-next-line no-underscore-dangle - const { name, } = remoteOperation.__.executeFx; - - const $IsRetry = AttachWithDomain.store<boolean>(false, { - name: `IsRetry-${name}`, - }); - const $LastParams = AttachWithDomain.store<WithoutAccess<Params> | null>( - null, - { - name: `LastParams-${name}`, - } - ); - const refreshFx = AttachWithDomain.effect<void, StandardResponse<Tokens>>( - `refreshFx-${name}` - ); - refreshFx.use(authApi.refresh); - - sample({ - clock: remoteOperation.finished.failure, - source: $IsRetry, - filter: (isRetry, { error, }) => { - return !isRetry && 'statusCode' in error && error.statusCode === 401; - }, - fn: (_, { params, }) => params, - target: [$LastParams, refreshFx], - }); - - sample({ - clock: refreshFx, - fn: () => true, - target: $IsRetry, - }); - - sample({ - clock: refreshFx.doneData, - filter: (data) => data.data !== null, - fn: (data) => data.data!.accessToken, - target: $AccessToken, - }); - - sample({ - clock: refreshFx.doneData, - source: $LastParams, - filter: Boolean, - fn: (params) => params, - target: remoteOperation.start, - }); - - sample({ - clock: refreshFx.doneData, - fn: () => false, - target: $IsRetry, - }); - - sample({ - clock: refreshFx.failData, - fn: (data) => data, - }); -}; diff --git a/src/models/fabrics/attachWithAccessToken.ts b/src/models/fabrics/attachWithAccessToken.ts deleted file mode 100644 index 35e26ab9..00000000 --- a/src/models/fabrics/attachWithAccessToken.ts +++ /dev/null @@ -1,44 +0,0 @@ -/* eslint-disable import/no-extraneous-dependencies */ -import { Effect, Store } from 'effector'; -import { attach } from 'effector-logger'; -import { AccessOptions, StandardFailError } from '@/packages'; -import { $AccessToken } from '../auth/units'; - -export interface AttachWithAccessTokenOptions< - Params extends Required<AccessOptions>, - Done, - Fail extends StandardFailError -> { - readonly effect: Effect<Params, Done, Fail>; - readonly name?: string; -} - -export type WithoutAccess<Params extends Required<AccessOptions>> = Omit< - Params, - keyof Required<AccessOptions> ->; - -export const attachWithAccessToken = < - Params extends Required<AccessOptions>, - Done, - Fail extends StandardFailError ->( - options: AttachWithAccessTokenOptions<Params, Done, Fail> -): Effect<WithoutAccess<Params>, Done, Fail> => { - const { effect, name } = options; - - return attach< - WithoutAccess<Params>, - Store<string | null>, - Effect<Params, Done, Fail> - >({ - effect, - source: $AccessToken, - mapParams: (params, accessToken): Params => - ({ - ...params, - accessToken, - } as Params), - name, - }); -}; diff --git a/src/models/fabrics/createMutationWithAccess.ts b/src/models/fabrics/createMutationWithAccess.ts deleted file mode 100644 index 86944649..00000000 --- a/src/models/fabrics/createMutationWithAccess.ts +++ /dev/null @@ -1,51 +0,0 @@ -/* eslint-disable import/no-extraneous-dependencies */ -import { - Contract, - createMutation, - InvalidDataError, - Mutation -} from '@farfetched/core'; -import { Effect } from 'effector'; -import { StaticOrReactive } from '@farfetched/core/src/misc/sourced'; -import { AccessOptions, StandardFailError } from '@/packages'; -import { attachWithAccessToken, WithoutAccess } from './attachWithAccessToken'; -import { attachRemoteOperationWithAccess } from './attachRemoteOperationWithAccess'; - -export interface CreateMutationWithAccessOptions< - Params extends Required<AccessOptions>, - Data, - ContractData extends Data, - Error extends StandardFailError -> { - effect: Effect<Params, Data, Error>; - contract: Contract<Data, ContractData>; - readonly name?: string; - readonly enabled?: StaticOrReactive<boolean>; -} - -export const createMutationWithAccess = < - Params extends Required<AccessOptions>, - Data, - ContractData extends Data, - Error extends StandardFailError ->( - options: CreateMutationWithAccessOptions<Params, Data, ContractData, Error> - ): Mutation<WithoutAccess<Params>, ContractData, Error | InvalidDataError> => { - const { effect, ...rest } = options; - const attached = attachWithAccessToken({ - effect, - }); - const mutation = createMutation< - WithoutAccess<Params>, - Data, - ContractData, - Error - >({ - ...rest, - effect: attached, - }); - - attachRemoteOperationWithAccess(mutation); - - return mutation as any; -}; diff --git a/src/models/fabrics/createQueryWithAccess.ts b/src/models/fabrics/createQueryWithAccess.ts deleted file mode 100644 index 5b127a3b..00000000 --- a/src/models/fabrics/createQueryWithAccess.ts +++ /dev/null @@ -1,79 +0,0 @@ -/* eslint-disable import/no-extraneous-dependencies */ -import { - Contract, - createQuery, - InvalidDataError, - Query, - TwoArgsDynamicallySourcedField, - Validator -} from '@farfetched/core'; -import { StaticOrReactive } from '@farfetched/core/src/misc/sourced'; -import { Serialize } from '@farfetched/core/src/serialization/type'; -import { Effect } from 'effector'; -import { AccessOptions, StandardFailError } from '@/packages'; -import { attachWithAccessToken, WithoutAccess } from './attachWithAccessToken'; -import { attachRemoteOperationWithAccess } from './attachRemoteOperationWithAccess'; - -export interface CreateQueryWithAccessOptions< - Params extends AccessOptions, - Response, - Error extends StandardFailError, - ContractData extends Response, - MappedData, - MapDataSource = void, - ValidationSource = void -> { - readonly effect: Effect<Params, Response, Error>; - readonly contract: Contract<Response, ContractData>; - readonly mapData: TwoArgsDynamicallySourcedField< - ContractData, - Params, - MappedData, - MapDataSource - >; - readonly validate?: Validator<ContractData, Params, ValidationSource>; - readonly name?: string; - readonly enabled?: StaticOrReactive<boolean>; - readonly serialize?: Serialize<MappedData>; -} - -export const createQueryWithAccess = < - Params extends Required<AccessOptions>, - Response, - Error extends StandardFailError, - ContractData extends Response, - MappedData, - MapDataSource = void, - ValidationSource = void ->( - options: CreateQueryWithAccessOptions< - Params, - Response, - Error, - ContractData, - MappedData, - MapDataSource, - ValidationSource - > - ): Query<WithoutAccess<Params>, MappedData, Error | InvalidDataError> => { - const { effect, ...rest } = options; - const attached = attachWithAccessToken({ - effect, - }); - const query = createQuery< - WithoutAccess<Params>, - Response, - Error, - ContractData, - MappedData, - MapDataSource, - ValidationSource - >({ - ...rest, - effect: attached, - } as any); - - attachRemoteOperationWithAccess(query); - - return query as any; -}; diff --git a/src/models/fabrics/index.ts b/src/models/fabrics/index.ts deleted file mode 100644 index b5f626d5..00000000 --- a/src/models/fabrics/index.ts +++ /dev/null @@ -1,13 +0,0 @@ -export { - attachWithAccessToken, - type AttachWithAccessTokenOptions, - type WithoutAccess, -} from './attachWithAccessToken'; -export { - createMutationWithAccess, - type CreateMutationWithAccessOptions, -} from './createMutationWithAccess'; -export { - createQueryWithAccess, - type CreateQueryWithAccessOptions, -} from './createQueryWithAccess'; diff --git a/src/models/groups/index.ts b/src/models/groups/index.ts deleted file mode 100644 index 8ca3a656..00000000 --- a/src/models/groups/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from './types'; -export * from './units'; -export * from './queries'; -export * from './utils'; diff --git a/src/models/groups/init.ts b/src/models/groups/init.ts deleted file mode 100644 index 5cd2d208..00000000 --- a/src/models/groups/init.ts +++ /dev/null @@ -1,82 +0,0 @@ -/* eslint-disable import/no-extraneous-dependencies */ -import { sample } from 'effector-logger'; -import { groupsApi } from '@/api'; -import { closeCreateGroupPopup, closeUpdateGroupPopup } from '../routing'; -import { - createGroupMutation, - getGroupsQuery, - removeGroupMutation, - updateGroupMutation -} from './queries'; -import { - getGroupsFx, - createGroupFx, - removeGroupFx, - updateGroupFx, - GroupsGate, - $GroupsMap -} from './units'; -import { createGroupsMap } from './utils'; - -getGroupsFx.use(groupsApi.getAll); -createGroupFx.use(groupsApi.create); -updateGroupFx.use(groupsApi.update); -removeGroupFx.use(groupsApi.remove); - -sample({ - clock: createGroupMutation.finished.success, - source: getGroupsQuery.$data, - fn: (groups, { result: { data, }, }) => { - return [...groups, data]; - }, - target: getGroupsQuery.$data, -}); - -sample({ - clock: updateGroupMutation.finished.success, - source: getGroupsQuery.$data, - fn: (groups, { result: { data, }, }) => { - return groups.map((group) => { - if (group.id === data.id) { - return data; - } - return group; - }); - }, - target: getGroupsQuery.$data, -}); - -sample({ - clock: removeGroupMutation.finished.success, - source: getGroupsQuery.$data, - fn: (groups, { result: { data, }, params, }) => { - if (!groups || !data) { - return groups; - } - const { id, } = params; - return groups.filter((group) => group.id !== id); - }, - target: getGroupsQuery.$data, -}); - -sample({ - clock: GroupsGate.open, - fn: ({ roomId, }) => roomId, - target: getGroupsQuery.start, -}); - -sample({ - source: getGroupsQuery.$data, - fn: (data) => (data ? createGroupsMap(data) : {}), - target: $GroupsMap, -}); - -sample({ - clock: createGroupMutation.finished.success, - target: closeCreateGroupPopup, -}); - -sample({ - clock: updateGroupMutation.finished.success, - target: closeUpdateGroupPopup, -}); diff --git a/src/models/groups/queries.ts b/src/models/groups/queries.ts deleted file mode 100644 index 560542df..00000000 --- a/src/models/groups/queries.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { createQuery } from '@farfetched/core'; -import { runtypeContract } from '@farfetched/runtypes'; -import { Array, Boolean } from 'runtypes'; -import { StandardFailError } from '@/packages'; -import { - CreateGroupRequest, - UpdateGroupRequest, - RemoveGroupRequest -} from '@/api'; -import { - getStandardSuccessResponse, - StandardResponse, - StandardSuccessResponse -} from '@/types'; -import { dataExtractor, getIsSuccessResponseValidator } from '../utils'; -import { Group, group } from './types'; -import { - createGroupFx, - getGroupsFx, - removeGroupFx, - updateGroupFx -} from './units'; -import { createMutationWithAccess } from '../fabrics'; - -export const getGroupsQuery = createQuery< - number, - StandardResponse<Group[]>, - StandardFailError, - StandardSuccessResponse<Group[]>, - Group[] ->({ - initialData: [], - effect: getGroupsFx, - contract: runtypeContract(getStandardSuccessResponse(Array(group))), - validate: getIsSuccessResponseValidator(), - mapData: dataExtractor, -}); - -export const createGroupMutation = createMutationWithAccess< - CreateGroupRequest, - StandardResponse<Group>, - StandardSuccessResponse<Group>, - StandardFailError ->({ - effect: createGroupFx, - contract: runtypeContract(getStandardSuccessResponse(group)), -}); - -export const updateGroupMutation = createMutationWithAccess< - UpdateGroupRequest, - StandardResponse<Group>, - StandardSuccessResponse<Group>, - StandardFailError ->({ - effect: updateGroupFx, - contract: runtypeContract(getStandardSuccessResponse(group)), -}); - -export const removeGroupMutation = createMutationWithAccess< - RemoveGroupRequest, - StandardResponse<boolean>, - StandardSuccessResponse<boolean>, - StandardFailError ->({ - effect: removeGroupFx, - contract: runtypeContract(getStandardSuccessResponse(Boolean)), -}); diff --git a/src/models/groups/types.ts b/src/models/groups/types.ts deleted file mode 100644 index 2eb3afdb..00000000 --- a/src/models/groups/types.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Record, Number, String, Static } from 'runtypes'; -import { hex } from '@/types'; - -export const group = Record({ - id: Number, - roomId: Number, - name: String, - mainColor: hex, - secondColor: hex, -}); - -export interface Group extends Static<typeof group> {} - -export interface GroupsMap { - [id: number]: Group | undefined; -} diff --git a/src/models/groups/units.ts b/src/models/groups/units.ts deleted file mode 100644 index 9c51257a..00000000 --- a/src/models/groups/units.ts +++ /dev/null @@ -1,49 +0,0 @@ -/* eslint-disable import/no-extraneous-dependencies */ -import { createDomain } from 'effector-logger'; -import { createGate } from 'effector-react'; -import { StandardFailError } from '@/packages'; -import { - CreateGroupRequest, - UpdateGroupRequest, - RemoveGroupRequest, -} from '@/api'; -import { StandardResponse, InRoomRequest } from '@/types'; -import { Group, GroupsMap } from './types'; - -export const GroupsDomain = createDomain('GroupsDomain'); - -export const $GroupsMap = GroupsDomain.store<GroupsMap>( - {}, - { - name: 'GroupsMap', - } -); - -export const getGroupsFx = GroupsDomain.effect< - number, - StandardResponse<Group[]>, - StandardFailError ->('getGroupsFx'); - -export const createGroupFx = GroupsDomain.effect< - CreateGroupRequest, - StandardResponse<Group>, - StandardFailError ->('createGroupFx'); - -export const updateGroupFx = GroupsDomain.effect< - UpdateGroupRequest, - StandardResponse<Group>, - StandardFailError ->('updateGroupFx'); - -export const removeGroupFx = GroupsDomain.effect< - RemoveGroupRequest, - StandardResponse<boolean>, - StandardFailError ->('removeGroupFx'); - -export const GroupsGate = createGate<InRoomRequest>({ - domain: GroupsDomain, - name: 'groupsGate', -}); diff --git a/src/models/groups/utils.ts b/src/models/groups/utils.ts deleted file mode 100644 index 4f37c100..00000000 --- a/src/models/groups/utils.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Group, GroupsMap } from './types'; - -export const createGroupsMap = (groups: Group[]): GroupsMap => { - return Object.values(groups).reduce<GroupsMap>((map, group) => { - map[group.id] = group; - return map; - }, {}); -}; diff --git a/src/models/index.ts b/src/models/index.ts deleted file mode 100644 index 19195074..00000000 --- a/src/models/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -export * from './activities'; -export * from './auth'; -export * from './groups'; -export * from './progress'; -export * from './rooms'; -export * from './routing'; -export * from './tasks'; diff --git a/src/models/init.ts b/src/models/init.ts deleted file mode 100644 index abde190a..00000000 --- a/src/models/init.ts +++ /dev/null @@ -1,7 +0,0 @@ -import './auth/init'; -import './rooms/init'; -import './tasks/init'; -import './groups/init'; -import './progress/init'; -import './activities/init'; -import './routing/init'; diff --git a/src/models/progress/handler.ts b/src/models/progress/handler.ts deleted file mode 100644 index 4e08ce37..00000000 --- a/src/models/progress/handler.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { Progress } from './types'; - -export interface ProgressChange { - readonly groupId: number; - readonly progress: any; -} - -export const changeProgressHandler = ( - state: Progress[], - changes: ProgressChange[] -) => { - const newState: Progress[] = []; - const idsMap = Object.values(changes).reduce<Record<number, ProgressChange>>( - (acc, change) => { - acc[change.groupId] = change; - return acc; - }, - {} - ); - state.forEach((progress) => { - const change = idsMap[progress.groupId]; - if (change) { - const changedProgress = change.progress; - if (changedProgress) { - newState.push(changedProgress); - } - delete idsMap[progress.groupId]; - return; - } - newState.push(progress); - }); - - const rest = Object.values(idsMap); - if (rest.length) { - rest.forEach((change) => newState.push(change.progress)); - } - - return newState; -}; diff --git a/src/models/progress/index.ts b/src/models/progress/index.ts deleted file mode 100644 index 788cd45a..00000000 --- a/src/models/progress/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './types'; -export * from './units'; -export * from './queries'; diff --git a/src/models/progress/init.ts b/src/models/progress/init.ts deleted file mode 100644 index 4078809a..00000000 --- a/src/models/progress/init.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { sample } from 'effector'; -import { progressApi } from '@/api'; -import { - createTaskMutation, - removeTaskMutation, - updateTaskMutation, -} from '../tasks'; -import { getProgressFx, ProgressGate } from './units'; -import { removeGroupMutation, updateGroupMutation } from '../groups'; -import { getProgressQuery } from './queries'; - -getProgressFx.use(progressApi.getAll); - -sample({ - clock: [ - createTaskMutation.finished.success, - updateTaskMutation.finished.success, - removeTaskMutation.finished.success, - updateGroupMutation.finished.success, - removeGroupMutation.finished.success, - ], - fn: ({ params: { roomId } }) => { - return roomId; - }, - target: getProgressQuery.start, -}); - -sample({ - clock: ProgressGate.open, - fn: ({ roomId }) => roomId, - target: getProgressQuery.start, -}); diff --git a/src/models/progress/queries.ts b/src/models/progress/queries.ts deleted file mode 100644 index 983e3d38..00000000 --- a/src/models/progress/queries.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { createQuery } from '@farfetched/core'; -import { runtypeContract } from '@farfetched/runtypes'; -import { Array } from 'runtypes'; -import { StandardFailError } from '@/packages'; -import { - getStandardSuccessResponse, - StandardResponse, - StandardSuccessResponse, -} from '@/types'; -import { getIsSuccessResponseValidator, dataExtractor } from '../utils'; -import { Progress, progress } from './types'; -import { getProgressFx } from './units'; - -export const getProgressQuery = createQuery< - number, - StandardResponse<Progress[]>, - StandardFailError, - StandardSuccessResponse<Progress[]>, - Progress[] ->({ - effect: getProgressFx, - contract: runtypeContract(getStandardSuccessResponse(Array(progress))), - validate: getIsSuccessResponseValidator(), - mapData: dataExtractor, -}); diff --git a/src/models/progress/types.ts b/src/models/progress/types.ts deleted file mode 100644 index 7c79a7fb..00000000 --- a/src/models/progress/types.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { Number, Record, Static } from 'runtypes'; - -export const progress = Record({ - groupId: Number, - completedCount: Number, - totalCount: Number, -}).asReadonly(); - -export interface Progress extends Static<typeof progress> {} diff --git a/src/models/progress/units.ts b/src/models/progress/units.ts deleted file mode 100644 index bd088d23..00000000 --- a/src/models/progress/units.ts +++ /dev/null @@ -1,19 +0,0 @@ -/* eslint-disable import/no-extraneous-dependencies */ -import { createDomain } from 'effector-logger'; -import { createGate } from 'effector-react'; -import { StandardFailError } from '@/packages'; -import { StandardResponse, InRoomRequest } from '@/types'; -import { Progress } from './types'; - -export const ProgressDomain = createDomain('ProgressDomain'); - -export const getProgressFx = ProgressDomain.effect< - number, - StandardResponse<Progress[]>, - StandardFailError ->('getProgressFx'); - -export const ProgressGate = createGate<InRoomRequest>({ - domain: ProgressDomain, - name: 'progressGate', -}); diff --git a/src/models/rooms/index.ts b/src/models/rooms/index.ts deleted file mode 100644 index 4d92e5de..00000000 --- a/src/models/rooms/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './units'; -export * from './types'; -export * from './queries'; diff --git a/src/models/rooms/init.ts b/src/models/rooms/init.ts deleted file mode 100644 index 6d251a1e..00000000 --- a/src/models/rooms/init.ts +++ /dev/null @@ -1,60 +0,0 @@ -/* eslint-disable import/no-extraneous-dependencies */ -import { sample } from 'effector-logger'; -import { roomsApi } from '@/api'; -import { closeCreateRoomPopup, closeUpdateRoomPopup } from '../routing'; -import { - getRoomFx, - getRoomsFx, - createRoomFx, - removeRoomFx, - updateRoomFx, - RoomsGate, - RoomGate -} from './units'; -import { - createRoomMutation, - removeRoomMutation, - getRoomsQuery, - updateRoomMutation, - getRoomQuery -} from './queries'; - -getRoomsFx.use(roomsApi.getAll); -getRoomFx.use(roomsApi.getOne); -removeRoomFx.use(roomsApi.remove); -updateRoomFx.use(roomsApi.update); -createRoomFx.use(roomsApi.create); - -sample({ - clock: [ - removeRoomMutation.finished.success, - updateRoomMutation.finished.success, - createRoomMutation.finished.success - ], - fn: () => ({}), - target: getRoomsQuery.start, -}); - -sample({ - clock: updateRoomMutation.finished.success, - target: closeUpdateRoomPopup, -}); - -sample({ - clock: createRoomMutation.finished.success, - target: closeCreateRoomPopup, -}); - -sample({ - clock: RoomsGate.open, - fn: () => ({}), - target: getRoomsQuery.start, -}); - -sample({ - clock: RoomGate.open, - fn: ({ roomId, }) => roomId, - target: getRoomQuery.start, -}); - -getRoomsQuery.finished.finally.watch(console.log); diff --git a/src/models/rooms/queries.ts b/src/models/rooms/queries.ts deleted file mode 100644 index 3edfc3fe..00000000 --- a/src/models/rooms/queries.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { createQuery } from '@farfetched/core'; -import { runtypeContract } from '@farfetched/runtypes'; -import { Array, Boolean } from 'runtypes'; -import { StandardFailError } from '@/packages'; -import { - CreateRoomRequest, - GetRoomsRequest, - RemoveRoomRequest, - UpdateRoomRequest, -} from '@/api'; -import { - getStandardSuccessResponse, - StandardResponse, - StandardSuccessResponse, -} from '@/types'; -import { dataExtractor, getIsSuccessResponseValidator } from '../utils'; -import { createMutationWithAccess, createQueryWithAccess } from '../fabrics'; -import { room, Room } from './types'; -import { - getRoomFx, - getRoomsFx, - removeRoomFx, - createRoomFx, - updateRoomFx, -} from './units'; - -export const getRoomsQuery = createQueryWithAccess< - GetRoomsRequest, - StandardResponse<Room[]>, - StandardFailError, - StandardSuccessResponse<Room[]>, - Room[] ->({ - effect: getRoomsFx, - contract: runtypeContract(getStandardSuccessResponse(Array(room))), - validate: getIsSuccessResponseValidator(), - mapData: dataExtractor, -}); - -export const getRoomQuery = createQuery< - number, - StandardResponse<Room>, - StandardFailError, - StandardSuccessResponse<Room>, - Room ->({ - effect: getRoomFx, - contract: runtypeContract(getStandardSuccessResponse(room)), - validate: getIsSuccessResponseValidator(), - mapData: dataExtractor, -}); - -export const createRoomMutation = createMutationWithAccess< - CreateRoomRequest, - StandardResponse<Room>, - StandardSuccessResponse<Room>, - StandardFailError ->({ - effect: createRoomFx, - contract: runtypeContract(getStandardSuccessResponse(room)), -}); - -export const updateRoomMutation = createMutationWithAccess< - UpdateRoomRequest, - StandardResponse<Room>, - StandardSuccessResponse<Room>, - StandardFailError ->({ - effect: updateRoomFx, - contract: runtypeContract(getStandardSuccessResponse(room)), -}); - -export const removeRoomMutation = createMutationWithAccess< - RemoveRoomRequest, - StandardResponse<boolean>, - StandardSuccessResponse<boolean>, - StandardFailError ->({ - effect: removeRoomFx, - contract: runtypeContract(getStandardSuccessResponse(Boolean)), -}); diff --git a/src/models/rooms/types.ts b/src/models/rooms/types.ts deleted file mode 100644 index e249d5c7..00000000 --- a/src/models/rooms/types.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { Record, Number, String, Static } from 'runtypes'; - -export const room = Record({ - id: Number, - name: String, - description: String, -}).asReadonly(); - -export interface Room extends Static<typeof room> {} diff --git a/src/models/rooms/units.ts b/src/models/rooms/units.ts deleted file mode 100644 index 48220706..00000000 --- a/src/models/rooms/units.ts +++ /dev/null @@ -1,54 +0,0 @@ -/* eslint-disable import/no-extraneous-dependencies */ -import { createDomain } from 'effector-logger'; -import { createGate } from 'effector-react'; -import { StandardFailError } from '@/packages'; -import { - CreateRoomRequest, - GetRoomsRequest, - RemoveRoomRequest, - UpdateRoomRequest, -} from '@/api'; -import { StandardResponse, InRoomRequest } from '@/types'; -import { Room } from './types'; - -export const RoomsDomain = createDomain('RoomsDomain'); - -export const getRoomsFx = RoomsDomain.effect< - GetRoomsRequest, - StandardResponse<Room[]>, - StandardFailError ->('getRoomsFx'); - -export const getRoomFx = RoomsDomain.effect< - number, - StandardResponse<Room>, - StandardFailError ->('getRoomFx'); - -export const createRoomFx = RoomsDomain.effect< - CreateRoomRequest, - StandardResponse<Room>, - StandardFailError ->('createRoomFx'); - -export const updateRoomFx = RoomsDomain.effect< - UpdateRoomRequest, - StandardResponse<Room>, - StandardFailError ->('updateRoomFx'); - -export const removeRoomFx = RoomsDomain.effect< - RemoveRoomRequest, - StandardResponse<boolean>, - StandardFailError ->('removeRoomFx'); - -export const RoomsGate = createGate({ - domain: RoomsDomain, - name: 'roomsGate', -}); - -export const RoomGate = createGate<InRoomRequest>({ - domain: RoomsDomain, - name: 'roomGate', -}); diff --git a/src/models/routing/index.ts b/src/models/routing/index.ts deleted file mode 100644 index 4a2bff76..00000000 --- a/src/models/routing/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './units'; -export * from './types'; diff --git a/src/models/routing/init.ts b/src/models/routing/init.ts deleted file mode 100644 index 6050b5d3..00000000 --- a/src/models/routing/init.ts +++ /dev/null @@ -1,150 +0,0 @@ -import { sample } from 'effector'; -import { HistoryPushParams, querySync, redirect } from 'atomic-router'; -import { roomRoute, roomsRoute } from '@/routes'; -import { getParams, popups } from '@/const'; -import { - $groupId, - $location, - $popups, - $roomId, - $taskId, - $taskStatus, - closeCreateGroupPopup, - closeCreateRoomPopup, - closeCreateTaskPopup, - closeUpdateGroupPopup, - closeUpdateRoomPopup, - closeUpdateTaskPopup, - controls, - goToState, - removePopup, - router, - saveCurrentLocation, - setState, -} from './units'; - -querySync({ - controls, - source: { - [getParams.popup]: $popups, - }, -}); - -querySync({ - controls, - source: { - [getParams.groupId]: $groupId, - [getParams.taskId]: $taskId, - [getParams.taskStatus]: $taskStatus, - }, - route: roomRoute, -}); - -querySync({ - controls, - source: { - [getParams.roomId]: $roomId, - }, - route: roomsRoute, -}); - -sample({ - clock: removePopup, - source: $popups, - fn: (popups, popup) => { - return popups.replaceAll(popup, ''); - }, - target: $popups, -}); - -sample({ - clock: closeUpdateGroupPopup, - fn: () => popups.updateGroup, - target: removePopup, -}); - -sample({ - clock: closeCreateGroupPopup, - fn: () => popups.createGroup, - target: removePopup, -}); - -sample({ - clock: closeCreateTaskPopup, - fn: () => popups.createTask, - target: removePopup, -}); - -sample({ - clock: closeUpdateTaskPopup, - fn: () => popups.updateTask, - target: removePopup, -}); - -sample({ - clock: closeCreateRoomPopup, - fn: () => popups.createRoom, - target: removePopup, -}); - -sample({ - clock: closeUpdateRoomPopup, - fn: () => popups.updateRoom, - target: removePopup, -}); - -sample({ - clock: setState, - target: $location, -}); - -sample({ - clock: saveCurrentLocation, - source: { path: router.$path, query: router.$query }, - fn: ({ path, query }) => { - return { path, query }; - }, - target: $location, -}); - -sample({ - clock: goToState, - source: $location, - fn: ({ path, query }): Omit<HistoryPushParams, 'history'> => ({ - method: 'replace', - path, - query, - params: {}, - }), - target: router.push, -}); - -sample({ - clock: [closeUpdateGroupPopup, closeCreateGroupPopup], - target: $groupId.reinit!, -}); - -sample({ - clock: [closeCreateTaskPopup, closeUpdateTaskPopup], - target: $taskId.reinit!, -}); - -sample({ - clock: [closeCreateTaskPopup, closeUpdateTaskPopup], - target: $taskId.reinit!, -}); - -sample({ - clock: [closeUpdateTaskPopup], - target: $taskStatus.reinit!, -}); - -sample({ - clock: [closeCreateRoomPopup, closeUpdateRoomPopup], - target: $roomId.reinit!, -}); - -redirect({ - clock: router.routeNotFound, - route: roomsRoute, -}); diff --git a/src/models/routing/types.ts b/src/models/routing/types.ts deleted file mode 100644 index ab260198..00000000 --- a/src/models/routing/types.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { RouteQuery } from 'atomic-router'; - -export interface Location { - readonly path: string; - readonly query: RouteQuery; -} diff --git a/src/models/routing/units.ts b/src/models/routing/units.ts deleted file mode 100644 index 0aed334d..00000000 --- a/src/models/routing/units.ts +++ /dev/null @@ -1,35 +0,0 @@ -// eslint-disable-next-line import/no-extraneous-dependencies -import { createDomain } from 'effector-logger'; -import { createHistoryRouter, createRouterControls } from 'atomic-router'; -import { routes } from '@/routes'; -import { TaskStatus } from '../tasks'; -import { Location } from './types'; - -export const QueriesDomain = createDomain(); - -export const controls = createRouterControls(); -export const router = createHistoryRouter({ - routes, - controls, -}); - -export const $popups = QueriesDomain.store<string>(''); -export const $roomId = QueriesDomain.store<null | number>(null); -export const $taskId = QueriesDomain.store<null | number>(null); -export const $groupId = QueriesDomain.store<null | number>(null); -export const $taskStatus = QueriesDomain.store<null | TaskStatus>(null); -export const $location = QueriesDomain.store<Location>({ - path: '/rooms', - query: {}, -}); - -export const removePopup = QueriesDomain.event<string>(); -export const closeUpdateRoomPopup = QueriesDomain.event(); -export const closeCreateRoomPopup = QueriesDomain.event(); -export const closeCreateTaskPopup = QueriesDomain.event(); -export const closeUpdateTaskPopup = QueriesDomain.event(); -export const closeCreateGroupPopup = QueriesDomain.event(); -export const closeUpdateGroupPopup = QueriesDomain.event(); -export const setState = QueriesDomain.event<Location>(); -export const saveCurrentLocation = QueriesDomain.event(); -export const goToState = QueriesDomain.event(); diff --git a/src/models/tasks/handlers.ts b/src/models/tasks/handlers.ts deleted file mode 100644 index 00ca9fc9..00000000 --- a/src/models/tasks/handlers.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { Task } from './types'; - -export const editTaskHandler = (tasks: Task[], { task }: { task: Task }) => { - return tasks.map((t) => (t.id === task.id ? task : t)); -}; diff --git a/src/models/tasks/index.ts b/src/models/tasks/index.ts deleted file mode 100644 index 788cd45a..00000000 --- a/src/models/tasks/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './types'; -export * from './units'; -export * from './queries'; diff --git a/src/models/tasks/init.ts b/src/models/tasks/init.ts deleted file mode 100644 index 3071bbbd..00000000 --- a/src/models/tasks/init.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { sample } from 'effector'; -import { tasksApi } from '@/api'; -import { - getTasksFx, - getTaskFx, - createTaskFx, - removeTaskFx, - updateTaskFx, - TasksGate, - TaskGate -} from './units'; -import { - createTaskMutation, - getTaskQuery, - getTasksQuery, - removeTaskMutation, - updateTaskMutation -} from './queries'; -import { closeCreateTaskPopup, closeUpdateTaskPopup } from '../routing'; - -getTasksFx.use(tasksApi.getAll); -getTaskFx.use(tasksApi.getOne); -createTaskFx.use(tasksApi.create); -updateTaskFx.use(tasksApi.update); -removeTaskFx.use(tasksApi.remove); - -sample({ - clock: createTaskMutation.finished.success, - source: getTasksQuery.$data, - fn: (tasks, { result: { data, }, }) => { - return [...tasks, data]; - }, - target: getTasksQuery.$data, -}); - -sample({ - clock: updateTaskMutation.finished.success, - source: getTasksQuery.$data, - fn: (tasks, { result: { data, }, }) => { - return tasks.map((task) => (task.id === data.id ? data : task)); - }, - target: getTasksQuery.$data, -}); - -sample({ - clock: removeTaskMutation.finished.success, - source: getTasksQuery.$data, - fn: (tasks, { params, result: { data, }, }) => { - if (!tasks || !data) { - return tasks; - } - return tasks.filter((task) => task.id !== params.id); - }, - target: getTasksQuery.$data, -}); - -sample({ - clock: TasksGate.open, - fn: ({ roomId, }) => roomId, - target: getTasksQuery.start, -}); - -sample({ - clock: TaskGate.open, - target: getTaskQuery.start, -}); - -sample({ - clock: updateTaskMutation.finished.success, - target: closeUpdateTaskPopup, -}); - -sample({ - clock: createTaskMutation.finished.success, - target: closeCreateTaskPopup, -}); diff --git a/src/models/tasks/queries.ts b/src/models/tasks/queries.ts deleted file mode 100644 index 5c08ae72..00000000 --- a/src/models/tasks/queries.ts +++ /dev/null @@ -1,82 +0,0 @@ -import { createQuery } from '@farfetched/core'; -import { runtypeContract } from '@farfetched/runtypes'; -import { Array, Boolean } from 'runtypes'; -import { - getStandardSuccessResponse, - StandardResponse, - StandardSuccessResponse -} from '@/types'; -import { Task, task } from './types'; -import { - createTaskFx, - getTaskFx, - getTasksFx, - removeTaskFx, - updateTaskFx -} from './units'; -import { - GetTaskRequest, - CreateTaskRequest, - UpdateTaskRequest, - RemoveTaskRequest -} from '@/api'; -import { StandardFailError } from '@/packages'; -import { getIsSuccessResponseValidator, dataExtractor } from '../utils'; -import { createMutationWithAccess } from '../fabrics'; - -export const getTasksQuery = createQuery< - number, - StandardResponse<Task[]>, - StandardFailError, - StandardSuccessResponse<Task[]>, - Task[] ->({ - initialData: [], - effect: getTasksFx, - contract: runtypeContract(getStandardSuccessResponse(Array(task))), - validate: getIsSuccessResponseValidator(), - mapData: dataExtractor, -}); - -export const getTaskQuery = createQuery< - GetTaskRequest, - StandardResponse<Task>, - StandardFailError, - StandardSuccessResponse<Task>, - Task ->({ - effect: getTaskFx, - contract: runtypeContract(getStandardSuccessResponse(task)), - validate: getIsSuccessResponseValidator(), - mapData: dataExtractor, -}); - -export const createTaskMutation = createMutationWithAccess< - CreateTaskRequest, - StandardResponse<Task>, - StandardSuccessResponse<Task>, - StandardFailError ->({ - effect: createTaskFx, - contract: runtypeContract(getStandardSuccessResponse(task)), -}); - -export const updateTaskMutation = createMutationWithAccess< - UpdateTaskRequest, - StandardResponse<Task>, - StandardSuccessResponse<Task>, - StandardFailError ->({ - effect: updateTaskFx, - contract: runtypeContract(getStandardSuccessResponse(task)), -}); - -export const removeTaskMutation = createMutationWithAccess< - RemoveTaskRequest, - StandardResponse<boolean>, - StandardSuccessResponse<boolean>, - StandardFailError ->({ - effect: removeTaskFx, - contract: runtypeContract(getStandardSuccessResponse(Boolean)), -}); diff --git a/src/models/tasks/types.ts b/src/models/tasks/types.ts deleted file mode 100644 index 47b24eca..00000000 --- a/src/models/tasks/types.ts +++ /dev/null @@ -1,40 +0,0 @@ -/* eslint-disable sonarjs/no-duplicate-string */ -import { Record, Number, String, Static, Union, Literal } from 'runtypes'; - -export const taskStatus = Union( - Literal('done'), - Literal('in progress'), - Literal('review'), - Literal('ready') -); - -export type TaskStatus = Static<typeof taskStatus>; -export const statuses: TaskStatus[] = [ - 'done', - 'in progress', - 'ready', - 'review', -]; - -export const task = Record({ - id: Number, - groupId: Number, - roomId: Number, - authorId: Number, - status: taskStatus, - content: String, - createdAt: String, -}); - -export interface Task extends Static<typeof task> {} - -export interface GroupedByStatusTasks { - readonly ready: Task[]; - readonly 'in progress': Task[]; - readonly needReview: Task[]; - readonly done: Task[]; -} - -export type StatusNamesStore = { - readonly [key in keyof GroupedByStatusTasks]: TaskStatus; -}; diff --git a/src/models/tasks/units.ts b/src/models/tasks/units.ts deleted file mode 100644 index 76ead42a..00000000 --- a/src/models/tasks/units.ts +++ /dev/null @@ -1,54 +0,0 @@ -/* eslint-disable import/no-extraneous-dependencies */ -import { createDomain } from 'effector-logger'; -import { createGate } from 'effector-react'; -import { StandardFailError } from '@/packages'; -import { StandardResponse, InRoomRequest } from '@/types'; -import { - GetTaskRequest, - CreateTaskRequest, - UpdateTaskRequest, - RemoveTaskRequest, -} from '@/api'; -import { Task } from './types'; - -export const TasksDomain = createDomain('TasksDomain'); - -export const getTasksFx = TasksDomain.effect< - number, - StandardResponse<Task[]>, - StandardFailError ->('getTasksFx'); - -export const getTaskFx = TasksDomain.effect< - GetTaskRequest, - StandardResponse<Task>, - StandardFailError ->('getTaskFx'); - -export const createTaskFx = TasksDomain.effect< - CreateTaskRequest, - StandardResponse<Task>, - StandardFailError ->('createTaskFx'); - -export const updateTaskFx = TasksDomain.effect< - UpdateTaskRequest, - StandardResponse<Task>, - StandardFailError ->('updateTaskFx'); - -export const removeTaskFx = TasksDomain.effect< - RemoveTaskRequest, - StandardResponse<boolean>, - StandardFailError ->('removeTaskFx'); - -export const TasksGate = createGate<InRoomRequest>({ - domain: TasksDomain, - name: 'tasksGate', -}); - -export const TaskGate = createGate<GetTaskRequest>({ - domain: TasksDomain, - name: 'taskGate', -}); diff --git a/src/models/utils/dataExtractor.ts b/src/models/utils/dataExtractor.ts deleted file mode 100644 index 6046b274..00000000 --- a/src/models/utils/dataExtractor.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { StandardSuccessResponse } from '@/types'; - -export const dataExtractor = <T>({ - result, -}: { - result: StandardSuccessResponse<T>; -}): T => { - return result.data; -}; diff --git a/src/models/utils/index.ts b/src/models/utils/index.ts deleted file mode 100644 index b496f44e..00000000 --- a/src/models/utils/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { dataExtractor } from './dataExtractor'; -export { getIsSuccessResponseValidator } from './isSuccessResponse'; diff --git a/src/models/utils/isSuccessResponse.ts b/src/models/utils/isSuccessResponse.ts deleted file mode 100644 index f63f737d..00000000 --- a/src/models/utils/isSuccessResponse.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { Validator } from '@farfetched/core'; -import { StandardResponse, StandardSuccessResponse } from '@/types'; - -export const getIsSuccessResponseValidator = <T>(): Validator< - StandardResponse<T>, - unknown, - void -> => { - return ( - data - ): data is { result: StandardSuccessResponse<T>; params: unknown } => - data.result.errorMessage === null; -}; diff --git a/src/packages/index.ts b/src/packages/index.ts deleted file mode 100644 index 56e4b055..00000000 --- a/src/packages/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './request'; diff --git a/src/packages/request/base/baseFetcher.ts b/src/packages/request/base/baseFetcher.ts deleted file mode 100644 index 18f099a0..00000000 --- a/src/packages/request/base/baseFetcher.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { Path } from '../types'; -import { BaseFetcherOptions } from './types'; - -export abstract class BaseFetcher<I, CO> { - readonly #baseURL: string; - - readonly #credentials?: boolean; - - #instance: I | undefined; - - constructor(options: BaseFetcherOptions) { - const { baseURL, credentials } = options; - - this.#baseURL = baseURL; - this.#credentials = credentials; - } - - get credentials() { - return this.#credentials; - } - - get baseURL() { - if (typeof this.#baseURL === 'undefined') { - throw new Error('baseURL is undefined'); - } - return this.#baseURL; - } - - get instance() { - if (typeof this.#instance === 'undefined') { - throw new Error('baseURL is undefined'); - } - return this.#instance; - } - - set instance(i: I) { - this.#instance = i; - } - - abstract create(options: CO): BaseFetcher<I, CO>; - - createPath(path: Path): string { - const { url, query = {} } = path; - const newURL: Array<string | number> = - typeof url === 'string' || typeof url === 'number' - ? [this.baseURL, url] - : [this.baseURL, ...url]; - const params = new URLSearchParams(query); - const stringParams = params.toString(); - const search = stringParams ? `?${stringParams}` : ''; - return `${newURL.join('/')}${search}`; - } -} diff --git a/src/packages/request/base/index.ts b/src/packages/request/base/index.ts deleted file mode 100644 index ff2699df..00000000 --- a/src/packages/request/base/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './baseFetcher'; -export * from './types'; diff --git a/src/packages/request/base/types.ts b/src/packages/request/base/types.ts deleted file mode 100644 index 338a9ee0..00000000 --- a/src/packages/request/base/types.ts +++ /dev/null @@ -1,4 +0,0 @@ -export interface BaseFetcherOptions { - readonly baseURL: string; - readonly credentials?: boolean; -} diff --git a/src/packages/request/error/index.ts b/src/packages/request/error/index.ts deleted file mode 100644 index 3a0c7b97..00000000 --- a/src/packages/request/error/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './standardFailError'; diff --git a/src/packages/request/error/standardFailError.ts b/src/packages/request/error/standardFailError.ts deleted file mode 100644 index ccd744b6..00000000 --- a/src/packages/request/error/standardFailError.ts +++ /dev/null @@ -1,8 +0,0 @@ -export class StandardFailError extends Error { - readonly statusCode: number; - - constructor(statusCode: number, message: string) { - super(message); - this.statusCode = statusCode; - } -} diff --git a/src/packages/request/fetcher/fetcher.ts b/src/packages/request/fetcher/fetcher.ts deleted file mode 100644 index 9a6b36b8..00000000 --- a/src/packages/request/fetcher/fetcher.ts +++ /dev/null @@ -1,103 +0,0 @@ -import axios, { AxiosInstance } from 'axios'; -import { api } from '@/const'; -import { BaseFetcher, BaseFetcherOptions } from '../base'; -import { BaseRequestOptions, BodyRequestOptions } from './types'; -import { StandardFailError } from '../error'; - -export class Fetcher extends BaseFetcher<AxiosInstance, BaseFetcherOptions> { - constructor(options: BaseFetcherOptions) { - const { baseURL, credentials } = options; - super(options); - super.instance = axios.create({ - baseURL, - withCredentials: credentials, - }); - } - - override create(options: BaseFetcherOptions): Fetcher { - const newURL = this.createPath({ - url: options.baseURL, - }); - return new Fetcher({ - credentials: this.credentials, - ...options, - baseURL: newURL, - }); - } - - async get<R>(options: BaseRequestOptions): Promise<R> { - const { path, accessToken, headers = {} } = options; - const url = this.createPath(path); - try { - const { data } = await this.instance.get(url, { - headers: { - ...headers, - Authorization: `Bearer ${accessToken}`, - }, - }); - return data; - } catch (error) { - Fetcher.#throwError(error); - } - } - - async post<R, B = any>(options: BodyRequestOptions<B>): Promise<R> { - const { path, accessToken, headers = {}, body } = options; - const url = this.createPath(path); - try { - const { data } = await this.instance.post(url, body, { - headers: { - ...headers, - Authorization: `Bearer ${accessToken}`, - }, - }); - return data; - } catch (error) { - Fetcher.#throwError(error); - } - } - - async put<R, B = any>(options: BodyRequestOptions<B>): Promise<R> { - const { path, accessToken, headers = {}, body } = options; - const url = this.createPath(path); - try { - const { data } = await this.instance.put(url, body, { - headers: { - ...headers, - Authorization: `Bearer ${accessToken}`, - }, - }); - return data; - } catch (error) { - Fetcher.#throwError(error); - } - } - - async delete<R>(options: BaseRequestOptions): Promise<R> { - const { path, accessToken, headers = {} } = options; - const url = this.createPath(path); - try { - const { data } = await this.instance.delete(url, { - headers: { - ...headers, - Authorization: `Bearer ${accessToken}`, - }, - }); - return data; - } catch (error) { - Fetcher.#throwError(error); - } - } - - static #throwError(error: any): never { - throw new StandardFailError( - error.response.status!, - error.response.statusText - ); - } -} - -export const fetcher = new Fetcher({ - baseURL: api, - credentials: true, -}); diff --git a/src/packages/request/fetcher/index.ts b/src/packages/request/fetcher/index.ts deleted file mode 100644 index 989a42c1..00000000 --- a/src/packages/request/fetcher/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './fetcher'; -export * from './types'; diff --git a/src/packages/request/fetcher/types.ts b/src/packages/request/fetcher/types.ts deleted file mode 100644 index dc81f471..00000000 --- a/src/packages/request/fetcher/types.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { AccessOptions, Path } from '../types'; - -export interface BaseRequestOptions extends AccessOptions { - readonly path: Path; - readonly headers?: Headers; -} - -export interface BodyRequestOptions<B> extends BaseRequestOptions { - readonly body: B; -} diff --git a/src/packages/request/index.ts b/src/packages/request/index.ts deleted file mode 100644 index ca5d1e7a..00000000 --- a/src/packages/request/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from './fetcher'; -export * from './streamFetcher'; -export * from './error'; -export * from './types'; diff --git a/src/packages/request/streamFetcher/index.ts b/src/packages/request/streamFetcher/index.ts deleted file mode 100644 index 2cdb5c86..00000000 --- a/src/packages/request/streamFetcher/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './streamFetcher'; -export * from './types'; diff --git a/src/packages/request/streamFetcher/streamFetcher.ts b/src/packages/request/streamFetcher/streamFetcher.ts deleted file mode 100644 index be81ee29..00000000 --- a/src/packages/request/streamFetcher/streamFetcher.ts +++ /dev/null @@ -1,47 +0,0 @@ -/* eslint-disable @typescript-eslint/no-unused-vars */ -import { io, Socket } from 'socket.io-client'; -import { api } from '@/const'; -import { BaseFetcher } from '../base'; -import { ConnectionOptions, CallBack } from './types'; - -export class StreamFetcher extends BaseFetcher<Socket, object> { - create(options: object) { - return this; - } - - connect(options: ConnectionOptions): void { - const { onError, accessToken } = options; - const socket = io(this.baseURL, { - auth: { token: accessToken }, - }); - - socket.once('connect_error', () => { - onError(this.connect.bind(this)); - }); - - socket.once('connection', () => { - this.instance = socket; - }); - } - - disconnect(): void { - this.instance.disconnect(); - } - - on<R>(event: string, cb: CallBack<R>): void { - this.instance.on(event, cb); - } - - off<R>(event: string, cb: CallBack<R>): void { - this.instance.off(event, cb); - } - - emit<B extends Array<unknown>>(event: string, body?: B): void { - this.instance.emit(event, body); - } -} - -export const streamFetcher = new StreamFetcher({ - baseURL: api, - credentials: true, -}); diff --git a/src/packages/request/streamFetcher/types.ts b/src/packages/request/streamFetcher/types.ts deleted file mode 100644 index 5ec68f54..00000000 --- a/src/packages/request/streamFetcher/types.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { AccessOptions } from '../types'; - -export type CallBack<Arg> = (arg: Arg) => void; -export type Reconnect = CallBack<ConnectionOptions>; -export type OnError = CallBack<Reconnect>; - -export interface ConnectionOptions extends AccessOptions { - readonly onError: OnError; -} diff --git a/src/packages/request/types.ts b/src/packages/request/types.ts deleted file mode 100644 index 57ae5d32..00000000 --- a/src/packages/request/types.ts +++ /dev/null @@ -1,8 +0,0 @@ -export interface Path { - readonly url: string | number | Array<string | number>; - readonly query?: Record<string, string>; -} - -export interface AccessOptions { - readonly accessToken?: string | null; -} diff --git a/src/pages/LoginPage/LoginPage.module.css b/src/pages/LoginPage/LoginPage.module.css deleted file mode 100644 index 7fee2b98..00000000 --- a/src/pages/LoginPage/LoginPage.module.css +++ /dev/null @@ -1,5 +0,0 @@ -.button { - justify-self: end; - - width: max-content; -} diff --git a/src/pages/LoginPage/LoginPage.module.css.d.ts b/src/pages/LoginPage/LoginPage.module.css.d.ts deleted file mode 100644 index 27385054..00000000 --- a/src/pages/LoginPage/LoginPage.module.css.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -declare const styles: { - readonly button: string; -}; -export = styles; diff --git a/src/pages/LoginPage/LoginPage.tsx b/src/pages/LoginPage/LoginPage.tsx deleted file mode 100644 index d3d0f4d8..00000000 --- a/src/pages/LoginPage/LoginPage.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import * as React from 'react'; -import { Link } from 'atomic-router-react'; -import { Button, Typography } from '@mui/material'; -import { useTranslation } from 'react-i18next'; -import { registrationRoute } from '@/routes'; -import { usePageTitle } from '@/hooks'; -import { CommonProps } from '@/types'; -import { AuthLayout } from '@/layouts'; -import { LoginForm } from '@/components'; - -import styles from './LoginPage.module.css'; - -const LoginPage: React.FC<CommonProps> = ({ className }) => { - const { t } = useTranslation('login'); - usePageTitle(t('title')); - - return ( - <AuthLayout className={className}> - <Typography variant='h3' component='h2' align='center'> - {t('title')} - </Typography> - <LoginForm /> - <Button className={styles.button} to={registrationRoute} component={Link}> - {t('actions.registration')} - </Button> - </AuthLayout> - ); -}; -export default LoginPage; diff --git a/src/pages/LoginPage/index.ts b/src/pages/LoginPage/index.ts deleted file mode 100644 index bcf79128..00000000 --- a/src/pages/LoginPage/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default } from './LoginPage'; diff --git a/src/pages/LoginPage/styles.ts b/src/pages/LoginPage/styles.ts deleted file mode 100644 index 091b238a..00000000 --- a/src/pages/LoginPage/styles.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { Button, styled } from '@mui/material'; - -export const StyledLink = styled(Button)` - justify-self: end; - - width: max-content; -`; diff --git a/src/pages/RegistrationPage/RegistrationPage.module.css b/src/pages/RegistrationPage/RegistrationPage.module.css deleted file mode 100644 index 7fee2b98..00000000 --- a/src/pages/RegistrationPage/RegistrationPage.module.css +++ /dev/null @@ -1,5 +0,0 @@ -.button { - justify-self: end; - - width: max-content; -} diff --git a/src/pages/RegistrationPage/RegistrationPage.module.css.d.ts b/src/pages/RegistrationPage/RegistrationPage.module.css.d.ts deleted file mode 100644 index 27385054..00000000 --- a/src/pages/RegistrationPage/RegistrationPage.module.css.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -declare const styles: { - readonly button: string; -}; -export = styles; diff --git a/src/pages/RegistrationPage/RegistrationPage.tsx b/src/pages/RegistrationPage/RegistrationPage.tsx deleted file mode 100644 index d78d8a85..00000000 --- a/src/pages/RegistrationPage/RegistrationPage.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import * as React from 'react'; -import { Button, Typography } from '@mui/material'; -import { Link } from 'atomic-router-react'; -import { useTranslation } from 'react-i18next'; -import { loginRoute } from '@/routes'; -import { AuthLayout } from '@/layouts'; -import { RegistrationForm } from '@/components'; -import { CommonProps } from '@/types'; -import { usePageTitle } from '@/hooks'; - -import styles from './RegistrationPage.module.css'; - -const RegistrationPage: React.FC<CommonProps> = ({ className }) => { - const { t } = useTranslation('registration'); - - usePageTitle(t('title')); - - return ( - <AuthLayout className={className}> - <Typography variant='h3' component='h2' align='center'> - {t('title')} - </Typography> - <RegistrationForm /> - <Button className={styles.button} to={loginRoute} component={Link}> - {t('actions.login')} - </Button> - </AuthLayout> - ); -}; - -export default RegistrationPage; diff --git a/src/pages/RegistrationPage/index.ts b/src/pages/RegistrationPage/index.ts deleted file mode 100644 index c58da732..00000000 --- a/src/pages/RegistrationPage/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default } from './RegistrationPage'; diff --git a/src/pages/RoomPage/RoomPage.tsx b/src/pages/RoomPage/RoomPage.tsx deleted file mode 100644 index 76162978..00000000 --- a/src/pages/RoomPage/RoomPage.tsx +++ /dev/null @@ -1,40 +0,0 @@ -import * as React from 'react'; -import cn from 'classnames'; -import { useGate } from 'effector-react'; -import { useTranslation } from 'react-i18next'; -import { - TasksGate, - GroupsGate, - ActivityGate, - ProgressGate, - RoomGate, -} from '@/models'; -import { roomRoute } from '@/routes'; -import { MainLayout } from '@/layouts'; -import { usePageTitle, useParam } from '@/hooks'; -import { CommonProps } from '@/types'; -import { AsideBar, RoomHeader, Tasks } from '@/components'; - -import styles from './Rooms.module.css'; - -const RoomPage: React.FC<CommonProps> = (props) => { - const { className } = props; - const { t } = useTranslation('room'); - const roomId = useParam(roomRoute, 'id'); - useGate(RoomGate, { roomId }); - useGate(TasksGate, { roomId }); - useGate(GroupsGate, { roomId }); - useGate(ActivityGate, { roomId }); - useGate(ProgressGate, { roomId }); - usePageTitle(t('title')); - - return ( - <MainLayout className={cn(styles.layout, className)}> - <RoomHeader /> - <Tasks className={styles.tasks} /> - <AsideBar className={styles.aside} /> - </MainLayout> - ); -}; - -export default RoomPage; diff --git a/src/pages/RoomPage/Rooms.module.css b/src/pages/RoomPage/Rooms.module.css deleted file mode 100644 index 3301a987..00000000 --- a/src/pages/RoomPage/Rooms.module.css +++ /dev/null @@ -1,51 +0,0 @@ -.layout { - display: grid; - grid-template-columns: var(--room-page-template-columns); - grid-template-rows: min-content 1fr; - gap: 1em; -} -.tasks { - grid-column: var(--room-page-grid-column); - - height: 100%; -} - -@media (min-width: 1300px) { - .layout { - --room-page-template-columns: 4fr 1fr; - - height: 100vh; - } - - .tasks { - grid-row: 2; - } - - .aside { - grid-row: 1 / -1; - - border-left: 1px solid #d9e0e9; - } -} - -@media (max-width: 1300px) { - .layout { - --room-page-template-columns: 1fr; - } - - .tasks { - --room-page-grid-column: span 2; - } - - .aside { - grid-template-columns: repeat(2, 1fr); - grid-row: 3; - gap: 10px; - } -} - -@media (max-width: 600px) { - .aside { - grid-template-columns: 1fr; - } -} diff --git a/src/pages/RoomPage/Rooms.module.css.d.ts b/src/pages/RoomPage/Rooms.module.css.d.ts deleted file mode 100644 index e33ddbfe..00000000 --- a/src/pages/RoomPage/Rooms.module.css.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -declare const styles: { - readonly layout: string; - readonly tasks: string; - readonly aside: string; -}; -export = styles; diff --git a/src/pages/RoomPage/index.ts b/src/pages/RoomPage/index.ts deleted file mode 100644 index 7e054332..00000000 --- a/src/pages/RoomPage/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default } from './RoomPage'; diff --git a/src/pages/RoomsPage/RoomsPage.tsx b/src/pages/RoomsPage/RoomsPage.tsx deleted file mode 100644 index 6d383fd6..00000000 --- a/src/pages/RoomsPage/RoomsPage.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import * as React from 'react'; -import cn from 'classnames'; -import { useGate } from 'effector-react'; -import { useTranslation } from 'react-i18next'; -import { RoomsGate } from '@/models'; -import { usePageTitle } from '@/hooks'; -import { CommonProps } from '@/types'; -import { MainLayout } from '@/layouts'; -import { RoomList, RoomsHeader } from '@/components'; - -import styles from './RoomsPage.module.css'; - -const RoomsPage: React.FC<CommonProps> = (props) => { - const { className } = props; - const { t } = useTranslation('rooms'); - useGate(RoomsGate); - usePageTitle(t('title')); - - return ( - <MainLayout className={cn(styles.layout, className)}> - <RoomsHeader /> - <RoomList /> - </MainLayout> - ); -}; - -export default RoomsPage; diff --git a/src/pages/RoomsPage/index.ts b/src/pages/RoomsPage/index.ts deleted file mode 100644 index e5550fb3..00000000 --- a/src/pages/RoomsPage/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default } from './RoomsPage'; diff --git a/src/pages/SettingsPage/SettingsPage.module.css.d.ts b/src/pages/SettingsPage/SettingsPage.module.css.d.ts deleted file mode 100644 index bf31a3d6..00000000 --- a/src/pages/SettingsPage/SettingsPage.module.css.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -declare const styles: { - readonly page: string; - readonly header: string; - readonly navigation: string; -}; -export = styles; diff --git a/src/pages/SettingsPage/SettingsPage.tsx b/src/pages/SettingsPage/SettingsPage.tsx deleted file mode 100644 index 0ebfe295..00000000 --- a/src/pages/SettingsPage/SettingsPage.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import * as React from 'react'; -import { Typography } from '@mui/material'; -import { usePageTitle } from '@/hooks'; -import { MainLayout } from '@/layouts'; - -import SettingsPageNavigation from './SettingsPage.module.css'; - -const SettingsPage: React.FC = () => { - usePageTitle('Settings'); - return ( - <MainLayout> - <div className={SettingsPageNavigation.header}> - <Typography component='h2'>Settings</Typography> - </div> - </MainLayout> - ); -}; - -export default SettingsPage; diff --git a/src/pages/SettingsPage/index.ts b/src/pages/SettingsPage/index.ts deleted file mode 100644 index 579720f4..00000000 --- a/src/pages/SettingsPage/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default } from './SettingsPage'; diff --git a/src/pages/index.tsx b/src/pages/index.tsx new file mode 100644 index 00000000..70ee6d7b --- /dev/null +++ b/src/pages/index.tsx @@ -0,0 +1,33 @@ +import { createRoutesView } from 'atomic-router-react'; + +import { loginPage } from './login'; +import { registrationPage } from './registration'; +import { activateAccountPage } from './registration-activate'; +import { thanksRegistrationPage } from './registration-thanks'; +import { roomActivitiesPage } from './room-activities'; +import { roomInvitationPage } from './room-invitation'; +import { roomTagsPage } from './room-tags'; +import { roomTasksPage } from './room-tasks'; +import { roomUsersPage } from './room-users'; +import { roomsPage } from './rooms'; +import { settingsPage } from './settings'; + +const Routes = createRoutesView({ + routes: [ + loginPage, + registrationPage, + thanksRegistrationPage, + activateAccountPage, + roomTagsPage, + roomTasksPage, + roomUsersPage, + roomActivitiesPage, + roomsPage, + roomInvitationPage, + settingsPage + ], +}); + +export const Pages = () => { + return <Routes />; +}; diff --git a/src/pages/login/index.ts b/src/pages/login/index.ts new file mode 100644 index 00000000..03528b2a --- /dev/null +++ b/src/pages/login/index.ts @@ -0,0 +1,17 @@ +import { RouteRecord, createRouteView } from 'atomic-router-react'; +import { lazy } from 'react'; + +import { PageLoader } from '@/shared/ui'; + +import { anonymousRoute, currentRoute } from './model'; + +const Page = lazy(() => import('./page')); + +export const loginPage: RouteRecord<any, any> = { + route: currentRoute, + view: createRouteView({ + route: anonymousRoute, + view: Page, + otherwise: PageLoader, + }), +}; diff --git a/src/pages/login/model.ts b/src/pages/login/model.ts new file mode 100644 index 00000000..fb160f8c --- /dev/null +++ b/src/pages/login/model.ts @@ -0,0 +1,16 @@ +import { sample } from 'effector'; + +import { loginModel } from '@/features/auth'; + +import { routes } from '@/shared/configs'; +import { sessionModel } from '@/shared/models'; + +export const currentRoute = routes.login; +export const anonymousRoute = sessionModel.chainAnonymous(currentRoute, { + otherwise: routes.rooms.base.open, +}); + +sample({ + clock: anonymousRoute.closed, + target: loginModel.form.reset, +}); diff --git a/src/pages/login/page.tsx b/src/pages/login/page.tsx new file mode 100644 index 00000000..26ae2be3 --- /dev/null +++ b/src/pages/login/page.tsx @@ -0,0 +1,49 @@ +import { Typography, Link as MuiLink } from '@mui/material'; +import { Link } from 'atomic-router-react'; +import cn from 'classnames'; +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { AuthLayout } from '@/widgets/page'; + +import { LoginForm } from '@/features/auth'; + +import { routes } from '@/shared/configs'; +import { usePageTitle } from '@/shared/lib'; +import { CommonProps } from '@/shared/types'; +import { PageTitle } from '@/shared/ui'; + +import styles from './styles.module.css'; + +const LoginPage: React.FC<CommonProps> = ({ className, }) => { + const { t, } = useTranslation('login'); + const pageTitle = t('title'); + const createRightNow = t('create_right_now', { + returnObjects: true, + }) as Array<string>; + const hasAccountQuestion = t('has_account_question'); + + usePageTitle(pageTitle); + + return ( + <AuthLayout className={cn(styles.layout, className)}> + <PageTitle + className={styles.title} + title={pageTitle} + extra={ + <Typography className={styles.link}> + <span className={styles.question}>{hasAccountQuestion}</span> + <br /> {createRightNow[0]}{' '} + <MuiLink to={routes.registration.base} component={Link}> + {createRightNow[1]} + </MuiLink>{' '} + {createRightNow[2]} + </Typography> + } + /> + <LoginForm className={styles.form} /> + </AuthLayout> + ); +}; + +export default LoginPage; diff --git a/src/pages/login/styles.module.css b/src/pages/login/styles.module.css new file mode 100644 index 00000000..328c2271 --- /dev/null +++ b/src/pages/login/styles.module.css @@ -0,0 +1,22 @@ +.layout { + justify-items: center; +} + +.form { + width: clamp(200px, 100%, 500px); +} + +.title { + display: flex; + gap: 0; + flex-direction: column; + align-items: center; +} + +.link { + text-align: center; +} + +.question { + font-weight: 700; +} diff --git a/src/pages/login/styles.module.css.d.ts b/src/pages/login/styles.module.css.d.ts new file mode 100644 index 00000000..a4ec9ec6 --- /dev/null +++ b/src/pages/login/styles.module.css.d.ts @@ -0,0 +1,8 @@ +declare const styles: { + readonly form: string; + readonly layout: string; + readonly link: string; + readonly question: string; + readonly title: string; +}; +export = styles; diff --git a/src/pages/registration-activate/index.ts b/src/pages/registration-activate/index.ts new file mode 100644 index 00000000..ab1202cb --- /dev/null +++ b/src/pages/registration-activate/index.ts @@ -0,0 +1,21 @@ +import { RouteRecord, createRouteView } from 'atomic-router-react'; +import { lazy } from 'react'; + +import { PageLoader } from '@/shared/ui'; + +import { anonymousRoute, currentRoute, hiddenRoute } from './model'; + +const Page = lazy(() => import('./page')); + +export const activateAccountPage: RouteRecord<any, any> = { + route: currentRoute, + view: createRouteView({ + route: anonymousRoute, + view: createRouteView({ + route: hiddenRoute, + view: Page, + otherwise: PageLoader, + }), + otherwise: PageLoader, + }), +}; diff --git a/src/pages/registration-activate/model.ts b/src/pages/registration-activate/model.ts new file mode 100644 index 00000000..bd66e77a --- /dev/null +++ b/src/pages/registration-activate/model.ts @@ -0,0 +1,73 @@ +import { createEvent, sample } from 'effector'; +import { CreateSnackbarOptions } from 'effector-mui-snacks'; +import { delay, splitMap } from 'patronum'; + +import { activateAccountModel } from '@/features/auth'; + +import { ActivateParams } from '@/shared/api'; +import { i18n, routes } from '@/shared/configs'; +import { chainInternalRoute, isHttpErrorCode } from '@/shared/lib'; +import { notificationsModel, sessionModel } from '@/shared/models'; + +export const currentRoute = routes.registration.activate; +export const anonymousRoute = sessionModel.chainAnonymous(currentRoute, { + otherwise: routes.rooms.base.open, +}); +export const hiddenRoute = chainInternalRoute(anonymousRoute, { + otherwise: routes.login.open, + isInternal: anonymousRoute.$query.map((query) => Boolean(query.token)), +}); +const tryActivate = createEvent<ActivateParams>(); + +sample({ + clock: hiddenRoute.closed, + target: activateAccountModel.query.reset, +}); + +sample({ + clock: hiddenRoute.opened, + fn: ({ query, }) => query as ActivateParams, + target: tryActivate, +}); + +delay({ + source: tryActivate, + timeout: 500, + target: activateAccountModel.query.start, +}); + +const { userError, serverError, } = splitMap({ + source: activateAccountModel.query.finished.failure, + cases: { + userError: ({ error, }) => { + if (isHttpErrorCode(error, 409)) { + return 'already_activated'; + } + }, + serverError: ({ error, }) => { + return isHttpErrorCode(error, 500) ? 'server_error' : undefined; + }, + }, +}); + +sample({ + clock: userError, + filter: hiddenRoute.$isOpened, + fn: (error) => + ({ + message: i18n.t(`errors.${error}`, { ns: 'activate', }), + color: 'error', + } as CreateSnackbarOptions), + target: notificationsModel.create, +}); + +sample({ + clock: serverError, + filter: hiddenRoute.$isOpened, + fn: () => + ({ + message: i18n.t('errors.default', { ns: 'common', }), + color: 'error', + } as CreateSnackbarOptions), + target: notificationsModel.create, +}); diff --git a/src/pages/registration-activate/page.module.css b/src/pages/registration-activate/page.module.css new file mode 100644 index 00000000..9fdaf593 --- /dev/null +++ b/src/pages/registration-activate/page.module.css @@ -0,0 +1,10 @@ +.container { + justify-content: flex-start; + padding-top: 4em; +} + +.text { + max-width: 400px; + + text-align: center; +} diff --git a/src/pages/registration-activate/page.module.css.d.ts b/src/pages/registration-activate/page.module.css.d.ts new file mode 100644 index 00000000..43458f92 --- /dev/null +++ b/src/pages/registration-activate/page.module.css.d.ts @@ -0,0 +1,5 @@ +declare const styles: { + readonly container: string; + readonly text: string; +}; +export = styles; diff --git a/src/pages/registration-activate/page.tsx b/src/pages/registration-activate/page.tsx new file mode 100644 index 00000000..56017ec8 --- /dev/null +++ b/src/pages/registration-activate/page.tsx @@ -0,0 +1,97 @@ +import { Typography, Link as MUILink, CircularProgress } from '@mui/material'; +import { Link } from 'atomic-router-react'; +import { useUnit } from 'effector-react'; +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { AuthLayout } from '@/widgets/page'; + +import { activateAccountModel } from '@/features/auth'; + +import { routes } from '@/shared/configs'; +import { usePageTitle } from '@/shared/lib'; +import { CommonProps } from '@/shared/types'; +import { Center, PageTitle } from '@/shared/ui'; + +import styles from './page.module.css'; + +const RegistrationThanksPage: React.FC<CommonProps> = (props) => { + const { className, } = props; + const { t, } = useTranslation('activate'); + + const title = t('title'); + + usePageTitle(title); + + return ( + <AuthLayout className={className} classes={{ center: styles.container, }}> + <PageTitle title={title} /> + <Loading /> + <Success /> + <Error /> + </AuthLayout> + ); +}; + +const Loading: React.FC = () => { + const { t, } = useTranslation('activate'); + const loading = useUnit(activateAccountModel.query.$pending); + + if (!loading) { + return null; + } + + const text = t('text', { context: 'loading', }); + + return ( + <Center> + <CircularProgress size={80} /> + <Typography>{text}</Typography> + </Center> + ); +}; + +const Success: React.FC = () => { + const { t, } = useTranslation('activate'); + + const activated = useUnit(activateAccountModel.query.$data); + + if (!activated) { + return null; + } + + const text = t('text', { context: 'success', }); + const navigate = t('actions.navigate'); + + return ( + <> + <Typography className={styles.text}>{text}</Typography> + <MUILink to={routes.login} component={Link}> + {navigate} + </MUILink> + </> + ); +}; + +const Error: React.FC = () => { + const { t, } = useTranslation('activate'); + const error = useUnit(activateAccountModel.query.$error); + + if (!error) { + return null; + } + + const text = t('text', { context: 'fail', }); + const navigate = t('actions.navigate'); + + return ( + <> + <Typography className={styles.text}>{text}</Typography> + <MUILink to={routes.login} component={Link}> + {navigate} + </MUILink> + </> + ); +}; + +export default RegistrationThanksPage; diff --git a/src/pages/registration-thanks/index.ts b/src/pages/registration-thanks/index.ts new file mode 100644 index 00000000..19c7ff93 --- /dev/null +++ b/src/pages/registration-thanks/index.ts @@ -0,0 +1,21 @@ +import { RouteRecord, createRouteView } from 'atomic-router-react'; +import { lazy } from 'react'; + +import { PageLoader } from '@/shared/ui'; + +import { anonymousRoute, currentRoute, hiddenRoute } from './model'; + +const Page = lazy(() => import('./page')); + +export const thanksRegistrationPage: RouteRecord<any, any> = { + route: currentRoute, + view: createRouteView({ + route: anonymousRoute, + view: createRouteView({ + route: hiddenRoute, + view: Page, + otherwise: PageLoader, + }), + otherwise: PageLoader, + }), +}; diff --git a/src/pages/registration-thanks/model.ts b/src/pages/registration-thanks/model.ts new file mode 100644 index 00000000..27346237 --- /dev/null +++ b/src/pages/registration-thanks/model.ts @@ -0,0 +1,37 @@ +import { querySync } from 'atomic-router'; +import { createStore, sample } from 'effector'; + +import { controls, routes } from '@/shared/configs'; +import { chainInternalRoute } from '@/shared/lib'; +import { internalRoutingModel, sessionModel } from '@/shared/models'; + +export const currentRoute = routes.registration.thanks; +export const anonymousRoute = sessionModel.chainAnonymous(currentRoute, { + otherwise: routes.rooms.base.open, +}); +export const hiddenRoute = chainInternalRoute(anonymousRoute, { + otherwise: routes.login.open, + isInternal: internalRoutingModel.$internalRoute.$flag, +}); + +export const $username = createStore(''); +export const $email = createStore(''); + +/** + * @todo Add guard for redirect from this route if user was not redirected from registration page + */ + +querySync({ + source: { + email: $email, + username: $username, + }, + route: hiddenRoute, + clock: hiddenRoute.opened, + controls, +}); + +sample({ + clock: hiddenRoute.closed, + target: internalRoutingModel.$internalRoute.disable, +}); diff --git a/src/pages/registration-thanks/page.module.css b/src/pages/registration-thanks/page.module.css new file mode 100644 index 00000000..9fdaf593 --- /dev/null +++ b/src/pages/registration-thanks/page.module.css @@ -0,0 +1,10 @@ +.container { + justify-content: flex-start; + padding-top: 4em; +} + +.text { + max-width: 400px; + + text-align: center; +} diff --git a/src/pages/registration-thanks/page.module.css.d.ts b/src/pages/registration-thanks/page.module.css.d.ts new file mode 100644 index 00000000..43458f92 --- /dev/null +++ b/src/pages/registration-thanks/page.module.css.d.ts @@ -0,0 +1,5 @@ +declare const styles: { + readonly container: string; + readonly text: string; +}; +export = styles; diff --git a/src/pages/registration-thanks/page.tsx b/src/pages/registration-thanks/page.tsx new file mode 100644 index 00000000..20dfc679 --- /dev/null +++ b/src/pages/registration-thanks/page.tsx @@ -0,0 +1,45 @@ +import { Typography, Link as MUILink } from '@mui/material'; +import { Link } from 'atomic-router-react'; +import { useUnit } from 'effector-react'; +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { AuthLayout } from '@/widgets/page'; + +import { routes } from '@/shared/configs'; +import { usePageTitle } from '@/shared/lib'; +import { CommonProps } from '@/shared/types'; +import { PageTitle } from '@/shared/ui'; + +import { $email, $username } from './model'; +import styles from './page.module.css'; + +const RegistrationThanksPage: React.FC<CommonProps> = (props) => { + const { className, } = props; + const { t, } = useTranslation('thanks'); + + const [username, email] = useUnit([$username, $email]); + + const title = t('title'); + const titleLong = t('title', { context: 'long', username, }); + const content = t('content', { email, returnObjects: true, }) as string[]; + const navigate = t('actions.navigate'); + + usePageTitle(title); + + return ( + <AuthLayout className={className} classes={{ center: styles.container, }}> + <PageTitle title={titleLong} /> + <Typography className={styles.text}> + {content[0]} + <b>{email}</b> + {content[1]} + </Typography> + <MUILink to={routes.login} component={Link}> + {navigate} + </MUILink> + </AuthLayout> + ); +}; + +export default RegistrationThanksPage; diff --git a/src/pages/registration/index.ts b/src/pages/registration/index.ts new file mode 100644 index 00000000..cb51fbe0 --- /dev/null +++ b/src/pages/registration/index.ts @@ -0,0 +1,17 @@ +import { RouteRecord, createRouteView } from 'atomic-router-react'; +import { lazy } from 'react'; + +import { PageLoader } from '@/shared/ui'; + +import { currentRoute, anonymousRoute } from './model'; + +const Page = lazy(() => import('./page')); + +export const registrationPage: RouteRecord<any, any> = { + route: currentRoute, + view: createRouteView({ + route: anonymousRoute, + view: Page, + otherwise: PageLoader, + }), +}; diff --git a/src/pages/registration/model.ts b/src/pages/registration/model.ts new file mode 100644 index 00000000..557d613a --- /dev/null +++ b/src/pages/registration/model.ts @@ -0,0 +1,33 @@ +import { redirect } from 'atomic-router'; +import { sample } from 'effector'; + +import { registrationModel } from '@/features/auth'; + +import { routes } from '@/shared/configs'; +import { internalRoutingModel, sessionModel } from '@/shared/models'; + +export const currentRoute = routes.registration.base; +export const anonymousRoute = sessionModel.chainAnonymous(currentRoute, { + otherwise: routes.rooms.base.open, +}); + +sample({ + clock: anonymousRoute.closed, + target: registrationModel.form.reset, +}); + +sample({ + clock: registrationModel.mutation.finished.success, + target: internalRoutingModel.$internalRoute.enable, +}); + +redirect({ + clock: registrationModel.mutation.finished.success, + query: ({ params, }) => { + return { + email: params.email, + username: params.username, + }; + }, + route: routes.registration.thanks, +}); diff --git a/src/pages/registration/page.tsx b/src/pages/registration/page.tsx new file mode 100644 index 00000000..d4ca35fb --- /dev/null +++ b/src/pages/registration/page.tsx @@ -0,0 +1,50 @@ +import { Link as MuiLink, Typography } from '@mui/material'; +import { Link } from 'atomic-router-react'; +import cn from 'classnames'; +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { AuthLayout } from '@/widgets/page'; + +import { RegistrationForm } from '@/features/auth'; + +import { routes } from '@/shared/configs'; +import { usePageTitle } from '@/shared/lib'; +import { CommonProps } from '@/shared/types'; +import { PageTitle } from '@/shared/ui'; + +import styles from './styles.module.css'; + +const RegistrationPage: React.FC<CommonProps> = (props) => { + const { className, } = props; + const { t, } = useTranslation('registration'); + const pageTitle = t('title'); + const loginRightNow = t('login_right_now', { + returnObjects: true, + }) as Array<string>; + const hasAccountQuestion = t('has_account_question'); + + usePageTitle(pageTitle); + + return ( + <AuthLayout className={cn(styles.layout, className)}> + <PageTitle + className={styles.title} + title={pageTitle} + extra={ + <Typography className={styles.link}> + <span className={styles.question}>{hasAccountQuestion}</span> + <br /> {loginRightNow[0]}{' '} + <MuiLink to={routes.login} component={Link}> + {loginRightNow[1]} + </MuiLink>{' '} + {loginRightNow[2]} + </Typography> + } + /> + <RegistrationForm className={styles.form} /> + </AuthLayout> + ); +}; + +export default RegistrationPage; diff --git a/src/pages/registration/styles.module.css b/src/pages/registration/styles.module.css new file mode 100644 index 00000000..328c2271 --- /dev/null +++ b/src/pages/registration/styles.module.css @@ -0,0 +1,22 @@ +.layout { + justify-items: center; +} + +.form { + width: clamp(200px, 100%, 500px); +} + +.title { + display: flex; + gap: 0; + flex-direction: column; + align-items: center; +} + +.link { + text-align: center; +} + +.question { + font-weight: 700; +} diff --git a/src/pages/registration/styles.module.css.d.ts b/src/pages/registration/styles.module.css.d.ts new file mode 100644 index 00000000..a4ec9ec6 --- /dev/null +++ b/src/pages/registration/styles.module.css.d.ts @@ -0,0 +1,8 @@ +declare const styles: { + readonly form: string; + readonly layout: string; + readonly link: string; + readonly question: string; + readonly title: string; +}; +export = styles; diff --git a/src/pages/room-activities/index.ts b/src/pages/room-activities/index.ts new file mode 100644 index 00000000..df76b321 --- /dev/null +++ b/src/pages/room-activities/index.ts @@ -0,0 +1,20 @@ +import { RouteRecord, createRouteView } from 'atomic-router-react'; +import { lazy } from 'react'; + +import { RoomLayout } from '@/widgets/rooms'; + +import { PageLoader } from '@/shared/ui'; + +import { authorizedRoute, currentRoute } from './model'; + +const Page = lazy(() => import('./page')); + +export const roomActivitiesPage: RouteRecord<any, any> = { + route: currentRoute, + view: createRouteView<any, any, any>({ + route: authorizedRoute, + view: Page, + otherwise: PageLoader, + }), + layout: RoomLayout, +}; diff --git a/src/pages/room-activities/model.ts b/src/pages/room-activities/model.ts new file mode 100644 index 00000000..9dc2df49 --- /dev/null +++ b/src/pages/room-activities/model.ts @@ -0,0 +1,122 @@ +import { querySync } from 'atomic-router'; +import { createStore, createEvent, sample } from 'effector'; + +import { activitiesFiltersModel } from '@/features/activities'; + +import { + activitiesInRoomModel, + activityActionsModel, + activitySpheresModel +} from '@/entities/activities'; +import { roomsModel } from '@/entities/rooms'; +import { usersInRoomModel } from '@/entities/users'; + +import { GetActivitiesInRoomParams } from '@/shared/api'; +import { controls, getParams, routes } from '@/shared/configs'; +import { sessionModel } from '@/shared/models'; + +export const currentRoute = routes.room.activities; +export const authorizedRoute = sessionModel.chainAuthorized(currentRoute, { + otherwise: routes.login.open, +}); + +const $page = createStore<null | string>(null); +export const pageChanged = createEvent<null | number>(); + +const { fields, formValidated, reset, $values, } = activitiesFiltersModel.form; + +const formApplied = createEvent<void>(); + +const queries = [ + activitiesInRoomModel.query, + usersInRoomModel.query, + roomsModel.query, + activityActionsModel.query, + activitySpheresModel.query +]; +const sorting = { + by: 'createdAt', + type: 'desc', +} as const; + +sample({ + clock: [formValidated, reset], + target: formApplied, +}); + +sample({ + clock: pageChanged, + fn: (page) => page as string | null, + target: $page, +}); + +sample({ + clock: formApplied, + fn: () => null, + target: $page, +}); + +sample({ + clock: [formApplied, pageChanged], + source: { + params: authorizedRoute.$params, + page: $page, + values: $values, + }, + fn: ({ params, values, page, }): GetActivitiesInRoomParams => { + return { + roomId: params.id, + ...sorting, + ...values, + page: page ? Number(page) : 1, + }; + }, + target: activitiesInRoomModel.query.start, +}); + +sample({ + clock: authorizedRoute.opened, + fn: ({ params, query, }): GetActivitiesInRoomParams => ({ + roomId: params.id, + activistIds: query[getParams.userId], + actionIds: query[getParams.actionId], + after: query[getParams.after], + before: query[getParams.before], + sphereIds: query[getParams.sphereId], + count: query[getParams.count], + page: query[getParams.page], + ...sorting, + }), + target: queries.map((query) => query.start), +}); + +sample({ + clock: authorizedRoute.closed, + target: reset, +}); + +sample({ + clock: authorizedRoute.closed, + target: queries.map((query) => query.reset), +}); + +querySync({ + controls, + source: { + [getParams.page]: $page, + }, + route: authorizedRoute, +}); + +querySync({ + controls, + source: { + [getParams.userId]: fields.activistIds.$value, + [getParams.actionId]: fields.actionIds.$value, + [getParams.after]: fields.after.$value, + [getParams.before]: fields.before.$value, + [getParams.sphereId]: fields.sphereIds.$value, + }, + clock: formApplied, + route: authorizedRoute, +}); diff --git a/src/pages/room-activities/page.module.css b/src/pages/room-activities/page.module.css new file mode 100644 index 00000000..7af1457b --- /dev/null +++ b/src/pages/room-activities/page.module.css @@ -0,0 +1,10 @@ +.wrapper { + display: grid; + gap: 1.5em; + + padding: 0; +} + +.pagination { + justify-self: center; +} diff --git a/src/pages/room-activities/page.module.css.d.ts b/src/pages/room-activities/page.module.css.d.ts new file mode 100644 index 00000000..de7dfb85 --- /dev/null +++ b/src/pages/room-activities/page.module.css.d.ts @@ -0,0 +1,5 @@ +declare const styles: { + readonly pagination: string; + readonly wrapper: string; +}; +export = styles; diff --git a/src/pages/room-activities/page.tsx b/src/pages/room-activities/page.tsx new file mode 100644 index 00000000..75ecc90c --- /dev/null +++ b/src/pages/room-activities/page.tsx @@ -0,0 +1,28 @@ +import { Container } from '@mui/material'; +import cn from 'classnames'; +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { ActivitiesFilters } from '@/features/activities'; + +import { CommonProps } from '@/shared/types'; +import { SectionHeader } from '@/shared/ui'; + +import styles from './page.module.css'; +import { ActivityList } from './ui'; + +const ActivitiesPage: React.FC<CommonProps> = React.memo((props) => { + const { className, } = props; + const { t, } = useTranslation('room-activities'); + + const title = t('title'); + + return ( + <Container className={cn(styles.wrapper, className)}> + <SectionHeader title={title} actions={<ActivitiesFilters />} /> + <ActivityList /> + </Container> + ); +}); + +export default ActivitiesPage; diff --git a/src/pages/room-activities/ui/activities-pagination/activities-pagination.tsx b/src/pages/room-activities/ui/activities-pagination/activities-pagination.tsx new file mode 100644 index 00000000..8bc8eed3 --- /dev/null +++ b/src/pages/room-activities/ui/activities-pagination/activities-pagination.tsx @@ -0,0 +1,44 @@ +import { Pagination, PaginationItem } from '@mui/material'; +import { useUnit } from 'effector-react'; +import * as React from 'react'; + +import { activitiesInRoomModel } from '@/entities/activities'; + +import { getParams } from '@/shared/configs'; +import { useQueryParam } from '@/shared/lib'; +import { CommonProps } from '@/shared/types'; + +import { pageChanged } from '../../model'; + +export interface ActivitiesPaginationProps extends CommonProps {} + +export const ActivitiesPagination: React.FC<ActivitiesPaginationProps> = ( + props +) => { + const { className, } = props; + + const onPageChanged = useUnit(pageChanged); + const hasItems = useUnit(activitiesInRoomModel.$hasItems); + const pageCount = useUnit(activitiesInRoomModel.$pageCount); + const page = parseInt(useQueryParam(getParams.page, '1'), 10); + + return hasItems ? ( + <Pagination + className={className} + count={pageCount} + page={page} + onChange={(_, page) => { + window.scrollTo({ + left: 0, + top: 0, + }); + onPageChanged(page); + }} + color='primary' + size='large' + renderItem={(item) => { + return <PaginationItem {...item} role='link' />; + }} + /> + ) : null; +}; diff --git a/src/pages/room-activities/ui/activities-pagination/index.ts b/src/pages/room-activities/ui/activities-pagination/index.ts new file mode 100644 index 00000000..a28a5ad4 --- /dev/null +++ b/src/pages/room-activities/ui/activities-pagination/index.ts @@ -0,0 +1,4 @@ +export { + ActivitiesPagination, + type ActivitiesPaginationProps +} from './activities-pagination'; diff --git a/src/pages/room-activities/ui/activity-list/activity-list.module.css b/src/pages/room-activities/ui/activity-list/activity-list.module.css new file mode 100644 index 00000000..e69de29b diff --git a/src/pages/room-activities/ui/activity-list/activity-list.module.css.d.ts b/src/pages/room-activities/ui/activity-list/activity-list.module.css.d.ts new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/src/pages/room-activities/ui/activity-list/activity-list.module.css.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/src/pages/room-activities/ui/activity-list/activity-list.tsx b/src/pages/room-activities/ui/activity-list/activity-list.tsx new file mode 100644 index 00000000..625a5e3e --- /dev/null +++ b/src/pages/room-activities/ui/activity-list/activity-list.tsx @@ -0,0 +1,68 @@ +import ReplayIcon from '@mui/icons-material/Replay'; +import { useUnit } from 'effector-react'; +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { + SkeletonActivityListItem, + ActivityListItem, + activitiesInRoomModel +} from '@/entities/activities'; + +import { routes } from '@/shared/configs'; +import { useParam } from '@/shared/lib'; +import { CommonProps } from '@/shared/types'; +import { FriendlyList, TextWithAction } from '@/shared/ui'; + +import { ActivitiesPagination } from '../activities-pagination'; + +export interface ActivityListProps extends CommonProps {} + +export const ActivityList: React.FC<ActivityListProps> = (props) => { + const { className, } = props; + const { t, } = useTranslation('activities'); + + const emptyText = t('list.empty_text'); + + const hasItems = useUnit(activitiesInRoomModel.$hasItems); + + return ( + <FriendlyList + className={className} + $query={activitiesInRoomModel.query} + getData={(data) => data.items} + getKey={(item) => item.id} + skeletonsCount={50} + ErrorComponent={Error} + ItemComponent={ActivityListItem} + SkeletonComponent={SkeletonActivityListItem} + emptyText={emptyText} + slots={{ + after: hasItems ? <ActivitiesPagination /> : null, + }} + /> + ); +}; + +const Error: React.FC = () => { + const { t, } = useTranslation('activities'); + + const actionText = t('actions.retry', { ns: 'common', }); + const text = t('actions.retry_actions.text'); + + const roomId = useParam(routes.room.tasks, 'id'); + const start = useUnit(activitiesInRoomModel.query.start); + + const onRetry = React.useCallback(() => { + start({ roomId, }); + }, [roomId]); + + return ( + <TextWithAction + actionText={actionText} + text={text} + onClick={onRetry} + icon={<ReplayIcon />} + /> + ); +}; diff --git a/src/pages/room-activities/ui/activity-list/index.ts b/src/pages/room-activities/ui/activity-list/index.ts new file mode 100644 index 00000000..b68095a5 --- /dev/null +++ b/src/pages/room-activities/ui/activity-list/index.ts @@ -0,0 +1 @@ +export { ActivityList, type ActivityListProps } from './activity-list'; diff --git a/src/pages/room-activities/ui/index.ts b/src/pages/room-activities/ui/index.ts new file mode 100644 index 00000000..f30df2b1 --- /dev/null +++ b/src/pages/room-activities/ui/index.ts @@ -0,0 +1 @@ +export * from './activity-list'; diff --git a/src/pages/room-invitation/index.ts b/src/pages/room-invitation/index.ts new file mode 100644 index 00000000..cec5b274 --- /dev/null +++ b/src/pages/room-invitation/index.ts @@ -0,0 +1,21 @@ +import { RouteRecord, createRouteView } from 'atomic-router-react'; +import { lazy } from 'react'; + +import { PageLoader } from '@/shared/ui'; + +import { authorizedRoute, currentRoute, hiddenRoute } from './model'; + +const Page = lazy(() => import('./page')); + +export const roomInvitationPage: RouteRecord<any, any> = { + route: currentRoute, + view: createRouteView({ + route: authorizedRoute, + view: createRouteView({ + route: hiddenRoute, + view: Page, + otherwise: PageLoader, + }), + otherwise: PageLoader, + }), +}; diff --git a/src/pages/room-invitation/model.ts b/src/pages/room-invitation/model.ts new file mode 100644 index 00000000..867af190 --- /dev/null +++ b/src/pages/room-invitation/model.ts @@ -0,0 +1,55 @@ +import { sample } from 'effector'; + +import { + approveInvitationModel, + rejectInvitationModel +} from '@/features/invitation'; + +import { invitationViaTokenModel } from '@/entities/invitations'; + +import { routes } from '@/shared/configs'; +import { chainInternalRoute } from '@/shared/lib'; +import { sessionModel } from '@/shared/models'; + +export const currentRoute = routes.rooms.invite; +export const authorizedRoute = sessionModel.chainAuthorized(currentRoute, { + otherwise: routes.login.open, +}); + +export const hiddenRoute = chainInternalRoute(authorizedRoute, { + otherwise: routes.rooms.base.open, + isInternal: authorizedRoute.$query.map((query) => Boolean(query.token)), +}); + +sample({ + clock: hiddenRoute.opened, + fn: ({ query, }) => { + return { token: query.token, }; + }, + target: invitationViaTokenModel.query.start, +}); + +sample({ + clock: hiddenRoute.closed, + target: invitationViaTokenModel.query.reset, +}); + +sample({ + clock: invitationViaTokenModel.query.finished.failure, + target: routes.rooms.base.open, +}); + +sample({ + clock: [approveInvitationModel.mutation.finished.success], + source: invitationViaTokenModel.query.$data, + filter: Boolean, + fn: (invitation) => ({ id: invitation.room.id, }), + target: routes.room.tasks.open, +}); + +sample({ + clock: [rejectInvitationModel.mutation.finished.success], + source: invitationViaTokenModel.query.$data, + filter: Boolean, + target: routes.rooms.base.open, +}); diff --git a/src/pages/room-invitation/page.tsx b/src/pages/room-invitation/page.tsx new file mode 100644 index 00000000..e30d6e9c --- /dev/null +++ b/src/pages/room-invitation/page.tsx @@ -0,0 +1,61 @@ +import cn from 'classnames'; +import { useUnit } from 'effector-react'; +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { InvitationCard } from '@/widgets/invitations'; +import { MainHeader } from '@/widgets/page'; + +import { + SkeletonInvitationCard, + invitationViaTokenModel +} from '@/entities/invitations'; + +import { usePageTitle } from '@/shared/lib'; +import { CommonProps } from '@/shared/types'; +import { Center, Layout } from '@/shared/ui'; + +import styles from './styles.module.css'; + + +const RoomsPage: React.FC<CommonProps> = (props) => { + const { className, } = props; + const { t, } = useTranslation('room-invitation'); + const title = t('title'); + usePageTitle(title); + + return ( + <Layout + className={cn(styles.layout, className)} + slots={{ + header: <MainHeader />, + }}> + <Center> + <Loading /> + <Result /> + </Center> + </Layout> + ); +}; + +const Loading: React.FC = () => { + const loaded = useUnit(invitationViaTokenModel.$loaded); + + if (loaded) { + return null; + } + + return <SkeletonInvitationCard />; +}; + +const Result: React.FC = () => { + const invitation = useUnit(invitationViaTokenModel.query.$data); + + if (!invitation) { + return null; + } + + return <InvitationCard {...invitation} />; +}; + +export default RoomsPage; diff --git a/src/pages/RoomsPage/RoomsPage.module.css b/src/pages/room-invitation/styles.module.css similarity index 100% rename from src/pages/RoomsPage/RoomsPage.module.css rename to src/pages/room-invitation/styles.module.css diff --git a/src/layouts/MainLayout/MainLayout.module.css.d.ts b/src/pages/room-invitation/styles.module.css.d.ts similarity index 100% rename from src/layouts/MainLayout/MainLayout.module.css.d.ts rename to src/pages/room-invitation/styles.module.css.d.ts diff --git a/src/pages/room-tags/index.ts b/src/pages/room-tags/index.ts new file mode 100644 index 00000000..cd6791f8 --- /dev/null +++ b/src/pages/room-tags/index.ts @@ -0,0 +1,20 @@ +import { RouteRecord, createRouteView } from 'atomic-router-react'; +import { lazy } from 'react'; + +import { RoomLayout } from '@/widgets/rooms'; + +import { PageLoader } from '@/shared/ui'; + +import { currentRoute, authorizedRoute } from './model'; + +const Page = lazy(() => import('./page')); + +export const roomTagsPage: RouteRecord<any, any> = { + route: currentRoute, + view: createRouteView<any, any, any>({ + route: authorizedRoute, + view: Page, + otherwise: PageLoader, + }), + layout: RoomLayout, +}; diff --git a/src/pages/room-tags/model.ts b/src/pages/room-tags/model.ts new file mode 100644 index 00000000..1c8e292f --- /dev/null +++ b/src/pages/room-tags/model.ts @@ -0,0 +1,18 @@ +import { sample } from 'effector'; + +import { roomsModel } from '@/entities/rooms'; +import { tagsModel } from '@/entities/tags'; + +import { routes } from '@/shared/configs'; +import { sessionModel } from '@/shared/models'; + +export const currentRoute = routes.room.tags; +export const authorizedRoute = sessionModel.chainAuthorized(currentRoute, { + otherwise: routes.login.open, +}); + +sample({ + clock: authorizedRoute.opened, + fn: ({ params, }) => ({ roomId: params.id, }), + target: [tagsModel.query.start, roomsModel.query.start], +}); diff --git a/src/pages/room-tags/page.module.css b/src/pages/room-tags/page.module.css new file mode 100644 index 00000000..8bd69f6a --- /dev/null +++ b/src/pages/room-tags/page.module.css @@ -0,0 +1,6 @@ +.container { + display: grid; + gap: 1.5em; + + padding: 0; +} diff --git a/src/pages/room-tags/page.module.css.d.ts b/src/pages/room-tags/page.module.css.d.ts new file mode 100644 index 00000000..4a355a77 --- /dev/null +++ b/src/pages/room-tags/page.module.css.d.ts @@ -0,0 +1,4 @@ +declare const styles: { + readonly container: string; +}; +export = styles; diff --git a/src/pages/room-tags/page.tsx b/src/pages/room-tags/page.tsx new file mode 100644 index 00000000..291a4ce7 --- /dev/null +++ b/src/pages/room-tags/page.tsx @@ -0,0 +1,39 @@ +import { Container } from '@mui/material'; +import cn from 'classnames'; +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { Popups, PopupsProps } from '@/widgets/page'; + +import { CreateTag, OpenCreateTagForm, UpdateTag } from '@/features/tags'; + +import { popupsMap } from '@/shared/configs'; +import { CommonProps } from '@/shared/types'; +import { SectionHeader } from '@/shared/ui'; + +import styles from './page.module.css'; +import { TagsList } from './ui'; + +export interface TagsPageProps extends CommonProps {} + +const popupMap: PopupsProps['popupMap'] = { + [popupsMap.createTag]: CreateTag, + [popupsMap.updateTag]: UpdateTag, +}; + +const TagsPage: React.FC<TagsPageProps> = React.memo(function TagsPage(props) { + const { className, } = props; + const { t, } = useTranslation('room-tags'); + + const title = t('title'); + + return ( + <Container className={cn(styles.container, className)}> + <SectionHeader title={title} actions={<OpenCreateTagForm />} /> + <TagsList /> + <Popups popupMap={popupMap} /> + </Container> + ); +}); + +export default TagsPage; diff --git a/src/pages/room-tags/ui/index.ts b/src/pages/room-tags/ui/index.ts new file mode 100644 index 00000000..437a3d57 --- /dev/null +++ b/src/pages/room-tags/ui/index.ts @@ -0,0 +1 @@ +export * from './tags-list'; diff --git a/src/pages/room-tags/ui/tags-list/index.ts b/src/pages/room-tags/ui/tags-list/index.ts new file mode 100644 index 00000000..42657803 --- /dev/null +++ b/src/pages/room-tags/ui/tags-list/index.ts @@ -0,0 +1 @@ +export { TagsList } from './tags-list'; diff --git a/src/pages/room-tags/ui/tags-list/tags-list.tsx b/src/pages/room-tags/ui/tags-list/tags-list.tsx new file mode 100644 index 00000000..7869df6b --- /dev/null +++ b/src/pages/room-tags/ui/tags-list/tags-list.tsx @@ -0,0 +1,58 @@ +import ReplayIcon from '@mui/icons-material/Replay'; +import { useUnit } from 'effector-react'; +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { TagListItem } from '@/widgets/tags'; + +import { tagsModel, SkeletonTagListItem } from '@/entities/tags'; + +import { routes } from '@/shared/configs'; +import { useParam } from '@/shared/lib'; +import { CommonProps } from '@/shared/types'; +import { FriendlyList, TextWithAction } from '@/shared/ui'; + +export const TagsList: React.FC<CommonProps> = (props) => { + const { className, } = props; + + const { t, } = useTranslation('room-tags'); + + const emptyText = t('list.empty_text'); + + return ( + <FriendlyList + className={className} + $query={tagsModel.query} + getKey={(item) => item.id} + ItemComponent={TagListItem} + SkeletonComponent={SkeletonTagListItem} + skeletonsCount={15} + ErrorComponent={Error} + emptyText={emptyText} + /> + ); +}; + +const Error: React.FC = () => { + const { t, } = useTranslation('room-tags'); + + const actionText = t('actions.retry', { ns: 'common', }); + const text = t('actions.retry_tags.text'); + + const start = useUnit(tagsModel.query.start); + + const roomId = useParam(routes.room.tags, 'id'); + + const onRetry = () => { + start({ roomId, }); + }; + + return ( + <TextWithAction + actionText={actionText} + text={text} + onClick={onRetry} + icon={<ReplayIcon />} + /> + ); +}; diff --git a/src/pages/room-tasks/index.ts b/src/pages/room-tasks/index.ts new file mode 100644 index 00000000..eb79c074 --- /dev/null +++ b/src/pages/room-tasks/index.ts @@ -0,0 +1,20 @@ +import { RouteRecord, createRouteView } from 'atomic-router-react'; +import { lazy } from 'react'; + +import { RoomLayout } from '@/widgets/rooms'; + +import { PageLoader } from '@/shared/ui'; + +import { currentRoute, authorizedRoute } from './model'; + +const Page = lazy(() => import('./page')); + +export const roomTasksPage: RouteRecord<any, any> = { + route: currentRoute, + view: createRouteView<any, any, any>({ + route: authorizedRoute, + view: Page, + otherwise: PageLoader, + }), + layout: RoomLayout, +}; diff --git a/src/pages/room-tasks/model.ts b/src/pages/room-tasks/model.ts new file mode 100644 index 00000000..bc761782 --- /dev/null +++ b/src/pages/room-tasks/model.ts @@ -0,0 +1,189 @@ +import { cache, createQuery, update } from '@farfetched/core'; +import { runtypeContract } from '@farfetched/runtypes'; +import { RouteQuery, querySync } from 'atomic-router'; +import { createDomain, createStore, sample } from 'effector'; +import { empty, not } from 'patronum'; + +import { dragTaskModel } from '@/widgets/tasks'; + +import { + createTaskModel, + removeTaskModel, + tasksFiltersModel, + updateTaskModel +} from '@/features/tasks'; + +import { progressesModel } from '@/entities/progresses'; +import { roomsModel } from '@/entities/rooms'; +import { tagsModel } from '@/entities/tags'; +import { tasksInRoomModel } from '@/entities/tasks'; +import { usersInRoomModel } from '@/entities/users'; + +import { + Activity, + UpdateTaskParams, + activitiesApi, + activity +} from '@/shared/api'; +import { controls, getParams, routes } from '@/shared/configs'; +import { dataExtractor } from '@/shared/lib'; +import { sessionModel } from '@/shared/models'; +import { + InRoomParams, + StandardResponse, + PaginationResponse, + getStandardResponse, + getPaginationResponse +} from '@/shared/types'; + +export const currentRoute = routes.room.tasks; +export const authorizedRoute = sessionModel.chainAuthorized(currentRoute, { + otherwise: routes.login.open, +}); +const { formValidated, reset, fields, } = tasksFiltersModel.form; + +const activitiesDomain = createDomain(); +const handlerFx = activitiesDomain.effect< + InRoomParams, + StandardResponse<PaginationResponse<Activity>> +>(({ roomId, }) => + activitiesApi.getAll({ roomId, count: 6, by: 'createdAt', type: 'desc', }) +); +const $roomId = createStore<null | number>(null); + +export const query = createQuery< + InRoomParams, + StandardResponse<PaginationResponse<Activity>>, + Error, + StandardResponse<PaginationResponse<Activity>>, + PaginationResponse<Activity> +>({ + initialData: { items: [], totalCount: 0, limit: 5, }, + effect: handlerFx, + contract: runtypeContract( + getStandardResponse(getPaginationResponse(activity)) + ), + mapData: dataExtractor, +}); + +const queries = [ + tasksInRoomModel.query, + tagsModel.query, + roomsModel.query, + usersInRoomModel.query, + progressesModel.query, + query +]; + +const mapQuery = (query: RouteQuery) => { + return { + authorIds: query[getParams.userId], + tagIds: query[getParams.userId], + before: query[getParams.before], + after: query[getParams.after], + }; +}; + +cache(query); + +sample({ + source: authorizedRoute.$params, + fn: (params) => params.id, + target: $roomId, +}); + +sample({ + clock: $roomId, + source: authorizedRoute.$query, + filter: not(empty($roomId)), + fn: (query, roomId) => ({ + roomId: roomId as number, + ...mapQuery(query), + }), + target: queries.map((query) => query.start), +}); + +querySync({ + controls, + source: { + [getParams.userId]: fields.authorIds.$value, + [getParams.tagId]: fields.tagIds.$value, + [getParams.after]: fields.after.$value, + [getParams.before]: fields.before.$value, + }, + clock: [formValidated, reset], + route: authorizedRoute, +}); + +sample({ + clock: [formValidated, reset], + source: authorizedRoute.$params, + filter: authorizedRoute.$isOpened, + fn: ({ id, }, values) => ({ roomId: id, ...values, }), + target: tasksInRoomModel.query.start, +}); + +sample({ + clock: authorizedRoute.closed, + target: reset, +}); + +sample({ + clock: authorizedRoute.closed, + target: queries.map((query) => query.reset), +}); + +sample({ + clock: authorizedRoute.closed, + target: $roomId.reinit!, +}); + +sample({ + clock: dragTaskModel.dropped, + source: { id: dragTaskModel.$id, roomId: $roomId, }, + fn: ({ id, roomId, }, evt) => { + const { status, } = evt.currentTarget.dataset; + return { + id, + roomId, + status, + } as UpdateTaskParams; + }, + target: updateTaskModel.mutation.start, +}); + +const queriesForUpdate = [progressesModel.query, query]; + +[ + updateTaskModel.mutation, + removeTaskModel.mutation, + createTaskModel.mutation +].forEach((mutation) => { + queriesForUpdate.forEach((query) => { + update(query, { + on: mutation, + by: { + success: ({ query, }) => { + if (!query) { + return { + result: { items: [], totalCount: 0, limit: 50, }, + refetch: true, + }; + } + + if ('error' in query) { + return { + error: query.error, + refetch: true, + }; + } + + return { + result: query.result, + refetch: true, + }; + }, + }, + }); + }); +}); diff --git a/src/pages/room-tasks/page.module.css b/src/pages/room-tasks/page.module.css new file mode 100644 index 00000000..5812bfdb --- /dev/null +++ b/src/pages/room-tasks/page.module.css @@ -0,0 +1,29 @@ +.wrapper { + display: grid; + grid-template-columns: 6fr 400px; + grid-template-rows: max-content 1fr; + grid-template-areas: '. aside' 'tasks aside'; + gap: 1em; + + height: 100%; + width: 100%; +} + +.tasks { + grid-area: tasks; +} + +.aside { + grid-area: aside; +} + +@media (max-width: 1440px) { + .wrapper { + grid-template-columns: 1fr; + grid-template-areas: '.' 'tasks'; + } + + .tasks { + padding-bottom: 1.5em; + } +} diff --git a/src/pages/room-tasks/page.module.css.d.ts b/src/pages/room-tasks/page.module.css.d.ts new file mode 100644 index 00000000..1351ad14 --- /dev/null +++ b/src/pages/room-tasks/page.module.css.d.ts @@ -0,0 +1,6 @@ +declare const styles: { + readonly aside: string; + readonly tasks: string; + readonly wrapper: string; +}; +export = styles; diff --git a/src/pages/room-tasks/page.tsx b/src/pages/room-tasks/page.tsx new file mode 100644 index 00000000..d3ea1d55 --- /dev/null +++ b/src/pages/room-tasks/page.tsx @@ -0,0 +1,54 @@ +import cn from 'classnames'; +import { useUnit } from 'effector-react'; +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { Popups, PopupsProps } from '@/widgets/page'; + +import { CreateTask, TasksFilters, UpdateTask } from '@/features/tasks'; + +import { popupsMap } from '@/shared/configs'; +import { deviceInfoModel } from '@/shared/models'; +import { CommonProps } from '@/shared/types'; +import { SectionHeader, Show } from '@/shared/ui'; + +import styles from './page.module.css'; +import { Tasks, Aside, MobileAside, TaskPopup } from './ui'; + +const popupMap: PopupsProps['popupMap'] = { + [popupsMap.createTask]: CreateTask, + [popupsMap.updateTask]: UpdateTask, + [popupsMap.task]: TaskPopup, +}; + +const TasksPage: React.FC<CommonProps> = (props) => { + const { className, } = props; + const { t, } = useTranslation('room-tasks'); + const isDesktopLarge = useUnit(deviceInfoModel.$isDesktopLarge); + + const title = t('title'); + const showAside = isDesktopLarge; + + return ( + <div className={cn(styles.wrapper, className)}> + <SectionHeader + title={title} + actions={ + <> + <TasksFilters /> + <Show show={!showAside}> + <MobileAside /> + </Show> + </> + } + /> + <Tasks className={styles.tasks} /> + <Show show={showAside}> + <Aside className={styles.aside} /> + </Show> + <Popups popupMap={popupMap} /> + </div> + ); +}; + +export default TasksPage; diff --git a/src/pages/room-tasks/ui/aside/aside.module.css b/src/pages/room-tasks/ui/aside/aside.module.css new file mode 100644 index 00000000..af827b69 --- /dev/null +++ b/src/pages/room-tasks/ui/aside/aside.module.css @@ -0,0 +1,7 @@ +.aside { + display: grid; + gap: 1em; + grid-template-rows: 3fr 7fr; + + height: min(100%, 960px); +} diff --git a/src/pages/room-tasks/ui/aside/aside.module.css.d.ts b/src/pages/room-tasks/ui/aside/aside.module.css.d.ts new file mode 100644 index 00000000..dc2abb62 --- /dev/null +++ b/src/pages/room-tasks/ui/aside/aside.module.css.d.ts @@ -0,0 +1,4 @@ +declare const styles: { + readonly aside: string; +}; +export = styles; diff --git a/src/pages/room-tasks/ui/aside/aside.tsx b/src/pages/room-tasks/ui/aside/aside.tsx new file mode 100644 index 00000000..ff804bdc --- /dev/null +++ b/src/pages/room-tasks/ui/aside/aside.tsx @@ -0,0 +1,24 @@ +import cn from 'classnames'; +import * as React from 'react'; + +import { CommonProps } from '@/shared/types'; + +import { LastActivities } from '../last-activities'; +import { TasksProgress } from '../tasks-progresses'; + +import styles from './aside.module.css'; + +export interface AsideProps extends CommonProps { + readonly disableBorder?: boolean; +} + +export const Aside: React.FC<AsideProps> = (props) => { + const { className, disableBorder, } = props; + + return ( + <div className={cn(styles.aside, className)}> + <TasksProgress disableBorder={disableBorder} /> + <LastActivities disableBorder={disableBorder} /> + </div> + ); +}; diff --git a/src/pages/room-tasks/ui/aside/index.ts b/src/pages/room-tasks/ui/aside/index.ts new file mode 100644 index 00000000..70f434cd --- /dev/null +++ b/src/pages/room-tasks/ui/aside/index.ts @@ -0,0 +1 @@ +export { Aside, type AsideProps } from './aside'; diff --git a/src/pages/room-tasks/ui/index.ts b/src/pages/room-tasks/ui/index.ts new file mode 100644 index 00000000..a8d9d051 --- /dev/null +++ b/src/pages/room-tasks/ui/index.ts @@ -0,0 +1,4 @@ +export * from './tasks'; +export * from './aside'; +export * from './mobile-aside'; +export * from './task-popup'; diff --git a/src/pages/room-tasks/ui/last-activities/index.ts b/src/pages/room-tasks/ui/last-activities/index.ts new file mode 100644 index 00000000..fc3f8406 --- /dev/null +++ b/src/pages/room-tasks/ui/last-activities/index.ts @@ -0,0 +1 @@ +export { LastActivities, type LastActivitiesProps } from './last-activities'; diff --git a/src/pages/room-tasks/ui/last-activities/last-activities.tsx b/src/pages/room-tasks/ui/last-activities/last-activities.tsx new file mode 100644 index 00000000..b0610c11 --- /dev/null +++ b/src/pages/room-tasks/ui/last-activities/last-activities.tsx @@ -0,0 +1,77 @@ +import ReplayIcon from '@mui/icons-material/Replay'; +import { Typography } from '@mui/material'; +import { useUnit } from 'effector-react'; +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { OpenAllRoomActivities } from '@/features/activities'; + +import { + ActivityListItem, + SkeletonActivityListItem +} from '@/entities/activities'; + +import { routes } from '@/shared/configs'; +import { useParam } from '@/shared/lib'; +import { CommonProps } from '@/shared/types'; +import { FriendlyList, TextWithAction } from '@/shared/ui'; + +import { query } from '../../model'; + +export interface LastActivitiesProps extends CommonProps { + readonly disableBorder?: boolean; +} + +export const LastActivities: React.FC<LastActivitiesProps> = (props) => { + const { className, disableBorder, } = props; + const { t, } = useTranslation('activities'); + + const emptyText = t('list.empty_text'); + const title = t('blocks.last_activities.title', { ns: 'room-tasks', }); + + return ( + <FriendlyList + className={className} + $query={query} + getData={(data) => data.items} + getKey={(item) => item.id} + skeletonsCount={6} + ErrorComponent={Error} + ItemComponent={ActivityListItem} + SkeletonComponent={SkeletonActivityListItem} + emptyText={emptyText} + slots={{ + before: ( + <Typography variant='h6' component='h2' fontWeight={700}> + {title} + </Typography> + ), + after: <OpenAllRoomActivities />, + }} + disableBorder={disableBorder} + /> + ); +}; + +const Error: React.FC = () => { + const { t, } = useTranslation('activities'); + + const roomId = useParam(routes.room.tasks, 'id'); + const start = useUnit(query.start); + + const onRetry = React.useCallback(() => { + start({ roomId, }); + }, [roomId]); + + const actionText = t('actions.retry', { ns: 'common', }); + const text = t('actions.retry_actions.text'); + + return ( + <TextWithAction + actionText={actionText} + text={text} + onClick={onRetry} + icon={<ReplayIcon />} + /> + ); +}; diff --git a/src/pages/room-tasks/ui/mobile-aside/index.ts b/src/pages/room-tasks/ui/mobile-aside/index.ts new file mode 100644 index 00000000..7ab2df05 --- /dev/null +++ b/src/pages/room-tasks/ui/mobile-aside/index.ts @@ -0,0 +1 @@ +export { MobileAside, type MobileAsideProps } from './mobile-aside'; diff --git a/src/pages/room-tasks/ui/mobile-aside/mobile-aside.module.css b/src/pages/room-tasks/ui/mobile-aside/mobile-aside.module.css new file mode 100644 index 00000000..192ce137 --- /dev/null +++ b/src/pages/room-tasks/ui/mobile-aside/mobile-aside.module.css @@ -0,0 +1,10 @@ +.drawer { + width: clamp(320px, 100%, 400px); +} + +.header { + display: flex; + justify-content: end; + + padding: 1em; +} diff --git a/src/pages/room-tasks/ui/mobile-aside/mobile-aside.module.css.d.ts b/src/pages/room-tasks/ui/mobile-aside/mobile-aside.module.css.d.ts new file mode 100644 index 00000000..b002d7bd --- /dev/null +++ b/src/pages/room-tasks/ui/mobile-aside/mobile-aside.module.css.d.ts @@ -0,0 +1,5 @@ +declare const styles: { + readonly drawer: string; + readonly header: string; +}; +export = styles; diff --git a/src/pages/room-tasks/ui/mobile-aside/mobile-aside.tsx b/src/pages/room-tasks/ui/mobile-aside/mobile-aside.tsx new file mode 100644 index 00000000..f1319853 --- /dev/null +++ b/src/pages/room-tasks/ui/mobile-aside/mobile-aside.tsx @@ -0,0 +1,50 @@ +import AnalyticsIcon from '@mui/icons-material/Analytics'; +import CloseIcon from '@mui/icons-material/Close'; +import { Drawer, IconButton, Tooltip } from '@mui/material'; +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { useToggle } from '@/shared/lib'; +import { CommonProps } from '@/shared/types'; + +import { Aside } from '../aside'; + +import styles from './mobile-aside.module.css'; + +export interface MobileAsideProps extends CommonProps {} + +export const MobileAside: React.FC<MobileAsideProps> = (props) => { + const { className, } = props; + const { t, } = useTranslation('room-tasks'); + + const [open, { toggle, toggleOff, }] = useToggle(); + const title = t('blocks.mobile_aside.title'); + const close = t('actions.close', { ns: 'common', }); + + return ( + <div className={className}> + <Tooltip title={title}> + <IconButton onClick={toggle}> + <AnalyticsIcon /> + </IconButton> + </Tooltip> + + <Drawer + classes={{ + paper: styles.drawer, + }} + open={open} + onClose={toggleOff} + anchor='right'> + <div className={styles.header}> + <Tooltip title={close}> + <IconButton onClick={toggleOff}> + <CloseIcon /> + </IconButton> + </Tooltip> + </div> + <Aside disableBorder /> + </Drawer> + </div> + ); +}; diff --git a/src/pages/room-tasks/ui/task-popup/index.ts b/src/pages/room-tasks/ui/task-popup/index.ts new file mode 100644 index 00000000..b37fae77 --- /dev/null +++ b/src/pages/room-tasks/ui/task-popup/index.ts @@ -0,0 +1 @@ +export { TaskPopup, type TaskPopupProps } from './task-popup'; diff --git a/src/pages/room-tasks/ui/task-popup/task-popup.tsx b/src/pages/room-tasks/ui/task-popup/task-popup.tsx new file mode 100644 index 00000000..03d606e9 --- /dev/null +++ b/src/pages/room-tasks/ui/task-popup/task-popup.tsx @@ -0,0 +1,20 @@ +import { Button } from '@mui/material'; +import * as React from 'react'; + +import { BasePopupProps } from '@/shared/types'; +import { MainPopup } from '@/shared/ui'; + +export interface TaskPopupProps extends BasePopupProps {} + +export const TaskPopup: React.FC<TaskPopupProps> = (props) => { + const { isOpen, } = props; + + return ( + <MainPopup isOpen={isOpen} onClose={console.log} title='Task' maxWidth='md'> + Task + <Button>Edit</Button> + <Button>Write comment</Button> + Comments + </MainPopup> + ); +}; diff --git a/src/pages/room-tasks/ui/tasks-progresses/index.ts b/src/pages/room-tasks/ui/tasks-progresses/index.ts new file mode 100644 index 00000000..ee0c0dd6 --- /dev/null +++ b/src/pages/room-tasks/ui/tasks-progresses/index.ts @@ -0,0 +1 @@ +export { TasksProgress } from './tasks-progresses'; diff --git a/src/pages/room-tasks/ui/tasks-progresses/tasks-progresses.module.css b/src/pages/room-tasks/ui/tasks-progresses/tasks-progresses.module.css new file mode 100644 index 00000000..3c25378a --- /dev/null +++ b/src/pages/room-tasks/ui/tasks-progresses/tasks-progresses.module.css @@ -0,0 +1,9 @@ +.wrapper { + overflow-y: auto; +} + +.list { + padding: 0 1em; + + overflow-y: scroll; +} diff --git a/src/pages/room-tasks/ui/tasks-progresses/tasks-progresses.module.css.d.ts b/src/pages/room-tasks/ui/tasks-progresses/tasks-progresses.module.css.d.ts new file mode 100644 index 00000000..e3a4be53 --- /dev/null +++ b/src/pages/room-tasks/ui/tasks-progresses/tasks-progresses.module.css.d.ts @@ -0,0 +1,5 @@ +declare const styles: { + readonly list: string; + readonly wrapper: string; +}; +export = styles; diff --git a/src/pages/room-tasks/ui/tasks-progresses/tasks-progresses.tsx b/src/pages/room-tasks/ui/tasks-progresses/tasks-progresses.tsx new file mode 100644 index 00000000..6c938d45 --- /dev/null +++ b/src/pages/room-tasks/ui/tasks-progresses/tasks-progresses.tsx @@ -0,0 +1,78 @@ +import ReplayIcon from '@mui/icons-material/Replay'; +import { Typography } from '@mui/material'; +import cn from 'classnames'; +import { useUnit } from 'effector-react'; +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { + SkeletonTaskProgress, + TaskProgress, + progressesModel +} from '@/entities/progresses'; + +import { routes } from '@/shared/configs'; +import { useParam } from '@/shared/lib'; +import { CommonProps } from '@/shared/types'; +import { FriendlyList, TextWithAction } from '@/shared/ui'; + +import styles from './tasks-progresses.module.css'; + +export interface TasksProgressProps extends CommonProps { + readonly disableBorder?: boolean; +} + +export const TasksProgress: React.FC<TasksProgressProps> = (props) => { + const { className, disableBorder, } = props; + const { t, } = useTranslation('room-tasks'); + + const title = t('blocks.tasks_progress.title'); + const emptyText = t('blocks.tasks_progress.empty_text'); + + return ( + <FriendlyList + className={cn(styles.wrapper, className)} + $query={progressesModel.query} + getKey={(item) => item.tag.id} + ItemComponent={TaskProgress} + SkeletonComponent={SkeletonTaskProgress} + ErrorComponent={Error} + emptyText={emptyText} + skeletonsCount={3} + disableBorder={disableBorder} + slots={{ + before: ( + <Typography variant='h6' component='h2' fontWeight={700}> + {title} + </Typography> + ), + }} + classes={{ + list: styles.list, + }} + /> + ); +}; + +const Error: React.FC = () => { + const { t, } = useTranslation('room-tasks'); + + const roomId = useParam(routes.room.tasks, 'id'); + const start = useUnit(progressesModel.query.start); + + const onRetry = React.useCallback(() => { + start({ roomId, }); + }, [roomId]); + + const text = t('actions.retry_progress.text'); + const actionText = t('actions.retry', { ns: 'common', }); + + return ( + <TextWithAction + text={text} + onClick={onRetry} + actionText={actionText} + icon={<ReplayIcon />} + /> + ); +}; diff --git a/src/pages/room-tasks/ui/tasks/index.ts b/src/pages/room-tasks/ui/tasks/index.ts new file mode 100644 index 00000000..8b03923e --- /dev/null +++ b/src/pages/room-tasks/ui/tasks/index.ts @@ -0,0 +1 @@ +export { Tasks } from './tasks'; diff --git a/src/pages/room-tasks/ui/tasks/tasks.module.css b/src/pages/room-tasks/ui/tasks/tasks.module.css new file mode 100644 index 00000000..aef45f54 --- /dev/null +++ b/src/pages/room-tasks/ui/tasks/tasks.module.css @@ -0,0 +1,10 @@ +.wrapper { + display: grid; + grid-template-columns: repeat(4, minmax(300px, 1fr)); + gap: 1rem; + + height: 100%; + width: 100%; + + overflow-x: scroll; +} diff --git a/src/shared/components/LoadingWrapper/LoadingWrapper.module.css.d.ts b/src/pages/room-tasks/ui/tasks/tasks.module.css.d.ts similarity index 100% rename from src/shared/components/LoadingWrapper/LoadingWrapper.module.css.d.ts rename to src/pages/room-tasks/ui/tasks/tasks.module.css.d.ts diff --git a/src/pages/room-tasks/ui/tasks/tasks.tsx b/src/pages/room-tasks/ui/tasks/tasks.tsx new file mode 100644 index 00000000..1b9e2c1f --- /dev/null +++ b/src/pages/room-tasks/ui/tasks/tasks.tsx @@ -0,0 +1,67 @@ +import ReplayIcon from '@mui/icons-material/Replay'; +import cn from 'classnames'; +import { useUnit } from 'effector-react'; +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { TaskColumn } from '@/widgets/tasks'; + +import { tasksInRoomModel } from '@/entities/tasks'; + +import { routes } from '@/shared/configs'; +import { useParam } from '@/shared/lib'; +import { CommonProps } from '@/shared/types'; +import { TextWithAction } from '@/shared/ui'; + +import styles from './tasks.module.css'; + +export const Tasks: React.FC<CommonProps> = (props) => { + const { className, } = props; + const { t, } = useTranslation('tasks'); + const roomId = useParam(routes.room.tasks, 'id'); + const tasks = useUnit({ + pending: tasksInRoomModel.query.$pending, + stale: tasksInRoomModel.query.$stale, + error: tasksInRoomModel.query.$error, + start: tasksInRoomModel.query.start, + }); + const columns = useUnit(tasksInRoomModel.$tasksColumns); + + const isLoading = tasks.pending && !tasks.stale; + const isError = !!tasks.error; + + if (isError) { + const onRetry = () => { + tasks.start({ roomId, }); + }; + + const text = t('actions.retry_tasks.text'); + const actionText = t('actions.retry', { ns: 'common', }); + + return ( + <TextWithAction + className={className} + actionText={actionText} + text={text} + onClick={onRetry} + icon={<ReplayIcon />} + /> + ); + } + + return ( + <section className={cn(styles.wrapper, className)}> + {columns.map(({ status, tasks, hasActions, }) => ( + <TaskColumn + roomId={roomId} + tasks={tasks} + isLoading={isLoading} + columnStatus={status} + header={t(`statuses.${status}`)} + hasActions={hasActions} + key={status} + /> + ))} + </section> + ); +}; diff --git a/src/pages/room-users/index.ts b/src/pages/room-users/index.ts new file mode 100644 index 00000000..29cebe15 --- /dev/null +++ b/src/pages/room-users/index.ts @@ -0,0 +1,20 @@ +import { RouteRecord, createRouteView } from 'atomic-router-react'; +import { lazy } from 'react'; + +import { RoomLayout } from '@/widgets/rooms'; + +import { PageLoader } from '@/shared/ui'; + +import { currentRoute, authorizedRoute } from './model'; + +const Page = lazy(() => import('./page')); + +export const roomUsersPage: RouteRecord<any, any> = { + route: currentRoute, + view: createRouteView<any, any, any>({ + route: authorizedRoute, + view: Page, + otherwise: PageLoader, + }), + layout: RoomLayout, +}; diff --git a/src/pages/room-users/model.ts b/src/pages/room-users/model.ts new file mode 100644 index 00000000..85ad4b6f --- /dev/null +++ b/src/pages/room-users/model.ts @@ -0,0 +1,32 @@ +import { sample } from 'effector'; + +import { invitationsModel } from '@/entities/invitations'; +import { roomsModel } from '@/entities/rooms'; +import { usersInRoomModel } from '@/entities/users'; + +import { routes } from '@/shared/configs'; +import { sessionModel } from '@/shared/models'; + +export const currentRoute = routes.room.users; +export const authorizedRoute = sessionModel.chainAuthorized(currentRoute, { + otherwise: routes.login.open, +}); + +sample({ + clock: authorizedRoute.opened, + fn: ({ params, }) => ({ roomId: params.id, }), + target: [ + usersInRoomModel.query.start, + roomsModel.query.start, + invitationsModel.query.start + ], +}); + +sample({ + clock: authorizedRoute.closed, + target: [ + usersInRoomModel.query.reset, + roomsModel.query.reset, + invitationsModel.query.reset + ], +}); diff --git a/src/pages/room-users/page.module.css b/src/pages/room-users/page.module.css new file mode 100644 index 00000000..3b0eb023 --- /dev/null +++ b/src/pages/room-users/page.module.css @@ -0,0 +1,12 @@ +.wrapper { + display: grid; + gap: 1.5em; + grid-template-rows: max-content; + + padding: 0; +} + +.group { + display: grid; + gap: 0.5em; +} diff --git a/src/pages/room-users/page.module.css.d.ts b/src/pages/room-users/page.module.css.d.ts new file mode 100644 index 00000000..c7d04d55 --- /dev/null +++ b/src/pages/room-users/page.module.css.d.ts @@ -0,0 +1,5 @@ +declare const styles: { + readonly group: string; + readonly wrapper: string; +}; +export = styles; diff --git a/src/pages/room-users/page.tsx b/src/pages/room-users/page.tsx new file mode 100644 index 00000000..f3671ec6 --- /dev/null +++ b/src/pages/room-users/page.tsx @@ -0,0 +1,52 @@ +import { Container } from '@mui/material'; +import cn from 'classnames'; +import { useUnit } from 'effector-react'; +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { + CreateInvitation, + CreateInvitationButton +} from '@/widgets/invitations'; +import { Popups, PopupsProps } from '@/widgets/page'; + +import { roomModel } from '@/entities/rooms'; + +import { popupsMap } from '@/shared/configs'; +import { CommonProps } from '@/shared/types'; +import { SectionHeader } from '@/shared/ui'; + +import styles from './page.module.css'; +import { InvitationList, UserList } from './ui'; + +export interface UsersPageProps extends CommonProps {} + +const popupMap: PopupsProps['popupMap'] = { + [popupsMap.createInvitation]: CreateInvitation, +}; + +const UsersPage: React.FC<UsersPageProps> = (props) => { + const { className, } = props; + const { t, } = useTranslation('room-users'); + const canChange = useUnit(roomModel.$canChange); + + const usersTitle = t('title'); + const invitationsTitle = t('title', { ns: 'room-invitations', }); + const actions = canChange ? <CreateInvitationButton /> : null; + + return ( + <Container className={cn(styles.wrapper, className)}> + <div className={styles.group}> + <SectionHeader title={usersTitle} actions={actions} /> + <UserList /> + </div> + <div className={styles.group}> + <SectionHeader title={invitationsTitle} /> + <InvitationList /> + </div> + <Popups popupMap={popupMap} /> + </Container> + ); +}; + +export default UsersPage; diff --git a/src/pages/room-users/ui/index.ts b/src/pages/room-users/ui/index.ts new file mode 100644 index 00000000..96afbf5a --- /dev/null +++ b/src/pages/room-users/ui/index.ts @@ -0,0 +1,2 @@ +export * from './user-list'; +export * from './invitation-list'; diff --git a/src/pages/room-users/ui/invitation-list/index.ts b/src/pages/room-users/ui/invitation-list/index.ts new file mode 100644 index 00000000..99b9e981 --- /dev/null +++ b/src/pages/room-users/ui/invitation-list/index.ts @@ -0,0 +1 @@ +export { InvitationList, type InvitationListProps } from './invitation-list'; diff --git a/src/pages/room-users/ui/invitation-list/invitation-list.tsx b/src/pages/room-users/ui/invitation-list/invitation-list.tsx new file mode 100644 index 00000000..881da79c --- /dev/null +++ b/src/pages/room-users/ui/invitation-list/invitation-list.tsx @@ -0,0 +1,76 @@ +import ReplayIcon from '@mui/icons-material/Replay'; +import { useUnit } from 'effector-react'; +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { + InvitationListItem, + InvitationListItemProps +} from '@/widgets/invitations'; + +import { + SkeletonInvitationListItem, + invitationsModel +} from '@/entities/invitations'; + +import { Invitation } from '@/shared/api'; +import { routes } from '@/shared/configs'; +import { useParam } from '@/shared/lib'; +import { CommonProps } from '@/shared/types'; +import { FriendlyList, TextWithAction } from '@/shared/ui'; + +export interface InvitationListProps extends CommonProps {} + +export const InvitationList: React.FC<InvitationListProps> = (props) => { + const { className, } = props; + const { t, } = useTranslation('room-invitations'); + const roomId = useParam(routes.room.users, 'id'); + + const emptyText = t('list.empty_text'); + + return ( + <FriendlyList<Invitation[], InvitationListItemProps, any> + className={className} + $query={invitationsModel.query} + getData={(invitation) => + invitation.map((invitation) => ({ + id: invitation.id, + email: invitation.user!.email, + username: invitation.user!.username, + photo: invitation.user!.photo, + inviterName: invitation.inviter.username, + roomId, + })) + } + getKey={(item) => item.id} + skeletonsCount={25} + ErrorComponent={Error} + ItemComponent={InvitationListItem} + SkeletonComponent={SkeletonInvitationListItem} + emptyText={emptyText} + /> + ); +}; + +const Error: React.FC = () => { + const { t, } = useTranslation('room-invitations'); + + const roomId = useParam(routes.room.users, 'id'); + const start = useUnit(invitationsModel.query.start); + + const text = t('actions.retry_invitations.text'); + const actionText = t('actions.retry', { ns: 'common', }); + + const onRetry = React.useCallback(() => { + start({ roomId, }); + }, [roomId]); + + return ( + <TextWithAction + actionText={actionText} + text={text} + onClick={onRetry} + icon={<ReplayIcon />} + /> + ); +}; diff --git a/src/pages/room-users/ui/user-list/index.ts b/src/pages/room-users/ui/user-list/index.ts new file mode 100644 index 00000000..ba9c5532 --- /dev/null +++ b/src/pages/room-users/ui/user-list/index.ts @@ -0,0 +1 @@ +export { UserList, type UserListProps } from './user-list'; diff --git a/src/pages/room-users/ui/user-list/user-list.tsx b/src/pages/room-users/ui/user-list/user-list.tsx new file mode 100644 index 00000000..1651647e --- /dev/null +++ b/src/pages/room-users/ui/user-list/user-list.tsx @@ -0,0 +1,60 @@ +import ReplayIcon from '@mui/icons-material/Replay'; +import { useUnit } from 'effector-react'; +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { UserInRoomListItem } from '@/widgets/users'; + +import { SkeletonUserListItem, usersInRoomModel } from '@/entities/users'; + +import { routes } from '@/shared/configs'; +import { useParam } from '@/shared/lib'; +import { CommonProps } from '@/shared/types'; +import { FriendlyList, TextWithAction } from '@/shared/ui'; + +export interface UserListProps extends CommonProps {} + +export const UserList: React.FC<UserListProps> = (props) => { + const { className, } = props; + const { t, } = useTranslation('room-users'); + const roomId = useParam(routes.room.users, 'id'); + + const emptyText = t('list.empty_text'); + + return ( + <FriendlyList + className={className} + $query={usersInRoomModel.query} + getData={(users) => users.map((user) => ({ ...user, roomId, }))} + getKey={(item) => item.id} + skeletonsCount={25} + ErrorComponent={Error} + ItemComponent={UserInRoomListItem as any} + SkeletonComponent={SkeletonUserListItem} + emptyText={emptyText} + /> + ); +}; + +const Error: React.FC = () => { + const { t, } = useTranslation('room-users'); + + const roomId = useParam(routes.room.users, 'id'); + const start = useUnit(usersInRoomModel.query.start); + + const text = t('actions.retry_users.text'); + const actionText = t('actions.retry', { ns: 'common', }); + + const onRetry = React.useCallback(() => { + start({ roomId, }); + }, [roomId]); + + return ( + <TextWithAction + actionText={actionText} + text={text} + onClick={onRetry} + icon={<ReplayIcon />} + /> + ); +}; diff --git a/src/pages/rooms/index.ts b/src/pages/rooms/index.ts new file mode 100644 index 00000000..377225cd --- /dev/null +++ b/src/pages/rooms/index.ts @@ -0,0 +1,17 @@ +import { RouteRecord, createRouteView } from 'atomic-router-react'; +import { lazy } from 'react'; + +import { PageLoader } from '@/shared/ui'; + +import { authorizedRoute, currentRoute } from './model'; + +const Page = lazy(() => import('./page')); + +export const roomsPage: RouteRecord<any, any> = { + route: currentRoute, + view: createRouteView({ + route: authorizedRoute, + view: Page, + otherwise: PageLoader, + }), +}; diff --git a/src/pages/rooms/model.ts b/src/pages/rooms/model.ts new file mode 100644 index 00000000..6ee6de17 --- /dev/null +++ b/src/pages/rooms/model.ts @@ -0,0 +1,21 @@ +import { sample } from 'effector'; + +import { roomsModel } from '@/entities/rooms'; + +import { routes } from '@/shared/configs'; +import { sessionModel } from '@/shared/models'; + +export const currentRoute = routes.rooms.base; +export const authorizedRoute = sessionModel.chainAuthorized(currentRoute, { + otherwise: routes.login.open, +}); + +sample({ + clock: authorizedRoute.opened, + target: roomsModel.query.start, +}); + +sample({ + clock: authorizedRoute.closed, + target: roomsModel.query.reset, +}); diff --git a/src/pages/rooms/page.tsx b/src/pages/rooms/page.tsx new file mode 100644 index 00000000..8996922a --- /dev/null +++ b/src/pages/rooms/page.tsx @@ -0,0 +1,36 @@ +import cn from 'classnames'; +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { Popups, PopupsProps } from '@/widgets/page'; +import { RoomList } from '@/widgets/rooms'; + +import { CreateRoom, UpdateRoom } from '@/features/rooms'; + +import { popupsMap } from '@/shared/configs'; +import { usePageTitle } from '@/shared/lib'; +import { CommonProps } from '@/shared/types'; + +import styles from './styles.module.css'; +import { RoomsLayout } from './ui'; + +const popupMap: PopupsProps['popupMap'] = { + [popupsMap.createRoom]: CreateRoom, + [popupsMap.updateRoom]: UpdateRoom, +}; + +const RoomsPage: React.FC<CommonProps> = (props) => { + const { className, } = props; + const { t, } = useTranslation('rooms'); + const title = t('title'); + usePageTitle(title); + + return ( + <RoomsLayout className={cn(styles.layout, className)}> + <RoomList /> + <Popups popupMap={popupMap} /> + </RoomsLayout> + ); +}; + +export default RoomsPage; diff --git a/src/pages/rooms/styles.module.css b/src/pages/rooms/styles.module.css new file mode 100644 index 00000000..2771539c --- /dev/null +++ b/src/pages/rooms/styles.module.css @@ -0,0 +1,5 @@ +.layout { + display: grid; + grid-template-rows: min-content 1fr; + gap: 1em; +} diff --git a/src/pages/RoomsPage/RoomsPage.module.css.d.ts b/src/pages/rooms/styles.module.css.d.ts similarity index 100% rename from src/pages/RoomsPage/RoomsPage.module.css.d.ts rename to src/pages/rooms/styles.module.css.d.ts diff --git a/src/pages/rooms/ui/index.ts b/src/pages/rooms/ui/index.ts new file mode 100644 index 00000000..fb3cadf5 --- /dev/null +++ b/src/pages/rooms/ui/index.ts @@ -0,0 +1 @@ +export { RoomsLayout } from './rooms-layout'; diff --git a/src/pages/rooms/ui/rooms-header/index.ts b/src/pages/rooms/ui/rooms-header/index.ts new file mode 100644 index 00000000..e3532bf6 --- /dev/null +++ b/src/pages/rooms/ui/rooms-header/index.ts @@ -0,0 +1 @@ +export { RoomsHeader } from './rooms-header'; diff --git a/src/pages/rooms/ui/rooms-header/rooms-header.tsx b/src/pages/rooms/ui/rooms-header/rooms-header.tsx new file mode 100644 index 00000000..e743ccda --- /dev/null +++ b/src/pages/rooms/ui/rooms-header/rooms-header.tsx @@ -0,0 +1,29 @@ +import { Typography } from '@mui/material'; +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { MainHeader } from '@/widgets/page'; + +import { OpenCreateRoom } from '@/features/rooms'; + +import { CommonProps } from '@/shared/types'; + +export const RoomsHeader: React.FC<CommonProps> = (props) => { + const { className, } = props; + const { t, } = useTranslation('rooms'); + const title = t('title'); + + return ( + <MainHeader + className={className} + slots={{ + left: ( + <Typography variant='h5' component='h1'> + {title} + </Typography> + ), + right: <OpenCreateRoom />, + }} + /> + ); +}; diff --git a/src/pages/rooms/ui/rooms-layout/index.ts b/src/pages/rooms/ui/rooms-layout/index.ts new file mode 100644 index 00000000..8905ab12 --- /dev/null +++ b/src/pages/rooms/ui/rooms-layout/index.ts @@ -0,0 +1 @@ +export { RoomsLayout, type RoomsLayoutProps } from './rooms-layout'; diff --git a/src/pages/rooms/ui/rooms-layout/rooms-layout.tsx b/src/pages/rooms/ui/rooms-layout/rooms-layout.tsx new file mode 100644 index 00000000..bade8143 --- /dev/null +++ b/src/pages/rooms/ui/rooms-layout/rooms-layout.tsx @@ -0,0 +1,24 @@ +import * as React from 'react'; + +import { CommonProps } from '@/shared/types'; +import { Layout } from '@/shared/ui'; + +import { RoomsHeader } from '../rooms-header'; + +export interface RoomsLayoutProps + extends CommonProps, + Required<React.PropsWithChildren> {} + +export const RoomsLayout: React.FC<RoomsLayoutProps> = (props) => { + const { className, children, } = props; + + return ( + <Layout + className={className} + slots={{ + header: <RoomsHeader />, + }}> + {children} + </Layout> + ); +}; diff --git a/src/pages/settings/index.ts b/src/pages/settings/index.ts new file mode 100644 index 00000000..c5b324d7 --- /dev/null +++ b/src/pages/settings/index.ts @@ -0,0 +1,20 @@ +import { RouteRecord, createRouteView } from 'atomic-router-react'; +import { lazy } from 'react'; + +import { RoomLayout } from '@/widgets/rooms'; + +import { PageLoader } from '@/shared/ui'; + +import { currentRoute, authorizedRoute } from './model'; + +const Page = lazy(() => import('./page')); + +export const settingsPage: RouteRecord<any, any> = { + route: currentRoute, + view: createRouteView<any, any, any>({ + route: authorizedRoute, + view: Page, + otherwise: PageLoader, + }), + layout: RoomLayout, +}; diff --git a/src/pages/settings/model.ts b/src/pages/settings/model.ts new file mode 100644 index 00000000..d500764d --- /dev/null +++ b/src/pages/settings/model.ts @@ -0,0 +1,7 @@ +import { routes } from '@/shared/configs'; +import { sessionModel } from '@/shared/models'; + +export const currentRoute = routes.settings; +export const authorizedRoute = sessionModel.chainAuthorized(currentRoute, { + otherwise: routes.login.open, +}); diff --git a/src/pages/settings/page.tsx b/src/pages/settings/page.tsx new file mode 100644 index 00000000..2ba20ba4 --- /dev/null +++ b/src/pages/settings/page.tsx @@ -0,0 +1,22 @@ +import { Typography } from '@mui/material'; +import * as React from 'react'; + +import { MainLayout } from '@/widgets/page'; + +import { usePageTitle } from '@/shared/lib'; + +import styles from './styles.module.css'; + +const SettingsPage: React.FC = () => { + usePageTitle('Settings'); + + return ( + <MainLayout> + <div className={styles.header}> + <Typography component='h2'>Settings</Typography> + </div> + </MainLayout> + ); +}; + +export default SettingsPage; diff --git a/src/pages/SettingsPage/SettingsPage.module.css b/src/pages/settings/styles.module.css similarity index 100% rename from src/pages/SettingsPage/SettingsPage.module.css rename to src/pages/settings/styles.module.css diff --git a/src/pages/settings/styles.module.css.d.ts b/src/pages/settings/styles.module.css.d.ts new file mode 100644 index 00000000..519def86 --- /dev/null +++ b/src/pages/settings/styles.module.css.d.ts @@ -0,0 +1,6 @@ +declare const styles: { + readonly header: string; + readonly navigation: string; + readonly page: string; +}; +export = styles; diff --git a/src/routes/index.ts b/src/routes/index.ts deleted file mode 100644 index a3820983..00000000 --- a/src/routes/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './routes'; diff --git a/src/routes/routes.ts b/src/routes/routes.ts deleted file mode 100644 index 677489c0..00000000 --- a/src/routes/routes.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { ComponentType, lazy } from 'react'; -import { createRoute, UnmappedRouteObject } from 'atomic-router'; -import { paths } from '@/const'; - -export const roomsRoute = createRoute(); -export const roomRoute = createRoute<{ id: number }>(); -export const loginRoute = createRoute(); -export const registrationRoute = createRoute(); - -const LoginPage = lazy(() => import('@/pages/LoginPage')); -const RegistrationPage = lazy(() => import('@/pages/RegistrationPage')); -const RoomsPage = lazy(() => import('@/pages/RoomsPage')); -const RoomPage = lazy(() => import('@/pages/RoomPage')); - -interface Route extends UnmappedRouteObject<any> { - readonly Component: ComponentType; -} - -export const routes: Route[] = [ - { - path: paths.rooms, - Component: RoomsPage, - route: roomsRoute, - }, - { - path: paths.room, - Component: RoomPage, - route: roomRoute, - }, - { - path: paths.login, - Component: LoginPage, - route: loginRoute, - }, - { - path: paths.registration, - Component: RegistrationPage, - route: registrationRoute, - }, -]; diff --git a/src/shared/api/activities/index.ts b/src/shared/api/activities/index.ts new file mode 100644 index 00000000..2fe7e295 --- /dev/null +++ b/src/shared/api/activities/index.ts @@ -0,0 +1,2 @@ +export * as activitiesApi from './requests'; +export * from './types'; diff --git a/src/shared/api/activities/requests.ts b/src/shared/api/activities/requests.ts new file mode 100644 index 00000000..6dd88fd0 --- /dev/null +++ b/src/shared/api/activities/requests.ts @@ -0,0 +1,33 @@ +import { PaginationResponse, StandardResponse } from '@/shared/types'; + +import { instance, normalizeQuery } from '../request'; + +import { + Activity, + ActivityAction, + ActivitySphere, + GetActivitiesInRoomParams +} from './types'; + +export const getAll = async ({ + roomId, + ...query +}: GetActivitiesInRoomParams) => { + return instance + .get(`activities/${roomId}`, { + searchParams: new URLSearchParams(normalizeQuery(query)), + }) + .json<StandardResponse<PaginationResponse<Activity>>>(); +}; + +export const getActions = async () => { + return instance + .get('activities/actions/all') + .json<StandardResponse<ActivityAction[]>>(); +}; + +export const getSpheres = async () => { + return instance + .get('activities/spheres/all') + .json<StandardResponse<ActivitySphere[]>>(); +}; diff --git a/src/shared/api/activities/types.ts b/src/shared/api/activities/types.ts new file mode 100644 index 00000000..26e894c9 --- /dev/null +++ b/src/shared/api/activities/types.ts @@ -0,0 +1,49 @@ +import { Number, Record, Static, String } from 'runtypes'; + +import { + DatesFiltersParams, + InRoomParams, + PaginationParams, + SortParams +} from '@/shared/types'; + +import { user } from '../auth'; + +export const activityAction = Record({ + id: Number, + name: String, +}).asReadonly(); + +export interface ActivityAction extends Static<typeof activityAction> {} + +export const activitySphere = Record({ + id: Number, + name: String, +}).asReadonly(); + +export interface ActivitySphere extends Static<typeof activitySphere> {} + +export const activity = Record({ + id: Number, + roomId: Number, + activist: user, + action: activityAction, + sphere: activitySphere, + createdAt: String, +}).asReadonly(); + +export interface Activity extends Static<typeof activity> {} + +export interface GetActivitiesInRoomParams + extends InRoomParams, + PaginationParams, + SortParams, + DatesFiltersParams { + readonly activistIds?: number[]; + readonly sphereIds?: number[]; + readonly actionIds?: number[]; +} + +export interface GetLastActivitiesInRoomParams extends InRoomParams { + readonly count: number; +} diff --git a/src/shared/api/auth/index.ts b/src/shared/api/auth/index.ts new file mode 100644 index 00000000..77ca9057 --- /dev/null +++ b/src/shared/api/auth/index.ts @@ -0,0 +1,2 @@ +export * as authApi from './requests'; +export * from './types'; diff --git a/src/shared/api/auth/requests.ts b/src/shared/api/auth/requests.ts new file mode 100644 index 00000000..c6c9e724 --- /dev/null +++ b/src/shared/api/auth/requests.ts @@ -0,0 +1,45 @@ +import { StandardResponse } from '@/shared/types'; + +import { instance, normalizeQuery } from '../request'; + +import { + ActivateParams, + AuthResponse, + LoginParams, + RegistrationParams, + User +} from './types'; + +export const auth = async () => { + return instance + .get('auth', { credentials: 'include', }) + .json<StandardResponse<AuthResponse>>(); +}; + +export const login = async (body: LoginParams) => { + return instance + .post('auth/login', { + json: body, + }) + .json<StandardResponse<AuthResponse>>(); +}; + +export const registration = async (body: RegistrationParams) => { + return instance + .post('auth/registration', { + json: body, + }) + .json<StandardResponse<User>>(); +}; + +export const activate = async (query: ActivateParams) => { + return instance + .put('auth/registration/activate', { + searchParams: new URLSearchParams(normalizeQuery(query)), + }) + .json<StandardResponse<boolean>>(); +}; + +export const logout = async () => { + return instance.delete('auth/logout').json<StandardResponse<boolean>>(); +}; diff --git a/src/shared/api/auth/types.ts b/src/shared/api/auth/types.ts new file mode 100644 index 00000000..4d90eaa5 --- /dev/null +++ b/src/shared/api/auth/types.ts @@ -0,0 +1,35 @@ +import { Record, String, Static, Number } from 'runtypes'; + +import { tokens } from '../request'; + +export const user = Record({ + id: Number, + email: String, + username: String, + photo: String.nullable(), +}).asReadonly(); + +export interface User extends Static<typeof user> {} + +export const authResponse = Record({ + tokens, + user, +}).asReadonly(); + +export interface AuthResponse extends Static<typeof authResponse> {} + +export interface LoginParams { + readonly email: string; + readonly password: string; + readonly rememberMe: boolean; +} + +export interface RegistrationParams { + readonly email: string; + readonly username: string; + readonly password: string; +} + +export interface ActivateParams { + readonly token: string; +} diff --git a/src/shared/api/comments/index.ts b/src/shared/api/comments/index.ts new file mode 100644 index 00000000..74860e8f --- /dev/null +++ b/src/shared/api/comments/index.ts @@ -0,0 +1,2 @@ +export * as commentsApi from './requests'; +export * from './types'; diff --git a/src/shared/api/comments/requests.ts b/src/shared/api/comments/requests.ts new file mode 100644 index 00000000..fd8198bf --- /dev/null +++ b/src/shared/api/comments/requests.ts @@ -0,0 +1,46 @@ +import { StandardResponse } from '@/shared/types'; + +import { instance } from '../request'; + +import { + BaseCommentParams, + Comment, + CreateParams, + GetOneParams, + RemoveParams, + UpdateParams +} from './types'; + +export const getAll = ({ roomId, taskId, }: BaseCommentParams) => { + return instance + .get(`comments/${roomId}/${taskId}`) + .json<StandardResponse<Comment[]>>(); +}; + +export const getOne = ({ roomId, taskId, id, }: GetOneParams) => { + return instance + .get(`comments/${roomId}/${taskId}/${id}`) + .json<StandardResponse<Comment>>(); +}; + +export const create = ({ roomId, taskId, ...body }: CreateParams) => { + return instance + .post(`comments/${roomId}/${taskId}/create`, { + json: body, + }) + .json<StandardResponse<Comment>>(); +}; + +export const update = ({ roomId, taskId, id, ...body }: UpdateParams) => { + return instance + .put(`comments/${roomId}/${taskId}/${id}/update`, { + json: body, + }) + .json<StandardResponse<Comment>>(); +}; + +export const remove = ({ roomId, taskId, id, }: RemoveParams) => { + return instance + .delete(`comments/${roomId}/${taskId}/${id}/remove`) + .json<StandardResponse<boolean>>(); +}; diff --git a/src/shared/api/comments/types.ts b/src/shared/api/comments/types.ts new file mode 100644 index 00000000..21faa5d6 --- /dev/null +++ b/src/shared/api/comments/types.ts @@ -0,0 +1,38 @@ +import { Number, Record, String, Static } from 'runtypes'; + +import { InRoomParams } from '@/shared/types'; + +import { user } from '../auth'; + +export const comment = Record({ + id: Number, + roomId: Number, + author: user, + taskId: Number, + content: String, + createdAt: String, + updatedAt: String.nullable(), +}).asReadonly(); + +export interface Comment extends Static<typeof comment> {} + +export interface BaseCommentParams extends InRoomParams { + readonly taskId: number; +} + +export interface GetOneParams extends BaseCommentParams { + readonly id: number; +} + +export interface CreateParams extends BaseCommentParams { + readonly content: string; +} + +export interface UpdateParams extends BaseCommentParams { + readonly id: number; + readonly content: string; +} + +export interface RemoveParams extends BaseCommentParams { + readonly id: number; +} diff --git a/src/shared/api/index.ts b/src/shared/api/index.ts new file mode 100644 index 00000000..52fd8177 --- /dev/null +++ b/src/shared/api/index.ts @@ -0,0 +1,10 @@ +export * from './auth'; +export * from './rooms'; +export * from './tasks'; +export * from './tags'; +export * from './activities'; +export * from './progresses'; +export * from './users'; +export * from './members'; +export * from './comments'; +export * from './invitations'; diff --git a/src/shared/api/invitations/index.ts b/src/shared/api/invitations/index.ts new file mode 100644 index 00000000..4f31acd7 --- /dev/null +++ b/src/shared/api/invitations/index.ts @@ -0,0 +1,2 @@ +export * as invitationsApi from './requests'; +export * from './types'; diff --git a/src/shared/api/invitations/requests.ts b/src/shared/api/invitations/requests.ts new file mode 100644 index 00000000..c225ba72 --- /dev/null +++ b/src/shared/api/invitations/requests.ts @@ -0,0 +1,72 @@ +import { instance } from '../request'; + +import { + ApproveInvitationRequestParams, + ApproveInvitationResponseData, + GenerateLinkRequestParams, + GenerateLinkResponseData, + GetAllInvitationsRequestParams, + GetAllInvitationsResponseData, + GetInvitationViaTokenRequestParams, + GetInvitationViaTokenResponseData, + InviteUserRequestParams, + InviteUserResponseData, + RejectInvitationRequestParams, + RejectInvitationResponseData, + RemoveInvitationRequestParams, + RemoveInvitationResponseData +} from './types'; + +export const getAll = async ({ + roomId, +}: GetAllInvitationsRequestParams): GetAllInvitationsResponseData => { + return instance.get(`invitations/${roomId}`).json(); +}; + +export const getViaToken = async ({ + token, +}: GetInvitationViaTokenRequestParams): GetInvitationViaTokenResponseData => { + return instance.get(`invitations/via/${token}`).json(); +}; + +export const invite = async ({ + roomId, + userId, +}: InviteUserRequestParams): InviteUserResponseData => { + return instance + .post(`invitations/invite/${roomId}`, { json: { userId, }, }) + .json(); +}; + +export const generateLink = async ({ + roomId, +}: GenerateLinkRequestParams): GenerateLinkResponseData => { + return instance.post(`invitations/invite/${roomId}/generate-link`).json(); +}; + +export const approveInvitation = async ({ + id, +}: ApproveInvitationRequestParams): ApproveInvitationResponseData => { + return instance + .put(`invitations/invite/approve`, { + json: { id, }, + }) + .json(); +}; + +export const rejectInvitation = async ({ + id, +}: RejectInvitationRequestParams): RejectInvitationResponseData => { + return instance + .put(`invitations/invite/reject`, { + json: { id, }, + }) + .json(); +}; + +export const remove = async ({ + roomId, + id, +}: RemoveInvitationRequestParams): RemoveInvitationResponseData => { + return instance.delete(`invitations/invite/${roomId}/${id}`).json(); +}; diff --git a/src/shared/api/invitations/types.ts b/src/shared/api/invitations/types.ts new file mode 100644 index 00000000..b493a3b3 --- /dev/null +++ b/src/shared/api/invitations/types.ts @@ -0,0 +1,66 @@ +import { Literal, Number, Record, Static, Union } from 'runtypes'; + +import { InRoomParams, StandardResponse } from '@/shared/types'; + +import { user } from '../auth'; +import { room } from '../rooms'; + +export const invitationStatus = Union( + Literal('sended'), + Literal('approved'), + Literal('rejected') +); + +export type InvitationStatus = Static<typeof invitationStatus>; + +export const invitation = Record({ + id: Number, + room, + user: user.nullable(), + inviter: user, + status: invitationStatus, +}); + +export interface Invitation extends Static<typeof invitation> {} + +export type GetAllInvitationsRequestParams = InRoomParams; + +export type GetAllInvitationsResponseData = Promise< + StandardResponse<Invitation[]> +>; + +export interface GetInvitationViaTokenRequestParams { + readonly token: string; +} + +export type GetInvitationViaTokenResponseData = Promise< + StandardResponse<Invitation> +>; + +export type GenerateLinkRequestParams = InRoomParams; + +export type GenerateLinkResponseData = Promise<StandardResponse<string>>; + +export interface InviteUserRequestParams extends InRoomParams { + readonly userId: number; +} + +export type InviteUserResponseData = Promise<StandardResponse<Invitation>>; + +export interface ApproveInvitationRequestParams { + readonly id: number; +} + +export type ApproveInvitationResponseData = Promise<StandardResponse<boolean>>; + +export interface RejectInvitationRequestParams { + readonly id: number; +} + +export type RejectInvitationResponseData = Promise<StandardResponse<boolean>>; + +export interface RemoveInvitationRequestParams extends InRoomParams { + readonly id: number; +} + +export type RemoveInvitationResponseData = Promise<StandardResponse<boolean>>; diff --git a/src/shared/api/members/index.ts b/src/shared/api/members/index.ts new file mode 100644 index 00000000..42fb3527 --- /dev/null +++ b/src/shared/api/members/index.ts @@ -0,0 +1,2 @@ +export * as membersApi from './requests'; +export * from './types'; diff --git a/src/shared/api/members/requests.ts b/src/shared/api/members/requests.ts new file mode 100644 index 00000000..3d163e0b --- /dev/null +++ b/src/shared/api/members/requests.ts @@ -0,0 +1,22 @@ +import { InRoomParams, StandardResponse } from '@/shared/types'; + +import { User } from '../auth'; +import { instance } from '../request'; + +import { RemoveUserParams } from './types'; + +export const getAll = async ({ roomId, }: InRoomParams) => { + return instance.get(`members/${roomId}`).json<StandardResponse<User[]>>(); +}; + +export const exit = async ({ roomId, }: InRoomParams) => { + return instance + .delete(`members/${roomId}/exit`) + .json<StandardResponse<boolean>>(); +}; + +export const remove = async ({ roomId, userId, }: RemoveUserParams) => { + return instance + .delete(`members/${roomId}/remove/${userId}`) + .json<StandardResponse<boolean>>(); +}; diff --git a/src/shared/api/members/types.ts b/src/shared/api/members/types.ts new file mode 100644 index 00000000..e4fdf9c0 --- /dev/null +++ b/src/shared/api/members/types.ts @@ -0,0 +1,13 @@ +import { InRoomParams } from '@/shared/types'; + +export interface AddUserRoomParams extends InRoomParams { + readonly userId: number; +} + +export interface InviteByHashParams extends InRoomParams { + readonly token: string; +} + +export interface RemoveUserParams extends InRoomParams { + readonly userId: number; +} diff --git a/src/shared/api/progresses/index.ts b/src/shared/api/progresses/index.ts new file mode 100644 index 00000000..d9c71a92 --- /dev/null +++ b/src/shared/api/progresses/index.ts @@ -0,0 +1,2 @@ +export * as progressApi from './requests'; +export * from './types'; diff --git a/src/shared/api/progresses/requests.ts b/src/shared/api/progresses/requests.ts new file mode 100644 index 00000000..e5607dda --- /dev/null +++ b/src/shared/api/progresses/requests.ts @@ -0,0 +1,11 @@ +import { InRoomParams, StandardResponse } from '@/shared/types'; + +import { instance } from '../request'; + +import { Progress } from './types'; + +export const getAll = async ({ roomId, }: InRoomParams) => { + return instance + .get(`progress/${roomId}`) + .json<StandardResponse<Progress[]>>(); +}; diff --git a/src/shared/api/progresses/types.ts b/src/shared/api/progresses/types.ts new file mode 100644 index 00000000..4fbfe81d --- /dev/null +++ b/src/shared/api/progresses/types.ts @@ -0,0 +1,11 @@ +import { Number, Record, Static } from 'runtypes'; + +import { tag } from '../tags'; + +export const progress = Record({ + tag, + donecount: Number, + totalcount: Number, +}).asReadonly(); + +export interface Progress extends Static<typeof progress> {} diff --git a/src/shared/api/request/index.ts b/src/shared/api/request/index.ts new file mode 100644 index 00000000..6cc9ad10 --- /dev/null +++ b/src/shared/api/request/index.ts @@ -0,0 +1,3 @@ +export * from './request'; +export * from './types'; +export * from './lib'; diff --git a/src/shared/api/request/lib.ts b/src/shared/api/request/lib.ts new file mode 100644 index 00000000..e590c1c2 --- /dev/null +++ b/src/shared/api/request/lib.ts @@ -0,0 +1,14 @@ +export const normalizeQuery = ( + object: Record<string, any> +): Record<string, string> => { + const entries = Object.entries(object); + + return entries.reduce((object, [key, value]) => { + if (value === undefined || value === null) { + return object; + } + + object[key] = value; + return object; + }, {} as Record<string, string>); +}; diff --git a/src/shared/api/request/request.ts b/src/shared/api/request/request.ts new file mode 100644 index 00000000..29d19f75 --- /dev/null +++ b/src/shared/api/request/request.ts @@ -0,0 +1,76 @@ +import ky from 'ky'; + +import { StandardResponse } from '@/shared/types'; + +import { api } from '../../configs'; + +import { Tokens } from './types'; + +let token: string | null = null; + +export const instance = ky.create({ + mode: 'cors', + prefixUrl: api, + hooks: { + beforeRequest: [ + (request) => { + if (!token) { + return; + } + if (request.headers.get('authorization')) { + return; + } + + request.headers.set('authorization', `Bearer ${token}`); + } + ], + afterResponse: [ + (request) => { + const isLogout = request.url.includes('logout'); + + if (isLogout) { + token = null; + } + }, + async (_request, options, response) => { + if (!response.ok) { + return; + } + + const body = await response.json(); + + if ( + !('data' in body) || + typeof body.data !== 'object' || + body.data === null + ) { + return; + } + if (!('tokens' in body.data)) { + return; + } + if (!('accessToken' in body.data.tokens)) { + return; + } + + token = body.data.tokens.accessToken; + }, + + async (request, options, response) => { + if (response.status !== 401) { + return; + } + + const { data: tokens, } = await instance + .get('auth/refresh', { credentials: 'include', }) + .json<StandardResponse<Tokens>>(); + + token = tokens.accessToken; + + request.headers.set('authorization', `Bearer ${token}`); + + return ky(request); + } + ], + }, +}); diff --git a/src/shared/api/request/types.ts b/src/shared/api/request/types.ts new file mode 100644 index 00000000..454e02b7 --- /dev/null +++ b/src/shared/api/request/types.ts @@ -0,0 +1,8 @@ +import { Record, Static, String } from 'runtypes'; + +export const tokens = Record({ + accessToken: String, + refreshToken: String, +}).asReadonly(); + +export interface Tokens extends Static<typeof tokens> {} diff --git a/src/shared/api/rooms/index.ts b/src/shared/api/rooms/index.ts new file mode 100644 index 00000000..08b3762e --- /dev/null +++ b/src/shared/api/rooms/index.ts @@ -0,0 +1,2 @@ +export * as roomsApi from './requests'; +export * from './types'; diff --git a/src/shared/api/rooms/requests.ts b/src/shared/api/rooms/requests.ts new file mode 100644 index 00000000..8ad9b019 --- /dev/null +++ b/src/shared/api/rooms/requests.ts @@ -0,0 +1,35 @@ +import { InRoomParams, StandardResponse } from '@/shared/types'; + +import { instance } from '../request'; + +import { CreateRoomParams, Room, UpdateRoomParams } from './types'; + +export const getAll = async () => { + return instance.get('rooms').json<StandardResponse<Room[]>>(); +}; + +export const getOne = async ({ roomId, }: InRoomParams) => { + return instance.get(`rooms/${roomId}`).json<StandardResponse<Room>>(); +}; + +export const create = async (body: CreateRoomParams) => { + return instance + .post('rooms/create', { + json: body, + }) + .json<StandardResponse<Room>>(); +}; + +export const update = async ({ roomId, ...body }: UpdateRoomParams) => { + return instance + .put(`rooms/${roomId}/update`, { + json: body, + }) + .json<StandardResponse<Room>>(); +}; + +export const remove = async ({ roomId, }: InRoomParams) => { + return instance + .delete(`rooms/${roomId}/remove`) + .json<StandardResponse<boolean>>(); +}; diff --git a/src/shared/api/rooms/types.ts b/src/shared/api/rooms/types.ts new file mode 100644 index 00000000..52689f89 --- /dev/null +++ b/src/shared/api/rooms/types.ts @@ -0,0 +1,18 @@ +import { Record, Number, String, Static, Boolean } from 'runtypes'; + +import { InRoomParams } from '@/shared/types'; + +export const room = Record({ + id: Number, + ownerId: Number, + name: String, + description: String, + canChange: Boolean.optional(), +}).asReadonly(); + +export interface Room extends Static<typeof room> {} + +export interface CreateRoomParams extends Pick<Room, 'description' | 'name'> {} +export interface UpdateRoomParams + extends Partial<CreateRoomParams>, + InRoomParams {} diff --git a/src/shared/api/tags/index.ts b/src/shared/api/tags/index.ts new file mode 100644 index 00000000..1539b5ca --- /dev/null +++ b/src/shared/api/tags/index.ts @@ -0,0 +1,2 @@ +export * as tagsApi from './requests'; +export * from './types'; diff --git a/src/shared/api/tags/requests.ts b/src/shared/api/tags/requests.ts new file mode 100644 index 00000000..ec68a0cb --- /dev/null +++ b/src/shared/api/tags/requests.ts @@ -0,0 +1,39 @@ +import { InRoomParams, StandardResponse } from '@/shared/types'; + +import { instance } from '../request'; + +import { + GetTagParams, + CreateTagParams, + UpdateTagParams, + RemoveTagParams, + Tag +} from './types'; + +export const getAll = async (params: InRoomParams) => { + return instance.get(`tags/${params.roomId}`).json<StandardResponse<Tag[]>>(); +}; + +export const getOne = async ({ roomId, id, }: GetTagParams) => { + return instance.get(`tags/${roomId}/${id}`).json<StandardResponse<Tag>>(); +}; + +export const create = async ({ roomId, ...body }: CreateTagParams) => { + return instance + .post(`tags/${roomId}/create`, { json: body, }) + .json<StandardResponse<Tag>>(); +}; + +export const update = async ({ id, roomId, ...body }: UpdateTagParams) => { + return instance + .put(`tags/${roomId}/${id}/update`, { + json: body, + }) + .json<StandardResponse<Tag>>(); +}; + +export const remove = async ({ roomId, id, }: RemoveTagParams) => { + return instance + .delete(`tags/${roomId}/${id}/remove`) + .json<StandardResponse<boolean>>(); +}; diff --git a/src/shared/api/tags/types.ts b/src/shared/api/tags/types.ts new file mode 100644 index 00000000..4021bae0 --- /dev/null +++ b/src/shared/api/tags/types.ts @@ -0,0 +1,29 @@ +import { Record, Number, String, Static } from 'runtypes'; + +import { hex, InRoomParams } from '@/shared/types'; + +export const tag = Record({ + id: Number, + roomId: Number, + name: String, + mainColor: hex, + secondColor: hex, +}); + +export interface Tag extends Static<typeof tag> {} + +export interface GetTagParams extends InRoomParams { + readonly id: number; +} + +export interface CreateTagParams extends Omit<Tag, 'id'> {} + +export interface UpdateTagParams + extends Partial<Omit<CreateTagParams, 'roomId'>>, + InRoomParams { + readonly id: number; +} + +export interface RemoveTagParams extends InRoomParams { + readonly id: number; +} diff --git a/src/shared/api/tasks/index.ts b/src/shared/api/tasks/index.ts new file mode 100644 index 00000000..5e1d5fdb --- /dev/null +++ b/src/shared/api/tasks/index.ts @@ -0,0 +1,2 @@ +export * as tasksApi from './requests'; +export * from './types'; diff --git a/src/shared/api/tasks/requests.ts b/src/shared/api/tasks/requests.ts new file mode 100644 index 00000000..5c79a0c5 --- /dev/null +++ b/src/shared/api/tasks/requests.ts @@ -0,0 +1,46 @@ +import { StandardResponse } from '@/shared/types'; + +import { instance, normalizeQuery } from '../request'; + +import { + GetTaskParams, + CreateTaskParams, + UpdateTaskParams, + RemoveTaskParams, + Task, + GetTasksParams +} from './types'; + +export const getAll = async ({ roomId, ...query }: GetTasksParams) => { + return instance + .get(`tasks/${roomId}`, { + searchParams: new URLSearchParams(normalizeQuery(query)), + }) + .json<StandardResponse<Task[]>>(); +}; + +export const getOne = async ({ roomId, id, }: GetTaskParams) => { + return instance.get(`tasks/${roomId}/${id}`).json<StandardResponse<Task>>(); +}; + +export const create = async ({ roomId, ...body }: CreateTaskParams) => { + return instance + .post(`tasks/${roomId}/create`, { + json: body, + }) + .json<StandardResponse<Task>>(); +}; + +export const update = async ({ id, roomId, ...body }: UpdateTaskParams) => { + return instance + .put(`tasks/${roomId}/${id}/update`, { + json: body, + }) + .json<StandardResponse<Task>>(); +}; + +export const remove = async ({ roomId, id, }: RemoveTaskParams) => { + return instance + .delete(`tasks/${roomId}/${id}/remove`) + .json<StandardResponse<boolean>>(); +}; diff --git a/src/shared/api/tasks/types.ts b/src/shared/api/tasks/types.ts new file mode 100644 index 00000000..0d1b55c1 --- /dev/null +++ b/src/shared/api/tasks/types.ts @@ -0,0 +1,74 @@ +import { + Record, + Number, + String, + Static, + Union, + Literal, + Array +} from 'runtypes'; + +import { DatesFiltersParams, InRoomParams } from '@/shared/types'; + +import { user } from '../auth'; +import { tag } from '../tags'; + +export const taskStatus = Union( + Literal('done'), + Literal('in_progress'), + Literal('review'), + Literal('ready') +); + +export type TaskStatus = Static<typeof taskStatus>; +export const statuses: TaskStatus[] = [ + 'done', + 'in_progress', + 'ready', + 'review' +]; + +export const task = Record({ + id: Number, + roomId: Number, + tags: Array(tag), + author: user, + title: String, + description: String.nullable(), + status: taskStatus, + createdAt: String, + updatedAt: String.nullable(), +}); + +export interface Task extends Static<typeof task> {} + +export interface GroupedByStatusTasks { + readonly ready: Task[]; + readonly in_progress: Task[]; + readonly needReview: Task[]; + readonly done: Task[]; +} + +export interface GetTasksParams extends InRoomParams, DatesFiltersParams { + readonly authorIds?: number[]; + readonly tagIds?: number[]; +} + +export interface GetTaskParams extends InRoomParams { + readonly id: number; +} + +export interface CreateTaskParams + extends Pick<Task, 'roomId' | 'title' | 'status' | 'description'> { + readonly tagIds: number[]; +} + +export interface UpdateTaskParams + extends Partial<Omit<CreateTaskParams, 'roomId'>>, + InRoomParams { + readonly id: number; +} + +export interface RemoveTaskParams extends InRoomParams { + readonly id: number; +} diff --git a/src/shared/api/users/index.ts b/src/shared/api/users/index.ts new file mode 100644 index 00000000..daf04b7c --- /dev/null +++ b/src/shared/api/users/index.ts @@ -0,0 +1,2 @@ +export * as usersApi from './requests'; +export * from './types'; diff --git a/src/shared/api/users/requests.ts b/src/shared/api/users/requests.ts new file mode 100644 index 00000000..398e2f5a --- /dev/null +++ b/src/shared/api/users/requests.ts @@ -0,0 +1,14 @@ +import { StandardResponse } from '@/shared/types'; + +import { User } from '../auth'; +import { instance, normalizeQuery } from '../request'; + +import { SearchUsersQuery } from './types'; + +export const searchUsers = async (query: SearchUsersQuery) => { + return instance + .get('users', { + searchParams: new URLSearchParams(normalizeQuery(query)), + }) + .json<StandardResponse<User[]>>(); +}; diff --git a/src/shared/api/users/types.ts b/src/shared/api/users/types.ts new file mode 100644 index 00000000..24b649d3 --- /dev/null +++ b/src/shared/api/users/types.ts @@ -0,0 +1,3 @@ +export interface SearchUsersQuery { + readonly username: string; +} diff --git a/src/shared/components/Checkbox/Checkbox.tsx b/src/shared/components/Checkbox/Checkbox.tsx deleted file mode 100644 index bca2d528..00000000 --- a/src/shared/components/Checkbox/Checkbox.tsx +++ /dev/null @@ -1,51 +0,0 @@ -import * as React from 'react'; -import { - FormControlLabel, - Checkbox as CheckboxMUI, - CheckboxProps as MUICheckboxProps -} from '@mui/material'; -import { - FieldValues, - useController, - UseControllerProps, - UseControllerReturn -} from 'react-hook-form'; -import { CommonProps } from '@/types'; - -export interface CheckboxProps<FormValues extends FieldValues> - extends CommonProps, - UseControllerProps<FormValues>, - Omit< - MUICheckboxProps, - keyof UseControllerProps | keyof UseControllerReturn - > { - readonly label?: string | null; -} - -export const Checkbox = <FormValues extends FieldValues>( - props: CheckboxProps<FormValues> -) => { - const { - label, - name, - control, - defaultValue, - rules, - shouldUnregister, - ...rest - } = props; - const { field, } = useController({ - name, - control, - defaultValue, - rules, - shouldUnregister, - }); - const { ref, ...controls } = field; - return ( - <FormControlLabel - control={<CheckboxMUI {...rest} {...controls} inputRef={ref} />} - label={label} - /> - ); -}; diff --git a/src/shared/components/Checkbox/index.ts b/src/shared/components/Checkbox/index.ts deleted file mode 100644 index 2fc90789..00000000 --- a/src/shared/components/Checkbox/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { Checkbox, type CheckboxProps } from './Checkbox'; diff --git a/src/shared/components/DateTime/DateTime.tsx b/src/shared/components/DateTime/DateTime.tsx deleted file mode 100644 index 0c0b2222..00000000 --- a/src/shared/components/DateTime/DateTime.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import * as React from 'react'; -import { Typography } from '@mui/material'; -import dayjs from 'dayjs'; -import { CommonProps } from '@/types'; - -export interface DateTimeProps extends CommonProps { - readonly date: string | number | Date; - readonly format: string; -} - -export const DateTime: React.FC<DateTimeProps> = React.memo(function Datetime( - props -) { - const { className, date, format } = props; - const jsDate = new Date(date).toISOString(); - const showDate = dayjs(jsDate).format(format); - return ( - <Typography - className={className} - variant='body2' - dateTime={jsDate} - component='time'> - {showDate} - </Typography> - ); -}); diff --git a/src/shared/components/DateTime/index.ts b/src/shared/components/DateTime/index.ts deleted file mode 100644 index ec68bb8d..00000000 --- a/src/shared/components/DateTime/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { DateTime, type DateTimeProps } from './DateTime'; diff --git a/src/shared/components/EditMenu/EditMenu.tsx b/src/shared/components/EditMenu/EditMenu.tsx deleted file mode 100644 index abaae723..00000000 --- a/src/shared/components/EditMenu/EditMenu.tsx +++ /dev/null @@ -1,35 +0,0 @@ -import * as React from 'react'; -import { IconButton, Menu } from '@mui/material'; -import MoreHorizIcon from '@mui/icons-material/MoreHoriz'; -import { useToggle } from '@/hooks'; -import { CommonProps, Size } from '@/types'; -import { MenuOption, MenuItem } from '@/shared/components'; - -export interface EditMenuProps extends CommonProps { - readonly alt?: string; - readonly options: MenuOption<object>[]; - readonly size?: Size; -} - -export const EditMenu: React.FC<EditMenuProps> = React.memo((props) => { - const { options, className, size, alt } = props; - const [isOpen, toggle] = useToggle(); - const [reference, setReference] = React.useState<HTMLElement | null>(null); - return ( - <div className={className}> - <IconButton - onClick={toggle} - size={size} - tabIndex={0} - title={alt} - ref={setReference}> - <MoreHorizIcon /> - </IconButton> - <Menu anchorEl={reference} open={isOpen} onClose={toggle}> - {options.map((option) => ( - <MenuItem {...option} key={option.label} /> - ))} - </Menu> - </div> - ); -}); diff --git a/src/shared/components/EditMenu/index.ts b/src/shared/components/EditMenu/index.ts deleted file mode 100644 index b373ead1..00000000 --- a/src/shared/components/EditMenu/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { EditMenu, type EditMenuProps as EditMenuComponent } from './EditMenu'; diff --git a/src/shared/components/Field/Field.module.css b/src/shared/components/Field/Field.module.css deleted file mode 100644 index 93fdd1f2..00000000 --- a/src/shared/components/Field/Field.module.css +++ /dev/null @@ -1,11 +0,0 @@ -.field { - display: grid; - - row-gap: 5px; -} - -.error { - --outline: var(--error); - --border: var(--error-lighter); - --text: var(--error-lighter); -} diff --git a/src/shared/components/Field/Field.module.css.d.ts b/src/shared/components/Field/Field.module.css.d.ts deleted file mode 100644 index 1697a59b..00000000 --- a/src/shared/components/Field/Field.module.css.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -declare const styles: { - readonly field: string; - readonly error: string; -}; -export = styles; diff --git a/src/shared/components/Field/Field.tsx b/src/shared/components/Field/Field.tsx deleted file mode 100644 index 20c79177..00000000 --- a/src/shared/components/Field/Field.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import * as React from 'react'; -import { TextField, TextFieldProps } from '@mui/material'; -import { - FieldValues, - useController, - UseControllerProps, - UseControllerReturn, -} from 'react-hook-form'; -import { CommonProps } from '@/types'; - -export interface FieldProps<FormValues extends FieldValues> - extends CommonProps, - UseControllerProps<FormValues>, - Omit< - TextFieldProps, - keyof UseControllerProps | keyof UseControllerReturn - > {} - -export const Field = <FormValues extends FieldValues>( - props: FieldProps<FormValues> -) => { - const { name, control, defaultValue, rules, shouldUnregister, ...rest } = - props; - const { field, fieldState } = useController({ - name, - control, - defaultValue, - rules, - shouldUnregister, - }); - const { ref, ...controls } = field; - const { error } = fieldState; - return ( - <TextField - {...rest} - {...controls} - inputRef={ref} - error={!!error} - helperText={error?.message} - /> - ); -}; diff --git a/src/shared/components/Field/index.ts b/src/shared/components/Field/index.ts deleted file mode 100644 index 5ba95574..00000000 --- a/src/shared/components/Field/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { Field, type FieldProps } from './Field'; diff --git a/src/shared/components/GroupLabel/GroupLabel.module.css b/src/shared/components/GroupLabel/GroupLabel.module.css deleted file mode 100644 index d3c5526e..00000000 --- a/src/shared/components/GroupLabel/GroupLabel.module.css +++ /dev/null @@ -1,9 +0,0 @@ -.label { - display: inline-block; - - width: max-content; - - padding: 2px 13px; - - border-radius: 100px; -} diff --git a/src/shared/components/GroupLabel/GroupLabel.tsx b/src/shared/components/GroupLabel/GroupLabel.tsx deleted file mode 100644 index 76ab240b..00000000 --- a/src/shared/components/GroupLabel/GroupLabel.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import * as React from 'react'; -import cn from 'classnames'; -import { SxProps, Typography } from '@mui/material'; -import { CommonProps } from '@/types'; -import { Group } from '@/models'; - -import styles from './GroupLabel.module.css'; - -export interface GroupLabelProps - extends CommonProps, - Omit<Group, 'id' | 'roomId'> {} - -export const GroupLabel: React.FC<GroupLabelProps> = React.memo( - function GroupLabel(props) { - const { className, mainColor, name, secondColor } = props; - const sx: SxProps = { - backgroundColor: secondColor, - color: mainColor, - }; - - return ( - <Typography - className={cn(styles.label, className)} - variant='body2' - sx={sx}> - {name} - </Typography> - ); - } -); diff --git a/src/shared/components/GroupLabel/index.ts b/src/shared/components/GroupLabel/index.ts deleted file mode 100644 index ba5e8cc4..00000000 --- a/src/shared/components/GroupLabel/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { GroupLabel, type GroupLabelProps } from './GroupLabel'; diff --git a/src/shared/components/LoadingIndicator/LoadingIndicator.module.css.d.ts b/src/shared/components/LoadingIndicator/LoadingIndicator.module.css.d.ts deleted file mode 100644 index 1d98473b..00000000 --- a/src/shared/components/LoadingIndicator/LoadingIndicator.module.css.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -declare const styles: { - readonly indicatorContainer: string; - readonly circleGroup: string; - readonly circle: string; - readonly jump: string; - readonly small: string; - readonly medium: string; - readonly large: string; - readonly circle1: string; - readonly circle2: string; - readonly circle3: string; - readonly circle4: string; -}; -export = styles; diff --git a/src/shared/components/LoadingIndicator/LoadingIndicator.tsx b/src/shared/components/LoadingIndicator/LoadingIndicator.tsx deleted file mode 100644 index e4e4dabd..00000000 --- a/src/shared/components/LoadingIndicator/LoadingIndicator.tsx +++ /dev/null @@ -1,35 +0,0 @@ -import cn from 'classnames'; -import * as React from 'react'; -import { Typography } from '@mui/material'; -import { CommonProps, Size } from '@/types'; - -import styles from './LoadingIndicator.module.css'; - -export interface LoadingIndicatorProps extends CommonProps { - readonly size?: Size; - readonly text?: string | null; -} - -export const LoadingIndicator: React.FC<LoadingIndicatorProps> = (props) => { - const { className, text, size = 'medium', } = props; - const classes = cn(styles.indicatorContainer, styles[size]); - - return ( - <div className={className}> - <progress className='visibility-hidden' /> - <div className={classes}> - <div className={styles.circleGroup}> - <span className={cn(styles.circle, styles.circle1)} /> - <span className={cn(styles.circle, styles.circle2)} /> - <span className={cn(styles.circle, styles.circle3)} /> - <span className={cn(styles.circle, styles.circle4)} /> - </div> - {text && ( - <Typography align='center' fontWeight={500} component='h2'> - {text} - </Typography> - )} - </div> - </div> - ); -}; diff --git a/src/shared/components/LoadingIndicator/index.ts b/src/shared/components/LoadingIndicator/index.ts deleted file mode 100644 index bd8ce35b..00000000 --- a/src/shared/components/LoadingIndicator/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export { - LoadingIndicator, - type LoadingIndicatorProps, -} from './LoadingIndicator'; diff --git a/src/shared/components/LoadingWrapper/LoadingWrapper.module.css b/src/shared/components/LoadingWrapper/LoadingWrapper.module.css deleted file mode 100644 index e318dcd3..00000000 --- a/src/shared/components/LoadingWrapper/LoadingWrapper.module.css +++ /dev/null @@ -1,10 +0,0 @@ -.wrapper { - display: flex; - justify-content: center; - align-items: center; - - width: 100%; - height: 100%; - - background-color: white; -} diff --git a/src/shared/components/LoadingWrapper/LoadingWrapper.tsx b/src/shared/components/LoadingWrapper/LoadingWrapper.tsx deleted file mode 100644 index 8e3dab46..00000000 --- a/src/shared/components/LoadingWrapper/LoadingWrapper.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import * as React from 'react'; -import cn from 'classnames'; -import { CommonProps } from '@/types'; - -import styles from './LoadingWrapper.module.css'; - -export interface LoadingWrapperProps extends CommonProps { - readonly isLoading: boolean; - readonly loadingIndicator: React.ReactElement; -} - -export const LoadingWrapper: React.FC< - React.PropsWithChildren<LoadingWrapperProps> -> = (props) => { - const { className, isLoading, loadingIndicator, children } = props; - return isLoading ? ( - <div className={cn(styles.wrapper, className)}>{loadingIndicator}</div> - ) : ( - (children as React.ReactElement) - ); -}; diff --git a/src/shared/components/LoadingWrapper/index.ts b/src/shared/components/LoadingWrapper/index.ts deleted file mode 100644 index cc628924..00000000 --- a/src/shared/components/LoadingWrapper/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { LoadingWrapper, type LoadingWrapperProps } from './LoadingWrapper'; diff --git a/src/shared/components/MainPopup/MainPopup.module.css b/src/shared/components/MainPopup/MainPopup.module.css deleted file mode 100644 index 41f0090c..00000000 --- a/src/shared/components/MainPopup/MainPopup.module.css +++ /dev/null @@ -1,20 +0,0 @@ -.overlay { - display: grid; - - row-gap: 10px; - - padding: 10px; - margin: 0 10px; - - background-color: white; - - border-radius: 8px; - box-shadow: rgba(99, 99, 99, 0.4) 0 2px 8px 0px; - border-color: rgba(162, 179, 207, 0.2); -} - -.header { - font-weight: 500; - - text-align: center; -} diff --git a/src/shared/components/MainPopup/MainPopup.module.css.d.ts b/src/shared/components/MainPopup/MainPopup.module.css.d.ts deleted file mode 100644 index 8d8717bb..00000000 --- a/src/shared/components/MainPopup/MainPopup.module.css.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -declare const styles: { - readonly overlay: string; - readonly header: string; -}; -export = styles; diff --git a/src/shared/components/MainPopup/MainPopup.tsx b/src/shared/components/MainPopup/MainPopup.tsx deleted file mode 100644 index 4c842e7e..00000000 --- a/src/shared/components/MainPopup/MainPopup.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import * as React from 'react'; -import { Dialog, DialogContent, DialogTitle } from '@mui/material'; -import { CommonProps, VoidFunction } from '@/types'; - -export interface MainPopupProps extends CommonProps { - readonly isOpen: boolean; - readonly onClose: VoidFunction; - readonly header: string; - readonly closeOnEsc?: boolean; -} - -export const MainPopup: React.FC<React.PropsWithChildren<MainPopupProps>> = ( - props -) => { - const { isOpen, onClose, children, className, header, } = props; - return ( - <Dialog className={className} open={isOpen} onClose={onClose}> - <DialogTitle align='center'>{header}</DialogTitle> - <DialogContent>{children}</DialogContent> - </Dialog> - ); -}; diff --git a/src/shared/components/MainPopup/index.ts b/src/shared/components/MainPopup/index.ts deleted file mode 100644 index ea7c109a..00000000 --- a/src/shared/components/MainPopup/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { MainPopup, type MainPopupProps } from './MainPopup'; diff --git a/src/shared/components/MenuItem/MenuItem.tsx b/src/shared/components/MenuItem/MenuItem.tsx deleted file mode 100644 index 4147b648..00000000 --- a/src/shared/components/MenuItem/MenuItem.tsx +++ /dev/null @@ -1,50 +0,0 @@ -import * as React from 'react'; -import { - ListItemIcon, - ListItemText, - MenuItem as MenuItemMUI, -} from '@mui/material'; -import { Link } from 'atomic-router-react'; -import { RouteInstance, RouteQuery } from 'atomic-router'; -import { CommonProps } from '@/types'; - -interface BaseMenuOption { - readonly label: string; - readonly icon?: React.ReactElement; -} - -interface ButtonMenuOption extends BaseMenuOption { - readonly onClick: React.MouseEventHandler<HTMLButtonElement>; - readonly to?: never; - readonly params?: never; - readonly query?: never; -} - -interface LinkMenuOption<P extends object> extends BaseMenuOption { - readonly onClick?: React.MouseEventHandler<HTMLButtonElement>; - readonly to: RouteInstance<P>; - readonly params: P; - readonly query?: RouteQuery; -} - -export type MenuOption<P extends object> = ButtonMenuOption | LinkMenuOption<P>; - -export type MenuItemProps<P extends object> = CommonProps & - MenuOption<P> & { - readonly role?: React.AriaRole; - }; - -export const MenuItem = <P extends object>( - props: React.PropsWithChildren<MenuItemProps<P>> -) => { - const { label, icon, onClick, to, params, query, ...rest } = props; - const itemButtonProps = to - ? { component: Link, to, params, query, onClick } - : { onClick, component: 'button' }; - return ( - <MenuItemMUI {...rest} {...(itemButtonProps as any)}> - {icon && <ListItemIcon>{icon}</ListItemIcon>} - <ListItemText>{label}</ListItemText> - </MenuItemMUI> - ); -}; diff --git a/src/shared/components/MenuItem/index.ts b/src/shared/components/MenuItem/index.ts deleted file mode 100644 index d7e768a9..00000000 --- a/src/shared/components/MenuItem/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { MenuItem, type MenuOption } from './MenuItem'; diff --git a/src/shared/components/SkeletonGroupLabel/SkeletonGroupLabel.tsx b/src/shared/components/SkeletonGroupLabel/SkeletonGroupLabel.tsx deleted file mode 100644 index 4275128f..00000000 --- a/src/shared/components/SkeletonGroupLabel/SkeletonGroupLabel.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import * as React from 'react'; -import { Skeleton } from '@mui/material'; -import { CommonProps } from '@/types'; - -export interface SkeletonGroupLabelProps extends CommonProps {} - -export const SkeletonGroupLabel: React.FC<SkeletonGroupLabelProps> = React.memo( - function SkeletonGroupLabel(props) { - const { className } = props; - return <Skeleton className={className} width='5em' height='1em + 4px' />; - } -); diff --git a/src/shared/components/SkeletonGroupLabel/index.ts b/src/shared/components/SkeletonGroupLabel/index.ts deleted file mode 100644 index 5415ce3b..00000000 --- a/src/shared/components/SkeletonGroupLabel/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export { - SkeletonGroupLabel, - type SkeletonGroupLabelProps, -} from './SkeletonGroupLabel'; diff --git a/src/shared/components/index.ts b/src/shared/components/index.ts deleted file mode 100644 index f535c53e..00000000 --- a/src/shared/components/index.ts +++ /dev/null @@ -1,10 +0,0 @@ -export * from './Checkbox'; -export * from './DateTime'; -export * from './EditMenu'; -export * from './Field'; -export * from './GroupLabel'; -export * from './LoadingIndicator'; -export * from './LoadingWrapper'; -export * from './MainPopup'; -export * from './MenuItem'; -export * from './SkeletonGroupLabel'; diff --git a/src/shared/configs/const/api.ts b/src/shared/configs/const/api.ts new file mode 100644 index 00000000..2c9ffece --- /dev/null +++ b/src/shared/configs/const/api.ts @@ -0,0 +1,4 @@ +// eslint-disable-next-line import/no-mutable-exports +export const base = import.meta.env.VITE_API_HOST ?? ''; + +export const api = `${base}/api`; diff --git a/src/shared/configs/const/forms.ts b/src/shared/configs/const/forms.ts new file mode 100644 index 00000000..8e6e22cd --- /dev/null +++ b/src/shared/configs/const/forms.ts @@ -0,0 +1,4 @@ +export const ALLOWED_SYMBOLS = /[a-zA-Z0-9_\- !*+()]/; + +export const MIN_LENGTH = 6; +export const MAX_SHORT_LENGTH = 32; diff --git a/src/const/index.ts b/src/shared/configs/const/index.ts similarity index 100% rename from src/const/index.ts rename to src/shared/configs/const/index.ts diff --git a/src/shared/configs/const/routes.ts b/src/shared/configs/const/routes.ts new file mode 100644 index 00000000..4d0fc257 --- /dev/null +++ b/src/shared/configs/const/routes.ts @@ -0,0 +1,27 @@ +export const getParams = { + popup: 'popup', + taskStatus: 'task-status', + taskId: 'task', + tagId: 'tag', + roomId: 'room', + tab: 'tab', + userId: 'user', + before: 'b', + after: 'a', + actionId: 'action', + sphereId: 'sphere', + count: 'cnt', + page: 'p', +} as const; + +export const popupsMap = { + createTask: 'create-task', + updateTask: 'update-task', + tags: 'tags', + createTag: 'create-tag', + updateTag: 'update-tag', + createRoom: 'create-room', + updateRoom: 'update-room', + createInvitation: 'i-user', + task: 'task', +} as const; diff --git a/src/const/ui.ts b/src/shared/configs/const/ui.ts similarity index 100% rename from src/const/ui.ts rename to src/shared/configs/const/ui.ts diff --git a/src/shared/configs/i18n/index.ts b/src/shared/configs/i18n/index.ts new file mode 100644 index 00000000..159ad839 --- /dev/null +++ b/src/shared/configs/i18n/index.ts @@ -0,0 +1,21 @@ +import i18n from 'i18next'; +import LanguageDetector from 'i18next-browser-languagedetector'; +import Backend from 'i18next-http-backend'; +import { initReactI18next } from 'react-i18next'; + +i18n + .use(Backend) + .use(LanguageDetector) + .use(initReactI18next) + .init({ + fallbackLng: 'en', + partialBundledLanguages: true, + debug: import.meta.env.DEV, + interpolation: { + escapeValue: false, + }, + defaultNS: ['common'], + resources: {}, + }); + +export { i18n }; diff --git a/src/shared/configs/i18n/locales/en/activate.json b/src/shared/configs/i18n/locales/en/activate.json new file mode 100644 index 00000000..c10d03d3 --- /dev/null +++ b/src/shared/configs/i18n/locales/en/activate.json @@ -0,0 +1,12 @@ +{ + "title": "Activating the account", + "text_loading": "The account is activating", + "text_success": "The account has been successfully activated", + "text_fail": "The account has not been activated", + "actions": { + "navigate": "Go to login page" + }, + "errors": { + "already_activated": "The account has already been activated" + } +} diff --git a/src/shared/configs/i18n/locales/en/activities.json b/src/shared/configs/i18n/locales/en/activities.json new file mode 100644 index 00000000..57754c53 --- /dev/null +++ b/src/shared/configs/i18n/locales/en/activities.json @@ -0,0 +1,24 @@ +{ + "card": { + "text": "User {{ activist }} has $t(type.{{ type }}) the $t(spheres.{{ sphere }})" + }, + "list": { + "empty_text": "Here will be shown activities in room" + }, + "spheres": { + "task": "task", + "tag": "tag", + "comment": "comment" + }, + "type": { + "create": "created", + "update": "updated", + "remove": "removed", + "create_comment": "left" + }, + "actions": { + "retry_actions": { + "text": "Activities were not loaded. Click to retry" + } + } +} diff --git a/src/shared/configs/i18n/locales/en/common.json b/src/shared/configs/i18n/locales/en/common.json new file mode 100644 index 00000000..1a1cb769 --- /dev/null +++ b/src/shared/configs/i18n/locales/en/common.json @@ -0,0 +1,52 @@ +{ + "loading": "Loading...", + "actions": { + "add": "Add", + "create": "Create", + "update": "Update", + "edit": "Edit", + "save": "Save", + "remove": "Remove", + "exit": "Exit", + "close": "Close", + "cancel": "Cancel", + "open": "Open", + "retry": "Retry" + }, + "errors": { + "default": "Something went wrong" + }, + "navigation": { + "items": { + "rooms": "Rooms" + }, + "menu": { + "title": "My rooms" + } + }, + "fields": { + "create_after": "Create after", + "create_before": "Create before" + }, + "languages": { + "ru": "Russian", + "en": "English", + "ru_short": "Ru", + "en_short": "En" + }, + "color_schemes": { + "schemes": { + "dark": "Dark scheme", + "system": "OS scheme", + "light": "Light scheme" + }, + "activated": "$t(color_schemes.schemes.{{ scheme }}) activate now" + }, + "profile_menu": { + "title": "{{ username }}'s profile settings", + "items": { + "settings": "Settings", + "logout": "Logout" + } + } +} diff --git a/src/shared/configs/i18n/locales/en/login.json b/src/shared/configs/i18n/locales/en/login.json new file mode 100644 index 00000000..e7a9d461 --- /dev/null +++ b/src/shared/configs/i18n/locales/en/login.json @@ -0,0 +1,29 @@ +{ + "title": "Login", + "has_account_question": "Don't you have an account yet?", + "create_right_now": ["Then", "create it", "right now"], + "login_form": { + "fields": { + "email": "Email", + "password": "Password", + "remember_me": "Remember me" + }, + "submit": "Login", + "errors": { + "email": { + "empty": "Email must be provided", + "email": "It's an invalid email pattern", + "min_length": "Email must contain at least {{ min_symbols_count }} letters", + "max_length": "Email must contain no more {{ max_symbols_count }} letters", + "not_found": "User was not found" + }, + "password": { + "empty": "Password must be provided", + "pattern": "Password can only contain latins alphas, numeric and !, *, (, ), _, +", + "min_length": "Password must contain at least {{ min_symbols_count }} letters", + "max_length": "Password must contain no more {{ max_symbols_count }} letters", + "incorrect_password": "Incorrect password" + } + } + } +} diff --git a/src/shared/configs/i18n/locales/en/registration.json b/src/shared/configs/i18n/locales/en/registration.json new file mode 100644 index 00000000..5046d3fd --- /dev/null +++ b/src/shared/configs/i18n/locales/en/registration.json @@ -0,0 +1,38 @@ +{ + "title": "Registration", + "has_account_question": "Do you have an account?", + "login_right_now": ["Then", "login it", "right now"], + "registration_form": { + "fields": { + "email": "Email", + "username": "Username", + "password": "Password", + "repeat_password": "Repeat password" + }, + "submit": "Registration", + "errors": { + "email": { + "empty": "Email must be provided", + "email": "It's an invalid email pattern", + "min_length": "Email must contain at least {{ min_symbols_count }} letters", + "max_length": "Email must contain no more {{ max_symbols_count }} letters", + "exists": "User already registered" + }, + "username": { + "empty": "Username must be provided", + "pattern": "Username can only contain latins alphas, numeric and !, *, (, ), _, +", + "min_length": "Username must contain at least {{ min_symbols_count }} letters", + "max_length": "Username must contain no more {{ max_symbols_count }} letters" + }, + "password": { + "empty": "Password must be provided", + "pattern": "Password can only contain latins alphas, numeric and !, *, (, ), _, +", + "min_length": "Password must contain at least {{ min_symbols_count }} letters", + "max_length": "Password must contain no more {{ max_symbols_count }} letters" + }, + "repeat_password": { + "equal": "Passwords must be equal" + } + } + } +} diff --git a/src/shared/configs/i18n/locales/en/room-activities.json b/src/shared/configs/i18n/locales/en/room-activities.json new file mode 100644 index 00000000..eec5cb8a --- /dev/null +++ b/src/shared/configs/i18n/locales/en/room-activities.json @@ -0,0 +1,17 @@ +{ + "title": "Activities", + "actions": { + "filter_activities": { + "title": "Activities filters", + "fields": { + "types": "Activities types", + "spheres": "Activities spheres", + "users": "Users" + }, + "actions": { + "submit": "Apply", + "reset": "Reset" + } + } + } +} diff --git a/src/shared/configs/i18n/locales/en/room-invitation.json b/src/shared/configs/i18n/locales/en/room-invitation.json new file mode 100644 index 00000000..b65dc20d --- /dev/null +++ b/src/shared/configs/i18n/locales/en/room-invitation.json @@ -0,0 +1,39 @@ +{ + "title": "Invitation answer", + "card": { + "title": "User {{ inviter_name }} invite you", + "text": [ + "User ", + "{{ inviter_name }}", + " inviter you, ", + "{{ user_name }}", + ", into room ", + "{{ room_name }}" + ] + }, + "actions": { + "approve": { + "actions": { + "button": "Approve" + }, + "notifications": { + "success": "Invitation was successfully approved", + "error": "Invitation was not approved" + } + }, + "reject": { + "actions": { + "button": "Reject" + }, + "notifications": { + "success": "Invitation was successfully rejected", + "error": "Invitation was not rejected" + } + }, + "via-token": { + "notifications": { + "error": "Invitation was not loaded. It's not available for you" + } + } + } +} diff --git a/src/shared/configs/i18n/locales/en/room-invitations.json b/src/shared/configs/i18n/locales/en/room-invitations.json new file mode 100644 index 00000000..a1c1c753 --- /dev/null +++ b/src/shared/configs/i18n/locales/en/room-invitations.json @@ -0,0 +1,61 @@ +{ + "title": "Invitations", + "list": { + "empty_text": "There are no invitations in room yet", + "item": { + "inviter": "Invited by {{ inviter_name }}" + } + }, + "actions": { + "invite_user": { + "title": "Invite user into room", + "title_short": "Personal invitation", + "fields": { + "user": "Username" + }, + "actions": { + "submit": "Invite {{ username }} to the room", + "submit_disabled": "Select user above" + }, + "notifications": { + "success": "Invitation was sent successfully", + "error": "Invitation was not sent" + } + }, + "generate_link": { + "title": "Generate link for mass invitation", + "title_short": "Via link", + "fields": { + "link": "Link" + }, + "actions": { + "copy": "Copy link" + }, + "notifications": { + "success": "Link was copied", + "error": "Link was not copied" + } + }, + "retry_invitations": { + "text": "Invitations were not loaded. Click to retry" + }, + "create_invitation": { + "actions": { + "open": "Invite user" + } + }, + "remove_invitation": { + "title": "Are you sure?", + "content": "Do you want to $t(common:actions.remove) this invitation? You will be able to invite him again.", + "actions": { + "open": "$t(common:actions.remove) invitation", + "agree": "$t(common:actions.remove)", + "disagree": "$t(common:actions.cancel)" + }, + "notifications": { + "success": "Invitation was removed from the room successfully", + "error": "Invitation was not removed from the room" + } + } + } +} diff --git a/src/shared/configs/i18n/locales/en/room-tags.json b/src/shared/configs/i18n/locales/en/room-tags.json new file mode 100644 index 00000000..a88aa67d --- /dev/null +++ b/src/shared/configs/i18n/locales/en/room-tags.json @@ -0,0 +1,51 @@ +{ + "title": "Tags", + "list": { + "empty_text": "There is not tags in the room yet" + }, + "actions": { + "create_tag": { + "title": "$t(common:actions.create) tag", + "actions": { + "open": "$t(common:actions.create) tag" + }, + "notifications": { + "success": "Tag was created successfully", + "error": "Tag was not created" + } + }, + "update_tag": { + "title": "$t(common:actions.update) tag", + "actions": { + "open": "$t(common:actions.update) tag" + }, + "notifications": { + "success": "Tag was updated successfully", + "error": "Tag was not updated" + } + }, + "remove_tag": { + "title": "Are you sure?", + "text": "Do you want to $t(common:actions.remove) this tag? All tasks, having only this tag, will be deleted", + "actions": { + "open": "$t(common:actions.remove) tag", + "agree": "$t(common:actions.remove)", + "disagree": "$t(common:actions.cancel)" + }, + "notifications": { + "success": "Tag was removed successfully", + "error": "Tag was not removed" + } + }, + "tag_form": { + "fields": { + "name": "Name", + "main_color": "Primary color", + "second_color": "Secondary color" + } + }, + "retry_tags": { + "text": "Tags were not loaded. Click to retry" + } + } +} diff --git a/src/shared/configs/i18n/locales/en/room-tasks.json b/src/shared/configs/i18n/locales/en/room-tasks.json new file mode 100644 index 00000000..6da049b3 --- /dev/null +++ b/src/shared/configs/i18n/locales/en/room-tasks.json @@ -0,0 +1,24 @@ +{ + "title": "Tasks", + "blocks": { + "tasks_progress": { + "title": "Tasks progress", + "empty_text": "Here will be shown your task progress", + "aria_label": "Progress of {{ tag_name }} tasks is {{ done_count }} from {{ total_count }}" + }, + "last_activities": { + "title": "Last activities", + "actions": { + "open": "$t(common:actions.open) all activities" + } + }, + "mobile_aside": { + "title": "Statistic" + } + }, + "actions": { + "retry_progress": { + "text": "Progress was not loaded. Click to retry" + } + } +} diff --git a/src/shared/configs/i18n/locales/en/room-users.json b/src/shared/configs/i18n/locales/en/room-users.json new file mode 100644 index 00000000..7f47cc25 --- /dev/null +++ b/src/shared/configs/i18n/locales/en/room-users.json @@ -0,0 +1,24 @@ +{ + "title": "Users", + "list": { + "empty_text": "There are no users in room yet" + }, + "actions": { + "remove_user": { + "title": "Are you sure?", + "content": "Do you want to $t(common:actions.remove) this user? You will be able to invite him again.", + "actions": { + "open": "$t(common:actions.remove) user", + "agree": "$t(common:actions.remove)", + "disagree": "$t(common:actions.cancel)" + }, + "notifications": { + "success": "User was removed from the room successfully", + "error": "User was not removed from the room" + } + }, + "retry_users": { + "text": "Users were not loaded. Click to retry" + } + } +} diff --git a/src/shared/configs/i18n/locales/en/room.json b/src/shared/configs/i18n/locales/en/room.json new file mode 100644 index 00000000..b1301bc9 --- /dev/null +++ b/src/shared/configs/i18n/locales/en/room.json @@ -0,0 +1,8 @@ +{ + "tabs": { + "tasks": "Tasks", + "tags": "Tags", + "activities": "Activities", + "users": "Users" + } +} diff --git a/src/shared/configs/i18n/locales/en/rooms.json b/src/shared/configs/i18n/locales/en/rooms.json new file mode 100644 index 00000000..8ae0fd1f --- /dev/null +++ b/src/shared/configs/i18n/locales/en/rooms.json @@ -0,0 +1,68 @@ +{ + "title": "Rooms", + "rooms_list": { + "empty_text": "There are no room yet. Create it" + }, + "card": { + "description": "Description" + }, + "actions": { + "exit_room": { + "name": "$t(common:actions.exit) from room", + "title": "Are you sure?", + "content": "Do you want to exit from this room?", + "actions": { + "agree": "$t(common:actions.exit)", + "disagree": "$t(common:actions.cancel)" + }, + "notifications": { + "success": "You exited from user successfully", + "error": "You didn't exit from room" + } + }, + "remove_room": { + "name": "$t(common:actions.remove) room", + "title": "Are you sure?", + "content": "Do you want to remove this room? All tasks and tags will be removed", + "actions": { + "agree": "$t(common:actions.remove)", + "disagree": "$t(common:actions.cancel)" + }, + "notifications": { + "success": "Room was removed successfully", + "error": "Room was not removed" + } + }, + "update_room": { + "name": "$t(common:actions.edit) room", + "title": "$t(common:actions.edit) room", + "notifications": { + "success": "Room was updated successfully", + "error": "Room was not updated" + } + }, + "room_form": { + "fields": { + "name": "Name", + "description": "Description" + }, + "errors": { + "name": { + "empty": "Name must be provided", + "min_length": "Name must contain at least {{ min_symbols_count }} letters", + "max_length": "Name must contain no more {{ max_symbols_count }} letters" + }, + "description": { + "max_length": "Description must contain no more {{ max_symbols_count }} letters" + } + } + }, + "create_room": { + "title": "$t(common:actions.create) room", + "notifications": { + "success": "Room was created successfully", + "error": "Room was not created" + } + } + } +} diff --git a/src/shared/configs/i18n/locales/en/tasks.json b/src/shared/configs/i18n/locales/en/tasks.json new file mode 100644 index 00000000..e6eac9db --- /dev/null +++ b/src/shared/configs/i18n/locales/en/tasks.json @@ -0,0 +1,65 @@ +{ + "statuses": { + "ready": "Ready", + "in_progress": "In progress", + "review": "Need review", + "done": "Done" + }, + "actions": { + "tasks_filters": { + "title": "Tasks filter", + "fields": { + "tags": "Tags", + "authors": "Authors" + }, + "actions": { + "submit": "Apply", + "reset": "Reset" + } + }, + "create_task": { + "title": "$t(common:actions.create) task", + "actions": { + "open": "$t(common:actions.create) task" + }, + "notifications": { + "success": "Task was created successfully", + "error": "Task was not created" + } + }, + "update_task": { + "title": "$t(common:actions.update) task", + "actions": { + "open": "$t(common:actions.update) task" + }, + "notifications": { + "success": "Task was updated successfully", + "error": "Task was not updated" + } + }, + "remove_task": { + "name": "$t(common:actions.remove) task", + "title": "Are you sure?", + "content": "Do you want to delete this task?", + "actions": { + "agree": "$t(common:actions.remove)", + "disagree": "$t(common:actions.cancel)" + }, + "notifications": { + "success": "Task was removed successfully", + "error": "Task was not removed" + } + }, + "task_form": { + "fields": { + "title": "Title", + "tags": "Tags", + "status": "Status", + "description": "Description" + } + }, + "retry_tasks": { + "text": "Tasks were not loaded. Click to retry" + } + } +} diff --git a/src/shared/configs/i18n/locales/en/thanks.json b/src/shared/configs/i18n/locales/en/thanks.json new file mode 100644 index 00000000..f268437a --- /dev/null +++ b/src/shared/configs/i18n/locales/en/thanks.json @@ -0,0 +1,11 @@ +{ + "title": "Thanks for registration", + "title_long": "{{ username }}, thanks for registration", + "content": [ + "The registration confirmation email has been sent on your email ", + ". After confirmation, you will can login into account" + ], + "actions": { + "navigate": "Go to the login page" + } +} diff --git a/src/shared/configs/i18n/locales/ru/activate.json b/src/shared/configs/i18n/locales/ru/activate.json new file mode 100644 index 00000000..e7481f76 --- /dev/null +++ b/src/shared/configs/i18n/locales/ru/activate.json @@ -0,0 +1,12 @@ +{ + "title": "Активация аккаунта", + "text_loading": "Аккаунт активируется", + "text_success": "Аккаунт был успешно активирован", + "text_fail": "Во время активации аккаунта произошла ошибка", + "actions": { + "navigate": "Перейти на страницу входа" + }, + "errors": { + "already_activated": "Аккаунт уже активирован" + } +} diff --git a/src/shared/configs/i18n/locales/ru/activities.json b/src/shared/configs/i18n/locales/ru/activities.json new file mode 100644 index 00000000..a3a147cf --- /dev/null +++ b/src/shared/configs/i18n/locales/ru/activities.json @@ -0,0 +1,25 @@ +{ + "card": { + "text": "Пользователь {{ activist }} $t(type.{{ type }}) $t(spheres.{{ sphere }}, {\"context\":\"vp\" })" + }, + "list": { + "empty_text": "Здесь будут показываться активности в комнате" + }, + "spheres": { + "task": "задача", + "task_vp": "задачу", + "tag": "тэг", + "comment": "комментарий" + }, + "type": { + "create": "создал", + "update": "изменил", + "remove": "удалил", + "create_comment": "оставил" + }, + "actions": { + "retry_actions": { + "text": "Активности не загружены. Нажмите, чтобы повторить" + } + } +} diff --git a/src/shared/configs/i18n/locales/ru/common.json b/src/shared/configs/i18n/locales/ru/common.json new file mode 100644 index 00000000..62f9bbfb --- /dev/null +++ b/src/shared/configs/i18n/locales/ru/common.json @@ -0,0 +1,52 @@ +{ + "loading": "Загрузка...", + "actions": { + "add": "Добавить", + "create": "Добавить", + "update": "Изменить", + "edit": "Изменить", + "save": "Сохранить", + "remove": "Удалить", + "exit": "Выйти", + "close": "Закрыть", + "cancel": "Отменить", + "open": "Открыть", + "retry": "Повторить" + }, + "errors": { + "default": "Что-то пошло не так" + }, + "navigation": { + "items": { + "rooms": "Комнаты" + }, + "menu": { + "title": "Мои комнаты" + } + }, + "fields": { + "create_after": "Создано после", + "create_before": "Создано до" + }, + "languages": { + "ru": "Русский", + "en": "Английский", + "ru_short": "Рус", + "en_short": "Англ" + }, + "color_schemes": { + "schemes": { + "dark": "Темная тема", + "system": "Системная тема", + "light": "Светлая тема" + }, + "activated": "Выбрана $t(color_schemes.schemes.{{ scheme }})" + }, + "profile_menu": { + "title": "Настройки профиля {{ username }}", + "items": { + "settings": "Настройки", + "logout": "Выйти" + } + } +} diff --git a/src/shared/configs/i18n/locales/ru/login.json b/src/shared/configs/i18n/locales/ru/login.json new file mode 100644 index 00000000..5c848248 --- /dev/null +++ b/src/shared/configs/i18n/locales/ru/login.json @@ -0,0 +1,29 @@ +{ + "title": "Вход", + "has_account_question": "Еще нет аккаунта?", + "create_right_now": ["Тогда", "создайте его", "прямо сейчас"], + "login_form": { + "fields": { + "email": "Электронная почта", + "password": "Пароль", + "remember_me": "Запомнить меня" + }, + "submit": "Войти", + "errors": { + "email": { + "empty": "Почта не должна быть пустой", + "email": "Неправильный адрес электронной почты", + "min_length": "Почта должна быть не короче {{ min_symbols_count }} символов", + "max_length": "Почта должна быть не длиннее {{ max_symbols_count }} символов", + "not_found": "Пользователь не найден" + }, + "password": { + "empty": "Пароль не должен быть пустым", + "pattern": "Пароль может содержать только латинский буквы, цифры и !, *, (, ), _, +", + "min_length": "Пароль должен быть не короче {{ min_symbols_count }} символов", + "max_length": "Пароль должен быть не длиннее {{ max_symbols_count }} символов", + "incorrect_password": "Неверный пароль" + } + } + } +} diff --git a/src/shared/configs/i18n/locales/ru/registration.json b/src/shared/configs/i18n/locales/ru/registration.json new file mode 100644 index 00000000..d9350fa7 --- /dev/null +++ b/src/shared/configs/i18n/locales/ru/registration.json @@ -0,0 +1,38 @@ +{ + "title": "Регистрация", + "has_account_question": "Уже есть аккаунт?", + "login_right_now": ["тогда", "войдите в него", "прямо сейчас"], + "registration_form": { + "fields": { + "email": "Электронная почта", + "username": "Имя пользователя", + "password": "Пароль", + "repeat_password": "Повторите пароль" + }, + "submit": "Зарегистрироваться", + "errors": { + "email": { + "empty": "Почта не должна быть пустой", + "email": "Неправильный адрес электронной почты", + "min_length": "Почта должна быть не короче {{ min_symbols_count }} символов", + "max_length": "Почта должна быть не длиннее {{ max_symbols_count }} символов", + "exists": "Пользователь уже существует" + }, + "username": { + "empty": "Имя пользователя не должна быть пустой", + "pattern": "Имя пользователя может содержать только латинский буквы, цифры и !, *, (, ), _, +", + "min_length": "Имя пользователя должна быть не короче {{ min_symbols_count }} символов", + "max_length": "Имя пользователя должна быть не длиннее {{ max_symbols_count }} символов" + }, + "password": { + "empty": "Пароль не должен быть пустым", + "pattern": "Пароль может содержать только латинский буквы, цифры и !, *, (, ), _, +", + "min_length": "Пароль должен быть не короче {{ min_symbols_count }} символов", + "max_length": "Пароль должен быть не длиннее {{ max_symbols_count }} символов" + }, + "repeat_password": { + "equal": "Пароли должны совпадать" + } + } + } +} diff --git a/src/shared/configs/i18n/locales/ru/room-activities.json b/src/shared/configs/i18n/locales/ru/room-activities.json new file mode 100644 index 00000000..03519dbd --- /dev/null +++ b/src/shared/configs/i18n/locales/ru/room-activities.json @@ -0,0 +1,17 @@ +{ + "title": "Активности", + "actions": { + "filter_activities": { + "title": "Фильтры активностей", + "fields": { + "types": "Типы активностей", + "spheres": "Сферы активностей", + "users": "Пользователи" + }, + "actions": { + "submit": "Применить", + "reset": "Сбросить" + } + } + } +} diff --git a/src/shared/configs/i18n/locales/ru/room-invitation.json b/src/shared/configs/i18n/locales/ru/room-invitation.json new file mode 100644 index 00000000..fafdc451 --- /dev/null +++ b/src/shared/configs/i18n/locales/ru/room-invitation.json @@ -0,0 +1,39 @@ +{ + "title": "Ответ на приглашение", + "card": { + "title": "Пользователь {{ inviter_name }} приглашает вас", + "text": [ + "Пользователь ", + "{{ inviter_name }}", + " приглашает вас, ", + "{{ user_name }}", + ", в комнату ", + "{{ room_name }}" + ] + }, + "actions": { + "approve": { + "actions": { + "button": "Принять" + }, + "notifications": { + "success": "Приглашение было успешно принято", + "error": "Приглашение не было принято" + } + }, + "reject": { + "actions": { + "button": "Отклонить" + }, + "notifications": { + "success": "Приглашение было успешно отклонено", + "error": "Приглашение не было отклонено" + } + }, + "via-token": { + "notifications": { + "error": "Приглашение не было загружено. Оно не доступно для вас" + } + } + } +} diff --git a/src/shared/configs/i18n/locales/ru/room-invitations.json b/src/shared/configs/i18n/locales/ru/room-invitations.json new file mode 100644 index 00000000..69be3913 --- /dev/null +++ b/src/shared/configs/i18n/locales/ru/room-invitations.json @@ -0,0 +1,61 @@ +{ + "title": "Приглашения", + "list": { + "empty_text": "В комнате еще нет приглашений", + "item": { + "inviter": "Приглашен пользователем {{ inviter_name }}" + } + }, + "actions": { + "invite_user": { + "title": "Пригласить пользователя в комнату", + "title_short": "Персональное приглашение", + "fields": { + "user": "Имя пользователя" + }, + "actions": { + "submit": "Пригласить {{ username }} в комнату", + "submit_disabled": "Выберите пользователя выше" + }, + "notifications": { + "success": "Приглашение было отправлено успешно", + "error": "Приглашение не было отправлено" + } + }, + "generate_link": { + "title": "Сгенерировать ссылку-приглашение", + "title_short": "По ссылке", + "fields": { + "link": "Ссылка" + }, + "actions": { + "copy": "Скопировать ссылку" + }, + "notifications": { + "success": "Ссылка была скопирована", + "error": "Ссылка не была скопирована" + } + }, + "retry_invitations": { + "text": "Приглашения не были загружены. Нажмите, чтобы повторить" + }, + "create_invitation": { + "actions": { + "open": "Пригласить пользователя" + } + }, + "remove_invitation": { + "title": "вы уверены?", + "content": "Вы хотите $t(common:actions.remove) это приглашение? Вы сможете пригласить пользователя снова", + "actions": { + "open": "$t(common:actions.remove) приглашение", + "agree": "$t(common:actions.remove)", + "disagree": "$t(common:actions.cancel)" + }, + "notifications": { + "success": "Приглашение было успешно удалено", + "error": "Приглашение не было удалено" + } + } + } +} diff --git a/src/shared/configs/i18n/locales/ru/room-tags.json b/src/shared/configs/i18n/locales/ru/room-tags.json new file mode 100644 index 00000000..0da3c886 --- /dev/null +++ b/src/shared/configs/i18n/locales/ru/room-tags.json @@ -0,0 +1,51 @@ +{ + "title": "Тэги", + "list": { + "empty_text": "В комнате еще не создан ни один тэг." + }, + "actions": { + "create_tag": { + "title": "$t(common:actions.create) тэг", + "actions": { + "open": "$t(common:actions.create) тэг" + }, + "notifications": { + "success": "Тэг был успешно создан", + "error": "Тэг не был создан" + } + }, + "update_tag": { + "title": "$t(common:actions.update) тэг", + "actions": { + "open": "$t(common:actions.update) тэг" + }, + "notifications": { + "success": "Тэг был успешно обновлен", + "error": "Тэг не был обновлен" + } + }, + "remove_tag": { + "title": "Вы уверены?", + "text": "Вы хотите удалить этот тэг? Все задачи, которые имеют только этот тэг, будут удалены", + "actions": { + "open": "$t(common:actions.remove) тэг", + "agree": "$t(common:actions.remove)", + "disagree": "$t(common:actions.cancel)" + }, + "notifications": { + "success": "Тэг был успешно удален", + "error": "Тэг не был удален" + } + }, + "tag_form": { + "fields": { + "name": "Название", + "main_color": "Главный цвет", + "second_color": "Вторичный цвет" + } + }, + "retry_tags": { + "text": "Тэги не были загружены. Нажмите, чтобы повторить" + } + } +} diff --git a/src/shared/configs/i18n/locales/ru/room-tasks.json b/src/shared/configs/i18n/locales/ru/room-tasks.json new file mode 100644 index 00000000..6d4033ec --- /dev/null +++ b/src/shared/configs/i18n/locales/ru/room-tasks.json @@ -0,0 +1,24 @@ +{ + "title": "Задачи", + "blocks": { + "tasks_progress": { + "title": "Прогресс задач", + "empty_text": "Здесь будут отображаться процесс решения задач", + "aria_label": "Прогресс решения задач с тэгом {{ tag_name }} - {{ done_count }} из {{ total_count }}" + }, + "last_activities": { + "title": "Последние активности", + "actions": { + "open": "$t(common:actions.open) все активности" + } + }, + "mobile_aside": { + "title": "Статистика" + } + }, + "actions": { + "retry_progress": { + "text": "Прогресс не был загружен. Нажмите, чтобы повторить" + } + } +} diff --git a/src/shared/configs/i18n/locales/ru/room-users.json b/src/shared/configs/i18n/locales/ru/room-users.json new file mode 100644 index 00000000..26798f1a --- /dev/null +++ b/src/shared/configs/i18n/locales/ru/room-users.json @@ -0,0 +1,24 @@ +{ + "title": "Пользователи", + "list": { + "empty_text": "В комнате еще нет пользователей" + }, + "actions": { + "remove_user": { + "title": "Вы уверены?", + "content": "Вы уверены, что хотите $t(common:actions.remove) этого пользователя? Вы сможете пригласить его потом снова", + "actions": { + "open": "$t(common:actions.remove) пользователя", + "agree": "$t(common:actions.remove)", + "disagree": "$t(common:actions.cancel)" + }, + "notifications": { + "success": "Пользователь был удален из комнаты успешно", + "error": "Пользователь не был удален из комнаты" + } + }, + "retry_users": { + "text": "Пользователи не были загружены. Нажмите, чтобы повторить" + } + } +} diff --git a/src/shared/configs/i18n/locales/ru/room.json b/src/shared/configs/i18n/locales/ru/room.json new file mode 100644 index 00000000..d02aae1d --- /dev/null +++ b/src/shared/configs/i18n/locales/ru/room.json @@ -0,0 +1,8 @@ +{ + "tabs": { + "tasks": "Задачи", + "tags": "Тэги", + "activities": "Активности", + "users": "Пользователи" + } +} diff --git a/src/shared/configs/i18n/locales/ru/rooms.json b/src/shared/configs/i18n/locales/ru/rooms.json new file mode 100644 index 00000000..fc9d7aaa --- /dev/null +++ b/src/shared/configs/i18n/locales/ru/rooms.json @@ -0,0 +1,68 @@ +{ + "title": "Комнаты", + "rooms_list": { + "empty_text": "Еще нет ни одной комнаты. Создайте ее" + }, + "card": { + "description": "Описание" + }, + "actions": { + "exit_room": { + "name": "$t(common:actions.exit) из комнаты", + "title": "Вы уверены?", + "content": "Вы хотите выйти из этой комнаты?", + "actions": { + "agree": "$t(common:actions.exit)", + "disagree": "$t(common:actions.cancel)" + }, + "notifications": { + "success": "Вы успешно вышли из комнаты", + "error": "Вы не смогли выйти из комнаты" + } + }, + "remove_room": { + "name": "$t(common:actions.remove) комнату", + "title": "Вы уверены?", + "content": "Вы хотите удалить комнату? Все задачи, тэги и активности будут удалены.", + "actions": { + "agree": "$t(common:actions.remove)", + "disagree": "$t(common:actions.cancel)" + }, + "notifications": { + "success": "Комната была успешно удалена", + "error": "Комната не была удалена" + } + }, + "update_room": { + "name": "$t(common:actions.edit) комнату", + "title": "$t(common:actions.edit) комнату", + "notifications": { + "success": "Комната была успешно обновлена", + "error": "Комната не была удалена" + } + }, + "room_form": { + "fields": { + "name": "Название", + "description": "Описание" + }, + "errors": { + "name": { + "empty": "Название не должно быть пустым", + "min_length": "Название должен быть не короче {{ min_symbols_count }} символов", + "max_length": "Название должен быть не длиннее {{ max_symbols_count }} символов" + }, + "description": { + "max_length": "Описание должен быть не длиннее {{ max_symbols_count }} символов" + } + } + }, + "create_room": { + "title": "$t(common:actions.create) комнату", + "notifications": { + "success": "Комната была успешно создана", + "error": "Комната не была создана" + } + } + } +} diff --git a/src/shared/configs/i18n/locales/ru/tasks.json b/src/shared/configs/i18n/locales/ru/tasks.json new file mode 100644 index 00000000..c846a4c3 --- /dev/null +++ b/src/shared/configs/i18n/locales/ru/tasks.json @@ -0,0 +1,65 @@ +{ + "statuses": { + "ready": "В ожидании", + "in_progress": "В процессе", + "review": "Требуется ревью", + "done": "Выполнено" + }, + "actions": { + "tasks_filters": { + "title": "Фильтры задач", + "fields": { + "tags": "Тэги", + "authors": "Авторы" + }, + "actions": { + "submit": "Применить", + "reset": "Сбросить" + } + }, + "create_task": { + "title": "$t(common:actions.create) задачу", + "actions": { + "open": "$t(common:actions.create) задачу" + }, + "notifications": { + "success": "Задача была успешно создана", + "error": "Задача не была создана" + } + }, + "update_task": { + "title": "$t(common:actions.update) задачу", + "actions": { + "open": "$t(common:actions.update) задачу" + }, + "notifications": { + "success": "Задача была успешно изменена", + "error": "Задача не была изменена" + } + }, + "remove_task": { + "name": "$t(common:actions.remove) задачу", + "title": "Вы уверены?", + "content": "Вы хотите $t(common:actions.remove) задачу?", + "actions": { + "agree": "$t(common:actions.remove)", + "disagree": "$t(common:actions.cancel)" + }, + "notifications": { + "success": "Задача была успешно удалена", + "error": "Задача не была удалена" + } + }, + "task_form": { + "fields": { + "title": "Название", + "tags": "Тэги", + "status": "Статус", + "description": "Описание" + } + }, + "retry_tasks": { + "text": "Задачи не были загружены. Нажмите, чтобы повторить" + } + } +} diff --git a/src/shared/configs/i18n/locales/ru/thanks.json b/src/shared/configs/i18n/locales/ru/thanks.json new file mode 100644 index 00000000..aa23535b --- /dev/null +++ b/src/shared/configs/i18n/locales/ru/thanks.json @@ -0,0 +1,11 @@ +{ + "title": "Спасибо за регистрацию", + "title_long": "{{ username }}, спасибо за регистрацию!", + "content": [ + "На вашу почту ", + "отправлено письмо с подтверждением почты. После подтверждения, вы сможете войти в свой аккаунт." + ], + "actions": { + "navigate": "Перейти на страницу входа" + } +} diff --git a/src/shared/configs/index.ts b/src/shared/configs/index.ts new file mode 100644 index 00000000..aaee642c --- /dev/null +++ b/src/shared/configs/index.ts @@ -0,0 +1,3 @@ +export * from './routes'; +export * from './const'; +export * from './i18n'; diff --git a/src/shared/configs/routes.ts b/src/shared/configs/routes.ts new file mode 100644 index 00000000..f0fac0fa --- /dev/null +++ b/src/shared/configs/routes.ts @@ -0,0 +1,79 @@ +import { + createHistoryRouter, + createRoute, + createRouterControls +} from 'atomic-router'; + +export const routes = { + rooms: { base: createRoute(), invite: createRoute(), }, + room: { + base: createRoute<{ id: number; tab: string }>(), + tasks: createRoute<{ id: number }>(), + tags: createRoute<{ id: number }>(), + activities: createRoute<{ id: number }>(), + users: createRoute<{ id: number }>(), + }, + login: createRoute(), + registration: { + base: createRoute(), + thanks: createRoute(), + activate: createRoute(), + }, + settings: createRoute(), +}; + +export const controls = createRouterControls(); + +export const router = createHistoryRouter({ + routes: [ + { + path: '/login', + route: routes.login, + }, + { + path: '/registration', + route: routes.registration.base, + }, + { + path: '/registration/thanks', + route: routes.registration.thanks, + }, + { + path: '/registration/activate', + route: routes.registration.activate, + }, + { + path: '/rooms', + route: routes.rooms.base, + }, + { + path: '/rooms/invite', + route: routes.rooms.invite, + }, + { + path: '/rooms/:id/:tab', + route: routes.room.base, + }, + { + path: '/rooms/:id/tasks', + route: routes.room.tasks, + }, + { + path: '/rooms/:id/tags', + route: routes.room.tags, + }, + { + path: '/rooms/:id/activities', + route: routes.room.activities, + }, + { + path: '/rooms/:id/users', + route: routes.room.users, + }, + { + path: '/settings', + route: routes.settings, + } + ], + controls, +}); diff --git a/src/shared/lib/chain-internal-route.ts b/src/shared/lib/chain-internal-route.ts new file mode 100644 index 00000000..df0cc3c6 --- /dev/null +++ b/src/shared/lib/chain-internal-route.ts @@ -0,0 +1,51 @@ +import { + RouteInstance, + RouteParams, + RouteParamsAndQuery, + chainRoute +} from 'atomic-router'; +import { Event, Store, createEvent, sample } from 'effector'; +import { not } from 'patronum'; + +import { ChainedParams } from '../types'; + +export interface ChainInternalRouteParams extends ChainedParams { + readonly isInternal: Store<boolean>; +} + +export const chainInternalRoute = <Params extends RouteParams>( + route: RouteInstance<Params>, + options: ChainInternalRouteParams +): RouteInstance<Params> => { + const { isInternal, otherwise, } = options; + + const startNavigationChecking = createEvent<RouteParamsAndQuery<Params>>(); + const userNavigated = createEvent(); + const internalNavigated = createEvent(); + + sample({ + clock: startNavigationChecking, + filter: isInternal, + target: internalNavigated, + }); + + sample({ + clock: startNavigationChecking, + filter: not(isInternal), + target: userNavigated, + }); + + if (otherwise) { + sample({ + clock: userNavigated, + target: otherwise as Event<any>, + }); + } + + return chainRoute({ + route, + beforeOpen: startNavigationChecking, + openOn: internalNavigated, + cancelOn: userNavigated, + }); +}; diff --git a/src/shared/lib/create-flag.ts b/src/shared/lib/create-flag.ts new file mode 100644 index 00000000..5da5f7f0 --- /dev/null +++ b/src/shared/lib/create-flag.ts @@ -0,0 +1,36 @@ +import { createEvent, createStore, sample } from 'effector'; + +export const createFlag = (defaultValue = false) => { + const $flag = createStore<boolean>(defaultValue); + + const enable = createEvent(); + const toggle = createEvent(); + const disable = createEvent(); + + sample({ + clock: toggle, + source: $flag, + fn: (flag) => !flag, + target: $flag, + }); + + sample({ + clock: enable, + fn: () => true, + target: $flag, + }); + + sample({ + clock: disable, + fn: () => false, + target: $flag, + }); + + return { + $flag, + enable, + disable, + toggle, + '@@unitShape': () => ({ flag: $flag, enable, disable, toggle, }), + }; +}; diff --git a/src/shared/lib/create-rule-from-schema.ts b/src/shared/lib/create-rule-from-schema.ts new file mode 100644 index 00000000..87b7715a --- /dev/null +++ b/src/shared/lib/create-rule-from-schema.ts @@ -0,0 +1,26 @@ +import { Rule } from 'effector-forms'; +import Joi from 'joi'; + +export const createRuleFromSchema = <V, T = any>( + name: string, + schema: Joi.Schema<T> +): Rule<V> => { + return { + name, + validator: (value) => { + const result = schema.validate(value); + + if (!result.error) { + return { + isValid: true, + }; + } + + const { details, } = result.error; + return { + isValid: false, + errorText: details.map((error) => error.message).join(','), + }; + }, + }; +}; diff --git a/src/shared/lib/data-extractor.ts b/src/shared/lib/data-extractor.ts new file mode 100644 index 00000000..663349eb --- /dev/null +++ b/src/shared/lib/data-extractor.ts @@ -0,0 +1,9 @@ +import { StandardResponse } from '@/shared/types'; + +export const dataExtractor = <T>({ + result, +}: { + result: StandardResponse<T>; +}): T => { + return result.data; +}; diff --git a/src/shared/lib/group.ts b/src/shared/lib/group.ts new file mode 100644 index 00000000..0446fe28 --- /dev/null +++ b/src/shared/lib/group.ts @@ -0,0 +1,20 @@ +export type Grouped<K extends string | number, T> = { + [Key in K]: T[]; +}; + +export const group = <T extends Record<string, any>, K extends keyof T>( + array: T[], + key: K +): Grouped<T[K], T> => { + return array.reduce((grouped, item) => { + const value = item[key]; + + if (!grouped[value]) { + grouped[value] = []; + } + + grouped[value].push(item); + + return grouped; + }, {} as Grouped<T[K], T>); +}; diff --git a/src/shared/lib/index.ts b/src/shared/lib/index.ts new file mode 100644 index 00000000..71d92191 --- /dev/null +++ b/src/shared/lib/index.ts @@ -0,0 +1,13 @@ +export * from './usePageTitle'; +export * from './useToggle'; +export * from './useParam'; +export * from './data-extractor'; +export * from './useQueryParam'; +export * from './create-rule-from-schema'; +export * from './string-to-color'; +export * from './use-prevent-default'; +export * from './prepare-picker-control'; +export * from './group'; +export * from './is-http-error-code'; +export * from './chain-internal-route'; +export * from './create-flag'; diff --git a/src/shared/lib/is-http-error-code.ts b/src/shared/lib/is-http-error-code.ts new file mode 100644 index 00000000..524967e4 --- /dev/null +++ b/src/shared/lib/is-http-error-code.ts @@ -0,0 +1,9 @@ +import { HTTPError } from 'ky'; + +export const isHttpError = (error: Error): error is HTTPError => { + return 'request' in error; +}; + +export const isHttpErrorCode = (error: any, code: number): boolean => { + return isHttpError(error) && error.response.status === code; +}; diff --git a/src/shared/lib/prepare-picker-control.ts b/src/shared/lib/prepare-picker-control.ts new file mode 100644 index 00000000..f4560517 --- /dev/null +++ b/src/shared/lib/prepare-picker-control.ts @@ -0,0 +1,40 @@ +import { PickerProps } from '../types'; + +export const preparePickerHandler = < + O extends Record<string, any>, + K extends keyof O, + T extends O[K] +>( + params: Pick<PickerProps<T>, 'multiple' | 'onChange'>, + key: K + ) => { + const { onChange, multiple, } = params; + + if (multiple) { + return (_: unknown, data: O[]) => { + (onChange as any)(data.map((tag) => tag[key])); + }; + } + + return (_: unknown, data: O | null) => { + (onChange as any)(data?.[key] || null); + }; +}; + +export const preparePickerSelectedValue = < + O extends Record<string, any>, + K extends keyof O, + T extends O[K] +>( + params: Pick<PickerProps<T>, 'multiple' | 'value'>, + data: O[], + key: K + ) => { + const { value, multiple, } = params; + + if (multiple) { + return data.filter((data) => (value as T[]).includes(data[key])); + } + + return data.find((data) => data[key] === value) ?? null; +}; diff --git a/src/shared/lib/string-to-color.ts b/src/shared/lib/string-to-color.ts new file mode 100644 index 00000000..1ae42d5b --- /dev/null +++ b/src/shared/lib/string-to-color.ts @@ -0,0 +1,27 @@ +/** + * Get color by passed string + * @param string + * @returns hex color + * + * @see https://mui.com/material-ui/react-avatar/#letter-avatars + */ + +export const stringToColor = (string: string) => { + let hash = 0; + let i; + + /* eslint-disable no-bitwise */ + for (i = 0; i < string.length; i += 1) { + hash = string.charCodeAt(i) + ((hash << 5) - hash); + } + + let color = '#'; + + for (i = 0; i < 3; i += 1) { + const value = (hash >> (i * 8)) & 0xff; + color += `00${value.toString(16)}`.slice(-2); + } + /* eslint-enable no-bitwise */ + + return color; +}; diff --git a/src/shared/lib/use-prevent-default.ts b/src/shared/lib/use-prevent-default.ts new file mode 100644 index 00000000..3516f429 --- /dev/null +++ b/src/shared/lib/use-prevent-default.ts @@ -0,0 +1,15 @@ +import { SyntheticEvent, useCallback } from 'react'; + +import { VoidFunction } from '../types'; + +export const usePreventDefault = < + Element extends HTMLElement, + Event extends SyntheticEvent<Element> +>( + fn: VoidFunction + ) => { + return useCallback((evt: Event) => { + evt.preventDefault(); + fn(); + }, []); +}; diff --git a/src/hooks/usePageTitle.ts b/src/shared/lib/usePageTitle.ts similarity index 100% rename from src/hooks/usePageTitle.ts rename to src/shared/lib/usePageTitle.ts diff --git a/src/shared/lib/useParam.ts b/src/shared/lib/useParam.ts new file mode 100644 index 00000000..612b74e2 --- /dev/null +++ b/src/shared/lib/useParam.ts @@ -0,0 +1,15 @@ +import { RouteInstance } from 'atomic-router'; +import { useStoreMap } from 'effector-react'; + +export const useParam = <P extends object, K extends keyof P>( + route: RouteInstance<P>, + param: K +): P[K] => { + return useStoreMap({ + store: route.$params, + fn: (state, [key]) => { + return state[key]; + }, + keys: [param], + }); +}; diff --git a/src/shared/lib/useQueryParam.ts b/src/shared/lib/useQueryParam.ts new file mode 100644 index 00000000..38cea924 --- /dev/null +++ b/src/shared/lib/useQueryParam.ts @@ -0,0 +1,17 @@ +import { useStoreMap } from 'effector-react'; + +import { controls } from '@/shared/configs'; + +export const useQueryParam = <T extends string | null = null>( + name: string, + defaultValue: T +): string | T => { + return useStoreMap({ + store: controls.$query, + fn: (query, [key]) => { + return query[key] ?? undefined; + }, + keys: [name], + defaultValue, + }); +}; diff --git a/src/shared/lib/useToggle.ts b/src/shared/lib/useToggle.ts new file mode 100644 index 00000000..ee69367b --- /dev/null +++ b/src/shared/lib/useToggle.ts @@ -0,0 +1,15 @@ +import * as React from 'react'; + +export const useToggle = (defaultValue = false) => { + const [toggled, setToggled] = React.useState(defaultValue); + + const toggle = React.useCallback(() => { + setToggled((toggled) => !toggled); + }, []); + + const toggleOn = React.useCallback(() => setToggled(true), []); + + const toggleOff = React.useCallback(() => setToggled(false), []); + + return [toggled, { toggle, toggleOff, toggleOn, }] as const; +}; diff --git a/src/shared/models/app.ts b/src/shared/models/app.ts new file mode 100644 index 00000000..a2c59499 --- /dev/null +++ b/src/shared/models/app.ts @@ -0,0 +1,3 @@ +import { createEvent } from 'effector'; + +export const started = createEvent(); diff --git a/src/shared/models/device-info/index.ts b/src/shared/models/device-info/index.ts new file mode 100644 index 00000000..c7f44aa0 --- /dev/null +++ b/src/shared/models/device-info/index.ts @@ -0,0 +1,2 @@ +export * as deviceInfoModel from './model'; +export * from './types'; diff --git a/src/shared/models/device-info/lib.ts b/src/shared/models/device-info/lib.ts new file mode 100644 index 00000000..62adfd37 --- /dev/null +++ b/src/shared/models/device-info/lib.ts @@ -0,0 +1,22 @@ +import { Devices } from './types'; + +export const calculateDevice = (): Devices => { + const { innerWidth: width, } = window; + + if (width <= 540) { + return 'mobile'; + } + + if (width <= 720) { + return 'tablet-vertical'; + } + + if (width <= 1200) { + return 'tablet-horizontal'; + } + if (width <= 1440) { + return 'desktop-small'; + } + + return 'desktop-large'; +}; diff --git a/src/shared/models/device-info/model.ts b/src/shared/models/device-info/model.ts new file mode 100644 index 00000000..09bf5a3c --- /dev/null +++ b/src/shared/models/device-info/model.ts @@ -0,0 +1,48 @@ +import { createDomain, sample } from 'effector'; + +// eslint-disable-next-line no-restricted-imports +import { started } from '../app'; + +import { calculateDevice } from './lib'; +import { Devices } from './types'; + +const deviceInfoDomain = createDomain(); + +export const $device = deviceInfoDomain.store<Devices>('desktop-large'); + +export const $isMobile = $device.map((device) => device === 'mobile'); +export const $isTabletVertical = $device.map( + (device) => device === 'tablet-vertical' +); +export const $isTabletHorizontal = $device.map( + (device) => device === 'tablet-horizontal' +); +export const $isDesktopSmall = $device.map( + (device) => device === 'desktop-small' +); +export const $isDesktopLarge = $device.map( + (device) => device === 'desktop-large' +); + +const calculateDeviceFx = deviceInfoDomain.effect<unknown, Devices>( + calculateDevice +); + +export const subscribeFx = deviceInfoDomain.effect(() => { + window.addEventListener('resize', calculateDeviceFx); + return calculateDevice(); +}); + +export const unsubscribeFx = deviceInfoDomain.effect(() => + window.removeEventListener('resize', calculateDeviceFx) +); + +sample({ + clock: [calculateDeviceFx.doneData, subscribeFx.doneData], + target: $device, +}); + +sample({ + clock: started, + target: [subscribeFx, calculateDeviceFx], +}); diff --git a/src/shared/models/device-info/types.ts b/src/shared/models/device-info/types.ts new file mode 100644 index 00000000..d8d3e57e --- /dev/null +++ b/src/shared/models/device-info/types.ts @@ -0,0 +1,6 @@ +export type Devices = + | 'mobile' + | 'tablet-vertical' + | 'tablet-horizontal' + | 'desktop-small' + | 'desktop-large'; diff --git a/src/shared/models/i18next.ts b/src/shared/models/i18next.ts new file mode 100644 index 00000000..7d6f0e8b --- /dev/null +++ b/src/shared/models/i18next.ts @@ -0,0 +1,38 @@ +import { createEffect, createEvent, createStore, sample } from 'effector'; + +import { i18n } from '../configs'; + +import { started } from './app'; + +export type AllowedLanguages = 'ru' | 'en'; + +export const $language = createStore<AllowedLanguages>( + i18n.language as AllowedLanguages +); +export const changeLanguage = createEvent<AllowedLanguages>(); +const changeLanguageFx = createEffect((language: AllowedLanguages) => { + i18n.changeLanguage(language); + + return language; +}); + +sample({ + clock: changeLanguage, + source: $language, + filter: (usingLanguage, language) => { + return usingLanguage !== language; + }, + fn: (_, language) => language, + target: changeLanguageFx, +}); + +sample({ + clock: changeLanguageFx.doneData, + target: $language, +}); + +sample({ + clock: started, + fn: () => i18n.language as AllowedLanguages, + target: $language, +}); diff --git a/src/shared/models/index.ts b/src/shared/models/index.ts new file mode 100644 index 00000000..73ff3188 --- /dev/null +++ b/src/shared/models/index.ts @@ -0,0 +1,7 @@ +export * as sessionModel from './session'; +export * as appModel from './app'; +export * as notificationsModel from './notifications'; +export * from './device-info'; +export * as i18nModel from './i18next'; +export * as colorSchemeModel from './scheme'; +export * as internalRoutingModel from './internal-routing'; diff --git a/src/shared/models/internal-routing.ts b/src/shared/models/internal-routing.ts new file mode 100644 index 00000000..e92daa34 --- /dev/null +++ b/src/shared/models/internal-routing.ts @@ -0,0 +1,3 @@ +import { createFlag } from '../lib'; + +export const $internalRoute = createFlag(false); diff --git a/src/shared/models/notifications.ts b/src/shared/models/notifications.ts new file mode 100644 index 00000000..c5f15547 --- /dev/null +++ b/src/shared/models/notifications.ts @@ -0,0 +1,14 @@ +import { createSnackbarStackModel } from 'effector-mui-snacks'; + +export const notifications = createSnackbarStackModel({ + maxCount: 3, + timeout: 3000, + variant: 'filled', + closable: true, + position: { + horizontal: 'left', + vertical: 'bottom', + }, +}); + +export const { $items, create, } = notifications; diff --git a/src/shared/models/scheme.ts b/src/shared/models/scheme.ts new file mode 100644 index 00000000..c99322cf --- /dev/null +++ b/src/shared/models/scheme.ts @@ -0,0 +1,54 @@ +import { useColorScheme } from '@mui/material'; +import { trackMediaQuery } from '@withease/web-api'; +import { combine, createEvent, createStore, sample } from 'effector'; +import persist from 'effector-localstorage'; +import { useUnit } from 'effector-react'; +import { useLayoutEffect } from 'react'; + +import { started } from './app'; + +export type ColorScheme = 'dark' | 'system' | 'light'; + +export type BinaryColorScheme = Exclude<ColorScheme, 'system'>; + +const { $matches: $preferDark, } = trackMediaQuery( + '(prefers-color-scheme: dark)', + { + setup: started, + } +); + +export const $scheme = createStore<ColorScheme>('system'); +export const $biScheme = combine( + { scheme: $scheme, preferDark: $preferDark, }, + ({ scheme, preferDark, }): BinaryColorScheme => { + if (scheme !== 'system') { + return scheme; + } + + return preferDark ? 'dark' : 'light'; + } +); + +export const colorSchemeChanged = createEvent<ColorScheme | null>(); + +export const useSyncScheme = () => { + const { setMode, } = useColorScheme(); + const mode = useUnit($biScheme); + + useLayoutEffect(() => { + setMode(mode); + }, [mode]); +}; + +persist({ + store: $scheme, + key: 'bt-color-scheme', +}); + +sample({ + clock: colorSchemeChanged, + source: $scheme, + fn: (currentScheme, scheme) => scheme ?? currentScheme, + target: $scheme, +}); diff --git a/src/shared/models/session.ts b/src/shared/models/session.ts new file mode 100644 index 00000000..09d08c10 --- /dev/null +++ b/src/shared/models/session.ts @@ -0,0 +1,200 @@ +import { createQuery } from '@farfetched/core'; +import { runtypeContract } from '@farfetched/runtypes'; +import { + RouteInstance, + RouteParams, + RouteParamsAndQuery, + chainRoute +} from 'atomic-router'; +import { + combine, + sample, + createEvent, + createStore, + createEffect, + Event +} from 'effector'; +import { equals } from 'patronum'; + +import { User, AuthResponse, authResponse, authApi } from '@/shared/api'; +import { dataExtractor } from '@/shared/lib'; +import { + ChainedParams, + StandardResponse, + getStandardResponse +} from '@/shared/types'; + +type Status = 'initial' | 'pending' | 'authorized' | 'anonymous'; + +export const $user = createStore<User | null>(null); +export const $status = createStore<Status>('initial'); +export const $isAuth = $status.map((status) => status === 'authorized'); +export const setUser = createEvent<User | null>(); + +const handlerFx = createEffect(authApi.auth); + +export const query = createQuery< + void, + StandardResponse<AuthResponse>, + Error, + StandardResponse<AuthResponse>, + AuthResponse +>({ + effect: handlerFx, + contract: runtypeContract(getStandardResponse(authResponse)), + mapData: dataExtractor, +}); + +sample({ + clock: query.start, + filter: equals($status, 'initial'), + fn: () => 'pending' as const, + target: $status, +}); + +sample({ + clock: query.finished.success, + fn: () => 'authorized' as const, + target: $status, +}); + +sample({ + clock: query.finished.failure, + fn: () => 'anonymous' as const, + target: $status, +}); + +sample({ + clock: query.finished.success, + fn: ({ result, }) => result.user, + target: $user, +}); + +export const chainAuthorized = <Params extends RouteParams>( + route: RouteInstance<Params>, + options?: ChainedParams +): RouteInstance<Params> => { + const sessionCheckStarted = createEvent<RouteParamsAndQuery<Params>>(); + const alreadyAnonymous = createEvent(); + const alreadyAuthorized = createEvent(); + const sessionCheckSuccessful = createEvent(); + const sessionCheckFailure = createEvent(); + + const $paramsAndQuery = combine({ + params: route.$params, + query: route.$query, + }); + + sample({ + clock: sessionCheckStarted, + filter: equals($status, 'initial'), + target: query.start, + }); + + sample({ + clock: sessionCheckStarted, + source: $paramsAndQuery, + filter: equals($status, 'anonymous'), + target: alreadyAnonymous, + }); + + sample({ + clock: sessionCheckStarted, + source: $paramsAndQuery, + filter: equals($status, 'authorized'), + target: alreadyAuthorized, + }); + + sample({ + clock: [alreadyAnonymous, query.finished.failure], + source: $paramsAndQuery, + filter: route.$isOpened, + target: sessionCheckFailure, + }); + + sample({ + clock: [alreadyAuthorized, query.finished.success], + source: $paramsAndQuery, + filter: route.$isOpened, + target: sessionCheckSuccessful, + }); + + if (options?.otherwise) { + sample({ + clock: sessionCheckFailure, + target: options.otherwise as Event<any>, + }); + } + + return chainRoute({ + route, + beforeOpen: sessionCheckStarted, + openOn: sessionCheckSuccessful, + cancelOn: sessionCheckFailure, + }); +}; + +export const chainAnonymous = <Params extends RouteParams>( + route: RouteInstance<Params>, + options?: ChainedParams +): RouteInstance<Params> => { + const sessionCheckStarted = createEvent<RouteParamsAndQuery<Params>>(); + const alreadyAnonymous = createEvent(); + const alreadyAuthorized = createEvent(); + const sessionCheckSuccessful = createEvent(); + const sessionCheckFailure = createEvent(); + + const $paramsAndQuery = combine({ + params: route.$params, + query: route.$query, + }); + + sample({ + clock: sessionCheckStarted, + filter: equals($status, 'initial'), + target: query.start, + }); + + sample({ + clock: sessionCheckStarted, + source: $paramsAndQuery, + filter: equals($status, 'anonymous'), + target: alreadyAnonymous, + }); + + sample({ + clock: sessionCheckStarted, + source: $paramsAndQuery, + filter: equals($status, 'authorized'), + target: alreadyAuthorized, + }); + + sample({ + clock: [alreadyAnonymous, query.finished.failure], + source: $paramsAndQuery, + filter: route.$isOpened, + target: sessionCheckFailure, + }); + + sample({ + clock: [alreadyAuthorized, query.finished.success], + source: $paramsAndQuery, + filter: route.$isOpened, + target: sessionCheckSuccessful, + }); + + if (options?.otherwise) { + sample({ + clock: sessionCheckSuccessful, + filter: route.$isOpened, + target: options.otherwise as Event<any>, + }); + } + + return chainRoute({ + route, + beforeOpen: sessionCheckStarted, + openOn: sessionCheckFailure, + cancelOn: sessionCheckSuccessful, + }); +}; diff --git a/src/shared/types/common.ts b/src/shared/types/common.ts new file mode 100644 index 00000000..60223982 --- /dev/null +++ b/src/shared/types/common.ts @@ -0,0 +1,13 @@ +import { Effect, Event } from 'effector'; +import { Template, String, Static } from 'runtypes'; + +export const hex = Template`#${String.withConstraint( + (code) => code.length === 3 || code.length === 6 +)}`; +export type HEX = Static<typeof hex>; + +export type VoidFunction = () => void; + +export interface ChainedParams { + readonly otherwise?: Event<any> | Effect<any, any>; +} diff --git a/src/shared/types/index.ts b/src/shared/types/index.ts new file mode 100644 index 00000000..4e651f74 --- /dev/null +++ b/src/shared/types/index.ts @@ -0,0 +1,4 @@ +export * from './common'; +export * from './request'; +export * from './response'; +export * from './ui'; diff --git a/src/shared/types/request.ts b/src/shared/types/request.ts new file mode 100644 index 00000000..e916550d --- /dev/null +++ b/src/shared/types/request.ts @@ -0,0 +1,20 @@ +export interface InRoomParams { + readonly roomId: number; +} + +export interface PaginationParams { + readonly page?: number; + readonly count?: number; +} + +export type SortDirection = 'asc' | 'desc'; + +export interface SortParams { + readonly by?: string | null; + readonly type?: SortDirection | null; +} + +export interface DatesFiltersParams { + readonly before?: string | null; + readonly after?: string | null; +} diff --git a/src/shared/types/response.ts b/src/shared/types/response.ts new file mode 100644 index 00000000..e08cb7c9 --- /dev/null +++ b/src/shared/types/response.ts @@ -0,0 +1,27 @@ +import { Runtype, Record, Number, Array } from 'runtypes'; + +export const getStandardResponse = <RT>(T: Runtype<RT>) => { + return Record({ + data: T, + statusCode: Number, + }).asReadonly(); +}; + +export interface StandardResponse<T> { + readonly data: T; + readonly statusCode: number; +} + +export const getPaginationResponse = <RT>(T: Runtype<RT>) => { + return Record({ + items: Array(T), + totalCount: Number, + limit: Number, + }).asReadonly(); +}; + +export interface PaginationResponse<T> { + readonly items: T[]; + readonly totalCount: number; + readonly limit: number; +} diff --git a/src/shared/types/ui.ts b/src/shared/types/ui.ts new file mode 100644 index 00000000..3977de60 --- /dev/null +++ b/src/shared/types/ui.ts @@ -0,0 +1,36 @@ +import { ReactNode } from 'react'; + +export type Size = 'small' | 'medium' | 'large'; + +export interface CommonProps { + className?: string; +} + +export interface BasePopupProps extends CommonProps { + readonly isOpen: boolean; + readonly slots?: Slots<'actions'>; +} + +interface SinglePickerProps<T> { + readonly onChange: (value: T | null) => unknown; + readonly value: T | null; + readonly multiple?: never; + readonly limitTags?: never; +} + +interface MultiplePickerProps<T> { + readonly onChange: (value: T[]) => unknown; + readonly value: T[]; + readonly multiple: true; + readonly limitTags?: number; +} + +export type PickerProps<T> = SinglePickerProps<T> | MultiplePickerProps<T>; + +export type Slots<T extends string> = { + readonly [K in T]?: ReactNode | null; +}; + +export type Classes<T extends string> = { + readonly [K in T]?: string; +}; diff --git a/src/shared/ui/center/center.module.css b/src/shared/ui/center/center.module.css new file mode 100644 index 00000000..1c1265f1 --- /dev/null +++ b/src/shared/ui/center/center.module.css @@ -0,0 +1,23 @@ +.center { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 1em; +} + +.auto { + min-height: auto; +} + +.container { + min-height: 100%; +} + +.page { + min-height: 100vh; +} + +.content { + min-height: max-content; +} diff --git a/src/shared/ui/center/center.module.css.d.ts b/src/shared/ui/center/center.module.css.d.ts new file mode 100644 index 00000000..dcf7dfc0 --- /dev/null +++ b/src/shared/ui/center/center.module.css.d.ts @@ -0,0 +1,8 @@ +declare const styles: { + readonly auto: string; + readonly center: string; + readonly container: string; + readonly content: string; + readonly page: string; +}; +export = styles; diff --git a/src/shared/ui/center/center.tsx b/src/shared/ui/center/center.tsx new file mode 100644 index 00000000..3406d647 --- /dev/null +++ b/src/shared/ui/center/center.tsx @@ -0,0 +1,22 @@ +import cn from 'classnames'; +import * as React from 'react'; + +import { CommonProps } from '@/shared/types'; + +import styles from './center.module.css'; + +type Height = 'auto' | 'container' | 'page' | 'content'; + +export interface CenterProps extends CommonProps { + readonly height?: Height; +} + +export const Center: React.FC<React.PropsWithChildren<CenterProps>> = ( + props +) => { + const { className, children, height = 'auto', } = props; + + const classes = cn(styles.center, styles[height], className); + + return <div className={classes}>{children}</div>; +}; diff --git a/src/shared/ui/center/index.ts b/src/shared/ui/center/index.ts new file mode 100644 index 00000000..f458db35 --- /dev/null +++ b/src/shared/ui/center/index.ts @@ -0,0 +1 @@ +export { Center, type CenterProps } from './center'; diff --git a/src/shared/ui/checkbox/checkbox.tsx b/src/shared/ui/checkbox/checkbox.tsx new file mode 100644 index 00000000..3b5d97e9 --- /dev/null +++ b/src/shared/ui/checkbox/checkbox.tsx @@ -0,0 +1,30 @@ +import { + FormControlLabel, + Checkbox as CheckboxMUI, + CheckboxProps as MUICheckboxProps +} from '@mui/material'; +import { ConnectedField } from 'effector-forms'; +import * as React from 'react'; + +import { CommonProps } from '@/shared/types'; + +export interface CheckboxProps + extends CommonProps, + Pick<ConnectedField<any>, 'name' | 'onChange' | 'value'>, + Omit<MUICheckboxProps, keyof ConnectedField<any>> { + readonly label?: string | null; +} + +export const Checkbox: React.FC<CheckboxProps> = React.memo((props) => { + const { label, onChange, ...rest } = props; + + const handleChange: React.ChangeEventHandler<HTMLInputElement> = (evt) => { + onChange(evt.target.checked); + }; + return ( + <FormControlLabel + control={<CheckboxMUI {...rest} onChange={handleChange} />} + label={label} + /> + ); +}); diff --git a/src/shared/ui/checkbox/index.ts b/src/shared/ui/checkbox/index.ts new file mode 100644 index 00000000..d415305c --- /dev/null +++ b/src/shared/ui/checkbox/index.ts @@ -0,0 +1 @@ +export { Checkbox, type CheckboxProps } from './checkbox'; diff --git a/src/shared/ui/confirm/confirm.tsx b/src/shared/ui/confirm/confirm.tsx new file mode 100644 index 00000000..9c05a0c1 --- /dev/null +++ b/src/shared/ui/confirm/confirm.tsx @@ -0,0 +1,51 @@ +import { + Button, + Dialog, + DialogActions, + DialogContent, + DialogContentText, + DialogTitle +} from '@mui/material'; +import * as React from 'react'; + +import { BasePopupProps, CommonProps, VoidFunction } from '@/shared/types'; + +export interface ConfirmProps extends BasePopupProps, CommonProps { + readonly title: string; + readonly onClose: VoidFunction; + readonly onAgree: VoidFunction; + readonly onDisagree: VoidFunction; + readonly agreeText: string; + readonly disagreeText: string; + readonly content: string; +} + +export const Confirm: React.FC<ConfirmProps> = (props) => { + const { + isOpen, + agreeText, + disagreeText, + onAgree, + onDisagree, + onClose, + title, + content, + className, + } = props; + return ( + <Dialog open={isOpen} onClose={onClose} maxWidth='sm' fullWidth> + <DialogTitle>{title}</DialogTitle> + <DialogContent> + <DialogContentText className={className}>{content}</DialogContentText> + </DialogContent> + <DialogActions> + <Button onClick={onDisagree} color='primary' autoFocus> + {disagreeText} + </Button> + <Button onClick={onAgree} color='error'> + {agreeText} + </Button> + </DialogActions> + </Dialog> + ); +}; diff --git a/src/shared/ui/confirm/index.ts b/src/shared/ui/confirm/index.ts new file mode 100644 index 00000000..6696f114 --- /dev/null +++ b/src/shared/ui/confirm/index.ts @@ -0,0 +1 @@ +export { Confirm, type ConfirmProps } from './confirm'; diff --git a/src/shared/ui/controlled-toggle-button-group/controlled-toggle-button-group.tsx b/src/shared/ui/controlled-toggle-button-group/controlled-toggle-button-group.tsx new file mode 100644 index 00000000..81521a87 --- /dev/null +++ b/src/shared/ui/controlled-toggle-button-group/controlled-toggle-button-group.tsx @@ -0,0 +1,42 @@ +import { + FormControl, + FormLabel, + ToggleButtonGroup, + FormHelperText, + ToggleButtonGroupProps +} from '@mui/material'; +import * as React from 'react'; + +import { CommonProps } from '@/shared/types'; + +export interface ControlledToggleButtonGroupProps + extends CommonProps, + Omit<ToggleButtonGroupProps, 'onChange'> { + readonly onChange: (value: any) => unknown; + readonly label?: string; + readonly error?: boolean; + readonly helperText?: string; +} + +export const ControlledToggleButtonGroup: React.FC< + ControlledToggleButtonGroupProps +> = (props) => { + const { error, helperText, label, children, className, onChange, ...rest } = + props; + + const id = React.useId(); + + const changeHandle = (_: unknown, values: string | null) => { + onChange(values); + }; + + return ( + <FormControl className={className} error={error}> + <FormLabel htmlFor={id}>{label}</FormLabel> + <ToggleButtonGroup onChange={changeHandle} {...rest} id={id}> + {children} + </ToggleButtonGroup> + {helperText ? <FormHelperText>{helperText}</FormHelperText> : null} + </FormControl> + ); +}; diff --git a/src/shared/ui/controlled-toggle-button-group/index.ts b/src/shared/ui/controlled-toggle-button-group/index.ts new file mode 100644 index 00000000..63cb1432 --- /dev/null +++ b/src/shared/ui/controlled-toggle-button-group/index.ts @@ -0,0 +1,4 @@ +export { + ControlledToggleButtonGroup, + type ControlledToggleButtonGroupProps +} from './controlled-toggle-button-group'; diff --git a/src/shared/ui/date-picker/date-picker.tsx b/src/shared/ui/date-picker/date-picker.tsx new file mode 100644 index 00000000..02a36fef --- /dev/null +++ b/src/shared/ui/date-picker/date-picker.tsx @@ -0,0 +1,69 @@ +import { TextFieldProps } from '@mui/material'; +import { + DatePicker as MUIDatePicker, + DatePickerProps as MUIDatePIckerProps +} from '@mui/x-date-pickers'; +import dayjs, { Dayjs } from 'dayjs'; +import * as React from 'react'; + +import { CommonProps } from '@/shared/types'; + +import { Field, FieldProps } from '../field'; + +type FieldKeys = 'value' | 'onBlur' | 'name' | 'isValid' | 'helperText'; + +export interface DatePickerProps + extends CommonProps, + Pick<FieldProps, FieldKeys>, + Omit<MUIDatePIckerProps<Dayjs>, FieldKeys | 'onChange'> { + readonly onChange: (date: string | null) => void; +} + +export const DatePicker = React.memo( + (props: DatePickerProps): React.ReactElement => { + const { onChange, value, isValid, name, onBlur, helperText, ...rest } = + props; + const preparedValue = dayjs(value); + const handleChange: MUIDatePIckerProps<Dayjs>['onChange'] = (date) => { + let newDate: string | null; + + try { + newDate = date?.toDate().toJSON() ?? null; + } catch { + newDate = null; + } + + onChange(newDate); + }; + + const textField = (params: TextFieldProps) => { + const handleBlur = (...args: any[]) => { + onBlur?.(); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + params.onBlur?.(...args); + }; + + return ( + <Field + {...params} + onBlur={handleBlur} + isValid={isValid} + name={name} + helperText={helperText} + /> + ); + }; + + return ( + <MUIDatePicker + {...rest} + value={preparedValue} + onChange={handleChange} + slots={{ + textField, + }} + /> + ); + } +); diff --git a/src/shared/ui/date-picker/index.ts b/src/shared/ui/date-picker/index.ts new file mode 100644 index 00000000..d2785941 --- /dev/null +++ b/src/shared/ui/date-picker/index.ts @@ -0,0 +1 @@ +export { DatePicker, type DatePickerProps } from './date-picker'; diff --git a/src/shared/ui/date-time/date-time.tsx b/src/shared/ui/date-time/date-time.tsx new file mode 100644 index 00000000..422ee24b --- /dev/null +++ b/src/shared/ui/date-time/date-time.tsx @@ -0,0 +1,30 @@ +import { Typography } from '@mui/material'; +import dayjs from 'dayjs'; +import * as React from 'react'; + +import { CommonProps } from '@/shared/types'; + +export interface DateTimeProps extends CommonProps { + readonly date: string | number | Date; + readonly format: string; +} + +export const DateTime: React.FC<DateTimeProps> = React.memo(function Datetime( + props +) { + const { className, date, format, } = props; + const jsDate = new Date(date).toISOString(); + const showDate = dayjs(jsDate).format(format); + const title = dayjs(jsDate).toISOString(); + + return ( + <Typography + className={className} + variant='body2' + dateTime={jsDate} + title={title} + component='time'> + {showDate} + </Typography> + ); +}); diff --git a/src/shared/ui/date-time/index.ts b/src/shared/ui/date-time/index.ts new file mode 100644 index 00000000..2784b0c9 --- /dev/null +++ b/src/shared/ui/date-time/index.ts @@ -0,0 +1 @@ +export { DateTime, type DateTimeProps } from './date-time'; diff --git a/src/shared/ui/edit-menu/edit-menu.tsx b/src/shared/ui/edit-menu/edit-menu.tsx new file mode 100644 index 00000000..dcfe0a41 --- /dev/null +++ b/src/shared/ui/edit-menu/edit-menu.tsx @@ -0,0 +1,38 @@ +import MoreHorizIcon from '@mui/icons-material/MoreHoriz'; +import { IconButton, Menu } from '@mui/material'; +import { CommonProps } from '@mui/material/OverridableComponent'; +import * as React from 'react'; + +import { useToggle } from '@/shared/lib'; +import { Size } from '@/shared/types'; +import { MenuOption, MenuItem } from '@/shared/ui'; + +export interface EditMenuProps extends CommonProps, React.PropsWithChildren { + readonly alt?: string; + readonly options?: MenuOption<object>[]; + readonly size?: Size; +} + +export const EditMenu: React.FC<EditMenuProps> = React.memo((props) => { + const { options, className, size, alt, children, } = props; + const [isOpen, { toggle, }] = useToggle(); + const [reference, setReference] = React.useState<HTMLElement | null>(null); + return ( + <div className={className}> + <IconButton + onClick={toggle} + size={size} + tabIndex={0} + title={alt} + ref={setReference}> + <MoreHorizIcon /> + </IconButton> + <Menu anchorEl={reference} open={isOpen} onClose={toggle}> + {options?.map((option) => ( + <MenuItem {...option} key={option.label} /> + ))} + {children} + </Menu> + </div> + ); +}); diff --git a/src/shared/ui/edit-menu/index.ts b/src/shared/ui/edit-menu/index.ts new file mode 100644 index 00000000..161bd464 --- /dev/null +++ b/src/shared/ui/edit-menu/index.ts @@ -0,0 +1 @@ +export { EditMenu, type EditMenuProps } from './edit-menu'; diff --git a/src/shared/ui/field/field.tsx b/src/shared/ui/field/field.tsx new file mode 100644 index 00000000..c71da35d --- /dev/null +++ b/src/shared/ui/field/field.tsx @@ -0,0 +1,30 @@ +import { TextField, TextFieldProps } from '@mui/material'; +import { ConnectedField } from 'effector-forms'; +import * as React from 'react'; + +import { CommonProps } from '@/shared/types'; + +export interface FieldProps + extends CommonProps, + Partial< + Pick< + ConnectedField<any>, + 'isValid' | 'name' | 'onChange' | 'onBlur' | 'value' + > + >, + Omit<TextFieldProps, keyof ConnectedField<any>> {} + +export const Field: React.FC<FieldProps> = React.memo((props) => { + const { isValid, onChange, ...rest } = props; + const handleChange: React.ChangeEventHandler<HTMLInputElement> = (evt) => { + onChange?.(evt.target.value); + }; + + return ( + <TextField + {...(rest as TextFieldProps)} + onChange={handleChange} + error={!isValid} + /> + ); +}); diff --git a/src/shared/ui/field/index.ts b/src/shared/ui/field/index.ts new file mode 100644 index 00000000..7e3d4774 --- /dev/null +++ b/src/shared/ui/field/index.ts @@ -0,0 +1 @@ +export { Field, type FieldProps } from './field'; diff --git a/src/shared/ui/filters-popover/filters-popover.tsx b/src/shared/ui/filters-popover/filters-popover.tsx new file mode 100644 index 00000000..dabcea48 --- /dev/null +++ b/src/shared/ui/filters-popover/filters-popover.tsx @@ -0,0 +1,83 @@ +import { Tooltip, IconButton, Popover } from '@mui/material'; +import { useUnit } from 'effector-react'; +import * as React from 'react'; + +import { deviceInfoModel } from '@/shared/models'; +import { CommonProps, VoidFunction } from '@/shared/types'; + +import { FullWidthPopup, FullWidthPopupProps } from '../full-width-popup'; + +interface RenderProps { + readonly isPopup: boolean; +} + +export interface FiltersPopoverProps extends CommonProps { + readonly open: boolean; + readonly children: React.ComponentType<RenderProps>; + readonly onOpen: VoidFunction; + readonly onClose: VoidFunction; + readonly title: string; + readonly icon: React.ReactElement; + readonly slots?: FullWidthPopupProps['slots']; +} + +export const FiltersPopover: React.FC<FiltersPopoverProps> = (props) => { + const { title, open, onClose, onOpen, icon, children, className, slots, } = + props; + + const [ref, setRef] = React.useState<HTMLElement | null>(null); + + const [isMobile, isVertical] = useUnit([ + deviceInfoModel.$isMobile, + deviceInfoModel.$isTabletVertical + ]); + + const isPopup = isMobile || isVertical; + + const child = React.createElement(children, { isPopup, }); + + let content: React.ReactElement; + + if (isPopup) { + content = ( + <FullWidthPopup + isOpen={open} + onClose={onClose} + title={title} + slots={slots}> + {child} + </FullWidthPopup> + ); + } else { + content = ( + <Popover + open={open} + onClose={onClose} + anchorEl={ref} + anchorOrigin={{ + horizontal: 'right', + vertical: 'bottom', + }} + transformOrigin={{ + horizontal: 'right', + vertical: 'top', + }}> + {child} + </Popover> + ); + } + + return ( + <> + <Tooltip title={title}> + <IconButton + className={className} + onClick={open ? onClose : onOpen} + ref={setRef}> + {icon} + </IconButton> + </Tooltip> + {content} + </> + ); +}; diff --git a/src/shared/ui/filters-popover/index.ts b/src/shared/ui/filters-popover/index.ts new file mode 100644 index 00000000..95f80bee --- /dev/null +++ b/src/shared/ui/filters-popover/index.ts @@ -0,0 +1 @@ +export { FiltersPopover, type FiltersPopoverProps } from './filters-popover'; diff --git a/src/shared/ui/form/form.module.css b/src/shared/ui/form/form.module.css new file mode 100644 index 00000000..e0e4a9b3 --- /dev/null +++ b/src/shared/ui/form/form.module.css @@ -0,0 +1,6 @@ +.form { + display: grid; + gap: 1em; + + padding: 1.5em; +} diff --git a/src/shared/ui/form/form.module.css.d.ts b/src/shared/ui/form/form.module.css.d.ts new file mode 100644 index 00000000..824addc2 --- /dev/null +++ b/src/shared/ui/form/form.module.css.d.ts @@ -0,0 +1,4 @@ +declare const styles: { + readonly form: string; +}; +export = styles; diff --git a/src/shared/ui/form/form.tsx b/src/shared/ui/form/form.tsx new file mode 100644 index 00000000..b75ebcb2 --- /dev/null +++ b/src/shared/ui/form/form.tsx @@ -0,0 +1,15 @@ +import { Paper, PaperProps } from '@mui/material'; +import cn from 'classnames'; +import * as React from 'react'; + +import styles from './form.module.css'; + +export const Form: React.FC<PaperProps<'form'>> = (props) => { + const { className, children, ...rest } = props; + + return ( + <Paper className={cn(styles.form, className)} {...rest} component='form'> + {children} + </Paper> + ); +}; diff --git a/src/shared/ui/form/index.ts b/src/shared/ui/form/index.ts new file mode 100644 index 00000000..9398c9eb --- /dev/null +++ b/src/shared/ui/form/index.ts @@ -0,0 +1 @@ +export { Form } from './form'; diff --git a/src/shared/ui/friendly-list/friendly-list.module.css b/src/shared/ui/friendly-list/friendly-list.module.css new file mode 100644 index 00000000..649d1c3e --- /dev/null +++ b/src/shared/ui/friendly-list/friendly-list.module.css @@ -0,0 +1,23 @@ +.paper { + display: grid; + grid-template-rows: 1fr; + gap: 1em; + + padding: 0.5em 0; +} + +.after { + grid-template-rows: 1fr max-content; +} + +.before { + grid-template-rows: max-content 1fr; +} + +.both { + grid-template-rows: max-content 1fr max-content; +} + +.border-disabled { + border: 0; +} diff --git a/src/shared/ui/friendly-list/friendly-list.module.css.d.ts b/src/shared/ui/friendly-list/friendly-list.module.css.d.ts new file mode 100644 index 00000000..73b0324b --- /dev/null +++ b/src/shared/ui/friendly-list/friendly-list.module.css.d.ts @@ -0,0 +1,8 @@ +declare const styles: { + readonly after: string; + readonly before: string; + readonly 'border-disabled': string; + readonly both: string; + readonly paper: string; +}; +export = styles; diff --git a/src/shared/ui/friendly-list/friendly-list.tsx b/src/shared/ui/friendly-list/friendly-list.tsx new file mode 100644 index 00000000..630c554e --- /dev/null +++ b/src/shared/ui/friendly-list/friendly-list.tsx @@ -0,0 +1,157 @@ +import { Query } from '@farfetched/core'; +import { List, ListItemProps, Paper, Typography } from '@mui/material'; +import cn from 'classnames'; +import { useUnit } from 'effector-react'; +import * as React from 'react'; + +import { getEmptyArray } from '@/shared/configs'; +import { Classes, CommonProps, Slots } from '@/shared/types'; + +import { Center } from '../center'; + +import styles from './friendly-list.module.css'; + +interface BaseFriendlyListProps< + Item, + Error, + ListItemOmittedProps = Omit<ListItemProps, keyof Item> +> extends CommonProps { + readonly skeletonsCount: number; + readonly ItemComponent: React.ComponentType< + ListItemOmittedProps & Item & CommonProps + >; + readonly SkeletonComponent: React.ComponentType<ListItemOmittedProps>; + readonly ErrorComponent: React.ComponentType<{ readonly error: Error }>; + readonly emptyText: string; + readonly getKey: (item: Item) => React.Key | null; + readonly slots?: Slots<'before' | 'after'>; + readonly classes?: Classes<'list'>; + readonly disableBorder?: boolean; +} + +interface ArrayQueryFriendlyListProps<Item, Error> + extends BaseFriendlyListProps<Item, Error> { + readonly $query: Query<any, Item[], Error, any>; + readonly getData?: never; +} + +interface AnyQueryFriendlyListProps<RawData, Item, Error> + extends BaseFriendlyListProps<Item, Error> { + readonly $query: Query<any, RawData, Error, any>; + readonly getData: (data: RawData) => Item[] | null; +} + +export type FriendlyListProps<RawData, Item, Error> = + | ArrayQueryFriendlyListProps<Item, Error> + | AnyQueryFriendlyListProps<RawData, Item, Error>; + +export const FriendlyList = <RawData, Item, Error>( + props: FriendlyListProps<RawData, Item, Error> +): React.ReactElement => { + const { + $query, + getData, + getKey, + emptyText, + ErrorComponent, + ItemComponent, + SkeletonComponent, + skeletonsCount, + className, + slots, + disableBorder, + classes, + } = props; + + const finished = useUnit($query.finished); + const [alreadyFetched, setAlreadyFetched] = React.useState(finished); + + React.useEffect(() => { + if (finished) { + setAlreadyFetched(finished); + } + }, [finished]); + + const query = useUnit($query as Query<any, Item[] | RawData, any>); + + const arrayData = (getData ? getData(query.data as RawData) : query.data) as + | Item[] + | null; + + const isEmpty = !arrayData?.length; + const isLoading = query.pending && !alreadyFetched; + const isError = !query.error; + + let content: React.ReactElement | null = null; + + if (!isError) { + content = ( + <Center> + {React.createElement(ErrorComponent, { error: query.error, })} + </Center> + ); + } else if (isLoading) { + const array = getEmptyArray(skeletonsCount); + const count = array.length; + + const skeletons = array.map((_, index) => + React.createElement(SkeletonComponent, { + key: index, + divider: index + 1 !== count, + } as any) + ); + + content = ( + <List className={classes?.list} disablePadding> + {skeletons} + </List> + ); + } else if (isEmpty) { + content = ( + <Center> + <Typography fontWeight={500}>{emptyText}</Typography> + </Center> + ); + } else { + const count = arrayData.length; + const items = arrayData.map((item, index) => + React.createElement(ItemComponent, { + ...item, + divider: index + 1 !== count, + key: getKey(item), + } as any) + ); + + content = ( + <List className={classes?.list} disablePadding> + {items} + </List> + ); + } + + const hasBeforeSlot = !!slots?.before; + const hasAfterSlot = !!slots?.after; + const slotBefore = hasBeforeSlot ? <Center>{slots.before}</Center> : null; + const slotAfter = hasAfterSlot ? <Center>{slots.after}</Center> : null; + + const hasBothSlot = hasBeforeSlot && hasAfterSlot; + + const paperClasses = cn( + styles.paper, + { + [styles.after]: hasAfterSlot, + [styles.before]: hasBeforeSlot, + [styles.both]: hasBothSlot, + [styles['border-disabled']]: disableBorder, + }, + className + ); + + return ( + <Paper className={paperClasses}> + {slotBefore} + {content} + {slotAfter} + </Paper> + ); +}; diff --git a/src/shared/ui/friendly-list/index.ts b/src/shared/ui/friendly-list/index.ts new file mode 100644 index 00000000..8f2b01d9 --- /dev/null +++ b/src/shared/ui/friendly-list/index.ts @@ -0,0 +1 @@ +export { FriendlyList, type FriendlyListProps } from './friendly-list'; diff --git a/src/shared/ui/full-width-popup/full-width-popup.module.css b/src/shared/ui/full-width-popup/full-width-popup.module.css new file mode 100644 index 00000000..96005545 --- /dev/null +++ b/src/shared/ui/full-width-popup/full-width-popup.module.css @@ -0,0 +1,5 @@ +.cross { + position: absolute; + top: 8px; + right: 8px; +} diff --git a/src/shared/ui/full-width-popup/full-width-popup.module.css.d.ts b/src/shared/ui/full-width-popup/full-width-popup.module.css.d.ts new file mode 100644 index 00000000..80c727d4 --- /dev/null +++ b/src/shared/ui/full-width-popup/full-width-popup.module.css.d.ts @@ -0,0 +1,4 @@ +declare const styles: { + readonly cross: string; +}; +export = styles; diff --git a/src/shared/ui/full-width-popup/full-width-popup.tsx b/src/shared/ui/full-width-popup/full-width-popup.tsx new file mode 100644 index 00000000..13560a12 --- /dev/null +++ b/src/shared/ui/full-width-popup/full-width-popup.tsx @@ -0,0 +1,50 @@ +import CloseIcon from '@mui/icons-material/Close'; +import { + Dialog, + DialogActions, + DialogContent, + DialogTitle, + IconButton, + Slide, + SlideProps +} from '@mui/material'; +import * as React from 'react'; + +import { BasePopupProps, VoidFunction } from '@/shared/types'; + +import styles from './full-width-popup.module.css'; + +export interface FullWidthPopupProps + extends BasePopupProps, + React.PropsWithChildren { + readonly onClose: VoidFunction; + readonly title: string; +} + +export const FullWidthPopup: React.FC<FullWidthPopupProps> = (props) => { + const { isOpen, onClose, title, className, children, slots, } = props; + + return ( + <Dialog + open={isOpen} + onClose={onClose} + TransitionComponent={Transition} + fullScreen> + <DialogTitle align='center'> + {title} + <IconButton className={styles.cross} onClick={onClose}> + <CloseIcon /> + </IconButton> + </DialogTitle> + <DialogContent className={className}>{children}</DialogContent> + {slots?.actions ? <DialogActions>{slots.actions}</DialogActions> : null} + </Dialog> + ); +}; + +const Transition = React.forwardRef(function Transition( + props: NonNullable<SlideProps>, + ref: React.Ref<unknown> +) { + return <Slide direction='up' ref={ref} {...props} />; +}); diff --git a/src/shared/ui/full-width-popup/index.ts b/src/shared/ui/full-width-popup/index.ts new file mode 100644 index 00000000..9b50b36d --- /dev/null +++ b/src/shared/ui/full-width-popup/index.ts @@ -0,0 +1 @@ +export { FullWidthPopup, type FullWidthPopupProps } from './full-width-popup'; diff --git a/src/shared/ui/index.ts b/src/shared/ui/index.ts new file mode 100644 index 00000000..022d4ded --- /dev/null +++ b/src/shared/ui/index.ts @@ -0,0 +1,24 @@ +export * from './checkbox'; +export * from './date-time'; +export * from './edit-menu'; +export * from './field'; +export * from './loading-indicator'; +export * from './loading-wrapper'; +export * from './main-popup'; +export * from './menu-item'; +export * from './confirm'; +export * from './text-with-action'; +export * from './date-picker'; +export * from './controlled-toggle-button-group'; +export * from './filters-popover'; +export * from './section-header'; +export * from './full-width-popup'; +export * from './password-field'; +export * from './form'; +export * from './center'; +export * from './page-loader'; +export * from './page-title'; +export * from './show'; +export * from './friendly-list'; +export * from './template-header'; +export * from './layout'; diff --git a/src/shared/ui/layout/index.ts b/src/shared/ui/layout/index.ts new file mode 100644 index 00000000..bbb164fc --- /dev/null +++ b/src/shared/ui/layout/index.ts @@ -0,0 +1 @@ +export { Layout, type LayoutProps } from './layout'; diff --git a/src/shared/ui/layout/layout.module.css b/src/shared/ui/layout/layout.module.css new file mode 100644 index 00000000..63ec12c4 --- /dev/null +++ b/src/shared/ui/layout/layout.module.css @@ -0,0 +1,23 @@ +.wrapper { + display: grid; + grid-template-rows: max-content 1fr; + + min-height: 100vh; +} + +.wrapper--headerless { + grid-template-rows: 1fr; +} + +.layout { + width: 100%; + max-width: 1920px; + + padding: 2em; +} + +@media (max-width: 600px) { + .layout { + padding: 1em; + } +} diff --git a/src/shared/ui/layout/layout.module.css.d.ts b/src/shared/ui/layout/layout.module.css.d.ts new file mode 100644 index 00000000..b7f1d3f8 --- /dev/null +++ b/src/shared/ui/layout/layout.module.css.d.ts @@ -0,0 +1,6 @@ +declare const styles: { + readonly layout: string; + readonly wrapper: string; + readonly 'wrapper--headerless': string; +}; +export = styles; diff --git a/src/shared/ui/layout/layout.tsx b/src/shared/ui/layout/layout.tsx new file mode 100644 index 00000000..5c44fa41 --- /dev/null +++ b/src/shared/ui/layout/layout.tsx @@ -0,0 +1,33 @@ +import cn from 'classnames'; +import * as React from 'react'; + +import { CommonProps, Slots } from '@/shared/types'; + +import styles from './layout.module.css'; + + +export interface LayoutProps + extends CommonProps, + Required<React.PropsWithChildren> { + readonly slots?: Slots<'header'>; +} + +export const Layout: React.FC<LayoutProps> = (props) => { + const { className, children, slots = {}, } = props; + + const hasHeader = !!slots.header; + const classes = cn( + styles.wrapper, + { + [styles['wrapper--headerless']]: !hasHeader, + }, + className + ); + + return ( + <div className={classes}> + {slots.header} + <main className={styles.layout}>{children}</main> + </div> + ); +}; diff --git a/src/shared/ui/loading-indicator/index.ts b/src/shared/ui/loading-indicator/index.ts new file mode 100644 index 00000000..68f56fdb --- /dev/null +++ b/src/shared/ui/loading-indicator/index.ts @@ -0,0 +1,4 @@ +export { + LoadingIndicator, + type LoadingIndicatorProps +} from './loading-indicator'; diff --git a/src/shared/components/LoadingIndicator/LoadingIndicator.module.css b/src/shared/ui/loading-indicator/loading-indicator.module.css similarity index 100% rename from src/shared/components/LoadingIndicator/LoadingIndicator.module.css rename to src/shared/ui/loading-indicator/loading-indicator.module.css diff --git a/src/shared/ui/loading-indicator/loading-indicator.module.css.d.ts b/src/shared/ui/loading-indicator/loading-indicator.module.css.d.ts new file mode 100644 index 00000000..65872a4e --- /dev/null +++ b/src/shared/ui/loading-indicator/loading-indicator.module.css.d.ts @@ -0,0 +1,14 @@ +declare const styles: { + readonly circle: string; + readonly circle1: string; + readonly circle2: string; + readonly circle3: string; + readonly circle4: string; + readonly circleGroup: string; + readonly indicatorContainer: string; + readonly jump: string; + readonly large: string; + readonly medium: string; + readonly small: string; +}; +export = styles; diff --git a/src/shared/ui/loading-indicator/loading-indicator.tsx b/src/shared/ui/loading-indicator/loading-indicator.tsx new file mode 100644 index 00000000..1fc85fd8 --- /dev/null +++ b/src/shared/ui/loading-indicator/loading-indicator.tsx @@ -0,0 +1,36 @@ +import { Typography } from '@mui/material'; +import cn from 'classnames'; +import * as React from 'react'; + +import { CommonProps, Size } from '@/shared/types'; + +import styles from './loading-indicator.module.css'; + +export interface LoadingIndicatorProps extends CommonProps { + readonly size?: Size; + readonly text?: string | null; +} + +export const LoadingIndicator: React.FC<LoadingIndicatorProps> = (props) => { + const { className, text, size = 'medium', } = props; + const classes = cn(styles.indicatorContainer, styles[size]); + + return ( + <div className={className}> + <progress className='visibility-hidden' /> + <div className={classes}> + <div className={styles.circleGroup}> + <span className={cn(styles.circle, styles.circle1)} /> + <span className={cn(styles.circle, styles.circle2)} /> + <span className={cn(styles.circle, styles.circle3)} /> + <span className={cn(styles.circle, styles.circle4)} /> + </div> + {text && ( + <Typography align='center' fontWeight={500} component='h2'> + {text} + </Typography> + )} + </div> + </div> + ); +}; diff --git a/src/shared/ui/loading-wrapper/index.ts b/src/shared/ui/loading-wrapper/index.ts new file mode 100644 index 00000000..50bc30c4 --- /dev/null +++ b/src/shared/ui/loading-wrapper/index.ts @@ -0,0 +1 @@ +export { LoadingWrapper, type LoadingWrapperProps } from './loading-wrapper'; diff --git a/src/shared/ui/loading-wrapper/loading-wrapper.module.css b/src/shared/ui/loading-wrapper/loading-wrapper.module.css new file mode 100644 index 00000000..71e09fe7 --- /dev/null +++ b/src/shared/ui/loading-wrapper/loading-wrapper.module.css @@ -0,0 +1,10 @@ +.wrapper { + display: flex; + justify-content: center; + align-items: center; + + width: 100%; + height: 100%; + + /* background-color: white; */ +} diff --git a/src/shared/ui/loading-wrapper/loading-wrapper.module.css.d.ts b/src/shared/ui/loading-wrapper/loading-wrapper.module.css.d.ts new file mode 100644 index 00000000..6bc0cf72 --- /dev/null +++ b/src/shared/ui/loading-wrapper/loading-wrapper.module.css.d.ts @@ -0,0 +1,4 @@ +declare const styles: { + readonly wrapper: string; +}; +export = styles; diff --git a/src/shared/ui/loading-wrapper/loading-wrapper.tsx b/src/shared/ui/loading-wrapper/loading-wrapper.tsx new file mode 100644 index 00000000..63a12669 --- /dev/null +++ b/src/shared/ui/loading-wrapper/loading-wrapper.tsx @@ -0,0 +1,22 @@ +import cn from 'classnames'; +import * as React from 'react'; + +import { CommonProps } from '@/shared/types'; + +import styles from './loading-wrapper.module.css'; + +export interface LoadingWrapperProps extends CommonProps { + readonly isLoading: boolean; + readonly loadingIndicator: React.ReactElement; +} + +export const LoadingWrapper: React.FC< + React.PropsWithChildren<LoadingWrapperProps> +> = (props) => { + const { className, isLoading, loadingIndicator, children, } = props; + return ( + <div className={cn({ [styles.wrapper]: isLoading, }, className)}> + {isLoading ? loadingIndicator : children} + </div> + ); +}; diff --git a/src/shared/ui/main-popup/index.ts b/src/shared/ui/main-popup/index.ts new file mode 100644 index 00000000..91965ae5 --- /dev/null +++ b/src/shared/ui/main-popup/index.ts @@ -0,0 +1 @@ +export { MainPopup, type MainPopupProps } from './main-popup'; diff --git a/src/shared/ui/main-popup/main-popup.module.css b/src/shared/ui/main-popup/main-popup.module.css new file mode 100644 index 00000000..96005545 --- /dev/null +++ b/src/shared/ui/main-popup/main-popup.module.css @@ -0,0 +1,5 @@ +.cross { + position: absolute; + top: 8px; + right: 8px; +} diff --git a/src/shared/ui/main-popup/main-popup.module.css.d.ts b/src/shared/ui/main-popup/main-popup.module.css.d.ts new file mode 100644 index 00000000..80c727d4 --- /dev/null +++ b/src/shared/ui/main-popup/main-popup.module.css.d.ts @@ -0,0 +1,4 @@ +declare const styles: { + readonly cross: string; +}; +export = styles; diff --git a/src/shared/ui/main-popup/main-popup.tsx b/src/shared/ui/main-popup/main-popup.tsx new file mode 100644 index 00000000..79127568 --- /dev/null +++ b/src/shared/ui/main-popup/main-popup.tsx @@ -0,0 +1,47 @@ +import CloseIcon from '@mui/icons-material/Close'; +import { + Breakpoint, + Dialog, + DialogActions, + DialogContent, + DialogTitle, + IconButton +} from '@mui/material'; +import * as React from 'react'; + +import { BasePopupProps, CommonProps, VoidFunction } from '@/shared/types'; + +import styles from './main-popup.module.css'; + +export interface MainPopupProps extends CommonProps, BasePopupProps { + readonly onClose: VoidFunction; + readonly title: string; + readonly maxWidth?: Breakpoint; +} + +export const MainPopup: React.FC<React.PropsWithChildren<MainPopupProps>> = ( + props +) => { + const { + isOpen, + onClose, + children, + className, + title, + slots, + maxWidth = 'sm', + } = props; + + return ( + <Dialog open={isOpen} onClose={onClose} maxWidth={maxWidth} fullWidth> + <DialogTitle align='center'> + {title} + <IconButton className={styles.cross} onClick={onClose}> + <CloseIcon /> + </IconButton> + </DialogTitle> + <DialogContent className={className}>{children}</DialogContent> + {slots?.actions ? <DialogActions>{slots.actions}</DialogActions> : null} + </Dialog> + ); +}; diff --git a/src/shared/ui/menu-item/index.ts b/src/shared/ui/menu-item/index.ts new file mode 100644 index 00000000..81ad47d0 --- /dev/null +++ b/src/shared/ui/menu-item/index.ts @@ -0,0 +1 @@ +export { MenuItem, type MenuOption } from './menu-item'; diff --git a/src/shared/ui/menu-item/menu-item.tsx b/src/shared/ui/menu-item/menu-item.tsx new file mode 100644 index 00000000..b4e70036 --- /dev/null +++ b/src/shared/ui/menu-item/menu-item.tsx @@ -0,0 +1,47 @@ +import { ListItemIcon, MenuItem as MenuItemMUI } from '@mui/material'; +import { RouteInstance, RouteQuery } from 'atomic-router'; +import { Link } from 'atomic-router-react'; +import * as React from 'react'; + +import { CommonProps } from '@/shared/types'; + +interface BaseMenuOption { + readonly label: string; + readonly icon?: React.ReactElement; +} + +interface ButtonMenuOption extends BaseMenuOption { + readonly onClick: React.MouseEventHandler<HTMLButtonElement>; + readonly to?: never; + readonly params?: never; + readonly query?: never; +} + +interface LinkMenuOption<P extends object> extends BaseMenuOption { + readonly onClick?: React.MouseEventHandler<HTMLButtonElement>; + readonly to: RouteInstance<P>; + readonly params: P; + readonly query?: RouteQuery; +} + +export type MenuOption<P extends object> = ButtonMenuOption | LinkMenuOption<P>; + +export type MenuItemProps<P extends object> = CommonProps & + MenuOption<P> & { + readonly role?: React.AriaRole; + }; + +export const MenuItem = <P extends object>( + props: React.PropsWithChildren<MenuItemProps<P>> +) => { + const { label, icon, onClick, to, params, query, ...rest } = props; + const itemButtonProps = to + ? { component: Link, to, params, query, } + : { onClick, }; + return ( + <MenuItemMUI {...rest} {...(itemButtonProps as any)}> + {icon ? <ListItemIcon>{icon}</ListItemIcon> : null} + {label} + </MenuItemMUI> + ); +}; diff --git a/src/shared/ui/page-loader/index.ts b/src/shared/ui/page-loader/index.ts new file mode 100644 index 00000000..721cee8a --- /dev/null +++ b/src/shared/ui/page-loader/index.ts @@ -0,0 +1 @@ +export { PageLoader, type PageLoaderProps } from './page-loader'; diff --git a/src/shared/ui/page-loader/page-loader.tsx b/src/shared/ui/page-loader/page-loader.tsx new file mode 100644 index 00000000..ca0275d4 --- /dev/null +++ b/src/shared/ui/page-loader/page-loader.tsx @@ -0,0 +1,23 @@ +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { CommonProps } from '@/shared/types'; + +import { Center } from '../center'; +import { LoadingIndicator } from '../loading-indicator'; + +export interface PageLoaderProps extends CommonProps {} + +export const PageLoader: React.FC<PageLoaderProps> = (props) => { + const { className, } = props; + + const { t, } = useTranslation('common'); + + const loadingText = t('loading'); + + return ( + <Center className={className} height='page'> + <LoadingIndicator text={loadingText} /> + </Center> + ); +}; diff --git a/src/shared/ui/page-title/index.ts b/src/shared/ui/page-title/index.ts new file mode 100644 index 00000000..f15afa24 --- /dev/null +++ b/src/shared/ui/page-title/index.ts @@ -0,0 +1 @@ +export { PageTitle, type PageTitleProps } from './page-title'; diff --git a/src/shared/ui/page-title/page-title.module.css b/src/shared/ui/page-title/page-title.module.css new file mode 100644 index 00000000..36cb636c --- /dev/null +++ b/src/shared/ui/page-title/page-title.module.css @@ -0,0 +1,9 @@ +.wrapper { + display: grid; + grid-template-columns: 1fr max-content; + gap: 1em; +} + +.title { + font-weight: 700; +} diff --git a/src/shared/ui/page-title/page-title.module.css.d.ts b/src/shared/ui/page-title/page-title.module.css.d.ts new file mode 100644 index 00000000..b5fe8aa3 --- /dev/null +++ b/src/shared/ui/page-title/page-title.module.css.d.ts @@ -0,0 +1,5 @@ +declare const styles: { + readonly title: string; + readonly wrapper: string; +}; +export = styles; diff --git a/src/shared/ui/page-title/page-title.tsx b/src/shared/ui/page-title/page-title.tsx new file mode 100644 index 00000000..18591e5b --- /dev/null +++ b/src/shared/ui/page-title/page-title.tsx @@ -0,0 +1,24 @@ +import { Typography } from '@mui/material'; +import cn from 'classnames'; +import * as React from 'react'; + +import { CommonProps } from '@/shared/types'; + +import styles from './page-title.module.css'; + +export interface PageTitleProps extends CommonProps { + readonly title: React.ReactNode; + readonly extra?: React.ReactElement | null; +} + +export const PageTitle: React.FC<PageTitleProps> = (props) => { + const { extra, className, title, } = props; + return ( + <div className={cn(styles.wrapper, className)}> + <Typography className={styles.title} variant='h4' component='h1'> + {title} + </Typography> + {extra} + </div> + ); +}; diff --git a/src/shared/ui/password-field/index.ts b/src/shared/ui/password-field/index.ts new file mode 100644 index 00000000..c8bffcb9 --- /dev/null +++ b/src/shared/ui/password-field/index.ts @@ -0,0 +1 @@ +export { PasswordField, type PasswordFieldProps } from './password-field'; diff --git a/src/shared/ui/password-field/password-field.tsx b/src/shared/ui/password-field/password-field.tsx new file mode 100644 index 00000000..48d4c44d --- /dev/null +++ b/src/shared/ui/password-field/password-field.tsx @@ -0,0 +1,35 @@ +import Visibility from '@mui/icons-material/Visibility'; +import VisibilityOff from '@mui/icons-material/VisibilityOff'; +import { IconButton, InputAdornment } from '@mui/material'; +import * as React from 'react'; + +import { useToggle } from '@/shared/lib'; + +import { Field, FieldProps } from '../field'; + +export interface PasswordFieldProps + extends Omit<FieldProps, 'select' | 'type' | 'multiline'> {} + +export const PasswordField: React.FC<PasswordFieldProps> = (props) => { + const { InputProps, } = props; + const [showPassword, handlers] = useToggle(false); + + const type = showPassword ? 'text' : 'password'; + + return ( + <Field + {...props} + type={type} + InputProps={{ + ...InputProps, + endAdornment: ( + <InputAdornment position='end'> + <IconButton onClick={handlers.toggle}> + {showPassword ? <VisibilityOff /> : <Visibility />} + </IconButton> + </InputAdornment> + ), + }} + /> + ); +}; diff --git a/src/shared/ui/section-header/index.ts b/src/shared/ui/section-header/index.ts new file mode 100644 index 00000000..8ca8552f --- /dev/null +++ b/src/shared/ui/section-header/index.ts @@ -0,0 +1 @@ +export { SectionHeader, type SectionHeaderProps } from './section-header'; diff --git a/src/shared/ui/section-header/section-header.module.css b/src/shared/ui/section-header/section-header.module.css new file mode 100644 index 00000000..051b59fb --- /dev/null +++ b/src/shared/ui/section-header/section-header.module.css @@ -0,0 +1,10 @@ +.wrapper { + display: grid; + gap: 1em; + grid-template-columns: 1fr max-content; +} + +.actions { + display: flex; + gap: 0.5em; +} diff --git a/src/shared/ui/section-header/section-header.module.css.d.ts b/src/shared/ui/section-header/section-header.module.css.d.ts new file mode 100644 index 00000000..f078b0af --- /dev/null +++ b/src/shared/ui/section-header/section-header.module.css.d.ts @@ -0,0 +1,5 @@ +declare const styles: { + readonly actions: string; + readonly wrapper: string; +}; +export = styles; diff --git a/src/shared/ui/section-header/section-header.tsx b/src/shared/ui/section-header/section-header.tsx new file mode 100644 index 00000000..00b7073b --- /dev/null +++ b/src/shared/ui/section-header/section-header.tsx @@ -0,0 +1,24 @@ +import { Typography } from '@mui/material'; +import cn from 'classnames'; +import * as React from 'react'; + +import { CommonProps } from '@/shared/types'; + +import styles from './section-header.module.css'; + +export interface SectionHeaderProps extends CommonProps { + readonly title: string; + readonly actions?: React.ReactElement | null; +} + +export const SectionHeader: React.FC<SectionHeaderProps> = (props) => { + const { title, actions, className, } = props; + return ( + <header className={cn(styles.wrapper, className)}> + <Typography variant='h5' component='h2' fontWeight={700}> + {title} + </Typography> + <div className={styles.actions}>{actions}</div> + </header> + ); +}; diff --git a/src/shared/ui/show/index.ts b/src/shared/ui/show/index.ts new file mode 100644 index 00000000..734b739d --- /dev/null +++ b/src/shared/ui/show/index.ts @@ -0,0 +1 @@ +export { Show, type ShowProps } from './show'; diff --git a/src/shared/ui/show/show.tsx b/src/shared/ui/show/show.tsx new file mode 100644 index 00000000..e1ec4a0a --- /dev/null +++ b/src/shared/ui/show/show.tsx @@ -0,0 +1,15 @@ +import * as React from 'react'; + +export interface ShowProps extends Required<React.PropsWithChildren> { + readonly show: boolean; +} + +export const Show: React.FC<ShowProps> = (props) => { + const { show, children, } = props; + + if (show) { + return children; + } + + return null; +}; diff --git a/src/shared/ui/template-header/index.ts b/src/shared/ui/template-header/index.ts new file mode 100644 index 00000000..12e409bf --- /dev/null +++ b/src/shared/ui/template-header/index.ts @@ -0,0 +1 @@ +export { TemplateHeader, type TemplateHeaderProps } from './template-header'; diff --git a/src/shared/ui/template-header/template-header.module.css b/src/shared/ui/template-header/template-header.module.css new file mode 100644 index 00000000..d7052f41 --- /dev/null +++ b/src/shared/ui/template-header/template-header.module.css @@ -0,0 +1,52 @@ +.container { + border-left: none; + border-top: none; + border-right: none; +} + +.bar { + display: grid; + grid-template-columns: 150px 1fr 150px; + gap: 0.5em; + align-items: center; + + padding: 0 1em; + + overflow: hidden; +} + +.left { + grid-column: 1; + justify-self: start; +} + +.center { + grid-column: 2; + justify-self: center; +} + +.right { + grid-column: 3; + justify-self: end; +} + +.side { + display: flex; + align-items: center; + gap: inherit; +} + +@media (max-width: 1024px) { + .bar { + grid-template-columns: repeat(2, 1fr); + } + + .center { + grid-column: 1 / -1; + grid-row: 2; + } + + .right { + grid-column: 2; + } +} diff --git a/src/shared/ui/template-header/template-header.module.css.d.ts b/src/shared/ui/template-header/template-header.module.css.d.ts new file mode 100644 index 00000000..1a2375a9 --- /dev/null +++ b/src/shared/ui/template-header/template-header.module.css.d.ts @@ -0,0 +1,9 @@ +declare const styles: { + readonly bar: string; + readonly center: string; + readonly container: string; + readonly left: string; + readonly right: string; + readonly side: string; +}; +export = styles; diff --git a/src/shared/ui/template-header/template-header.tsx b/src/shared/ui/template-header/template-header.tsx new file mode 100644 index 00000000..a1470244 --- /dev/null +++ b/src/shared/ui/template-header/template-header.tsx @@ -0,0 +1,32 @@ +import { AppBar, Toolbar } from '@mui/material'; +import cn from 'classnames'; +import * as React from 'react'; + +import { CommonProps, Slots } from '@/shared/types'; + +import styles from './template-header.module.css'; + +export interface TemplateHeaderProps extends CommonProps { + readonly slots?: Slots<'left' | 'right' | 'center'>; +} + +export const TemplateHeader: React.FC<TemplateHeaderProps> = (props) => { + const { className, slots = {}, } = props; + + return ( + <AppBar + className={cn(styles.container, className)} + position='static' + color='default' + elevation={0} + variant='outlined'> + <Toolbar className={styles.bar}> + <div className={cn(styles.left, styles.side)}>{slots.left}</div> + {slots.center ? ( + <div className={styles.center}>{slots.center}</div> + ) : null} + <div className={cn(styles.right, styles.side)}>{slots.right}</div> + </Toolbar> + </AppBar> + ); +}; diff --git a/src/shared/ui/text-with-action/index.ts b/src/shared/ui/text-with-action/index.ts new file mode 100644 index 00000000..b4f5326c --- /dev/null +++ b/src/shared/ui/text-with-action/index.ts @@ -0,0 +1 @@ +export { TextWithAction, type TextWithActionProps } from './text-with-action'; diff --git a/src/shared/ui/text-with-action/text-with-action.module.css b/src/shared/ui/text-with-action/text-with-action.module.css new file mode 100644 index 00000000..0c2816e9 --- /dev/null +++ b/src/shared/ui/text-with-action/text-with-action.module.css @@ -0,0 +1,8 @@ +.box { + display: flex; + gap: 1em; + flex-direction: column; + align-items: center; + + padding: 1em; +} diff --git a/src/shared/ui/text-with-action/text-with-action.module.css.d.ts b/src/shared/ui/text-with-action/text-with-action.module.css.d.ts new file mode 100644 index 00000000..81502483 --- /dev/null +++ b/src/shared/ui/text-with-action/text-with-action.module.css.d.ts @@ -0,0 +1,4 @@ +declare const styles: { + readonly box: string; +}; +export = styles; diff --git a/src/shared/ui/text-with-action/text-with-action.tsx b/src/shared/ui/text-with-action/text-with-action.tsx new file mode 100644 index 00000000..9948dc7d --- /dev/null +++ b/src/shared/ui/text-with-action/text-with-action.tsx @@ -0,0 +1,29 @@ +import { Button, Typography } from '@mui/material'; +import cn from 'classnames'; +import * as React from 'react'; + +import { CommonProps, VoidFunction } from '@/shared/types'; + +import styles from './text-with-action.module.css'; + +export interface TextWithActionProps extends CommonProps { + readonly text: string; + readonly onClick: VoidFunction; + readonly actionText: string; + readonly icon?: React.ReactElement | null; +} + +export const TextWithAction: React.FC<TextWithActionProps> = (props) => { + const { text, onClick, className, actionText, icon, } = props; + + return ( + <div className={cn(styles.box, className)}> + <Typography variant='h6' component='p'> + {text} + </Typography> + <Button startIcon={icon} onClick={onClick}> + {actionText} + </Button> + </div> + ); +}; diff --git a/src/types/api.ts b/src/types/api.ts deleted file mode 100644 index b814e4e0..00000000 --- a/src/types/api.ts +++ /dev/null @@ -1,5 +0,0 @@ -export type Query = { - readonly [key: string]: QueryValue; -}; - -export type QueryValue = string | number | undefined | null; diff --git a/src/types/common.ts b/src/types/common.ts deleted file mode 100644 index c91b6e59..00000000 --- a/src/types/common.ts +++ /dev/null @@ -1,26 +0,0 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ -import { Template, String, Static } from 'runtypes'; - -export const hex = Template`#${String.withConstraint( - (code) => code.length === 3 || code.length === 6 -)}`; -export type HEX = Static<typeof hex>; - -export interface CommonProps { - className?: string; -} - -export type AnyObject = Record<string, any>; - -export type ExtractProps< - T extends AnyFunction, - K extends keyof Parameters<T>[0] = never -> = Omit<Parameters<T>[0], K>; - -export type AnyFunction = (...args: any[]) => any; - -export type VoidFunction = () => void; - -export type AddType<T extends AnyObject, AT> = { - [K in keyof T]: T[K] | AT; -}; diff --git a/src/types/index.ts b/src/types/index.ts deleted file mode 100644 index 6cd77d8d..00000000 --- a/src/types/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -export * from './api'; -export * from './common'; -export * from './request'; -export * from './response'; -export * from './styles'; -export * from './ui'; diff --git a/src/types/request.ts b/src/types/request.ts deleted file mode 100644 index d16ec678..00000000 --- a/src/types/request.ts +++ /dev/null @@ -1,3 +0,0 @@ -export interface InRoomRequest { - readonly roomId: number; -} diff --git a/src/types/response.ts b/src/types/response.ts deleted file mode 100644 index c58c176e..00000000 --- a/src/types/response.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { Runtype, Record, Null, Number, String, Static, Union } from 'runtypes'; - -export const getStandardSuccessResponse = <RT>(T: Runtype<RT>) => { - return Record({ - data: T, - errorMessage: Null, - statusCode: Number, - }).asReadonly(); -}; - -export interface StandardSuccessResponse<T> { - readonly data: T; - readonly errorMessage: null; - readonly statusCode: number; -} - -export const standardFailResponse = Record({ - data: Null, - errorMessage: String, - statusCode: Number, -}).asReadonly(); - -export type StandardFailResponse = Static<typeof standardFailResponse>; - -export const getStandardResponse = <RT>(T: Runtype<RT>) => { - return Union(getStandardSuccessResponse(T), standardFailResponse); -}; - -export type StandardResponse<T> = - | StandardFailResponse - | StandardSuccessResponse<T>; - -export const voidResponse = Record({}); -export type VoidResponse = Static<typeof voidResponse>; diff --git a/src/types/styles.ts b/src/types/styles.ts deleted file mode 100644 index 64dd32ce..00000000 --- a/src/types/styles.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { experimental_extendTheme as extendTheme } from '@mui/material'; - -export const theme = extendTheme({ - shape: { - borderRadius: 8, - }, - spacing: (tab: number) => `${tab}rem`, -}); diff --git a/src/types/ui.ts b/src/types/ui.ts deleted file mode 100644 index 298de7a7..00000000 --- a/src/types/ui.ts +++ /dev/null @@ -1,12 +0,0 @@ -export type Size = 'small' | 'medium' | 'large'; -export type Color = - | 'primary' - | 'secondary' - | 'success' - | 'error' - | 'warning' - | 'dark'; - -export interface BasePopupProps { - readonly isOpen: boolean; -} diff --git a/src/utils/index.ts b/src/utils/index.ts deleted file mode 100644 index 0cb6d1bb..00000000 --- a/src/utils/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { prepareQuery } from './prepareQuery'; -export { prepareLink, type PrepareLinkParams } from './prepareLink'; diff --git a/src/utils/prepareLink.ts b/src/utils/prepareLink.ts deleted file mode 100644 index 40e4f305..00000000 --- a/src/utils/prepareLink.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { Query, AddType } from '@/types'; -import { Location } from '@/models'; -import { prepareQuery } from './prepareQuery'; - -export interface PrepareLinkParams { - readonly path?: string; - readonly query?: Query; - readonly keepOldQuery?: boolean; - readonly deleteQuery?: AddType<Query, boolean>; -} - -export const prepareLink = ( - location: Location, - params: PrepareLinkParams -): string => { - const { path, query = {}, keepOldQuery = false, deleteQuery } = params; - - let newQuery = prepareQuery(query, keepOldQuery ? location.query : {}); - newQuery = prepareQuery(query, {}, deleteQuery); - const to = path ?? location.path; - - return `${to}?${newQuery}`; -}; diff --git a/src/utils/prepareQuery.ts b/src/utils/prepareQuery.ts deleted file mode 100644 index 29df5c4d..00000000 --- a/src/utils/prepareQuery.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { Query, AddType } from '@/types'; - -export const prepareQuery = ( - query: Query, - defaultValue?: Record<string, string>, - deletedQuery: AddType<Query, boolean> = {} -): URLSearchParams => { - const newQuery = new URLSearchParams(defaultValue); - - Object.entries(query).forEach(([key, value]) => { - const deletedValue = deletedQuery[key]; - if (typeof value !== 'undefined' && value !== null) { - newQuery.set(key, value.toString()); - } else if (deletedValue) { - newQuery.delete(key); - } - }); - - return newQuery; -}; diff --git a/src/widgets/invitations/index.ts b/src/widgets/invitations/index.ts new file mode 100644 index 00000000..452c4133 --- /dev/null +++ b/src/widgets/invitations/index.ts @@ -0,0 +1,2 @@ +export * from './models'; +export * from './ui'; diff --git a/src/widgets/invitations/models/create-invitation.ts b/src/widgets/invitations/models/create-invitation.ts new file mode 100644 index 00000000..fd354d24 --- /dev/null +++ b/src/widgets/invitations/models/create-invitation.ts @@ -0,0 +1,22 @@ +import { sample } from 'effector'; + +import { inviteUserIntoRoomModel } from '@/features/invitation'; + +import { createPopupControlModel } from '@/entities/popups'; +import { searchUserModel } from '@/entities/users'; + +import { popupsMap } from '@/shared/configs'; + +export const { close, $isOpen, } = createPopupControlModel( + popupsMap.createInvitation +); + +sample({ + clock: inviteUserIntoRoomModel.mutation.finished.success, + target: close, +}); + +sample({ + clock: close, + target: [searchUserModel.query.reset, inviteUserIntoRoomModel.form.reset], +}); diff --git a/src/widgets/invitations/models/index.ts b/src/widgets/invitations/models/index.ts new file mode 100644 index 00000000..184997ef --- /dev/null +++ b/src/widgets/invitations/models/index.ts @@ -0,0 +1 @@ +export * as createInvitationModel from './create-invitation'; diff --git a/src/widgets/invitations/ui/create-invitation/create-invitation-button.tsx b/src/widgets/invitations/ui/create-invitation/create-invitation-button.tsx new file mode 100644 index 00000000..42c3e73c --- /dev/null +++ b/src/widgets/invitations/ui/create-invitation/create-invitation-button.tsx @@ -0,0 +1,33 @@ +import PersonAddAlt1Icon from '@mui/icons-material/PersonAddAlt1'; +import { IconButton, Tooltip } from '@mui/material'; +import { Link } from 'atomic-router-react'; +import { useUnit } from 'effector-react'; +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { getParams, popupsMap, routes } from '@/shared/configs'; +import { CommonProps } from '@/shared/types'; + +export interface CreateInvitationButtonProps extends CommonProps {} + +export const CreateInvitationButton: React.FC<CreateInvitationButtonProps> = + React.memo(() => { + const { t, } = useTranslation('room-invitations'); + const params = useUnit(routes.room.users.$params); + + const title = t('actions.create_invitation.actions.open'); + + return ( + <Tooltip title={title}> + <IconButton + to={routes.room.users as any} + params={params} + query={{ + [getParams.popup]: popupsMap.createInvitation, + }} + component={Link}> + <PersonAddAlt1Icon /> + </IconButton> + </Tooltip> + ); + }); diff --git a/src/widgets/invitations/ui/create-invitation/create-invitation.module.css b/src/widgets/invitations/ui/create-invitation/create-invitation.module.css new file mode 100644 index 00000000..5b341d56 --- /dev/null +++ b/src/widgets/invitations/ui/create-invitation/create-invitation.module.css @@ -0,0 +1,3 @@ +.tab { + padding: 0; +} diff --git a/src/widgets/invitations/ui/create-invitation/create-invitation.module.css.d.ts b/src/widgets/invitations/ui/create-invitation/create-invitation.module.css.d.ts new file mode 100644 index 00000000..650f1a91 --- /dev/null +++ b/src/widgets/invitations/ui/create-invitation/create-invitation.module.css.d.ts @@ -0,0 +1,4 @@ +declare const styles: { + readonly tab: string; +}; +export = styles; diff --git a/src/widgets/invitations/ui/create-invitation/create-invitation.tsx b/src/widgets/invitations/ui/create-invitation/create-invitation.tsx new file mode 100644 index 00000000..615d3f77 --- /dev/null +++ b/src/widgets/invitations/ui/create-invitation/create-invitation.tsx @@ -0,0 +1,77 @@ +import AddLinkIcon from '@mui/icons-material/AddLink'; +import PersonAddIcon from '@mui/icons-material/PersonAdd'; +import { TabContext, TabList, TabPanel } from '@mui/lab'; +import { Tab } from '@mui/material'; +import { useUnit } from 'effector-react'; +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { + GenerateInvitationLink, + InviteUserIntoRoom +} from '@/features/invitation'; + +import { routes } from '@/shared/configs'; +import { useParam } from '@/shared/lib'; +import { deviceInfoModel } from '@/shared/models'; +import { BasePopupProps, CommonProps } from '@/shared/types'; +import { MainPopup } from '@/shared/ui'; + +import { createInvitationModel } from '../../models'; + +import styles from './create-invitation.module.css'; + +export interface CreateInvitationProps extends CommonProps, BasePopupProps {} + +export const CreateInvitation: React.FC<CreateInvitationProps> = (props) => { + const [tab, setTab] = React.useState('invite_user'); + const { t, } = useTranslation('room-invitations'); + const roomId = useParam(routes.room.users, 'id'); + + const close = useUnit(createInvitationModel.close); + + const [isVertical, isMobile] = useUnit([ + deviceInfoModel.$isTabletVertical, + deviceInfoModel.$isMobile + ]); + + const showLabels = !isVertical && !isMobile; + + const translation = t('actions', { returnObjects: true, }) as Record< + string, + any + >; + + const { title, } = translation[tab]; + + const onChange = React.useCallback((_evt: unknown, value: string) => { + setTab(value); + }, []); + + return ( + <MainPopup {...props} title={title} onClose={close}> + <TabContext value={tab}> + <TabList onChange={onChange} variant='fullWidth' scrollButtons='auto'> + <Tab + icon={<AddLinkIcon />} + iconPosition='start' + label={showLabels ? translation.generate_link.title_short : null} + value='generate_link' + /> + <Tab + icon={<PersonAddIcon />} + iconPosition='start' + label={showLabels ? translation.invite_user.title_short : null} + value='invite_user' + /> + </TabList> + <TabPanel className={styles.tab} value='generate_link'> + <GenerateInvitationLink roomId={roomId} /> + </TabPanel> + <TabPanel className={styles.tab} value='invite_user'> + <InviteUserIntoRoom /> + </TabPanel> + </TabContext> + </MainPopup> + ); +}; diff --git a/src/widgets/invitations/ui/create-invitation/index.ts b/src/widgets/invitations/ui/create-invitation/index.ts new file mode 100644 index 00000000..d5bb016e --- /dev/null +++ b/src/widgets/invitations/ui/create-invitation/index.ts @@ -0,0 +1,8 @@ +export { + CreateInvitation, + type CreateInvitationProps +} from './create-invitation'; +export { + CreateInvitationButton, + type CreateInvitationButtonProps +} from './create-invitation-button'; diff --git a/src/widgets/invitations/ui/index.ts b/src/widgets/invitations/ui/index.ts new file mode 100644 index 00000000..0a1db956 --- /dev/null +++ b/src/widgets/invitations/ui/index.ts @@ -0,0 +1,3 @@ +export * from './create-invitation'; +export * from './invitation-list-item'; +export * from './invitation-card'; diff --git a/src/widgets/invitations/ui/invitation-card/index.ts b/src/widgets/invitations/ui/invitation-card/index.ts new file mode 100644 index 00000000..37d8d303 --- /dev/null +++ b/src/widgets/invitations/ui/invitation-card/index.ts @@ -0,0 +1 @@ +export { InvitationCard, type InvitationCardProps } from './ui'; diff --git a/src/widgets/invitations/ui/invitation-card/ui.tsx b/src/widgets/invitations/ui/invitation-card/ui.tsx new file mode 100644 index 00000000..035508ff --- /dev/null +++ b/src/widgets/invitations/ui/invitation-card/ui.tsx @@ -0,0 +1,69 @@ +import { useUnit } from 'effector-react'; +import * as React from 'react'; + +import { + ApproveInvitationButton, + RejectInvitationButton +} from '@/features/invitation'; + +import { TemplateInvitationCard } from '@/entities/invitations'; +import { UserAvatar } from '@/entities/users'; + +import { Room, User } from '@/shared/api'; +import { sessionModel } from '@/shared/models'; +import { CommonProps } from '@/shared/types'; + + + +export interface InvitationCardProps extends CommonProps { + readonly id: number; + readonly inviter: User; + readonly room: Room; +} + +export const InvitationCard: React.FC<InvitationCardProps> = (props) => { + const { id, inviter, room, className, } = props; + + const user = useUnit(sessionModel.$user); + + if (!user) { + return null; + } + + const inviterAvatar = ( + <UserAvatar + email={inviter.email} + photo={inviter.photo} + username={inviter.username} + /> + ); + + const userAvatar = ( + <UserAvatar + email={user.email} + photo={user.photo} + username={user.username} + /> + ); + + const actions = ( + <> + <RejectInvitationButton id={id} /> + <ApproveInvitationButton id={id} /> + </> + ); + + return ( + <TemplateInvitationCard + className={className} + inviterName={inviter.username} + roomName={room.name} + username={user.username} + slots={{ + inviterAvatar, + userAvatar, + actions, + }} + /> + ); +}; diff --git a/src/widgets/invitations/ui/invitation-list-item/index.ts b/src/widgets/invitations/ui/invitation-list-item/index.ts new file mode 100644 index 00000000..1751f614 --- /dev/null +++ b/src/widgets/invitations/ui/invitation-list-item/index.ts @@ -0,0 +1,4 @@ +export { + InvitationListItem, + type InvitationListItemProps +} from './invitation-list-item'; diff --git a/src/widgets/invitations/ui/invitation-list-item/invitation-list-item.tsx b/src/widgets/invitations/ui/invitation-list-item/invitation-list-item.tsx new file mode 100644 index 00000000..ba263d2f --- /dev/null +++ b/src/widgets/invitations/ui/invitation-list-item/invitation-list-item.tsx @@ -0,0 +1,48 @@ +import { useUnit } from 'effector-react'; +import * as React from 'react'; + +import { RemoveInvitation } from '@/features/invitation'; + +import { + TemplateInvitationListItem, + TemplateInvitationListItemProps +} from '@/entities/invitations'; +import { roomModel } from '@/entities/rooms'; +import { UserAvatar } from '@/entities/users'; + +import { CommonProps } from '@/shared/types'; + +export interface InvitationListItemProps + extends CommonProps, + Omit<TemplateInvitationListItemProps, 'slots' | 'id'> { + readonly id: number; + readonly roomId: number; + readonly email: string; + readonly photo: string | null; +} + +export const InvitationListItem: React.FC<InvitationListItemProps> = ( + props +) => { + const { id, roomId, username, email, photo, ...rest } = props; + const canChange = useUnit(roomModel.$canChange); + + const actions = canChange ? ( + <RemoveInvitation id={id} roomId={roomId} /> + ) : null; + + const userAvatar = ( + <UserAvatar username={username} email={email} photo={photo} /> + ); + + return ( + <TemplateInvitationListItem + {...rest} + username={username} + slots={{ + userAvatar, + actions, + }} + /> + ); +}; diff --git a/src/widgets/page/index.ts b/src/widgets/page/index.ts new file mode 100644 index 00000000..5ecdd1f3 --- /dev/null +++ b/src/widgets/page/index.ts @@ -0,0 +1 @@ +export * from './ui'; diff --git a/src/widgets/page/ui/auth-header/auth-header.tsx b/src/widgets/page/ui/auth-header/auth-header.tsx new file mode 100644 index 00000000..24e52c79 --- /dev/null +++ b/src/widgets/page/ui/auth-header/auth-header.tsx @@ -0,0 +1,26 @@ +import * as React from 'react'; + +import { AdaptiveColorSchemeToggler, ChangeLanguage } from '@/features/page'; + +import { CommonProps } from '@/shared/types'; +import { TemplateHeader } from '@/shared/ui'; + +export interface AuthHeaderProps extends CommonProps {} + +export const AuthHeader: React.FC<AuthHeaderProps> = (props) => { + const { className, } = props; + + return ( + <TemplateHeader + className={className} + slots={{ + right: ( + <> + <ChangeLanguage /> + <AdaptiveColorSchemeToggler /> + </> + ), + }} + /> + ); +}; diff --git a/src/widgets/page/ui/auth-header/index.ts b/src/widgets/page/ui/auth-header/index.ts new file mode 100644 index 00000000..f34a7c11 --- /dev/null +++ b/src/widgets/page/ui/auth-header/index.ts @@ -0,0 +1 @@ +export { AuthHeader, type AuthHeaderProps } from './auth-header'; diff --git a/src/widgets/page/ui/auth-layout/auth-layout.tsx b/src/widgets/page/ui/auth-layout/auth-layout.tsx new file mode 100644 index 00000000..993c04f7 --- /dev/null +++ b/src/widgets/page/ui/auth-layout/auth-layout.tsx @@ -0,0 +1,27 @@ +import * as React from 'react'; + +import { Classes, CommonProps } from '@/shared/types'; +import { Center, Layout } from '@/shared/ui'; + +import { AuthHeader } from '../auth-header'; + +export interface AuthLayoutProps extends CommonProps { + readonly classes?: Classes<'header' | 'center'>; +} + +export const AuthLayout: React.FC<React.PropsWithChildren<AuthLayoutProps>> = ( + props +) => { + const { className, classes, children, } = props; + return ( + <Layout + className={className} + slots={{ + header: <AuthHeader className={classes?.header} />, + }}> + <Center className={classes?.center} height='container'> + {children} + </Center> + </Layout> + ); +}; diff --git a/src/widgets/page/ui/auth-layout/index.ts b/src/widgets/page/ui/auth-layout/index.ts new file mode 100644 index 00000000..ec3cb0e8 --- /dev/null +++ b/src/widgets/page/ui/auth-layout/index.ts @@ -0,0 +1 @@ +export { AuthLayout, type AuthLayoutProps } from './auth-layout'; diff --git a/src/widgets/page/ui/error-boundary/error-boundary.tsx b/src/widgets/page/ui/error-boundary/error-boundary.tsx new file mode 100644 index 00000000..a2681e16 --- /dev/null +++ b/src/widgets/page/ui/error-boundary/error-boundary.tsx @@ -0,0 +1,20 @@ +import * as React from 'react'; + +import { CommonProps } from '@/shared/types'; + +export interface ErrorBoundaryProps extends CommonProps {} + +export class ErrorBoundary extends React.Component<React.PropsWithChildren> { + componentDidCatch(error: Error): void { + console.log(error); + } + + static getDerivedStateFromError() { + return <div>Error</div>; + } + + render(): React.ReactNode { + const { children, } = this.props; + return children; + } +} diff --git a/src/widgets/page/ui/error-boundary/index.ts b/src/widgets/page/ui/error-boundary/index.ts new file mode 100644 index 00000000..7bc73e59 --- /dev/null +++ b/src/widgets/page/ui/error-boundary/index.ts @@ -0,0 +1 @@ +export { ErrorBoundary, type ErrorBoundaryProps } from './error-boundary'; diff --git a/src/widgets/page/ui/index.ts b/src/widgets/page/ui/index.ts new file mode 100644 index 00000000..a31666a2 --- /dev/null +++ b/src/widgets/page/ui/index.ts @@ -0,0 +1,6 @@ +export * from './auth-header'; +export * from './error-boundary'; +export * from './main-header'; +export * from './popups'; +export * from './auth-layout'; +export * from './main-layout'; diff --git a/src/widgets/page/ui/main-header/index.ts b/src/widgets/page/ui/main-header/index.ts new file mode 100644 index 00000000..e1d1c7bd --- /dev/null +++ b/src/widgets/page/ui/main-header/index.ts @@ -0,0 +1 @@ +export { MainHeader, type MainHeaderProps } from './main-header'; diff --git a/src/widgets/page/ui/main-header/main-header.tsx b/src/widgets/page/ui/main-header/main-header.tsx new file mode 100644 index 00000000..f85f8075 --- /dev/null +++ b/src/widgets/page/ui/main-header/main-header.tsx @@ -0,0 +1,39 @@ +import * as React from 'react'; + +import { ProfileMenu } from '@/features/auth'; +import { AdaptiveColorSchemeToggler, ChangeLanguage } from '@/features/page'; + +import { CommonProps } from '@/shared/types'; +import { TemplateHeader, TemplateHeaderProps } from '@/shared/ui'; + +import { Menu } from '../menu'; + + +export interface MainHeaderProps extends CommonProps, TemplateHeaderProps {} + +export const MainHeader: React.FC<MainHeaderProps> = (props) => { + const { className, slots, } = props; + + return ( + <TemplateHeader + className={className} + slots={{ + ...slots, + left: ( + <> + <Menu /> + {slots?.left} + </> + ), + right: ( + <> + {slots?.right} + <ChangeLanguage /> + <AdaptiveColorSchemeToggler /> + <ProfileMenu /> + </> + ), + }} + /> + ); +}; diff --git a/src/widgets/page/ui/main-layout/index.ts b/src/widgets/page/ui/main-layout/index.ts new file mode 100644 index 00000000..b8249639 --- /dev/null +++ b/src/widgets/page/ui/main-layout/index.ts @@ -0,0 +1 @@ +export { MainLayout, type MainLayoutProps } from './main-layout'; diff --git a/src/widgets/page/ui/main-layout/main-layout.tsx b/src/widgets/page/ui/main-layout/main-layout.tsx new file mode 100644 index 00000000..2e57c453 --- /dev/null +++ b/src/widgets/page/ui/main-layout/main-layout.tsx @@ -0,0 +1,24 @@ +import * as React from 'react'; + +import { CommonProps } from '@/shared/types'; +import { Layout } from '@/shared/ui'; + +import { MainHeader } from '../main-header'; + +export interface MainLayoutProps + extends CommonProps, + Required<React.PropsWithChildren> {} + +export const MainLayout: React.FC<MainLayoutProps> = (props) => { + const { className, children, } = props; + + return ( + <Layout + className={className} + slots={{ + header: <MainHeader />, + }}> + {children} + </Layout> + ); +}; diff --git a/src/widgets/page/ui/menu/index.ts b/src/widgets/page/ui/menu/index.ts new file mode 100644 index 00000000..01435c7b --- /dev/null +++ b/src/widgets/page/ui/menu/index.ts @@ -0,0 +1 @@ +export { Menu } from './menu'; diff --git a/src/widgets/page/ui/menu/menu.module.css b/src/widgets/page/ui/menu/menu.module.css new file mode 100644 index 00000000..61f70f47 --- /dev/null +++ b/src/widgets/page/ui/menu/menu.module.css @@ -0,0 +1,3 @@ +.menu { + min-width: 250px; +} diff --git a/src/widgets/page/ui/menu/menu.module.css.d.ts b/src/widgets/page/ui/menu/menu.module.css.d.ts new file mode 100644 index 00000000..a7957c0b --- /dev/null +++ b/src/widgets/page/ui/menu/menu.module.css.d.ts @@ -0,0 +1,4 @@ +declare const styles: { + readonly menu: string; +}; +export = styles; diff --git a/src/widgets/page/ui/menu/menu.tsx b/src/widgets/page/ui/menu/menu.tsx new file mode 100644 index 00000000..56f53fa9 --- /dev/null +++ b/src/widgets/page/ui/menu/menu.tsx @@ -0,0 +1,51 @@ +/* eslint-disable jsx-a11y/no-static-element-interactions */ +/* eslint-disable jsx-a11y/click-events-have-key-events */ +import MenuIcon from '@mui/icons-material/Menu'; +import { + Divider, + Drawer, + IconButton, + List, + ListSubheader +} from '@mui/material'; +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { Navigation } from '@/features/page'; + +import { RoomListItem, useRooms } from '@/entities/rooms'; + +import { useToggle } from '@/shared/lib'; + +import styles from './menu.module.css'; + +export const Menu: React.FC = () => { + const [isOpen, { toggleOff: close, toggleOn: open, }] = useToggle(); + const rooms = useRooms(); + const { t, } = useTranslation('common'); + + const subheader = t('navigation.menu.title'); + + return ( + <> + <IconButton onClick={isOpen ? close : open}> + <MenuIcon /> + </IconButton> + <Drawer + open={isOpen} + onClose={close} + PaperProps={{ className: styles.menu, }}> + <div onClick={close}> + <Navigation /> + <Divider /> + <List> + <ListSubheader disableSticky>{subheader}</ListSubheader> + {rooms.data.map((room) => ( + <RoomListItem {...room} key={room.id} /> + ))} + </List> + </div> + </Drawer> + </> + ); +}; diff --git a/src/widgets/page/ui/popups/index.ts b/src/widgets/page/ui/popups/index.ts new file mode 100644 index 00000000..5958e2bc --- /dev/null +++ b/src/widgets/page/ui/popups/index.ts @@ -0,0 +1 @@ +export { Popups, type PopupsProps } from './popups'; diff --git a/src/widgets/page/ui/popups/popups.tsx b/src/widgets/page/ui/popups/popups.tsx new file mode 100644 index 00000000..8dd24475 --- /dev/null +++ b/src/widgets/page/ui/popups/popups.tsx @@ -0,0 +1,33 @@ +import * as React from 'react'; + +import { usePopups } from '@/entities/popups'; + +import { BasePopupProps, CommonProps } from '@/shared/types'; + +export interface PopupsProps extends CommonProps { + readonly popupMap: Record<string, React.ComponentType<BasePopupProps>>; +} + +export const Popups: React.FC<PopupsProps> = (props) => { + const { popupMap, className, } = props; + const { mountedPopups, popups, } = usePopups(); + return ( + <> + {mountedPopups.map((popup) => { + const Component = popupMap[popup]; + + if (!Component) { + return null; + } + + return ( + <Component + className={className} + isOpen={popups.includes(popup)} + key={popup} + /> + ); + })} + </> + ); +}; diff --git a/src/widgets/rooms/index.ts b/src/widgets/rooms/index.ts new file mode 100644 index 00000000..5ecdd1f3 --- /dev/null +++ b/src/widgets/rooms/index.ts @@ -0,0 +1 @@ +export * from './ui'; diff --git a/src/widgets/rooms/ui/index.ts b/src/widgets/rooms/ui/index.ts new file mode 100644 index 00000000..d4bb348e --- /dev/null +++ b/src/widgets/rooms/ui/index.ts @@ -0,0 +1,3 @@ +export * from './room-card'; +export * from './room-list'; +export * from './room-layout'; diff --git a/src/widgets/rooms/ui/room-card/index.ts b/src/widgets/rooms/ui/room-card/index.ts new file mode 100644 index 00000000..38bd5527 --- /dev/null +++ b/src/widgets/rooms/ui/room-card/index.ts @@ -0,0 +1 @@ +export { RoomCard, type RoomCardProps } from './room-card'; diff --git a/src/widgets/rooms/ui/room-card/room-card.tsx b/src/widgets/rooms/ui/room-card/room-card.tsx new file mode 100644 index 00000000..d7b57829 --- /dev/null +++ b/src/widgets/rooms/ui/room-card/room-card.tsx @@ -0,0 +1,39 @@ +import * as React from 'react'; + +import { + OpenRoom, + OpenUpdateRoomFormMenuItem, + RemoveRoomMenuItem +} from '@/features/rooms'; +import { ExitRoomUserMenuItem } from '@/features/users'; + +import { TemplateRoomCard } from '@/entities/rooms'; + +import { Room } from '@/shared/api'; +import { CommonProps } from '@/shared/types'; +import { EditMenu } from '@/shared/ui'; + +export interface RoomCardProps extends CommonProps, Room {} + +export const RoomCard: React.FC<RoomCardProps> = (props) => { + const { id, canChange, } = props; + return ( + <TemplateRoomCard + {...props} + menu={canChange ? <CardMenu roomId={id} /> : null} + actions={<OpenRoom id={id} />} + /> + ); +}; + +const CardMenu: React.FC<{ roomId: number }> = (props) => { + const { roomId, } = props; + + return ( + <EditMenu> + <OpenUpdateRoomFormMenuItem roomId={roomId} /> + <ExitRoomUserMenuItem roomId={roomId} /> + <RemoveRoomMenuItem roomId={roomId} /> + </EditMenu> + ); +}; diff --git a/src/widgets/rooms/ui/room-header/index.ts b/src/widgets/rooms/ui/room-header/index.ts new file mode 100644 index 00000000..aa36c3b5 --- /dev/null +++ b/src/widgets/rooms/ui/room-header/index.ts @@ -0,0 +1 @@ +export { RoomHeader } from './room-header'; diff --git a/src/widgets/rooms/ui/room-header/room-header.module.css b/src/widgets/rooms/ui/room-header/room-header.module.css new file mode 100644 index 00000000..0c34f0ea --- /dev/null +++ b/src/widgets/rooms/ui/room-header/room-header.module.css @@ -0,0 +1,18 @@ +.header { + display: grid; + grid-template-columns: 1fr max-content; + column-gap: 1em; + align-items: center; + + padding: 2rem 0; +} + +.titleSkeleton { + margin-bottom: 0.2em; +} + +.description { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} diff --git a/src/widgets/rooms/ui/room-header/room-header.module.css.d.ts b/src/widgets/rooms/ui/room-header/room-header.module.css.d.ts new file mode 100644 index 00000000..8ae8e86d --- /dev/null +++ b/src/widgets/rooms/ui/room-header/room-header.module.css.d.ts @@ -0,0 +1,6 @@ +declare const styles: { + readonly description: string; + readonly header: string; + readonly titleSkeleton: string; +}; +export = styles; diff --git a/src/widgets/rooms/ui/room-header/room-header.tsx b/src/widgets/rooms/ui/room-header/room-header.tsx new file mode 100644 index 00000000..b2c7ef3e --- /dev/null +++ b/src/widgets/rooms/ui/room-header/room-header.tsx @@ -0,0 +1,44 @@ +import { Skeleton, Typography } from '@mui/material'; +import cn from 'classnames'; +import * as React from 'react'; + +import { MainHeader } from '@/widgets/page'; + +import { useRoom } from '@/entities/rooms'; + +import { routes } from '@/shared/configs'; +import { useParam } from '@/shared/lib'; +import { CommonProps } from '@/shared/types'; + +import { Tabs } from '../tabs'; + +import styles from './room-header.module.css'; + +export const RoomHeader: React.FC<CommonProps> = (props) => { + const { className, } = props; + const id = useParam(routes.room.base, 'id'); + const { data: room, pending, } = useRoom(id); + + return ( + <MainHeader + className={cn(className)} + slots={{ + left: ( + <div> + <Typography variant='h6' component='h1'> + {pending ? ( + <Skeleton className={styles.titleSkeleton} width='10em' /> + ) : ( + room?.name + )} + </Typography> + <Typography className={styles.description} variant='body2'> + {pending ? <Skeleton width='10em' /> : room?.description} + </Typography> + </div> + ), + center: <Tabs />, + }} + /> + ); +}; diff --git a/src/widgets/rooms/ui/room-layout/index.ts b/src/widgets/rooms/ui/room-layout/index.ts new file mode 100644 index 00000000..2b799948 --- /dev/null +++ b/src/widgets/rooms/ui/room-layout/index.ts @@ -0,0 +1 @@ +export { RoomLayout, type RoomLayoutProps } from './ui'; diff --git a/src/widgets/rooms/ui/room-layout/ui.module.css b/src/widgets/rooms/ui/room-layout/ui.module.css new file mode 100644 index 00000000..7c8df36a --- /dev/null +++ b/src/widgets/rooms/ui/room-layout/ui.module.css @@ -0,0 +1,5 @@ +.layout { + justify-self: center; + + width: 100%; +} diff --git a/src/widgets/rooms/ui/room-layout/ui.module.css.d.ts b/src/widgets/rooms/ui/room-layout/ui.module.css.d.ts new file mode 100644 index 00000000..2ee60697 --- /dev/null +++ b/src/widgets/rooms/ui/room-layout/ui.module.css.d.ts @@ -0,0 +1,4 @@ +declare const styles: { + readonly layout: string; +}; +export = styles; diff --git a/src/widgets/rooms/ui/room-layout/ui.tsx b/src/widgets/rooms/ui/room-layout/ui.tsx new file mode 100644 index 00000000..c0b43ddc --- /dev/null +++ b/src/widgets/rooms/ui/room-layout/ui.tsx @@ -0,0 +1,25 @@ +import cn from 'classnames'; +import * as React from 'react'; + +import { CommonProps } from '@/shared/types'; +import { Layout, PageLoader } from '@/shared/ui'; + +import { RoomHeader } from '../room-header'; + +import styles from './ui.module.css'; + +export interface RoomLayoutProps extends CommonProps, React.PropsWithChildren {} + +export const RoomLayout: React.FC<RoomLayoutProps> = (props) => { + const { className, children, } = props; + + return ( + <Layout + className={cn(styles.layout, className)} + slots={{ + header: <RoomHeader />, + }}> + <React.Suspense fallback={<PageLoader />}>{children}</React.Suspense> + </Layout> + ); +}; diff --git a/src/widgets/rooms/ui/room-list/index.ts b/src/widgets/rooms/ui/room-list/index.ts new file mode 100644 index 00000000..7a2121ff --- /dev/null +++ b/src/widgets/rooms/ui/room-list/index.ts @@ -0,0 +1 @@ +export { RoomList } from './room-list'; diff --git a/src/widgets/rooms/ui/room-list/room-list.module.css b/src/widgets/rooms/ui/room-list/room-list.module.css new file mode 100644 index 00000000..1f43e34e --- /dev/null +++ b/src/widgets/rooms/ui/room-list/room-list.module.css @@ -0,0 +1,5 @@ +.list { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(min(320px, 100%), 1fr)); + gap: 1em; +} diff --git a/src/widgets/rooms/ui/room-list/room-list.module.css.d.ts b/src/widgets/rooms/ui/room-list/room-list.module.css.d.ts new file mode 100644 index 00000000..5d09dcfe --- /dev/null +++ b/src/widgets/rooms/ui/room-list/room-list.module.css.d.ts @@ -0,0 +1,4 @@ +declare const styles: { + readonly list: string; +}; +export = styles; diff --git a/src/widgets/rooms/ui/room-list/room-list.tsx b/src/widgets/rooms/ui/room-list/room-list.tsx new file mode 100644 index 00000000..6fe9cd52 --- /dev/null +++ b/src/widgets/rooms/ui/room-list/room-list.tsx @@ -0,0 +1,31 @@ +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { SkeletonRoomCard, roomsModel } from '@/entities/rooms'; + +import { FriendlyList } from '@/shared/ui'; + +import { RoomCard } from '../room-card'; + +import styles from './room-list.module.css'; + +export const RoomList: React.FC = () => { + const { t, } = useTranslation('rooms'); + const emptyText = t('rooms_list.empty_text'); + + return ( + <FriendlyList + $query={roomsModel.query} + getKey={(item) => item.id} + ItemComponent={RoomCard} + SkeletonComponent={SkeletonRoomCard} + skeletonsCount={15} + ErrorComponent={() => null} + emptyText={emptyText} + classes={{ + list: styles.list, + }} + disableBorder + /> + ); +}; diff --git a/src/widgets/rooms/ui/tabs/index.ts b/src/widgets/rooms/ui/tabs/index.ts new file mode 100644 index 00000000..81aabb71 --- /dev/null +++ b/src/widgets/rooms/ui/tabs/index.ts @@ -0,0 +1 @@ +export { Tabs } from './tabs'; diff --git a/src/widgets/rooms/ui/tabs/tabs.tsx b/src/widgets/rooms/ui/tabs/tabs.tsx new file mode 100644 index 00000000..09fd9850 --- /dev/null +++ b/src/widgets/rooms/ui/tabs/tabs.tsx @@ -0,0 +1,73 @@ +import AssessmentIcon from '@mui/icons-material/Assessment'; +import LabelIcon from '@mui/icons-material/Label'; +import ListAltIcon from '@mui/icons-material/ListAlt'; +import PeopleIcon from '@mui/icons-material/People'; +import { TabContext, TabList } from '@mui/lab'; +import { Tab } from '@mui/material'; +import { useUnit } from 'effector-react'; +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { routes } from '@/shared/configs'; +import { useParam } from '@/shared/lib'; +import { deviceInfoModel } from '@/shared/models'; +import { CommonProps } from '@/shared/types'; + +export const Tabs: React.FC<CommonProps> = React.memo(() => { + const { t, } = useTranslation('room'); + const tab = useParam(routes.room.base, 'tab') || 'tasks'; + const id = useParam(routes.room.base, 'id'); + + const tabs = t('tabs', { returnObjects: true, }) as Record<string, string>; + + const [isVertical, isMobile] = useUnit([ + deviceInfoModel.$isTabletVertical, + deviceInfoModel.$isMobile + ]); + + const showLabels = !isVertical && !isMobile; + + const onChange = React.useCallback( + (_evt: unknown, value: string) => { + routes.room.base.navigate({ + params: { + id, + tab: value, + }, + query: {}, + }); + }, + [id] + ); + + return ( + <TabContext value={tab}> + <TabList onChange={onChange} variant='scrollable' scrollButtons='auto'> + <Tab + icon={<ListAltIcon />} + iconPosition='start' + label={showLabels ? tabs.tasks : null} + value='tasks' + /> + <Tab + icon={<LabelIcon />} + iconPosition='start' + label={showLabels ? tabs.tags : null} + value='tags' + /> + <Tab + icon={<AssessmentIcon />} + iconPosition='start' + label={showLabels ? tabs.activities : null} + value='activities' + /> + <Tab + icon={<PeopleIcon />} + iconPosition='start' + label={showLabels ? tabs.users : null} + value='users' + /> + </TabList> + </TabContext> + ); +}); diff --git a/src/widgets/tags/index.ts b/src/widgets/tags/index.ts new file mode 100644 index 00000000..5ecdd1f3 --- /dev/null +++ b/src/widgets/tags/index.ts @@ -0,0 +1 @@ +export * from './ui'; diff --git a/src/widgets/tags/ui/index.ts b/src/widgets/tags/ui/index.ts new file mode 100644 index 00000000..45ade1d4 --- /dev/null +++ b/src/widgets/tags/ui/index.ts @@ -0,0 +1 @@ +export * from './tag-list-item'; diff --git a/src/widgets/tags/ui/tag-list-item/index.ts b/src/widgets/tags/ui/tag-list-item/index.ts new file mode 100644 index 00000000..0989288e --- /dev/null +++ b/src/widgets/tags/ui/tag-list-item/index.ts @@ -0,0 +1 @@ +export { TagListItem, type TagListItemProps } from './tag-list-item'; diff --git a/src/widgets/tags/ui/tag-list-item/tag-list-item.tsx b/src/widgets/tags/ui/tag-list-item/tag-list-item.tsx new file mode 100644 index 00000000..8a1b17b4 --- /dev/null +++ b/src/widgets/tags/ui/tag-list-item/tag-list-item.tsx @@ -0,0 +1,27 @@ +import { ListItemProps } from '@mui/material'; +import * as React from 'react'; + +import { TagCardActions } from '@/features/tags'; + +import { TemplateTagListItem } from '@/entities/tags'; + +import { Tag } from '@/shared/api'; +import { CommonProps } from '@/shared/types'; + + +export interface TagListItemProps + extends CommonProps, + Tag, + Omit<ListItemProps, keyof Tag> {} + +export const TagListItem: React.FC<TagListItemProps> = (props) => { + const { id, } = props; + return ( + <TemplateTagListItem + {...props} + slots={{ + actions: <TagCardActions tagId={id} />, + }} + /> + ); +}; diff --git a/src/widgets/tasks/index.ts b/src/widgets/tasks/index.ts new file mode 100644 index 00000000..80b33de4 --- /dev/null +++ b/src/widgets/tasks/index.ts @@ -0,0 +1,2 @@ +export * from './model'; +export * from './ui'; diff --git a/src/widgets/tasks/lib/index.ts b/src/widgets/tasks/lib/index.ts new file mode 100644 index 00000000..63c4915c --- /dev/null +++ b/src/widgets/tasks/lib/index.ts @@ -0,0 +1 @@ +export * from './use-task-card-is-drag'; diff --git a/src/widgets/tasks/lib/use-task-card-is-drag.ts b/src/widgets/tasks/lib/use-task-card-is-drag.ts new file mode 100644 index 00000000..8d733116 --- /dev/null +++ b/src/widgets/tasks/lib/use-task-card-is-drag.ts @@ -0,0 +1,14 @@ +import { useStoreMap } from 'effector-react'; + +import { dragTaskModel } from '../model'; + +export const useTaskCardIsDrag = (id: number): boolean => { + return useStoreMap({ + store: dragTaskModel.$id, + keys: [id], + defaultValue: false, + fn: (draggingId, [id]) => { + return draggingId === id; + }, + }); +}; diff --git a/src/widgets/tasks/model/drag.ts b/src/widgets/tasks/model/drag.ts new file mode 100644 index 00000000..d839ceb0 --- /dev/null +++ b/src/widgets/tasks/model/drag.ts @@ -0,0 +1,51 @@ +import { createDomain, sample } from 'effector'; +import { DragEvent } from 'react'; + +import { TaskStatus } from '@/shared/api'; + +const dragTaskDomain = createDomain(); + +export const $id = dragTaskDomain.store<number | null>(null); +export const $startColumn = dragTaskDomain.store<TaskStatus | null>(null); + +export const dragStarted = dragTaskDomain.event<DragEvent<HTMLDivElement>>(); +export const dragEnded = dragTaskDomain.event<DragEvent<HTMLDivElement>>(); +export const drop = dragTaskDomain.event<DragEvent<HTMLDivElement>>(); +export const dropped = dragTaskDomain.event<DragEvent<HTMLDivElement>>(); + +sample({ + clock: dragStarted, + fn: (evt) => { + const id = Number(evt.currentTarget.dataset.id); + return Number.isNaN(id) ? null : id; + }, + target: $id, +}); + +sample({ + clock: dragStarted, + fn: (evt) => { + return (evt.currentTarget.dataset.status as TaskStatus) ?? null; + }, + target: $startColumn, +}); + +sample({ + clock: drop, + source: { + id: $id, + startColumn: $startColumn, + }, + filter: ({ id, startColumn, }, evt) => { + const { status, } = evt.currentTarget.dataset; + return id !== null && startColumn !== status && !!status; + }, + fn: (_, evt) => evt, + target: dropped, +}); + +sample({ + clock: dragEnded, + fn: () => null, + target: [$id, $startColumn], +}); diff --git a/src/widgets/tasks/model/index.ts b/src/widgets/tasks/model/index.ts new file mode 100644 index 00000000..e8d1fddc --- /dev/null +++ b/src/widgets/tasks/model/index.ts @@ -0,0 +1 @@ +export * as dragTaskModel from './drag'; diff --git a/src/widgets/tasks/ui/index.ts b/src/widgets/tasks/ui/index.ts new file mode 100644 index 00000000..d930c052 --- /dev/null +++ b/src/widgets/tasks/ui/index.ts @@ -0,0 +1,2 @@ +export * from './task-column'; +export * from './task-card'; diff --git a/src/widgets/tasks/ui/task-card/index.ts b/src/widgets/tasks/ui/task-card/index.ts new file mode 100644 index 00000000..780f34b7 --- /dev/null +++ b/src/widgets/tasks/ui/task-card/index.ts @@ -0,0 +1 @@ +export { TaskCard, type TaskCardProps } from './task-card'; diff --git a/src/widgets/tasks/ui/task-card/task-card.module.css b/src/widgets/tasks/ui/task-card/task-card.module.css new file mode 100644 index 00000000..f550bc69 --- /dev/null +++ b/src/widgets/tasks/ui/task-card/task-card.module.css @@ -0,0 +1,13 @@ +.card { + cursor: pointer; +} + +.tags { + display: flex; + flex-wrap: wrap; + gap: 0.5em; +} + +.drag { + opacity: 0.1; +} diff --git a/src/widgets/tasks/ui/task-card/task-card.module.css.d.ts b/src/widgets/tasks/ui/task-card/task-card.module.css.d.ts new file mode 100644 index 00000000..c68dbaa6 --- /dev/null +++ b/src/widgets/tasks/ui/task-card/task-card.module.css.d.ts @@ -0,0 +1,6 @@ +declare const styles: { + readonly card: string; + readonly drag: string; + readonly tags: string; +}; +export = styles; diff --git a/src/widgets/tasks/ui/task-card/task-card.tsx b/src/widgets/tasks/ui/task-card/task-card.tsx new file mode 100644 index 00000000..ac853cdf --- /dev/null +++ b/src/widgets/tasks/ui/task-card/task-card.tsx @@ -0,0 +1,74 @@ +import cn from 'classnames'; +import { useUnit } from 'effector-react'; +import * as React from 'react'; + +import { + OpenUpdateTaskFormMenuItem, + RemoveTaskMenuItem +} from '@/features/tasks'; + +import { TagLabel, SkeletonTagLabel } from '@/entities/tags'; +import { TemplateTaskCard } from '@/entities/tasks'; +import { UserAvatar } from '@/entities/users'; + +import { Task } from '@/shared/api'; +import { getEmptyArray } from '@/shared/configs'; +import { CommonProps } from '@/shared/types'; +import { EditMenu } from '@/shared/ui'; + +import { useTaskCardIsDrag } from '../../lib'; +import { dragTaskModel } from '../../model'; + +import styles from './task-card.module.css'; + +export interface TaskCardProps extends CommonProps, Task {} + +export const TaskCard: React.FC<TaskCardProps> = React.memo((props) => { + const { tags, id, roomId, className, status, author, ...rest } = props; + const [onDragEnd, onDragStart] = useUnit([ + dragTaskModel.dragEnded, + dragTaskModel.dragStarted + ]); + const isDrag = useTaskCardIsDrag(id); + + const actions = <CardMenu roomId={roomId} taskId={id} />; + const tagElements = + tags.length > 0 + ? tags.map((tag) => <TagLabel {...tag} key={tag.id} />) + : getEmptyArray(2).map((_, i) => <SkeletonTagLabel key={i} />); + + const userAvatar = <UserAvatar {...author} size={24} />; + + return ( + <TemplateTaskCard + className={cn(styles.card, { [styles.drag]: isDrag, }, className)} + {...rest} + slots={{ + actions, + userAvatar, + tags: <div className={styles.tags}>{tagElements}</div>, + }} + id={id} + status={status} + onDragStart={onDragStart} + onDragEnd={onDragEnd} + data-id={id} + data-status={status} + draggable + /> + ); +}); + +interface CardMenuProps { + readonly taskId: number; + readonly roomId: number; +} + +const CardMenu: React.FC<CardMenuProps> = (props) => { + return ( + <EditMenu> + <OpenUpdateTaskFormMenuItem {...props} /> + <RemoveTaskMenuItem {...props} /> + </EditMenu> + ); +}; diff --git a/src/widgets/tasks/ui/task-column/index.ts b/src/widgets/tasks/ui/task-column/index.ts new file mode 100644 index 00000000..72ec60b7 --- /dev/null +++ b/src/widgets/tasks/ui/task-column/index.ts @@ -0,0 +1 @@ +export { TaskColumn, type TaskColumnProps } from './task-column'; diff --git a/src/components/Tasks/components/TaskList/TaskList.module.css b/src/widgets/tasks/ui/task-column/task-column.module.css similarity index 100% rename from src/components/Tasks/components/TaskList/TaskList.module.css rename to src/widgets/tasks/ui/task-column/task-column.module.css diff --git a/src/widgets/tasks/ui/task-column/task-column.module.css.d.ts b/src/widgets/tasks/ui/task-column/task-column.module.css.d.ts new file mode 100644 index 00000000..995563e1 --- /dev/null +++ b/src/widgets/tasks/ui/task-column/task-column.module.css.d.ts @@ -0,0 +1,6 @@ +declare const styles: { + readonly innerWrapper: string; + readonly list: string; + readonly wrapper: string; +}; +export = styles; diff --git a/src/widgets/tasks/ui/task-column/task-column.tsx b/src/widgets/tasks/ui/task-column/task-column.tsx new file mode 100644 index 00000000..153c24f9 --- /dev/null +++ b/src/widgets/tasks/ui/task-column/task-column.tsx @@ -0,0 +1,71 @@ +import { Stack } from '@mui/material'; +import cn from 'classnames'; +import { useUnit } from 'effector-react'; +import * as React from 'react'; + +import { OpenCreateTaskButton } from '@/features/tasks'; + +import { SkeletonTaskCard, TaskColumnHeader } from '@/entities/tasks'; + +import { Task, TaskStatus } from '@/shared/api'; +import { getEmptyArray } from '@/shared/configs'; +import { CommonProps } from '@/shared/types'; + +import { dragTaskModel } from '../../model'; +import { TaskCard } from '../task-card'; + +import styles from './task-column.module.css'; + +export interface TaskColumnProps extends CommonProps { + readonly tasks: Task[]; + readonly roomId: number; + readonly isLoading: boolean; + readonly columnStatus: TaskStatus; + readonly hasActions?: boolean; + readonly header?: string | null; +} +const onDragOver: React.DragEventHandler<HTMLDivElement> = (evt) => + evt.preventDefault(); + +export const TaskColumn: React.FC<TaskColumnProps> = (props) => { + const { + tasks, + className, + columnStatus, + hasActions, + header, + isLoading, + roomId, + } = props; + const onDrop = useUnit(dragTaskModel.drop); + + let items: React.ReactElement[]; + + if (isLoading) { + items = getEmptyArray(4).map((_, i) => <SkeletonTaskCard key={i} />); + } else { + items = tasks.map((task) => { + return <TaskCard {...task} key={task.id} />; + }); + } + + const headerActions = hasActions ? ( + <OpenCreateTaskButton roomId={roomId} columnStatus={columnStatus} /> + ) : null; + + return ( + <Stack + className={cn(styles.wrapper, className)} + spacing={1} + onDrop={onDrop} + onDragOver={onDragOver} + data-status={columnStatus}> + <TaskColumnHeader slots={{ actions: headerActions, }}> + {header} + </TaskColumnHeader> + <Stack className={styles.list} spacing={1} component='main'> + {items} + </Stack> + </Stack> + ); +}; diff --git a/src/widgets/users/index.ts b/src/widgets/users/index.ts new file mode 100644 index 00000000..5ecdd1f3 --- /dev/null +++ b/src/widgets/users/index.ts @@ -0,0 +1 @@ +export * from './ui'; diff --git a/src/widgets/users/ui/index.ts b/src/widgets/users/ui/index.ts new file mode 100644 index 00000000..6f2f6777 --- /dev/null +++ b/src/widgets/users/ui/index.ts @@ -0,0 +1 @@ +export * from './user-in-room-list-item'; diff --git a/src/widgets/users/ui/user-in-room-list-item/index.ts b/src/widgets/users/ui/user-in-room-list-item/index.ts new file mode 100644 index 00000000..96379ff0 --- /dev/null +++ b/src/widgets/users/ui/user-in-room-list-item/index.ts @@ -0,0 +1 @@ +export { UserInRoomListItem, type UserInRoomListItemProps } from './ui'; diff --git a/src/widgets/users/ui/user-in-room-list-item/ui.tsx b/src/widgets/users/ui/user-in-room-list-item/ui.tsx new file mode 100644 index 00000000..dd93ebbd --- /dev/null +++ b/src/widgets/users/ui/user-in-room-list-item/ui.tsx @@ -0,0 +1,50 @@ +import { useUnit } from 'effector-react'; +import * as React from 'react'; + +import { ExitRoomUserButton, RemoveUserFromRoom } from '@/features/users'; + +import { roomModel } from '@/entities/rooms'; +import { + TemplateUserListItem, + TemplateUserListItemProps +} from '@/entities/users'; + +import { sessionModel } from '@/shared/models'; +import { CommonProps } from '@/shared/types'; + +export interface UserInRoomListItemProps + extends CommonProps, + Omit<TemplateUserListItemProps, 'slots'> { + readonly roomId: number; +} + +export const UserInRoomListItem: React.FC<UserInRoomListItemProps> = ( + props +) => { + const { id, roomId, ...rest } = props; + + const authUser = useUnit(sessionModel.$user); + const room = useUnit(roomModel.query.$data); + + const isOwnerAuthorized = authUser?.id === room?.ownerId; + const isOwner = id === room?.ownerId; + + const isAuthorized = authUser?.id === id; + + const exitButton = + isAuthorized && !isOwner ? <ExitRoomUserButton roomId={roomId} /> : null; + + const removeUserButton = + isOwnerAuthorized && !isOwner ? ( + <RemoveUserFromRoom userId={id} roomId={roomId} /> + ) : null; + + const actions = ( + <> + {exitButton} + {removeUserButton} + </> + ); + + return <TemplateUserListItem id={id} {...rest} slots={{ actions, }} />; +}; diff --git a/tsconfig.json b/tsconfig.json index 81d7e25a..a2e6031f 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -20,6 +20,6 @@ "@/*": ["*"] } }, - "include": ["src", "templates"], + "include": ["src"], "references": [{ "path": "./tsconfig.node.json" }] } diff --git a/vite.config.ts b/vite.config.ts index e34cca1d..241ebf2e 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,16 +1,23 @@ /* eslint-disable import/no-extraneous-dependencies */ -import { defineConfig, splitVendorChunkPlugin } from 'vite'; -import react from '@vitejs/plugin-react'; -import { babel } from '@rollup/plugin-babel'; import * as path from 'path'; -// https://vitejs.dev/config/ +import { babel } from '@rollup/plugin-babel'; +import react from '@vitejs/plugin-react'; +import { defineConfig, splitVendorChunkPlugin } from 'vite'; +import { viteStaticCopy } from 'vite-plugin-static-copy'; + +const LOCALE_FILE_REGEXP = /src\/([\w-/ ])*\/([\w-]+)\/([\w-]+)\.json$/; + export default defineConfig({ server: { port: 3000, cors: true, - open: true, - hmr: true, + proxy: { + '/api': { + changeOrigin: true, + target: 'http://localhost:5000', + }, + }, }, resolve: { alias: { @@ -29,6 +36,25 @@ export default defineConfig({ browserslistConfigFile: true, extensions: ['.ts', '.tsx'], }), - splitVendorChunkPlugin() + splitVendorChunkPlugin(), + viteStaticCopy({ + targets: [ + { + src: 'src/**/locales/**/*.json', + rename: (_name, _extension, path) => { + const matches = path.match(LOCALE_FILE_REGEXP); + + if (matches.length < 4) { + return ''; + } + + const [, , language, namespace] = matches; + + return `${language}/${namespace}.json`; + }, + dest: 'locales', + } + ], + }) ], });