diff --git a/changelog-dev.hbs b/changelog-dev.hbs index 4a39542c0..15469d6cd 100644 --- a/changelog-dev.hbs +++ b/changelog-dev.hbs @@ -1,12 +1,15 @@ From newest to oldest: {{#each releases}} {{#each merges}} - - {{message}}{{#if href}} [#{{id}}]({{href}}){{/if}} + - + {{message}}{{#if href}} [#{{id}}]({{href}}){{/if}} {{/each}} {{#each fixes}} - - {{commit.subject}}{{#if href}} [#{{id}}]({{href}}){{/if}} + - + {{commit.subject}}{{#if href}} [#{{id}}]({{href}}){{/if}} {{/each}} {{#each commits}} - - {{subject}}{{#if href}} [{{shorthash}}]({{href}}){{/if}} + - + {{subject}}{{#if href}} [{{shorthash}}]({{href}}){{/if}} {{/each}} -{{/each}} +{{/each}} \ No newline at end of file diff --git a/changelog-master.hbs b/changelog-master.hbs index 4a39542c0..15469d6cd 100644 --- a/changelog-master.hbs +++ b/changelog-master.hbs @@ -1,12 +1,15 @@ From newest to oldest: {{#each releases}} {{#each merges}} - - {{message}}{{#if href}} [#{{id}}]({{href}}){{/if}} + - + {{message}}{{#if href}} [#{{id}}]({{href}}){{/if}} {{/each}} {{#each fixes}} - - {{commit.subject}}{{#if href}} [#{{id}}]({{href}}){{/if}} + - + {{commit.subject}}{{#if href}} [#{{id}}]({{href}}){{/if}} {{/each}} {{#each commits}} - - {{subject}}{{#if href}} [{{shorthash}}]({{href}}){{/if}} + - + {{subject}}{{#if href}} [{{shorthash}}]({{href}}){{/if}} {{/each}} -{{/each}} +{{/each}} \ No newline at end of file diff --git a/frontend/.gitignore b/frontend/.gitignore index 1da13b089..28212c025 100644 --- a/frontend/.gitignore +++ b/frontend/.gitignore @@ -2,5 +2,6 @@ node_modules dist *.local build +coverage *.tsbuildinfo diff --git a/frontend/config/chunks.ts b/frontend/config/chunks.ts index 1d992f5a2..c5c5f7fba 100644 --- a/frontend/config/chunks.ts +++ b/frontend/config/chunks.ts @@ -2,7 +2,6 @@ import { dependencies } from "../package.json"; const vendors = [ "react", - "react-redux", "react-router-dom", "react-dom", "react-query", diff --git a/frontend/index.html b/frontend/index.html index 9bfe7e734..a416f01cd 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -18,7 +18,9 @@
diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 911e4db0c..6afd5c631 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -9,12 +9,12 @@ "version": "1.0.0", "license": "GPL-3", "dependencies": { + "@mantine/core": "^4", + "@mantine/hooks": "^4", "axios": "^0.26", "react": "^17", - "react-bootstrap": "^1", "react-dom": "^17", "react-query": "^3.34", - "react-redux": "^7.2", "react-router-dom": "^6.2.1", "socket.io-client": "^4" }, @@ -25,37 +25,32 @@ "@fortawesome/free-regular-svg-icons": "^6", "@fortawesome/free-solid-svg-icons": "^6", "@fortawesome/react-fontawesome": "^0.1", - "@reduxjs/toolkit": "^1", + "@mantine/dropzone": "^4", + "@mantine/modals": "^4", + "@mantine/notifications": "^4", "@testing-library/jest-dom": "latest", "@testing-library/react": "12", "@testing-library/react-hooks": "latest", "@testing-library/user-event": "latest", - "@types/bootstrap": "^4", "@types/lodash": "^4", "@types/node": "^17", "@types/react": "^17", "@types/react-dom": "^17", - "@types/react-helmet": "^6.1", "@types/react-table": "^7", "@vitejs/plugin-react": "^1.3", - "bootstrap": "^4", - "clsx": "^1.1.1", + "clsx": "^1", "eslint": "^8", - "eslint-config-react-app": "^7.0.0", + "eslint-config-react-app": "^7", "eslint-plugin-react-hooks": "^4", - "husky": "^7", + "husky": "^8", "jsdom": "latest", "lodash": "^4", "moment": "^2.29.1", "prettier": "^2", "prettier-plugin-organize-imports": "^2", "pretty-quick": "^3.1", - "rc-slider": "^9.7", - "react-helmet": "^6.1", - "react-select": "^5.0.1", "react-table": "^7", "recharts": "^2.0.8", - "rooks": "^5", "sass": "^1", "typescript": "^4", "vite": "latest", @@ -64,12 +59,13 @@ } }, "node_modules/@ampproject/remapping": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.1.2.tgz", - "integrity": "sha512-hoyByceqwKirw7w3Z7gnIIZC3Wx3J484Y3L/cMpXFbr7d9ZQj2mODrirNzcJa+SM3UlpWXYvKV4RlRpFXlWgXg==", - "dev": true, + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", + "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", + "devOptional": true, "dependencies": { - "@jridgewell/trace-mapping": "^0.3.0" + "@jridgewell/gen-mapping": "^0.1.0", + "@jridgewell/trace-mapping": "^0.3.9" }, "engines": { "node": ">=6.0.0" @@ -79,7 +75,7 @@ "version": "7.16.7", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", - "dev": true, + "devOptional": true, "dependencies": { "@babel/highlight": "^7.16.7" }, @@ -88,34 +84,34 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.17.7", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.17.7.tgz", - "integrity": "sha512-p8pdE6j0a29TNGebNm7NzYZWB3xVZJBZ7XGs42uAKzQo8VQ3F0By/cQCtUEABwIqw5zo6WA4NbmxsfzADzMKnQ==", - "dev": true, + "version": "7.17.10", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.17.10.tgz", + "integrity": "sha512-GZt/TCsG70Ms19gfZO1tM4CVnXsPgEPBCpJu+Qz3L0LUDsY5nZqFZglIoPC1kIYOtNBZlrnFT+klg12vFGZXrw==", + "devOptional": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.17.8", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.17.8.tgz", - "integrity": "sha512-OdQDV/7cRBtJHLSOBqqbYNkOcydOgnX59TZx4puf41fzcVtN3e/4yqY8lMQsK+5X2lJtAdmA+6OHqsj1hBJ4IQ==", - "dev": true, + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.18.2.tgz", + "integrity": "sha512-A8pri1YJiC5UnkdrWcmfZTJTV85b4UXTAfImGmCfYmax4TR9Cw8sDS0MOk++Gp2mE/BefVJ5nwy5yzqNJbP/DQ==", + "devOptional": true, "dependencies": { "@ampproject/remapping": "^2.1.0", "@babel/code-frame": "^7.16.7", - "@babel/generator": "^7.17.7", - "@babel/helper-compilation-targets": "^7.17.7", - "@babel/helper-module-transforms": "^7.17.7", - "@babel/helpers": "^7.17.8", - "@babel/parser": "^7.17.8", + "@babel/generator": "^7.18.2", + "@babel/helper-compilation-targets": "^7.18.2", + "@babel/helper-module-transforms": "^7.18.0", + "@babel/helpers": "^7.18.2", + "@babel/parser": "^7.18.0", "@babel/template": "^7.16.7", - "@babel/traverse": "^7.17.3", - "@babel/types": "^7.17.0", + "@babel/traverse": "^7.18.2", + "@babel/types": "^7.18.2", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", - "json5": "^2.1.2", + "json5": "^2.2.1", "semver": "^6.3.0" }, "engines": { @@ -127,9 +123,9 @@ } }, "node_modules/@babel/eslint-parser": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.17.0.tgz", - "integrity": "sha512-PUEJ7ZBXbRkbq3qqM/jZ2nIuakUBqCYc7Qf52Lj7dlZ6zERnqisdHioL0l4wwQZnmskMeasqUNzLBFKs3nylXA==", + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.18.2.tgz", + "integrity": "sha512-oFQYkE8SuH14+uR51JVAmdqwKYXGRjEXx7s+WiagVjqQ+HPE+nnwyF2qlVG8evUsUHmPcA+6YXMEDbIhEyQc5A==", "dev": true, "dependencies": { "eslint-scope": "^5.1.1", @@ -176,19 +172,33 @@ } }, "node_modules/@babel/generator": { - "version": "7.17.7", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.17.7.tgz", - "integrity": "sha512-oLcVCTeIFadUoArDTwpluncplrYBmTCCZZgXCbgNGvOBBiSDDK3eWO4b/+eOTli5tKv1lg+a5/NAXg+nTcei1w==", - "dev": true, + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.18.2.tgz", + "integrity": "sha512-W1lG5vUwFvfMd8HVXqdfbuG7RuaSrTCCD8cl8fP8wOivdbtbIg2Db3IWUcgvfxKbbn6ZBGYRW/Zk1MIwK49mgw==", + "devOptional": true, "dependencies": { - "@babel/types": "^7.17.0", - "jsesc": "^2.5.1", - "source-map": "^0.5.0" + "@babel/types": "^7.18.2", + "@jridgewell/gen-mapping": "^0.3.0", + "jsesc": "^2.5.1" }, "engines": { "node": ">=6.9.0" } }, + "node_modules/@babel/generator/node_modules/@jridgewell/gen-mapping": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.1.tgz", + "integrity": "sha512-GcHwniMlA2z+WFPWuY8lp3fsza0I8xPFMWL5+n8LYyP6PSvPrXf4+n8stDHZY2DM0zy9sVkRDy1jDI4XGzYVqg==", + "devOptional": true, + "dependencies": { + "@jridgewell/set-array": "^1.0.0", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/@babel/helper-annotate-as-pure": { "version": "7.16.7", "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.7.tgz", @@ -215,14 +225,14 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.17.7", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.17.7.tgz", - "integrity": "sha512-UFzlz2jjd8kroj0hmCFV5zr+tQPi1dpC2cRsDV/3IEW8bJfCPrPpmcSN6ZS8RqIq4LXcmpipCQFPddyFA5Yc7w==", - "dev": true, + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.18.2.tgz", + "integrity": "sha512-s1jnPotJS9uQnzFtiZVBUxe67CuBa679oWFHpxYYnTpRL/1ffhyX44R9uYiXoa/pLXcY9H2moJta0iaanlk/rQ==", + "devOptional": true, "dependencies": { - "@babel/compat-data": "^7.17.7", + "@babel/compat-data": "^7.17.10", "@babel/helper-validator-option": "^7.16.7", - "browserslist": "^4.17.5", + "browserslist": "^4.20.2", "semver": "^6.3.0" }, "engines": { @@ -233,15 +243,15 @@ } }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.17.6", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.17.6.tgz", - "integrity": "sha512-SogLLSxXm2OkBbSsHZMM4tUi8fUzjs63AT/d0YQIzr6GSd8Hxsbk2KYDX0k0DweAzGMj/YWeiCsorIdtdcW8Eg==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.18.0.tgz", + "integrity": "sha512-Kh8zTGR9de3J63e5nS0rQUdRs/kbtwoeQQ0sriS0lItjC96u8XXZN6lKpuyWd2coKSU13py/y+LTmThLuVX0Pg==", "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.16.7", "@babel/helper-environment-visitor": "^7.16.7", - "@babel/helper-function-name": "^7.16.7", - "@babel/helper-member-expression-to-functions": "^7.16.7", + "@babel/helper-function-name": "^7.17.9", + "@babel/helper-member-expression-to-functions": "^7.17.7", "@babel/helper-optimise-call-expression": "^7.16.7", "@babel/helper-replace-supers": "^7.16.7", "@babel/helper-split-export-declaration": "^7.16.7" @@ -254,9 +264,9 @@ } }, "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.17.0.tgz", - "integrity": "sha512-awO2So99wG6KnlE+TPs6rn83gCz5WlEePJDTnLEqbchMVrBeAujURVphRdigsk094VhvZehFoNOihSlcBjwsXA==", + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.17.12.tgz", + "integrity": "sha512-b2aZrV4zvutr9AIa6/gA3wsZKRwTKYoDxYiFKcESS3Ug2GTXzwBEvMuuFLhCQpEnRXs1zng4ISAXSUxxKBIcxw==", "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.16.7", @@ -289,13 +299,10 @@ } }, "node_modules/@babel/helper-environment-visitor": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz", - "integrity": "sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag==", - "dev": true, - "dependencies": { - "@babel/types": "^7.16.7" - }, + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.2.tgz", + "integrity": "sha512-14GQKWkX9oJzPiQQ7/J36FTXcD4kSp8egKjO9nINlSKiHITRA9q/R74qu8S9xlc/b/yjsJItQUeeh3xnGN0voQ==", + "devOptional": true, "engines": { "node": ">=6.9.0" } @@ -313,26 +320,13 @@ } }, "node_modules/@babel/helper-function-name": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz", - "integrity": "sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA==", - "dev": true, + "version": "7.17.9", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.17.9.tgz", + "integrity": "sha512-7cRisGlVtiVqZ0MW0/yFB4atgpGLWEHUVYnb448hZK4x+vih0YO5UoS11XIYtZYqHd0dIPMdUSv8q5K4LdMnIg==", + "devOptional": true, "dependencies": { - "@babel/helper-get-function-arity": "^7.16.7", "@babel/template": "^7.16.7", - "@babel/types": "^7.16.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-get-function-arity": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz", - "integrity": "sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw==", - "dev": true, - "dependencies": { - "@babel/types": "^7.16.7" + "@babel/types": "^7.17.0" }, "engines": { "node": ">=6.9.0" @@ -342,7 +336,7 @@ "version": "7.16.7", "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz", "integrity": "sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==", - "dev": true, + "devOptional": true, "dependencies": { "@babel/types": "^7.16.7" }, @@ -366,7 +360,7 @@ "version": "7.16.7", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz", "integrity": "sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==", - "dev": true, + "devOptional": true, "dependencies": { "@babel/types": "^7.16.7" }, @@ -375,10 +369,10 @@ } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.17.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.17.7.tgz", - "integrity": "sha512-VmZD99F3gNTYB7fJRDTi+u6l/zxY0BE6OIxPSU7a50s6ZUQkHwSDmV92FfM+oCG0pZRVojGYhkR8I0OGeCVREw==", - "dev": true, + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.18.0.tgz", + "integrity": "sha512-kclUYSUBIjlvnzN2++K9f2qzYKFgjmnmjwL4zlmU5f8ZtzgWe8s0rUPSTGy2HmK4P8T52MQsS+HTQAgZd3dMEA==", + "devOptional": true, "dependencies": { "@babel/helper-environment-visitor": "^7.16.7", "@babel/helper-module-imports": "^7.16.7", @@ -386,8 +380,8 @@ "@babel/helper-split-export-declaration": "^7.16.7", "@babel/helper-validator-identifier": "^7.16.7", "@babel/template": "^7.16.7", - "@babel/traverse": "^7.17.3", - "@babel/types": "^7.17.0" + "@babel/traverse": "^7.18.0", + "@babel/types": "^7.18.0" }, "engines": { "node": ">=6.9.0" @@ -406,9 +400,9 @@ } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz", - "integrity": "sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA==", + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.17.12.tgz", + "integrity": "sha512-JDkf04mqtN3y4iAbO1hv9U2ARpPyPL1zqyWs/2WG1pgSq9llHFjStX5jdxb84himgJm+8Ng+x0oiWF/nw/XQKA==", "dev": true, "engines": { "node": ">=6.9.0" @@ -429,28 +423,28 @@ } }, "node_modules/@babel/helper-replace-supers": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.16.7.tgz", - "integrity": "sha512-y9vsWilTNaVnVh6xiJfABzsNpgDPKev9HnAgz6Gb1p6UUwf9NepdlsV7VXGCftJM+jqD5f7JIEubcpLjZj5dBw==", + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.18.2.tgz", + "integrity": "sha512-XzAIyxx+vFnrOxiQrToSUOzUOn0e1J2Li40ntddek1Y69AXUTXoDJ40/D5RdjFu7s7qHiaeoTiempZcbuVXh2Q==", "dev": true, "dependencies": { - "@babel/helper-environment-visitor": "^7.16.7", - "@babel/helper-member-expression-to-functions": "^7.16.7", + "@babel/helper-environment-visitor": "^7.18.2", + "@babel/helper-member-expression-to-functions": "^7.17.7", "@babel/helper-optimise-call-expression": "^7.16.7", - "@babel/traverse": "^7.16.7", - "@babel/types": "^7.16.7" + "@babel/traverse": "^7.18.2", + "@babel/types": "^7.18.2" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-simple-access": { - "version": "7.17.7", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.17.7.tgz", - "integrity": "sha512-txyMCGroZ96i+Pxr3Je3lzEJjqwaRC9buMUgtomcrLe5Nd0+fk1h0LLA+ixUF5OW7AhHuQ7Es1WcQJZmZsz2XA==", - "dev": true, + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.18.2.tgz", + "integrity": "sha512-7LIrjYzndorDY88MycupkpQLKS1AFfsVRm2k/9PtKScSy5tZq0McZTj+DiMRynboZfIqOKvo03pmhTaUgiD6fQ==", + "devOptional": true, "dependencies": { - "@babel/types": "^7.17.0" + "@babel/types": "^7.18.2" }, "engines": { "node": ">=6.9.0" @@ -472,7 +466,7 @@ "version": "7.16.7", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz", "integrity": "sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==", - "dev": true, + "devOptional": true, "dependencies": { "@babel/types": "^7.16.7" }, @@ -484,7 +478,7 @@ "version": "7.16.7", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", - "dev": true, + "devOptional": true, "engines": { "node": ">=6.9.0" } @@ -493,7 +487,7 @@ "version": "7.16.7", "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz", "integrity": "sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==", - "dev": true, + "devOptional": true, "engines": { "node": ">=6.9.0" } @@ -514,24 +508,24 @@ } }, "node_modules/@babel/helpers": { - "version": "7.17.8", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.17.8.tgz", - "integrity": "sha512-QcL86FGxpfSJwGtAvv4iG93UL6bmqBdmoVY0CMCU2g+oD2ezQse3PT5Pa+jiD6LJndBQi0EDlpzOWNlLuhz5gw==", - "dev": true, + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.18.2.tgz", + "integrity": "sha512-j+d+u5xT5utcQSzrh9p+PaJX94h++KN+ng9b9WEJq7pkUPAd61FGqhjuUEdfknb3E/uDBb7ruwEeKkIxNJPIrg==", + "devOptional": true, "dependencies": { "@babel/template": "^7.16.7", - "@babel/traverse": "^7.17.3", - "@babel/types": "^7.17.0" + "@babel/traverse": "^7.18.2", + "@babel/types": "^7.18.2" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.16.10", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.10.tgz", - "integrity": "sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==", - "dev": true, + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.17.12.tgz", + "integrity": "sha512-7yykMVF3hfZY2jsHZEEgLc+3x4o1O+fYyULu11GynEUQNwB6lua+IIQn1FiJxNucd5UlyJryrwsOh8PL9Sn8Qg==", + "devOptional": true, "dependencies": { "@babel/helper-validator-identifier": "^7.16.7", "chalk": "^2.0.0", @@ -545,7 +539,7 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, + "devOptional": true, "dependencies": { "color-convert": "^1.9.0" }, @@ -557,7 +551,7 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, + "devOptional": true, "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -571,7 +565,7 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, + "devOptional": true, "dependencies": { "color-name": "1.1.3" } @@ -579,14 +573,14 @@ "node_modules/@babel/highlight/node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "devOptional": true }, "node_modules/@babel/highlight/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": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true, + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "devOptional": true, "engines": { "node": ">=0.8.0" } @@ -594,8 +588,8 @@ "node_modules/@babel/highlight/node_modules/has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true, + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "devOptional": true, "engines": { "node": ">=4" } @@ -604,7 +598,7 @@ "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, + "devOptional": true, "dependencies": { "has-flag": "^3.0.0" }, @@ -613,10 +607,10 @@ } }, "node_modules/@babel/parser": { - "version": "7.17.8", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.8.tgz", - "integrity": "sha512-BoHhDJrJXqcg+ZL16Xv39H9n+AqJ4pcDrQBGZN+wHxIysrLZ3/ECwCBUch/1zUNhnsXULcONU3Ei5Hmkfk6kiQ==", - "dev": true, + "version": "7.18.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.4.tgz", + "integrity": "sha512-FDge0dFazETFcxGw/EXzOkN8uJp0PC7Qbm+Pe9T+av2zlBpOgunFHkQPPn+eRuClU73JF+98D531UgayY89tow==", + "devOptional": true, "bin": { "parser": "bin/babel-parser.js" }, @@ -625,12 +619,12 @@ } }, "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.16.7", - "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.16.7.tgz", - "integrity": "sha512-anv/DObl7waiGEnC24O9zqL0pSuI9hljihqiDuFHC8d7/bjr/4RLGPWuc8rYOff/QPzbEPSkzG8wGG9aDuhHRg==", + "version": "7.17.12", + "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.17.12.tgz", + "integrity": "sha512-xCJQXl4EeQ3J9C4yOmpTrtVGmzpm2iSzyxbkZHw7UCnZBftHpF/hpII80uWVyVrc40ytIClHjgWGTG1g/yB+aw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7" + "@babel/helper-plugin-utils": "^7.17.12" }, "engines": { "node": ">=6.9.0" @@ -640,14 +634,14 @@ } }, "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.16.7.tgz", - "integrity": "sha512-di8vUHRdf+4aJ7ltXhaDbPoszdkh59AQtJM5soLsuHpQJdFQZOA4uGj0V2u/CZ8bJ/u8ULDL5yq6FO/bCXnKHw==", + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.17.12.tgz", + "integrity": "sha512-/vt0hpIw0x4b6BLKUkwlvEoiGZYYLNZ96CzyHYPbtG2jZGz6LBe7/V+drYrc/d+ovrF9NBi0pmtvmNb/FsWtRQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-plugin-utils": "^7.17.12", "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0", - "@babel/plugin-proposal-optional-chaining": "^7.16.7" + "@babel/plugin-proposal-optional-chaining": "^7.17.12" }, "engines": { "node": ">=6.9.0" @@ -657,12 +651,12 @@ } }, "node_modules/@babel/plugin-proposal-async-generator-functions": { - "version": "7.16.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.16.8.tgz", - "integrity": "sha512-71YHIvMuiuqWJQkebWJtdhQTfd4Q4mF76q2IX37uZPkG9+olBxsX+rH1vkhFto4UeJZ9dPY2s+mDvhDm1u2BGQ==", + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.17.12.tgz", + "integrity": "sha512-RWVvqD1ooLKP6IqWTA5GyFVX2isGEgC5iFxKzfYOIy/QEFdxYyCybBDtIGjipHpb9bDWHzcqGqFakf+mVmBTdQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-plugin-utils": "^7.17.12", "@babel/helper-remap-async-to-generator": "^7.16.8", "@babel/plugin-syntax-async-generators": "^7.8.4" }, @@ -674,13 +668,13 @@ } }, "node_modules/@babel/plugin-proposal-class-properties": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.16.7.tgz", - "integrity": "sha512-IobU0Xme31ewjYOShSIqd/ZGM/r/cuOz2z0MDbNrhF5FW+ZVgi0f2lyeoj9KFPDOAqsYxmLWZte1WOwlvY9aww==", + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.17.12.tgz", + "integrity": "sha512-U0mI9q8pW5Q9EaTHFPwSVusPMV/DV9Mm8p7csqROFLtIE9rBF5piLqyrBGigftALrBcsBGu4m38JneAe7ZDLXw==", "dev": true, "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7" + "@babel/helper-create-class-features-plugin": "^7.17.12", + "@babel/helper-plugin-utils": "^7.17.12" }, "engines": { "node": ">=6.9.0" @@ -690,13 +684,13 @@ } }, "node_modules/@babel/plugin-proposal-class-static-block": { - "version": "7.17.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.17.6.tgz", - "integrity": "sha512-X/tididvL2zbs7jZCeeRJ8167U/+Ac135AM6jCAx6gYXDUviZV5Ku9UDvWS2NCuWlFjIRXklYhwo6HhAC7ETnA==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.18.0.tgz", + "integrity": "sha512-t+8LsRMMDE74c6sV7KShIw13sqbqd58tlqNrsWoWBTIMw7SVQ0cZ905wLNS/FBCy/3PyooRHLFFlfrUNyyz5lA==", "dev": true, "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.17.6", - "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-create-class-features-plugin": "^7.18.0", + "@babel/helper-plugin-utils": "^7.17.12", "@babel/plugin-syntax-class-static-block": "^7.14.5" }, "engines": { @@ -707,15 +701,16 @@ } }, "node_modules/@babel/plugin-proposal-decorators": { - "version": "7.17.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.17.8.tgz", - "integrity": "sha512-U69odN4Umyyx1xO1rTII0IDkAEC+RNlcKXtqOblfpzqy1C+aOplb76BQNq0+XdpVkOaPlpEDwd++joY8FNFJKA==", + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.18.2.tgz", + "integrity": "sha512-kbDISufFOxeczi0v4NQP3p5kIeW6izn/6klfWBrIIdGZZe4UpHR+QU03FAoWjGGd9SUXAwbw2pup1kaL4OQsJQ==", "dev": true, "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.17.6", - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/helper-replace-supers": "^7.16.7", - "@babel/plugin-syntax-decorators": "^7.17.0", + "@babel/helper-create-class-features-plugin": "^7.18.0", + "@babel/helper-plugin-utils": "^7.17.12", + "@babel/helper-replace-supers": "^7.18.2", + "@babel/helper-split-export-declaration": "^7.16.7", + "@babel/plugin-syntax-decorators": "^7.17.12", "charcodes": "^0.2.0" }, "engines": { @@ -742,12 +737,12 @@ } }, "node_modules/@babel/plugin-proposal-export-namespace-from": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.16.7.tgz", - "integrity": "sha512-ZxdtqDXLRGBL64ocZcs7ovt71L3jhC1RGSyR996svrCi3PYqHNkb3SwPJCs8RIzD86s+WPpt2S73+EHCGO+NUA==", + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.17.12.tgz", + "integrity": "sha512-j7Ye5EWdwoXOpRmo5QmRyHPsDIe6+u70ZYZrd7uz+ebPYFKfRcLcNu3Ro0vOlJ5zuv8rU7xa+GttNiRzX56snQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-plugin-utils": "^7.17.12", "@babel/plugin-syntax-export-namespace-from": "^7.8.3" }, "engines": { @@ -758,12 +753,12 @@ } }, "node_modules/@babel/plugin-proposal-json-strings": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.16.7.tgz", - "integrity": "sha512-lNZ3EEggsGY78JavgbHsK9u5P3pQaW7k4axlgFLYkMd7UBsiNahCITShLjNQschPyjtO6dADrL24757IdhBrsQ==", + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.17.12.tgz", + "integrity": "sha512-rKJ+rKBoXwLnIn7n6o6fulViHMrOThz99ybH+hKHcOZbnN14VuMnH9fo2eHE69C8pO4uX1Q7t2HYYIDmv8VYkg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-plugin-utils": "^7.17.12", "@babel/plugin-syntax-json-strings": "^7.8.3" }, "engines": { @@ -774,12 +769,12 @@ } }, "node_modules/@babel/plugin-proposal-logical-assignment-operators": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.16.7.tgz", - "integrity": "sha512-K3XzyZJGQCr00+EtYtrDjmwX7o7PLK6U9bi1nCwkQioRFVUv6dJoxbQjtWVtP+bCPy82bONBKG8NPyQ4+i6yjg==", + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.17.12.tgz", + "integrity": "sha512-EqFo2s1Z5yy+JeJu7SFfbIUtToJTVlC61/C7WLKDntSw4Sz6JNAIfL7zQ74VvirxpjB5kz/kIx0gCcb+5OEo2Q==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-plugin-utils": "^7.17.12", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" }, "engines": { @@ -790,12 +785,12 @@ } }, "node_modules/@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.16.7.tgz", - "integrity": "sha512-aUOrYU3EVtjf62jQrCj63pYZ7k6vns2h/DQvHPWGmsJRYzWXZ6/AsfgpiRy6XiuIDADhJzP2Q9MwSMKauBQ+UQ==", + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.17.12.tgz", + "integrity": "sha512-ws/g3FSGVzv+VH86+QvgtuJL/kR67xaEIF2x0iPqdDfYW6ra6JF3lKVBkWynRLcNtIC1oCTfDRVxmm2mKzy+ag==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-plugin-utils": "^7.17.12", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" }, "engines": { @@ -822,16 +817,16 @@ } }, "node_modules/@babel/plugin-proposal-object-rest-spread": { - "version": "7.17.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.17.3.tgz", - "integrity": "sha512-yuL5iQA/TbZn+RGAfxQXfi7CNLmKi1f8zInn4IgobuCWcAb7i+zj4TYzQ9l8cEzVyJ89PDGuqxK1xZpUDISesw==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.18.0.tgz", + "integrity": "sha512-nbTv371eTrFabDfHLElkn9oyf9VG+VKK6WMzhY2o4eHKaG19BToD9947zzGMO6I/Irstx9d8CwX6njPNIAR/yw==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.17.0", - "@babel/helper-compilation-targets": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7", + "@babel/compat-data": "^7.17.10", + "@babel/helper-compilation-targets": "^7.17.10", + "@babel/helper-plugin-utils": "^7.17.12", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.16.7" + "@babel/plugin-transform-parameters": "^7.17.12" }, "engines": { "node": ">=6.9.0" @@ -857,12 +852,12 @@ } }, "node_modules/@babel/plugin-proposal-optional-chaining": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.16.7.tgz", - "integrity": "sha512-eC3xy+ZrUcBtP7x+sq62Q/HYd674pPTb/77XZMb5wbDPGWIdUbSr4Agr052+zaUPSb+gGRnjxXfKFvx5iMJ+DA==", + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.17.12.tgz", + "integrity": "sha512-7wigcOs/Z4YWlK7xxjkvaIw84vGhDv/P1dFGQap0nHkc8gFKY/r+hXc8Qzf5k1gY7CvGIcHqAnOagVKJJ1wVOQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-plugin-utils": "^7.17.12", "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0", "@babel/plugin-syntax-optional-chaining": "^7.8.3" }, @@ -874,13 +869,13 @@ } }, "node_modules/@babel/plugin-proposal-private-methods": { - "version": "7.16.11", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.16.11.tgz", - "integrity": "sha512-F/2uAkPlXDr8+BHpZvo19w3hLFKge+k75XUprE6jaqKxjGkSYcK+4c+bup5PdW/7W/Rpjwql7FTVEDW+fRAQsw==", + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.17.12.tgz", + "integrity": "sha512-SllXoxo19HmxhDWm3luPz+cPhtoTSKLJE9PXshsfrOzBqs60QP0r8OaJItrPhAj0d7mZMnNF0Y1UUggCDgMz1A==", "dev": true, "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.16.10", - "@babel/helper-plugin-utils": "^7.16.7" + "@babel/helper-create-class-features-plugin": "^7.17.12", + "@babel/helper-plugin-utils": "^7.17.12" }, "engines": { "node": ">=6.9.0" @@ -890,14 +885,14 @@ } }, "node_modules/@babel/plugin-proposal-private-property-in-object": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.16.7.tgz", - "integrity": "sha512-rMQkjcOFbm+ufe3bTZLyOfsOUOxyvLXZJCTARhJr+8UMSoZmqTe1K1BgkFcrW37rAchWg57yI69ORxiWvUINuQ==", + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.17.12.tgz", + "integrity": "sha512-/6BtVi57CJfrtDNKfK5b66ydK2J5pXUKBKSPD2G1whamMuEnZWgoOIfO8Vf9F/DoD4izBLD/Au4NMQfruzzykg==", "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.16.7", - "@babel/helper-create-class-features-plugin": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-create-class-features-plugin": "^7.17.12", + "@babel/helper-plugin-utils": "^7.17.12", "@babel/plugin-syntax-private-property-in-object": "^7.14.5" }, "engines": { @@ -908,13 +903,13 @@ } }, "node_modules/@babel/plugin-proposal-unicode-property-regex": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.16.7.tgz", - "integrity": "sha512-QRK0YI/40VLhNVGIjRNAAQkEHws0cswSdFFjpFyt943YmJIU1da9uW63Iu6NFV6CxTZW5eTDCrwZUstBWgp/Rg==", + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.17.12.tgz", + "integrity": "sha512-Wb9qLjXf3ZazqXA7IvI7ozqRIXIGPtSo+L5coFmEkhTQK18ao4UDDD0zdTGAarmbLj2urpRwrc6893cu5Bfh0A==", "dev": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7" + "@babel/helper-create-regexp-features-plugin": "^7.17.12", + "@babel/helper-plugin-utils": "^7.17.12" }, "engines": { "node": ">=4" @@ -963,12 +958,12 @@ } }, "node_modules/@babel/plugin-syntax-decorators": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.17.0.tgz", - "integrity": "sha512-qWe85yCXsvDEluNP0OyeQjH63DlhAR3W7K9BxxU1MvbDb48tgBG+Ao6IJJ6smPDrrVzSQZrbF6donpkFBMcs3A==", + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.17.12.tgz", + "integrity": "sha512-D1Hz0qtGTza8K2xGyEdVNCYLdVHukAcbQr4K3/s6r/esadyEriZovpJimQOpu8ju4/jV8dW/1xdaE0UpDroidw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7" + "@babel/helper-plugin-utils": "^7.17.12" }, "engines": { "node": ">=6.9.0" @@ -1002,12 +997,27 @@ } }, "node_modules/@babel/plugin-syntax-flow": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.16.7.tgz", - "integrity": "sha512-UDo3YGQO0jH6ytzVwgSLv9i/CzMcUjbKenL67dTrAZPPv6GFAtDhe6jqnvmoKzC/7htNTohhos+onPtDMqJwaQ==", + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.17.12.tgz", + "integrity": "sha512-B8QIgBvkIG6G2jgsOHQUist7Sm0EBLDCx8sen072IwqNuzMegZNXrYnSv77cYzA8mLDZAfQYqsLIhimiP1s2HQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7" + "@babel/helper-plugin-utils": "^7.17.12" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.17.12.tgz", + "integrity": "sha512-n/loy2zkq9ZEM8tEOwON9wTQSTNDTDEz6NujPtJGLU7qObzT1N4c4YZZf8E6ATB2AjNQg/Ib2AIpO03EZaCehw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.17.12" }, "engines": { "node": ">=6.9.0" @@ -1029,12 +1039,12 @@ } }, "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.16.7.tgz", - "integrity": "sha512-Esxmk7YjA8QysKeT3VhTXvF6y77f/a91SIs4pWb4H2eWGQkCKFgQaG6hdoEVZtGsrAcb2K5BW66XsOErD4WU3Q==", + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.17.12.tgz", + "integrity": "sha512-spyY3E3AURfxh/RHtjx5j6hs8am5NbUBGfcZ2vB3uShSpZdQyXSf5rR5Mk76vbtlAZOelyVQ71Fg0x9SG4fsog==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7" + "@babel/helper-plugin-utils": "^7.17.12" }, "engines": { "node": ">=6.9.0" @@ -1146,12 +1156,12 @@ } }, "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.16.7.tgz", - "integrity": "sha512-YhUIJHHGkqPgEcMYkPCKTyGUdoGKWtopIycQyjJH8OjvRgOYsXsaKehLVPScKJWAULPxMa4N1vCe6szREFlZ7A==", + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.17.12.tgz", + "integrity": "sha512-TYY0SXFiO31YXtNg3HtFwNJHjLsAyIIhAhNWkQ5whPPS7HWUFlg9z0Ta4qAQNjQbP1wsSt/oKkmZ/4/WWdMUpw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7" + "@babel/helper-plugin-utils": "^7.17.12" }, "engines": { "node": ">=6.9.0" @@ -1161,12 +1171,12 @@ } }, "node_modules/@babel/plugin-transform-arrow-functions": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.16.7.tgz", - "integrity": "sha512-9ffkFFMbvzTvv+7dTp/66xvZAWASuPD5Tl9LK3Z9vhOmANo6j94rik+5YMBt4CwHVMWLWpMsriIc2zsa3WW3xQ==", + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.17.12.tgz", + "integrity": "sha512-PHln3CNi/49V+mza4xMwrg+WGYevSF1oaiXaC2EQfdp4HWlSjRsrDXWJiQBKpP7749u6vQ9mcry2uuFOv5CXvA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7" + "@babel/helper-plugin-utils": "^7.17.12" }, "engines": { "node": ">=6.9.0" @@ -1176,13 +1186,13 @@ } }, "node_modules/@babel/plugin-transform-async-to-generator": { - "version": "7.16.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.16.8.tgz", - "integrity": "sha512-MtmUmTJQHCnyJVrScNzNlofQJ3dLFuobYn3mwOTKHnSCMtbNsqvF71GQmJfFjdrXSsAA7iysFmYWw4bXZ20hOg==", + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.17.12.tgz", + "integrity": "sha512-J8dbrWIOO3orDzir57NRsjg4uxucvhby0L/KZuGsWDj0g7twWK3g7JhJhOrXtuXiw8MeiSdJ3E0OW9H8LYEzLQ==", "dev": true, "dependencies": { "@babel/helper-module-imports": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-plugin-utils": "^7.17.12", "@babel/helper-remap-async-to-generator": "^7.16.8" }, "engines": { @@ -1208,12 +1218,12 @@ } }, "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.16.7.tgz", - "integrity": "sha512-ObZev2nxVAYA4bhyusELdo9hb3H+A56bxH3FZMbEImZFiEDYVHXQSJ1hQKFlDnlt8G9bBrCZ5ZpURZUrV4G5qQ==", + "version": "7.18.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.18.4.tgz", + "integrity": "sha512-+Hq10ye+jlvLEogSOtq4mKvtk7qwcUQ1f0Mrueai866C82f844Yom2cttfJdMdqRLTxWpsbfbkIkOIfovyUQXw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7" + "@babel/helper-plugin-utils": "^7.17.12" }, "engines": { "node": ">=6.9.0" @@ -1223,17 +1233,17 @@ } }, "node_modules/@babel/plugin-transform-classes": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.16.7.tgz", - "integrity": "sha512-WY7og38SFAGYRe64BrjKf8OrE6ulEHtr5jEYaZMwox9KebgqPi67Zqz8K53EKk1fFEJgm96r32rkKZ3qA2nCWQ==", + "version": "7.18.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.18.4.tgz", + "integrity": "sha512-e42NSG2mlKWgxKUAD9EJJSkZxR67+wZqzNxLSpc51T8tRU5SLFHsPmgYR5yr7sdgX4u+iHA1C5VafJ6AyImV3A==", "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.16.7", - "@babel/helper-environment-visitor": "^7.16.7", - "@babel/helper-function-name": "^7.16.7", + "@babel/helper-environment-visitor": "^7.18.2", + "@babel/helper-function-name": "^7.17.9", "@babel/helper-optimise-call-expression": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/helper-replace-supers": "^7.16.7", + "@babel/helper-plugin-utils": "^7.17.12", + "@babel/helper-replace-supers": "^7.18.2", "@babel/helper-split-export-declaration": "^7.16.7", "globals": "^11.1.0" }, @@ -1245,12 +1255,12 @@ } }, "node_modules/@babel/plugin-transform-computed-properties": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.16.7.tgz", - "integrity": "sha512-gN72G9bcmenVILj//sv1zLNaPyYcOzUho2lIJBMh/iakJ9ygCo/hEF9cpGb61SCMEDxbbyBoVQxrt+bWKu5KGw==", + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.17.12.tgz", + "integrity": "sha512-a7XINeplB5cQUWMg1E/GI1tFz3LfK021IjV1rj1ypE+R7jHm+pIHmHl25VNkZxtx9uuYp7ThGk8fur1HHG7PgQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7" + "@babel/helper-plugin-utils": "^7.17.12" }, "engines": { "node": ">=6.9.0" @@ -1260,12 +1270,12 @@ } }, "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.17.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.17.7.tgz", - "integrity": "sha512-XVh0r5yq9sLR4vZ6eVZe8FKfIcSgaTBxVBRSYokRj2qksf6QerYnTxz9/GTuKTH/n/HwLP7t6gtlybHetJ/6hQ==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.18.0.tgz", + "integrity": "sha512-Mo69klS79z6KEfrLg/1WkmVnB8javh75HX4pi2btjvlIoasuxilEyjtsQW6XPrubNd7AQy0MMaNIaQE4e7+PQw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7" + "@babel/helper-plugin-utils": "^7.17.12" }, "engines": { "node": ">=6.9.0" @@ -1291,12 +1301,12 @@ } }, "node_modules/@babel/plugin-transform-duplicate-keys": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.16.7.tgz", - "integrity": "sha512-03DvpbRfvWIXyK0/6QiR1KMTWeT6OcQ7tbhjrXyFS02kjuX/mu5Bvnh5SDSWHxyawit2g5aWhKwI86EE7GUnTw==", + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.17.12.tgz", + "integrity": "sha512-EA5eYFUG6xeerdabina/xIoB95jJ17mAkR8ivx6ZSu9frKShBjpOGZPn511MTDTkiCO+zXnzNczvUM69YSf3Zw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7" + "@babel/helper-plugin-utils": "^7.17.12" }, "engines": { "node": ">=6.9.0" @@ -1322,13 +1332,13 @@ } }, "node_modules/@babel/plugin-transform-flow-strip-types": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.16.7.tgz", - "integrity": "sha512-mzmCq3cNsDpZZu9FADYYyfZJIOrSONmHcop2XEKPdBNMa4PDC4eEvcOvzZaCNcjKu72v0XQlA5y1g58aLRXdYg==", + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.17.12.tgz", + "integrity": "sha512-g8cSNt+cHCpG/uunPQELdq/TeV3eg1OLJYwxypwHtAWo9+nErH3lQx9CSO2uI9lF74A0mR0t4KoMjs1snSgnTw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/plugin-syntax-flow": "^7.16.7" + "@babel/helper-plugin-utils": "^7.17.12", + "@babel/plugin-syntax-flow": "^7.17.12" }, "engines": { "node": ">=6.9.0" @@ -1338,12 +1348,12 @@ } }, "node_modules/@babel/plugin-transform-for-of": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.16.7.tgz", - "integrity": "sha512-/QZm9W92Ptpw7sjI9Nx1mbcsWz33+l8kuMIQnDwgQBG5s3fAfQvkRjQ7NqXhtNcKOnPkdICmUHyCaWW06HCsqg==", + "version": "7.18.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.18.1.tgz", + "integrity": "sha512-+TTB5XwvJ5hZbO8xvl2H4XaMDOAK57zF4miuC9qQJgysPNEAZZ9Z69rdF5LJkozGdZrjBIUAIyKUWRMmebI7vg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7" + "@babel/helper-plugin-utils": "^7.17.12" }, "engines": { "node": ">=6.9.0" @@ -1370,12 +1380,12 @@ } }, "node_modules/@babel/plugin-transform-literals": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.16.7.tgz", - "integrity": "sha512-6tH8RTpTWI0s2sV6uq3e/C9wPo4PTqqZps4uF0kzQ9/xPLFQtipynvmT1g/dOfEJ+0EQsHhkQ/zyRId8J2b8zQ==", + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.17.12.tgz", + "integrity": "sha512-8iRkvaTjJciWycPIZ9k9duu663FT7VrBdNqNgxnVXEFwOIp55JWcZd23VBRySYbnS3PwQ3rGiabJBBBGj5APmQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7" + "@babel/helper-plugin-utils": "^7.17.12" }, "engines": { "node": ">=6.9.0" @@ -1400,13 +1410,13 @@ } }, "node_modules/@babel/plugin-transform-modules-amd": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.16.7.tgz", - "integrity": "sha512-KaaEtgBL7FKYwjJ/teH63oAmE3lP34N3kshz8mm4VMAw7U3PxjVwwUmxEFksbgsNUaO3wId9R2AVQYSEGRa2+g==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.18.0.tgz", + "integrity": "sha512-h8FjOlYmdZwl7Xm2Ug4iX2j7Qy63NANI+NQVWQzv6r25fqgg7k2dZl03p95kvqNclglHs4FZ+isv4p1uXMA+QA==", "dev": true, "dependencies": { - "@babel/helper-module-transforms": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-module-transforms": "^7.18.0", + "@babel/helper-plugin-utils": "^7.17.12", "babel-plugin-dynamic-import-node": "^2.3.3" }, "engines": { @@ -1417,14 +1427,14 @@ } }, "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.17.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.17.7.tgz", - "integrity": "sha512-ITPmR2V7MqioMJyrxUo2onHNC3e+MvfFiFIR0RP21d3PtlVb6sfzoxNKiphSZUOM9hEIdzCcZe83ieX3yoqjUA==", + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.18.2.tgz", + "integrity": "sha512-f5A865gFPAJAEE0K7F/+nm5CmAE3y8AWlMBG9unu5j9+tk50UQVK0QS8RNxSp7MJf0wh97uYyLWt3Zvu71zyOQ==", "dev": true, "dependencies": { - "@babel/helper-module-transforms": "^7.17.7", - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/helper-simple-access": "^7.17.7", + "@babel/helper-module-transforms": "^7.18.0", + "@babel/helper-plugin-utils": "^7.17.12", + "@babel/helper-simple-access": "^7.18.2", "babel-plugin-dynamic-import-node": "^2.3.3" }, "engines": { @@ -1435,14 +1445,14 @@ } }, "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.17.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.17.8.tgz", - "integrity": "sha512-39reIkMTUVagzgA5x88zDYXPCMT6lcaRKs1+S9K6NKBPErbgO/w/kP8GlNQTC87b412ZTlmNgr3k2JrWgHH+Bw==", + "version": "7.18.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.18.4.tgz", + "integrity": "sha512-lH2UaQaHVOAeYrUUuZ8i38o76J/FnO8vu21OE+tD1MyP9lxdZoSfz+pDbWkq46GogUrdrMz3tiz/FYGB+bVThg==", "dev": true, "dependencies": { "@babel/helper-hoist-variables": "^7.16.7", - "@babel/helper-module-transforms": "^7.17.7", - "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-module-transforms": "^7.18.0", + "@babel/helper-plugin-utils": "^7.17.12", "@babel/helper-validator-identifier": "^7.16.7", "babel-plugin-dynamic-import-node": "^2.3.3" }, @@ -1454,13 +1464,13 @@ } }, "node_modules/@babel/plugin-transform-modules-umd": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.16.7.tgz", - "integrity": "sha512-EMh7uolsC8O4xhudF2F6wedbSHm1HHZ0C6aJ7K67zcDNidMzVcxWdGr+htW9n21klm+bOn+Rx4CBsAntZd3rEQ==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.18.0.tgz", + "integrity": "sha512-d/zZ8I3BWli1tmROLxXLc9A6YXvGK8egMxHp+E/rRwMh1Kip0AP77VwZae3snEJ33iiWwvNv2+UIIhfalqhzZA==", "dev": true, "dependencies": { - "@babel/helper-module-transforms": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7" + "@babel/helper-module-transforms": "^7.18.0", + "@babel/helper-plugin-utils": "^7.17.12" }, "engines": { "node": ">=6.9.0" @@ -1470,12 +1480,13 @@ } }, "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.16.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.16.8.tgz", - "integrity": "sha512-j3Jw+n5PvpmhRR+mrgIh04puSANCk/T/UA3m3P1MjJkhlK906+ApHhDIqBQDdOgL/r1UYpz4GNclTXxyZrYGSw==", + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.17.12.tgz", + "integrity": "sha512-vWoWFM5CKaTeHrdUJ/3SIOTRV+MBVGybOC9mhJkaprGNt5demMymDW24yC74avb915/mIRe3TgNb/d8idvnCRA==", "dev": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.16.7" + "@babel/helper-create-regexp-features-plugin": "^7.17.12", + "@babel/helper-plugin-utils": "^7.17.12" }, "engines": { "node": ">=6.9.0" @@ -1485,12 +1496,12 @@ } }, "node_modules/@babel/plugin-transform-new-target": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.16.7.tgz", - "integrity": "sha512-xiLDzWNMfKoGOpc6t3U+etCE2yRnn3SM09BXqWPIZOBpL2gvVrBWUKnsJx0K/ADi5F5YC5f8APFfWrz25TdlGg==", + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.17.12.tgz", + "integrity": "sha512-CaOtzk2fDYisbjAD4Sd1MTKGVIpRtx9bWLyj24Y/k6p4s4gQ3CqDGJauFJxt8M/LEx003d0i3klVqnN73qvK3w==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7" + "@babel/helper-plugin-utils": "^7.17.12" }, "engines": { "node": ">=6.9.0" @@ -1516,12 +1527,12 @@ } }, "node_modules/@babel/plugin-transform-parameters": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.16.7.tgz", - "integrity": "sha512-AT3MufQ7zZEhU2hwOA11axBnExW0Lszu4RL/tAlUJBuNoRak+wehQW8h6KcXOcgjY42fHtDxswuMhMjFEuv/aw==", + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.17.12.tgz", + "integrity": "sha512-6qW4rWo1cyCdq1FkYri7AHpauchbGLXpdwnYsfxFb+KtddHENfsY5JZb35xUwkK5opOLcJ3BNd2l7PhRYGlwIA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7" + "@babel/helper-plugin-utils": "^7.17.12" }, "engines": { "node": ">=6.9.0" @@ -1561,16 +1572,16 @@ } }, "node_modules/@babel/plugin-transform-react-jsx": { - "version": "7.17.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.17.3.tgz", - "integrity": "sha512-9tjBm4O07f7mzKSIlEmPdiE6ub7kfIe6Cd+w+oQebpATfTQMAgW+YOuWxogbKVTulA+MEO7byMeIUtQ1z+z+ZQ==", + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.17.12.tgz", + "integrity": "sha512-Lcaw8bxd1DKht3thfD4A12dqo1X16he1Lm8rIv8sTwjAYNInRS1qHa9aJoqvzpscItXvftKDCfaEQzwoVyXpEQ==", "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.16.7", "@babel/helper-module-imports": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/plugin-syntax-jsx": "^7.16.7", - "@babel/types": "^7.17.0" + "@babel/helper-plugin-utils": "^7.17.12", + "@babel/plugin-syntax-jsx": "^7.17.12", + "@babel/types": "^7.17.12" }, "engines": { "node": ">=6.9.0" @@ -1595,12 +1606,12 @@ } }, "node_modules/@babel/plugin-transform-react-jsx-self": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.16.7.tgz", - "integrity": "sha512-oe5VuWs7J9ilH3BCCApGoYjHoSO48vkjX2CbA5bFVhIuO2HKxA3vyF7rleA4o6/4rTDbk6r8hBW7Ul8E+UZrpA==", + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.17.12.tgz", + "integrity": "sha512-7S9G2B44EnYOx74mue02t1uD8ckWZ/ee6Uz/qfdzc35uWHX5NgRy9i+iJSb2LFRgMd+QV9zNcStQaazzzZ3n3Q==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7" + "@babel/helper-plugin-utils": "^7.17.12" }, "engines": { "node": ">=6.9.0" @@ -1625,13 +1636,13 @@ } }, "node_modules/@babel/plugin-transform-react-pure-annotations": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.16.7.tgz", - "integrity": "sha512-hs71ToC97k3QWxswh2ElzMFABXHvGiJ01IB1TbYQDGeWRKWz/MPUTh5jGExdHvosYKpnJW5Pm3S4+TA3FyX+GA==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.18.0.tgz", + "integrity": "sha512-6+0IK6ouvqDn9bmEG7mEyF/pwlJXVj5lwydybpyyH3D0A7Hftk+NCTdYjnLNZksn261xaOV5ksmp20pQEmc2RQ==", "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7" + "@babel/helper-plugin-utils": "^7.17.12" }, "engines": { "node": ">=6.9.0" @@ -1641,12 +1652,13 @@ } }, "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.16.7.tgz", - "integrity": "sha512-mF7jOgGYCkSJagJ6XCujSQg+6xC1M77/03K2oBmVJWoFGNUtnVJO4WHKJk3dnPC8HCcj4xBQP1Egm8DWh3Pb3Q==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.18.0.tgz", + "integrity": "sha512-C8YdRw9uzx25HSIzwA7EM7YP0FhCe5wNvJbZzjVNHHPGVcDJ3Aie+qGYYdS1oVQgn+B3eAIJbWFLrJ4Jipv7nw==", "dev": true, "dependencies": { - "regenerator-transform": "^0.14.2" + "@babel/helper-plugin-utils": "^7.17.12", + "regenerator-transform": "^0.15.0" }, "engines": { "node": ">=6.9.0" @@ -1656,12 +1668,12 @@ } }, "node_modules/@babel/plugin-transform-reserved-words": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.16.7.tgz", - "integrity": "sha512-KQzzDnZ9hWQBjwi5lpY5v9shmm6IVG0U9pB18zvMu2i4H90xpT4gmqwPYsn8rObiadYe2M0gmgsiOIF5A/2rtg==", + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.17.12.tgz", + "integrity": "sha512-1KYqwbJV3Co03NIi14uEHW8P50Md6KqFgt0FfpHdK6oyAHQVTosgPuPSiWud1HX0oYJ1hGRRlk0fP87jFpqXZA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7" + "@babel/helper-plugin-utils": "^7.17.12" }, "engines": { "node": ">=6.9.0" @@ -1671,13 +1683,13 @@ } }, "node_modules/@babel/plugin-transform-runtime": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.17.0.tgz", - "integrity": "sha512-fr7zPWnKXNc1xoHfrIU9mN/4XKX4VLZ45Q+oMhfsYIaHvg7mHgmhfOy/ckRWqDK7XF3QDigRpkh5DKq6+clE8A==", + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.18.2.tgz", + "integrity": "sha512-mr1ufuRMfS52ttq+1G1PD8OJNqgcTFjq3hwn8SZ5n1x1pBhi0E36rYMdTK0TsKtApJ4lDEdfXJwtGobQMHSMPg==", "dev": true, "dependencies": { "@babel/helper-module-imports": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-plugin-utils": "^7.17.12", "babel-plugin-polyfill-corejs2": "^0.3.0", "babel-plugin-polyfill-corejs3": "^0.5.0", "babel-plugin-polyfill-regenerator": "^0.3.0", @@ -1706,12 +1718,12 @@ } }, "node_modules/@babel/plugin-transform-spread": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.16.7.tgz", - "integrity": "sha512-+pjJpgAngb53L0iaA5gU/1MLXJIfXcYepLgXB3esVRf4fqmj8f2cxM3/FKaHsZms08hFQJkFccEWuIpm429TXg==", + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.17.12.tgz", + "integrity": "sha512-9pgmuQAtFi3lpNUstvG9nGfk9DkrdmWNp9KeKPFmuZCpEnxRzYlS8JgwPjYj+1AWDOSvoGN0H30p1cBOmT/Svg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-plugin-utils": "^7.17.12", "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0" }, "engines": { @@ -1737,12 +1749,12 @@ } }, "node_modules/@babel/plugin-transform-template-literals": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.16.7.tgz", - "integrity": "sha512-VwbkDDUeenlIjmfNeDX/V0aWrQH2QiVyJtwymVQSzItFDTpxfyJh3EVaQiS0rIN/CqbLGr0VcGmuwyTdZtdIsA==", + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.2.tgz", + "integrity": "sha512-/cmuBVw9sZBGZVOMkpAEaVLwm4JmK2GZ1dFKOGGpMzEHWFmyZZ59lUU0PdRr8YNYeQdNzTDwuxP2X2gzydTc9g==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7" + "@babel/helper-plugin-utils": "^7.17.12" }, "engines": { "node": ">=6.9.0" @@ -1752,12 +1764,12 @@ } }, "node_modules/@babel/plugin-transform-typeof-symbol": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.16.7.tgz", - "integrity": "sha512-p2rOixCKRJzpg9JB4gjnG4gjWkWa89ZoYUnl9snJ1cWIcTH/hvxZqfO+WjG6T8DRBpctEol5jw1O5rA8gkCokQ==", + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.17.12.tgz", + "integrity": "sha512-Q8y+Jp7ZdtSPXCThB6zjQ74N3lj0f6TDh1Hnf5B+sYlzQ8i5Pjp8gW0My79iekSpT4WnI06blqP6DT0OmaXXmw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7" + "@babel/helper-plugin-utils": "^7.17.12" }, "engines": { "node": ">=6.9.0" @@ -1767,14 +1779,14 @@ } }, "node_modules/@babel/plugin-transform-typescript": { - "version": "7.16.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.16.8.tgz", - "integrity": "sha512-bHdQ9k7YpBDO2d0NVfkj51DpQcvwIzIusJ7mEUaMlbZq3Kt/U47j24inXZHQ5MDiYpCs+oZiwnXyKedE8+q7AQ==", + "version": "7.18.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.18.4.tgz", + "integrity": "sha512-l4vHuSLUajptpHNEOUDEGsnpl9pfRLsN1XUoDQDD/YBuXTM+v37SHGS+c6n4jdcZy96QtuUuSvZYMLSSsjH8Mw==", "dev": true, "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/plugin-syntax-typescript": "^7.16.7" + "@babel/helper-create-class-features-plugin": "^7.18.0", + "@babel/helper-plugin-utils": "^7.17.12", + "@babel/plugin-syntax-typescript": "^7.17.12" }, "engines": { "node": ">=6.9.0" @@ -1815,37 +1827,38 @@ } }, "node_modules/@babel/preset-env": { - "version": "7.16.11", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.16.11.tgz", - "integrity": "sha512-qcmWG8R7ZW6WBRPZK//y+E3Cli151B20W1Rv7ln27vuPaXU/8TKms6jFdiJtF7UDTxcrb7mZd88tAeK9LjdT8g==", + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.18.2.tgz", + "integrity": "sha512-PfpdxotV6afmXMU47S08F9ZKIm2bJIQ0YbAAtDfIENX7G1NUAXigLREh69CWDjtgUy7dYn7bsMzkgdtAlmS68Q==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.16.8", - "@babel/helper-compilation-targets": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7", + "@babel/compat-data": "^7.17.10", + "@babel/helper-compilation-targets": "^7.18.2", + "@babel/helper-plugin-utils": "^7.17.12", "@babel/helper-validator-option": "^7.16.7", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.16.7", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.16.7", - "@babel/plugin-proposal-async-generator-functions": "^7.16.8", - "@babel/plugin-proposal-class-properties": "^7.16.7", - "@babel/plugin-proposal-class-static-block": "^7.16.7", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.17.12", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.17.12", + "@babel/plugin-proposal-async-generator-functions": "^7.17.12", + "@babel/plugin-proposal-class-properties": "^7.17.12", + "@babel/plugin-proposal-class-static-block": "^7.18.0", "@babel/plugin-proposal-dynamic-import": "^7.16.7", - "@babel/plugin-proposal-export-namespace-from": "^7.16.7", - "@babel/plugin-proposal-json-strings": "^7.16.7", - "@babel/plugin-proposal-logical-assignment-operators": "^7.16.7", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.16.7", + "@babel/plugin-proposal-export-namespace-from": "^7.17.12", + "@babel/plugin-proposal-json-strings": "^7.17.12", + "@babel/plugin-proposal-logical-assignment-operators": "^7.17.12", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.17.12", "@babel/plugin-proposal-numeric-separator": "^7.16.7", - "@babel/plugin-proposal-object-rest-spread": "^7.16.7", + "@babel/plugin-proposal-object-rest-spread": "^7.18.0", "@babel/plugin-proposal-optional-catch-binding": "^7.16.7", - "@babel/plugin-proposal-optional-chaining": "^7.16.7", - "@babel/plugin-proposal-private-methods": "^7.16.11", - "@babel/plugin-proposal-private-property-in-object": "^7.16.7", - "@babel/plugin-proposal-unicode-property-regex": "^7.16.7", + "@babel/plugin-proposal-optional-chaining": "^7.17.12", + "@babel/plugin-proposal-private-methods": "^7.17.12", + "@babel/plugin-proposal-private-property-in-object": "^7.17.12", + "@babel/plugin-proposal-unicode-property-regex": "^7.17.12", "@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.17.12", "@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", @@ -1855,44 +1868,44 @@ "@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.16.7", - "@babel/plugin-transform-async-to-generator": "^7.16.8", + "@babel/plugin-transform-arrow-functions": "^7.17.12", + "@babel/plugin-transform-async-to-generator": "^7.17.12", "@babel/plugin-transform-block-scoped-functions": "^7.16.7", - "@babel/plugin-transform-block-scoping": "^7.16.7", - "@babel/plugin-transform-classes": "^7.16.7", - "@babel/plugin-transform-computed-properties": "^7.16.7", - "@babel/plugin-transform-destructuring": "^7.16.7", + "@babel/plugin-transform-block-scoping": "^7.17.12", + "@babel/plugin-transform-classes": "^7.17.12", + "@babel/plugin-transform-computed-properties": "^7.17.12", + "@babel/plugin-transform-destructuring": "^7.18.0", "@babel/plugin-transform-dotall-regex": "^7.16.7", - "@babel/plugin-transform-duplicate-keys": "^7.16.7", + "@babel/plugin-transform-duplicate-keys": "^7.17.12", "@babel/plugin-transform-exponentiation-operator": "^7.16.7", - "@babel/plugin-transform-for-of": "^7.16.7", + "@babel/plugin-transform-for-of": "^7.18.1", "@babel/plugin-transform-function-name": "^7.16.7", - "@babel/plugin-transform-literals": "^7.16.7", + "@babel/plugin-transform-literals": "^7.17.12", "@babel/plugin-transform-member-expression-literals": "^7.16.7", - "@babel/plugin-transform-modules-amd": "^7.16.7", - "@babel/plugin-transform-modules-commonjs": "^7.16.8", - "@babel/plugin-transform-modules-systemjs": "^7.16.7", - "@babel/plugin-transform-modules-umd": "^7.16.7", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.16.8", - "@babel/plugin-transform-new-target": "^7.16.7", + "@babel/plugin-transform-modules-amd": "^7.18.0", + "@babel/plugin-transform-modules-commonjs": "^7.18.2", + "@babel/plugin-transform-modules-systemjs": "^7.18.0", + "@babel/plugin-transform-modules-umd": "^7.18.0", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.17.12", + "@babel/plugin-transform-new-target": "^7.17.12", "@babel/plugin-transform-object-super": "^7.16.7", - "@babel/plugin-transform-parameters": "^7.16.7", + "@babel/plugin-transform-parameters": "^7.17.12", "@babel/plugin-transform-property-literals": "^7.16.7", - "@babel/plugin-transform-regenerator": "^7.16.7", - "@babel/plugin-transform-reserved-words": "^7.16.7", + "@babel/plugin-transform-regenerator": "^7.18.0", + "@babel/plugin-transform-reserved-words": "^7.17.12", "@babel/plugin-transform-shorthand-properties": "^7.16.7", - "@babel/plugin-transform-spread": "^7.16.7", + "@babel/plugin-transform-spread": "^7.17.12", "@babel/plugin-transform-sticky-regex": "^7.16.7", - "@babel/plugin-transform-template-literals": "^7.16.7", - "@babel/plugin-transform-typeof-symbol": "^7.16.7", + "@babel/plugin-transform-template-literals": "^7.18.2", + "@babel/plugin-transform-typeof-symbol": "^7.17.12", "@babel/plugin-transform-unicode-escapes": "^7.16.7", "@babel/plugin-transform-unicode-regex": "^7.16.7", "@babel/preset-modules": "^0.1.5", - "@babel/types": "^7.16.8", + "@babel/types": "^7.18.2", "babel-plugin-polyfill-corejs2": "^0.3.0", "babel-plugin-polyfill-corejs3": "^0.5.0", "babel-plugin-polyfill-regenerator": "^0.3.0", - "core-js-compat": "^3.20.2", + "core-js-compat": "^3.22.1", "semver": "^6.3.0" }, "engines": { @@ -1919,15 +1932,15 @@ } }, "node_modules/@babel/preset-react": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.16.7.tgz", - "integrity": "sha512-fWpyI8UM/HE6DfPBzD8LnhQ/OcH8AgTaqcqP2nGOXEUV+VKBR5JRN9hCk9ai+zQQ57vtm9oWeXguBCPNUjytgA==", + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.17.12.tgz", + "integrity": "sha512-h5U+rwreXtZaRBEQhW1hOJLMq8XNJBQ/9oymXiCXTuT/0uOwpbT0gUt+sXeOqoXBgNuUKI7TaObVwoEyWkpFgA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-plugin-utils": "^7.17.12", "@babel/helper-validator-option": "^7.16.7", "@babel/plugin-transform-react-display-name": "^7.16.7", - "@babel/plugin-transform-react-jsx": "^7.16.7", + "@babel/plugin-transform-react-jsx": "^7.17.12", "@babel/plugin-transform-react-jsx-development": "^7.16.7", "@babel/plugin-transform-react-pure-annotations": "^7.16.7" }, @@ -1939,14 +1952,14 @@ } }, "node_modules/@babel/preset-typescript": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.16.7.tgz", - "integrity": "sha512-WbVEmgXdIyvzB77AQjGBEyYPZx+8tTsO50XtfozQrkW8QB2rLJpH2lgx0TRw5EJrBxOZQ+wCcyPVQvS8tjEHpQ==", + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.17.12.tgz", + "integrity": "sha512-S1ViF8W2QwAKUGJXxP9NAfNaqGDdEBJKpYkxHf5Yy2C4NPPzXGeR3Lhk7G8xJaaLcFTRfNjVbtbVtm8Gb0mqvg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-plugin-utils": "^7.17.12", "@babel/helper-validator-option": "^7.16.7", - "@babel/plugin-transform-typescript": "^7.16.7" + "@babel/plugin-transform-typescript": "^7.17.12" }, "engines": { "node": ">=6.9.0" @@ -1956,9 +1969,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.17.8", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.8.tgz", - "integrity": "sha512-dQpEpK0O9o6lj6oPu0gRDbbnk+4LeHlNcBpspf6Olzt3GIX4P1lWF1gS+pHLDFlaJvbR6q7jCfQ08zA4QJBnmA==", + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.18.3.tgz", + "integrity": "sha512-38Y8f7YUhce/K7RMwTp7m0uCumpv9hZkitCbBClqQIow1qSbCvGkcegKOXpEWCQLfWmevgRiWokZ1GkpfhbZug==", "dependencies": { "regenerator-runtime": "^0.13.4" }, @@ -1967,9 +1980,9 @@ } }, "node_modules/@babel/runtime-corejs3": { - "version": "7.17.8", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.17.8.tgz", - "integrity": "sha512-ZbYSUvoSF6dXZmMl/CYTMOvzIFnbGfv4W3SEHYgMvNsFTeLaF2gkGAF4K2ddmtSK4Emej+0aYcnSC6N5dPCXUQ==", + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.18.3.tgz", + "integrity": "sha512-l4ddFwrc9rnR+EJsHsh+TJ4A35YqQz/UqcjtlX2ov53hlJYG5CxtQmNZxyajwDVmCxwy++rtvGU5HazCK4W41Q==", "dev": true, "dependencies": { "core-js-pure": "^3.20.2", @@ -1983,7 +1996,7 @@ "version": "7.16.7", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz", "integrity": "sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==", - "dev": true, + "devOptional": true, "dependencies": { "@babel/code-frame": "^7.16.7", "@babel/parser": "^7.16.7", @@ -1994,19 +2007,19 @@ } }, "node_modules/@babel/traverse": { - "version": "7.17.3", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.17.3.tgz", - "integrity": "sha512-5irClVky7TxRWIRtxlh2WPUUOLhcPN06AGgaQSB8AEwuyEBgJVuJ5imdHm5zxk8w0QS5T+tDfnDxAlhWjpb7cw==", - "dev": true, + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.18.2.tgz", + "integrity": "sha512-9eNwoeovJ6KH9zcCNnENY7DMFwTU9JdGCFtqNLfUAqtUHRCOsTOqWoffosP8vKmNYeSBUv3yVJXjfd8ucwOjUA==", + "devOptional": true, "dependencies": { "@babel/code-frame": "^7.16.7", - "@babel/generator": "^7.17.3", - "@babel/helper-environment-visitor": "^7.16.7", - "@babel/helper-function-name": "^7.16.7", + "@babel/generator": "^7.18.2", + "@babel/helper-environment-visitor": "^7.18.2", + "@babel/helper-function-name": "^7.17.9", "@babel/helper-hoist-variables": "^7.16.7", "@babel/helper-split-export-declaration": "^7.16.7", - "@babel/parser": "^7.17.3", - "@babel/types": "^7.17.0", + "@babel/parser": "^7.18.0", + "@babel/types": "^7.18.2", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -2015,10 +2028,10 @@ } }, "node_modules/@babel/types": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz", - "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==", - "dev": true, + "version": "7.18.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.18.4.tgz", + "integrity": "sha512-ThN1mBcMq5pG/Vm2IcBmPPfyPXbd8S02rS+OBIDENdufvqC7Z/jHPCv9IcP01277aKtDI8g/2XysBN4hA8niiw==", + "devOptional": true, "dependencies": { "@babel/helper-validator-identifier": "^7.16.7", "to-fast-properties": "^2.0.0" @@ -2027,61 +2040,10 @@ "node": ">=6.9.0" } }, - "node_modules/@emotion/babel-plugin": { - "version": "11.7.2", - "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.7.2.tgz", - "integrity": "sha512-6mGSCWi9UzXut/ZAN6lGFu33wGR3SJisNl3c0tvlmb8XChH1b2SUvxvnOh7hvLpqyRdHHU9AiazV3Cwbk5SXKQ==", - "dev": true, - "dependencies": { - "@babel/helper-module-imports": "^7.12.13", - "@babel/plugin-syntax-jsx": "^7.12.13", - "@babel/runtime": "^7.13.10", - "@emotion/hash": "^0.8.0", - "@emotion/memoize": "^0.7.5", - "@emotion/serialize": "^1.0.2", - "babel-plugin-macros": "^2.6.1", - "convert-source-map": "^1.5.0", - "escape-string-regexp": "^4.0.0", - "find-root": "^1.1.0", - "source-map": "^0.5.7", - "stylis": "4.0.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@emotion/babel-plugin/node_modules/babel-plugin-macros": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-2.8.0.tgz", - "integrity": "sha512-SEP5kJpfGYqYKpBrj5XU3ahw5p5GOHJ0U5ssOSQ/WBVdwkD2Dzlce95exQTs3jOVWPPKLBN2rlEWkCK7dSmLvg==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.7.2", - "cosmiconfig": "^6.0.0", - "resolve": "^1.12.0" - } - }, - "node_modules/@emotion/babel-plugin/node_modules/cosmiconfig": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", - "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", - "dev": true, - "dependencies": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.1.0", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.7.2" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/@emotion/cache": { "version": "11.7.1", "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.7.1.tgz", "integrity": "sha512-r65Zy4Iljb8oyjtLeCuBH8Qjiy107dOYC6SJq7g7GV5UCQWMObY4SJDPGFjiiVpPrOJ2hmJOoBiYTC7hwx9E2A==", - "dev": true, "dependencies": { "@emotion/memoize": "^0.7.4", "@emotion/sheet": "^1.1.0", @@ -2093,26 +2055,23 @@ "node_modules/@emotion/hash": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.8.0.tgz", - "integrity": "sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==", - "dev": true + "integrity": "sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==" }, "node_modules/@emotion/memoize": { "version": "0.7.5", "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.5.tgz", - "integrity": "sha512-igX9a37DR2ZPGYtV6suZ6whr8pTFtyHL3K/oLUotxpSVO2ASaprmAe2Dkq7tBo7CRY7MMDrAa9nuQP9/YG8FxQ==", - "dev": true + "integrity": "sha512-igX9a37DR2ZPGYtV6suZ6whr8pTFtyHL3K/oLUotxpSVO2ASaprmAe2Dkq7tBo7CRY7MMDrAa9nuQP9/YG8FxQ==" }, "node_modules/@emotion/react": { - "version": "11.8.2", - "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.8.2.tgz", - "integrity": "sha512-+1bcHBaNJv5nkIIgnGKVsie3otS0wF9f1T1hteF3WeVvMNQEtfZ4YyFpnphGoot3ilU/wWMgP2SgIDuHLE/wAA==", - "dev": true, + "version": "11.7.1", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.7.1.tgz", + "integrity": "sha512-DV2Xe3yhkF1yT4uAUoJcYL1AmrnO5SVsdfvu+fBuS7IbByDeTVx9+wFmvx9Idzv7/78+9Mgx2Hcmr7Fex3tIyw==", "dependencies": { "@babel/runtime": "^7.13.10", - "@emotion/babel-plugin": "^11.7.1", "@emotion/cache": "^11.7.1", "@emotion/serialize": "^1.0.2", - "@emotion/utils": "^1.1.0", + "@emotion/sheet": "^1.1.0", + "@emotion/utils": "^1.0.0", "@emotion/weak-memoize": "^0.2.5", "hoist-non-react-statics": "^3.3.1" }, @@ -2133,7 +2092,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.0.2.tgz", "integrity": "sha512-95MgNJ9+/ajxU7QIAruiOAdYNjxZX7G2mhgrtDWswA21VviYIRP1R5QilZ/bDY42xiKsaktP4egJb3QdYQZi1A==", - "dev": true, "dependencies": { "@emotion/hash": "^0.8.0", "@emotion/memoize": "^0.7.4", @@ -2145,41 +2103,37 @@ "node_modules/@emotion/sheet": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.1.0.tgz", - "integrity": "sha512-u0AX4aSo25sMAygCuQTzS+HsImZFuS8llY8O7b9MDRzbJM0kVJlAz6KNDqcG7pOuQZJmj/8X/rAW+66kMnMW+g==", - "dev": true + "integrity": "sha512-u0AX4aSo25sMAygCuQTzS+HsImZFuS8llY8O7b9MDRzbJM0kVJlAz6KNDqcG7pOuQZJmj/8X/rAW+66kMnMW+g==" }, "node_modules/@emotion/unitless": { "version": "0.7.5", "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", - "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==", - "dev": true + "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==" }, "node_modules/@emotion/utils": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.1.0.tgz", - "integrity": "sha512-iRLa/Y4Rs5H/f2nimczYmS5kFJEbpiVvgN3XVfZ022IYhuNA1IRSHEizcof88LtCTXtl9S2Cxt32KgaXEu72JQ==", - "dev": true + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.0.0.tgz", + "integrity": "sha512-mQC2b3XLDs6QCW+pDQDiyO/EdGZYOygE8s5N5rrzjSI4M3IejPE/JPndCBwRT9z982aqQNi6beWs1UeayrQxxA==" }, "node_modules/@emotion/weak-memoize": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.2.5.tgz", - "integrity": "sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA==", - "dev": true + "integrity": "sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA==" }, "node_modules/@eslint/eslintrc": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.1.tgz", - "integrity": "sha512-bxvbYnBPN1Gibwyp6NrpnFzA3YtRL3BBAyEAFVIpNTm2Rn4Vy87GA5M4aSn3InRrlsbX5N0GW7XIx+U4SAEKdQ==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.0.tgz", + "integrity": "sha512-UWW0TMTmk2d7hLcWD1/e2g5HDM/HQ3csaLSqXCfqwh4uNDuNqlaKWXmEsL4Cs41Z0KnILNvwbHAah3C2yt06kw==", "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.3.1", - "globals": "^13.9.0", + "espree": "^9.3.2", + "globals": "^13.15.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", - "minimatch": "^3.0.4", + "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" }, "engines": { @@ -2187,9 +2141,9 @@ } }, "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "13.13.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.13.0.tgz", - "integrity": "sha512-EQ7Q18AJlPwp3vUDL4mKA0KXrXyNIQyWon6T6XQiBQF0XHvRsiCSrWmmeATpUzdJN2HhWZU6Pdl0a9zdep5p6A==", + "version": "13.15.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.15.0.tgz", + "integrity": "sha512-bpzcOlgDhMG070Av0Vy5Owklpv1I6+j96GhUI7Rh7IzDCKLzboflLrrfqMu8NquDbiR4EOQk7XzJwqVJxicxog==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -2214,9 +2168,9 @@ } }, "node_modules/@fontsource/roboto": { - "version": "4.5.5", - "resolved": "https://registry.npmjs.org/@fontsource/roboto/-/roboto-4.5.5.tgz", - "integrity": "sha512-Pe1p+gAO6K0aLxBXlLoJRHVx352tVc/v/7DOnvM3t+FYXb+KUga9aCD1NpnDfd0kKnWXqrZyAXguyyFWDDuphw==", + "version": "4.5.7", + "resolved": "https://registry.npmjs.org/@fontsource/roboto/-/roboto-4.5.7.tgz", + "integrity": "sha512-m57UMER23Mk6Drg9OjtHW1Y+0KPGyZfE5XJoPTOsLARLar6013kJj4X2HICt+iFLJqIgTahA/QAvSn9lwF1EEw==", "dev": true }, "node_modules/@fortawesome/fontawesome-common-types": { @@ -2314,48 +2268,154 @@ "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", "dev": true }, + "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==", + "devOptional": true, + "dependencies": { + "@jridgewell/set-array": "^1.0.0", + "@jridgewell/sourcemap-codec": "^1.4.10" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/@jridgewell/resolve-uri": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.5.tgz", - "integrity": "sha512-VPeQ7+wH0itvQxnG+lIzWgkysKIr3L9sslimFW55rHMdGu/qCQ5z5h9zq4gI8uBtqkpHhsF4Z/OwExufUCThew==", - "dev": true, + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.7.tgz", + "integrity": "sha512-8cXDaBBHOr2pQ7j77Y6Vp5VDT2sIqWyWQ56TjEq4ih/a4iST3dItRe8Q9fp0rrIl9DoKhWQtUQz/YpOxLkXbNA==", + "devOptional": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.1.tgz", + "integrity": "sha512-Ct5MqZkLGEXTVmQYbGtx9SVqD2fqwvdubdps5D3djjAkgkKwT918VNOz65pEHFaYTeWcukmJmH5SwsA9Tn2ObQ==", + "devOptional": true, "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.11", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.11.tgz", - "integrity": "sha512-Fg32GrJo61m+VqYSdRSjRXMjQ06j8YIYfcTqndLYVAaHmroZHLJZCydsWBOTDqXS2v+mjxohBWEMfg97GXmYQg==", - "dev": true + "version": "1.4.13", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.13.tgz", + "integrity": "sha512-GryiOJmNcWbovBxTfZSF71V/mXbgcV3MewDe3kIMCLyIh5e7SKAeUZs+rMnJ8jkMolZ/4/VsdBmMrw3l+VdZ3w==", + "devOptional": true }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.4.tgz", - "integrity": "sha512-vFv9ttIedivx0ux3QSjhgtCVjPZd5l46ZOMDSCwnH1yUO2e964gO8LZGyv2QkqcgR6TnBU1v+1IFqmeoG+0UJQ==", - "dev": true, + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.13.tgz", + "integrity": "sha512-o1xbKhp9qnIAoHJSWd6KlCZfqslL4valSF81H8ImioOAxluWYWOpWkpyktY2vnt4tbrX9XYaxovq6cgowaJp2w==", + "devOptional": true, "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" } }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, + "node_modules/@mantine/core": { + "version": "4.2.7", + "resolved": "https://registry.npmjs.org/@mantine/core/-/core-4.2.7.tgz", + "integrity": "sha512-WlieaDsqsFhtebRhP/pFNCuqTqPCihkNHHPL6tbd02psEqM8crPrktaO9cAJNyHa3Jna8eUthRRMp8737IHDjg==", "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" + "@mantine/styles": "4.2.7", + "@popperjs/core": "^2.9.3", + "@radix-ui/react-scroll-area": "^0.1.1", + "react-popper": "^2.2.5", + "react-textarea-autosize": "^8.3.2" }, - "engines": { - "node": ">= 8" + "peerDependencies": { + "@mantine/hooks": "4.2.7", + "react": ">=16.8.0", + "react-dom": ">=16.8.0" } }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "node_modules/@mantine/dropzone": { + "version": "4.2.7", + "resolved": "https://registry.npmjs.org/@mantine/dropzone/-/dropzone-4.2.7.tgz", + "integrity": "sha512-eQTVX5hClHNYR6UzNa4P559LsbfdqNHJUu/P7TiIvwIHqKRVjDRkuSZMciSpWqBueBfzrdCZQ32exb3l299Xfg==", + "dev": true, + "dependencies": { + "react-dropzone": "^11.4.2" + }, + "peerDependencies": { + "@mantine/core": "4.2.7", + "@mantine/hooks": "4.2.7", + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@mantine/hooks": { + "version": "4.2.7", + "resolved": "https://registry.npmjs.org/@mantine/hooks/-/hooks-4.2.7.tgz", + "integrity": "sha512-lBzoVjiqCCbQyr9YIRReFCo2jSXAZGSOgf1QDVa4rq3BxkwVDBsriHOpvG9h4mq2sWh4sjzPvfgy/OK/e2QpYQ==", + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@mantine/modals": { + "version": "4.2.7", + "resolved": "https://registry.npmjs.org/@mantine/modals/-/modals-4.2.7.tgz", + "integrity": "sha512-BxTqsX/z4fJudYsUQ0dWoman/AQClsXVpeWh9zrceRvJQHdtLjL1H8ZfY8WeXYEwkM5iMelSpz9TTkHx+/Shwg==", + "dev": true, + "peerDependencies": { + "@mantine/core": "4.2.7", + "@mantine/hooks": "4.2.7", + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@mantine/notifications": { + "version": "4.2.7", + "resolved": "https://registry.npmjs.org/@mantine/notifications/-/notifications-4.2.7.tgz", + "integrity": "sha512-vENIJTyCJMt6yDSsTRlyzFo9xFbivssqQoILOhc03nUvNepfiibcNsOvCAen7r3A+BKYgLYxlKxPVNyLtQ4AUA==", + "dev": true, + "dependencies": { + "react-transition-group": "^4.4.2" + }, + "peerDependencies": { + "@mantine/core": "4.2.7", + "@mantine/hooks": "4.2.7", + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@mantine/styles": { + "version": "4.2.7", + "resolved": "https://registry.npmjs.org/@mantine/styles/-/styles-4.2.7.tgz", + "integrity": "sha512-Ox9tgVqACQYAR7U1OvXELIoHUvPQS6ke4hXEa4Lzo6ErPN7kpopbve/HwJbcuipqieomvXkMCY4Fyt1pBt0xSQ==", + "dependencies": { + "@emotion/cache": "11.7.1", + "@emotion/react": "11.7.1", + "@emotion/serialize": "1.0.2", + "@emotion/utils": "1.0.0", + "clsx": "^1.1.1", + "csstype": "3.0.9" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true, "engines": { "node": ">= 8" @@ -2375,61 +2435,146 @@ } }, "node_modules/@popperjs/core": { - "version": "2.11.4", - "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.4.tgz", - "integrity": "sha512-q/ytXxO5NKvyT37pmisQAItCFqA7FD/vNb8dgaJy3/630Fsc+Mz9/9f2SziBoIZ30TJooXyTwZmhi1zjXmObYg==", + "version": "2.11.5", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.5.tgz", + "integrity": "sha512-9X2obfABZuDVLCgPK9aX0a/x4jaOEweTTWE2+9sr0Qqqevj2Uv5XorvusThmc9XGYpS9yI+fhh8RTafBtGposw==", "funding": { "type": "opencollective", "url": "https://opencollective.com/popperjs" } }, - "node_modules/@reduxjs/toolkit": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.8.1.tgz", - "integrity": "sha512-Q6mzbTpO9nOYRnkwpDlFOAbQnd3g7zj7CtHAZWz5SzE5lcV97Tf8f3SzOO8BoPOMYBFgfZaqTUZqgGu+a0+Fng==", - "dev": true, + "node_modules/@radix-ui/number": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-0.1.0.tgz", + "integrity": "sha512-rpf6QiOWLHAkM4FEMYu9i+5Jr8cKT893+R4mPpcdsy4LD7omr9JfdOqj/h/xPA5+EcVrpMMlU6rrRYpUB5UI8g==", + "dependencies": { + "@babel/runtime": "^7.13.10" + } + }, + "node_modules/@radix-ui/primitive": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-0.1.0.tgz", + "integrity": "sha512-tqxZKybwN5Fa3VzZry4G6mXAAb9aAqKmPtnVbZpL0vsBwvOHTBwsjHVPXylocYLwEtBY9SCe665bYnNB515uoA==", + "dependencies": { + "@babel/runtime": "^7.13.10" + } + }, + "node_modules/@radix-ui/react-compose-refs": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-0.1.0.tgz", + "integrity": "sha512-eyclbh+b77k+69Dk72q3694OHrn9B3QsoIRx7ywX341U9RK1ThgQjMFZoPtmZNQTksXHLNEiefR8hGVeFyInGg==", "dependencies": { - "immer": "^9.0.7", - "redux": "^4.1.2", - "redux-thunk": "^2.4.1", - "reselect": "^4.1.5" + "@babel/runtime": "^7.13.10" }, "peerDependencies": { - "react": "^16.9.0 || ^17.0.0 || ^18", - "react-redux": "^7.2.1 || ^8.0.0-beta" + "react": "^16.8 || ^17.0" + } + }, + "node_modules/@radix-ui/react-context": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-0.1.1.tgz", + "integrity": "sha512-PkyVX1JsLBioeu0jB9WvRpDBBLtLZohVDT3BB5CTSJqActma8S8030P57mWZb4baZifMvN7KKWPAA40UmWKkQg==", + "dependencies": { + "@babel/runtime": "^7.13.10" }, - "peerDependenciesMeta": { - "react": { - "optional": true - }, - "react-redux": { - "optional": true - } + "peerDependencies": { + "react": "^16.8 || ^17.0" } }, - "node_modules/@restart/context": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@restart/context/-/context-2.1.4.tgz", - "integrity": "sha512-INJYZQJP7g+IoDUh/475NlGiTeMfwTXUEr3tmRneckHIxNolGOW9CTq83S8cxq0CgJwwcMzMJFchxvlwe7Rk8Q==", + "node_modules/@radix-ui/react-presence": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-0.1.2.tgz", + "integrity": "sha512-3BRlFZraooIUfRlyN+b/Xs5hq1lanOOo/+3h6Pwu2GMFjkGKKa4Rd51fcqGqnVlbr3jYg+WLuGyAV4KlgqwrQw==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "0.1.0", + "@radix-ui/react-use-layout-effect": "0.1.0" + }, "peerDependencies": { - "react": ">=16.3.2" + "react": ">=16.8" } }, - "node_modules/@restart/hooks": { - "version": "0.3.27", - "resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.3.27.tgz", - "integrity": "sha512-s984xV/EapUIfkjlf8wz9weP2O9TNKR96C68FfMEy2bE69+H4cNv3RD4Mf97lW7Htt7PjZrYTjSC8f3SB9VCXw==", + "node_modules/@radix-ui/react-primitive": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-0.1.4.tgz", + "integrity": "sha512-6gSl2IidySupIMJFjYnDIkIWRyQdbu/AHK7rbICPani+LW4b0XdxBXc46og/iZvuwW8pjCS8I2SadIerv84xYA==", "dependencies": { - "dequal": "^2.0.2" + "@babel/runtime": "^7.13.10", + "@radix-ui/react-slot": "0.1.2" }, "peerDependencies": { - "react": ">=16.8.0" + "react": "^16.8 || ^17.0" + } + }, + "node_modules/@radix-ui/react-scroll-area": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-scroll-area/-/react-scroll-area-0.1.4.tgz", + "integrity": "sha512-QHxRsjy+hsHwQYJ9cCNgSJ5+6ioZu1KhwD1UOXoHNciuFGMX08v+uJPKXIz+ySv03Rx6cOz6f/Fk5aPHRMFi/A==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/number": "0.1.0", + "@radix-ui/primitive": "0.1.0", + "@radix-ui/react-compose-refs": "0.1.0", + "@radix-ui/react-context": "0.1.1", + "@radix-ui/react-presence": "0.1.2", + "@radix-ui/react-primitive": "0.1.4", + "@radix-ui/react-use-callback-ref": "0.1.0", + "@radix-ui/react-use-direction": "0.1.0", + "@radix-ui/react-use-layout-effect": "0.1.0" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0" + } + }, + "node_modules/@radix-ui/react-slot": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-0.1.2.tgz", + "integrity": "sha512-ADkqfL+agEzEguU3yS26jfB50hRrwf7U4VTwAOZEmi/g+ITcBWe12yM46ueS/UCIMI9Py+gFUaAdxgxafFvY2Q==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "0.1.0" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0" + } + }, + "node_modules/@radix-ui/react-use-callback-ref": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-0.1.0.tgz", + "integrity": "sha512-Va041McOFFl+aV+sejvl0BS2aeHx86ND9X/rVFmEFQKTXCp6xgUK0NGUAGcgBlIjnJSbMYPGEk1xKSSlVcN2Aw==", + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0" + } + }, + "node_modules/@radix-ui/react-use-direction": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-direction/-/react-use-direction-0.1.0.tgz", + "integrity": "sha512-NajpY/An9TCPSfOVkgWIdXJV+VuWl67PxB6kOKYmtNAFHvObzIoh8o0n9sAuwSAyFCZVq211FEf9gvVDRhOyiA==", + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0" + } + }, + "node_modules/@radix-ui/react-use-layout-effect": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-0.1.0.tgz", + "integrity": "sha512-+wdeS51Y+E1q1Wmd+1xSSbesZkpVj4jsg0BojCbopWvgq5iBvixw5vgemscdh58ep98BwUbsFYnrywFhV9yrVg==", + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0" } }, "node_modules/@rollup/pluginutils": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.2.0.tgz", - "integrity": "sha512-2WUyJNRkyH5p487pGnn4tWAsxhEFKN/pT8CMgHshd5H+IXkOnKvKZwsz5ZWz+YCXkleZRAU5kwbfgF8CPfDRqA==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.2.1.tgz", + "integrity": "sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==", "dev": true, "dependencies": { "estree-walker": "^2.0.1", @@ -2440,28 +2585,20 @@ } }, "node_modules/@rushstack/eslint-patch": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.1.1.tgz", - "integrity": "sha512-BUyKJGdDWqvWC5GEhyOiUrGNi9iJUr4CU0O2WxJL6QJhHeeA/NVBalH+FeK0r/x/W0rPymXt5s78TDS7d6lCwg==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.1.3.tgz", + "integrity": "sha512-WiBSI6JBIhC6LRIsB2Kwh8DsGTlbBU+mLRxJmAe3LjHTdkDpwIbEOZgoXBbZilk/vlfjK8i6nKRAvIRn1XaIMw==", "dev": true }, - "node_modules/@socket.io/base64-arraybuffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@socket.io/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz", - "integrity": "sha512-dOlCBKnDw4iShaIsH/bxujKTM18+2TOAsYz+KSc11Am38H4q5Xw8Bbz97ZYdrVNM+um3p7w86Bvvmcn9q+5+eQ==", - "engines": { - "node": ">= 0.6.0" - } - }, "node_modules/@socket.io/component-emitter": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.0.0.tgz", - "integrity": "sha512-2pTGuibAXJswAPJjaKisthqS/NOK5ypG4LYT6tEAV0S/mxW0zOIvYvGK0V8w8+SHxAm6vRMSjqSalFXeBAqs+Q==" + "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/@testing-library/dom": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.12.0.tgz", - "integrity": "sha512-rBrJk5WjI02X1edtiUcZhgyhgBhiut96r5Jp8J5qktKdcvLcZpKDW8i2hkGMMItxrghjXuQ5AM6aE0imnFawaw==", + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.13.0.tgz", + "integrity": "sha512-9VHgfIatKNXQNaZTtLnalIy0jNZzY35a4S3oi08YAt9Hv1VsfZ/DfA45lM8D/UhtHBGJ4/lGwp0PZkVndRkoOQ==", "dev": true, "dependencies": { "@babel/code-frame": "^7.10.4", @@ -2478,9 +2615,9 @@ } }, "node_modules/@testing-library/jest-dom": { - "version": "5.16.3", - "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.16.3.tgz", - "integrity": "sha512-u5DfKj4wfSt6akfndfu1eG06jsdyA/IUrlX2n3pyq5UXgXMhXY+NJb8eNK/7pqPWAhCKsCGWDdDO0zKMKAYkEA==", + "version": "5.16.4", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.16.4.tgz", + "integrity": "sha512-Gy+IoFutbMQcky0k+bqqumXZ1cTGswLsFqmNLzNdSKkU9KGV2u9oXhukCbbJ9/LRPKiqwxEE8VpV/+YZlfkPUA==", "dev": true, "dependencies": { "@babel/runtime": "^7.9.2", @@ -2513,44 +2650,45 @@ } }, "node_modules/@testing-library/react": { - "version": "12.1.4", - "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-12.1.4.tgz", - "integrity": "sha512-jiPKOm7vyUw311Hn/HlNQ9P8/lHNtArAx0PisXyFixDDvfl8DbD6EUdbshK5eqauvBSvzZd19itqQ9j3nferJA==", + "version": "12.1.5", + "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-12.1.5.tgz", + "integrity": "sha512-OfTXCJUFgjd/digLUuPxa0+/3ZxsQmE7ub9kcbW/wi96Bh3o/p5vrETcBGfP17NWPGqeYYl5LTRpwyGoMC4ysg==", "dev": true, "dependencies": { "@babel/runtime": "^7.12.5", "@testing-library/dom": "^8.0.0", - "@types/react-dom": "*" + "@types/react-dom": "<18.0.0" }, "engines": { "node": ">=12" }, "peerDependencies": { - "react": "*", - "react-dom": "*" + "react": "<18.0.0", + "react-dom": "<18.0.0" } }, "node_modules/@testing-library/react-hooks": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@testing-library/react-hooks/-/react-hooks-7.0.2.tgz", - "integrity": "sha512-dYxpz8u9m4q1TuzfcUApqi8iFfR6R0FaMbr2hjZJy1uC8z+bO/K4v8Gs9eogGKYQop7QsrBTFkv/BCF7MzD2Cg==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@testing-library/react-hooks/-/react-hooks-8.0.0.tgz", + "integrity": "sha512-uZqcgtcUUtw7Z9N32W13qQhVAD+Xki2hxbTR461MKax8T6Jr8nsUvZB+vcBTkzY2nFvsUet434CsgF0ncW2yFw==", "dev": true, "dependencies": { "@babel/runtime": "^7.12.5", - "@types/react": ">=16.9.0", - "@types/react-dom": ">=16.9.0", - "@types/react-test-renderer": ">=16.9.0", "react-error-boundary": "^3.1.0" }, "engines": { "node": ">=12" }, "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0", - "react-test-renderer": ">=16.9.0" + "@types/react": "^16.9.0 || ^17.0.0", + "react": "^16.9.0 || ^17.0.0", + "react-dom": "^16.9.0 || ^17.0.0", + "react-test-renderer": "^16.9.0 || ^17.0.0" }, "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, "react-dom": { "optional": true }, @@ -2560,9 +2698,9 @@ } }, "node_modules/@testing-library/user-event": { - "version": "14.0.4", - "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.0.4.tgz", - "integrity": "sha512-VBZe5lcUsmrQyOwIFvqOxLBoaTw1/Qy4Ek+VgmFYs719bs2SxUp42vbsb7ATlQDkHdj4OIQlucfpwxe5WoG1jA==", + "version": "14.2.0", + "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.2.0.tgz", + "integrity": "sha512-+hIlG4nJS6ivZrKnOP7OGsDu9Fxmryj9vCl8x0ZINtTJcCHs2zLsYif5GzuRiBF2ck5GZG2aQr7Msg+EHlnYVQ==", "dev": true, "engines": { "node": ">=12", @@ -2587,20 +2725,10 @@ "integrity": "sha512-HnYpAE1Y6kRyKM/XkEuiRQhTHvkzMBurTHnpFLYLBGPIylZNPs9jJcuOOYWxPLJCSEtmZT0Y8rHDokKN7rRTig==", "dev": true }, - "node_modules/@types/bootstrap": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/@types/bootstrap/-/bootstrap-4.6.1.tgz", - "integrity": "sha512-Frg9beNcvrS9gouBeJxkAq7UzoWh5W91J6FIIlJYquf9XE7f0lkqn096KjJ0U7Jgo17oNO4pxDICfXvsCotfWQ==", - "dev": true, - "dependencies": { - "@types/jquery": "*", - "popper.js": "^1.14.1" - } - }, "node_modules/@types/chai": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.0.tgz", - "integrity": "sha512-/ceqdqeRraGolFTcfoXNiqjyQhZzbINDngeoAq9GoHa8PPK1yNzTaxWjA6BFWp5Ua9JpXEMSS4s5i9tS0hOJtw==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.1.tgz", + "integrity": "sha512-/zPMqDkzSZ8t3VtxOa4KPq7uzzW978M9Tvh+j7GHKuo6k6GTLxPJ4J5gE5cjfJ26pnXst0N5Hax8Sr0T2Mi9zQ==", "dev": true }, "node_modules/@types/chai-subset": { @@ -2612,84 +2740,16 @@ "@types/chai": "*" } }, - "node_modules/@types/d3-color": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-2.0.3.tgz", - "integrity": "sha512-+0EtEjBfKEDtH9Rk3u3kLOUXM5F+iZK+WvASPb0MhIZl8J8NUvGeZRwKCXl+P3HkYx5TdU4YtcibpqHkSR9n7w==", - "dev": true - }, - "node_modules/@types/d3-interpolate": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-2.0.2.tgz", - "integrity": "sha512-lElyqlUfIPyWG/cD475vl6msPL4aMU7eJvx1//Q177L8mdXoVPFl1djIESF2FKnc0NyaHvQlJpWwKJYwAhUoCw==", - "dev": true, - "dependencies": { - "@types/d3-color": "^2" - } - }, - "node_modules/@types/d3-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-2.0.2.tgz", - "integrity": "sha512-3YHpvDw9LzONaJzejXLOwZ3LqwwkoXb9LI2YN7Hbd6pkGo5nIlJ09ul4bQhBN4hQZJKmUpX8HkVqbzgUKY48cg==", - "dev": true - }, - "node_modules/@types/d3-scale": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-3.3.2.tgz", - "integrity": "sha512-gGqr7x1ost9px3FvIfUMi5XA/F/yAf4UkUDtdQhpH92XCT0Oa7zkkRzY61gPVJq+DxpHn/btouw5ohWkbBsCzQ==", - "dev": true, - "dependencies": { - "@types/d3-time": "^2" - } - }, - "node_modules/@types/d3-shape": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-2.1.3.tgz", - "integrity": "sha512-HAhCel3wP93kh4/rq+7atLdybcESZ5bRHDEZUojClyZWsRuEMo3A52NGYJSh48SxfxEU6RZIVbZL2YFZ2OAlzQ==", - "dev": true, - "dependencies": { - "@types/d3-path": "^2" - } - }, - "node_modules/@types/d3-time": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-2.1.1.tgz", - "integrity": "sha512-9MVYlmIgmRR31C5b4FVSWtuMmBHh2mOWQYfl7XAYOa8dsnb7iEmUmRSWSFgXFtkjxO65d7hTUHQC+RhR/9IWFg==", - "dev": true - }, - "node_modules/@types/hoist-non-react-statics": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz", - "integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==", - "dependencies": { - "@types/react": "*", - "hoist-non-react-statics": "^3.3.0" - } - }, - "node_modules/@types/invariant": { - "version": "2.2.35", - "resolved": "https://registry.npmjs.org/@types/invariant/-/invariant-2.2.35.tgz", - "integrity": "sha512-DxX1V9P8zdJPYQat1gHyY0xj3efl8gnMVjiM9iCY6y27lj+PoQWkgjt8jDqmovPqULkKVpKRg8J36iQiA+EtEg==" - }, "node_modules/@types/jest": { - "version": "27.4.1", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.4.1.tgz", - "integrity": "sha512-23iPJADSmicDVrWk+HT58LMJtzLAnB2AgIzplQuq/bSrGaxCrlvRFjGbXmamnnk/mAmCdLStiGqggu28ocUyiw==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.5.1.tgz", + "integrity": "sha512-fUy7YRpT+rHXto1YlL+J9rs0uLGyiqVt3ZOTQR+4ROc47yNl8WLdVLgUloBRhOxP1PZvguHl44T3H0wAWxahYQ==", "dev": true, "dependencies": { "jest-matcher-utils": "^27.0.0", "pretty-format": "^27.0.0" } }, - "node_modules/@types/jquery": { - "version": "3.5.14", - "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.5.14.tgz", - "integrity": "sha512-X1gtMRMbziVQkErhTQmSe2jFwwENA/Zr+PprCkF63vFq+Yt5PZ4AlKqgmeNlwgn7dhsXEK888eIW2520EpC+xg==", - "dev": true, - "dependencies": { - "@types/sizzle": "*" - } - }, "node_modules/@types/json-schema": { "version": "7.0.11", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", @@ -2699,13 +2759,13 @@ "node_modules/@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", "dev": true }, "node_modules/@types/lodash": { - "version": "4.14.181", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.181.tgz", - "integrity": "sha512-n3tyKthHJbkiWhDZs3DkhkCzt2MexYHXlX0td5iMplyfwketaOeKboEVBqzceH7juqvEg3q5oUoBFxSLu7zFag==", + "version": "4.14.182", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.182.tgz", + "integrity": "sha512-/THyiqyQAP9AfARo4pF+aCGcyiQ94tX/Is2I7HofNRqoYLgN1PBoOWu2/zTA5zMxzP5EFutMtWtGAFRKUe961Q==", "dev": true }, "node_modules/@types/minimatch": { @@ -2715,9 +2775,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "17.0.23", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.23.tgz", - "integrity": "sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==", + "version": "17.0.36", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.36.tgz", + "integrity": "sha512-V3orv+ggDsWVHP99K3JlwtH20R7J4IhI1Kksgc+64q5VxgfRkQG8Ws3MFm/FZOKDYGy9feGFlZ70/HpCNe9QaA==", "dev": true }, "node_modules/@types/parse-json": { @@ -2727,14 +2787,16 @@ "dev": true }, "node_modules/@types/prop-types": { - "version": "15.7.4", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.4.tgz", - "integrity": "sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ==" + "version": "15.7.5", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", + "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==", + "dev": true }, "node_modules/@types/react": { - "version": "17.0.43", - "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.43.tgz", - "integrity": "sha512-8Q+LNpdxf057brvPu1lMtC5Vn7J119xrP1aq4qiaefNioQUYANF/CYeK4NsKorSZyUGJ66g0IM+4bbjwx45o2A==", + "version": "17.0.45", + "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.45.tgz", + "integrity": "sha512-YfhQ22Lah2e3CHPsb93tRwIGNiSwkuz1/blk4e6QrWS0jQzCSNbGLtOEYhPg02W0yGTTmpajp7dCTbBAMN3qsg==", + "dev": true, "dependencies": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -2742,60 +2804,23 @@ } }, "node_modules/@types/react-dom": { - "version": "17.0.14", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.14.tgz", - "integrity": "sha512-H03xwEP1oXmSfl3iobtmQ/2dHF5aBHr8aUMwyGZya6OW45G+xtdzmq6HkncefiBt5JU8DVyaWl/nWZbjZCnzAQ==", - "dev": true, - "dependencies": { - "@types/react": "*" - } - }, - "node_modules/@types/react-helmet": { - "version": "6.1.5", - "resolved": "https://registry.npmjs.org/@types/react-helmet/-/react-helmet-6.1.5.tgz", - "integrity": "sha512-/ICuy7OHZxR0YCAZLNg9r7I9aijWUWvxaPR6uTuyxe8tAj5RL4Sw1+R6NhXUtOsarkGYPmaHdBDvuXh2DIN/uA==", + "version": "17.0.17", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.17.tgz", + "integrity": "sha512-VjnqEmqGnasQKV0CWLevqMTXBYG9GbwuE6x3VetERLh0cq2LTptFE73MrQi2S7GkKXCf2GgwItB/melLnxfnsg==", "dev": true, "dependencies": { - "@types/react": "*" - } - }, - "node_modules/@types/react-redux": { - "version": "7.1.23", - "resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.23.tgz", - "integrity": "sha512-D02o3FPfqQlfu2WeEYwh3x2otYd2Dk1o8wAfsA0B1C2AJEFxE663Ozu7JzuWbznGgW248NaOF6wsqCGNq9d3qw==", - "dependencies": { - "@types/hoist-non-react-statics": "^3.3.0", - "@types/react": "*", - "hoist-non-react-statics": "^3.3.0", - "redux": "^4.0.0" + "@types/react": "^17" } }, "node_modules/@types/react-table": { - "version": "7.7.10", - "resolved": "https://registry.npmjs.org/@types/react-table/-/react-table-7.7.10.tgz", - "integrity": "sha512-yt7FHv/2cFsucStSWLBOB3OmsRZF08DvVHzz8Zg41B4tzRL6pQ+5VYvmhaR1dKS//tDG4UOJ1RQJPEINHYoRtg==", - "dev": true, - "dependencies": { - "@types/react": "*" - } - }, - "node_modules/@types/react-test-renderer": { - "version": "17.0.1", - "resolved": "https://registry.npmjs.org/@types/react-test-renderer/-/react-test-renderer-17.0.1.tgz", - "integrity": "sha512-3Fi2O6Zzq/f3QR9dRnlnHso9bMl7weKCviFmfF6B4LS1Uat6Hkm15k0ZAQuDz+UBq6B3+g+NM6IT2nr5QgPzCw==", + "version": "7.7.12", + "resolved": "https://registry.npmjs.org/@types/react-table/-/react-table-7.7.12.tgz", + "integrity": "sha512-bRUent+NR/WwtDGwI/BqhZ8XnHghwHw0HUKeohzB5xN3K2qKWYE5w19e7GCuOkL1CXD9Gi1HFy7TIm2AvgWUHg==", "dev": true, "dependencies": { "@types/react": "*" } }, - "node_modules/@types/react-transition-group": { - "version": "4.4.4", - "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.4.tgz", - "integrity": "sha512-7gAPz7anVK5xzbeQW9wFBDg7G++aPLAFY0QaSMOou9rJZpbuI58WAuJrgu+qR92l61grlnCUe7AFX8KGahAgug==", - "dependencies": { - "@types/react": "*" - } - }, "node_modules/@types/resize-observer-browser": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/@types/resize-observer-browser/-/resize-observer-browser-0.1.7.tgz", @@ -2805,12 +2830,7 @@ "node_modules/@types/scheduler": { "version": "0.16.2", "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", - "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==" - }, - "node_modules/@types/sizzle": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.3.tgz", - "integrity": "sha512-JYM8x9EGF163bEyhdJBpR2QX1R5naCJHC8ucJylJ3w9/CVBaskdQ8WqBf8MmQrd1kRvp/a4TS8HJ+bxzR7ZJYQ==", + "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==", "dev": true }, "node_modules/@types/testing-library__jest-dom": { @@ -2822,25 +2842,20 @@ "@types/jest": "*" } }, - "node_modules/@types/warning": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/warning/-/warning-3.0.0.tgz", - "integrity": "sha1-DSUBJorY+ZYrdA04fEZU9fjiPlI=" - }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.17.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.17.0.tgz", - "integrity": "sha512-qVstvQilEd89HJk3qcbKt/zZrfBZ+9h2ynpAGlWjWiizA7m/MtLT9RoX6gjtpE500vfIg8jogAkDzdCxbsFASQ==", + "version": "5.27.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.27.0.tgz", + "integrity": "sha512-DDrIA7GXtmHXr1VCcx9HivA39eprYBIFxbQEHI6NyraRDxCGpxAFiYQAT/1Y0vh1C+o2vfBiy4IuPoXxtTZCAQ==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.17.0", - "@typescript-eslint/type-utils": "5.17.0", - "@typescript-eslint/utils": "5.17.0", - "debug": "^4.3.2", + "@typescript-eslint/scope-manager": "5.27.0", + "@typescript-eslint/type-utils": "5.27.0", + "@typescript-eslint/utils": "5.27.0", + "debug": "^4.3.4", "functional-red-black-tree": "^1.0.1", - "ignore": "^5.1.8", + "ignore": "^5.2.0", "regexpp": "^3.2.0", - "semver": "^7.3.5", + "semver": "^7.3.7", "tsutils": "^3.21.0" }, "engines": { @@ -2861,9 +2876,9 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -2876,12 +2891,12 @@ } }, "node_modules/@typescript-eslint/experimental-utils": { - "version": "5.17.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.17.0.tgz", - "integrity": "sha512-U4sM5z0/ymSYqQT6I7lz8l0ZZ9zrya5VIwrwAP5WOJVabVtVsIpTMxPQe+D3qLyePT+VlETUTO2nA1+PufPx9Q==", + "version": "5.27.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.27.0.tgz", + "integrity": "sha512-ZOn342bYh19IYvkiorrqnzNoRAr91h3GiFSSfa4tlHV+R9GgR8SxCwAi8PKMyT8+pfwMxfQdNbwKsMurbF9hzg==", "dev": true, "dependencies": { - "@typescript-eslint/utils": "5.17.0" + "@typescript-eslint/utils": "5.27.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -2895,15 +2910,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "5.17.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.17.0.tgz", - "integrity": "sha512-aRzW9Jg5Rlj2t2/crzhA2f23SIYFlF9mchGudyP0uiD6SenIxzKoLjwzHbafgHn39dNV/TV7xwQkLfFTZlJ4ig==", + "version": "5.27.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.27.0.tgz", + "integrity": "sha512-8oGjQF46c52l7fMiPPvX4It3u3V3JipssqDfHQ2hcR0AeR8Zge+OYyKUCm5b70X72N1qXt0qgHenwN6Gc2SXZA==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.17.0", - "@typescript-eslint/types": "5.17.0", - "@typescript-eslint/typescript-estree": "5.17.0", - "debug": "^4.3.2" + "@typescript-eslint/scope-manager": "5.27.0", + "@typescript-eslint/types": "5.27.0", + "@typescript-eslint/typescript-estree": "5.27.0", + "debug": "^4.3.4" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -2922,13 +2937,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "5.17.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.17.0.tgz", - "integrity": "sha512-062iCYQF/doQ9T2WWfJohQKKN1zmmXVfAcS3xaiialiw8ZUGy05Em6QVNYJGO34/sU1a7a+90U3dUNfqUDHr3w==", + "version": "5.27.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.27.0.tgz", + "integrity": "sha512-VnykheBQ/sHd1Vt0LJ1JLrMH1GzHO+SzX6VTXuStISIsvRiurue/eRkTqSrG0CexHQgKG8shyJfR4o5VYioB9g==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.17.0", - "@typescript-eslint/visitor-keys": "5.17.0" + "@typescript-eslint/types": "5.27.0", + "@typescript-eslint/visitor-keys": "5.27.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -2939,13 +2954,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "5.17.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.17.0.tgz", - "integrity": "sha512-3hU0RynUIlEuqMJA7dragb0/75gZmwNwFf/QJokWzPehTZousP/MNifVSgjxNcDCkM5HI2K22TjQWUmmHUINSg==", + "version": "5.27.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.27.0.tgz", + "integrity": "sha512-vpTvRRchaf628Hb/Xzfek+85o//zEUotr1SmexKvTfs7czXfYjXVT/a5yDbpzLBX1rhbqxjDdr1Gyo0x1Fc64g==", "dev": true, "dependencies": { - "@typescript-eslint/utils": "5.17.0", - "debug": "^4.3.2", + "@typescript-eslint/utils": "5.27.0", + "debug": "^4.3.4", "tsutils": "^3.21.0" }, "engines": { @@ -2965,9 +2980,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "5.17.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.17.0.tgz", - "integrity": "sha512-AgQ4rWzmCxOZLioFEjlzOI3Ch8giDWx8aUDxyNw9iOeCvD3GEYAB7dxWGQy4T/rPVe8iPmu73jPHuaSqcjKvxw==", + "version": "5.27.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.27.0.tgz", + "integrity": "sha512-lY6C7oGm9a/GWhmUDOs3xAVRz4ty/XKlQ2fOLr8GAIryGn0+UBOoJDWyHer3UgrHkenorwvBnphhP+zPmzmw0A==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -2978,17 +2993,17 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.17.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.17.0.tgz", - "integrity": "sha512-X1gtjEcmM7Je+qJRhq7ZAAaNXYhTgqMkR10euC4Si6PIjb+kwEQHSxGazXUQXFyqfEXdkGf6JijUu5R0uceQzg==", + "version": "5.27.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.27.0.tgz", + "integrity": "sha512-QywPMFvgZ+MHSLRofLI7BDL+UczFFHyj0vF5ibeChDAJgdTV8k4xgEwF0geFhVlPc1p8r70eYewzpo6ps+9LJQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.17.0", - "@typescript-eslint/visitor-keys": "5.17.0", - "debug": "^4.3.2", - "globby": "^11.0.4", + "@typescript-eslint/types": "5.27.0", + "@typescript-eslint/visitor-keys": "5.27.0", + "debug": "^4.3.4", + "globby": "^11.1.0", "is-glob": "^4.0.3", - "semver": "^7.3.5", + "semver": "^7.3.7", "tsutils": "^3.21.0" }, "engines": { @@ -3005,9 +3020,9 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -3020,15 +3035,15 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "5.17.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.17.0.tgz", - "integrity": "sha512-DVvndq1QoxQH+hFv+MUQHrrWZ7gQ5KcJzyjhzcqB1Y2Xes1UQQkTRPUfRpqhS8mhTWsSb2+iyvDW1Lef5DD7vA==", + "version": "5.27.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.27.0.tgz", + "integrity": "sha512-nZvCrkIJppym7cIbP3pOwIkAefXOmfGPnCM0LQfzNaKxJHI6VjI8NC662uoiPlaf5f6ymkTy9C3NQXev2mdXmA==", "dev": true, "dependencies": { "@types/json-schema": "^7.0.9", - "@typescript-eslint/scope-manager": "5.17.0", - "@typescript-eslint/types": "5.17.0", - "@typescript-eslint/typescript-estree": "5.17.0", + "@typescript-eslint/scope-manager": "5.27.0", + "@typescript-eslint/types": "5.27.0", + "@typescript-eslint/typescript-estree": "5.27.0", "eslint-scope": "^5.1.1", "eslint-utils": "^3.0.0" }, @@ -3066,13 +3081,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.17.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.17.0.tgz", - "integrity": "sha512-6K/zlc4OfCagUu7Am/BD5k8PSWQOgh34Nrv9Rxe2tBzlJ7uOeJ/h7ugCGDCeEZHT6k2CJBhbk9IsbkPI0uvUkA==", + "version": "5.27.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.27.0.tgz", + "integrity": "sha512-46cYrteA2MrIAjv9ai44OQDUoCZyHeGIc4lsjCUX2WT6r4C+kidz1bNiR4017wHOPUythYeH+Sc7/cFP97KEAA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.17.0", - "eslint-visitor-keys": "^3.0.0" + "@typescript-eslint/types": "5.27.0", + "eslint-visitor-keys": "^3.3.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -3083,18 +3098,18 @@ } }, "node_modules/@vitejs/plugin-react": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-1.3.0.tgz", - "integrity": "sha512-H+yIupjUE4a+E4oeWUv4xUJIMR0DWBIMUG/DYgvj0J9Vu1rdHAlJ5JdbI+N1KDUD7Ee2fZ1DMPZ/NBg6mXtoCw==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-1.3.2.tgz", + "integrity": "sha512-aurBNmMo0kz1O4qRoY+FM4epSA39y3ShWGuqfLRA/3z0oEJAdtoSfgA3aO98/PCCHAqMaduLxIxErWrVKIFzXA==", "dev": true, "dependencies": { - "@babel/core": "^7.17.8", + "@babel/core": "^7.17.10", "@babel/plugin-transform-react-jsx": "^7.17.3", "@babel/plugin-transform-react-jsx-development": "^7.16.7", "@babel/plugin-transform-react-jsx-self": "^7.16.7", "@babel/plugin-transform-react-jsx-source": "^7.16.7", - "@rollup/pluginutils": "^4.2.0", - "react-refresh": "^0.11.0", + "@rollup/pluginutils": "^4.2.1", + "react-refresh": "^0.13.0", "resolve": "^1.22.0" }, "engines": { @@ -3102,15 +3117,15 @@ } }, "node_modules/abab": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", - "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", + "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", "dev": true }, "node_modules/acorn": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", - "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", + "version": "8.7.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz", + "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -3264,14 +3279,14 @@ } }, "node_modules/array-includes": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.4.tgz", - "integrity": "sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.5.tgz", + "integrity": "sha512-iSDYZMMyTPkiFasVqfuAQnWAYcvO/SeBSCGKePoEthjp4LEMTe4uLc7b025o4jAZpHhihh8xPo99TNWUWWkGDQ==", "dev": true, "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1", + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5", "get-intrinsic": "^1.1.1", "is-string": "^1.0.7" }, @@ -3292,14 +3307,15 @@ } }, "node_modules/array.prototype.flat": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.5.tgz", - "integrity": "sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.0.tgz", + "integrity": "sha512-12IUEkHsAhA4DY5s0FPgNXIdc8VRSqD9Zp78a5au9abH/SOBrsp082JOWFNTjkMozh8mqcdiKuaLGhPeYztxSw==", "dev": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.19.0" + "es-abstract": "^1.19.2", + "es-shim-unscopables": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -3309,14 +3325,15 @@ } }, "node_modules/array.prototype.flatmap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.2.5.tgz", - "integrity": "sha512-08u6rVyi1Lj7oqWbS9nUxliETrtIROT4XGTA4D/LWGten6E3ocm7cy9SIrmNHOL5XVbVuckUp3X6Xyg8/zpvHA==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.0.tgz", + "integrity": "sha512-PZC9/8TKAIxcWKdyeb77EzULHPrIX/tIZebLJUQOMR1OwYosT8yggdfWScfTBCDj5utONvOuPQQumYsU2ULbkg==", "dev": true, "dependencies": { - "call-bind": "^1.0.0", + "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.19.0" + "es-abstract": "^1.19.2", + "es-shim-unscopables": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -3346,13 +3363,13 @@ "node_modules/ast-types-flow": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", - "integrity": "sha1-9wtzXGvKGlycItmCw+Oef+ujva0=", + "integrity": "sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==", "dev": true }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", "dev": true }, "node_modules/atob": { @@ -3367,15 +3384,24 @@ "node": ">= 4.5.0" } }, - "node_modules/axe-core": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.4.1.tgz", - "integrity": "sha512-gd1kmb21kwNuWr6BQz8fv6GNECPBnUasepcoLbekws23NVBLODdsClRZ+bQ8+9Uomf3Sm3+Vwn0oYG9NvwnJCw==", + "node_modules/attr-accept": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/attr-accept/-/attr-accept-2.2.2.tgz", + "integrity": "sha512-7prDjvt9HmqiZ0cl5CRjtS84sEyhsHP2coDkaZKRKVfCDo9s7iw7ChVmar78Gu9pC4SoR/28wFu/G5JJhTnqEg==", "dev": true, "engines": { "node": ">=4" } }, + "node_modules/axe-core": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.4.2.tgz", + "integrity": "sha512-LVAaGp/wkkgYJcjmHsoKx4juT1aQvJyPcW09MLCjVTh3V2cc6PnyempiLMNH5iMdfIX/zdbjUx2KDjMLCTdPeA==", + "dev": true, + "engines": { + "node": ">=12" + } + }, "node_modules/axios": { "version": "0.26.1", "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz", @@ -3483,11 +3509,6 @@ "babel-plugin-transform-react-remove-prop-types": "^0.4.24" } }, - "node_modules/backo2": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", - "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=" - }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -3510,20 +3531,6 @@ "node": ">=8" } }, - "node_modules/bootstrap": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.6.1.tgz", - "integrity": "sha512-0dj+VgI9Ecom+rvvpNZ4MUZJz8dcX7WCX+eTID9+/8HgOkv3dsRzi8BGeZJCQU6flWQVYxwTQnEZFrmJSEO7og==", - "dev": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/bootstrap" - }, - "peerDependencies": { - "jquery": "1.9.1 - 3", - "popper.js": "^1.16.1" - } - }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -3567,10 +3574,10 @@ "dev": true }, "node_modules/browserslist": { - "version": "4.20.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.2.tgz", - "integrity": "sha512-CQOBCqp/9pDvDbx3xfMi+86pr4KXIf2FDkTTdeuYw8OxS9t898LA1Khq57gtufFILXpfgsSx5woNgsBgvGjpsA==", - "dev": true, + "version": "4.20.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.3.tgz", + "integrity": "sha512-NBhymBQl1zM0Y5dQT/O+xiLP9/rzOIQdKM/eMJBAq7yBgaB6krIYLGejrwVYnSHZdqjscB1SPuAjHwxjvN6Wdg==", + "devOptional": true, "funding": [ { "type": "opencollective", @@ -3582,10 +3589,10 @@ } ], "dependencies": { - "caniuse-lite": "^1.0.30001317", - "electron-to-chromium": "^1.4.84", + "caniuse-lite": "^1.0.30001332", + "electron-to-chromium": "^1.4.118", "escalade": "^3.1.1", - "node-releases": "^2.0.2", + "node-releases": "^2.0.3", "picocolors": "^1.0.0" }, "bin": { @@ -3618,10 +3625,10 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001324", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001324.tgz", - "integrity": "sha512-/eYp1J6zYh1alySQB4uzYFkLmxxI8tk0kxldbNHXp8+v+rdMKdUBNjRLz7T7fz6Iox+1lIdYpc7rq6ZcXfTukg==", - "dev": true, + "version": "1.0.30001344", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001344.tgz", + "integrity": "sha512-0ZFjnlCaXNOAYcV7i+TtdKBp0L/3XEU2MF/x6Du1lrh+SRX4IfzIVL4HNJg5pB2PmFb8rszIGyOvsZnqqRoc2g==", + "devOptional": true, "funding": [ { "type": "opencollective", @@ -3679,7 +3686,7 @@ "node_modules/check-error": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==", "dev": true, "engines": { "node": "*" @@ -3727,13 +3734,13 @@ "node_modules/classnames": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz", - "integrity": "sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA==" + "integrity": "sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA==", + "dev": true }, "node_modules/clsx": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.1.1.tgz", "integrity": "sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA==", - "dev": true, "engines": { "node": ">=6" } @@ -3780,7 +3787,7 @@ "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, "node_modules/confusing-browser-globals": { "version": "1.0.11", @@ -3792,18 +3799,18 @@ "version": "1.8.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", - "dev": true, + "devOptional": true, "dependencies": { "safe-buffer": "~5.1.1" } }, "node_modules/core-js-compat": { - "version": "3.21.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.21.1.tgz", - "integrity": "sha512-gbgX5AUvMb8gwxC7FLVWYT7Kkgu/y7+h/h1X43yJkNqhlK2fuYyQimqvKGNZFAY6CKii/GFKJ2cp/1/42TN36g==", + "version": "3.22.7", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.22.7.tgz", + "integrity": "sha512-uI9DAQKKiiE/mclIC5g4AjRpio27g+VMRhe6rQoz+q4Wm4L6A/fJhiLtBw+sfOpDG9wZ3O0pxIw7GbfOlBgjOA==", "dev": true, "dependencies": { - "browserslist": "^4.19.1", + "browserslist": "^4.20.3", "semver": "7.0.0" }, "funding": { @@ -3821,9 +3828,9 @@ } }, "node_modules/core-js-pure": { - "version": "3.21.1", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.21.1.tgz", - "integrity": "sha512-12VZfFIu+wyVbBebyHmRTuEE/tZrB4tJToWcwAMcsp3h4+sHR+fMJWbKpYiCRWlhFBq+KNyO8rIV9rTkeVmznQ==", + "version": "3.22.7", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.22.7.tgz", + "integrity": "sha512-wTriFxiZI+C8msGeh7fJcbC/a0V8fdInN1oS2eK79DMBGs8iIJiXhtFJCiT3rBa8w6zroHWW3p8ArlujZ/Mz+w==", "dev": true, "hasInstallScript": true, "funding": { @@ -3881,18 +3888,9 @@ "node_modules/css.escape": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", - "integrity": "sha1-QuJ9T6BK4y+TGktNQZH6nN3ul8s=", + "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==", "dev": true }, - "node_modules/css/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/cssom": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz", @@ -3918,9 +3916,9 @@ "dev": true }, "node_modules/csstype": { - "version": "3.0.11", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.11.tgz", - "integrity": "sha512-sa6P2wJ+CAbgyy4KFssIb/JNMLxFvKF1pCYCSXS8ZMuqZnMsrxqI2E5sPyoTpxoPU/gVZMzr2zjOfg8GIZOMsw==" + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.9.tgz", + "integrity": "sha512-rpw6JPxK6Rfg1zLOYCSwle2GFOOsnjmDYDaBwEcwoOg4qlsIVCN789VkBZDJAGi4T07gI4YSutR43t9Zz4Lzuw==" }, "node_modules/d3-array": { "version": "2.12.1", @@ -4005,14 +4003,27 @@ "dev": true }, "node_modules/data-urls": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-3.0.1.tgz", - "integrity": "sha512-Ds554NeT5Gennfoo9KN50Vh6tpgtvYEwraYjejXnyTpu1C7oXKxdFk75REooENHE8ndTVOJuv+BEs4/J/xcozw==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-3.0.2.tgz", + "integrity": "sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==", "dev": true, "dependencies": { - "abab": "^2.0.3", + "abab": "^2.0.6", "whatwg-mimetype": "^3.0.0", - "whatwg-url": "^10.0.0" + "whatwg-url": "^11.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/data-urls/node_modules/whatwg-url": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", + "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", + "dev": true, + "dependencies": { + "tr46": "^3.0.0", + "webidl-conversions": "^7.0.0" }, "engines": { "node": ">=12" @@ -4049,7 +4060,7 @@ "node_modules/decode-uri-component": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "integrity": "sha512-hjf+xovcEn31w/EUYdTXQh/8smFL/dzYjohQGEIgjyNavaJfBY2p5F527Bo1VPATxv0VYTUC2bOcXvqFwk78Og==", "dev": true, "engines": { "node": ">=0.10" @@ -4074,34 +4085,30 @@ "dev": true }, "node_modules/define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", + "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", "dev": true, "dependencies": { - "object-keys": "^1.0.12" + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" }, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "dev": true, "engines": { "node": ">=0.4.0" } }, - "node_modules/dequal": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.2.tgz", - "integrity": "sha512-q9K8BlJVxK7hQYqa6XISGmBZbtQQWVXSrRrWreHC94rMt1QL/Impruc+7p2CYSYuVIUr+YCt6hjrs1kkdJRTug==", - "engines": { - "node": ">=6" - } - }, "node_modules/detect-node": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", @@ -4141,21 +4148,16 @@ } }, "node_modules/dom-accessibility-api": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.13.tgz", - "integrity": "sha512-R305kwb5CcMDIpSHUnLyIAp7SrSPBx6F0VfQFB3M75xVMHhXJJIdePYgbPPh1o57vCHNu5QztokWUPsLjWzFqw==", - "dev": true - }, - "node_modules/dom-align": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/dom-align/-/dom-align-1.12.2.tgz", - "integrity": "sha512-pHuazgqrsTFrGU2WLDdXxCFabkdQDx72ddkraZNih1KsMcN5qsRSTR9O4VJRlwTPCPb5COYg3LOfiMHHcPInHg==", + "version": "0.5.14", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.14.tgz", + "integrity": "sha512-NMt+m9zFMPZe0JcY9gN224Qvk6qLIdqex29clBvc/y75ZBX9YA9wNK3frsYvu2DI1xcCIwxwnX+TlsJ2DSOADg==", "dev": true }, "node_modules/dom-helpers": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "dev": true, "dependencies": { "@babel/runtime": "^7.8.7", "csstype": "^3.0.2" @@ -4174,10 +4176,10 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.103", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.103.tgz", - "integrity": "sha512-c/uKWR1Z/W30Wy/sx3dkZoj4BijbXX85QKWu9jJfjho3LBAXNEGAEW3oWiGb+dotA6C6BzCTxL2/aLes7jlUeg==", - "dev": true + "version": "1.4.142", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.142.tgz", + "integrity": "sha512-ea8Q1YX0JRp4GylOmX4gFHIizi0j9GfRW4EkaHnkZp0agRCBB4ZGeCv17IEzIvBkiYVwfoKVhKZJbTfqCRdQdg==", + "devOptional": true }, "node_modules/emoji-regex": { "version": "9.2.2", @@ -4195,19 +4197,15 @@ } }, "node_modules/engine.io-client": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.1.1.tgz", - "integrity": "sha512-V05mmDo4gjimYW+FGujoGmmmxRaDsrVr7AXA3ZIfa04MWM1jOfZfUwou0oNqhNwy/votUDvGDt4JA4QF4e0b4g==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.2.2.tgz", + "integrity": "sha512-8ZQmx0LQGRTYkHuogVZuGSpDqYZtCM/nv8zQ68VZ+JkOpazJ7ICdsSpaO6iXwvaU30oFg5QJOJWj8zWqhbKjkQ==", "dependencies": { - "@socket.io/component-emitter": "~3.0.0", + "@socket.io/component-emitter": "~3.1.0", "debug": "~4.3.1", - "engine.io-parser": "~5.0.0", - "has-cors": "1.1.0", - "parseqs": "0.0.6", - "parseuri": "0.0.6", + "engine.io-parser": "~5.0.3", "ws": "~8.2.3", - "xmlhttprequest-ssl": "~2.0.0", - "yeast": "0.1.2" + "xmlhttprequest-ssl": "~2.0.0" } }, "node_modules/engine.io-client/node_modules/ws": { @@ -4231,12 +4229,9 @@ } }, "node_modules/engine.io-parser": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.3.tgz", - "integrity": "sha512-BtQxwF27XUNnSafQLvDi0dQ8s3i6VgzSoQMJacpIcGNrlUdfHSKbgm3jmjCVvQluGzqwujQMPAoMai3oYSTurg==", - "dependencies": { - "@socket.io/base64-arraybuffer": "~1.0.2" - }, + "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" } @@ -4251,31 +4246,34 @@ } }, "node_modules/es-abstract": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.2.tgz", - "integrity": "sha512-gfSBJoZdlL2xRiOCy0g8gLMryhoe1TlimjzU99L/31Z8QEGIhVQI+EWwt5lT+AuU9SnorVupXFqqOGqGfsyO6w==", + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.1.tgz", + "integrity": "sha512-WEm2oBhfoI2sImeM4OF2zE2V3BYdSF+KnSi9Sidz51fQHd7+JuF8Xgcj9/0o+OWeIeIS/MiuNnlruQrJf16GQA==", "dev": true, "dependencies": { "call-bind": "^1.0.2", "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", + "function.prototype.name": "^1.1.5", "get-intrinsic": "^1.1.1", "get-symbol-description": "^1.0.0", "has": "^1.0.3", + "has-property-descriptors": "^1.0.0", "has-symbols": "^1.0.3", "internal-slot": "^1.0.3", "is-callable": "^1.2.4", "is-negative-zero": "^2.0.2", "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.1", + "is-shared-array-buffer": "^1.0.2", "is-string": "^1.0.7", "is-weakref": "^1.0.2", "object-inspect": "^1.12.0", "object-keys": "^1.1.1", "object.assign": "^4.1.2", - "string.prototype.trimend": "^1.0.4", - "string.prototype.trimstart": "^1.0.4", - "unbox-primitive": "^1.0.1" + "regexp.prototype.flags": "^1.4.3", + "string.prototype.trimend": "^1.0.5", + "string.prototype.trimstart": "^1.0.5", + "unbox-primitive": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -4284,6 +4282,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/es-shim-unscopables": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", + "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + } + }, "node_modules/es-to-primitive": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", @@ -4302,9 +4309,9 @@ } }, "node_modules/esbuild": { - "version": "0.14.30", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.30.tgz", - "integrity": "sha512-wCecQSBkIjp2xjuXY+wcXS/PpOQo9rFh4NAKPh4Pm9f3fuLcnxkR0rDzA+mYP88FtXIUcXUyYmaIgfrzRl55jA==", + "version": "0.14.42", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.42.tgz", + "integrity": "sha512-V0uPZotCEHokJdNqyozH6qsaQXqmZEOiZWrXnds/zaH/0SyrIayRXWRB98CENO73MIZ9T3HBIOsmds5twWtmgw==", "dev": true, "hasInstallScript": true, "bin": { @@ -4314,32 +4321,32 @@ "node": ">=12" }, "optionalDependencies": { - "esbuild-android-64": "0.14.30", - "esbuild-android-arm64": "0.14.30", - "esbuild-darwin-64": "0.14.30", - "esbuild-darwin-arm64": "0.14.30", - "esbuild-freebsd-64": "0.14.30", - "esbuild-freebsd-arm64": "0.14.30", - "esbuild-linux-32": "0.14.30", - "esbuild-linux-64": "0.14.30", - "esbuild-linux-arm": "0.14.30", - "esbuild-linux-arm64": "0.14.30", - "esbuild-linux-mips64le": "0.14.30", - "esbuild-linux-ppc64le": "0.14.30", - "esbuild-linux-riscv64": "0.14.30", - "esbuild-linux-s390x": "0.14.30", - "esbuild-netbsd-64": "0.14.30", - "esbuild-openbsd-64": "0.14.30", - "esbuild-sunos-64": "0.14.30", - "esbuild-windows-32": "0.14.30", - "esbuild-windows-64": "0.14.30", - "esbuild-windows-arm64": "0.14.30" + "esbuild-android-64": "0.14.42", + "esbuild-android-arm64": "0.14.42", + "esbuild-darwin-64": "0.14.42", + "esbuild-darwin-arm64": "0.14.42", + "esbuild-freebsd-64": "0.14.42", + "esbuild-freebsd-arm64": "0.14.42", + "esbuild-linux-32": "0.14.42", + "esbuild-linux-64": "0.14.42", + "esbuild-linux-arm": "0.14.42", + "esbuild-linux-arm64": "0.14.42", + "esbuild-linux-mips64le": "0.14.42", + "esbuild-linux-ppc64le": "0.14.42", + "esbuild-linux-riscv64": "0.14.42", + "esbuild-linux-s390x": "0.14.42", + "esbuild-netbsd-64": "0.14.42", + "esbuild-openbsd-64": "0.14.42", + "esbuild-sunos-64": "0.14.42", + "esbuild-windows-32": "0.14.42", + "esbuild-windows-64": "0.14.42", + "esbuild-windows-arm64": "0.14.42" } }, "node_modules/esbuild-android-64": { - "version": "0.14.30", - "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.30.tgz", - "integrity": "sha512-vdJ7t8A8msPfKpYUGUV/KaTQRiZ0vDa2XSTlzXVkGGVHLKPeb85PBUtYJcEgw3htW3IdX5i1t1IMdQCwJJgNAg==", + "version": "0.14.42", + "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.42.tgz", + "integrity": "sha512-P4Y36VUtRhK/zivqGVMqhptSrFILAGlYp0Z8r9UQqHJ3iWztRCNWnlBzD9HRx0DbueXikzOiwyOri+ojAFfW6A==", "cpu": [ "x64" ], @@ -4353,9 +4360,9 @@ } }, "node_modules/esbuild-android-arm64": { - "version": "0.14.30", - "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.30.tgz", - "integrity": "sha512-BdgGfxeA5hBQNErLr7BWJUA8xjflEfyaARICy8e0OJYNSAwDbEzOf8LyiKWSrDcgV129mWhi3VpbNQvOIDEHcg==", + "version": "0.14.42", + "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.42.tgz", + "integrity": "sha512-0cOqCubq+RWScPqvtQdjXG3Czb3AWI2CaKw3HeXry2eoA2rrPr85HF7IpdU26UWdBXgPYtlTN1LUiuXbboROhg==", "cpu": [ "arm64" ], @@ -4369,9 +4376,9 @@ } }, "node_modules/esbuild-darwin-64": { - "version": "0.14.30", - "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.30.tgz", - "integrity": "sha512-VRaOXMMrsG5n53pl4qFZQdXy2+E0NoLP/QH3aDUI0+bQP+ZHDmbINKcDy2IX7GVFI9kqPS18iJNAs5a6/G2LZg==", + "version": "0.14.42", + "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.42.tgz", + "integrity": "sha512-ipiBdCA3ZjYgRfRLdQwP82rTiv/YVMtW36hTvAN5ZKAIfxBOyPXY7Cejp3bMXWgzKD8B6O+zoMzh01GZsCuEIA==", "cpu": [ "x64" ], @@ -4385,9 +4392,9 @@ } }, "node_modules/esbuild-darwin-arm64": { - "version": "0.14.30", - "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.30.tgz", - "integrity": "sha512-qDez+fHMOrO9Oc9qjt/x+sy09RJVh62kik5tVybKRLmezeV4qczM9/sAYY57YN0aWLdHbcCj2YqJUWYJNsgKnw==", + "version": "0.14.42", + "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.42.tgz", + "integrity": "sha512-bU2tHRqTPOaoH/4m0zYHbFWpiYDmaA0gt90/3BMEFaM0PqVK/a6MA2V/ypV5PO0v8QxN6gH5hBPY4YJ2lopXgA==", "cpu": [ "arm64" ], @@ -4401,9 +4408,9 @@ } }, "node_modules/esbuild-freebsd-64": { - "version": "0.14.30", - "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.30.tgz", - "integrity": "sha512-mec1jENcImVVagddZlGWsdAUwBnzR5cgnhzCxv+9fSMxKbx1uZYLLUAnLPp8m/i934zrumR1xGjJ5VoWdPlI2w==", + "version": "0.14.42", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.42.tgz", + "integrity": "sha512-75h1+22Ivy07+QvxHyhVqOdekupiTZVLN1PMwCDonAqyXd8TVNJfIRFrdL8QmSJrOJJ5h8H1I9ETyl2L8LQDaw==", "cpu": [ "x64" ], @@ -4417,9 +4424,9 @@ } }, "node_modules/esbuild-freebsd-arm64": { - "version": "0.14.30", - "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.30.tgz", - "integrity": "sha512-cpjbTs6Iok/AfeB0JgTzyUJTMStC1SQULmany5nHx6S4GTkSgaAHuJzZO0GcVWqghI4e0YL/bjXAhN5Mn6feNw==", + "version": "0.14.42", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.42.tgz", + "integrity": "sha512-W6Jebeu5TTDQMJUJVarEzRU9LlKpNkPBbjqSu+GUPTHDCly5zZEQq9uHkmHHl7OKm+mQ2zFySN83nmfCeZCyNA==", "cpu": [ "arm64" ], @@ -4433,9 +4440,9 @@ } }, "node_modules/esbuild-linux-32": { - "version": "0.14.30", - "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.30.tgz", - "integrity": "sha512-liIONVT4F2kZmOMwtwASqZ8WkIjb5HHBR9HUffdHiuotSTF3CyZO+EJf+Og+SYYuuVIvt0qHNSFjBA/iSESteQ==", + "version": "0.14.42", + "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.42.tgz", + "integrity": "sha512-Ooy/Bj+mJ1z4jlWcK5Dl6SlPlCgQB9zg1UrTCeY8XagvuWZ4qGPyYEWGkT94HUsRi2hKsXvcs6ThTOjBaJSMfg==", "cpu": [ "ia32" ], @@ -4449,9 +4456,9 @@ } }, "node_modules/esbuild-linux-64": { - "version": "0.14.30", - "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.30.tgz", - "integrity": "sha512-LUnpzoMpRqFON5En4qEj6NWiyH6a1K+Y2qYNKrCy5qPTjDoG/EWeqMz69n8Uv7pRuvDKl3FNGJ1dufTrA5i0sw==", + "version": "0.14.42", + "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.42.tgz", + "integrity": "sha512-2L0HbzQfbTuemUWfVqNIjOfaTRt9zsvjnme6lnr7/MO9toz/MJ5tZhjqrG6uDWDxhsaHI2/nsDgrv8uEEN2eoA==", "cpu": [ "x64" ], @@ -4465,9 +4472,9 @@ } }, "node_modules/esbuild-linux-arm": { - "version": "0.14.30", - "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.30.tgz", - "integrity": "sha512-97T+bbXnpqf7mfIG49UR7ZSJFGgvc22byn74qw3Kx2GDCBSQoVFjyWuKOHGXp8nXk3XYrdFF+mQ8yQ7aNsgQvg==", + "version": "0.14.42", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.42.tgz", + "integrity": "sha512-STq69yzCMhdRaWnh29UYrLSr/qaWMm/KqwaRF1pMEK7kDiagaXhSL1zQGXbYv94GuGY/zAwzK98+6idCMUOOCg==", "cpu": [ "arm" ], @@ -4481,9 +4488,9 @@ } }, "node_modules/esbuild-linux-arm64": { - "version": "0.14.30", - "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.30.tgz", - "integrity": "sha512-DHZHn6FK5q/KL0fpNT/0jE38Nnyk2rXxKE9WENi95EXtqfOLPgE8tzjTZQNgpr61R95QX4ymQU26ni3IZk8buQ==", + "version": "0.14.42", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.42.tgz", + "integrity": "sha512-c3Ug3e9JpVr8jAcfbhirtpBauLxzYPpycjWulD71CF6ZSY26tvzmXMJYooQ2YKqDY4e/fPu5K8bm7MiXMnyxuA==", "cpu": [ "arm64" ], @@ -4497,9 +4504,9 @@ } }, "node_modules/esbuild-linux-mips64le": { - "version": "0.14.30", - "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.30.tgz", - "integrity": "sha512-fLUzTFZ7uknC0aPTk7/lM7NmaG/9ZqE3SaHEphcaM009SZK/mDOvZugWi1ss6WGNhk13dUrhkfHcc4FSb9hYhg==", + "version": "0.14.42", + "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.42.tgz", + "integrity": "sha512-QuvpHGbYlkyXWf2cGm51LBCHx6eUakjaSrRpUqhPwjh/uvNUYvLmz2LgPTTPwCqaKt0iwL+OGVL0tXA5aDbAbg==", "cpu": [ "mips64el" ], @@ -4513,9 +4520,9 @@ } }, "node_modules/esbuild-linux-ppc64le": { - "version": "0.14.30", - "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.30.tgz", - "integrity": "sha512-2Oudm2WEfj0dNU9bzIl5L/LrsMEmHWsOsYgJJqu8fDyUDgER+J1d33qz3cUdjsJk7gAENayIxDSpsuCszx0w3A==", + "version": "0.14.42", + "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.42.tgz", + "integrity": "sha512-8ohIVIWDbDT+i7lCx44YCyIRrOW1MYlks9fxTo0ME2LS/fxxdoJBwHWzaDYhjvf8kNpA+MInZvyOEAGoVDrMHg==", "cpu": [ "ppc64" ], @@ -4529,9 +4536,9 @@ } }, "node_modules/esbuild-linux-riscv64": { - "version": "0.14.30", - "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.30.tgz", - "integrity": "sha512-RPMucPW47rV4t2jlelaE948iCRtbZf5RhifxSwzlpM1Mqdyu99MMNK0w4jFreGTmLN+oGomxIOxD6n+2E/XqHw==", + "version": "0.14.42", + "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.42.tgz", + "integrity": "sha512-DzDqK3TuoXktPyG1Lwx7vhaF49Onv3eR61KwQyxYo4y5UKTpL3NmuarHSIaSVlTFDDpcIajCDwz5/uwKLLgKiQ==", "cpu": [ "riscv64" ], @@ -4545,9 +4552,9 @@ } }, "node_modules/esbuild-linux-s390x": { - "version": "0.14.30", - "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.30.tgz", - "integrity": "sha512-OZ68r7ok6qO7hdwrwQn2p5jbIRRcUcVaAykB7e0uCA0ODwfeGunILM6phJtq2Oz4dlEEFvd+tSuma3paQKwt+A==", + "version": "0.14.42", + "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.42.tgz", + "integrity": "sha512-YFRhPCxl8nb//Wn6SiS5pmtplBi4z9yC2gLrYoYI/tvwuB1jldir9r7JwAGy1Ck4D7sE7wBN9GFtUUX/DLdcEQ==", "cpu": [ "s390x" ], @@ -4561,9 +4568,9 @@ } }, "node_modules/esbuild-netbsd-64": { - "version": "0.14.30", - "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.30.tgz", - "integrity": "sha512-iyejQUKn0TzpPkufq8pSCxOg9NheycQbMbPCmjefTe9wYuUlBt1TcHvdoJnYbQzsAhAh1BNq+s0ycRsIJFZzaQ==", + "version": "0.14.42", + "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.42.tgz", + "integrity": "sha512-QYSD2k+oT9dqB/4eEM9c+7KyNYsIPgzYOSrmfNGDIyJrbT1d+CFVKvnKahDKNJLfOYj8N4MgyFaU9/Ytc6w5Vw==", "cpu": [ "x64" ], @@ -4577,9 +4584,9 @@ } }, "node_modules/esbuild-openbsd-64": { - "version": "0.14.30", - "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.30.tgz", - "integrity": "sha512-UyK1MTMcy4j5fH260fsE1o6MVgWNhb62eCK2yCKCRazZv8Nqdc2WiP9ygjWidmEdCDS+A6MuVp9ozk9uoQtQpA==", + "version": "0.14.42", + "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.42.tgz", + "integrity": "sha512-M2meNVIKWsm2HMY7+TU9AxM7ZVwI9havdsw6m/6EzdXysyCFFSoaTQ/Jg03izjCsK17FsVRHqRe26Llj6x0MNA==", "cpu": [ "x64" ], @@ -4593,9 +4600,9 @@ } }, "node_modules/esbuild-sunos-64": { - "version": "0.14.30", - "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.30.tgz", - "integrity": "sha512-aQRtRTNKHB4YuG+xXATe5AoRTNY48IJg5vjE8ElxfmjO9+KdX7MHFkTLhlKevCD6rNANtB3qOlSIeAiXTwHNqw==", + "version": "0.14.42", + "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.42.tgz", + "integrity": "sha512-uXV8TAZEw36DkgW8Ak3MpSJs1ofBb3Smkc/6pZ29sCAN1KzCAQzsje4sUwugf+FVicrHvlamCOlFZIXgct+iqQ==", "cpu": [ "x64" ], @@ -4609,9 +4616,9 @@ } }, "node_modules/esbuild-windows-32": { - "version": "0.14.30", - "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.30.tgz", - "integrity": "sha512-9/fb1tPtpacMqxAXp3fGHowUDg/l9dVch5hKmCLEZC6PdGljh6h372zMdJwYfH0Bd5CCPT0Wx95uycBLJiqpXA==", + "version": "0.14.42", + "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.42.tgz", + "integrity": "sha512-4iw/8qWmRICWi9ZOnJJf9sYt6wmtp3hsN4TdI5NqgjfOkBVMxNdM9Vt3626G1Rda9ya2Q0hjQRD9W1o+m6Lz6g==", "cpu": [ "ia32" ], @@ -4625,9 +4632,9 @@ } }, "node_modules/esbuild-windows-64": { - "version": "0.14.30", - "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.30.tgz", - "integrity": "sha512-DHgITeUhPAnN9I5O6QBa1GVyPOhiYCn4S4TtQr7sO4+X0LNyqnlmA1M0qmGkUdDC1QQfjI8uQ4G/whdWb2pWIQ==", + "version": "0.14.42", + "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.42.tgz", + "integrity": "sha512-j3cdK+Y3+a5H0wHKmLGTJcq0+/2mMBHPWkItR3vytp/aUGD/ua/t2BLdfBIzbNN9nLCRL9sywCRpOpFMx3CxzA==", "cpu": [ "x64" ], @@ -4641,9 +4648,9 @@ } }, "node_modules/esbuild-windows-arm64": { - "version": "0.14.30", - "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.30.tgz", - "integrity": "sha512-F1kLyQH7zSgjh5eLxogGZN7C9+KNs9m+s7Q6WZoMmCWT/6j998zlaoECHyM8izJRRfsvw2eZlEa1jO6/IOU1AQ==", + "version": "0.14.42", + "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.42.tgz", + "integrity": "sha512-+lRAARnF+hf8J0mN27ujO+VbhPbDqJ8rCcJKye4y7YZLV6C4n3pTRThAb388k/zqF5uM0lS5O201u0OqoWSicw==", "cpu": [ "arm64" ], @@ -4660,7 +4667,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true, + "devOptional": true, "engines": { "node": ">=6" } @@ -4702,7 +4709,7 @@ "node_modules/escodegen/node_modules/levn": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", "dev": true, "dependencies": { "prelude-ls": "~1.1.2", @@ -4738,16 +4745,6 @@ "node": ">= 0.8.0" } }, - "node_modules/escodegen/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, - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/escodegen/node_modules/type-check": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", @@ -4761,12 +4758,12 @@ } }, "node_modules/eslint": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.12.0.tgz", - "integrity": "sha512-it1oBL9alZg1S8UycLm5YDMAkIhtH6FtAzuZs6YvoGVldWjbS08BkAdb/ymP9LlAyq8koANu32U7Ib/w+UNh8Q==", + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.16.0.tgz", + "integrity": "sha512-MBndsoXY/PeVTDJeWsYj7kLZ5hQpJOfMYLsF6LicLHQWbRDG19lK5jOix4DPl8yY4SUFcE3txy86OzFLWT+yoA==", "dev": true, "dependencies": { - "@eslint/eslintrc": "^1.2.1", + "@eslint/eslintrc": "^1.3.0", "@humanwhocodes/config-array": "^0.9.2", "ajv": "^6.10.0", "chalk": "^4.0.0", @@ -4777,14 +4774,14 @@ "eslint-scope": "^7.1.1", "eslint-utils": "^3.0.0", "eslint-visitor-keys": "^3.3.0", - "espree": "^9.3.1", + "espree": "^9.3.2", "esquery": "^1.4.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", "functional-red-black-tree": "^1.0.1", "glob-parent": "^6.0.1", - "globals": "^13.6.0", + "globals": "^13.15.0", "ignore": "^5.2.0", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", @@ -4793,7 +4790,7 @@ "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", + "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.1", "regexpp": "^3.2.0", @@ -4813,9 +4810,9 @@ } }, "node_modules/eslint-config-react-app": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/eslint-config-react-app/-/eslint-config-react-app-7.0.0.tgz", - "integrity": "sha512-xyymoxtIt1EOsSaGag+/jmcywRuieQoA2JbPCjnw9HukFj9/97aGPoZVFioaotzk1K5Qt9sHO5EutZbkrAXS0g==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/eslint-config-react-app/-/eslint-config-react-app-7.0.1.tgz", + "integrity": "sha512-K6rNzvkIeHaTd8m/QEh1Zko0KI7BACWkkneSs6s9cKZC/J27X3eZR6Upt1jkmZ/4FK+XUOPPxMEN7+lbUXfSlA==", "dev": true, "dependencies": { "@babel/core": "^7.16.0", @@ -4900,9 +4897,9 @@ } }, "node_modules/eslint-plugin-import": { - "version": "2.25.4", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.25.4.tgz", - "integrity": "sha512-/KJBASVFxpu0xg1kIBn9AUa8hQVnszpwgE7Ld0lKAlx7Ie87yzEzCgSkekt+le/YVhiaosO4Y14GDAOc41nfxA==", + "version": "2.26.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz", + "integrity": "sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==", "dev": true, "dependencies": { "array-includes": "^3.1.4", @@ -4910,14 +4907,14 @@ "debug": "^2.6.9", "doctrine": "^2.1.0", "eslint-import-resolver-node": "^0.3.6", - "eslint-module-utils": "^2.7.2", + "eslint-module-utils": "^2.7.3", "has": "^1.0.3", - "is-core-module": "^2.8.0", + "is-core-module": "^2.8.1", "is-glob": "^4.0.3", - "minimatch": "^3.0.4", + "minimatch": "^3.1.2", "object.values": "^1.1.5", - "resolve": "^1.20.0", - "tsconfig-paths": "^3.12.0" + "resolve": "^1.22.0", + "tsconfig-paths": "^3.14.1" }, "engines": { "node": ">=4" @@ -4950,7 +4947,7 @@ "node_modules/eslint-plugin-import/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true }, "node_modules/eslint-plugin-jest": { @@ -5017,25 +5014,25 @@ } }, "node_modules/eslint-plugin-react": { - "version": "7.29.4", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.29.4.tgz", - "integrity": "sha512-CVCXajliVh509PcZYRFyu/BoUEz452+jtQJq2b3Bae4v3xBUWPLCmtmBM+ZinG4MzwmxJgJ2M5rMqhqLVn7MtQ==", + "version": "7.30.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.30.0.tgz", + "integrity": "sha512-RgwH7hjW48BleKsYyHK5vUAvxtE9SMPDKmcPRQgtRCYaZA0XQPt5FSkrU3nhz5ifzMZcA8opwmRJ2cmOO8tr5A==", "dev": true, "dependencies": { - "array-includes": "^3.1.4", - "array.prototype.flatmap": "^1.2.5", + "array-includes": "^3.1.5", + "array.prototype.flatmap": "^1.3.0", "doctrine": "^2.1.0", "estraverse": "^5.3.0", "jsx-ast-utils": "^2.4.1 || ^3.0.0", "minimatch": "^3.1.2", "object.entries": "^1.1.5", "object.fromentries": "^2.0.5", - "object.hasown": "^1.1.0", + "object.hasown": "^1.1.1", "object.values": "^1.1.5", "prop-types": "^15.8.1", "resolve": "^2.0.0-next.3", "semver": "^6.3.0", - "string.prototype.matchall": "^4.0.6" + "string.prototype.matchall": "^4.0.7" }, "engines": { "node": ">=4" @@ -5045,9 +5042,9 @@ } }, "node_modules/eslint-plugin-react-hooks": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.4.0.tgz", - "integrity": "sha512-U3RVIfdzJaeKDQKEJbz5p3NW8/L80PCATJAfuojwbaEL+gBjfGdhUcGde+WGUW46Q5sr/NgxevsIiDtNXrvZaQ==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.5.0.tgz", + "integrity": "sha512-8k1gRt7D7h03kd+SAAlzXkQwWK22BnK6GKZG+FJA6BAGy22CFvl8kCIXKpVux0cCxMWDQUPqSok0LKaZ0aOcCw==", "dev": true, "engines": { "node": ">=10" @@ -5082,9 +5079,9 @@ } }, "node_modules/eslint-plugin-testing-library": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-testing-library/-/eslint-plugin-testing-library-5.2.0.tgz", - "integrity": "sha512-fYFH8lA1hbc1Epr9laNm/+YIR2d+R7WI8sFz9jIRAUfqCf21Nb5BzZwhNeZlu9wKXwDtuf+hUM5QJxG1PuDsTQ==", + "version": "5.5.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-testing-library/-/eslint-plugin-testing-library-5.5.1.tgz", + "integrity": "sha512-plLEkkbAKBjPxsLj7x4jNapcHAg2ernkQlKKrN2I8NrQwPISZHyCUNvg5Hv3EDqOQReToQb5bnqXYbkijJPE/g==", "dev": true, "dependencies": { "@typescript-eslint/utils": "^5.13.0" @@ -5147,9 +5144,9 @@ } }, "node_modules/eslint/node_modules/globals": { - "version": "13.13.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.13.0.tgz", - "integrity": "sha512-EQ7Q18AJlPwp3vUDL4mKA0KXrXyNIQyWon6T6XQiBQF0XHvRsiCSrWmmeATpUzdJN2HhWZU6Pdl0a9zdep5p6A==", + "version": "13.15.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.15.0.tgz", + "integrity": "sha512-bpzcOlgDhMG070Av0Vy5Owklpv1I6+j96GhUI7Rh7IzDCKLzboflLrrfqMu8NquDbiR4EOQk7XzJwqVJxicxog==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -5174,13 +5171,13 @@ } }, "node_modules/espree": { - "version": "9.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.1.tgz", - "integrity": "sha512-bvdyLmJMfwkV3NCRl5ZhJf22zBFo1y8bYh3VYb+bfzqNB4Je68P2sSuXyuFquzWLebHpNd2/d5uv7yoP9ISnGQ==", + "version": "9.3.2", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.2.tgz", + "integrity": "sha512-D211tC7ZwouTIuY5x9XnS0E9sWNChB7IYKX/Xp5eQj3nFXhqmiUDB9q27y76oFl8jTg3pXcQx/bpxMfs3CIZbA==", "dev": true, "dependencies": { - "acorn": "^8.7.0", - "acorn-jsx": "^5.3.1", + "acorn": "^8.7.1", + "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^3.3.0" }, "engines": { @@ -5326,7 +5323,7 @@ "node_modules/fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, "node_modules/fastq": { @@ -5350,6 +5347,18 @@ "node": "^10.12.0 || >=12.0.0" } }, + "node_modules/file-selector": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/file-selector/-/file-selector-0.4.0.tgz", + "integrity": "sha512-iACCiXeMYOvZqlF1kTiYINzgepRBymz1wwjiuup9u9nayhb6g4fSwiyJ/6adli+EPwrWtpgQAh2PoS7HukEGEg==", + "dev": true, + "dependencies": { + "tslib": "^2.0.3" + }, + "engines": { + "node": ">= 10" + } + }, "node_modules/fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -5362,16 +5371,10 @@ "node": ">=8" } }, - "node_modules/find-root": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", - "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", - "dev": true - }, "node_modules/find-up": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", "dev": true, "dependencies": { "locate-path": "^2.0.0" @@ -5400,9 +5403,9 @@ "dev": true }, "node_modules/follow-redirects": { - "version": "1.14.9", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz", - "integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==", + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz", + "integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==", "funding": [ { "type": "individual", @@ -5435,7 +5438,7 @@ "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, "node_modules/fsevents": { "version": "2.3.2", @@ -5457,17 +5460,44 @@ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "dev": true }, + "node_modules/function.prototype.name": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", + "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.0", + "functions-have-names": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/functional-red-black-tree": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", "dev": true }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true, + "devOptional": true, "engines": { "node": ">=6.9.0" } @@ -5475,7 +5505,7 @@ "node_modules/get-func-name": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", "dev": true, "engines": { "node": "*" @@ -5527,14 +5557,14 @@ } }, "node_modules/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.0.4", + "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" }, @@ -5561,7 +5591,7 @@ "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, + "devOptional": true, "engines": { "node": ">=4" } @@ -5599,19 +5629,14 @@ } }, "node_modules/has-bigints": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", - "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/has-cors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", - "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=" - }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -5621,6 +5646,18 @@ "node": ">=8" } }, + "node_modules/has-property-descriptors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", + "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/has-symbols": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", @@ -5664,11 +5701,6 @@ "react-is": "^16.7.0" } }, - "node_modules/hoist-non-react-statics/node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" - }, "node_modules/html-encoding-sniffer": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", @@ -5696,9 +5728,9 @@ } }, "node_modules/https-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", - "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", "dev": true, "dependencies": { "agent-base": "6", @@ -5718,15 +5750,15 @@ } }, "node_modules/husky": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/husky/-/husky-7.0.4.tgz", - "integrity": "sha512-vbaCKN2QLtP/vD4yvs6iz6hBEo6wkSzs8HpRah1Z6aGmF2KW5PdYuAd7uX5a+OyBZHBhd+TFLqgjUgytQr4RvQ==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/husky/-/husky-8.0.1.tgz", + "integrity": "sha512-xs7/chUH/CKdOCs7Zy0Aev9e/dKOMZf3K1Az1nar3tzlv0jfqnYtu235bstsWTmXOR0EfINrPa97yy4Lz6RiKw==", "dev": true, "bin": { "husky": "lib/bin.js" }, "engines": { - "node": ">=12" + "node": ">=14" }, "funding": { "url": "https://github.com/sponsors/typicode" @@ -5753,20 +5785,10 @@ "node": ">= 4" } }, - "node_modules/immer": { - "version": "9.0.12", - "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.12.tgz", - "integrity": "sha512-lk7UNmSbAukB5B6dh9fnh5D0bJTOFKxVg2cyJWTYrWRfhLrLMBquONcUs3aFq507hNoIZEDDh8lb8UtOizSMhA==", - "dev": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/immer" - } - }, "node_modules/immutable": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.0.0.tgz", - "integrity": "sha512-zIE9hX70qew5qTUjSS7wi1iwj/l7+m54KWU247nhM3v806UdGj1yDndXj+IOYxxtW9zyLI+xqFNZjTuDaLUqFw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.1.0.tgz", + "integrity": "sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==", "dev": true }, "node_modules/import-fresh": { @@ -5788,7 +5810,7 @@ "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, "engines": { "node": ">=0.8.19" @@ -5806,7 +5828,7 @@ "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -5837,18 +5859,10 @@ "integrity": "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==", "dev": true }, - "node_modules/invariant": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", - "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", - "dependencies": { - "loose-envify": "^1.0.0" - } - }, "node_modules/is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", "dev": true }, "node_modules/is-bigint": { @@ -5904,9 +5918,9 @@ } }, "node_modules/is-core-module": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz", - "integrity": "sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==", + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz", + "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==", "dev": true, "dependencies": { "has": "^1.0.3" @@ -5933,7 +5947,7 @@ "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, "engines": { "node": ">=0.10.0" @@ -6078,7 +6092,7 @@ "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, "node_modules/jest-diff": { @@ -6120,13 +6134,6 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jquery": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.0.tgz", - "integrity": "sha512-JVzAR/AjBvVt2BmYhxRCSYysDsPcssdmTFnzyLEts9qNwmjmu4JTAMYubEfwVOSwpQ1I1sKKFcxhZCI2buerfw==", - "dev": true, - "peer": true - }, "node_modules/js-sha3": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", @@ -6199,7 +6206,7 @@ "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true, + "devOptional": true, "bin": { "jsesc": "bin/jsesc" }, @@ -6222,14 +6229,14 @@ "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, "node_modules/json5": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", - "dev": true, + "devOptional": true, "bin": { "json5": "lib/cli.js" }, @@ -6238,9 +6245,9 @@ } }, "node_modules/jsx-ast-utils": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.2.2.tgz", - "integrity": "sha512-HDAyJ4MNQBboGpUnHAVUNJs6X0lh058s6FuixsFGP7MgJYpD6Vasd6nzSG5iIfXu1zAYlHJ/zsOKNlrenTUBnw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.0.tgz", + "integrity": "sha512-XzO9luP6L0xkxwhIJMTJQpZo/eeN60K08jHdexfD569AGxeNug6UketeHXEhROoM8aR7EcUoOQmIhcJQjcuq8Q==", "dev": true, "dependencies": { "array-includes": "^3.1.4", @@ -6259,7 +6266,7 @@ "node_modules/language-tags": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.5.tgz", - "integrity": "sha1-0yHbxNowuovzAk4ED6XBRmH5GTo=", + "integrity": "sha512-qJhlO9cGXi6hBGKoxEG/sKZDAHD5Hnu9Hs4WbOY3pCWXDhw0N8x1NenNzm2EnNLkLkk7J2SdxAkDSbb6ftT+UQ==", "dev": true, "dependencies": { "language-subtag-registry": "~0.3.2" @@ -6299,7 +6306,7 @@ "node_modules/locate-path": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", "dev": true, "dependencies": { "p-locate": "^2.0.0", @@ -6318,7 +6325,7 @@ "node_modules/lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", "dev": true }, "node_modules/lodash.merge": { @@ -6330,7 +6337,7 @@ "node_modules/lodash.pick": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz", - "integrity": "sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM=", + "integrity": "sha512-hXt6Ul/5yWjfklSGvLQl8vM//l3FtyHZeuelpzK6mm99pNvN9yTDruNZPEJZD1oWrqo+izBmB7oUfWgcCX7s4Q==", "dev": true }, "node_modules/loose-envify": { @@ -6368,7 +6375,7 @@ "node_modules/lz-string": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.4.4.tgz", - "integrity": "sha1-wNjq82BZ9wV5bh40SBHPTEmNOiY=", + "integrity": "sha512-0ckx7ZHRPqb0oUm8zNr+90mtf9DQB60H1wMCjBtfi62Kl3a7JbHob6gA2bC+xRvZoOL+1hzUK8jeuEIQE8svEQ==", "dev": true, "bin": { "lz-string": "bin/bin.js" @@ -6383,12 +6390,6 @@ "remove-accents": "0.4.2" } }, - "node_modules/memoize-one": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz", - "integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==", - "dev": true - }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -6479,9 +6480,9 @@ "dev": true }, "node_modules/moment": { - "version": "2.29.1", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", - "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==", + "version": "2.29.3", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.3.tgz", + "integrity": "sha512-c6YRvhEo//6T2Jz/vVtYzqBzwvPT95JBQ+smCytzf7c50oMZRsR/a4w88aD34I+/QVSfnoAnSBFPJHItlOMJVw==", "dev": true, "engines": { "node": "*" @@ -6520,15 +6521,15 @@ "node_modules/nano-time": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/nano-time/-/nano-time-1.0.0.tgz", - "integrity": "sha1-sFVPaa2J4i0JB/ehKwmTpdlhN+8=", + "integrity": "sha512-flnngywOoQ0lLQOTRNexn2gGSNuM9bKj9RZAWSzhQ+UJYaAFG9bac4DW9VHjUAzrOaIcajHybCTHe/bkvozQqA==", "dependencies": { "big-integer": "^1.6.16" } }, "node_modules/nanoid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.2.tgz", - "integrity": "sha512-CuHBogktKwpm5g2sRgv83jEy2ijFzBwMoYA60orPDR7ynsLijJDqgsi4RDGj3OJpy3Ieb+LYwiRmIOGyytgITA==", + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", + "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", "dev": true, "bin": { "nanoid": "bin/nanoid.cjs" @@ -6540,14 +6541,14 @@ "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, "node_modules/node-releases": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.2.tgz", - "integrity": "sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg==", - "dev": true + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.5.tgz", + "integrity": "sha512-U9h1NLROZTq9uE1SNffn6WuPDg8icmi3ns4rEl/oTfIle4iLjTliCzgTsbaIFMq/Xn078/lfY/BL0GWZ+psK4Q==", + "devOptional": true }, "node_modules/normalize-path": { "version": "3.0.0", @@ -6585,9 +6586,9 @@ } }, "node_modules/object-inspect": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", - "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", + "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -6652,13 +6653,13 @@ } }, "node_modules/object.hasown": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.0.tgz", - "integrity": "sha512-MhjYRfj3GBlhSkDHo6QmvgjRLXQ2zndabdf3nX0yTyZK9rPfxb6uRpAac8HXNLy1GpqWtZ81Qh4v3uOls2sRAg==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.1.tgz", + "integrity": "sha512-LYLe4tivNQzq4JdaWW6WO3HMZZJWzkkH8fnI6EebWl0VZth2wL2Lovm74ep2/gZzlaTdV62JZHEqHQ2yVn8Q/A==", "dev": true, "dependencies": { - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -6795,16 +6796,6 @@ "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", "dev": true }, - "node_modules/parseqs": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.6.tgz", - "integrity": "sha512-jeAGzMDbfSHHA091hr0r31eYfTig+29g3GKKE/PPbEQ65X0lmMwlEoqmhzu0iztID5uJpZsFlUPDP8ThPL7M8w==" - }, - "node_modules/parseuri": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.6.tgz", - "integrity": "sha512-AUjen8sAkGgao7UyCX6Ahv0gIK2fABKmYjvP4xmy5JaKvcbTRueIqIPHLAfq30xJddqSE033IOMUSOMCcK3Sow==" - }, "node_modules/path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", @@ -6865,7 +6856,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true + "devOptional": true }, "node_modules/picomatch": { "version": "2.3.1", @@ -6879,21 +6870,10 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/popper.js": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1.tgz", - "integrity": "sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ==", - "deprecated": "You can find the new Popper v2 at @popperjs/core, this package is dedicated to the legacy v1", - "dev": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/popperjs" - } - }, "node_modules/postcss": { - "version": "8.4.12", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.12.tgz", - "integrity": "sha512-lg6eITwYe9v6Hr5CncVbK70SoioNQIq81nsaG86ev5hAidQvmOeETBqs7jm43K2F5/Ley3ytDtriImV6TpNiSg==", + "version": "8.4.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz", + "integrity": "sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==", "dev": true, "funding": [ { @@ -6906,7 +6886,7 @@ } ], "dependencies": { - "nanoid": "^3.3.1", + "nanoid": "^3.3.4", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" }, @@ -6980,6 +6960,12 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/pretty-format/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, "node_modules/pretty-quick": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/pretty-quick/-/pretty-quick-3.1.3.tgz", @@ -7090,34 +7076,13 @@ "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dev": true, "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", "react-is": "^16.13.1" } }, - "node_modules/prop-types-extra": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/prop-types-extra/-/prop-types-extra-1.1.1.tgz", - "integrity": "sha512-59+AHNnHYCdiC+vMwY52WmvP5dM3QLeoumYuEyceQDi9aEhtwN9zIQ2ZNo25sMyXnbh32h+P1ezDsUpUH3JAew==", - "dependencies": { - "react-is": "^16.3.2", - "warning": "^4.0.0" - }, - "peerDependencies": { - "react": ">=0.14.0" - } - }, - "node_modules/prop-types-extra/node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" - }, - "node_modules/prop-types/node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" - }, "node_modules/psl": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", @@ -7172,114 +7137,6 @@ "performance-now": "^2.1.0" } }, - "node_modules/rc-align": { - "version": "4.0.11", - "resolved": "https://registry.npmjs.org/rc-align/-/rc-align-4.0.11.tgz", - "integrity": "sha512-n9mQfIYQbbNTbefyQnRHZPWuTEwG1rY4a9yKlIWHSTbgwI+XUMGRYd0uJ5pE2UbrNX0WvnMBA1zJ3Lrecpra/A==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.10.1", - "classnames": "2.x", - "dom-align": "^1.7.0", - "lodash": "^4.17.21", - "rc-util": "^5.3.0", - "resize-observer-polyfill": "^1.5.1" - }, - "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0" - } - }, - "node_modules/rc-motion": { - "version": "2.4.6", - "resolved": "https://registry.npmjs.org/rc-motion/-/rc-motion-2.4.6.tgz", - "integrity": "sha512-nXIHve2EDQZ8BFHfgJI3HYMMOZ7HGsolCfA9ozP99/gc1UqpgKys1TYrQWdXa2trff0V3JLhgn2zz+w9VsyktA==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.11.1", - "classnames": "^2.2.1", - "rc-util": "^5.19.2" - }, - "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0" - } - }, - "node_modules/rc-slider": { - "version": "9.7.5", - "resolved": "https://registry.npmjs.org/rc-slider/-/rc-slider-9.7.5.tgz", - "integrity": "sha512-LV/MWcXFjco1epPbdw1JlLXlTgmWpB9/Y/P2yinf8Pg3wElHxA9uajN21lJiWtZjf5SCUekfSP6QMJfDo4t1hg==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.10.1", - "classnames": "^2.2.5", - "rc-tooltip": "^5.0.1", - "rc-util": "^5.16.1", - "shallowequal": "^1.1.0" - }, - "engines": { - "node": ">=8.x" - }, - "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0" - } - }, - "node_modules/rc-tooltip": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/rc-tooltip/-/rc-tooltip-5.1.1.tgz", - "integrity": "sha512-alt8eGMJulio6+4/uDm7nvV+rJq9bsfxFDCI0ljPdbuoygUscbsMYb6EQgwib/uqsXQUvzk+S7A59uYHmEgmDA==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.11.2", - "rc-trigger": "^5.0.0" - }, - "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0" - } - }, - "node_modules/rc-trigger": { - "version": "5.2.11", - "resolved": "https://registry.npmjs.org/rc-trigger/-/rc-trigger-5.2.11.tgz", - "integrity": "sha512-YS+BA4P2aqp9qU7dcTQwsK56SOLJk7XDaFynnXg96obJOUVFiQ6Lfomq9em2dlB4uSjd7Z/gjriZdUY8S2CPQw==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.11.2", - "classnames": "^2.2.6", - "rc-align": "^4.0.0", - "rc-motion": "^2.0.0", - "rc-util": "^5.19.2" - }, - "engines": { - "node": ">=8.x" - }, - "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0" - } - }, - "node_modules/rc-util": { - "version": "5.19.3", - "resolved": "https://registry.npmjs.org/rc-util/-/rc-util-5.19.3.tgz", - "integrity": "sha512-S28epi9E2s7Nir05q8Ffl3hzDLwkavTGi0PGH1cTqCmkpG1AeBEuZgQDpksYeU6IgHcds5hWIPE5PUcdFiZl8w==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.12.5", - "react-is": "^16.12.0", - "shallowequal": "^1.1.0" - }, - "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0" - } - }, - "node_modules/rc-util/node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true - }, "node_modules/react": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", @@ -7292,34 +7149,6 @@ "node": ">=0.10.0" } }, - "node_modules/react-bootstrap": { - "version": "1.6.4", - "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-1.6.4.tgz", - "integrity": "sha512-z3BhBD4bEZuLP8VrYqAD7OT7axdcSkkyvWBWnS2U/4MhyabUihrUyucPWkan7aMI1XIHbmH4LCpEtzWGfx/yfA==", - "dependencies": { - "@babel/runtime": "^7.14.0", - "@restart/context": "^2.1.4", - "@restart/hooks": "^0.3.26", - "@types/invariant": "^2.2.33", - "@types/prop-types": "^15.7.3", - "@types/react": ">=16.14.8", - "@types/react-transition-group": "^4.4.1", - "@types/warning": "^3.0.0", - "classnames": "^2.3.1", - "dom-helpers": "^5.2.1", - "invariant": "^2.2.4", - "prop-types": "^15.7.2", - "prop-types-extra": "^1.1.0", - "react-overlays": "^5.1.1", - "react-transition-group": "^4.4.1", - "uncontrollable": "^7.2.1", - "warning": "^4.0.3" - }, - "peerDependencies": { - "react": ">=16.8.0", - "react-dom": ">=16.8.0" - } - }, "node_modules/react-dom": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz", @@ -7333,6 +7162,23 @@ "react": "17.0.2" } }, + "node_modules/react-dropzone": { + "version": "11.7.1", + "resolved": "https://registry.npmjs.org/react-dropzone/-/react-dropzone-11.7.1.tgz", + "integrity": "sha512-zxCMwhfPy1olUEbw3FLNPLhAm/HnaYH5aELIEglRbqabizKAdHs0h+WuyOpmA+v1JXn0++fpQDdNfUagWt5hJQ==", + "dev": true, + "dependencies": { + "attr-accept": "^2.2.2", + "file-selector": "^0.4.0", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">= 10.13" + }, + "peerDependencies": { + "react": ">= 16.8" + } + }, "node_modules/react-error-boundary": { "version": "3.1.4", "resolved": "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-3.1.4.tgz", @@ -7352,57 +7198,37 @@ "node_modules/react-fast-compare": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.0.tgz", - "integrity": "sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA==", - "dev": true - }, - "node_modules/react-helmet": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/react-helmet/-/react-helmet-6.1.0.tgz", - "integrity": "sha512-4uMzEY9nlDlgxr61NL3XbKRy1hEkXmKNXhjbAIOVw5vcFrsdYbH2FEwcNyWvWinl103nXgzYNlns9ca+8kFiWw==", - "dev": true, - "dependencies": { - "object-assign": "^4.1.1", - "prop-types": "^15.7.2", - "react-fast-compare": "^3.1.1", - "react-side-effect": "^2.1.0" - }, - "peerDependencies": { - "react": ">=16.3.0" - } + "integrity": "sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA==" }, "node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, "node_modules/react-lifecycles-compat": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", - "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" + "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==", + "dev": true }, - "node_modules/react-overlays": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/react-overlays/-/react-overlays-5.1.1.tgz", - "integrity": "sha512-eCN2s2/+GVZzpnId4XVWtvDPYYBD2EtOGP74hE+8yDskPzFy9+pV1H3ZZihxuRdEbQzzacySaaDkR7xE0ydl4Q==", + "node_modules/react-popper": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/react-popper/-/react-popper-2.3.0.tgz", + "integrity": "sha512-e1hj8lL3uM+sgSR4Lxzn5h1GxBlpa4CQz0XLF8kx4MDrDRWY0Ena4c97PUeSX9i5W3UAfDP0z0FXCTQkoXUl3Q==", "dependencies": { - "@babel/runtime": "^7.13.8", - "@popperjs/core": "^2.8.6", - "@restart/hooks": "^0.3.26", - "@types/warning": "^3.0.0", - "dom-helpers": "^5.2.0", - "prop-types": "^15.7.2", - "uncontrollable": "^7.2.1", - "warning": "^4.0.3" + "react-fast-compare": "^3.0.1", + "warning": "^4.0.2" }, "peerDependencies": { - "react": ">=16.3.0", - "react-dom": ">=16.3.0" + "@popperjs/core": "^2.0.0", + "react": "^16.8.0 || ^17 || ^18", + "react-dom": "^16.8.0 || ^17 || ^18" } }, "node_modules/react-query": { - "version": "3.34.19", - "resolved": "https://registry.npmjs.org/react-query/-/react-query-3.34.19.tgz", - "integrity": "sha512-JO0Ymi58WKmvnhgg6bGIrYIeKb64KsKaPWo8JcGnmK2jJxAs2XmMBzlP75ZepSU7CHzcsWtIIyhMrLbX3pb/3w==", + "version": "3.39.1", + "resolved": "https://registry.npmjs.org/react-query/-/react-query-3.39.1.tgz", + "integrity": "sha512-qYKT1bavdDiQZbngWZyPotlBVzcBjDYEJg5RQLBa++5Ix5jjfbEYJmHSZRZD+USVHUSvl/ey9Hu+QfF1QAK80A==", "dependencies": { "@babel/runtime": "^7.5.5", "broadcast-channel": "^3.4.1", @@ -7413,31 +7239,7 @@ "url": "https://github.com/sponsors/tannerlinsley" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0" - }, - "peerDependenciesMeta": { - "react-dom": { - "optional": true - }, - "react-native": { - "optional": true - } - } - }, - "node_modules/react-redux": { - "version": "7.2.8", - "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.8.tgz", - "integrity": "sha512-6+uDjhs3PSIclqoCk0kd6iX74gzrGc3W5zcAjbrFgEdIjRSQObdIwfx80unTkVUYvbQ95Y8Av3OvFHq1w5EOUw==", - "dependencies": { - "@babel/runtime": "^7.15.4", - "@types/react-redux": "^7.1.20", - "hoist-non-react-statics": "^3.3.2", - "loose-envify": "^1.4.0", - "prop-types": "^15.7.2", - "react-is": "^17.0.2" - }, - "peerDependencies": { - "react": "^16.8.3 || ^17 || ^18" + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" }, "peerDependenciesMeta": { "react-dom": { @@ -7449,9 +7251,9 @@ } }, "node_modules/react-refresh": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz", - "integrity": "sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A==", + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.13.0.tgz", + "integrity": "sha512-XP8A9BT0CpRBD+NYLLeIhld/RqG9+gktUjW1FkE+Vm7OCinbG1SshcK5tb9ls4kzvjZr9mOQc7HYgBngEyPAXg==", "dev": true, "engines": { "node": ">=0.10.0" @@ -7496,34 +7298,6 @@ "react-dom": ">=16.8" } }, - "node_modules/react-select": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/react-select/-/react-select-5.2.2.tgz", - "integrity": "sha512-miGS2rT1XbFNjduMZT+V73xbJEeMzVkJOz727F6MeAr2hKE0uUSA8Ff7vD44H32x2PD3SRB6OXTY/L+fTV3z9w==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.12.0", - "@emotion/cache": "^11.4.0", - "@emotion/react": "^11.1.1", - "@types/react-transition-group": "^4.4.0", - "memoize-one": "^5.0.0", - "prop-types": "^15.6.0", - "react-transition-group": "^4.3.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0", - "react-dom": "^16.8.0 || ^17.0.0" - } - }, - "node_modules/react-side-effect": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/react-side-effect/-/react-side-effect-2.1.1.tgz", - "integrity": "sha512-2FoTQzRNTncBVtnzxFOk2mCpcfxQpenBMbk5kSVBg5UcPqV9fRbgY2zhb7GTWWOlpFmAxhClBDlIq8Rsubz1yQ==", - "dev": true, - "peerDependencies": { - "react": "^16.3.0 || ^17.0.0" - } - }, "node_modules/react-smooth": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/react-smooth/-/react-smooth-2.0.0.tgz", @@ -7566,22 +7340,39 @@ } }, "node_modules/react-table": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/react-table/-/react-table-7.7.0.tgz", - "integrity": "sha512-jBlj70iBwOTvvImsU9t01LjFjy4sXEtclBovl3mTiqjz23Reu0DKnRza4zlLtOPACx6j2/7MrQIthIK1Wi+LIA==", + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/react-table/-/react-table-7.8.0.tgz", + "integrity": "sha512-hNaz4ygkZO4bESeFfnfOft73iBUj8K5oKi1EcSHPAibEydfsX2MyU6Z8KCr3mv3C9Kqqh71U+DhZkFvibbnPbA==", "dev": true, "funding": { "type": "github", "url": "https://github.com/sponsors/tannerlinsley" }, "peerDependencies": { - "react": "^16.8.3 || ^17.0.0-0" + "react": "^16.8.3 || ^17.0.0-0 || ^18.0.0" + } + }, + "node_modules/react-textarea-autosize": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/react-textarea-autosize/-/react-textarea-autosize-8.3.4.tgz", + "integrity": "sha512-CdtmP8Dc19xL8/R6sWvtknD/eCXkQr30dtvC4VmGInhRsfF8X/ihXCq6+9l9qbxmKRiq407/7z5fxE7cVWQNgQ==", + "dependencies": { + "@babel/runtime": "^7.10.2", + "use-composed-ref": "^1.3.0", + "use-latest": "^1.2.1" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, "node_modules/react-transition-group": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.2.tgz", "integrity": "sha512-/RNYfRAMlZwDSr6z4zNKV6xu53/e2BuaBbGhbyYIXTrmgu/bGHzmqOs7mJSJBHy9Ud+ApHx3QjrkKSp1pxvlFg==", + "dev": true, "dependencies": { "@babel/runtime": "^7.5.5", "dom-helpers": "^5.0.1", @@ -7606,14 +7397,11 @@ } }, "node_modules/recharts": { - "version": "2.1.9", - "resolved": "https://registry.npmjs.org/recharts/-/recharts-2.1.9.tgz", - "integrity": "sha512-VozH5uznUvGqD7n224FGj7cmMAenlS0HPCs+7r2HeeHiQK6un6z0CTZfWVAB860xbcr4m+BN/EGMPZmYWd34Rg==", + "version": "2.1.10", + "resolved": "https://registry.npmjs.org/recharts/-/recharts-2.1.10.tgz", + "integrity": "sha512-me6c8m2Gs88X/nuM2gDSTDIhpSLNMbiTrlE4Cu53hjZNegT3g3xLlTrbYSAQuBCFWuWJAZXCmEuMr6AwizLyaA==", "dev": true, "dependencies": { - "@types/d3-interpolate": "^2.0.0", - "@types/d3-scale": "^3.0.0", - "@types/d3-shape": "^2.0.0", "classnames": "^2.2.5", "d3-interpolate": "^2.0.0", "d3-scale": "^3.0.0", @@ -7643,12 +7431,6 @@ "decimal.js-light": "^2.4.1" } }, - "node_modules/recharts/node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true - }, "node_modules/redent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", @@ -7672,23 +7454,6 @@ "postcss-value-parser": "^3.3.0" } }, - "node_modules/redux": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/redux/-/redux-4.1.2.tgz", - "integrity": "sha512-SH8PglcebESbd/shgf6mii6EIoRM0zrQyjcuQ+ojmfxjTtE0z9Y8pa62iA/OJ58qjP6j27uyW4kUF4jl/jd6sw==", - "dependencies": { - "@babel/runtime": "^7.9.2" - } - }, - "node_modules/redux-thunk": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.4.1.tgz", - "integrity": "sha512-OOYGNY5Jy2TWvTL1KgAlVy6dcx3siPJ1wTq741EPyUKfn6W6nChdICjZwCd0p8AZBs5kWpZlbkXW2nE/zjUa+Q==", - "dev": true, - "peerDependencies": { - "redux": "^4" - } - }, "node_modules/regenerate": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", @@ -7713,22 +7478,23 @@ "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" }, "node_modules/regenerator-transform": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.5.tgz", - "integrity": "sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw==", + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.0.tgz", + "integrity": "sha512-LsrGtPmbYg19bcPHwdtmXwbW+TqNvtY4riE3P83foeHRroMbH6/2ddFBfab3t7kbzc7v7p4wbkIecHImqt0QNg==", "dev": true, "dependencies": { "@babel/runtime": "^7.8.4" } }, "node_modules/regexp.prototype.flags": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.1.tgz", - "integrity": "sha512-pMR7hBVUUGI7PMA37m2ofIdQCsomVnas+Jn5UPGAHQ+/LlwKm/aTLJHdasmHRzlfeZwHiAOaRSo2rbBDm3nNUQ==", + "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==", "dev": true, "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3" + "define-properties": "^1.1.3", + "functions-have-names": "^1.2.2" }, "engines": { "node": ">= 0.4" @@ -7787,7 +7553,7 @@ "node_modules/regjsparser/node_modules/jsesc": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", + "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", "dev": true, "bin": { "jsesc": "bin/jsesc" @@ -7798,12 +7564,6 @@ "resolved": "https://registry.npmjs.org/remove-accents/-/remove-accents-0.4.2.tgz", "integrity": "sha1-CkPTqq4egNuRngeuJUsoXZ4ce7U=" }, - "node_modules/reselect": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.5.tgz", - "integrity": "sha512-uVdlz8J7OO+ASpBYoz1Zypgx0KasCY20H+N8JD13oUMtPvSHQuscrHop4KbXrbsBcdB9Ds7lVK7eRkBIfO43vQ==", - "dev": true - }, "node_modules/resize-observer-polyfill": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz", @@ -7861,9 +7621,9 @@ } }, "node_modules/rollup": { - "version": "2.70.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.70.1.tgz", - "integrity": "sha512-CRYsI5EuzLbXdxC6RnYhOuRdtz4bhejPMSWjsFLfVM/7w/85n2szZv6yExqUXsBdz5KT8eoubeyDUDjhLHEslA==", + "version": "2.75.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.75.4.tgz", + "integrity": "sha512-JgZiJMJkKImMZJ8ZY1zU80Z2bA/TvrL/7D9qcBCrfl2bP+HUaIw0QHUroB4E3gBpFl6CRFM1YxGbuYGtdAswbQ==", "dev": true, "bin": { "rollup": "dist/bin/rollup" @@ -7875,23 +7635,6 @@ "fsevents": "~2.3.2" } }, - "node_modules/rooks": { - "version": "5.11.0", - "resolved": "https://registry.npmjs.org/rooks/-/rooks-5.11.0.tgz", - "integrity": "sha512-acyTuaYbB021hhHAN6uiU6QUUSuGucK9YOU16nOUM0oypqpckYm7nX5v9xnopoX4pNtrxzIM/mtjC8O7fF3/8A==", - "dev": true, - "dependencies": { - "lodash.debounce": "^4.0.8", - "raf": "^3.4.1" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" - } - }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -7919,7 +7662,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true + "devOptional": true }, "node_modules/safer-buffer": { "version": "2.1.2", @@ -7928,9 +7671,9 @@ "dev": true }, "node_modules/sass": { - "version": "1.49.11", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.49.11.tgz", - "integrity": "sha512-wvS/geXgHUGs6A/4ud5BFIWKO1nKd7wYIGimDk4q4GFkJicILActpv9ueMT4eRGSsp1BdKHuw1WwAHXbhsJELQ==", + "version": "1.52.1", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.52.1.tgz", + "integrity": "sha512-fSzYTbr7z8oQnVJ3Acp9hV80dM1fkMN7mSD/25mpcct9F7FPBMOI8krEYALgU1aZoqGhQNhTPsuSmxjnIvAm4Q==", "dev": true, "dependencies": { "chokidar": ">=3.0.0 <4.0.0", @@ -7969,17 +7712,11 @@ "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, + "devOptional": true, "bin": { "semver": "bin/semver.js" } }, - "node_modules/shallowequal": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", - "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==", - "dev": true - }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -8031,27 +7768,25 @@ } }, "node_modules/socket.io-client": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.4.1.tgz", - "integrity": "sha512-N5C/L5fLNha5Ojd7Yeb/puKcPWWcoB/A09fEjjNsg91EDVr5twk/OEyO6VT9dlLSUNY85NpW6KBhVMvaLKQ3vQ==", + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.5.1.tgz", + "integrity": "sha512-e6nLVgiRYatS+AHXnOnGi4ocOpubvOUCGhyWw8v+/FxW8saHkinG6Dfhi9TU0Kt/8mwJIAASxvw6eujQmjdZVA==", "dependencies": { - "@socket.io/component-emitter": "~3.0.0", - "backo2": "~1.0.2", + "@socket.io/component-emitter": "~3.1.0", "debug": "~4.3.2", - "engine.io-client": "~6.1.1", - "parseuri": "0.0.6", - "socket.io-parser": "~4.1.1" + "engine.io-client": "~6.2.1", + "socket.io-parser": "~4.2.0" }, "engines": { "node": ">=10.0.0" } }, "node_modules/socket.io-parser": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.1.2.tgz", - "integrity": "sha512-j3kk71QLJuyQ/hh5F/L2t1goqzdTL0gvDzuhTuNSwihfuFUrcSji0qFZmJJPtG6Rmug153eOPsUizeirf1IIog==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.0.tgz", + "integrity": "sha512-tLfmEwcEwnlQTxFB7jibL/q2+q8dlVQzj4JdRLJ/W/G1+Fu9VSxCx1Lo+n1HvXxKnM//dUuD0xgiA7tQf57Vng==", "dependencies": { - "@socket.io/component-emitter": "~3.0.0", + "@socket.io/component-emitter": "~3.1.0", "debug": "~4.3.1" }, "engines": { @@ -8059,9 +7794,9 @@ } }, "node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "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" @@ -8113,26 +7848,28 @@ } }, "node_modules/string.prototype.trimend": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", - "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz", + "integrity": "sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==", "dev": true, "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3" + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/string.prototype.trimstart": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", - "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz", + "integrity": "sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==", "dev": true, "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3" + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -8195,8 +7932,7 @@ "node_modules/stylis": { "version": "4.0.13", "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.0.13.tgz", - "integrity": "sha512-xGPXiFVl4YED9Jh7Euv2V220mriG9u4B2TA6Ybjc1catrstKD2PpIdU3U0RKpkVBC2EhmL/F0sPCr9vrFTNRag==", - "dev": true + "integrity": "sha512-xGPXiFVl4YED9Jh7Euv2V220mriG9u4B2TA6Ybjc1catrstKD2PpIdU3U0RKpkVBC2EhmL/F0sPCr9vrFTNRag==" }, "node_modules/supports-color": { "version": "7.2.0", @@ -8241,18 +7977,18 @@ "dev": true }, "node_modules/tinypool": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.1.2.tgz", - "integrity": "sha512-fvtYGXoui2RpeMILfkvGIgOVkzJEGediv8UJt7TxdAOY8pnvUkFg/fkvqTfXG9Acc9S17Cnn1S4osDc2164guA==", + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.1.3.tgz", + "integrity": "sha512-2IfcQh7CP46XGWGGbdyO4pjcKqsmVqFAPcXfPxcPXmOWt9cYkTP9HcDmGgsfijYoAEc4z9qcpM/BaBz46Y9/CQ==", "dev": true, "engines": { "node": ">=14.0.0" } }, "node_modules/tinyspy": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-0.3.0.tgz", - "integrity": "sha512-c5uFHqtUp74R2DJE3/Efg0mH5xicmgziaQXMm/LvuuZn3RdpADH32aEGDRyCzObXT1DNfwDMqRQ/Drh1MlO12g==", + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-0.3.2.tgz", + "integrity": "sha512-2+40EP4D3sFYy42UkgkFFB+kiX2Tg3URG/lVvAZFfLxgGpnWl5qQJuBw1gaLttq8UOS+2p3C0WrhJnQigLTT2Q==", "dev": true, "engines": { "node": ">=14.0.0" @@ -8262,7 +7998,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", - "dev": true, + "devOptional": true, "engines": { "node": ">=4" } @@ -8330,9 +8066,9 @@ } }, "node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", "dev": true }, "node_modules/tsutils": { @@ -8350,6 +8086,12 @@ "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", @@ -8384,9 +8126,9 @@ } }, "node_modules/typescript": { - "version": "4.6.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.3.tgz", - "integrity": "sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw==", + "version": "4.7.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.2.tgz", + "integrity": "sha512-Mamb1iX2FDUpcTRzltPxgWMKy3fhg0TN378ylbktPGPK/99KbDtMQ4W1hwgsbPAsG3a0xKa1vmw4VKZQbkvz5A==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -8397,34 +8139,20 @@ } }, "node_modules/unbox-primitive": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", - "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", "dev": true, "dependencies": { - "function-bind": "^1.1.1", - "has-bigints": "^1.0.1", - "has-symbols": "^1.0.2", + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", "which-boxed-primitive": "^1.0.2" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/uncontrollable": { - "version": "7.2.1", - "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-7.2.1.tgz", - "integrity": "sha512-svtcfoTADIB0nT9nltgjujTi7BzVmwjZClOmskKu/E8FW9BXzg9os8OLr4f8Dlnk0rYWJIWr4wv9eKUXiQvQwQ==", - "dependencies": { - "@babel/runtime": "^7.6.3", - "@types/react": ">=16.9.11", - "invariant": "^2.2.4", - "react-lifecycles-compat": "^3.0.4" - }, - "peerDependencies": { - "react": ">=15.0.0" - } - }, "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", @@ -8492,6 +8220,43 @@ "punycode": "^2.1.0" } }, + "node_modules/use-composed-ref": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/use-composed-ref/-/use-composed-ref-1.3.0.tgz", + "integrity": "sha512-GLMG0Jc/jiKov/3Ulid1wbv3r54K9HlMW29IWcDFPEqFkSO2nS0MuefWgMJpeHQ9YJeXDL3ZUF+P3jdXlZX/cQ==", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/use-isomorphic-layout-effect": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz", + "integrity": "sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/use-latest": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/use-latest/-/use-latest-1.2.1.tgz", + "integrity": "sha512-xA+AVm/Wlg3e2P/JiItTziwS7FK92LWrDB0p+hgXloIMuVCeJJ8v6f0eeHyPZaJrM+usM1FkFfbNCrJGs8A/zw==", + "dependencies": { + "use-isomorphic-layout-effect": "^1.1.1" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/v8-compile-cache": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", @@ -8499,13 +8264,13 @@ "dev": true }, "node_modules/vite": { - "version": "2.9.1", - "resolved": "https://registry.npmjs.org/vite/-/vite-2.9.1.tgz", - "integrity": "sha512-vSlsSdOYGcYEJfkQ/NeLXgnRv5zZfpAsdztkIrs7AZHV8RCMZQkwjo4DS5BnrYTqoWqLoUe1Cah4aVO4oNNqCQ==", + "version": "2.9.9", + "resolved": "https://registry.npmjs.org/vite/-/vite-2.9.9.tgz", + "integrity": "sha512-ffaam+NgHfbEmfw/Vuh6BHKKlI/XIAhxE5QSS7gFLIngxg171mg1P3a4LSRME0z2ZU1ScxoKzphkipcYwSD5Ew==", "dev": true, "dependencies": { "esbuild": "^0.14.27", - "postcss": "^8.4.12", + "postcss": "^8.4.13", "resolve": "^1.22.0", "rollup": "^2.59.0" }, @@ -8536,9 +8301,9 @@ } }, "node_modules/vite-plugin-checker": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/vite-plugin-checker/-/vite-plugin-checker-0.4.4.tgz", - "integrity": "sha512-bduh+oPybN0PIBCcAlIe8WlgG5P5WPVK0P43dB3jljsA/pR/Jp7BTXrflPdlWXxuQFdDasyOCVWpEVs1Zt+8yw==", + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/vite-plugin-checker/-/vite-plugin-checker-0.4.6.tgz", + "integrity": "sha512-oFel33hlsc8aUspfq0ThQRpWsfrG772fmZ5qPHKUhmew6ieejd2viITlwXHIRBY6hE3U0kirXoTWwft3DdbK+g==", "dev": true, "dependencies": { "@babel/code-frame": "^7.12.13", @@ -8565,18 +8330,19 @@ } }, "node_modules/vitest": { - "version": "0.8.4", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-0.8.4.tgz", - "integrity": "sha512-1OoAG1+VYkzp4WLCVQFRJX/OKk70rsMIM5H23crfc1wSEnJvHlxgQBS1HPpV/VYmjC8bIInKWhnB4Gaw32MnyQ==", + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-0.13.0.tgz", + "integrity": "sha512-vuYt3+G25MMnANgyMHHG3VK86C9K/VFi/8uH5myQ2v660W4WArv99ElakPlVFxxSXXM1jqQPiPj2ht35Bod9LQ==", "dev": true, "dependencies": { - "@types/chai": "^4.3.0", + "@types/chai": "^4.3.1", "@types/chai-subset": "^1.3.3", "chai": "^4.3.6", + "debug": "^4.3.4", "local-pkg": "^0.4.1", - "tinypool": "^0.1.2", - "tinyspy": "^0.3.0", - "vite": "^2.8.6" + "tinypool": "^0.1.3", + "tinyspy": "^0.3.2", + "vite": "^2.9.9" }, "bin": { "vitest": "vitest.mjs" @@ -8632,9 +8398,9 @@ } }, "node_modules/vscode-languageclient/node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -8669,9 +8435,9 @@ } }, "node_modules/vscode-languageserver-textdocument": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.4.tgz", - "integrity": "sha512-/xhqXP/2A2RSs+J8JNXpiiNVvvNM0oTosNVmQnunlKvq9o4mupHOBAnnzH0lwIPKazXKvAKsVp1kr+H/K4lgoQ==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.5.tgz", + "integrity": "sha512-1ah7zyQjKBudnMiHbZmxz5bYNM9KKZYz+5VQLj+yr8l+9w3g+WAhCkUkWbhMEdC5u0ub4Ndiye/fDyS8ghIKQg==", "dev": true }, "node_modules/vscode-languageserver-types": { @@ -8804,9 +8570,9 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, "node_modules/ws": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.5.0.tgz", - "integrity": "sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==", + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.7.0.tgz", + "integrity": "sha512-c2gsP0PRwcLFzUiA8Mkr37/MI7ilIlHQxaEAtd0uNMbVMoy8puJyafRlm0bV9MbGSabUPeLrRRaqIBcFcA2Pqg==", "dev": true, "engines": { "node": ">=10.0.0" @@ -8861,65 +8627,61 @@ "engines": { "node": ">= 6" } - }, - "node_modules/yeast": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", - "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=" } }, "dependencies": { "@ampproject/remapping": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.1.2.tgz", - "integrity": "sha512-hoyByceqwKirw7w3Z7gnIIZC3Wx3J484Y3L/cMpXFbr7d9ZQj2mODrirNzcJa+SM3UlpWXYvKV4RlRpFXlWgXg==", - "dev": true, + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", + "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", + "devOptional": true, "requires": { - "@jridgewell/trace-mapping": "^0.3.0" + "@jridgewell/gen-mapping": "^0.1.0", + "@jridgewell/trace-mapping": "^0.3.9" } }, "@babel/code-frame": { "version": "7.16.7", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", - "dev": true, + "devOptional": true, "requires": { "@babel/highlight": "^7.16.7" } }, "@babel/compat-data": { - "version": "7.17.7", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.17.7.tgz", - "integrity": "sha512-p8pdE6j0a29TNGebNm7NzYZWB3xVZJBZ7XGs42uAKzQo8VQ3F0By/cQCtUEABwIqw5zo6WA4NbmxsfzADzMKnQ==", - "dev": true + "version": "7.17.10", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.17.10.tgz", + "integrity": "sha512-GZt/TCsG70Ms19gfZO1tM4CVnXsPgEPBCpJu+Qz3L0LUDsY5nZqFZglIoPC1kIYOtNBZlrnFT+klg12vFGZXrw==", + "devOptional": true }, "@babel/core": { - "version": "7.17.8", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.17.8.tgz", - "integrity": "sha512-OdQDV/7cRBtJHLSOBqqbYNkOcydOgnX59TZx4puf41fzcVtN3e/4yqY8lMQsK+5X2lJtAdmA+6OHqsj1hBJ4IQ==", - "dev": true, + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.18.2.tgz", + "integrity": "sha512-A8pri1YJiC5UnkdrWcmfZTJTV85b4UXTAfImGmCfYmax4TR9Cw8sDS0MOk++Gp2mE/BefVJ5nwy5yzqNJbP/DQ==", + "devOptional": true, "requires": { "@ampproject/remapping": "^2.1.0", "@babel/code-frame": "^7.16.7", - "@babel/generator": "^7.17.7", - "@babel/helper-compilation-targets": "^7.17.7", - "@babel/helper-module-transforms": "^7.17.7", - "@babel/helpers": "^7.17.8", - "@babel/parser": "^7.17.8", + "@babel/generator": "^7.18.2", + "@babel/helper-compilation-targets": "^7.18.2", + "@babel/helper-module-transforms": "^7.18.0", + "@babel/helpers": "^7.18.2", + "@babel/parser": "^7.18.0", "@babel/template": "^7.16.7", - "@babel/traverse": "^7.17.3", - "@babel/types": "^7.17.0", + "@babel/traverse": "^7.18.2", + "@babel/types": "^7.18.2", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", - "json5": "^2.1.2", + "json5": "^2.2.1", "semver": "^6.3.0" } }, "@babel/eslint-parser": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.17.0.tgz", - "integrity": "sha512-PUEJ7ZBXbRkbq3qqM/jZ2nIuakUBqCYc7Qf52Lj7dlZ6zERnqisdHioL0l4wwQZnmskMeasqUNzLBFKs3nylXA==", + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.18.2.tgz", + "integrity": "sha512-oFQYkE8SuH14+uR51JVAmdqwKYXGRjEXx7s+WiagVjqQ+HPE+nnwyF2qlVG8evUsUHmPcA+6YXMEDbIhEyQc5A==", "dev": true, "requires": { "eslint-scope": "^5.1.1", @@ -8952,14 +8714,27 @@ } }, "@babel/generator": { - "version": "7.17.7", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.17.7.tgz", - "integrity": "sha512-oLcVCTeIFadUoArDTwpluncplrYBmTCCZZgXCbgNGvOBBiSDDK3eWO4b/+eOTli5tKv1lg+a5/NAXg+nTcei1w==", - "dev": true, + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.18.2.tgz", + "integrity": "sha512-W1lG5vUwFvfMd8HVXqdfbuG7RuaSrTCCD8cl8fP8wOivdbtbIg2Db3IWUcgvfxKbbn6ZBGYRW/Zk1MIwK49mgw==", + "devOptional": true, "requires": { - "@babel/types": "^7.17.0", - "jsesc": "^2.5.1", - "source-map": "^0.5.0" + "@babel/types": "^7.18.2", + "@jridgewell/gen-mapping": "^0.3.0", + "jsesc": "^2.5.1" + }, + "dependencies": { + "@jridgewell/gen-mapping": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.1.tgz", + "integrity": "sha512-GcHwniMlA2z+WFPWuY8lp3fsza0I8xPFMWL5+n8LYyP6PSvPrXf4+n8stDHZY2DM0zy9sVkRDy1jDI4XGzYVqg==", + "devOptional": true, + "requires": { + "@jridgewell/set-array": "^1.0.0", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + } + } } }, "@babel/helper-annotate-as-pure": { @@ -8982,36 +8757,36 @@ } }, "@babel/helper-compilation-targets": { - "version": "7.17.7", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.17.7.tgz", - "integrity": "sha512-UFzlz2jjd8kroj0hmCFV5zr+tQPi1dpC2cRsDV/3IEW8bJfCPrPpmcSN6ZS8RqIq4LXcmpipCQFPddyFA5Yc7w==", - "dev": true, + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.18.2.tgz", + "integrity": "sha512-s1jnPotJS9uQnzFtiZVBUxe67CuBa679oWFHpxYYnTpRL/1ffhyX44R9uYiXoa/pLXcY9H2moJta0iaanlk/rQ==", + "devOptional": true, "requires": { - "@babel/compat-data": "^7.17.7", + "@babel/compat-data": "^7.17.10", "@babel/helper-validator-option": "^7.16.7", - "browserslist": "^4.17.5", + "browserslist": "^4.20.2", "semver": "^6.3.0" } }, "@babel/helper-create-class-features-plugin": { - "version": "7.17.6", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.17.6.tgz", - "integrity": "sha512-SogLLSxXm2OkBbSsHZMM4tUi8fUzjs63AT/d0YQIzr6GSd8Hxsbk2KYDX0k0DweAzGMj/YWeiCsorIdtdcW8Eg==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.18.0.tgz", + "integrity": "sha512-Kh8zTGR9de3J63e5nS0rQUdRs/kbtwoeQQ0sriS0lItjC96u8XXZN6lKpuyWd2coKSU13py/y+LTmThLuVX0Pg==", "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.16.7", "@babel/helper-environment-visitor": "^7.16.7", - "@babel/helper-function-name": "^7.16.7", - "@babel/helper-member-expression-to-functions": "^7.16.7", + "@babel/helper-function-name": "^7.17.9", + "@babel/helper-member-expression-to-functions": "^7.17.7", "@babel/helper-optimise-call-expression": "^7.16.7", "@babel/helper-replace-supers": "^7.16.7", "@babel/helper-split-export-declaration": "^7.16.7" } }, "@babel/helper-create-regexp-features-plugin": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.17.0.tgz", - "integrity": "sha512-awO2So99wG6KnlE+TPs6rn83gCz5WlEePJDTnLEqbchMVrBeAujURVphRdigsk094VhvZehFoNOihSlcBjwsXA==", + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.17.12.tgz", + "integrity": "sha512-b2aZrV4zvutr9AIa6/gA3wsZKRwTKYoDxYiFKcESS3Ug2GTXzwBEvMuuFLhCQpEnRXs1zng4ISAXSUxxKBIcxw==", "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.16.7", @@ -9035,13 +8810,10 @@ } }, "@babel/helper-environment-visitor": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz", - "integrity": "sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag==", - "dev": true, - "requires": { - "@babel/types": "^7.16.7" - } + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.2.tgz", + "integrity": "sha512-14GQKWkX9oJzPiQQ7/J36FTXcD4kSp8egKjO9nINlSKiHITRA9q/R74qu8S9xlc/b/yjsJItQUeeh3xnGN0voQ==", + "devOptional": true }, "@babel/helper-explode-assignable-expression": { "version": "7.16.7", @@ -9053,30 +8825,20 @@ } }, "@babel/helper-function-name": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz", - "integrity": "sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA==", - "dev": true, + "version": "7.17.9", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.17.9.tgz", + "integrity": "sha512-7cRisGlVtiVqZ0MW0/yFB4atgpGLWEHUVYnb448hZK4x+vih0YO5UoS11XIYtZYqHd0dIPMdUSv8q5K4LdMnIg==", + "devOptional": true, "requires": { - "@babel/helper-get-function-arity": "^7.16.7", "@babel/template": "^7.16.7", - "@babel/types": "^7.16.7" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz", - "integrity": "sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw==", - "dev": true, - "requires": { - "@babel/types": "^7.16.7" + "@babel/types": "^7.17.0" } }, "@babel/helper-hoist-variables": { "version": "7.16.7", "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz", "integrity": "sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==", - "dev": true, + "devOptional": true, "requires": { "@babel/types": "^7.16.7" } @@ -9094,16 +8856,16 @@ "version": "7.16.7", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz", "integrity": "sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==", - "dev": true, + "devOptional": true, "requires": { "@babel/types": "^7.16.7" } }, "@babel/helper-module-transforms": { - "version": "7.17.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.17.7.tgz", - "integrity": "sha512-VmZD99F3gNTYB7fJRDTi+u6l/zxY0BE6OIxPSU7a50s6ZUQkHwSDmV92FfM+oCG0pZRVojGYhkR8I0OGeCVREw==", - "dev": true, + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.18.0.tgz", + "integrity": "sha512-kclUYSUBIjlvnzN2++K9f2qzYKFgjmnmjwL4zlmU5f8ZtzgWe8s0rUPSTGy2HmK4P8T52MQsS+HTQAgZd3dMEA==", + "devOptional": true, "requires": { "@babel/helper-environment-visitor": "^7.16.7", "@babel/helper-module-imports": "^7.16.7", @@ -9111,8 +8873,8 @@ "@babel/helper-split-export-declaration": "^7.16.7", "@babel/helper-validator-identifier": "^7.16.7", "@babel/template": "^7.16.7", - "@babel/traverse": "^7.17.3", - "@babel/types": "^7.17.0" + "@babel/traverse": "^7.18.0", + "@babel/types": "^7.18.0" } }, "@babel/helper-optimise-call-expression": { @@ -9125,9 +8887,9 @@ } }, "@babel/helper-plugin-utils": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz", - "integrity": "sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA==", + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.17.12.tgz", + "integrity": "sha512-JDkf04mqtN3y4iAbO1hv9U2ARpPyPL1zqyWs/2WG1pgSq9llHFjStX5jdxb84himgJm+8Ng+x0oiWF/nw/XQKA==", "dev": true }, "@babel/helper-remap-async-to-generator": { @@ -9142,25 +8904,25 @@ } }, "@babel/helper-replace-supers": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.16.7.tgz", - "integrity": "sha512-y9vsWilTNaVnVh6xiJfABzsNpgDPKev9HnAgz6Gb1p6UUwf9NepdlsV7VXGCftJM+jqD5f7JIEubcpLjZj5dBw==", + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.18.2.tgz", + "integrity": "sha512-XzAIyxx+vFnrOxiQrToSUOzUOn0e1J2Li40ntddek1Y69AXUTXoDJ40/D5RdjFu7s7qHiaeoTiempZcbuVXh2Q==", "dev": true, "requires": { - "@babel/helper-environment-visitor": "^7.16.7", - "@babel/helper-member-expression-to-functions": "^7.16.7", + "@babel/helper-environment-visitor": "^7.18.2", + "@babel/helper-member-expression-to-functions": "^7.17.7", "@babel/helper-optimise-call-expression": "^7.16.7", - "@babel/traverse": "^7.16.7", - "@babel/types": "^7.16.7" + "@babel/traverse": "^7.18.2", + "@babel/types": "^7.18.2" } }, "@babel/helper-simple-access": { - "version": "7.17.7", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.17.7.tgz", - "integrity": "sha512-txyMCGroZ96i+Pxr3Je3lzEJjqwaRC9buMUgtomcrLe5Nd0+fk1h0LLA+ixUF5OW7AhHuQ7Es1WcQJZmZsz2XA==", - "dev": true, + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.18.2.tgz", + "integrity": "sha512-7LIrjYzndorDY88MycupkpQLKS1AFfsVRm2k/9PtKScSy5tZq0McZTj+DiMRynboZfIqOKvo03pmhTaUgiD6fQ==", + "devOptional": true, "requires": { - "@babel/types": "^7.17.0" + "@babel/types": "^7.18.2" } }, "@babel/helper-skip-transparent-expression-wrappers": { @@ -9176,7 +8938,7 @@ "version": "7.16.7", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz", "integrity": "sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==", - "dev": true, + "devOptional": true, "requires": { "@babel/types": "^7.16.7" } @@ -9185,13 +8947,13 @@ "version": "7.16.7", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", - "dev": true + "devOptional": true }, "@babel/helper-validator-option": { "version": "7.16.7", "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz", "integrity": "sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==", - "dev": true + "devOptional": true }, "@babel/helper-wrap-function": { "version": "7.16.8", @@ -9206,21 +8968,21 @@ } }, "@babel/helpers": { - "version": "7.17.8", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.17.8.tgz", - "integrity": "sha512-QcL86FGxpfSJwGtAvv4iG93UL6bmqBdmoVY0CMCU2g+oD2ezQse3PT5Pa+jiD6LJndBQi0EDlpzOWNlLuhz5gw==", - "dev": true, + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.18.2.tgz", + "integrity": "sha512-j+d+u5xT5utcQSzrh9p+PaJX94h++KN+ng9b9WEJq7pkUPAd61FGqhjuUEdfknb3E/uDBb7ruwEeKkIxNJPIrg==", + "devOptional": true, "requires": { "@babel/template": "^7.16.7", - "@babel/traverse": "^7.17.3", - "@babel/types": "^7.17.0" + "@babel/traverse": "^7.18.2", + "@babel/types": "^7.18.2" } }, "@babel/highlight": { - "version": "7.16.10", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.10.tgz", - "integrity": "sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==", - "dev": true, + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.17.12.tgz", + "integrity": "sha512-7yykMVF3hfZY2jsHZEEgLc+3x4o1O+fYyULu11GynEUQNwB6lua+IIQn1FiJxNucd5UlyJryrwsOh8PL9Sn8Qg==", + "devOptional": true, "requires": { "@babel/helper-validator-identifier": "^7.16.7", "chalk": "^2.0.0", @@ -9231,7 +8993,7 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, + "devOptional": true, "requires": { "color-convert": "^1.9.0" } @@ -9240,7 +9002,7 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, + "devOptional": true, "requires": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -9251,7 +9013,7 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, + "devOptional": true, "requires": { "color-name": "1.1.3" } @@ -9259,26 +9021,26 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "devOptional": true }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "devOptional": true }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "devOptional": true }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, + "devOptional": true, "requires": { "has-flag": "^3.0.0" } @@ -9286,73 +9048,74 @@ } }, "@babel/parser": { - "version": "7.17.8", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.8.tgz", - "integrity": "sha512-BoHhDJrJXqcg+ZL16Xv39H9n+AqJ4pcDrQBGZN+wHxIysrLZ3/ECwCBUch/1zUNhnsXULcONU3Ei5Hmkfk6kiQ==", - "dev": true + "version": "7.18.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.4.tgz", + "integrity": "sha512-FDge0dFazETFcxGw/EXzOkN8uJp0PC7Qbm+Pe9T+av2zlBpOgunFHkQPPn+eRuClU73JF+98D531UgayY89tow==", + "devOptional": true }, "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.16.7", - "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.16.7.tgz", - "integrity": "sha512-anv/DObl7waiGEnC24O9zqL0pSuI9hljihqiDuFHC8d7/bjr/4RLGPWuc8rYOff/QPzbEPSkzG8wGG9aDuhHRg==", + "version": "7.17.12", + "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.17.12.tgz", + "integrity": "sha512-xCJQXl4EeQ3J9C4yOmpTrtVGmzpm2iSzyxbkZHw7UCnZBftHpF/hpII80uWVyVrc40ytIClHjgWGTG1g/yB+aw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.7" + "@babel/helper-plugin-utils": "^7.17.12" } }, "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.16.7.tgz", - "integrity": "sha512-di8vUHRdf+4aJ7ltXhaDbPoszdkh59AQtJM5soLsuHpQJdFQZOA4uGj0V2u/CZ8bJ/u8ULDL5yq6FO/bCXnKHw==", + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.17.12.tgz", + "integrity": "sha512-/vt0hpIw0x4b6BLKUkwlvEoiGZYYLNZ96CzyHYPbtG2jZGz6LBe7/V+drYrc/d+ovrF9NBi0pmtvmNb/FsWtRQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-plugin-utils": "^7.17.12", "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0", - "@babel/plugin-proposal-optional-chaining": "^7.16.7" + "@babel/plugin-proposal-optional-chaining": "^7.17.12" } }, "@babel/plugin-proposal-async-generator-functions": { - "version": "7.16.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.16.8.tgz", - "integrity": "sha512-71YHIvMuiuqWJQkebWJtdhQTfd4Q4mF76q2IX37uZPkG9+olBxsX+rH1vkhFto4UeJZ9dPY2s+mDvhDm1u2BGQ==", + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.17.12.tgz", + "integrity": "sha512-RWVvqD1ooLKP6IqWTA5GyFVX2isGEgC5iFxKzfYOIy/QEFdxYyCybBDtIGjipHpb9bDWHzcqGqFakf+mVmBTdQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-plugin-utils": "^7.17.12", "@babel/helper-remap-async-to-generator": "^7.16.8", "@babel/plugin-syntax-async-generators": "^7.8.4" } }, "@babel/plugin-proposal-class-properties": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.16.7.tgz", - "integrity": "sha512-IobU0Xme31ewjYOShSIqd/ZGM/r/cuOz2z0MDbNrhF5FW+ZVgi0f2lyeoj9KFPDOAqsYxmLWZte1WOwlvY9aww==", + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.17.12.tgz", + "integrity": "sha512-U0mI9q8pW5Q9EaTHFPwSVusPMV/DV9Mm8p7csqROFLtIE9rBF5piLqyrBGigftALrBcsBGu4m38JneAe7ZDLXw==", "dev": true, "requires": { - "@babel/helper-create-class-features-plugin": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7" + "@babel/helper-create-class-features-plugin": "^7.17.12", + "@babel/helper-plugin-utils": "^7.17.12" } }, "@babel/plugin-proposal-class-static-block": { - "version": "7.17.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.17.6.tgz", - "integrity": "sha512-X/tididvL2zbs7jZCeeRJ8167U/+Ac135AM6jCAx6gYXDUviZV5Ku9UDvWS2NCuWlFjIRXklYhwo6HhAC7ETnA==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.18.0.tgz", + "integrity": "sha512-t+8LsRMMDE74c6sV7KShIw13sqbqd58tlqNrsWoWBTIMw7SVQ0cZ905wLNS/FBCy/3PyooRHLFFlfrUNyyz5lA==", "dev": true, "requires": { - "@babel/helper-create-class-features-plugin": "^7.17.6", - "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-create-class-features-plugin": "^7.18.0", + "@babel/helper-plugin-utils": "^7.17.12", "@babel/plugin-syntax-class-static-block": "^7.14.5" } }, "@babel/plugin-proposal-decorators": { - "version": "7.17.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.17.8.tgz", - "integrity": "sha512-U69odN4Umyyx1xO1rTII0IDkAEC+RNlcKXtqOblfpzqy1C+aOplb76BQNq0+XdpVkOaPlpEDwd++joY8FNFJKA==", + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.18.2.tgz", + "integrity": "sha512-kbDISufFOxeczi0v4NQP3p5kIeW6izn/6klfWBrIIdGZZe4UpHR+QU03FAoWjGGd9SUXAwbw2pup1kaL4OQsJQ==", "dev": true, "requires": { - "@babel/helper-create-class-features-plugin": "^7.17.6", - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/helper-replace-supers": "^7.16.7", - "@babel/plugin-syntax-decorators": "^7.17.0", + "@babel/helper-create-class-features-plugin": "^7.18.0", + "@babel/helper-plugin-utils": "^7.17.12", + "@babel/helper-replace-supers": "^7.18.2", + "@babel/helper-split-export-declaration": "^7.16.7", + "@babel/plugin-syntax-decorators": "^7.17.12", "charcodes": "^0.2.0" } }, @@ -9367,42 +9130,42 @@ } }, "@babel/plugin-proposal-export-namespace-from": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.16.7.tgz", - "integrity": "sha512-ZxdtqDXLRGBL64ocZcs7ovt71L3jhC1RGSyR996svrCi3PYqHNkb3SwPJCs8RIzD86s+WPpt2S73+EHCGO+NUA==", + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.17.12.tgz", + "integrity": "sha512-j7Ye5EWdwoXOpRmo5QmRyHPsDIe6+u70ZYZrd7uz+ebPYFKfRcLcNu3Ro0vOlJ5zuv8rU7xa+GttNiRzX56snQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-plugin-utils": "^7.17.12", "@babel/plugin-syntax-export-namespace-from": "^7.8.3" } }, "@babel/plugin-proposal-json-strings": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.16.7.tgz", - "integrity": "sha512-lNZ3EEggsGY78JavgbHsK9u5P3pQaW7k4axlgFLYkMd7UBsiNahCITShLjNQschPyjtO6dADrL24757IdhBrsQ==", + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.17.12.tgz", + "integrity": "sha512-rKJ+rKBoXwLnIn7n6o6fulViHMrOThz99ybH+hKHcOZbnN14VuMnH9fo2eHE69C8pO4uX1Q7t2HYYIDmv8VYkg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-plugin-utils": "^7.17.12", "@babel/plugin-syntax-json-strings": "^7.8.3" } }, "@babel/plugin-proposal-logical-assignment-operators": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.16.7.tgz", - "integrity": "sha512-K3XzyZJGQCr00+EtYtrDjmwX7o7PLK6U9bi1nCwkQioRFVUv6dJoxbQjtWVtP+bCPy82bONBKG8NPyQ4+i6yjg==", + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.17.12.tgz", + "integrity": "sha512-EqFo2s1Z5yy+JeJu7SFfbIUtToJTVlC61/C7WLKDntSw4Sz6JNAIfL7zQ74VvirxpjB5kz/kIx0gCcb+5OEo2Q==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-plugin-utils": "^7.17.12", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" } }, "@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.16.7.tgz", - "integrity": "sha512-aUOrYU3EVtjf62jQrCj63pYZ7k6vns2h/DQvHPWGmsJRYzWXZ6/AsfgpiRy6XiuIDADhJzP2Q9MwSMKauBQ+UQ==", + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.17.12.tgz", + "integrity": "sha512-ws/g3FSGVzv+VH86+QvgtuJL/kR67xaEIF2x0iPqdDfYW6ra6JF3lKVBkWynRLcNtIC1oCTfDRVxmm2mKzy+ag==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-plugin-utils": "^7.17.12", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" } }, @@ -9417,16 +9180,16 @@ } }, "@babel/plugin-proposal-object-rest-spread": { - "version": "7.17.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.17.3.tgz", - "integrity": "sha512-yuL5iQA/TbZn+RGAfxQXfi7CNLmKi1f8zInn4IgobuCWcAb7i+zj4TYzQ9l8cEzVyJ89PDGuqxK1xZpUDISesw==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.18.0.tgz", + "integrity": "sha512-nbTv371eTrFabDfHLElkn9oyf9VG+VKK6WMzhY2o4eHKaG19BToD9947zzGMO6I/Irstx9d8CwX6njPNIAR/yw==", "dev": true, "requires": { - "@babel/compat-data": "^7.17.0", - "@babel/helper-compilation-targets": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7", + "@babel/compat-data": "^7.17.10", + "@babel/helper-compilation-targets": "^7.17.10", + "@babel/helper-plugin-utils": "^7.17.12", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.16.7" + "@babel/plugin-transform-parameters": "^7.17.12" } }, "@babel/plugin-proposal-optional-catch-binding": { @@ -9440,46 +9203,46 @@ } }, "@babel/plugin-proposal-optional-chaining": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.16.7.tgz", - "integrity": "sha512-eC3xy+ZrUcBtP7x+sq62Q/HYd674pPTb/77XZMb5wbDPGWIdUbSr4Agr052+zaUPSb+gGRnjxXfKFvx5iMJ+DA==", + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.17.12.tgz", + "integrity": "sha512-7wigcOs/Z4YWlK7xxjkvaIw84vGhDv/P1dFGQap0nHkc8gFKY/r+hXc8Qzf5k1gY7CvGIcHqAnOagVKJJ1wVOQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-plugin-utils": "^7.17.12", "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0", "@babel/plugin-syntax-optional-chaining": "^7.8.3" } }, "@babel/plugin-proposal-private-methods": { - "version": "7.16.11", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.16.11.tgz", - "integrity": "sha512-F/2uAkPlXDr8+BHpZvo19w3hLFKge+k75XUprE6jaqKxjGkSYcK+4c+bup5PdW/7W/Rpjwql7FTVEDW+fRAQsw==", + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.17.12.tgz", + "integrity": "sha512-SllXoxo19HmxhDWm3luPz+cPhtoTSKLJE9PXshsfrOzBqs60QP0r8OaJItrPhAj0d7mZMnNF0Y1UUggCDgMz1A==", "dev": true, "requires": { - "@babel/helper-create-class-features-plugin": "^7.16.10", - "@babel/helper-plugin-utils": "^7.16.7" + "@babel/helper-create-class-features-plugin": "^7.17.12", + "@babel/helper-plugin-utils": "^7.17.12" } }, "@babel/plugin-proposal-private-property-in-object": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.16.7.tgz", - "integrity": "sha512-rMQkjcOFbm+ufe3bTZLyOfsOUOxyvLXZJCTARhJr+8UMSoZmqTe1K1BgkFcrW37rAchWg57yI69ORxiWvUINuQ==", + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.17.12.tgz", + "integrity": "sha512-/6BtVi57CJfrtDNKfK5b66ydK2J5pXUKBKSPD2G1whamMuEnZWgoOIfO8Vf9F/DoD4izBLD/Au4NMQfruzzykg==", "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.16.7", - "@babel/helper-create-class-features-plugin": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-create-class-features-plugin": "^7.17.12", + "@babel/helper-plugin-utils": "^7.17.12", "@babel/plugin-syntax-private-property-in-object": "^7.14.5" } }, "@babel/plugin-proposal-unicode-property-regex": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.16.7.tgz", - "integrity": "sha512-QRK0YI/40VLhNVGIjRNAAQkEHws0cswSdFFjpFyt943YmJIU1da9uW63Iu6NFV6CxTZW5eTDCrwZUstBWgp/Rg==", + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.17.12.tgz", + "integrity": "sha512-Wb9qLjXf3ZazqXA7IvI7ozqRIXIGPtSo+L5coFmEkhTQK18ao4UDDD0zdTGAarmbLj2urpRwrc6893cu5Bfh0A==", "dev": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7" + "@babel/helper-create-regexp-features-plugin": "^7.17.12", + "@babel/helper-plugin-utils": "^7.17.12" } }, "@babel/plugin-syntax-async-generators": { @@ -9510,12 +9273,12 @@ } }, "@babel/plugin-syntax-decorators": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.17.0.tgz", - "integrity": "sha512-qWe85yCXsvDEluNP0OyeQjH63DlhAR3W7K9BxxU1MvbDb48tgBG+Ao6IJJ6smPDrrVzSQZrbF6donpkFBMcs3A==", + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.17.12.tgz", + "integrity": "sha512-D1Hz0qtGTza8K2xGyEdVNCYLdVHukAcbQr4K3/s6r/esadyEriZovpJimQOpu8ju4/jV8dW/1xdaE0UpDroidw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.7" + "@babel/helper-plugin-utils": "^7.17.12" } }, "@babel/plugin-syntax-dynamic-import": { @@ -9537,12 +9300,21 @@ } }, "@babel/plugin-syntax-flow": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.16.7.tgz", - "integrity": "sha512-UDo3YGQO0jH6ytzVwgSLv9i/CzMcUjbKenL67dTrAZPPv6GFAtDhe6jqnvmoKzC/7htNTohhos+onPtDMqJwaQ==", + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.17.12.tgz", + "integrity": "sha512-B8QIgBvkIG6G2jgsOHQUist7Sm0EBLDCx8sen072IwqNuzMegZNXrYnSv77cYzA8mLDZAfQYqsLIhimiP1s2HQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.7" + "@babel/helper-plugin-utils": "^7.17.12" + } + }, + "@babel/plugin-syntax-import-assertions": { + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.17.12.tgz", + "integrity": "sha512-n/loy2zkq9ZEM8tEOwON9wTQSTNDTDEz6NujPtJGLU7qObzT1N4c4YZZf8E6ATB2AjNQg/Ib2AIpO03EZaCehw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.17.12" } }, "@babel/plugin-syntax-json-strings": { @@ -9555,12 +9327,12 @@ } }, "@babel/plugin-syntax-jsx": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.16.7.tgz", - "integrity": "sha512-Esxmk7YjA8QysKeT3VhTXvF6y77f/a91SIs4pWb4H2eWGQkCKFgQaG6hdoEVZtGsrAcb2K5BW66XsOErD4WU3Q==", + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.17.12.tgz", + "integrity": "sha512-spyY3E3AURfxh/RHtjx5j6hs8am5NbUBGfcZ2vB3uShSpZdQyXSf5rR5Mk76vbtlAZOelyVQ71Fg0x9SG4fsog==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.7" + "@babel/helper-plugin-utils": "^7.17.12" } }, "@babel/plugin-syntax-logical-assignment-operators": { @@ -9636,31 +9408,31 @@ } }, "@babel/plugin-syntax-typescript": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.16.7.tgz", - "integrity": "sha512-YhUIJHHGkqPgEcMYkPCKTyGUdoGKWtopIycQyjJH8OjvRgOYsXsaKehLVPScKJWAULPxMa4N1vCe6szREFlZ7A==", + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.17.12.tgz", + "integrity": "sha512-TYY0SXFiO31YXtNg3HtFwNJHjLsAyIIhAhNWkQ5whPPS7HWUFlg9z0Ta4qAQNjQbP1wsSt/oKkmZ/4/WWdMUpw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.7" + "@babel/helper-plugin-utils": "^7.17.12" } }, "@babel/plugin-transform-arrow-functions": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.16.7.tgz", - "integrity": "sha512-9ffkFFMbvzTvv+7dTp/66xvZAWASuPD5Tl9LK3Z9vhOmANo6j94rik+5YMBt4CwHVMWLWpMsriIc2zsa3WW3xQ==", + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.17.12.tgz", + "integrity": "sha512-PHln3CNi/49V+mza4xMwrg+WGYevSF1oaiXaC2EQfdp4HWlSjRsrDXWJiQBKpP7749u6vQ9mcry2uuFOv5CXvA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.7" + "@babel/helper-plugin-utils": "^7.17.12" } }, "@babel/plugin-transform-async-to-generator": { - "version": "7.16.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.16.8.tgz", - "integrity": "sha512-MtmUmTJQHCnyJVrScNzNlofQJ3dLFuobYn3mwOTKHnSCMtbNsqvF71GQmJfFjdrXSsAA7iysFmYWw4bXZ20hOg==", + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.17.12.tgz", + "integrity": "sha512-J8dbrWIOO3orDzir57NRsjg4uxucvhby0L/KZuGsWDj0g7twWK3g7JhJhOrXtuXiw8MeiSdJ3E0OW9H8LYEzLQ==", "dev": true, "requires": { "@babel/helper-module-imports": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-plugin-utils": "^7.17.12", "@babel/helper-remap-async-to-generator": "^7.16.8" } }, @@ -9674,46 +9446,46 @@ } }, "@babel/plugin-transform-block-scoping": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.16.7.tgz", - "integrity": "sha512-ObZev2nxVAYA4bhyusELdo9hb3H+A56bxH3FZMbEImZFiEDYVHXQSJ1hQKFlDnlt8G9bBrCZ5ZpURZUrV4G5qQ==", + "version": "7.18.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.18.4.tgz", + "integrity": "sha512-+Hq10ye+jlvLEogSOtq4mKvtk7qwcUQ1f0Mrueai866C82f844Yom2cttfJdMdqRLTxWpsbfbkIkOIfovyUQXw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.7" + "@babel/helper-plugin-utils": "^7.17.12" } }, "@babel/plugin-transform-classes": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.16.7.tgz", - "integrity": "sha512-WY7og38SFAGYRe64BrjKf8OrE6ulEHtr5jEYaZMwox9KebgqPi67Zqz8K53EKk1fFEJgm96r32rkKZ3qA2nCWQ==", + "version": "7.18.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.18.4.tgz", + "integrity": "sha512-e42NSG2mlKWgxKUAD9EJJSkZxR67+wZqzNxLSpc51T8tRU5SLFHsPmgYR5yr7sdgX4u+iHA1C5VafJ6AyImV3A==", "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.16.7", - "@babel/helper-environment-visitor": "^7.16.7", - "@babel/helper-function-name": "^7.16.7", + "@babel/helper-environment-visitor": "^7.18.2", + "@babel/helper-function-name": "^7.17.9", "@babel/helper-optimise-call-expression": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/helper-replace-supers": "^7.16.7", + "@babel/helper-plugin-utils": "^7.17.12", + "@babel/helper-replace-supers": "^7.18.2", "@babel/helper-split-export-declaration": "^7.16.7", "globals": "^11.1.0" } }, "@babel/plugin-transform-computed-properties": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.16.7.tgz", - "integrity": "sha512-gN72G9bcmenVILj//sv1zLNaPyYcOzUho2lIJBMh/iakJ9ygCo/hEF9cpGb61SCMEDxbbyBoVQxrt+bWKu5KGw==", + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.17.12.tgz", + "integrity": "sha512-a7XINeplB5cQUWMg1E/GI1tFz3LfK021IjV1rj1ypE+R7jHm+pIHmHl25VNkZxtx9uuYp7ThGk8fur1HHG7PgQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.7" + "@babel/helper-plugin-utils": "^7.17.12" } }, "@babel/plugin-transform-destructuring": { - "version": "7.17.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.17.7.tgz", - "integrity": "sha512-XVh0r5yq9sLR4vZ6eVZe8FKfIcSgaTBxVBRSYokRj2qksf6QerYnTxz9/GTuKTH/n/HwLP7t6gtlybHetJ/6hQ==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.18.0.tgz", + "integrity": "sha512-Mo69klS79z6KEfrLg/1WkmVnB8javh75HX4pi2btjvlIoasuxilEyjtsQW6XPrubNd7AQy0MMaNIaQE4e7+PQw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.7" + "@babel/helper-plugin-utils": "^7.17.12" } }, "@babel/plugin-transform-dotall-regex": { @@ -9727,12 +9499,12 @@ } }, "@babel/plugin-transform-duplicate-keys": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.16.7.tgz", - "integrity": "sha512-03DvpbRfvWIXyK0/6QiR1KMTWeT6OcQ7tbhjrXyFS02kjuX/mu5Bvnh5SDSWHxyawit2g5aWhKwI86EE7GUnTw==", + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.17.12.tgz", + "integrity": "sha512-EA5eYFUG6xeerdabina/xIoB95jJ17mAkR8ivx6ZSu9frKShBjpOGZPn511MTDTkiCO+zXnzNczvUM69YSf3Zw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.7" + "@babel/helper-plugin-utils": "^7.17.12" } }, "@babel/plugin-transform-exponentiation-operator": { @@ -9746,22 +9518,22 @@ } }, "@babel/plugin-transform-flow-strip-types": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.16.7.tgz", - "integrity": "sha512-mzmCq3cNsDpZZu9FADYYyfZJIOrSONmHcop2XEKPdBNMa4PDC4eEvcOvzZaCNcjKu72v0XQlA5y1g58aLRXdYg==", + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.17.12.tgz", + "integrity": "sha512-g8cSNt+cHCpG/uunPQELdq/TeV3eg1OLJYwxypwHtAWo9+nErH3lQx9CSO2uI9lF74A0mR0t4KoMjs1snSgnTw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/plugin-syntax-flow": "^7.16.7" + "@babel/helper-plugin-utils": "^7.17.12", + "@babel/plugin-syntax-flow": "^7.17.12" } }, "@babel/plugin-transform-for-of": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.16.7.tgz", - "integrity": "sha512-/QZm9W92Ptpw7sjI9Nx1mbcsWz33+l8kuMIQnDwgQBG5s3fAfQvkRjQ7NqXhtNcKOnPkdICmUHyCaWW06HCsqg==", + "version": "7.18.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.18.1.tgz", + "integrity": "sha512-+TTB5XwvJ5hZbO8xvl2H4XaMDOAK57zF4miuC9qQJgysPNEAZZ9Z69rdF5LJkozGdZrjBIUAIyKUWRMmebI7vg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.7" + "@babel/helper-plugin-utils": "^7.17.12" } }, "@babel/plugin-transform-function-name": { @@ -9776,12 +9548,12 @@ } }, "@babel/plugin-transform-literals": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.16.7.tgz", - "integrity": "sha512-6tH8RTpTWI0s2sV6uq3e/C9wPo4PTqqZps4uF0kzQ9/xPLFQtipynvmT1g/dOfEJ+0EQsHhkQ/zyRId8J2b8zQ==", + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.17.12.tgz", + "integrity": "sha512-8iRkvaTjJciWycPIZ9k9duu663FT7VrBdNqNgxnVXEFwOIp55JWcZd23VBRySYbnS3PwQ3rGiabJBBBGj5APmQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.7" + "@babel/helper-plugin-utils": "^7.17.12" } }, "@babel/plugin-transform-member-expression-literals": { @@ -9794,67 +9566,68 @@ } }, "@babel/plugin-transform-modules-amd": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.16.7.tgz", - "integrity": "sha512-KaaEtgBL7FKYwjJ/teH63oAmE3lP34N3kshz8mm4VMAw7U3PxjVwwUmxEFksbgsNUaO3wId9R2AVQYSEGRa2+g==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.18.0.tgz", + "integrity": "sha512-h8FjOlYmdZwl7Xm2Ug4iX2j7Qy63NANI+NQVWQzv6r25fqgg7k2dZl03p95kvqNclglHs4FZ+isv4p1uXMA+QA==", "dev": true, "requires": { - "@babel/helper-module-transforms": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-module-transforms": "^7.18.0", + "@babel/helper-plugin-utils": "^7.17.12", "babel-plugin-dynamic-import-node": "^2.3.3" } }, "@babel/plugin-transform-modules-commonjs": { - "version": "7.17.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.17.7.tgz", - "integrity": "sha512-ITPmR2V7MqioMJyrxUo2onHNC3e+MvfFiFIR0RP21d3PtlVb6sfzoxNKiphSZUOM9hEIdzCcZe83ieX3yoqjUA==", + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.18.2.tgz", + "integrity": "sha512-f5A865gFPAJAEE0K7F/+nm5CmAE3y8AWlMBG9unu5j9+tk50UQVK0QS8RNxSp7MJf0wh97uYyLWt3Zvu71zyOQ==", "dev": true, "requires": { - "@babel/helper-module-transforms": "^7.17.7", - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/helper-simple-access": "^7.17.7", + "@babel/helper-module-transforms": "^7.18.0", + "@babel/helper-plugin-utils": "^7.17.12", + "@babel/helper-simple-access": "^7.18.2", "babel-plugin-dynamic-import-node": "^2.3.3" } }, "@babel/plugin-transform-modules-systemjs": { - "version": "7.17.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.17.8.tgz", - "integrity": "sha512-39reIkMTUVagzgA5x88zDYXPCMT6lcaRKs1+S9K6NKBPErbgO/w/kP8GlNQTC87b412ZTlmNgr3k2JrWgHH+Bw==", + "version": "7.18.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.18.4.tgz", + "integrity": "sha512-lH2UaQaHVOAeYrUUuZ8i38o76J/FnO8vu21OE+tD1MyP9lxdZoSfz+pDbWkq46GogUrdrMz3tiz/FYGB+bVThg==", "dev": true, "requires": { "@babel/helper-hoist-variables": "^7.16.7", - "@babel/helper-module-transforms": "^7.17.7", - "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-module-transforms": "^7.18.0", + "@babel/helper-plugin-utils": "^7.17.12", "@babel/helper-validator-identifier": "^7.16.7", "babel-plugin-dynamic-import-node": "^2.3.3" } }, "@babel/plugin-transform-modules-umd": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.16.7.tgz", - "integrity": "sha512-EMh7uolsC8O4xhudF2F6wedbSHm1HHZ0C6aJ7K67zcDNidMzVcxWdGr+htW9n21klm+bOn+Rx4CBsAntZd3rEQ==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.18.0.tgz", + "integrity": "sha512-d/zZ8I3BWli1tmROLxXLc9A6YXvGK8egMxHp+E/rRwMh1Kip0AP77VwZae3snEJ33iiWwvNv2+UIIhfalqhzZA==", "dev": true, "requires": { - "@babel/helper-module-transforms": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7" + "@babel/helper-module-transforms": "^7.18.0", + "@babel/helper-plugin-utils": "^7.17.12" } }, "@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.16.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.16.8.tgz", - "integrity": "sha512-j3Jw+n5PvpmhRR+mrgIh04puSANCk/T/UA3m3P1MjJkhlK906+ApHhDIqBQDdOgL/r1UYpz4GNclTXxyZrYGSw==", + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.17.12.tgz", + "integrity": "sha512-vWoWFM5CKaTeHrdUJ/3SIOTRV+MBVGybOC9mhJkaprGNt5demMymDW24yC74avb915/mIRe3TgNb/d8idvnCRA==", "dev": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.16.7" + "@babel/helper-create-regexp-features-plugin": "^7.17.12", + "@babel/helper-plugin-utils": "^7.17.12" } }, "@babel/plugin-transform-new-target": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.16.7.tgz", - "integrity": "sha512-xiLDzWNMfKoGOpc6t3U+etCE2yRnn3SM09BXqWPIZOBpL2gvVrBWUKnsJx0K/ADi5F5YC5f8APFfWrz25TdlGg==", + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.17.12.tgz", + "integrity": "sha512-CaOtzk2fDYisbjAD4Sd1MTKGVIpRtx9bWLyj24Y/k6p4s4gQ3CqDGJauFJxt8M/LEx003d0i3klVqnN73qvK3w==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.7" + "@babel/helper-plugin-utils": "^7.17.12" } }, "@babel/plugin-transform-object-super": { @@ -9868,12 +9641,12 @@ } }, "@babel/plugin-transform-parameters": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.16.7.tgz", - "integrity": "sha512-AT3MufQ7zZEhU2hwOA11axBnExW0Lszu4RL/tAlUJBuNoRak+wehQW8h6KcXOcgjY42fHtDxswuMhMjFEuv/aw==", + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.17.12.tgz", + "integrity": "sha512-6qW4rWo1cyCdq1FkYri7AHpauchbGLXpdwnYsfxFb+KtddHENfsY5JZb35xUwkK5opOLcJ3BNd2l7PhRYGlwIA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.7" + "@babel/helper-plugin-utils": "^7.17.12" } }, "@babel/plugin-transform-property-literals": { @@ -9895,16 +9668,16 @@ } }, "@babel/plugin-transform-react-jsx": { - "version": "7.17.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.17.3.tgz", - "integrity": "sha512-9tjBm4O07f7mzKSIlEmPdiE6ub7kfIe6Cd+w+oQebpATfTQMAgW+YOuWxogbKVTulA+MEO7byMeIUtQ1z+z+ZQ==", + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.17.12.tgz", + "integrity": "sha512-Lcaw8bxd1DKht3thfD4A12dqo1X16he1Lm8rIv8sTwjAYNInRS1qHa9aJoqvzpscItXvftKDCfaEQzwoVyXpEQ==", "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.16.7", "@babel/helper-module-imports": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/plugin-syntax-jsx": "^7.16.7", - "@babel/types": "^7.17.0" + "@babel/helper-plugin-utils": "^7.17.12", + "@babel/plugin-syntax-jsx": "^7.17.12", + "@babel/types": "^7.17.12" } }, "@babel/plugin-transform-react-jsx-development": { @@ -9917,12 +9690,12 @@ } }, "@babel/plugin-transform-react-jsx-self": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.16.7.tgz", - "integrity": "sha512-oe5VuWs7J9ilH3BCCApGoYjHoSO48vkjX2CbA5bFVhIuO2HKxA3vyF7rleA4o6/4rTDbk6r8hBW7Ul8E+UZrpA==", + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.17.12.tgz", + "integrity": "sha512-7S9G2B44EnYOx74mue02t1uD8ckWZ/ee6Uz/qfdzc35uWHX5NgRy9i+iJSb2LFRgMd+QV9zNcStQaazzzZ3n3Q==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.7" + "@babel/helper-plugin-utils": "^7.17.12" } }, "@babel/plugin-transform-react-jsx-source": { @@ -9935,41 +9708,42 @@ } }, "@babel/plugin-transform-react-pure-annotations": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.16.7.tgz", - "integrity": "sha512-hs71ToC97k3QWxswh2ElzMFABXHvGiJ01IB1TbYQDGeWRKWz/MPUTh5jGExdHvosYKpnJW5Pm3S4+TA3FyX+GA==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.18.0.tgz", + "integrity": "sha512-6+0IK6ouvqDn9bmEG7mEyF/pwlJXVj5lwydybpyyH3D0A7Hftk+NCTdYjnLNZksn261xaOV5ksmp20pQEmc2RQ==", "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7" + "@babel/helper-plugin-utils": "^7.17.12" } }, "@babel/plugin-transform-regenerator": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.16.7.tgz", - "integrity": "sha512-mF7jOgGYCkSJagJ6XCujSQg+6xC1M77/03K2oBmVJWoFGNUtnVJO4WHKJk3dnPC8HCcj4xBQP1Egm8DWh3Pb3Q==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.18.0.tgz", + "integrity": "sha512-C8YdRw9uzx25HSIzwA7EM7YP0FhCe5wNvJbZzjVNHHPGVcDJ3Aie+qGYYdS1oVQgn+B3eAIJbWFLrJ4Jipv7nw==", "dev": true, "requires": { - "regenerator-transform": "^0.14.2" + "@babel/helper-plugin-utils": "^7.17.12", + "regenerator-transform": "^0.15.0" } }, "@babel/plugin-transform-reserved-words": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.16.7.tgz", - "integrity": "sha512-KQzzDnZ9hWQBjwi5lpY5v9shmm6IVG0U9pB18zvMu2i4H90xpT4gmqwPYsn8rObiadYe2M0gmgsiOIF5A/2rtg==", + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.17.12.tgz", + "integrity": "sha512-1KYqwbJV3Co03NIi14uEHW8P50Md6KqFgt0FfpHdK6oyAHQVTosgPuPSiWud1HX0oYJ1hGRRlk0fP87jFpqXZA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.7" + "@babel/helper-plugin-utils": "^7.17.12" } }, "@babel/plugin-transform-runtime": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.17.0.tgz", - "integrity": "sha512-fr7zPWnKXNc1xoHfrIU9mN/4XKX4VLZ45Q+oMhfsYIaHvg7mHgmhfOy/ckRWqDK7XF3QDigRpkh5DKq6+clE8A==", + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.18.2.tgz", + "integrity": "sha512-mr1ufuRMfS52ttq+1G1PD8OJNqgcTFjq3hwn8SZ5n1x1pBhi0E36rYMdTK0TsKtApJ4lDEdfXJwtGobQMHSMPg==", "dev": true, "requires": { "@babel/helper-module-imports": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-plugin-utils": "^7.17.12", "babel-plugin-polyfill-corejs2": "^0.3.0", "babel-plugin-polyfill-corejs3": "^0.5.0", "babel-plugin-polyfill-regenerator": "^0.3.0", @@ -9986,12 +9760,12 @@ } }, "@babel/plugin-transform-spread": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.16.7.tgz", - "integrity": "sha512-+pjJpgAngb53L0iaA5gU/1MLXJIfXcYepLgXB3esVRf4fqmj8f2cxM3/FKaHsZms08hFQJkFccEWuIpm429TXg==", + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.17.12.tgz", + "integrity": "sha512-9pgmuQAtFi3lpNUstvG9nGfk9DkrdmWNp9KeKPFmuZCpEnxRzYlS8JgwPjYj+1AWDOSvoGN0H30p1cBOmT/Svg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-plugin-utils": "^7.17.12", "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0" } }, @@ -10005,32 +9779,32 @@ } }, "@babel/plugin-transform-template-literals": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.16.7.tgz", - "integrity": "sha512-VwbkDDUeenlIjmfNeDX/V0aWrQH2QiVyJtwymVQSzItFDTpxfyJh3EVaQiS0rIN/CqbLGr0VcGmuwyTdZtdIsA==", + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.2.tgz", + "integrity": "sha512-/cmuBVw9sZBGZVOMkpAEaVLwm4JmK2GZ1dFKOGGpMzEHWFmyZZ59lUU0PdRr8YNYeQdNzTDwuxP2X2gzydTc9g==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.7" + "@babel/helper-plugin-utils": "^7.17.12" } }, "@babel/plugin-transform-typeof-symbol": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.16.7.tgz", - "integrity": "sha512-p2rOixCKRJzpg9JB4gjnG4gjWkWa89ZoYUnl9snJ1cWIcTH/hvxZqfO+WjG6T8DRBpctEol5jw1O5rA8gkCokQ==", + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.17.12.tgz", + "integrity": "sha512-Q8y+Jp7ZdtSPXCThB6zjQ74N3lj0f6TDh1Hnf5B+sYlzQ8i5Pjp8gW0My79iekSpT4WnI06blqP6DT0OmaXXmw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.7" + "@babel/helper-plugin-utils": "^7.17.12" } }, "@babel/plugin-transform-typescript": { - "version": "7.16.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.16.8.tgz", - "integrity": "sha512-bHdQ9k7YpBDO2d0NVfkj51DpQcvwIzIusJ7mEUaMlbZq3Kt/U47j24inXZHQ5MDiYpCs+oZiwnXyKedE8+q7AQ==", + "version": "7.18.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.18.4.tgz", + "integrity": "sha512-l4vHuSLUajptpHNEOUDEGsnpl9pfRLsN1XUoDQDD/YBuXTM+v37SHGS+c6n4jdcZy96QtuUuSvZYMLSSsjH8Mw==", "dev": true, "requires": { - "@babel/helper-create-class-features-plugin": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/plugin-syntax-typescript": "^7.16.7" + "@babel/helper-create-class-features-plugin": "^7.18.0", + "@babel/helper-plugin-utils": "^7.17.12", + "@babel/plugin-syntax-typescript": "^7.17.12" } }, "@babel/plugin-transform-unicode-escapes": { @@ -10053,37 +9827,38 @@ } }, "@babel/preset-env": { - "version": "7.16.11", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.16.11.tgz", - "integrity": "sha512-qcmWG8R7ZW6WBRPZK//y+E3Cli151B20W1Rv7ln27vuPaXU/8TKms6jFdiJtF7UDTxcrb7mZd88tAeK9LjdT8g==", + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.18.2.tgz", + "integrity": "sha512-PfpdxotV6afmXMU47S08F9ZKIm2bJIQ0YbAAtDfIENX7G1NUAXigLREh69CWDjtgUy7dYn7bsMzkgdtAlmS68Q==", "dev": true, "requires": { - "@babel/compat-data": "^7.16.8", - "@babel/helper-compilation-targets": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7", + "@babel/compat-data": "^7.17.10", + "@babel/helper-compilation-targets": "^7.18.2", + "@babel/helper-plugin-utils": "^7.17.12", "@babel/helper-validator-option": "^7.16.7", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.16.7", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.16.7", - "@babel/plugin-proposal-async-generator-functions": "^7.16.8", - "@babel/plugin-proposal-class-properties": "^7.16.7", - "@babel/plugin-proposal-class-static-block": "^7.16.7", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.17.12", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.17.12", + "@babel/plugin-proposal-async-generator-functions": "^7.17.12", + "@babel/plugin-proposal-class-properties": "^7.17.12", + "@babel/plugin-proposal-class-static-block": "^7.18.0", "@babel/plugin-proposal-dynamic-import": "^7.16.7", - "@babel/plugin-proposal-export-namespace-from": "^7.16.7", - "@babel/plugin-proposal-json-strings": "^7.16.7", - "@babel/plugin-proposal-logical-assignment-operators": "^7.16.7", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.16.7", + "@babel/plugin-proposal-export-namespace-from": "^7.17.12", + "@babel/plugin-proposal-json-strings": "^7.17.12", + "@babel/plugin-proposal-logical-assignment-operators": "^7.17.12", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.17.12", "@babel/plugin-proposal-numeric-separator": "^7.16.7", - "@babel/plugin-proposal-object-rest-spread": "^7.16.7", + "@babel/plugin-proposal-object-rest-spread": "^7.18.0", "@babel/plugin-proposal-optional-catch-binding": "^7.16.7", - "@babel/plugin-proposal-optional-chaining": "^7.16.7", - "@babel/plugin-proposal-private-methods": "^7.16.11", - "@babel/plugin-proposal-private-property-in-object": "^7.16.7", - "@babel/plugin-proposal-unicode-property-regex": "^7.16.7", + "@babel/plugin-proposal-optional-chaining": "^7.17.12", + "@babel/plugin-proposal-private-methods": "^7.17.12", + "@babel/plugin-proposal-private-property-in-object": "^7.17.12", + "@babel/plugin-proposal-unicode-property-regex": "^7.17.12", "@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.17.12", "@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", @@ -10093,44 +9868,44 @@ "@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.16.7", - "@babel/plugin-transform-async-to-generator": "^7.16.8", + "@babel/plugin-transform-arrow-functions": "^7.17.12", + "@babel/plugin-transform-async-to-generator": "^7.17.12", "@babel/plugin-transform-block-scoped-functions": "^7.16.7", - "@babel/plugin-transform-block-scoping": "^7.16.7", - "@babel/plugin-transform-classes": "^7.16.7", - "@babel/plugin-transform-computed-properties": "^7.16.7", - "@babel/plugin-transform-destructuring": "^7.16.7", + "@babel/plugin-transform-block-scoping": "^7.17.12", + "@babel/plugin-transform-classes": "^7.17.12", + "@babel/plugin-transform-computed-properties": "^7.17.12", + "@babel/plugin-transform-destructuring": "^7.18.0", "@babel/plugin-transform-dotall-regex": "^7.16.7", - "@babel/plugin-transform-duplicate-keys": "^7.16.7", + "@babel/plugin-transform-duplicate-keys": "^7.17.12", "@babel/plugin-transform-exponentiation-operator": "^7.16.7", - "@babel/plugin-transform-for-of": "^7.16.7", + "@babel/plugin-transform-for-of": "^7.18.1", "@babel/plugin-transform-function-name": "^7.16.7", - "@babel/plugin-transform-literals": "^7.16.7", + "@babel/plugin-transform-literals": "^7.17.12", "@babel/plugin-transform-member-expression-literals": "^7.16.7", - "@babel/plugin-transform-modules-amd": "^7.16.7", - "@babel/plugin-transform-modules-commonjs": "^7.16.8", - "@babel/plugin-transform-modules-systemjs": "^7.16.7", - "@babel/plugin-transform-modules-umd": "^7.16.7", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.16.8", - "@babel/plugin-transform-new-target": "^7.16.7", + "@babel/plugin-transform-modules-amd": "^7.18.0", + "@babel/plugin-transform-modules-commonjs": "^7.18.2", + "@babel/plugin-transform-modules-systemjs": "^7.18.0", + "@babel/plugin-transform-modules-umd": "^7.18.0", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.17.12", + "@babel/plugin-transform-new-target": "^7.17.12", "@babel/plugin-transform-object-super": "^7.16.7", - "@babel/plugin-transform-parameters": "^7.16.7", + "@babel/plugin-transform-parameters": "^7.17.12", "@babel/plugin-transform-property-literals": "^7.16.7", - "@babel/plugin-transform-regenerator": "^7.16.7", - "@babel/plugin-transform-reserved-words": "^7.16.7", + "@babel/plugin-transform-regenerator": "^7.18.0", + "@babel/plugin-transform-reserved-words": "^7.17.12", "@babel/plugin-transform-shorthand-properties": "^7.16.7", - "@babel/plugin-transform-spread": "^7.16.7", + "@babel/plugin-transform-spread": "^7.17.12", "@babel/plugin-transform-sticky-regex": "^7.16.7", - "@babel/plugin-transform-template-literals": "^7.16.7", - "@babel/plugin-transform-typeof-symbol": "^7.16.7", + "@babel/plugin-transform-template-literals": "^7.18.2", + "@babel/plugin-transform-typeof-symbol": "^7.17.12", "@babel/plugin-transform-unicode-escapes": "^7.16.7", "@babel/plugin-transform-unicode-regex": "^7.16.7", "@babel/preset-modules": "^0.1.5", - "@babel/types": "^7.16.8", + "@babel/types": "^7.18.2", "babel-plugin-polyfill-corejs2": "^0.3.0", "babel-plugin-polyfill-corejs3": "^0.5.0", "babel-plugin-polyfill-regenerator": "^0.3.0", - "core-js-compat": "^3.20.2", + "core-js-compat": "^3.22.1", "semver": "^6.3.0" } }, @@ -10148,42 +9923,42 @@ } }, "@babel/preset-react": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.16.7.tgz", - "integrity": "sha512-fWpyI8UM/HE6DfPBzD8LnhQ/OcH8AgTaqcqP2nGOXEUV+VKBR5JRN9hCk9ai+zQQ57vtm9oWeXguBCPNUjytgA==", + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.17.12.tgz", + "integrity": "sha512-h5U+rwreXtZaRBEQhW1hOJLMq8XNJBQ/9oymXiCXTuT/0uOwpbT0gUt+sXeOqoXBgNuUKI7TaObVwoEyWkpFgA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-plugin-utils": "^7.17.12", "@babel/helper-validator-option": "^7.16.7", "@babel/plugin-transform-react-display-name": "^7.16.7", - "@babel/plugin-transform-react-jsx": "^7.16.7", + "@babel/plugin-transform-react-jsx": "^7.17.12", "@babel/plugin-transform-react-jsx-development": "^7.16.7", "@babel/plugin-transform-react-pure-annotations": "^7.16.7" } }, "@babel/preset-typescript": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.16.7.tgz", - "integrity": "sha512-WbVEmgXdIyvzB77AQjGBEyYPZx+8tTsO50XtfozQrkW8QB2rLJpH2lgx0TRw5EJrBxOZQ+wCcyPVQvS8tjEHpQ==", + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.17.12.tgz", + "integrity": "sha512-S1ViF8W2QwAKUGJXxP9NAfNaqGDdEBJKpYkxHf5Yy2C4NPPzXGeR3Lhk7G8xJaaLcFTRfNjVbtbVtm8Gb0mqvg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-plugin-utils": "^7.17.12", "@babel/helper-validator-option": "^7.16.7", - "@babel/plugin-transform-typescript": "^7.16.7" + "@babel/plugin-transform-typescript": "^7.17.12" } }, "@babel/runtime": { - "version": "7.17.8", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.8.tgz", - "integrity": "sha512-dQpEpK0O9o6lj6oPu0gRDbbnk+4LeHlNcBpspf6Olzt3GIX4P1lWF1gS+pHLDFlaJvbR6q7jCfQ08zA4QJBnmA==", + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.18.3.tgz", + "integrity": "sha512-38Y8f7YUhce/K7RMwTp7m0uCumpv9hZkitCbBClqQIow1qSbCvGkcegKOXpEWCQLfWmevgRiWokZ1GkpfhbZug==", "requires": { "regenerator-runtime": "^0.13.4" } }, "@babel/runtime-corejs3": { - "version": "7.17.8", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.17.8.tgz", - "integrity": "sha512-ZbYSUvoSF6dXZmMl/CYTMOvzIFnbGfv4W3SEHYgMvNsFTeLaF2gkGAF4K2ddmtSK4Emej+0aYcnSC6N5dPCXUQ==", + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.18.3.tgz", + "integrity": "sha512-l4ddFwrc9rnR+EJsHsh+TJ4A35YqQz/UqcjtlX2ov53hlJYG5CxtQmNZxyajwDVmCxwy++rtvGU5HazCK4W41Q==", "dev": true, "requires": { "core-js-pure": "^3.20.2", @@ -10194,7 +9969,7 @@ "version": "7.16.7", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz", "integrity": "sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==", - "dev": true, + "devOptional": true, "requires": { "@babel/code-frame": "^7.16.7", "@babel/parser": "^7.16.7", @@ -10202,84 +9977,37 @@ } }, "@babel/traverse": { - "version": "7.17.3", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.17.3.tgz", - "integrity": "sha512-5irClVky7TxRWIRtxlh2WPUUOLhcPN06AGgaQSB8AEwuyEBgJVuJ5imdHm5zxk8w0QS5T+tDfnDxAlhWjpb7cw==", - "dev": true, + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.18.2.tgz", + "integrity": "sha512-9eNwoeovJ6KH9zcCNnENY7DMFwTU9JdGCFtqNLfUAqtUHRCOsTOqWoffosP8vKmNYeSBUv3yVJXjfd8ucwOjUA==", + "devOptional": true, "requires": { "@babel/code-frame": "^7.16.7", - "@babel/generator": "^7.17.3", - "@babel/helper-environment-visitor": "^7.16.7", - "@babel/helper-function-name": "^7.16.7", + "@babel/generator": "^7.18.2", + "@babel/helper-environment-visitor": "^7.18.2", + "@babel/helper-function-name": "^7.17.9", "@babel/helper-hoist-variables": "^7.16.7", "@babel/helper-split-export-declaration": "^7.16.7", - "@babel/parser": "^7.17.3", - "@babel/types": "^7.17.0", + "@babel/parser": "^7.18.0", + "@babel/types": "^7.18.2", "debug": "^4.1.0", "globals": "^11.1.0" } }, "@babel/types": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz", - "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==", - "dev": true, + "version": "7.18.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.18.4.tgz", + "integrity": "sha512-ThN1mBcMq5pG/Vm2IcBmPPfyPXbd8S02rS+OBIDENdufvqC7Z/jHPCv9IcP01277aKtDI8g/2XysBN4hA8niiw==", + "devOptional": true, "requires": { "@babel/helper-validator-identifier": "^7.16.7", "to-fast-properties": "^2.0.0" } }, - "@emotion/babel-plugin": { - "version": "11.7.2", - "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.7.2.tgz", - "integrity": "sha512-6mGSCWi9UzXut/ZAN6lGFu33wGR3SJisNl3c0tvlmb8XChH1b2SUvxvnOh7hvLpqyRdHHU9AiazV3Cwbk5SXKQ==", - "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.12.13", - "@babel/plugin-syntax-jsx": "^7.12.13", - "@babel/runtime": "^7.13.10", - "@emotion/hash": "^0.8.0", - "@emotion/memoize": "^0.7.5", - "@emotion/serialize": "^1.0.2", - "babel-plugin-macros": "^2.6.1", - "convert-source-map": "^1.5.0", - "escape-string-regexp": "^4.0.0", - "find-root": "^1.1.0", - "source-map": "^0.5.7", - "stylis": "4.0.13" - }, - "dependencies": { - "babel-plugin-macros": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-2.8.0.tgz", - "integrity": "sha512-SEP5kJpfGYqYKpBrj5XU3ahw5p5GOHJ0U5ssOSQ/WBVdwkD2Dzlce95exQTs3jOVWPPKLBN2rlEWkCK7dSmLvg==", - "dev": true, - "requires": { - "@babel/runtime": "^7.7.2", - "cosmiconfig": "^6.0.0", - "resolve": "^1.12.0" - } - }, - "cosmiconfig": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", - "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", - "dev": true, - "requires": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.1.0", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.7.2" - } - } - } - }, "@emotion/cache": { "version": "11.7.1", "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.7.1.tgz", "integrity": "sha512-r65Zy4Iljb8oyjtLeCuBH8Qjiy107dOYC6SJq7g7GV5UCQWMObY4SJDPGFjiiVpPrOJ2hmJOoBiYTC7hwx9E2A==", - "dev": true, "requires": { "@emotion/memoize": "^0.7.4", "@emotion/sheet": "^1.1.0", @@ -10291,26 +10019,23 @@ "@emotion/hash": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.8.0.tgz", - "integrity": "sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==", - "dev": true + "integrity": "sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==" }, "@emotion/memoize": { "version": "0.7.5", "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.5.tgz", - "integrity": "sha512-igX9a37DR2ZPGYtV6suZ6whr8pTFtyHL3K/oLUotxpSVO2ASaprmAe2Dkq7tBo7CRY7MMDrAa9nuQP9/YG8FxQ==", - "dev": true + "integrity": "sha512-igX9a37DR2ZPGYtV6suZ6whr8pTFtyHL3K/oLUotxpSVO2ASaprmAe2Dkq7tBo7CRY7MMDrAa9nuQP9/YG8FxQ==" }, "@emotion/react": { - "version": "11.8.2", - "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.8.2.tgz", - "integrity": "sha512-+1bcHBaNJv5nkIIgnGKVsie3otS0wF9f1T1hteF3WeVvMNQEtfZ4YyFpnphGoot3ilU/wWMgP2SgIDuHLE/wAA==", - "dev": true, + "version": "11.7.1", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.7.1.tgz", + "integrity": "sha512-DV2Xe3yhkF1yT4uAUoJcYL1AmrnO5SVsdfvu+fBuS7IbByDeTVx9+wFmvx9Idzv7/78+9Mgx2Hcmr7Fex3tIyw==", "requires": { "@babel/runtime": "^7.13.10", - "@emotion/babel-plugin": "^11.7.1", "@emotion/cache": "^11.7.1", "@emotion/serialize": "^1.0.2", - "@emotion/utils": "^1.1.0", + "@emotion/sheet": "^1.1.0", + "@emotion/utils": "^1.0.0", "@emotion/weak-memoize": "^0.2.5", "hoist-non-react-statics": "^3.3.1" } @@ -10319,7 +10044,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.0.2.tgz", "integrity": "sha512-95MgNJ9+/ajxU7QIAruiOAdYNjxZX7G2mhgrtDWswA21VviYIRP1R5QilZ/bDY42xiKsaktP4egJb3QdYQZi1A==", - "dev": true, "requires": { "@emotion/hash": "^0.8.0", "@emotion/memoize": "^0.7.4", @@ -10331,48 +10055,44 @@ "@emotion/sheet": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.1.0.tgz", - "integrity": "sha512-u0AX4aSo25sMAygCuQTzS+HsImZFuS8llY8O7b9MDRzbJM0kVJlAz6KNDqcG7pOuQZJmj/8X/rAW+66kMnMW+g==", - "dev": true + "integrity": "sha512-u0AX4aSo25sMAygCuQTzS+HsImZFuS8llY8O7b9MDRzbJM0kVJlAz6KNDqcG7pOuQZJmj/8X/rAW+66kMnMW+g==" }, "@emotion/unitless": { "version": "0.7.5", "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", - "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==", - "dev": true + "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==" }, "@emotion/utils": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.1.0.tgz", - "integrity": "sha512-iRLa/Y4Rs5H/f2nimczYmS5kFJEbpiVvgN3XVfZ022IYhuNA1IRSHEizcof88LtCTXtl9S2Cxt32KgaXEu72JQ==", - "dev": true + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.0.0.tgz", + "integrity": "sha512-mQC2b3XLDs6QCW+pDQDiyO/EdGZYOygE8s5N5rrzjSI4M3IejPE/JPndCBwRT9z982aqQNi6beWs1UeayrQxxA==" }, "@emotion/weak-memoize": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.2.5.tgz", - "integrity": "sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA==", - "dev": true + "integrity": "sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA==" }, "@eslint/eslintrc": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.1.tgz", - "integrity": "sha512-bxvbYnBPN1Gibwyp6NrpnFzA3YtRL3BBAyEAFVIpNTm2Rn4Vy87GA5M4aSn3InRrlsbX5N0GW7XIx+U4SAEKdQ==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.0.tgz", + "integrity": "sha512-UWW0TMTmk2d7hLcWD1/e2g5HDM/HQ3csaLSqXCfqwh4uNDuNqlaKWXmEsL4Cs41Z0KnILNvwbHAah3C2yt06kw==", "dev": true, "requires": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.3.1", - "globals": "^13.9.0", + "espree": "^9.3.2", + "globals": "^13.15.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", - "minimatch": "^3.0.4", + "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" }, "dependencies": { "globals": { - "version": "13.13.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.13.0.tgz", - "integrity": "sha512-EQ7Q18AJlPwp3vUDL4mKA0KXrXyNIQyWon6T6XQiBQF0XHvRsiCSrWmmeATpUzdJN2HhWZU6Pdl0a9zdep5p6A==", + "version": "13.15.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.15.0.tgz", + "integrity": "sha512-bpzcOlgDhMG070Av0Vy5Owklpv1I6+j96GhUI7Rh7IzDCKLzboflLrrfqMu8NquDbiR4EOQk7XzJwqVJxicxog==", "dev": true, "requires": { "type-fest": "^0.20.2" @@ -10387,9 +10107,9 @@ } }, "@fontsource/roboto": { - "version": "4.5.5", - "resolved": "https://registry.npmjs.org/@fontsource/roboto/-/roboto-4.5.5.tgz", - "integrity": "sha512-Pe1p+gAO6K0aLxBXlLoJRHVx352tVc/v/7DOnvM3t+FYXb+KUga9aCD1NpnDfd0kKnWXqrZyAXguyyFWDDuphw==", + "version": "4.5.7", + "resolved": "https://registry.npmjs.org/@fontsource/roboto/-/roboto-4.5.7.tgz", + "integrity": "sha512-m57UMER23Mk6Drg9OjtHW1Y+0KPGyZfE5XJoPTOsLARLar6013kJj4X2HICt+iFLJqIgTahA/QAvSn9lwF1EEw==", "dev": true }, "@fortawesome/fontawesome-common-types": { @@ -10460,28 +10180,100 @@ "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", "dev": true }, + "@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==", + "devOptional": true, + "requires": { + "@jridgewell/set-array": "^1.0.0", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, "@jridgewell/resolve-uri": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.5.tgz", - "integrity": "sha512-VPeQ7+wH0itvQxnG+lIzWgkysKIr3L9sslimFW55rHMdGu/qCQ5z5h9zq4gI8uBtqkpHhsF4Z/OwExufUCThew==", - "dev": true + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.7.tgz", + "integrity": "sha512-8cXDaBBHOr2pQ7j77Y6Vp5VDT2sIqWyWQ56TjEq4ih/a4iST3dItRe8Q9fp0rrIl9DoKhWQtUQz/YpOxLkXbNA==", + "devOptional": true + }, + "@jridgewell/set-array": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.1.tgz", + "integrity": "sha512-Ct5MqZkLGEXTVmQYbGtx9SVqD2fqwvdubdps5D3djjAkgkKwT918VNOz65pEHFaYTeWcukmJmH5SwsA9Tn2ObQ==", + "devOptional": true }, "@jridgewell/sourcemap-codec": { - "version": "1.4.11", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.11.tgz", - "integrity": "sha512-Fg32GrJo61m+VqYSdRSjRXMjQ06j8YIYfcTqndLYVAaHmroZHLJZCydsWBOTDqXS2v+mjxohBWEMfg97GXmYQg==", - "dev": true + "version": "1.4.13", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.13.tgz", + "integrity": "sha512-GryiOJmNcWbovBxTfZSF71V/mXbgcV3MewDe3kIMCLyIh5e7SKAeUZs+rMnJ8jkMolZ/4/VsdBmMrw3l+VdZ3w==", + "devOptional": true }, "@jridgewell/trace-mapping": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.4.tgz", - "integrity": "sha512-vFv9ttIedivx0ux3QSjhgtCVjPZd5l46ZOMDSCwnH1yUO2e964gO8LZGyv2QkqcgR6TnBU1v+1IFqmeoG+0UJQ==", - "dev": true, + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.13.tgz", + "integrity": "sha512-o1xbKhp9qnIAoHJSWd6KlCZfqslL4valSF81H8ImioOAxluWYWOpWkpyktY2vnt4tbrX9XYaxovq6cgowaJp2w==", + "devOptional": true, "requires": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" } }, + "@mantine/core": { + "version": "4.2.7", + "resolved": "https://registry.npmjs.org/@mantine/core/-/core-4.2.7.tgz", + "integrity": "sha512-WlieaDsqsFhtebRhP/pFNCuqTqPCihkNHHPL6tbd02psEqM8crPrktaO9cAJNyHa3Jna8eUthRRMp8737IHDjg==", + "requires": { + "@mantine/styles": "4.2.7", + "@popperjs/core": "^2.9.3", + "@radix-ui/react-scroll-area": "^0.1.1", + "react-popper": "^2.2.5", + "react-textarea-autosize": "^8.3.2" + } + }, + "@mantine/dropzone": { + "version": "4.2.7", + "resolved": "https://registry.npmjs.org/@mantine/dropzone/-/dropzone-4.2.7.tgz", + "integrity": "sha512-eQTVX5hClHNYR6UzNa4P559LsbfdqNHJUu/P7TiIvwIHqKRVjDRkuSZMciSpWqBueBfzrdCZQ32exb3l299Xfg==", + "dev": true, + "requires": { + "react-dropzone": "^11.4.2" + } + }, + "@mantine/hooks": { + "version": "4.2.7", + "resolved": "https://registry.npmjs.org/@mantine/hooks/-/hooks-4.2.7.tgz", + "integrity": "sha512-lBzoVjiqCCbQyr9YIRReFCo2jSXAZGSOgf1QDVa4rq3BxkwVDBsriHOpvG9h4mq2sWh4sjzPvfgy/OK/e2QpYQ==", + "requires": {} + }, + "@mantine/modals": { + "version": "4.2.7", + "resolved": "https://registry.npmjs.org/@mantine/modals/-/modals-4.2.7.tgz", + "integrity": "sha512-BxTqsX/z4fJudYsUQ0dWoman/AQClsXVpeWh9zrceRvJQHdtLjL1H8ZfY8WeXYEwkM5iMelSpz9TTkHx+/Shwg==", + "dev": true, + "requires": {} + }, + "@mantine/notifications": { + "version": "4.2.7", + "resolved": "https://registry.npmjs.org/@mantine/notifications/-/notifications-4.2.7.tgz", + "integrity": "sha512-vENIJTyCJMt6yDSsTRlyzFo9xFbivssqQoILOhc03nUvNepfiibcNsOvCAen7r3A+BKYgLYxlKxPVNyLtQ4AUA==", + "dev": true, + "requires": { + "react-transition-group": "^4.4.2" + } + }, + "@mantine/styles": { + "version": "4.2.7", + "resolved": "https://registry.npmjs.org/@mantine/styles/-/styles-4.2.7.tgz", + "integrity": "sha512-Ox9tgVqACQYAR7U1OvXELIoHUvPQS6ke4hXEa4Lzo6ErPN7kpopbve/HwJbcuipqieomvXkMCY4Fyt1pBt0xSQ==", + "requires": { + "@emotion/cache": "11.7.1", + "@emotion/react": "11.7.1", + "@emotion/serialize": "1.0.2", + "@emotion/utils": "1.0.0", + "clsx": "^1.1.1", + "csstype": "3.0.9" + } + }, "@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -10509,40 +10301,115 @@ } }, "@popperjs/core": { - "version": "2.11.4", - "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.4.tgz", - "integrity": "sha512-q/ytXxO5NKvyT37pmisQAItCFqA7FD/vNb8dgaJy3/630Fsc+Mz9/9f2SziBoIZ30TJooXyTwZmhi1zjXmObYg==" + "version": "2.11.5", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.5.tgz", + "integrity": "sha512-9X2obfABZuDVLCgPK9aX0a/x4jaOEweTTWE2+9sr0Qqqevj2Uv5XorvusThmc9XGYpS9yI+fhh8RTafBtGposw==" }, - "@reduxjs/toolkit": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.8.1.tgz", - "integrity": "sha512-Q6mzbTpO9nOYRnkwpDlFOAbQnd3g7zj7CtHAZWz5SzE5lcV97Tf8f3SzOO8BoPOMYBFgfZaqTUZqgGu+a0+Fng==", - "dev": true, + "@radix-ui/number": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-0.1.0.tgz", + "integrity": "sha512-rpf6QiOWLHAkM4FEMYu9i+5Jr8cKT893+R4mPpcdsy4LD7omr9JfdOqj/h/xPA5+EcVrpMMlU6rrRYpUB5UI8g==", "requires": { - "immer": "^9.0.7", - "redux": "^4.1.2", - "redux-thunk": "^2.4.1", - "reselect": "^4.1.5" + "@babel/runtime": "^7.13.10" } }, - "@restart/context": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@restart/context/-/context-2.1.4.tgz", - "integrity": "sha512-INJYZQJP7g+IoDUh/475NlGiTeMfwTXUEr3tmRneckHIxNolGOW9CTq83S8cxq0CgJwwcMzMJFchxvlwe7Rk8Q==", - "requires": {} + "@radix-ui/primitive": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-0.1.0.tgz", + "integrity": "sha512-tqxZKybwN5Fa3VzZry4G6mXAAb9aAqKmPtnVbZpL0vsBwvOHTBwsjHVPXylocYLwEtBY9SCe665bYnNB515uoA==", + "requires": { + "@babel/runtime": "^7.13.10" + } + }, + "@radix-ui/react-compose-refs": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-0.1.0.tgz", + "integrity": "sha512-eyclbh+b77k+69Dk72q3694OHrn9B3QsoIRx7ywX341U9RK1ThgQjMFZoPtmZNQTksXHLNEiefR8hGVeFyInGg==", + "requires": { + "@babel/runtime": "^7.13.10" + } }, - "@restart/hooks": { - "version": "0.3.27", - "resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.3.27.tgz", - "integrity": "sha512-s984xV/EapUIfkjlf8wz9weP2O9TNKR96C68FfMEy2bE69+H4cNv3RD4Mf97lW7Htt7PjZrYTjSC8f3SB9VCXw==", + "@radix-ui/react-context": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-0.1.1.tgz", + "integrity": "sha512-PkyVX1JsLBioeu0jB9WvRpDBBLtLZohVDT3BB5CTSJqActma8S8030P57mWZb4baZifMvN7KKWPAA40UmWKkQg==", "requires": { - "dequal": "^2.0.2" + "@babel/runtime": "^7.13.10" + } + }, + "@radix-ui/react-presence": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-0.1.2.tgz", + "integrity": "sha512-3BRlFZraooIUfRlyN+b/Xs5hq1lanOOo/+3h6Pwu2GMFjkGKKa4Rd51fcqGqnVlbr3jYg+WLuGyAV4KlgqwrQw==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "0.1.0", + "@radix-ui/react-use-layout-effect": "0.1.0" + } + }, + "@radix-ui/react-primitive": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-0.1.4.tgz", + "integrity": "sha512-6gSl2IidySupIMJFjYnDIkIWRyQdbu/AHK7rbICPani+LW4b0XdxBXc46og/iZvuwW8pjCS8I2SadIerv84xYA==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-slot": "0.1.2" + } + }, + "@radix-ui/react-scroll-area": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-scroll-area/-/react-scroll-area-0.1.4.tgz", + "integrity": "sha512-QHxRsjy+hsHwQYJ9cCNgSJ5+6ioZu1KhwD1UOXoHNciuFGMX08v+uJPKXIz+ySv03Rx6cOz6f/Fk5aPHRMFi/A==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/number": "0.1.0", + "@radix-ui/primitive": "0.1.0", + "@radix-ui/react-compose-refs": "0.1.0", + "@radix-ui/react-context": "0.1.1", + "@radix-ui/react-presence": "0.1.2", + "@radix-ui/react-primitive": "0.1.4", + "@radix-ui/react-use-callback-ref": "0.1.0", + "@radix-ui/react-use-direction": "0.1.0", + "@radix-ui/react-use-layout-effect": "0.1.0" + } + }, + "@radix-ui/react-slot": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-0.1.2.tgz", + "integrity": "sha512-ADkqfL+agEzEguU3yS26jfB50hRrwf7U4VTwAOZEmi/g+ITcBWe12yM46ueS/UCIMI9Py+gFUaAdxgxafFvY2Q==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "0.1.0" + } + }, + "@radix-ui/react-use-callback-ref": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-0.1.0.tgz", + "integrity": "sha512-Va041McOFFl+aV+sejvl0BS2aeHx86ND9X/rVFmEFQKTXCp6xgUK0NGUAGcgBlIjnJSbMYPGEk1xKSSlVcN2Aw==", + "requires": { + "@babel/runtime": "^7.13.10" + } + }, + "@radix-ui/react-use-direction": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-direction/-/react-use-direction-0.1.0.tgz", + "integrity": "sha512-NajpY/An9TCPSfOVkgWIdXJV+VuWl67PxB6kOKYmtNAFHvObzIoh8o0n9sAuwSAyFCZVq211FEf9gvVDRhOyiA==", + "requires": { + "@babel/runtime": "^7.13.10" + } + }, + "@radix-ui/react-use-layout-effect": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-0.1.0.tgz", + "integrity": "sha512-+wdeS51Y+E1q1Wmd+1xSSbesZkpVj4jsg0BojCbopWvgq5iBvixw5vgemscdh58ep98BwUbsFYnrywFhV9yrVg==", + "requires": { + "@babel/runtime": "^7.13.10" } }, "@rollup/pluginutils": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.2.0.tgz", - "integrity": "sha512-2WUyJNRkyH5p487pGnn4tWAsxhEFKN/pT8CMgHshd5H+IXkOnKvKZwsz5ZWz+YCXkleZRAU5kwbfgF8CPfDRqA==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.2.1.tgz", + "integrity": "sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==", "dev": true, "requires": { "estree-walker": "^2.0.1", @@ -10550,25 +10417,20 @@ } }, "@rushstack/eslint-patch": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.1.1.tgz", - "integrity": "sha512-BUyKJGdDWqvWC5GEhyOiUrGNi9iJUr4CU0O2WxJL6QJhHeeA/NVBalH+FeK0r/x/W0rPymXt5s78TDS7d6lCwg==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.1.3.tgz", + "integrity": "sha512-WiBSI6JBIhC6LRIsB2Kwh8DsGTlbBU+mLRxJmAe3LjHTdkDpwIbEOZgoXBbZilk/vlfjK8i6nKRAvIRn1XaIMw==", "dev": true }, - "@socket.io/base64-arraybuffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@socket.io/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz", - "integrity": "sha512-dOlCBKnDw4iShaIsH/bxujKTM18+2TOAsYz+KSc11Am38H4q5Xw8Bbz97ZYdrVNM+um3p7w86Bvvmcn9q+5+eQ==" - }, "@socket.io/component-emitter": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.0.0.tgz", - "integrity": "sha512-2pTGuibAXJswAPJjaKisthqS/NOK5ypG4LYT6tEAV0S/mxW0zOIvYvGK0V8w8+SHxAm6vRMSjqSalFXeBAqs+Q==" + "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==" }, "@testing-library/dom": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.12.0.tgz", - "integrity": "sha512-rBrJk5WjI02X1edtiUcZhgyhgBhiut96r5Jp8J5qktKdcvLcZpKDW8i2hkGMMItxrghjXuQ5AM6aE0imnFawaw==", + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.13.0.tgz", + "integrity": "sha512-9VHgfIatKNXQNaZTtLnalIy0jNZzY35a4S3oi08YAt9Hv1VsfZ/DfA45lM8D/UhtHBGJ4/lGwp0PZkVndRkoOQ==", "dev": true, "requires": { "@babel/code-frame": "^7.10.4", @@ -10582,9 +10444,9 @@ } }, "@testing-library/jest-dom": { - "version": "5.16.3", - "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.16.3.tgz", - "integrity": "sha512-u5DfKj4wfSt6akfndfu1eG06jsdyA/IUrlX2n3pyq5UXgXMhXY+NJb8eNK/7pqPWAhCKsCGWDdDO0zKMKAYkEA==", + "version": "5.16.4", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.16.4.tgz", + "integrity": "sha512-Gy+IoFutbMQcky0k+bqqumXZ1cTGswLsFqmNLzNdSKkU9KGV2u9oXhukCbbJ9/LRPKiqwxEE8VpV/+YZlfkPUA==", "dev": true, "requires": { "@babel/runtime": "^7.9.2", @@ -10611,33 +10473,30 @@ } }, "@testing-library/react": { - "version": "12.1.4", - "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-12.1.4.tgz", - "integrity": "sha512-jiPKOm7vyUw311Hn/HlNQ9P8/lHNtArAx0PisXyFixDDvfl8DbD6EUdbshK5eqauvBSvzZd19itqQ9j3nferJA==", + "version": "12.1.5", + "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-12.1.5.tgz", + "integrity": "sha512-OfTXCJUFgjd/digLUuPxa0+/3ZxsQmE7ub9kcbW/wi96Bh3o/p5vrETcBGfP17NWPGqeYYl5LTRpwyGoMC4ysg==", "dev": true, "requires": { "@babel/runtime": "^7.12.5", "@testing-library/dom": "^8.0.0", - "@types/react-dom": "*" + "@types/react-dom": "<18.0.0" } }, "@testing-library/react-hooks": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@testing-library/react-hooks/-/react-hooks-7.0.2.tgz", - "integrity": "sha512-dYxpz8u9m4q1TuzfcUApqi8iFfR6R0FaMbr2hjZJy1uC8z+bO/K4v8Gs9eogGKYQop7QsrBTFkv/BCF7MzD2Cg==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@testing-library/react-hooks/-/react-hooks-8.0.0.tgz", + "integrity": "sha512-uZqcgtcUUtw7Z9N32W13qQhVAD+Xki2hxbTR461MKax8T6Jr8nsUvZB+vcBTkzY2nFvsUet434CsgF0ncW2yFw==", "dev": true, "requires": { "@babel/runtime": "^7.12.5", - "@types/react": ">=16.9.0", - "@types/react-dom": ">=16.9.0", - "@types/react-test-renderer": ">=16.9.0", "react-error-boundary": "^3.1.0" } }, "@testing-library/user-event": { - "version": "14.0.4", - "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.0.4.tgz", - "integrity": "sha512-VBZe5lcUsmrQyOwIFvqOxLBoaTw1/Qy4Ek+VgmFYs719bs2SxUp42vbsb7ATlQDkHdj4OIQlucfpwxe5WoG1jA==", + "version": "14.2.0", + "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.2.0.tgz", + "integrity": "sha512-+hIlG4nJS6ivZrKnOP7OGsDu9Fxmryj9vCl8x0ZINtTJcCHs2zLsYif5GzuRiBF2ck5GZG2aQr7Msg+EHlnYVQ==", "dev": true, "requires": {} }, @@ -10653,20 +10512,10 @@ "integrity": "sha512-HnYpAE1Y6kRyKM/XkEuiRQhTHvkzMBurTHnpFLYLBGPIylZNPs9jJcuOOYWxPLJCSEtmZT0Y8rHDokKN7rRTig==", "dev": true }, - "@types/bootstrap": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/@types/bootstrap/-/bootstrap-4.6.1.tgz", - "integrity": "sha512-Frg9beNcvrS9gouBeJxkAq7UzoWh5W91J6FIIlJYquf9XE7f0lkqn096KjJ0U7Jgo17oNO4pxDICfXvsCotfWQ==", - "dev": true, - "requires": { - "@types/jquery": "*", - "popper.js": "^1.14.1" - } - }, "@types/chai": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.0.tgz", - "integrity": "sha512-/ceqdqeRraGolFTcfoXNiqjyQhZzbINDngeoAq9GoHa8PPK1yNzTaxWjA6BFWp5Ua9JpXEMSS4s5i9tS0hOJtw==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.1.tgz", + "integrity": "sha512-/zPMqDkzSZ8t3VtxOa4KPq7uzzW978M9Tvh+j7GHKuo6k6GTLxPJ4J5gE5cjfJ26pnXst0N5Hax8Sr0T2Mi9zQ==", "dev": true }, "@types/chai-subset": { @@ -10678,84 +10527,16 @@ "@types/chai": "*" } }, - "@types/d3-color": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-2.0.3.tgz", - "integrity": "sha512-+0EtEjBfKEDtH9Rk3u3kLOUXM5F+iZK+WvASPb0MhIZl8J8NUvGeZRwKCXl+P3HkYx5TdU4YtcibpqHkSR9n7w==", - "dev": true - }, - "@types/d3-interpolate": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-2.0.2.tgz", - "integrity": "sha512-lElyqlUfIPyWG/cD475vl6msPL4aMU7eJvx1//Q177L8mdXoVPFl1djIESF2FKnc0NyaHvQlJpWwKJYwAhUoCw==", - "dev": true, - "requires": { - "@types/d3-color": "^2" - } - }, - "@types/d3-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-2.0.2.tgz", - "integrity": "sha512-3YHpvDw9LzONaJzejXLOwZ3LqwwkoXb9LI2YN7Hbd6pkGo5nIlJ09ul4bQhBN4hQZJKmUpX8HkVqbzgUKY48cg==", - "dev": true - }, - "@types/d3-scale": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-3.3.2.tgz", - "integrity": "sha512-gGqr7x1ost9px3FvIfUMi5XA/F/yAf4UkUDtdQhpH92XCT0Oa7zkkRzY61gPVJq+DxpHn/btouw5ohWkbBsCzQ==", - "dev": true, - "requires": { - "@types/d3-time": "^2" - } - }, - "@types/d3-shape": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-2.1.3.tgz", - "integrity": "sha512-HAhCel3wP93kh4/rq+7atLdybcESZ5bRHDEZUojClyZWsRuEMo3A52NGYJSh48SxfxEU6RZIVbZL2YFZ2OAlzQ==", - "dev": true, - "requires": { - "@types/d3-path": "^2" - } - }, - "@types/d3-time": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-2.1.1.tgz", - "integrity": "sha512-9MVYlmIgmRR31C5b4FVSWtuMmBHh2mOWQYfl7XAYOa8dsnb7iEmUmRSWSFgXFtkjxO65d7hTUHQC+RhR/9IWFg==", - "dev": true - }, - "@types/hoist-non-react-statics": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz", - "integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==", - "requires": { - "@types/react": "*", - "hoist-non-react-statics": "^3.3.0" - } - }, - "@types/invariant": { - "version": "2.2.35", - "resolved": "https://registry.npmjs.org/@types/invariant/-/invariant-2.2.35.tgz", - "integrity": "sha512-DxX1V9P8zdJPYQat1gHyY0xj3efl8gnMVjiM9iCY6y27lj+PoQWkgjt8jDqmovPqULkKVpKRg8J36iQiA+EtEg==" - }, "@types/jest": { - "version": "27.4.1", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.4.1.tgz", - "integrity": "sha512-23iPJADSmicDVrWk+HT58LMJtzLAnB2AgIzplQuq/bSrGaxCrlvRFjGbXmamnnk/mAmCdLStiGqggu28ocUyiw==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.5.1.tgz", + "integrity": "sha512-fUy7YRpT+rHXto1YlL+J9rs0uLGyiqVt3ZOTQR+4ROc47yNl8WLdVLgUloBRhOxP1PZvguHl44T3H0wAWxahYQ==", "dev": true, "requires": { "jest-matcher-utils": "^27.0.0", "pretty-format": "^27.0.0" } }, - "@types/jquery": { - "version": "3.5.14", - "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.5.14.tgz", - "integrity": "sha512-X1gtMRMbziVQkErhTQmSe2jFwwENA/Zr+PprCkF63vFq+Yt5PZ4AlKqgmeNlwgn7dhsXEK888eIW2520EpC+xg==", - "dev": true, - "requires": { - "@types/sizzle": "*" - } - }, "@types/json-schema": { "version": "7.0.11", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", @@ -10765,13 +10546,13 @@ "@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", "dev": true }, "@types/lodash": { - "version": "4.14.181", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.181.tgz", - "integrity": "sha512-n3tyKthHJbkiWhDZs3DkhkCzt2MexYHXlX0td5iMplyfwketaOeKboEVBqzceH7juqvEg3q5oUoBFxSLu7zFag==", + "version": "4.14.182", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.182.tgz", + "integrity": "sha512-/THyiqyQAP9AfARo4pF+aCGcyiQ94tX/Is2I7HofNRqoYLgN1PBoOWu2/zTA5zMxzP5EFutMtWtGAFRKUe961Q==", "dev": true }, "@types/minimatch": { @@ -10781,9 +10562,9 @@ "dev": true }, "@types/node": { - "version": "17.0.23", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.23.tgz", - "integrity": "sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==", + "version": "17.0.36", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.36.tgz", + "integrity": "sha512-V3orv+ggDsWVHP99K3JlwtH20R7J4IhI1Kksgc+64q5VxgfRkQG8Ws3MFm/FZOKDYGy9feGFlZ70/HpCNe9QaA==", "dev": true }, "@types/parse-json": { @@ -10793,14 +10574,16 @@ "dev": true }, "@types/prop-types": { - "version": "15.7.4", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.4.tgz", - "integrity": "sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ==" + "version": "15.7.5", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", + "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==", + "dev": true }, "@types/react": { - "version": "17.0.43", - "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.43.tgz", - "integrity": "sha512-8Q+LNpdxf057brvPu1lMtC5Vn7J119xrP1aq4qiaefNioQUYANF/CYeK4NsKorSZyUGJ66g0IM+4bbjwx45o2A==", + "version": "17.0.45", + "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.45.tgz", + "integrity": "sha512-YfhQ22Lah2e3CHPsb93tRwIGNiSwkuz1/blk4e6QrWS0jQzCSNbGLtOEYhPg02W0yGTTmpajp7dCTbBAMN3qsg==", + "dev": true, "requires": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -10808,60 +10591,23 @@ } }, "@types/react-dom": { - "version": "17.0.14", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.14.tgz", - "integrity": "sha512-H03xwEP1oXmSfl3iobtmQ/2dHF5aBHr8aUMwyGZya6OW45G+xtdzmq6HkncefiBt5JU8DVyaWl/nWZbjZCnzAQ==", - "dev": true, - "requires": { - "@types/react": "*" - } - }, - "@types/react-helmet": { - "version": "6.1.5", - "resolved": "https://registry.npmjs.org/@types/react-helmet/-/react-helmet-6.1.5.tgz", - "integrity": "sha512-/ICuy7OHZxR0YCAZLNg9r7I9aijWUWvxaPR6uTuyxe8tAj5RL4Sw1+R6NhXUtOsarkGYPmaHdBDvuXh2DIN/uA==", + "version": "17.0.17", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.17.tgz", + "integrity": "sha512-VjnqEmqGnasQKV0CWLevqMTXBYG9GbwuE6x3VetERLh0cq2LTptFE73MrQi2S7GkKXCf2GgwItB/melLnxfnsg==", "dev": true, "requires": { - "@types/react": "*" - } - }, - "@types/react-redux": { - "version": "7.1.23", - "resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.23.tgz", - "integrity": "sha512-D02o3FPfqQlfu2WeEYwh3x2otYd2Dk1o8wAfsA0B1C2AJEFxE663Ozu7JzuWbznGgW248NaOF6wsqCGNq9d3qw==", - "requires": { - "@types/hoist-non-react-statics": "^3.3.0", - "@types/react": "*", - "hoist-non-react-statics": "^3.3.0", - "redux": "^4.0.0" + "@types/react": "^17" } }, "@types/react-table": { - "version": "7.7.10", - "resolved": "https://registry.npmjs.org/@types/react-table/-/react-table-7.7.10.tgz", - "integrity": "sha512-yt7FHv/2cFsucStSWLBOB3OmsRZF08DvVHzz8Zg41B4tzRL6pQ+5VYvmhaR1dKS//tDG4UOJ1RQJPEINHYoRtg==", + "version": "7.7.12", + "resolved": "https://registry.npmjs.org/@types/react-table/-/react-table-7.7.12.tgz", + "integrity": "sha512-bRUent+NR/WwtDGwI/BqhZ8XnHghwHw0HUKeohzB5xN3K2qKWYE5w19e7GCuOkL1CXD9Gi1HFy7TIm2AvgWUHg==", "dev": true, "requires": { "@types/react": "*" } }, - "@types/react-test-renderer": { - "version": "17.0.1", - "resolved": "https://registry.npmjs.org/@types/react-test-renderer/-/react-test-renderer-17.0.1.tgz", - "integrity": "sha512-3Fi2O6Zzq/f3QR9dRnlnHso9bMl7weKCviFmfF6B4LS1Uat6Hkm15k0ZAQuDz+UBq6B3+g+NM6IT2nr5QgPzCw==", - "dev": true, - "requires": { - "@types/react": "*" - } - }, - "@types/react-transition-group": { - "version": "4.4.4", - "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.4.tgz", - "integrity": "sha512-7gAPz7anVK5xzbeQW9wFBDg7G++aPLAFY0QaSMOou9rJZpbuI58WAuJrgu+qR92l61grlnCUe7AFX8KGahAgug==", - "requires": { - "@types/react": "*" - } - }, "@types/resize-observer-browser": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/@types/resize-observer-browser/-/resize-observer-browser-0.1.7.tgz", @@ -10871,12 +10617,7 @@ "@types/scheduler": { "version": "0.16.2", "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", - "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==" - }, - "@types/sizzle": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.3.tgz", - "integrity": "sha512-JYM8x9EGF163bEyhdJBpR2QX1R5naCJHC8ucJylJ3w9/CVBaskdQ8WqBf8MmQrd1kRvp/a4TS8HJ+bxzR7ZJYQ==", + "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==", "dev": true }, "@types/testing-library__jest-dom": { @@ -10888,32 +10629,27 @@ "@types/jest": "*" } }, - "@types/warning": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/warning/-/warning-3.0.0.tgz", - "integrity": "sha1-DSUBJorY+ZYrdA04fEZU9fjiPlI=" - }, "@typescript-eslint/eslint-plugin": { - "version": "5.17.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.17.0.tgz", - "integrity": "sha512-qVstvQilEd89HJk3qcbKt/zZrfBZ+9h2ynpAGlWjWiizA7m/MtLT9RoX6gjtpE500vfIg8jogAkDzdCxbsFASQ==", + "version": "5.27.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.27.0.tgz", + "integrity": "sha512-DDrIA7GXtmHXr1VCcx9HivA39eprYBIFxbQEHI6NyraRDxCGpxAFiYQAT/1Y0vh1C+o2vfBiy4IuPoXxtTZCAQ==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.17.0", - "@typescript-eslint/type-utils": "5.17.0", - "@typescript-eslint/utils": "5.17.0", - "debug": "^4.3.2", + "@typescript-eslint/scope-manager": "5.27.0", + "@typescript-eslint/type-utils": "5.27.0", + "@typescript-eslint/utils": "5.27.0", + "debug": "^4.3.4", "functional-red-black-tree": "^1.0.1", - "ignore": "^5.1.8", + "ignore": "^5.2.0", "regexpp": "^3.2.0", - "semver": "^7.3.5", + "semver": "^7.3.7", "tsutils": "^3.21.0" }, "dependencies": { "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", "dev": true, "requires": { "lru-cache": "^6.0.0" @@ -10922,72 +10658,72 @@ } }, "@typescript-eslint/experimental-utils": { - "version": "5.17.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.17.0.tgz", - "integrity": "sha512-U4sM5z0/ymSYqQT6I7lz8l0ZZ9zrya5VIwrwAP5WOJVabVtVsIpTMxPQe+D3qLyePT+VlETUTO2nA1+PufPx9Q==", + "version": "5.27.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.27.0.tgz", + "integrity": "sha512-ZOn342bYh19IYvkiorrqnzNoRAr91h3GiFSSfa4tlHV+R9GgR8SxCwAi8PKMyT8+pfwMxfQdNbwKsMurbF9hzg==", "dev": true, "requires": { - "@typescript-eslint/utils": "5.17.0" + "@typescript-eslint/utils": "5.27.0" } }, "@typescript-eslint/parser": { - "version": "5.17.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.17.0.tgz", - "integrity": "sha512-aRzW9Jg5Rlj2t2/crzhA2f23SIYFlF9mchGudyP0uiD6SenIxzKoLjwzHbafgHn39dNV/TV7xwQkLfFTZlJ4ig==", + "version": "5.27.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.27.0.tgz", + "integrity": "sha512-8oGjQF46c52l7fMiPPvX4It3u3V3JipssqDfHQ2hcR0AeR8Zge+OYyKUCm5b70X72N1qXt0qgHenwN6Gc2SXZA==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.17.0", - "@typescript-eslint/types": "5.17.0", - "@typescript-eslint/typescript-estree": "5.17.0", - "debug": "^4.3.2" + "@typescript-eslint/scope-manager": "5.27.0", + "@typescript-eslint/types": "5.27.0", + "@typescript-eslint/typescript-estree": "5.27.0", + "debug": "^4.3.4" } }, "@typescript-eslint/scope-manager": { - "version": "5.17.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.17.0.tgz", - "integrity": "sha512-062iCYQF/doQ9T2WWfJohQKKN1zmmXVfAcS3xaiialiw8ZUGy05Em6QVNYJGO34/sU1a7a+90U3dUNfqUDHr3w==", + "version": "5.27.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.27.0.tgz", + "integrity": "sha512-VnykheBQ/sHd1Vt0LJ1JLrMH1GzHO+SzX6VTXuStISIsvRiurue/eRkTqSrG0CexHQgKG8shyJfR4o5VYioB9g==", "dev": true, "requires": { - "@typescript-eslint/types": "5.17.0", - "@typescript-eslint/visitor-keys": "5.17.0" + "@typescript-eslint/types": "5.27.0", + "@typescript-eslint/visitor-keys": "5.27.0" } }, "@typescript-eslint/type-utils": { - "version": "5.17.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.17.0.tgz", - "integrity": "sha512-3hU0RynUIlEuqMJA7dragb0/75gZmwNwFf/QJokWzPehTZousP/MNifVSgjxNcDCkM5HI2K22TjQWUmmHUINSg==", + "version": "5.27.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.27.0.tgz", + "integrity": "sha512-vpTvRRchaf628Hb/Xzfek+85o//zEUotr1SmexKvTfs7czXfYjXVT/a5yDbpzLBX1rhbqxjDdr1Gyo0x1Fc64g==", "dev": true, "requires": { - "@typescript-eslint/utils": "5.17.0", - "debug": "^4.3.2", + "@typescript-eslint/utils": "5.27.0", + "debug": "^4.3.4", "tsutils": "^3.21.0" } }, "@typescript-eslint/types": { - "version": "5.17.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.17.0.tgz", - "integrity": "sha512-AgQ4rWzmCxOZLioFEjlzOI3Ch8giDWx8aUDxyNw9iOeCvD3GEYAB7dxWGQy4T/rPVe8iPmu73jPHuaSqcjKvxw==", + "version": "5.27.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.27.0.tgz", + "integrity": "sha512-lY6C7oGm9a/GWhmUDOs3xAVRz4ty/XKlQ2fOLr8GAIryGn0+UBOoJDWyHer3UgrHkenorwvBnphhP+zPmzmw0A==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "5.17.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.17.0.tgz", - "integrity": "sha512-X1gtjEcmM7Je+qJRhq7ZAAaNXYhTgqMkR10euC4Si6PIjb+kwEQHSxGazXUQXFyqfEXdkGf6JijUu5R0uceQzg==", + "version": "5.27.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.27.0.tgz", + "integrity": "sha512-QywPMFvgZ+MHSLRofLI7BDL+UczFFHyj0vF5ibeChDAJgdTV8k4xgEwF0geFhVlPc1p8r70eYewzpo6ps+9LJQ==", "dev": true, "requires": { - "@typescript-eslint/types": "5.17.0", - "@typescript-eslint/visitor-keys": "5.17.0", - "debug": "^4.3.2", - "globby": "^11.0.4", + "@typescript-eslint/types": "5.27.0", + "@typescript-eslint/visitor-keys": "5.27.0", + "debug": "^4.3.4", + "globby": "^11.1.0", "is-glob": "^4.0.3", - "semver": "^7.3.5", + "semver": "^7.3.7", "tsutils": "^3.21.0" }, "dependencies": { "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", "dev": true, "requires": { "lru-cache": "^6.0.0" @@ -10996,15 +10732,15 @@ } }, "@typescript-eslint/utils": { - "version": "5.17.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.17.0.tgz", - "integrity": "sha512-DVvndq1QoxQH+hFv+MUQHrrWZ7gQ5KcJzyjhzcqB1Y2Xes1UQQkTRPUfRpqhS8mhTWsSb2+iyvDW1Lef5DD7vA==", + "version": "5.27.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.27.0.tgz", + "integrity": "sha512-nZvCrkIJppym7cIbP3pOwIkAefXOmfGPnCM0LQfzNaKxJHI6VjI8NC662uoiPlaf5f6ymkTy9C3NQXev2mdXmA==", "dev": true, "requires": { "@types/json-schema": "^7.0.9", - "@typescript-eslint/scope-manager": "5.17.0", - "@typescript-eslint/types": "5.17.0", - "@typescript-eslint/typescript-estree": "5.17.0", + "@typescript-eslint/scope-manager": "5.27.0", + "@typescript-eslint/types": "5.27.0", + "@typescript-eslint/typescript-estree": "5.27.0", "eslint-scope": "^5.1.1", "eslint-utils": "^3.0.0" }, @@ -11028,41 +10764,41 @@ } }, "@typescript-eslint/visitor-keys": { - "version": "5.17.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.17.0.tgz", - "integrity": "sha512-6K/zlc4OfCagUu7Am/BD5k8PSWQOgh34Nrv9Rxe2tBzlJ7uOeJ/h7ugCGDCeEZHT6k2CJBhbk9IsbkPI0uvUkA==", + "version": "5.27.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.27.0.tgz", + "integrity": "sha512-46cYrteA2MrIAjv9ai44OQDUoCZyHeGIc4lsjCUX2WT6r4C+kidz1bNiR4017wHOPUythYeH+Sc7/cFP97KEAA==", "dev": true, "requires": { - "@typescript-eslint/types": "5.17.0", - "eslint-visitor-keys": "^3.0.0" + "@typescript-eslint/types": "5.27.0", + "eslint-visitor-keys": "^3.3.0" } }, "@vitejs/plugin-react": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-1.3.0.tgz", - "integrity": "sha512-H+yIupjUE4a+E4oeWUv4xUJIMR0DWBIMUG/DYgvj0J9Vu1rdHAlJ5JdbI+N1KDUD7Ee2fZ1DMPZ/NBg6mXtoCw==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-1.3.2.tgz", + "integrity": "sha512-aurBNmMo0kz1O4qRoY+FM4epSA39y3ShWGuqfLRA/3z0oEJAdtoSfgA3aO98/PCCHAqMaduLxIxErWrVKIFzXA==", "dev": true, "requires": { - "@babel/core": "^7.17.8", + "@babel/core": "^7.17.10", "@babel/plugin-transform-react-jsx": "^7.17.3", "@babel/plugin-transform-react-jsx-development": "^7.16.7", "@babel/plugin-transform-react-jsx-self": "^7.16.7", "@babel/plugin-transform-react-jsx-source": "^7.16.7", - "@rollup/pluginutils": "^4.2.0", - "react-refresh": "^0.11.0", + "@rollup/pluginutils": "^4.2.1", + "react-refresh": "^0.13.0", "resolve": "^1.22.0" } }, "abab": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", - "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", + "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", "dev": true }, "acorn": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", - "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", + "version": "8.7.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz", + "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==", "dev": true }, "acorn-globals": { @@ -11170,14 +10906,14 @@ "dev": true }, "array-includes": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.4.tgz", - "integrity": "sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.5.tgz", + "integrity": "sha512-iSDYZMMyTPkiFasVqfuAQnWAYcvO/SeBSCGKePoEthjp4LEMTe4uLc7b025o4jAZpHhihh8xPo99TNWUWWkGDQ==", "dev": true, "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1", + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5", "get-intrinsic": "^1.1.1", "is-string": "^1.0.7" } @@ -11189,25 +10925,27 @@ "dev": true }, "array.prototype.flat": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.5.tgz", - "integrity": "sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.0.tgz", + "integrity": "sha512-12IUEkHsAhA4DY5s0FPgNXIdc8VRSqD9Zp78a5au9abH/SOBrsp082JOWFNTjkMozh8mqcdiKuaLGhPeYztxSw==", "dev": true, "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.19.0" + "es-abstract": "^1.19.2", + "es-shim-unscopables": "^1.0.0" } }, "array.prototype.flatmap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.2.5.tgz", - "integrity": "sha512-08u6rVyi1Lj7oqWbS9nUxliETrtIROT4XGTA4D/LWGten6E3ocm7cy9SIrmNHOL5XVbVuckUp3X6Xyg8/zpvHA==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.0.tgz", + "integrity": "sha512-PZC9/8TKAIxcWKdyeb77EzULHPrIX/tIZebLJUQOMR1OwYosT8yggdfWScfTBCDj5utONvOuPQQumYsU2ULbkg==", "dev": true, "requires": { - "call-bind": "^1.0.0", + "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.19.0" + "es-abstract": "^1.19.2", + "es-shim-unscopables": "^1.0.0" } }, "arrify": { @@ -11225,13 +10963,13 @@ "ast-types-flow": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", - "integrity": "sha1-9wtzXGvKGlycItmCw+Oef+ujva0=", + "integrity": "sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==", "dev": true }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", "dev": true }, "atob": { @@ -11240,10 +10978,16 @@ "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", "dev": true }, + "attr-accept": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/attr-accept/-/attr-accept-2.2.2.tgz", + "integrity": "sha512-7prDjvt9HmqiZ0cl5CRjtS84sEyhsHP2coDkaZKRKVfCDo9s7iw7ChVmar78Gu9pC4SoR/28wFu/G5JJhTnqEg==", + "dev": true + }, "axe-core": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.4.1.tgz", - "integrity": "sha512-gd1kmb21kwNuWr6BQz8fv6GNECPBnUasepcoLbekws23NVBLODdsClRZ+bQ8+9Uomf3Sm3+Vwn0oYG9NvwnJCw==", + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.4.2.tgz", + "integrity": "sha512-LVAaGp/wkkgYJcjmHsoKx4juT1aQvJyPcW09MLCjVTh3V2cc6PnyempiLMNH5iMdfIX/zdbjUx2KDjMLCTdPeA==", "dev": true }, "axios": { @@ -11340,11 +11084,6 @@ "babel-plugin-transform-react-remove-prop-types": "^0.4.24" } }, - "backo2": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", - "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=" - }, "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -11361,13 +11100,6 @@ "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true }, - "bootstrap": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.6.1.tgz", - "integrity": "sha512-0dj+VgI9Ecom+rvvpNZ4MUZJz8dcX7WCX+eTID9+/8HgOkv3dsRzi8BGeZJCQU6flWQVYxwTQnEZFrmJSEO7og==", - "dev": true, - "requires": {} - }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -11408,15 +11140,15 @@ "dev": true }, "browserslist": { - "version": "4.20.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.2.tgz", - "integrity": "sha512-CQOBCqp/9pDvDbx3xfMi+86pr4KXIf2FDkTTdeuYw8OxS9t898LA1Khq57gtufFILXpfgsSx5woNgsBgvGjpsA==", - "dev": true, + "version": "4.20.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.3.tgz", + "integrity": "sha512-NBhymBQl1zM0Y5dQT/O+xiLP9/rzOIQdKM/eMJBAq7yBgaB6krIYLGejrwVYnSHZdqjscB1SPuAjHwxjvN6Wdg==", + "devOptional": true, "requires": { - "caniuse-lite": "^1.0.30001317", - "electron-to-chromium": "^1.4.84", + "caniuse-lite": "^1.0.30001332", + "electron-to-chromium": "^1.4.118", "escalade": "^3.1.1", - "node-releases": "^2.0.2", + "node-releases": "^2.0.3", "picocolors": "^1.0.0" } }, @@ -11437,10 +11169,10 @@ "dev": true }, "caniuse-lite": { - "version": "1.0.30001324", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001324.tgz", - "integrity": "sha512-/eYp1J6zYh1alySQB4uzYFkLmxxI8tk0kxldbNHXp8+v+rdMKdUBNjRLz7T7fz6Iox+1lIdYpc7rq6ZcXfTukg==", - "dev": true + "version": "1.0.30001344", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001344.tgz", + "integrity": "sha512-0ZFjnlCaXNOAYcV7i+TtdKBp0L/3XEU2MF/x6Du1lrh+SRX4IfzIVL4HNJg5pB2PmFb8rszIGyOvsZnqqRoc2g==", + "devOptional": true }, "chai": { "version": "4.3.6", @@ -11476,7 +11208,7 @@ "check-error": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==", "dev": true }, "chokidar": { @@ -11509,13 +11241,13 @@ "classnames": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz", - "integrity": "sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA==" + "integrity": "sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA==", + "dev": true }, "clsx": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.1.1.tgz", - "integrity": "sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA==", - "dev": true + "integrity": "sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA==" }, "color-convert": { "version": "2.0.1", @@ -11550,7 +11282,7 @@ "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, "confusing-browser-globals": { "version": "1.0.11", @@ -11562,18 +11294,18 @@ "version": "1.8.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", - "dev": true, + "devOptional": true, "requires": { "safe-buffer": "~5.1.1" } }, "core-js-compat": { - "version": "3.21.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.21.1.tgz", - "integrity": "sha512-gbgX5AUvMb8gwxC7FLVWYT7Kkgu/y7+h/h1X43yJkNqhlK2fuYyQimqvKGNZFAY6CKii/GFKJ2cp/1/42TN36g==", + "version": "3.22.7", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.22.7.tgz", + "integrity": "sha512-uI9DAQKKiiE/mclIC5g4AjRpio27g+VMRhe6rQoz+q4Wm4L6A/fJhiLtBw+sfOpDG9wZ3O0pxIw7GbfOlBgjOA==", "dev": true, "requires": { - "browserslist": "^4.19.1", + "browserslist": "^4.20.3", "semver": "7.0.0" }, "dependencies": { @@ -11586,9 +11318,9 @@ } }, "core-js-pure": { - "version": "3.21.1", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.21.1.tgz", - "integrity": "sha512-12VZfFIu+wyVbBebyHmRTuEE/tZrB4tJToWcwAMcsp3h4+sHR+fMJWbKpYiCRWlhFBq+KNyO8rIV9rTkeVmznQ==", + "version": "3.22.7", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.22.7.tgz", + "integrity": "sha512-wTriFxiZI+C8msGeh7fJcbC/a0V8fdInN1oS2eK79DMBGs8iIJiXhtFJCiT3rBa8w6zroHWW3p8ArlujZ/Mz+w==", "dev": true }, "cosmiconfig": { @@ -11624,14 +11356,6 @@ "inherits": "^2.0.4", "source-map": "^0.6.1", "source-map-resolve": "^0.6.0" - }, - "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 - } } }, "css-unit-converter": { @@ -11643,7 +11367,7 @@ "css.escape": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", - "integrity": "sha1-QuJ9T6BK4y+TGktNQZH6nN3ul8s=", + "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==", "dev": true }, "cssom": { @@ -11670,9 +11394,9 @@ } }, "csstype": { - "version": "3.0.11", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.11.tgz", - "integrity": "sha512-sa6P2wJ+CAbgyy4KFssIb/JNMLxFvKF1pCYCSXS8ZMuqZnMsrxqI2E5sPyoTpxoPU/gVZMzr2zjOfg8GIZOMsw==" + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.9.tgz", + "integrity": "sha512-rpw6JPxK6Rfg1zLOYCSwle2GFOOsnjmDYDaBwEcwoOg4qlsIVCN789VkBZDJAGi4T07gI4YSutR43t9Zz4Lzuw==" }, "d3-array": { "version": "2.12.1", @@ -11757,14 +11481,26 @@ "dev": true }, "data-urls": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-3.0.1.tgz", - "integrity": "sha512-Ds554NeT5Gennfoo9KN50Vh6tpgtvYEwraYjejXnyTpu1C7oXKxdFk75REooENHE8ndTVOJuv+BEs4/J/xcozw==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-3.0.2.tgz", + "integrity": "sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==", "dev": true, "requires": { - "abab": "^2.0.3", + "abab": "^2.0.6", "whatwg-mimetype": "^3.0.0", - "whatwg-url": "^10.0.0" + "whatwg-url": "^11.0.0" + }, + "dependencies": { + "whatwg-url": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", + "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", + "dev": true, + "requires": { + "tr46": "^3.0.0", + "webidl-conversions": "^7.0.0" + } + } } }, "debug": { @@ -11790,7 +11526,7 @@ "decode-uri-component": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "integrity": "sha512-hjf+xovcEn31w/EUYdTXQh/8smFL/dzYjohQGEIgjyNavaJfBY2p5F527Bo1VPATxv0VYTUC2bOcXvqFwk78Og==", "dev": true }, "deep-eql": { @@ -11809,25 +11545,21 @@ "dev": true }, "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", + "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", "dev": true, "requires": { - "object-keys": "^1.0.12" + "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": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "dev": true }, - "dequal": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.2.tgz", - "integrity": "sha512-q9K8BlJVxK7hQYqa6XISGmBZbtQQWVXSrRrWreHC94rMt1QL/Impruc+7p2CYSYuVIUr+YCt6hjrs1kkdJRTug==" - }, "detect-node": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", @@ -11858,21 +11590,16 @@ } }, "dom-accessibility-api": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.13.tgz", - "integrity": "sha512-R305kwb5CcMDIpSHUnLyIAp7SrSPBx6F0VfQFB3M75xVMHhXJJIdePYgbPPh1o57vCHNu5QztokWUPsLjWzFqw==", - "dev": true - }, - "dom-align": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/dom-align/-/dom-align-1.12.2.tgz", - "integrity": "sha512-pHuazgqrsTFrGU2WLDdXxCFabkdQDx72ddkraZNih1KsMcN5qsRSTR9O4VJRlwTPCPb5COYg3LOfiMHHcPInHg==", + "version": "0.5.14", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.14.tgz", + "integrity": "sha512-NMt+m9zFMPZe0JcY9gN224Qvk6qLIdqex29clBvc/y75ZBX9YA9wNK3frsYvu2DI1xcCIwxwnX+TlsJ2DSOADg==", "dev": true }, "dom-helpers": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "dev": true, "requires": { "@babel/runtime": "^7.8.7", "csstype": "^3.0.2" @@ -11888,10 +11615,10 @@ } }, "electron-to-chromium": { - "version": "1.4.103", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.103.tgz", - "integrity": "sha512-c/uKWR1Z/W30Wy/sx3dkZoj4BijbXX85QKWu9jJfjho3LBAXNEGAEW3oWiGb+dotA6C6BzCTxL2/aLes7jlUeg==", - "dev": true + "version": "1.4.142", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.142.tgz", + "integrity": "sha512-ea8Q1YX0JRp4GylOmX4gFHIizi0j9GfRW4EkaHnkZp0agRCBB4ZGeCv17IEzIvBkiYVwfoKVhKZJbTfqCRdQdg==", + "devOptional": true }, "emoji-regex": { "version": "9.2.2", @@ -11909,19 +11636,15 @@ } }, "engine.io-client": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.1.1.tgz", - "integrity": "sha512-V05mmDo4gjimYW+FGujoGmmmxRaDsrVr7AXA3ZIfa04MWM1jOfZfUwou0oNqhNwy/votUDvGDt4JA4QF4e0b4g==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.2.2.tgz", + "integrity": "sha512-8ZQmx0LQGRTYkHuogVZuGSpDqYZtCM/nv8zQ68VZ+JkOpazJ7ICdsSpaO6iXwvaU30oFg5QJOJWj8zWqhbKjkQ==", "requires": { - "@socket.io/component-emitter": "~3.0.0", + "@socket.io/component-emitter": "~3.1.0", "debug": "~4.3.1", - "engine.io-parser": "~5.0.0", - "has-cors": "1.1.0", - "parseqs": "0.0.6", - "parseuri": "0.0.6", + "engine.io-parser": "~5.0.3", "ws": "~8.2.3", - "xmlhttprequest-ssl": "~2.0.0", - "yeast": "0.1.2" + "xmlhttprequest-ssl": "~2.0.0" }, "dependencies": { "ws": { @@ -11933,12 +11656,9 @@ } }, "engine.io-parser": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.3.tgz", - "integrity": "sha512-BtQxwF27XUNnSafQLvDi0dQ8s3i6VgzSoQMJacpIcGNrlUdfHSKbgm3jmjCVvQluGzqwujQMPAoMai3oYSTurg==", - "requires": { - "@socket.io/base64-arraybuffer": "~1.0.2" - } + "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", @@ -11950,31 +11670,43 @@ } }, "es-abstract": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.2.tgz", - "integrity": "sha512-gfSBJoZdlL2xRiOCy0g8gLMryhoe1TlimjzU99L/31Z8QEGIhVQI+EWwt5lT+AuU9SnorVupXFqqOGqGfsyO6w==", + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.1.tgz", + "integrity": "sha512-WEm2oBhfoI2sImeM4OF2zE2V3BYdSF+KnSi9Sidz51fQHd7+JuF8Xgcj9/0o+OWeIeIS/MiuNnlruQrJf16GQA==", "dev": true, "requires": { "call-bind": "^1.0.2", "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", + "function.prototype.name": "^1.1.5", "get-intrinsic": "^1.1.1", "get-symbol-description": "^1.0.0", "has": "^1.0.3", + "has-property-descriptors": "^1.0.0", "has-symbols": "^1.0.3", "internal-slot": "^1.0.3", "is-callable": "^1.2.4", "is-negative-zero": "^2.0.2", "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.1", + "is-shared-array-buffer": "^1.0.2", "is-string": "^1.0.7", "is-weakref": "^1.0.2", "object-inspect": "^1.12.0", "object-keys": "^1.1.1", "object.assign": "^4.1.2", - "string.prototype.trimend": "^1.0.4", - "string.prototype.trimstart": "^1.0.4", - "unbox-primitive": "^1.0.1" + "regexp.prototype.flags": "^1.4.3", + "string.prototype.trimend": "^1.0.5", + "string.prototype.trimstart": "^1.0.5", + "unbox-primitive": "^1.0.2" + } + }, + "es-shim-unscopables": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", + "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", + "dev": true, + "requires": { + "has": "^1.0.3" } }, "es-to-primitive": { @@ -11989,170 +11721,170 @@ } }, "esbuild": { - "version": "0.14.30", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.30.tgz", - "integrity": "sha512-wCecQSBkIjp2xjuXY+wcXS/PpOQo9rFh4NAKPh4Pm9f3fuLcnxkR0rDzA+mYP88FtXIUcXUyYmaIgfrzRl55jA==", - "dev": true, - "requires": { - "esbuild-android-64": "0.14.30", - "esbuild-android-arm64": "0.14.30", - "esbuild-darwin-64": "0.14.30", - "esbuild-darwin-arm64": "0.14.30", - "esbuild-freebsd-64": "0.14.30", - "esbuild-freebsd-arm64": "0.14.30", - "esbuild-linux-32": "0.14.30", - "esbuild-linux-64": "0.14.30", - "esbuild-linux-arm": "0.14.30", - "esbuild-linux-arm64": "0.14.30", - "esbuild-linux-mips64le": "0.14.30", - "esbuild-linux-ppc64le": "0.14.30", - "esbuild-linux-riscv64": "0.14.30", - "esbuild-linux-s390x": "0.14.30", - "esbuild-netbsd-64": "0.14.30", - "esbuild-openbsd-64": "0.14.30", - "esbuild-sunos-64": "0.14.30", - "esbuild-windows-32": "0.14.30", - "esbuild-windows-64": "0.14.30", - "esbuild-windows-arm64": "0.14.30" + "version": "0.14.42", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.42.tgz", + "integrity": "sha512-V0uPZotCEHokJdNqyozH6qsaQXqmZEOiZWrXnds/zaH/0SyrIayRXWRB98CENO73MIZ9T3HBIOsmds5twWtmgw==", + "dev": true, + "requires": { + "esbuild-android-64": "0.14.42", + "esbuild-android-arm64": "0.14.42", + "esbuild-darwin-64": "0.14.42", + "esbuild-darwin-arm64": "0.14.42", + "esbuild-freebsd-64": "0.14.42", + "esbuild-freebsd-arm64": "0.14.42", + "esbuild-linux-32": "0.14.42", + "esbuild-linux-64": "0.14.42", + "esbuild-linux-arm": "0.14.42", + "esbuild-linux-arm64": "0.14.42", + "esbuild-linux-mips64le": "0.14.42", + "esbuild-linux-ppc64le": "0.14.42", + "esbuild-linux-riscv64": "0.14.42", + "esbuild-linux-s390x": "0.14.42", + "esbuild-netbsd-64": "0.14.42", + "esbuild-openbsd-64": "0.14.42", + "esbuild-sunos-64": "0.14.42", + "esbuild-windows-32": "0.14.42", + "esbuild-windows-64": "0.14.42", + "esbuild-windows-arm64": "0.14.42" } }, "esbuild-android-64": { - "version": "0.14.30", - "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.30.tgz", - "integrity": "sha512-vdJ7t8A8msPfKpYUGUV/KaTQRiZ0vDa2XSTlzXVkGGVHLKPeb85PBUtYJcEgw3htW3IdX5i1t1IMdQCwJJgNAg==", + "version": "0.14.42", + "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.42.tgz", + "integrity": "sha512-P4Y36VUtRhK/zivqGVMqhptSrFILAGlYp0Z8r9UQqHJ3iWztRCNWnlBzD9HRx0DbueXikzOiwyOri+ojAFfW6A==", "dev": true, "optional": true }, "esbuild-android-arm64": { - "version": "0.14.30", - "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.30.tgz", - "integrity": "sha512-BdgGfxeA5hBQNErLr7BWJUA8xjflEfyaARICy8e0OJYNSAwDbEzOf8LyiKWSrDcgV129mWhi3VpbNQvOIDEHcg==", + "version": "0.14.42", + "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.42.tgz", + "integrity": "sha512-0cOqCubq+RWScPqvtQdjXG3Czb3AWI2CaKw3HeXry2eoA2rrPr85HF7IpdU26UWdBXgPYtlTN1LUiuXbboROhg==", "dev": true, "optional": true }, "esbuild-darwin-64": { - "version": "0.14.30", - "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.30.tgz", - "integrity": "sha512-VRaOXMMrsG5n53pl4qFZQdXy2+E0NoLP/QH3aDUI0+bQP+ZHDmbINKcDy2IX7GVFI9kqPS18iJNAs5a6/G2LZg==", + "version": "0.14.42", + "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.42.tgz", + "integrity": "sha512-ipiBdCA3ZjYgRfRLdQwP82rTiv/YVMtW36hTvAN5ZKAIfxBOyPXY7Cejp3bMXWgzKD8B6O+zoMzh01GZsCuEIA==", "dev": true, "optional": true }, "esbuild-darwin-arm64": { - "version": "0.14.30", - "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.30.tgz", - "integrity": "sha512-qDez+fHMOrO9Oc9qjt/x+sy09RJVh62kik5tVybKRLmezeV4qczM9/sAYY57YN0aWLdHbcCj2YqJUWYJNsgKnw==", + "version": "0.14.42", + "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.42.tgz", + "integrity": "sha512-bU2tHRqTPOaoH/4m0zYHbFWpiYDmaA0gt90/3BMEFaM0PqVK/a6MA2V/ypV5PO0v8QxN6gH5hBPY4YJ2lopXgA==", "dev": true, "optional": true }, "esbuild-freebsd-64": { - "version": "0.14.30", - "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.30.tgz", - "integrity": "sha512-mec1jENcImVVagddZlGWsdAUwBnzR5cgnhzCxv+9fSMxKbx1uZYLLUAnLPp8m/i934zrumR1xGjJ5VoWdPlI2w==", + "version": "0.14.42", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.42.tgz", + "integrity": "sha512-75h1+22Ivy07+QvxHyhVqOdekupiTZVLN1PMwCDonAqyXd8TVNJfIRFrdL8QmSJrOJJ5h8H1I9ETyl2L8LQDaw==", "dev": true, "optional": true }, "esbuild-freebsd-arm64": { - "version": "0.14.30", - "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.30.tgz", - "integrity": "sha512-cpjbTs6Iok/AfeB0JgTzyUJTMStC1SQULmany5nHx6S4GTkSgaAHuJzZO0GcVWqghI4e0YL/bjXAhN5Mn6feNw==", + "version": "0.14.42", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.42.tgz", + "integrity": "sha512-W6Jebeu5TTDQMJUJVarEzRU9LlKpNkPBbjqSu+GUPTHDCly5zZEQq9uHkmHHl7OKm+mQ2zFySN83nmfCeZCyNA==", "dev": true, "optional": true }, "esbuild-linux-32": { - "version": "0.14.30", - "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.30.tgz", - "integrity": "sha512-liIONVT4F2kZmOMwtwASqZ8WkIjb5HHBR9HUffdHiuotSTF3CyZO+EJf+Og+SYYuuVIvt0qHNSFjBA/iSESteQ==", + "version": "0.14.42", + "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.42.tgz", + "integrity": "sha512-Ooy/Bj+mJ1z4jlWcK5Dl6SlPlCgQB9zg1UrTCeY8XagvuWZ4qGPyYEWGkT94HUsRi2hKsXvcs6ThTOjBaJSMfg==", "dev": true, "optional": true }, "esbuild-linux-64": { - "version": "0.14.30", - "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.30.tgz", - "integrity": "sha512-LUnpzoMpRqFON5En4qEj6NWiyH6a1K+Y2qYNKrCy5qPTjDoG/EWeqMz69n8Uv7pRuvDKl3FNGJ1dufTrA5i0sw==", + "version": "0.14.42", + "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.42.tgz", + "integrity": "sha512-2L0HbzQfbTuemUWfVqNIjOfaTRt9zsvjnme6lnr7/MO9toz/MJ5tZhjqrG6uDWDxhsaHI2/nsDgrv8uEEN2eoA==", "dev": true, "optional": true }, "esbuild-linux-arm": { - "version": "0.14.30", - "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.30.tgz", - "integrity": "sha512-97T+bbXnpqf7mfIG49UR7ZSJFGgvc22byn74qw3Kx2GDCBSQoVFjyWuKOHGXp8nXk3XYrdFF+mQ8yQ7aNsgQvg==", + "version": "0.14.42", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.42.tgz", + "integrity": "sha512-STq69yzCMhdRaWnh29UYrLSr/qaWMm/KqwaRF1pMEK7kDiagaXhSL1zQGXbYv94GuGY/zAwzK98+6idCMUOOCg==", "dev": true, "optional": true }, "esbuild-linux-arm64": { - "version": "0.14.30", - "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.30.tgz", - "integrity": "sha512-DHZHn6FK5q/KL0fpNT/0jE38Nnyk2rXxKE9WENi95EXtqfOLPgE8tzjTZQNgpr61R95QX4ymQU26ni3IZk8buQ==", + "version": "0.14.42", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.42.tgz", + "integrity": "sha512-c3Ug3e9JpVr8jAcfbhirtpBauLxzYPpycjWulD71CF6ZSY26tvzmXMJYooQ2YKqDY4e/fPu5K8bm7MiXMnyxuA==", "dev": true, "optional": true }, "esbuild-linux-mips64le": { - "version": "0.14.30", - "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.30.tgz", - "integrity": "sha512-fLUzTFZ7uknC0aPTk7/lM7NmaG/9ZqE3SaHEphcaM009SZK/mDOvZugWi1ss6WGNhk13dUrhkfHcc4FSb9hYhg==", + "version": "0.14.42", + "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.42.tgz", + "integrity": "sha512-QuvpHGbYlkyXWf2cGm51LBCHx6eUakjaSrRpUqhPwjh/uvNUYvLmz2LgPTTPwCqaKt0iwL+OGVL0tXA5aDbAbg==", "dev": true, "optional": true }, "esbuild-linux-ppc64le": { - "version": "0.14.30", - "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.30.tgz", - "integrity": "sha512-2Oudm2WEfj0dNU9bzIl5L/LrsMEmHWsOsYgJJqu8fDyUDgER+J1d33qz3cUdjsJk7gAENayIxDSpsuCszx0w3A==", + "version": "0.14.42", + "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.42.tgz", + "integrity": "sha512-8ohIVIWDbDT+i7lCx44YCyIRrOW1MYlks9fxTo0ME2LS/fxxdoJBwHWzaDYhjvf8kNpA+MInZvyOEAGoVDrMHg==", "dev": true, "optional": true }, "esbuild-linux-riscv64": { - "version": "0.14.30", - "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.30.tgz", - "integrity": "sha512-RPMucPW47rV4t2jlelaE948iCRtbZf5RhifxSwzlpM1Mqdyu99MMNK0w4jFreGTmLN+oGomxIOxD6n+2E/XqHw==", + "version": "0.14.42", + "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.42.tgz", + "integrity": "sha512-DzDqK3TuoXktPyG1Lwx7vhaF49Onv3eR61KwQyxYo4y5UKTpL3NmuarHSIaSVlTFDDpcIajCDwz5/uwKLLgKiQ==", "dev": true, "optional": true }, "esbuild-linux-s390x": { - "version": "0.14.30", - "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.30.tgz", - "integrity": "sha512-OZ68r7ok6qO7hdwrwQn2p5jbIRRcUcVaAykB7e0uCA0ODwfeGunILM6phJtq2Oz4dlEEFvd+tSuma3paQKwt+A==", + "version": "0.14.42", + "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.42.tgz", + "integrity": "sha512-YFRhPCxl8nb//Wn6SiS5pmtplBi4z9yC2gLrYoYI/tvwuB1jldir9r7JwAGy1Ck4D7sE7wBN9GFtUUX/DLdcEQ==", "dev": true, "optional": true }, "esbuild-netbsd-64": { - "version": "0.14.30", - "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.30.tgz", - "integrity": "sha512-iyejQUKn0TzpPkufq8pSCxOg9NheycQbMbPCmjefTe9wYuUlBt1TcHvdoJnYbQzsAhAh1BNq+s0ycRsIJFZzaQ==", + "version": "0.14.42", + "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.42.tgz", + "integrity": "sha512-QYSD2k+oT9dqB/4eEM9c+7KyNYsIPgzYOSrmfNGDIyJrbT1d+CFVKvnKahDKNJLfOYj8N4MgyFaU9/Ytc6w5Vw==", "dev": true, "optional": true }, "esbuild-openbsd-64": { - "version": "0.14.30", - "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.30.tgz", - "integrity": "sha512-UyK1MTMcy4j5fH260fsE1o6MVgWNhb62eCK2yCKCRazZv8Nqdc2WiP9ygjWidmEdCDS+A6MuVp9ozk9uoQtQpA==", + "version": "0.14.42", + "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.42.tgz", + "integrity": "sha512-M2meNVIKWsm2HMY7+TU9AxM7ZVwI9havdsw6m/6EzdXysyCFFSoaTQ/Jg03izjCsK17FsVRHqRe26Llj6x0MNA==", "dev": true, "optional": true }, "esbuild-sunos-64": { - "version": "0.14.30", - "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.30.tgz", - "integrity": "sha512-aQRtRTNKHB4YuG+xXATe5AoRTNY48IJg5vjE8ElxfmjO9+KdX7MHFkTLhlKevCD6rNANtB3qOlSIeAiXTwHNqw==", + "version": "0.14.42", + "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.42.tgz", + "integrity": "sha512-uXV8TAZEw36DkgW8Ak3MpSJs1ofBb3Smkc/6pZ29sCAN1KzCAQzsje4sUwugf+FVicrHvlamCOlFZIXgct+iqQ==", "dev": true, "optional": true }, "esbuild-windows-32": { - "version": "0.14.30", - "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.30.tgz", - "integrity": "sha512-9/fb1tPtpacMqxAXp3fGHowUDg/l9dVch5hKmCLEZC6PdGljh6h372zMdJwYfH0Bd5CCPT0Wx95uycBLJiqpXA==", + "version": "0.14.42", + "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.42.tgz", + "integrity": "sha512-4iw/8qWmRICWi9ZOnJJf9sYt6wmtp3hsN4TdI5NqgjfOkBVMxNdM9Vt3626G1Rda9ya2Q0hjQRD9W1o+m6Lz6g==", "dev": true, "optional": true }, "esbuild-windows-64": { - "version": "0.14.30", - "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.30.tgz", - "integrity": "sha512-DHgITeUhPAnN9I5O6QBa1GVyPOhiYCn4S4TtQr7sO4+X0LNyqnlmA1M0qmGkUdDC1QQfjI8uQ4G/whdWb2pWIQ==", + "version": "0.14.42", + "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.42.tgz", + "integrity": "sha512-j3cdK+Y3+a5H0wHKmLGTJcq0+/2mMBHPWkItR3vytp/aUGD/ua/t2BLdfBIzbNN9nLCRL9sywCRpOpFMx3CxzA==", "dev": true, "optional": true }, "esbuild-windows-arm64": { - "version": "0.14.30", - "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.30.tgz", - "integrity": "sha512-F1kLyQH7zSgjh5eLxogGZN7C9+KNs9m+s7Q6WZoMmCWT/6j998zlaoECHyM8izJRRfsvw2eZlEa1jO6/IOU1AQ==", + "version": "0.14.42", + "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.42.tgz", + "integrity": "sha512-+lRAARnF+hf8J0mN27ujO+VbhPbDqJ8rCcJKye4y7YZLV6C4n3pTRThAb388k/zqF5uM0lS5O201u0OqoWSicw==", "dev": true, "optional": true }, @@ -12160,7 +11892,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true + "devOptional": true }, "escape-string-regexp": { "version": "4.0.0", @@ -12184,7 +11916,7 @@ "levn": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", "dev": true, "requires": { "prelude-ls": "~1.1.2", @@ -12211,13 +11943,6 @@ "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", "dev": true }, - "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, - "optional": true - }, "type-check": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", @@ -12230,12 +11955,12 @@ } }, "eslint": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.12.0.tgz", - "integrity": "sha512-it1oBL9alZg1S8UycLm5YDMAkIhtH6FtAzuZs6YvoGVldWjbS08BkAdb/ymP9LlAyq8koANu32U7Ib/w+UNh8Q==", + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.16.0.tgz", + "integrity": "sha512-MBndsoXY/PeVTDJeWsYj7kLZ5hQpJOfMYLsF6LicLHQWbRDG19lK5jOix4DPl8yY4SUFcE3txy86OzFLWT+yoA==", "dev": true, "requires": { - "@eslint/eslintrc": "^1.2.1", + "@eslint/eslintrc": "^1.3.0", "@humanwhocodes/config-array": "^0.9.2", "ajv": "^6.10.0", "chalk": "^4.0.0", @@ -12246,14 +11971,14 @@ "eslint-scope": "^7.1.1", "eslint-utils": "^3.0.0", "eslint-visitor-keys": "^3.3.0", - "espree": "^9.3.1", + "espree": "^9.3.2", "esquery": "^1.4.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", "functional-red-black-tree": "^1.0.1", "glob-parent": "^6.0.1", - "globals": "^13.6.0", + "globals": "^13.15.0", "ignore": "^5.2.0", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", @@ -12262,7 +11987,7 @@ "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", + "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.1", "regexpp": "^3.2.0", @@ -12273,9 +11998,9 @@ }, "dependencies": { "globals": { - "version": "13.13.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.13.0.tgz", - "integrity": "sha512-EQ7Q18AJlPwp3vUDL4mKA0KXrXyNIQyWon6T6XQiBQF0XHvRsiCSrWmmeATpUzdJN2HhWZU6Pdl0a9zdep5p6A==", + "version": "13.15.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.15.0.tgz", + "integrity": "sha512-bpzcOlgDhMG070Av0Vy5Owklpv1I6+j96GhUI7Rh7IzDCKLzboflLrrfqMu8NquDbiR4EOQk7XzJwqVJxicxog==", "dev": true, "requires": { "type-fest": "^0.20.2" @@ -12290,9 +12015,9 @@ } }, "eslint-config-react-app": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/eslint-config-react-app/-/eslint-config-react-app-7.0.0.tgz", - "integrity": "sha512-xyymoxtIt1EOsSaGag+/jmcywRuieQoA2JbPCjnw9HukFj9/97aGPoZVFioaotzk1K5Qt9sHO5EutZbkrAXS0g==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/eslint-config-react-app/-/eslint-config-react-app-7.0.1.tgz", + "integrity": "sha512-K6rNzvkIeHaTd8m/QEh1Zko0KI7BACWkkneSs6s9cKZC/J27X3eZR6Upt1jkmZ/4FK+XUOPPxMEN7+lbUXfSlA==", "dev": true, "requires": { "@babel/core": "^7.16.0", @@ -12364,9 +12089,9 @@ } }, "eslint-plugin-import": { - "version": "2.25.4", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.25.4.tgz", - "integrity": "sha512-/KJBASVFxpu0xg1kIBn9AUa8hQVnszpwgE7Ld0lKAlx7Ie87yzEzCgSkekt+le/YVhiaosO4Y14GDAOc41nfxA==", + "version": "2.26.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz", + "integrity": "sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==", "dev": true, "requires": { "array-includes": "^3.1.4", @@ -12374,14 +12099,14 @@ "debug": "^2.6.9", "doctrine": "^2.1.0", "eslint-import-resolver-node": "^0.3.6", - "eslint-module-utils": "^2.7.2", + "eslint-module-utils": "^2.7.3", "has": "^1.0.3", - "is-core-module": "^2.8.0", + "is-core-module": "^2.8.1", "is-glob": "^4.0.3", - "minimatch": "^3.0.4", + "minimatch": "^3.1.2", "object.values": "^1.1.5", - "resolve": "^1.20.0", - "tsconfig-paths": "^3.12.0" + "resolve": "^1.22.0", + "tsconfig-paths": "^3.14.1" }, "dependencies": { "debug": { @@ -12405,7 +12130,7 @@ "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true } } @@ -12452,25 +12177,25 @@ } }, "eslint-plugin-react": { - "version": "7.29.4", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.29.4.tgz", - "integrity": "sha512-CVCXajliVh509PcZYRFyu/BoUEz452+jtQJq2b3Bae4v3xBUWPLCmtmBM+ZinG4MzwmxJgJ2M5rMqhqLVn7MtQ==", + "version": "7.30.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.30.0.tgz", + "integrity": "sha512-RgwH7hjW48BleKsYyHK5vUAvxtE9SMPDKmcPRQgtRCYaZA0XQPt5FSkrU3nhz5ifzMZcA8opwmRJ2cmOO8tr5A==", "dev": true, "requires": { - "array-includes": "^3.1.4", - "array.prototype.flatmap": "^1.2.5", + "array-includes": "^3.1.5", + "array.prototype.flatmap": "^1.3.0", "doctrine": "^2.1.0", "estraverse": "^5.3.0", "jsx-ast-utils": "^2.4.1 || ^3.0.0", "minimatch": "^3.1.2", "object.entries": "^1.1.5", "object.fromentries": "^2.0.5", - "object.hasown": "^1.1.0", + "object.hasown": "^1.1.1", "object.values": "^1.1.5", "prop-types": "^15.8.1", "resolve": "^2.0.0-next.3", "semver": "^6.3.0", - "string.prototype.matchall": "^4.0.6" + "string.prototype.matchall": "^4.0.7" }, "dependencies": { "doctrine": { @@ -12495,16 +12220,16 @@ } }, "eslint-plugin-react-hooks": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.4.0.tgz", - "integrity": "sha512-U3RVIfdzJaeKDQKEJbz5p3NW8/L80PCATJAfuojwbaEL+gBjfGdhUcGde+WGUW46Q5sr/NgxevsIiDtNXrvZaQ==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.5.0.tgz", + "integrity": "sha512-8k1gRt7D7h03kd+SAAlzXkQwWK22BnK6GKZG+FJA6BAGy22CFvl8kCIXKpVux0cCxMWDQUPqSok0LKaZ0aOcCw==", "dev": true, "requires": {} }, "eslint-plugin-testing-library": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-testing-library/-/eslint-plugin-testing-library-5.2.0.tgz", - "integrity": "sha512-fYFH8lA1hbc1Epr9laNm/+YIR2d+R7WI8sFz9jIRAUfqCf21Nb5BzZwhNeZlu9wKXwDtuf+hUM5QJxG1PuDsTQ==", + "version": "5.5.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-testing-library/-/eslint-plugin-testing-library-5.5.1.tgz", + "integrity": "sha512-plLEkkbAKBjPxsLj7x4jNapcHAg2ernkQlKKrN2I8NrQwPISZHyCUNvg5Hv3EDqOQReToQb5bnqXYbkijJPE/g==", "dev": true, "requires": { "@typescript-eslint/utils": "^5.13.0" @@ -12544,13 +12269,13 @@ "dev": true }, "espree": { - "version": "9.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.1.tgz", - "integrity": "sha512-bvdyLmJMfwkV3NCRl5ZhJf22zBFo1y8bYh3VYb+bfzqNB4Je68P2sSuXyuFquzWLebHpNd2/d5uv7yoP9ISnGQ==", + "version": "9.3.2", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.2.tgz", + "integrity": "sha512-D211tC7ZwouTIuY5x9XnS0E9sWNChB7IYKX/Xp5eQj3nFXhqmiUDB9q27y76oFl8jTg3pXcQx/bpxMfs3CIZbA==", "dev": true, "requires": { - "acorn": "^8.7.0", - "acorn-jsx": "^5.3.1", + "acorn": "^8.7.1", + "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^3.3.0" } }, @@ -12664,7 +12389,7 @@ "fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, "fastq": { @@ -12685,6 +12410,15 @@ "flat-cache": "^3.0.4" } }, + "file-selector": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/file-selector/-/file-selector-0.4.0.tgz", + "integrity": "sha512-iACCiXeMYOvZqlF1kTiYINzgepRBymz1wwjiuup9u9nayhb6g4fSwiyJ/6adli+EPwrWtpgQAh2PoS7HukEGEg==", + "dev": true, + "requires": { + "tslib": "^2.0.3" + } + }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -12694,16 +12428,10 @@ "to-regex-range": "^5.0.1" } }, - "find-root": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", - "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", - "dev": true - }, "find-up": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", "dev": true, "requires": { "locate-path": "^2.0.0" @@ -12726,9 +12454,9 @@ "dev": true }, "follow-redirects": { - "version": "1.14.9", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz", - "integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==" + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz", + "integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==" }, "form-data": { "version": "4.0.0", @@ -12744,7 +12472,7 @@ "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, "fsevents": { "version": "2.3.2", @@ -12759,22 +12487,40 @@ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "dev": true }, + "function.prototype.name": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", + "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.0", + "functions-have-names": "^1.2.2" + } + }, "functional-red-black-tree": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", + "dev": true + }, + "functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", "dev": true }, "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 + "devOptional": true }, "get-func-name": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", "dev": true }, "get-intrinsic": { @@ -12808,14 +12554,14 @@ } }, "glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.0.4", + "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } @@ -12833,7 +12579,7 @@ "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 + "devOptional": true }, "globby": { "version": "11.1.0", @@ -12859,22 +12605,26 @@ } }, "has-bigints": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", - "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", "dev": true }, - "has-cors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", - "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=" - }, "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 }, + "has-property-descriptors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", + "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.1" + } + }, "has-symbols": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", @@ -12904,13 +12654,6 @@ "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", "requires": { "react-is": "^16.7.0" - }, - "dependencies": { - "react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" - } } }, "html-encoding-sniffer": { @@ -12934,9 +12677,9 @@ } }, "https-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", - "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", "dev": true, "requires": { "agent-base": "6", @@ -12950,9 +12693,9 @@ "dev": true }, "husky": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/husky/-/husky-7.0.4.tgz", - "integrity": "sha512-vbaCKN2QLtP/vD4yvs6iz6hBEo6wkSzs8HpRah1Z6aGmF2KW5PdYuAd7uX5a+OyBZHBhd+TFLqgjUgytQr4RvQ==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/husky/-/husky-8.0.1.tgz", + "integrity": "sha512-xs7/chUH/CKdOCs7Zy0Aev9e/dKOMZf3K1Az1nar3tzlv0jfqnYtu235bstsWTmXOR0EfINrPa97yy4Lz6RiKw==", "dev": true }, "iconv-lite": { @@ -12970,16 +12713,10 @@ "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", "dev": true }, - "immer": { - "version": "9.0.12", - "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.12.tgz", - "integrity": "sha512-lk7UNmSbAukB5B6dh9fnh5D0bJTOFKxVg2cyJWTYrWRfhLrLMBquONcUs3aFq507hNoIZEDDh8lb8UtOizSMhA==", - "dev": true - }, "immutable": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.0.0.tgz", - "integrity": "sha512-zIE9hX70qew5qTUjSS7wi1iwj/l7+m54KWU247nhM3v806UdGj1yDndXj+IOYxxtW9zyLI+xqFNZjTuDaLUqFw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.1.0.tgz", + "integrity": "sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==", "dev": true }, "import-fresh": { @@ -12995,7 +12732,7 @@ "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true }, "indent-string": { @@ -13007,7 +12744,7 @@ "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "requires": { "once": "^1.3.0", "wrappy": "1" @@ -13035,18 +12772,10 @@ "integrity": "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==", "dev": true }, - "invariant": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", - "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", - "requires": { - "loose-envify": "^1.0.0" - } - }, "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", "dev": true }, "is-bigint": { @@ -13084,9 +12813,9 @@ "dev": true }, "is-core-module": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz", - "integrity": "sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==", + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz", + "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==", "dev": true, "requires": { "has": "^1.0.3" @@ -13104,7 +12833,7 @@ "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true }, "is-glob": { @@ -13198,7 +12927,7 @@ "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, "jest-diff": { @@ -13231,13 +12960,6 @@ "pretty-format": "^27.5.1" } }, - "jquery": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.0.tgz", - "integrity": "sha512-JVzAR/AjBvVt2BmYhxRCSYysDsPcssdmTFnzyLEts9qNwmjmu4JTAMYubEfwVOSwpQ1I1sKKFcxhZCI2buerfw==", - "dev": true, - "peer": true - }, "js-sha3": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", @@ -13296,7 +13018,7 @@ "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true + "devOptional": true }, "json-parse-even-better-errors": { "version": "2.3.1", @@ -13313,19 +13035,19 @@ "json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, "json5": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", - "dev": true + "devOptional": true }, "jsx-ast-utils": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.2.2.tgz", - "integrity": "sha512-HDAyJ4MNQBboGpUnHAVUNJs6X0lh058s6FuixsFGP7MgJYpD6Vasd6nzSG5iIfXu1zAYlHJ/zsOKNlrenTUBnw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.0.tgz", + "integrity": "sha512-XzO9luP6L0xkxwhIJMTJQpZo/eeN60K08jHdexfD569AGxeNug6UketeHXEhROoM8aR7EcUoOQmIhcJQjcuq8Q==", "dev": true, "requires": { "array-includes": "^3.1.4", @@ -13341,7 +13063,7 @@ "language-tags": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.5.tgz", - "integrity": "sha1-0yHbxNowuovzAk4ED6XBRmH5GTo=", + "integrity": "sha512-qJhlO9cGXi6hBGKoxEG/sKZDAHD5Hnu9Hs4WbOY3pCWXDhw0N8x1NenNzm2EnNLkLkk7J2SdxAkDSbb6ftT+UQ==", "dev": true, "requires": { "language-subtag-registry": "~0.3.2" @@ -13372,7 +13094,7 @@ "locate-path": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", "dev": true, "requires": { "p-locate": "^2.0.0", @@ -13388,7 +13110,7 @@ "lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", "dev": true }, "lodash.merge": { @@ -13400,7 +13122,7 @@ "lodash.pick": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz", - "integrity": "sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM=", + "integrity": "sha512-hXt6Ul/5yWjfklSGvLQl8vM//l3FtyHZeuelpzK6mm99pNvN9yTDruNZPEJZD1oWrqo+izBmB7oUfWgcCX7s4Q==", "dev": true }, "loose-envify": { @@ -13432,7 +13154,7 @@ "lz-string": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.4.4.tgz", - "integrity": "sha1-wNjq82BZ9wV5bh40SBHPTEmNOiY=", + "integrity": "sha512-0ckx7ZHRPqb0oUm8zNr+90mtf9DQB60H1wMCjBtfi62Kl3a7JbHob6gA2bC+xRvZoOL+1hzUK8jeuEIQE8svEQ==", "dev": true }, "match-sorter": { @@ -13444,12 +13166,6 @@ "remove-accents": "0.4.2" } }, - "memoize-one": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz", - "integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==", - "dev": true - }, "merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -13519,9 +13235,9 @@ "dev": true }, "moment": { - "version": "2.29.1", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", - "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==", + "version": "2.29.3", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.3.tgz", + "integrity": "sha512-c6YRvhEo//6T2Jz/vVtYzqBzwvPT95JBQ+smCytzf7c50oMZRsR/a4w88aD34I+/QVSfnoAnSBFPJHItlOMJVw==", "dev": true }, "mri": { @@ -13551,28 +13267,28 @@ "nano-time": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/nano-time/-/nano-time-1.0.0.tgz", - "integrity": "sha1-sFVPaa2J4i0JB/ehKwmTpdlhN+8=", + "integrity": "sha512-flnngywOoQ0lLQOTRNexn2gGSNuM9bKj9RZAWSzhQ+UJYaAFG9bac4DW9VHjUAzrOaIcajHybCTHe/bkvozQqA==", "requires": { "big-integer": "^1.6.16" } }, "nanoid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.2.tgz", - "integrity": "sha512-CuHBogktKwpm5g2sRgv83jEy2ijFzBwMoYA60orPDR7ynsLijJDqgsi4RDGj3OJpy3Ieb+LYwiRmIOGyytgITA==", + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", + "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", "dev": true }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, "node-releases": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.2.tgz", - "integrity": "sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg==", - "dev": true + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.5.tgz", + "integrity": "sha512-U9h1NLROZTq9uE1SNffn6WuPDg8icmi3ns4rEl/oTfIle4iLjTliCzgTsbaIFMq/Xn078/lfY/BL0GWZ+psK4Q==", + "devOptional": true }, "normalize-path": { "version": "3.0.0", @@ -13601,9 +13317,9 @@ "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" }, "object-inspect": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", - "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", + "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", "dev": true }, "object-keys": { @@ -13647,13 +13363,13 @@ } }, "object.hasown": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.0.tgz", - "integrity": "sha512-MhjYRfj3GBlhSkDHo6QmvgjRLXQ2zndabdf3nX0yTyZK9rPfxb6uRpAac8HXNLy1GpqWtZ81Qh4v3uOls2sRAg==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.1.tgz", + "integrity": "sha512-LYLe4tivNQzq4JdaWW6WO3HMZZJWzkkH8fnI6EebWl0VZth2wL2Lovm74ep2/gZzlaTdV62JZHEqHQ2yVn8Q/A==", "dev": true, "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5" } }, "object.values": { @@ -13754,16 +13470,6 @@ "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", "dev": true }, - "parseqs": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.6.tgz", - "integrity": "sha512-jeAGzMDbfSHHA091hr0r31eYfTig+29g3GKKE/PPbEQ65X0lmMwlEoqmhzu0iztID5uJpZsFlUPDP8ThPL7M8w==" - }, - "parseuri": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.6.tgz", - "integrity": "sha512-AUjen8sAkGgao7UyCX6Ahv0gIK2fABKmYjvP4xmy5JaKvcbTRueIqIPHLAfq30xJddqSE033IOMUSOMCcK3Sow==" - }, "path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", @@ -13809,7 +13515,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true + "devOptional": true }, "picomatch": { "version": "2.3.1", @@ -13817,19 +13523,13 @@ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true }, - "popper.js": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1.tgz", - "integrity": "sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ==", - "dev": true - }, "postcss": { - "version": "8.4.12", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.12.tgz", - "integrity": "sha512-lg6eITwYe9v6Hr5CncVbK70SoioNQIq81nsaG86ev5hAidQvmOeETBqs7jm43K2F5/Ley3ytDtriImV6TpNiSg==", + "version": "8.4.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz", + "integrity": "sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==", "dev": true, "requires": { - "nanoid": "^3.3.1", + "nanoid": "^3.3.4", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" } @@ -13875,6 +13575,12 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true + }, + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true } } }, @@ -13957,33 +13663,11 @@ "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dev": true, "requires": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", "react-is": "^16.13.1" - }, - "dependencies": { - "react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" - } - } - }, - "prop-types-extra": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/prop-types-extra/-/prop-types-extra-1.1.1.tgz", - "integrity": "sha512-59+AHNnHYCdiC+vMwY52WmvP5dM3QLeoumYuEyceQDi9aEhtwN9zIQ2ZNo25sMyXnbh32h+P1ezDsUpUH3JAew==", - "requires": { - "react-is": "^16.3.2", - "warning": "^4.0.0" - }, - "dependencies": { - "react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" - } } }, "psl": { @@ -14023,86 +13707,6 @@ "performance-now": "^2.1.0" } }, - "rc-align": { - "version": "4.0.11", - "resolved": "https://registry.npmjs.org/rc-align/-/rc-align-4.0.11.tgz", - "integrity": "sha512-n9mQfIYQbbNTbefyQnRHZPWuTEwG1rY4a9yKlIWHSTbgwI+XUMGRYd0uJ5pE2UbrNX0WvnMBA1zJ3Lrecpra/A==", - "dev": true, - "requires": { - "@babel/runtime": "^7.10.1", - "classnames": "2.x", - "dom-align": "^1.7.0", - "lodash": "^4.17.21", - "rc-util": "^5.3.0", - "resize-observer-polyfill": "^1.5.1" - } - }, - "rc-motion": { - "version": "2.4.6", - "resolved": "https://registry.npmjs.org/rc-motion/-/rc-motion-2.4.6.tgz", - "integrity": "sha512-nXIHve2EDQZ8BFHfgJI3HYMMOZ7HGsolCfA9ozP99/gc1UqpgKys1TYrQWdXa2trff0V3JLhgn2zz+w9VsyktA==", - "dev": true, - "requires": { - "@babel/runtime": "^7.11.1", - "classnames": "^2.2.1", - "rc-util": "^5.19.2" - } - }, - "rc-slider": { - "version": "9.7.5", - "resolved": "https://registry.npmjs.org/rc-slider/-/rc-slider-9.7.5.tgz", - "integrity": "sha512-LV/MWcXFjco1epPbdw1JlLXlTgmWpB9/Y/P2yinf8Pg3wElHxA9uajN21lJiWtZjf5SCUekfSP6QMJfDo4t1hg==", - "dev": true, - "requires": { - "@babel/runtime": "^7.10.1", - "classnames": "^2.2.5", - "rc-tooltip": "^5.0.1", - "rc-util": "^5.16.1", - "shallowequal": "^1.1.0" - } - }, - "rc-tooltip": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/rc-tooltip/-/rc-tooltip-5.1.1.tgz", - "integrity": "sha512-alt8eGMJulio6+4/uDm7nvV+rJq9bsfxFDCI0ljPdbuoygUscbsMYb6EQgwib/uqsXQUvzk+S7A59uYHmEgmDA==", - "dev": true, - "requires": { - "@babel/runtime": "^7.11.2", - "rc-trigger": "^5.0.0" - } - }, - "rc-trigger": { - "version": "5.2.11", - "resolved": "https://registry.npmjs.org/rc-trigger/-/rc-trigger-5.2.11.tgz", - "integrity": "sha512-YS+BA4P2aqp9qU7dcTQwsK56SOLJk7XDaFynnXg96obJOUVFiQ6Lfomq9em2dlB4uSjd7Z/gjriZdUY8S2CPQw==", - "dev": true, - "requires": { - "@babel/runtime": "^7.11.2", - "classnames": "^2.2.6", - "rc-align": "^4.0.0", - "rc-motion": "^2.0.0", - "rc-util": "^5.19.2" - } - }, - "rc-util": { - "version": "5.19.3", - "resolved": "https://registry.npmjs.org/rc-util/-/rc-util-5.19.3.tgz", - "integrity": "sha512-S28epi9E2s7Nir05q8Ffl3hzDLwkavTGi0PGH1cTqCmkpG1AeBEuZgQDpksYeU6IgHcds5hWIPE5PUcdFiZl8w==", - "dev": true, - "requires": { - "@babel/runtime": "^7.12.5", - "react-is": "^16.12.0", - "shallowequal": "^1.1.0" - }, - "dependencies": { - "react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true - } - } - }, "react": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", @@ -14112,30 +13716,6 @@ "object-assign": "^4.1.1" } }, - "react-bootstrap": { - "version": "1.6.4", - "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-1.6.4.tgz", - "integrity": "sha512-z3BhBD4bEZuLP8VrYqAD7OT7axdcSkkyvWBWnS2U/4MhyabUihrUyucPWkan7aMI1XIHbmH4LCpEtzWGfx/yfA==", - "requires": { - "@babel/runtime": "^7.14.0", - "@restart/context": "^2.1.4", - "@restart/hooks": "^0.3.26", - "@types/invariant": "^2.2.33", - "@types/prop-types": "^15.7.3", - "@types/react": ">=16.14.8", - "@types/react-transition-group": "^4.4.1", - "@types/warning": "^3.0.0", - "classnames": "^2.3.1", - "dom-helpers": "^5.2.1", - "invariant": "^2.2.4", - "prop-types": "^15.7.2", - "prop-types-extra": "^1.1.0", - "react-overlays": "^5.1.1", - "react-transition-group": "^4.4.1", - "uncontrollable": "^7.2.1", - "warning": "^4.0.3" - } - }, "react-dom": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz", @@ -14146,6 +13726,17 @@ "scheduler": "^0.20.2" } }, + "react-dropzone": { + "version": "11.7.1", + "resolved": "https://registry.npmjs.org/react-dropzone/-/react-dropzone-11.7.1.tgz", + "integrity": "sha512-zxCMwhfPy1olUEbw3FLNPLhAm/HnaYH5aELIEglRbqabizKAdHs0h+WuyOpmA+v1JXn0++fpQDdNfUagWt5hJQ==", + "dev": true, + "requires": { + "attr-accept": "^2.2.2", + "file-selector": "^0.4.0", + "prop-types": "^15.8.1" + } + }, "react-error-boundary": { "version": "3.1.4", "resolved": "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-3.1.4.tgz", @@ -14158,73 +13749,42 @@ "react-fast-compare": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.0.tgz", - "integrity": "sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA==", - "dev": true - }, - "react-helmet": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/react-helmet/-/react-helmet-6.1.0.tgz", - "integrity": "sha512-4uMzEY9nlDlgxr61NL3XbKRy1hEkXmKNXhjbAIOVw5vcFrsdYbH2FEwcNyWvWinl103nXgzYNlns9ca+8kFiWw==", - "dev": true, - "requires": { - "object-assign": "^4.1.1", - "prop-types": "^15.7.2", - "react-fast-compare": "^3.1.1", - "react-side-effect": "^2.1.0" - } + "integrity": "sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA==" }, "react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, "react-lifecycles-compat": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", - "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" + "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==", + "dev": true }, - "react-overlays": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/react-overlays/-/react-overlays-5.1.1.tgz", - "integrity": "sha512-eCN2s2/+GVZzpnId4XVWtvDPYYBD2EtOGP74hE+8yDskPzFy9+pV1H3ZZihxuRdEbQzzacySaaDkR7xE0ydl4Q==", + "react-popper": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/react-popper/-/react-popper-2.3.0.tgz", + "integrity": "sha512-e1hj8lL3uM+sgSR4Lxzn5h1GxBlpa4CQz0XLF8kx4MDrDRWY0Ena4c97PUeSX9i5W3UAfDP0z0FXCTQkoXUl3Q==", "requires": { - "@babel/runtime": "^7.13.8", - "@popperjs/core": "^2.8.6", - "@restart/hooks": "^0.3.26", - "@types/warning": "^3.0.0", - "dom-helpers": "^5.2.0", - "prop-types": "^15.7.2", - "uncontrollable": "^7.2.1", - "warning": "^4.0.3" + "react-fast-compare": "^3.0.1", + "warning": "^4.0.2" } }, "react-query": { - "version": "3.34.19", - "resolved": "https://registry.npmjs.org/react-query/-/react-query-3.34.19.tgz", - "integrity": "sha512-JO0Ymi58WKmvnhgg6bGIrYIeKb64KsKaPWo8JcGnmK2jJxAs2XmMBzlP75ZepSU7CHzcsWtIIyhMrLbX3pb/3w==", + "version": "3.39.1", + "resolved": "https://registry.npmjs.org/react-query/-/react-query-3.39.1.tgz", + "integrity": "sha512-qYKT1bavdDiQZbngWZyPotlBVzcBjDYEJg5RQLBa++5Ix5jjfbEYJmHSZRZD+USVHUSvl/ey9Hu+QfF1QAK80A==", "requires": { "@babel/runtime": "^7.5.5", "broadcast-channel": "^3.4.1", "match-sorter": "^6.0.2" } }, - "react-redux": { - "version": "7.2.8", - "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.8.tgz", - "integrity": "sha512-6+uDjhs3PSIclqoCk0kd6iX74gzrGc3W5zcAjbrFgEdIjRSQObdIwfx80unTkVUYvbQ95Y8Av3OvFHq1w5EOUw==", - "requires": { - "@babel/runtime": "^7.15.4", - "@types/react-redux": "^7.1.20", - "hoist-non-react-statics": "^3.3.2", - "loose-envify": "^1.4.0", - "prop-types": "^15.7.2", - "react-is": "^17.0.2" - } - }, "react-refresh": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz", - "integrity": "sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A==", + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.13.0.tgz", + "integrity": "sha512-XP8A9BT0CpRBD+NYLLeIhld/RqG9+gktUjW1FkE+Vm7OCinbG1SshcK5tb9ls4kzvjZr9mOQc7HYgBngEyPAXg==", "dev": true }, "react-resize-detector": { @@ -14255,28 +13815,6 @@ "react-router": "6.3.0" } }, - "react-select": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/react-select/-/react-select-5.2.2.tgz", - "integrity": "sha512-miGS2rT1XbFNjduMZT+V73xbJEeMzVkJOz727F6MeAr2hKE0uUSA8Ff7vD44H32x2PD3SRB6OXTY/L+fTV3z9w==", - "dev": true, - "requires": { - "@babel/runtime": "^7.12.0", - "@emotion/cache": "^11.4.0", - "@emotion/react": "^11.1.1", - "@types/react-transition-group": "^4.4.0", - "memoize-one": "^5.0.0", - "prop-types": "^15.6.0", - "react-transition-group": "^4.3.0" - } - }, - "react-side-effect": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/react-side-effect/-/react-side-effect-2.1.1.tgz", - "integrity": "sha512-2FoTQzRNTncBVtnzxFOk2mCpcfxQpenBMbk5kSVBg5UcPqV9fRbgY2zhb7GTWWOlpFmAxhClBDlIq8Rsubz1yQ==", - "dev": true, - "requires": {} - }, "react-smooth": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/react-smooth/-/react-smooth-2.0.0.tgz", @@ -14312,16 +13850,27 @@ } }, "react-table": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/react-table/-/react-table-7.7.0.tgz", - "integrity": "sha512-jBlj70iBwOTvvImsU9t01LjFjy4sXEtclBovl3mTiqjz23Reu0DKnRza4zlLtOPACx6j2/7MrQIthIK1Wi+LIA==", + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/react-table/-/react-table-7.8.0.tgz", + "integrity": "sha512-hNaz4ygkZO4bESeFfnfOft73iBUj8K5oKi1EcSHPAibEydfsX2MyU6Z8KCr3mv3C9Kqqh71U+DhZkFvibbnPbA==", "dev": true, "requires": {} }, + "react-textarea-autosize": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/react-textarea-autosize/-/react-textarea-autosize-8.3.4.tgz", + "integrity": "sha512-CdtmP8Dc19xL8/R6sWvtknD/eCXkQr30dtvC4VmGInhRsfF8X/ihXCq6+9l9qbxmKRiq407/7z5fxE7cVWQNgQ==", + "requires": { + "@babel/runtime": "^7.10.2", + "use-composed-ref": "^1.3.0", + "use-latest": "^1.2.1" + } + }, "react-transition-group": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.2.tgz", "integrity": "sha512-/RNYfRAMlZwDSr6z4zNKV6xu53/e2BuaBbGhbyYIXTrmgu/bGHzmqOs7mJSJBHy9Ud+ApHx3QjrkKSp1pxvlFg==", + "dev": true, "requires": { "@babel/runtime": "^7.5.5", "dom-helpers": "^5.0.1", @@ -14339,14 +13888,11 @@ } }, "recharts": { - "version": "2.1.9", - "resolved": "https://registry.npmjs.org/recharts/-/recharts-2.1.9.tgz", - "integrity": "sha512-VozH5uznUvGqD7n224FGj7cmMAenlS0HPCs+7r2HeeHiQK6un6z0CTZfWVAB860xbcr4m+BN/EGMPZmYWd34Rg==", + "version": "2.1.10", + "resolved": "https://registry.npmjs.org/recharts/-/recharts-2.1.10.tgz", + "integrity": "sha512-me6c8m2Gs88X/nuM2gDSTDIhpSLNMbiTrlE4Cu53hjZNegT3g3xLlTrbYSAQuBCFWuWJAZXCmEuMr6AwizLyaA==", "dev": true, "requires": { - "@types/d3-interpolate": "^2.0.0", - "@types/d3-scale": "^3.0.0", - "@types/d3-shape": "^2.0.0", "classnames": "^2.2.5", "d3-interpolate": "^2.0.0", "d3-scale": "^3.0.0", @@ -14358,14 +13904,6 @@ "react-smooth": "^2.0.0", "recharts-scale": "^0.4.4", "reduce-css-calc": "^2.1.8" - }, - "dependencies": { - "react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true - } } }, "recharts-scale": { @@ -14397,21 +13935,6 @@ "postcss-value-parser": "^3.3.0" } }, - "redux": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/redux/-/redux-4.1.2.tgz", - "integrity": "sha512-SH8PglcebESbd/shgf6mii6EIoRM0zrQyjcuQ+ojmfxjTtE0z9Y8pa62iA/OJ58qjP6j27uyW4kUF4jl/jd6sw==", - "requires": { - "@babel/runtime": "^7.9.2" - } - }, - "redux-thunk": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.4.1.tgz", - "integrity": "sha512-OOYGNY5Jy2TWvTL1KgAlVy6dcx3siPJ1wTq741EPyUKfn6W6nChdICjZwCd0p8AZBs5kWpZlbkXW2nE/zjUa+Q==", - "dev": true, - "requires": {} - }, "regenerate": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", @@ -14433,22 +13956,23 @@ "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" }, "regenerator-transform": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.5.tgz", - "integrity": "sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw==", + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.0.tgz", + "integrity": "sha512-LsrGtPmbYg19bcPHwdtmXwbW+TqNvtY4riE3P83foeHRroMbH6/2ddFBfab3t7kbzc7v7p4wbkIecHImqt0QNg==", "dev": true, "requires": { "@babel/runtime": "^7.8.4" } }, "regexp.prototype.flags": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.1.tgz", - "integrity": "sha512-pMR7hBVUUGI7PMA37m2ofIdQCsomVnas+Jn5UPGAHQ+/LlwKm/aTLJHdasmHRzlfeZwHiAOaRSo2rbBDm3nNUQ==", + "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==", "dev": true, "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3" + "define-properties": "^1.1.3", + "functions-have-names": "^1.2.2" } }, "regexpp": { @@ -14489,7 +14013,7 @@ "jsesc": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", + "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", "dev": true } } @@ -14499,12 +14023,6 @@ "resolved": "https://registry.npmjs.org/remove-accents/-/remove-accents-0.4.2.tgz", "integrity": "sha1-CkPTqq4egNuRngeuJUsoXZ4ce7U=" }, - "reselect": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.5.tgz", - "integrity": "sha512-uVdlz8J7OO+ASpBYoz1Zypgx0KasCY20H+N8JD13oUMtPvSHQuscrHop4KbXrbsBcdB9Ds7lVK7eRkBIfO43vQ==", - "dev": true - }, "resize-observer-polyfill": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz", @@ -14543,24 +14061,14 @@ } }, "rollup": { - "version": "2.70.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.70.1.tgz", - "integrity": "sha512-CRYsI5EuzLbXdxC6RnYhOuRdtz4bhejPMSWjsFLfVM/7w/85n2szZv6yExqUXsBdz5KT8eoubeyDUDjhLHEslA==", + "version": "2.75.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.75.4.tgz", + "integrity": "sha512-JgZiJMJkKImMZJ8ZY1zU80Z2bA/TvrL/7D9qcBCrfl2bP+HUaIw0QHUroB4E3gBpFl6CRFM1YxGbuYGtdAswbQ==", "dev": true, "requires": { "fsevents": "~2.3.2" } }, - "rooks": { - "version": "5.11.0", - "resolved": "https://registry.npmjs.org/rooks/-/rooks-5.11.0.tgz", - "integrity": "sha512-acyTuaYbB021hhHAN6uiU6QUUSuGucK9YOU16nOUM0oypqpckYm7nX5v9xnopoX4pNtrxzIM/mtjC8O7fF3/8A==", - "dev": true, - "requires": { - "lodash.debounce": "^4.0.8", - "raf": "^3.4.1" - } - }, "run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -14574,7 +14082,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true + "devOptional": true }, "safer-buffer": { "version": "2.1.2", @@ -14583,9 +14091,9 @@ "dev": true }, "sass": { - "version": "1.49.11", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.49.11.tgz", - "integrity": "sha512-wvS/geXgHUGs6A/4ud5BFIWKO1nKd7wYIGimDk4q4GFkJicILActpv9ueMT4eRGSsp1BdKHuw1WwAHXbhsJELQ==", + "version": "1.52.1", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.52.1.tgz", + "integrity": "sha512-fSzYTbr7z8oQnVJ3Acp9hV80dM1fkMN7mSD/25mpcct9F7FPBMOI8krEYALgU1aZoqGhQNhTPsuSmxjnIvAm4Q==", "dev": true, "requires": { "chokidar": ">=3.0.0 <4.0.0", @@ -14615,13 +14123,7 @@ "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - }, - "shallowequal": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", - "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==", - "dev": true + "devOptional": true }, "shebang-command": { "version": "2.0.0", @@ -14662,31 +14164,29 @@ "dev": true }, "socket.io-client": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.4.1.tgz", - "integrity": "sha512-N5C/L5fLNha5Ojd7Yeb/puKcPWWcoB/A09fEjjNsg91EDVr5twk/OEyO6VT9dlLSUNY85NpW6KBhVMvaLKQ3vQ==", + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.5.1.tgz", + "integrity": "sha512-e6nLVgiRYatS+AHXnOnGi4ocOpubvOUCGhyWw8v+/FxW8saHkinG6Dfhi9TU0Kt/8mwJIAASxvw6eujQmjdZVA==", "requires": { - "@socket.io/component-emitter": "~3.0.0", - "backo2": "~1.0.2", + "@socket.io/component-emitter": "~3.1.0", "debug": "~4.3.2", - "engine.io-client": "~6.1.1", - "parseuri": "0.0.6", - "socket.io-parser": "~4.1.1" + "engine.io-client": "~6.2.1", + "socket.io-parser": "~4.2.0" } }, "socket.io-parser": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.1.2.tgz", - "integrity": "sha512-j3kk71QLJuyQ/hh5F/L2t1goqzdTL0gvDzuhTuNSwihfuFUrcSji0qFZmJJPtG6Rmug153eOPsUizeirf1IIog==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.0.tgz", + "integrity": "sha512-tLfmEwcEwnlQTxFB7jibL/q2+q8dlVQzj4JdRLJ/W/G1+Fu9VSxCx1Lo+n1HvXxKnM//dUuD0xgiA7tQf57Vng==", "requires": { - "@socket.io/component-emitter": "~3.0.0", + "@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", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true }, "source-map-js": { @@ -14728,23 +14228,25 @@ } }, "string.prototype.trimend": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", - "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz", + "integrity": "sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==", "dev": true, "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3" + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5" } }, "string.prototype.trimstart": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", - "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz", + "integrity": "sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==", "dev": true, "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3" + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5" } }, "strip-ansi": { @@ -14786,8 +14288,7 @@ "stylis": { "version": "4.0.13", "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.0.13.tgz", - "integrity": "sha512-xGPXiFVl4YED9Jh7Euv2V220mriG9u4B2TA6Ybjc1catrstKD2PpIdU3U0RKpkVBC2EhmL/F0sPCr9vrFTNRag==", - "dev": true + "integrity": "sha512-xGPXiFVl4YED9Jh7Euv2V220mriG9u4B2TA6Ybjc1catrstKD2PpIdU3U0RKpkVBC2EhmL/F0sPCr9vrFTNRag==" }, "supports-color": { "version": "7.2.0", @@ -14823,22 +14324,22 @@ "dev": true }, "tinypool": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.1.2.tgz", - "integrity": "sha512-fvtYGXoui2RpeMILfkvGIgOVkzJEGediv8UJt7TxdAOY8pnvUkFg/fkvqTfXG9Acc9S17Cnn1S4osDc2164guA==", + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.1.3.tgz", + "integrity": "sha512-2IfcQh7CP46XGWGGbdyO4pjcKqsmVqFAPcXfPxcPXmOWt9cYkTP9HcDmGgsfijYoAEc4z9qcpM/BaBz46Y9/CQ==", "dev": true }, "tinyspy": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-0.3.0.tgz", - "integrity": "sha512-c5uFHqtUp74R2DJE3/Efg0mH5xicmgziaQXMm/LvuuZn3RdpADH32aEGDRyCzObXT1DNfwDMqRQ/Drh1MlO12g==", + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-0.3.2.tgz", + "integrity": "sha512-2+40EP4D3sFYy42UkgkFFB+kiX2Tg3URG/lVvAZFfLxgGpnWl5qQJuBw1gaLttq8UOS+2p3C0WrhJnQigLTT2Q==", "dev": true }, "to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", - "dev": true + "devOptional": true }, "to-regex-range": { "version": "5.0.1", @@ -14893,9 +14394,9 @@ } }, "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", "dev": true }, "tsutils": { @@ -14905,6 +14406,14 @@ "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": { @@ -14929,34 +14438,23 @@ "dev": true }, "typescript": { - "version": "4.6.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.3.tgz", - "integrity": "sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw==", + "version": "4.7.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.2.tgz", + "integrity": "sha512-Mamb1iX2FDUpcTRzltPxgWMKy3fhg0TN378ylbktPGPK/99KbDtMQ4W1hwgsbPAsG3a0xKa1vmw4VKZQbkvz5A==", "dev": true }, "unbox-primitive": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", - "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", "dev": true, "requires": { - "function-bind": "^1.1.1", - "has-bigints": "^1.0.1", - "has-symbols": "^1.0.2", + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", "which-boxed-primitive": "^1.0.2" } }, - "uncontrollable": { - "version": "7.2.1", - "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-7.2.1.tgz", - "integrity": "sha512-svtcfoTADIB0nT9nltgjujTi7BzVmwjZClOmskKu/E8FW9BXzg9os8OLr4f8Dlnk0rYWJIWr4wv9eKUXiQvQwQ==", - "requires": { - "@babel/runtime": "^7.6.3", - "@types/react": ">=16.9.11", - "invariant": "^2.2.4", - "react-lifecycles-compat": "^3.0.4" - } - }, "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", @@ -15009,6 +14507,26 @@ "punycode": "^2.1.0" } }, + "use-composed-ref": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/use-composed-ref/-/use-composed-ref-1.3.0.tgz", + "integrity": "sha512-GLMG0Jc/jiKov/3Ulid1wbv3r54K9HlMW29IWcDFPEqFkSO2nS0MuefWgMJpeHQ9YJeXDL3ZUF+P3jdXlZX/cQ==", + "requires": {} + }, + "use-isomorphic-layout-effect": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz", + "integrity": "sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==", + "requires": {} + }, + "use-latest": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/use-latest/-/use-latest-1.2.1.tgz", + "integrity": "sha512-xA+AVm/Wlg3e2P/JiItTziwS7FK92LWrDB0p+hgXloIMuVCeJJ8v6f0eeHyPZaJrM+usM1FkFfbNCrJGs8A/zw==", + "requires": { + "use-isomorphic-layout-effect": "^1.1.1" + } + }, "v8-compile-cache": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", @@ -15016,22 +14534,22 @@ "dev": true }, "vite": { - "version": "2.9.1", - "resolved": "https://registry.npmjs.org/vite/-/vite-2.9.1.tgz", - "integrity": "sha512-vSlsSdOYGcYEJfkQ/NeLXgnRv5zZfpAsdztkIrs7AZHV8RCMZQkwjo4DS5BnrYTqoWqLoUe1Cah4aVO4oNNqCQ==", + "version": "2.9.9", + "resolved": "https://registry.npmjs.org/vite/-/vite-2.9.9.tgz", + "integrity": "sha512-ffaam+NgHfbEmfw/Vuh6BHKKlI/XIAhxE5QSS7gFLIngxg171mg1P3a4LSRME0z2ZU1ScxoKzphkipcYwSD5Ew==", "dev": true, "requires": { "esbuild": "^0.14.27", "fsevents": "~2.3.2", - "postcss": "^8.4.12", + "postcss": "^8.4.13", "resolve": "^1.22.0", "rollup": "^2.59.0" } }, "vite-plugin-checker": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/vite-plugin-checker/-/vite-plugin-checker-0.4.4.tgz", - "integrity": "sha512-bduh+oPybN0PIBCcAlIe8WlgG5P5WPVK0P43dB3jljsA/pR/Jp7BTXrflPdlWXxuQFdDasyOCVWpEVs1Zt+8yw==", + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/vite-plugin-checker/-/vite-plugin-checker-0.4.6.tgz", + "integrity": "sha512-oFel33hlsc8aUspfq0ThQRpWsfrG772fmZ5qPHKUhmew6ieejd2viITlwXHIRBY6hE3U0kirXoTWwft3DdbK+g==", "dev": true, "requires": { "@babel/code-frame": "^7.12.13", @@ -15052,18 +14570,19 @@ } }, "vitest": { - "version": "0.8.4", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-0.8.4.tgz", - "integrity": "sha512-1OoAG1+VYkzp4WLCVQFRJX/OKk70rsMIM5H23crfc1wSEnJvHlxgQBS1HPpV/VYmjC8bIInKWhnB4Gaw32MnyQ==", + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-0.13.0.tgz", + "integrity": "sha512-vuYt3+G25MMnANgyMHHG3VK86C9K/VFi/8uH5myQ2v660W4WArv99ElakPlVFxxSXXM1jqQPiPj2ht35Bod9LQ==", "dev": true, "requires": { - "@types/chai": "^4.3.0", + "@types/chai": "^4.3.1", "@types/chai-subset": "^1.3.3", "chai": "^4.3.6", + "debug": "^4.3.4", "local-pkg": "^0.4.1", - "tinypool": "^0.1.2", - "tinyspy": "^0.3.0", - "vite": "^2.8.6" + "tinypool": "^0.1.3", + "tinyspy": "^0.3.2", + "vite": "^2.9.9" } }, "vscode-jsonrpc": { @@ -15084,9 +14603,9 @@ }, "dependencies": { "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", "dev": true, "requires": { "lru-cache": "^6.0.0" @@ -15114,9 +14633,9 @@ } }, "vscode-languageserver-textdocument": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.4.tgz", - "integrity": "sha512-/xhqXP/2A2RSs+J8JNXpiiNVvvNM0oTosNVmQnunlKvq9o4mupHOBAnnzH0lwIPKazXKvAKsVp1kr+H/K4lgoQ==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.5.tgz", + "integrity": "sha512-1ah7zyQjKBudnMiHbZmxz5bYNM9KKZYz+5VQLj+yr8l+9w3g+WAhCkUkWbhMEdC5u0ub4Ndiye/fDyS8ghIKQg==", "dev": true }, "vscode-languageserver-types": { @@ -15222,9 +14741,9 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, "ws": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.5.0.tgz", - "integrity": "sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==", + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.7.0.tgz", + "integrity": "sha512-c2gsP0PRwcLFzUiA8Mkr37/MI7ilIlHQxaEAtd0uNMbVMoy8puJyafRlm0bV9MbGSabUPeLrRRaqIBcFcA2Pqg==", "dev": true, "requires": {} }, @@ -15256,11 +14775,6 @@ "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", "dev": true - }, - "yeast": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", - "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=" } } } diff --git a/frontend/package.json b/frontend/package.json index f4f5314eb..5cfba64a3 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -13,12 +13,12 @@ }, "private": true, "dependencies": { + "@mantine/core": "^4", + "@mantine/hooks": "^4", "axios": "^0.26", "react": "^17", - "react-bootstrap": "^1", "react-dom": "^17", "react-query": "^3.34", - "react-redux": "^7.2", "react-router-dom": "^6.2.1", "socket.io-client": "^4" }, @@ -29,37 +29,32 @@ "@fortawesome/free-regular-svg-icons": "^6", "@fortawesome/free-solid-svg-icons": "^6", "@fortawesome/react-fontawesome": "^0.1", - "@reduxjs/toolkit": "^1", + "@mantine/dropzone": "^4", + "@mantine/modals": "^4", + "@mantine/notifications": "^4", "@testing-library/jest-dom": "latest", "@testing-library/react": "12", "@testing-library/react-hooks": "latest", "@testing-library/user-event": "latest", - "@types/bootstrap": "^4", "@types/lodash": "^4", "@types/node": "^17", "@types/react": "^17", "@types/react-dom": "^17", - "@types/react-helmet": "^6.1", "@types/react-table": "^7", "@vitejs/plugin-react": "^1.3", - "bootstrap": "^4", - "clsx": "^1.1.1", + "clsx": "^1", "eslint": "^8", - "eslint-config-react-app": "^7.0.0", + "eslint-config-react-app": "^7", "eslint-plugin-react-hooks": "^4", - "husky": "^7", + "husky": "^8", "jsdom": "latest", "lodash": "^4", "moment": "^2.29.1", "prettier": "^2", "prettier-plugin-organize-imports": "^2", "pretty-quick": "^3.1", - "rc-slider": "^9.7", - "react-helmet": "^6.1", - "react-select": "^5.0.1", "react-table": "^7", "recharts": "^2.0.8", - "rooks": "^5", "sass": "^1", "typescript": "^4", "vite": "latest", diff --git a/frontend/src/App/Header.tsx b/frontend/src/App/Header.tsx index 2570b53e7..4c9449656 100644 --- a/frontend/src/App/Header.tsx +++ b/frontend/src/App/Header.tsx @@ -1,132 +1,118 @@ import { useSystem, useSystemSettings } from "@/apis/hooks"; -import { ActionButton, SearchBar } from "@/components"; -import { setSidebar } from "@/modules/redux/actions"; -import { useIsOffline } from "@/modules/redux/hooks"; -import { useReduxAction } from "@/modules/redux/hooks/base"; -import { Environment, useGotoHomepage, useIsMobile } from "@/utilities"; +import { Action, Search } from "@/components"; +import { Layout } from "@/constants"; +import { useNavbar } from "@/contexts/Navbar"; +import { useIsOnline } from "@/contexts/Online"; +import { Environment, useGotoHomepage } from "@/utilities"; import { - faBars, - faHeart, - faNetworkWired, - faUser, + faArrowRotateLeft, + faGear, + faPowerOff, } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { FunctionComponent, useMemo } from "react"; import { - Button, - Col, - Container, - Dropdown, - Image, - Navbar, - Row, -} from "react-bootstrap"; -import { Helmet } from "react-helmet"; -import NotificationCenter from "./Notification"; + Anchor, + Avatar, + Badge, + Burger, + createStyles, + Divider, + Group, + Header, + MediaQuery, + Menu, +} from "@mantine/core"; +import { FunctionComponent } from "react"; -const Header: FunctionComponent = () => { +const useStyles = createStyles((theme) => { + const headerBackgroundColor = + theme.colorScheme === "light" ? theme.colors.gray[0] : theme.colors.dark[4]; + return { + header: { + backgroundColor: headerBackgroundColor, + }, + }; +}); + +const AppHeader: FunctionComponent = () => { const { data: settings } = useSystemSettings(); + const hasLogout = settings?.auth.type === "form"; - const hasLogout = (settings?.auth.type ?? "none") === "form"; + const { show, showed } = useNavbar(); - const changeSidebar = useReduxAction(setSidebar); + const online = useIsOnline(); + const offline = !online; - const offline = useIsOffline(); + const { shutdown, restart, logout } = useSystem(); - const isMobile = useIsMobile(); + const goHome = useGotoHomepage(); - const { shutdown, restart, logout } = useSystem(); + const { classes } = useStyles(); - const serverActions = useMemo( - () => ( - - - - - - { - restart(); - }} + return ( +
+ + + - Restart - - { - shutdown(); - }} + + + + + - Shutdown - - - + + Bazarr + + + + + + } > - Logout - - - - ), - [hasLogout, logout, restart, shutdown] - ); - - const goHome = useGotoHomepage(); - - return ( - - - - -
- brand -
- - - - - - - - - - {offline ? ( - - {isMobile ? "" : "Connecting..."} - - ) : ( - serverActions - )} - - - -
+ Shutdown + + + +
+
+
+
); }; -export default Header; +export default AppHeader; diff --git a/frontend/src/App/Navbar.tsx b/frontend/src/App/Navbar.tsx new file mode 100644 index 000000000..365c765a2 --- /dev/null +++ b/frontend/src/App/Navbar.tsx @@ -0,0 +1,344 @@ +import { Action } from "@/components"; +import { Layout } from "@/constants"; +import { useNavbar } from "@/contexts/Navbar"; +import { useRouteItems } from "@/Router"; +import { CustomRouteObject, Route } from "@/Router/type"; +import { BuildKey, pathJoin } from "@/utilities"; +import { LOG } from "@/utilities/console"; +import { + faHeart, + faMoon, + faSun, + IconDefinition, +} from "@fortawesome/free-solid-svg-icons"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { + Anchor, + Badge, + Collapse, + createStyles, + Divider, + Group, + Navbar as MantineNavbar, + Stack, + Text, + useMantineColorScheme, +} from "@mantine/core"; +import { useHover } from "@mantine/hooks"; +import clsx from "clsx"; +import { + createContext, + FunctionComponent, + useContext, + useEffect, + useMemo, + useState, +} from "react"; +import { matchPath, NavLink, RouteObject, useLocation } from "react-router-dom"; + +const Selection = createContext<{ + selection: string | null; + select: (path: string | null) => void; +}>({ + selection: null, + select: () => { + LOG("error", "Selection context not initialized"); + }, +}); + +function useSelection() { + return useContext(Selection); +} + +function useBadgeValue(route: Route.Item) { + const { badge, children } = route; + return useMemo(() => { + let value = badge ?? 0; + + if (children === undefined) { + return value; + } + + value += + children.reduce((acc, child: Route.Item) => { + if (child.badge && child.hidden !== true) { + return acc + (child.badge ?? 0); + } + return acc; + }, 0) ?? 0; + + return value === 0 ? undefined : value; + }, [badge, children]); +} + +function useIsActive(parent: string, route: RouteObject) { + const { path, children } = route; + + const { pathname } = useLocation(); + const root = useMemo(() => pathJoin(parent, path ?? ""), [parent, path]); + + const paths = useMemo( + () => [root, ...(children?.map((v) => pathJoin(root, v.path ?? "")) ?? [])], + [root, children] + ); + + const selection = useSelection().selection; + return useMemo( + () => + selection?.includes(root) || + paths.some((path) => matchPath(path, pathname)), + [pathname, paths, root, selection] + ); +} + +const AppNavbar: FunctionComponent = () => { + const { showed } = useNavbar(); + const [selection, select] = useState(null); + + const { colorScheme, toggleColorScheme } = useMantineColorScheme(); + const dark = colorScheme === "dark"; + + const routes = useRouteItems(); + + const { pathname } = useLocation(); + useEffect(() => { + select(null); + }, [pathname]); + + return ( + + ); +}; + +const RouteItem: FunctionComponent<{ + route: CustomRouteObject; + parent: string; +}> = ({ route, parent }) => { + const { children, name, path, icon, hidden, element } = route; + + const { select } = useSelection(); + + const link = useMemo(() => pathJoin(parent, path ?? ""), [parent, path]); + + const badge = useBadgeValue(route); + + const isOpen = useIsActive(parent, route); + + // Ignore path if it is using match + if (hidden === true || path === undefined || path.includes(":")) { + return null; + } + + if (children !== undefined) { + const elements = ( + + {children.map((child, idx) => ( + + ))} + + ); + + if (name) { + return ( + + { + LOG("info", "clicked", link); + + const validated = + element !== undefined || + children?.find((v) => v.index === true) !== undefined; + + if (!validated) { + event.preventDefault(); + } + + if (isOpen) { + select(null); + } else { + select(link); + } + }} + > + + + ); + } else { + return elements; + } + } else { + return ( + + ); + } +}; + +const useStyles = createStyles((theme) => { + const borderColor = + theme.colorScheme === "light" ? theme.colors.gray[5] : theme.colors.dark[4]; + + const activeBorderColor = + theme.colorScheme === "light" + ? theme.colors.brand[4] + : theme.colors.brand[8]; + + const activeBackgroundColor = + theme.colorScheme === "light" ? theme.colors.gray[1] : theme.colors.dark[8]; + + const hoverBackgroundColor = + theme.colorScheme === "light" ? theme.colors.gray[0] : theme.colors.dark[7]; + + return { + text: { display: "inline-flex", alignItems: "center", width: "100%" }, + anchor: { + textDecoration: "none", + borderLeft: `2px solid ${borderColor}`, + }, + active: { + backgroundColor: activeBackgroundColor, + borderLeft: `2px solid ${activeBorderColor}`, + boxShadow: theme.shadows.xs, + }, + hover: { + backgroundColor: hoverBackgroundColor, + }, + icon: { width: "1.4rem", marginRight: theme.spacing.xs }, + badge: { + marginLeft: "auto", + textDecoration: "none", + boxShadow: theme.shadows.xs, + }, + }; +}); + +interface NavbarItemProps { + name: string; + link: string; + icon?: IconDefinition; + badge?: number; + primary?: boolean; + onClick?: (event: React.MouseEvent) => void; +} + +const NavbarItem: FunctionComponent = ({ + icon, + link, + name, + badge, + onClick, + primary = false, +}) => { + const { classes } = useStyles(); + + const { show } = useNavbar(); + + const { ref, hovered } = useHover(); + + return ( + ) => { + onClick?.(event); + if (!event.isDefaultPrevented()) { + show(false); + } + }} + className={({ isActive }) => + clsx( + clsx(classes.anchor, { + [classes.active]: isActive, + [classes.hover]: hovered, + }) + ) + } + > + + {icon && ( + + )} + {name} + + + + ); +}; + +export default AppNavbar; diff --git a/frontend/src/App/Notification.tsx b/frontend/src/App/Notification.tsx deleted file mode 100644 index 4ca969ac6..000000000 --- a/frontend/src/App/Notification.tsx +++ /dev/null @@ -1,241 +0,0 @@ -import { useReduxStore } from "@/modules/redux/hooks/base"; -import { BuildKey, useIsArrayExtended } from "@/utilities"; -import { - faBug, - faCircleNotch, - faExclamationTriangle, - faInfoCircle, - faStream, - IconDefinition, -} from "@fortawesome/free-solid-svg-icons"; -import { - FontAwesomeIcon, - FontAwesomeIconProps, -} from "@fortawesome/react-fontawesome"; -import { - Fragment, - FunctionComponent, - ReactNode, - useCallback, - useEffect, - useMemo, - useRef, - useState, -} from "react"; -import { - Button, - Dropdown, - Overlay, - ProgressBar, - Tooltip, -} from "react-bootstrap"; -import { useDidUpdate, useTimeoutWhen } from "rooks"; - -enum State { - Idle, - Working, - Failed, -} - -function useTotalProgress(progress: Site.Progress[]) { - return useMemo(() => { - const { value, count } = progress.reduce( - (prev, { value, count }) => { - prev.value += value; - prev.count += count; - return prev; - }, - { value: 0, count: 0 } - ); - - if (count === 0) { - return 0; - } else { - return (value + 0.001) / count; - } - }, [progress]); -} - -function useHasErrorNotification(notifications: Server.Notification[]) { - return useMemo( - () => notifications.find((v) => v.type !== "info") !== undefined, - [notifications] - ); -} - -const NotificationCenter: FunctionComponent = () => { - const { progress, notifications, notifier } = useReduxStore((s) => s.site); - - const dropdownRef = useRef(null); - const [hasNew, setHasNew] = useState(false); - - const hasNewProgress = useIsArrayExtended(progress); - const hasNewNotifications = useIsArrayExtended(notifications); - useDidUpdate(() => { - if (hasNewNotifications || hasNewProgress) { - setHasNew(true); - } - }, [hasNewProgress, hasNewNotifications]); - - useDidUpdate(() => { - if (progress.length === 0 && notifications.length === 0) { - setHasNew(false); - } - }, [progress.length, notifications.length]); - - const [btnState, setBtnState] = useState(State.Idle); - - const totalProgress = useTotalProgress(progress); - const hasError = useHasErrorNotification(notifications); - - useEffect(() => { - if (hasError) { - setBtnState(State.Failed); - } else if (totalProgress > 0 && totalProgress < 1.0) { - setBtnState(State.Working); - } else { - setBtnState(State.Idle); - } - }, [totalProgress, hasError]); - - const iconProps = useMemo(() => { - switch (btnState) { - case State.Idle: - return { - icon: faStream, - }; - case State.Working: - return { - icon: faCircleNotch, - spin: true, - }; - default: - return { - icon: faExclamationTriangle, - }; - } - }, [btnState]); - - const content = useMemo(() => { - const nodes: JSX.Element[] = []; - - nodes.push( - - {notifications.length > 0 ? "Notifications" : "No Notifications"} - - ); - nodes.push( - ...notifications.map((v, idx) => ( - - - - )) - ); - - nodes.push(); - - nodes.push( - - {progress.length > 0 ? "Background Tasks" : "No Background Tasks"} - - ); - nodes.push( - ...progress.map((v, idx) => ( - - - - )) - ); - - return nodes; - }, [progress, notifications]); - - const onToggleClick = useCallback(() => { - setHasNew(false); - }, []); - - // Tooltip Controller - const [showTooltip, setTooltip] = useState(false); - useTimeoutWhen(() => setTooltip(false), 3 * 1000, showTooltip); - useDidUpdate(() => { - if (notifier.content) { - setTooltip(true); - } - }, [notifier.timestamp]); - - return ( - - - - - - {content} - - - {(props) => { - return ( - - {notifier.content} - - ); - }} - - - ); -}; - -const Notification: FunctionComponent = ({ - type, - message, -}) => { - const icon = useMemo(() => { - switch (type) { - case "info": - return faInfoCircle; - case "warning": - return faExclamationTriangle; - default: - return faBug; - } - }, [type]); - return ( -
- - {message} -
- ); -}; - -const Progress: FunctionComponent = ({ - name, - value, - count, - header, -}) => { - const isCompleted = value / count > 1; - const displayValue = Math.min(count, value + 1); - return ( -
-

- {header} -

-

- {isCompleted ? "Completed successfully" : name} -

- -
- ); -}; - -export default NotificationCenter; diff --git a/frontend/src/App/index.tsx b/frontend/src/App/index.tsx index 4cd3236b1..c3451ae0b 100644 --- a/frontend/src/App/index.tsx +++ b/frontend/src/App/index.tsx @@ -1,58 +1,67 @@ -import { LoadingIndicator } from "@/components"; +import AppNavbar from "@/App/Navbar"; import ErrorBoundary from "@/components/ErrorBoundary"; -import { useNotification } from "@/modules/redux/hooks"; -import { useReduxStore } from "@/modules/redux/hooks/base"; -import SocketIO from "@/modules/socketio"; -import LaunchError from "@/pages/LaunchError"; -import Sidebar from "@/Sidebar"; +import { Layout } from "@/constants"; +import NavbarProvider from "@/contexts/Navbar"; +import OnlineProvider from "@/contexts/Online"; +import { notification } from "@/modules/task"; +import CriticalError from "@/pages/CriticalError"; import { Environment } from "@/utilities"; -import { FunctionComponent, useEffect } from "react"; -import { Row } from "react-bootstrap"; -import { Navigate, Outlet } from "react-router-dom"; -import { useEffectOnceWhen } from "rooks"; -import Header from "./Header"; +import { AppShell } from "@mantine/core"; +import { useWindowEvent } from "@mantine/hooks"; +import { showNotification } from "@mantine/notifications"; +import { FunctionComponent, useEffect, useState } from "react"; +import { Outlet, useNavigate } from "react-router-dom"; +import AppHeader from "./Header"; const App: FunctionComponent = () => { - const { status } = useReduxStore((s) => s.site); + const navigate = useNavigate(); - useEffect(() => { - SocketIO.initialize(); - }, []); + const [criticalError, setCriticalError] = useState(null); + const [navbar, setNavbar] = useState(false); + const [online, setOnline] = useState(true); + + useWindowEvent("app-critical-error", ({ detail }) => { + setCriticalError(detail.message); + }); + + useWindowEvent("app-login-required", () => { + navigate("/login"); + }); - const notify = useNotification("has-update", 10 * 1000); + useWindowEvent("app-online-status", ({ detail }) => { + setOnline(detail.online); + }); - // Has any update? - useEffectOnceWhen(() => { + useEffect(() => { if (Environment.hasUpdate) { - notify({ - type: "info", - message: "A new version of Bazarr is ready, restart is required", - // TODO: Restart action - }); + showNotification( + notification.info( + "Update available", + "A new version of Bazarr is ready, restart is required" + ) + ); } - }, status === "initialized"); - - if (status === "unauthenticated") { - return ; - } else if (status === "uninitialized") { - return ( - - Please wait - - ); - } else if (status === "error") { - return Cannot Initialize Bazarr; + }, []); + + if (criticalError !== null) { + return ; } return ( - -
-
- - - - + + + } + navbar={} + padding={0} + fixed + > + + + +
); }; diff --git a/frontend/src/App/theme.tsx b/frontend/src/App/theme.tsx new file mode 100644 index 000000000..b56318cd8 --- /dev/null +++ b/frontend/src/App/theme.tsx @@ -0,0 +1,72 @@ +import { + ColorScheme, + ColorSchemeProvider, + MantineProvider, + MantineThemeOverride, +} from "@mantine/core"; +import { useColorScheme } from "@mantine/hooks"; +import { FunctionComponent, useCallback, useEffect, useState } from "react"; + +const theme: MantineThemeOverride = { + fontFamily: [ + "Roboto", + "open sans", + "Helvetica Neue", + "Helvetica", + "Arial", + "sans-serif", + ], + colors: { + brand: [ + "#F8F0FC", + "#F3D9FA", + "#EEBEFA", + "#E599F7", + "#DA77F2", + "#CC5DE8", + "#BE4BDB", + "#AE3EC9", + "#9C36B5", + "#862E9C", + ], + }, + primaryColor: "brand", +}; + +function useAutoColorScheme() { + const preferredColorScheme = useColorScheme(); + const [colorScheme, setColorScheme] = useState(preferredColorScheme); + + // automatically switch dark/light theme + useEffect(() => { + setColorScheme(preferredColorScheme); + }, [preferredColorScheme]); + + const toggleColorScheme = useCallback((value?: ColorScheme) => { + setColorScheme((scheme) => value || (scheme === "dark" ? "light" : "dark")); + }, []); + + return { colorScheme, setColorScheme, toggleColorScheme }; +} + +const ThemeProvider: FunctionComponent = ({ children }) => { + const { colorScheme, toggleColorScheme } = useAutoColorScheme(); + + return ( + + + {children} + + + ); +}; + +export default ThemeProvider; diff --git a/frontend/src/Router/Redirector.tsx b/frontend/src/Router/Redirector.tsx index b76eeca0f..c9190c291 100644 --- a/frontend/src/Router/Redirector.tsx +++ b/frontend/src/Router/Redirector.tsx @@ -1,18 +1,27 @@ -import { useEnabledStatus } from "@/modules/redux/hooks"; -import { FunctionComponent } from "react"; -import { Navigate } from "react-router-dom"; +import { useSystemSettings } from "@/apis/hooks"; +import { LoadingOverlay } from "@mantine/core"; +import { FunctionComponent, useEffect } from "react"; +import { useNavigate } from "react-router-dom"; const Redirector: FunctionComponent = () => { - const { sonarr, radarr } = useEnabledStatus(); + const { data } = useSystemSettings(); - let path = "/settings/general"; - if (sonarr) { - path = "/series"; - } else if (radarr) { - path = "/movies"; - } + const navigate = useNavigate(); - return ; + useEffect(() => { + if (data) { + const { use_sonarr, use_radarr } = data.general; + if (use_sonarr) { + navigate("/series"); + } else if (use_radarr) { + navigate("/movies"); + } else { + navigate("/settings/general"); + } + } + }, [data, navigate]); + + return ; }; export default Redirector; diff --git a/frontend/src/Router/index.tsx b/frontend/src/Router/index.tsx index b47e823da..e6c4b37fb 100644 --- a/frontend/src/Router/index.tsx +++ b/frontend/src/Router/index.tsx @@ -1,7 +1,8 @@ import { useBadges } from "@/apis/hooks"; +import { useEnabledStatus } from "@/apis/hooks/site"; import App from "@/App"; -import Lazy from "@/components/Lazy"; -import { useEnabledStatus } from "@/modules/redux/hooks"; +import { Lazy } from "@/components/async"; +import Authentication from "@/pages/Authentication"; import BlacklistMoviesView from "@/pages/Blacklist/Movies"; import BlacklistSeriesView from "@/pages/Blacklist/Series"; import Episodes from "@/pages/Episodes"; @@ -10,6 +11,7 @@ import SeriesHistoryView from "@/pages/History/Series"; import MovieView from "@/pages/Movies"; import MovieDetailView from "@/pages/Movies/Details"; import MovieMassEditor from "@/pages/Movies/Editor"; +import NotFound from "@/pages/NotFound"; import SeriesView from "@/pages/Series"; import SeriesMassEditor from "@/pages/Series/Editor"; import SettingsGeneralView from "@/pages/Settings/General"; @@ -38,7 +40,7 @@ import { faLaptop, faPlay, } from "@fortawesome/free-solid-svg-icons"; -import React, { +import { createContext, FunctionComponent, lazy, @@ -51,8 +53,6 @@ import { CustomRouteObject } from "./type"; const HistoryStats = lazy(() => import("@/pages/History/Statistics")); const SystemStatusView = lazy(() => import("@/pages/System/Status")); -const Authentication = lazy(() => import("@/pages/Authentication")); -const NotFound = lazy(() => import("@/pages/404")); function useRoutes(): CustomRouteObject[] { const { data } = useBadges(); @@ -277,25 +277,17 @@ function useRoutes(): CustomRouteObject[] { }, ], }, + { + path: "*", + hidden: true, + element: , + }, ], }, { path: "/login", hidden: true, - element: ( - - - - ), - }, - { - path: "*", - hidden: true, - element: ( - - - - ), + element: , }, ], [data?.episodes, data?.movies, data?.providers, radarr, sonarr] diff --git a/frontend/src/Sidebar/index.tsx b/frontend/src/Sidebar/index.tsx deleted file mode 100644 index 20e9f06bb..000000000 --- a/frontend/src/Sidebar/index.tsx +++ /dev/null @@ -1,256 +0,0 @@ -import { setSidebar } from "@/modules/redux/actions"; -import { useReduxAction, useReduxStore } from "@/modules/redux/hooks/base"; -import { useRouteItems } from "@/Router"; -import { CustomRouteObject, Route } from "@/Router/type"; -import { BuildKey, Environment, pathJoin } from "@/utilities"; -import { LOG } from "@/utilities/console"; -import { useGotoHomepage } from "@/utilities/hooks"; -import { IconDefinition } from "@fortawesome/free-solid-svg-icons"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import clsx from "clsx"; -import { - createContext, - FunctionComponent, - useContext, - useEffect, - useMemo, - useState, -} from "react"; -import { - Badge, - Collapse, - Container, - Image, - ListGroup, - ListGroupItem, -} from "react-bootstrap"; -import { - matchPath, - NavLink, - RouteObject, - useLocation, - useNavigate, -} from "react-router-dom"; - -const Selection = createContext<{ - selection: string | null; - select: (path: string | null) => void; -}>({ - selection: null, - select: () => { - LOG("error", "Selection context not initialized"); - }, -}); - -function useSelection() { - return useContext(Selection); -} - -function useBadgeValue(route: Route.Item) { - const { badge, children } = route; - return useMemo(() => { - let value = badge ?? 0; - - if (children === undefined) { - return value; - } - - value += - children.reduce((acc, child: Route.Item) => { - if (child.badge && child.hidden !== true) { - return acc + (child.badge ?? 0); - } - return acc; - }, 0) ?? 0; - - return value === 0 ? undefined : value; - }, [badge, children]); -} - -function useIsActive(parent: string, route: RouteObject) { - const { path, children } = route; - - const { pathname } = useLocation(); - const root = useMemo(() => pathJoin(parent, path ?? ""), [parent, path]); - - const paths = useMemo( - () => [root, ...(children?.map((v) => pathJoin(root, v.path ?? "")) ?? [])], - [root, children] - ); - - const selection = useSelection().selection; - return useMemo( - () => - selection?.includes(root) || - paths.some((path) => matchPath(path, pathname)), - [pathname, paths, root, selection] - ); -} - -// Actual sidebar -const Sidebar: FunctionComponent = () => { - const [selection, select] = useState(null); - const isShow = useReduxStore((s) => s.site.showSidebar); - - const showSidebar = useReduxAction(setSidebar); - - const goHome = useGotoHomepage(); - - const routes = useRouteItems(); - - const { pathname } = useLocation(); - useEffect(() => { - select(null); - }, [pathname]); - - return ( - - -
showSidebar(false)} - >
-
- ); -}; - -const RouteItem: FunctionComponent<{ - route: CustomRouteObject; - parent: string; -}> = ({ route, parent }) => { - const { children, name, path, icon, hidden, element } = route; - - const isValidated = useMemo( - () => - element !== undefined || - children?.find((v) => v.index === true) !== undefined, - [element, children] - ); - - const { select } = useSelection(); - - const navigate = useNavigate(); - - const link = useMemo(() => pathJoin(parent, path ?? ""), [parent, path]); - - const badge = useBadgeValue(route); - - const isOpen = useIsActive(parent, route); - - if (hidden === true) { - return null; - } - - // Ignore path if it is using match - if (path === undefined || path.includes(":")) { - return null; - } - - if (children !== undefined) { - const elements = children.map((child, idx) => ( - - )); - - if (name) { - return ( -
- { - LOG("info", "clicked", link); - - if (isValidated) { - navigate(link); - } - - if (isOpen) { - select(null); - } else { - select(link); - } - }} - > - - - -
{elements}
-
-
- ); - } else { - return <>{elements}; - } - } else { - return ( - - clsx("list-group-item list-group-item-action button sb-collapse", { - active: isActive, - }) - } - > - - - ); - } -}; - -interface ItemComponentProps { - name: string; - icon?: IconDefinition; - badge?: number; -} - -const RouteItemContent: FunctionComponent = ({ - icon, - name, - badge, -}) => { - return ( - <> - {icon && } - - {name} - - - - ); -}; - -export default Sidebar; diff --git a/frontend/src/apis/hooks/site.ts b/frontend/src/apis/hooks/site.ts new file mode 100644 index 000000000..0ac244000 --- /dev/null +++ b/frontend/src/apis/hooks/site.ts @@ -0,0 +1,15 @@ +import { useSystemSettings } from "."; + +export function useEnabledStatus() { + const { data } = useSystemSettings(); + + return { + sonarr: data?.general.use_sonarr ?? false, + radarr: data?.general.use_radarr ?? false, + }; +} + +export function useShowOnlyDesired() { + const { data } = useSystemSettings(); + return data?.general.embedded_subs_show_desired ?? false; +} diff --git a/frontend/src/apis/hooks/system.ts b/frontend/src/apis/hooks/system.ts index 6c756df03..0cd7c3799 100644 --- a/frontend/src/apis/hooks/system.ts +++ b/frontend/src/apis/hooks/system.ts @@ -1,7 +1,7 @@ +import { Environment } from "@/utilities"; +import { setLoginRequired } from "@/utilities/event"; import { useMemo } from "react"; import { useMutation, useQuery, useQueryClient } from "react-query"; -import { setUnauthenticated } from "../../modules/redux/actions"; -import store from "../../modules/redux/store"; import { QueryKeys } from "../queries/keys"; import api from "../raw"; @@ -173,7 +173,7 @@ export function useSystem() { () => api.system.logout(), { onSuccess: () => { - store.dispatch(setUnauthenticated()); + setLoginRequired(); client.clear(); }, } @@ -185,7 +185,8 @@ export function useSystem() { api.system.login(param.username, param.password), { onSuccess: () => { - window.location.reload(); + // TODO: Hard-coded value + window.location.replace(`/${Environment.baseUrl}`); }, } ); @@ -216,7 +217,7 @@ export function useSystem() { shutdown, restart, login, - isWorking: isLoggingOut || isShuttingDown || isRestarting || isLoggingIn, + isMutating: isLoggingOut || isShuttingDown || isRestarting || isLoggingIn, }), [ isLoggingIn, diff --git a/frontend/src/apis/queries/client.ts b/frontend/src/apis/queries/client.ts index da73aab8b..91a0af712 100644 --- a/frontend/src/apis/queries/client.ts +++ b/frontend/src/apis/queries/client.ts @@ -1,15 +1,15 @@ +import SocketIO from "@/modules/socketio"; +import { setLoginRequired } from "@/utilities/event"; import Axios, { AxiosError, AxiosInstance, CancelTokenSource } from "axios"; -import { setUnauthenticated } from "../../modules/redux/actions"; -import { AppDispatch } from "../../modules/redux/store"; -import { Environment, isProdEnv } from "../../utilities"; +import { Environment } from "../../utilities"; class BazarrClient { axios!: AxiosInstance; source!: CancelTokenSource; - dispatch!: AppDispatch; constructor() { const baseUrl = `${Environment.baseUrl}/api/`; this.initialize(baseUrl, Environment.apiKey); + SocketIO.initialize(); } initialize(url: string, apikey?: string) { @@ -48,16 +48,10 @@ class BazarrClient { ); } - _resetApi(apikey: string) { - if (!isProdEnv) { - this.axios.defaults.headers.common["X-API-KEY"] = apikey; - } - } - handleError(code: number) { switch (code) { case 401: - this.dispatch(setUnauthenticated()); + setLoginRequired(); break; case 500: break; diff --git a/frontend/src/apis/queries/hooks.ts b/frontend/src/apis/queries/hooks.ts index db76cd32e..0b36421ea 100644 --- a/frontend/src/apis/queries/hooks.ts +++ b/frontend/src/apis/queries/hooks.ts @@ -1,4 +1,4 @@ -import { GetItemId } from "@/utilities"; +import { GetItemId, useOnValueChange } from "@/utilities"; import { usePageSize } from "@/utilities/storage"; import { useCallback, useEffect, useState } from "react"; import { @@ -13,17 +13,14 @@ export type UsePaginationQueryResult = UseQueryResult< DataWrapperWithTotal > & { controls: { - previousPage: () => void; - nextPage: () => void; gotoPage: (index: number) => void; }; paginationStatus: { + isPageLoading: boolean; totalCount: number; pageSize: number; pageCount: number; page: number; - canPrevious: boolean; - canNext: boolean; }; }; @@ -67,16 +64,6 @@ export function usePaginationQuery< const totalCount = data?.total ?? 0; const pageCount = Math.ceil(totalCount / pageSize); - const previousPage = useCallback(() => { - setIndex((index) => Math.max(0, index - 1)); - }, []); - - const nextPage = useCallback(() => { - if (pageCount > 0) { - setIndex((index) => Math.min(pageCount - 1, index + 1)); - } - }, [pageCount]); - const gotoPage = useCallback( (idx: number) => { if (idx >= 0 && idx < pageCount) { @@ -86,6 +73,20 @@ export function usePaginationQuery< [pageCount] ); + const [isPageLoading, setIsPageLoading] = useState(false); + + useOnValueChange(page, () => { + if (results.isFetching) { + setIsPageLoading(true); + } + }); + + useEffect(() => { + if (!results.isFetching) { + setIsPageLoading(false); + } + }, [results.isFetching]); + // Reset page index if we out of bound useEffect(() => { if (pageCount === 0) return; @@ -100,17 +101,14 @@ export function usePaginationQuery< return { ...results, paginationStatus: { + isPageLoading, totalCount, pageCount, pageSize, page, - canPrevious: page > 0, - canNext: page < pageCount - 1, }, controls: { gotoPage, - previousPage, - nextPage, }, }; } diff --git a/frontend/src/components/ItemOverview.tsx b/frontend/src/components/ItemOverview.tsx deleted file mode 100644 index 565430f2e..000000000 --- a/frontend/src/components/ItemOverview.tsx +++ /dev/null @@ -1,204 +0,0 @@ -import { BuildKey, isMovie } from "@/utilities"; -import { - useLanguageProfileBy, - useProfileItemsToLanguages, -} from "@/utilities/languages"; -import { - faBookmark as farBookmark, - faClone as fasClone, - faFolder, -} from "@fortawesome/free-regular-svg-icons"; -import { - faBookmark, - faLanguage, - faMusic, - faStream, - faTags, - IconDefinition, -} from "@fortawesome/free-solid-svg-icons"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { FunctionComponent, useMemo } from "react"; -import { - Badge, - Col, - Container, - Image, - OverlayTrigger, - Popover, - Row, -} from "react-bootstrap"; -import Language from "./bazarr/Language"; - -interface Props { - item: Item.Base; - details?: { icon: IconDefinition; text: string }[]; -} - -const ItemOverview: FunctionComponent = (props) => { - const { item, details } = props; - - const detailBadges = useMemo(() => { - const badges: (JSX.Element | null)[] = []; - badges.push( - - {item.path} - - ); - - badges.push( - ...(details?.map((val, idx) => ( - - {val.text} - - )) ?? []) - ); - - if (item.tags.length > 0) { - badges.push( - - {item.tags.join("|")} - - ); - } - - return badges; - }, [details, item.path, item.tags]); - - const audioBadges = useMemo( - () => - item.audio_language.map((v, idx) => ( - - {v.name} - - )), - [item.audio_language] - ); - - const profile = useLanguageProfileBy(item.profileId); - const profileItems = useProfileItemsToLanguages(profile); - - const languageBadges = useMemo(() => { - const badges: (JSX.Element | null)[] = []; - - if (profile) { - badges.push( - - {profile.name} - - ); - - badges.push( - ...profileItems.map((v, idx) => ( - - - - )) - ); - } - - return badges; - }, [profile, profileItems]); - - const alternativePopover = useMemo( - () => ( - - Alternate Titles - - {item.alternativeTitles.map((v, idx) => ( -
  • {v}
  • - ))} -
    -
    - ), - [item.alternativeTitles] - ); - - return ( - - - - - - - - - {isMovie(item) ? ( - - ) : null} -

    {item.title}

    - -
    - {detailBadges} - {audioBadges} - {languageBadges} - - {item.overview} - -
    - -
    -
    - ); -}; - -interface ItemBadgeProps { - icon: IconDefinition; - children: string | JSX.Element; - desc?: string; -} - -const DetailBadge: FunctionComponent = ({ - icon, - desc, - children, -}) => ( - - - {children} - -); - -export default ItemOverview; diff --git a/frontend/src/components/LanguageSelector.tsx b/frontend/src/components/LanguageSelector.tsx deleted file mode 100644 index 648ccf167..000000000 --- a/frontend/src/components/LanguageSelector.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import { Selector, SelectorOption, SelectorProps } from "@/components"; -import { useMemo } from "react"; - -interface Props { - options: readonly Language.Info[]; -} - -type RemovedSelectorProps = Omit< - SelectorProps, - "label" ->; - -export type LanguageSelectorProps = Override< - Props, - RemovedSelectorProps ->; - -function getLabel(lang: Language.Info) { - return lang.name; -} - -export function LanguageSelector( - props: LanguageSelectorProps -) { - const { options, ...selector } = props; - - const items = useMemo[]>( - () => - options.map((v) => ({ - label: v.name, - value: v, - })), - [options] - ); - - return ( - - ); -} diff --git a/frontend/src/components/Search.tsx b/frontend/src/components/Search.tsx new file mode 100644 index 000000000..ec1a23574 --- /dev/null +++ b/frontend/src/components/Search.tsx @@ -0,0 +1,70 @@ +import { useServerSearch } from "@/apis/hooks"; +import { useDebouncedValue } from "@/utilities"; +import { faSearch } from "@fortawesome/free-solid-svg-icons"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { Anchor, Autocomplete, SelectItemProps } from "@mantine/core"; +import { forwardRef, FunctionComponent, useMemo, useState } from "react"; +import { Link } from "react-router-dom"; + +type SearchResultItem = { + value: string; + link: string; +}; + +function useSearch(query: string) { + const debouncedQuery = useDebouncedValue(query, 500); + const { data } = useServerSearch(debouncedQuery, debouncedQuery.length > 0); + + return useMemo( + () => + data?.map((v) => { + let link: string; + if (v.sonarrSeriesId) { + link = `/series/${v.sonarrSeriesId}`; + } else if (v.radarrId) { + link = `/movies/${v.radarrId}`; + } else { + throw new Error("Unknown search result"); + } + + return { + value: `${v.title} (${v.year})`, + link, + }; + }) ?? [], + [data] + ); +} + +type ResultCompProps = SelectItemProps & SearchResultItem; + +const ResultComponent = forwardRef( + ({ link, value }, ref) => { + return ( + + {value} + + ); + } +); + +const Search: FunctionComponent = () => { + const [query, setQuery] = useState(""); + + const results = useSearch(query); + + return ( + } + itemComponent={ResultComponent} + placeholder="Search" + size="sm" + data={results} + value={query} + onChange={setQuery} + onBlur={() => setQuery("")} + > + ); +}; + +export default Search; diff --git a/frontend/src/components/SearchBar.tsx b/frontend/src/components/SearchBar.tsx deleted file mode 100644 index acdfd56a9..000000000 --- a/frontend/src/components/SearchBar.tsx +++ /dev/null @@ -1,119 +0,0 @@ -import { useServerSearch } from "@/apis/hooks"; -import { uniqueId } from "lodash"; -import { - FunctionComponent, - useCallback, - useEffect, - useMemo, - useState, -} from "react"; -import { Dropdown, Form } from "react-bootstrap"; -import { useNavigate } from "react-router-dom"; -import { useThrottle } from "rooks"; - -function useSearch(query: string) { - const { data } = useServerSearch(query, query.length > 0); - - return useMemo( - () => - data?.map((v) => { - let link: string; - let id: string; - if (v.sonarrSeriesId) { - link = `/series/${v.sonarrSeriesId}`; - id = `series-${v.sonarrSeriesId}`; - } else if (v.radarrId) { - link = `/movies/${v.radarrId}`; - id = `movie-${v.radarrId}`; - } else { - link = ""; - id = uniqueId("unknown"); - } - - return { - name: `${v.title} (${v.year})`, - link, - id, - }; - }) ?? [], - [data] - ); -} -export interface SearchResult { - id: string; - name: string; - link?: string; -} - -interface Props { - className?: string; - onFocus?: () => void; - onBlur?: () => void; -} - -export const SearchBar: FunctionComponent = ({ - onFocus, - onBlur, - className, -}) => { - const [display, setDisplay] = useState(""); - const [query, setQuery] = useState(""); - - const [debounce] = useThrottle(setQuery, 500); - useEffect(() => { - debounce(display); - }, [debounce, display]); - - const results = useSearch(query); - - const navigate = useNavigate(); - - const clear = useCallback(() => { - setDisplay(""); - setQuery(""); - }, []); - - const items = useMemo(() => { - const its = results.map((v) => ( - - {v.name} - - )); - - if (its.length === 0) { - its.push(No Found); - } - - return its; - }, [results]); - - return ( - { - if (link) { - clear(); - navigate(link); - } - }} - > - setDisplay(e.currentTarget.value)} - > - - {items} - - - ); -}; diff --git a/frontend/src/components/SubtitleToolsMenu.tsx b/frontend/src/components/SubtitleToolsMenu.tsx new file mode 100644 index 000000000..c82112961 --- /dev/null +++ b/frontend/src/components/SubtitleToolsMenu.tsx @@ -0,0 +1,209 @@ +import { useSubtitleAction } from "@/apis/hooks"; +import { ColorToolModal } from "@/components/forms/ColorToolForm"; +import { FrameRateModal } from "@/components/forms/FrameRateForm"; +import { TimeOffsetModal } from "@/components/forms/TimeOffsetForm"; +import { TranslationModal } from "@/components/forms/TranslationForm"; +import { useModals } from "@/modules/modals"; +import { ModalComponent } from "@/modules/modals/WithModal"; +import { task } from "@/modules/task"; +import { + faClock, + faCode, + faDeaf, + faExchangeAlt, + faFilm, + faImage, + faLanguage, + faMagic, + faPaintBrush, + faPlay, + faSearch, + faTextHeight, + faTrash, + IconDefinition, +} from "@fortawesome/free-solid-svg-icons"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { Divider, List, Menu, MenuProps, ScrollArea } from "@mantine/core"; +import { FunctionComponent, ReactElement, useCallback, useMemo } from "react"; + +export interface ToolOptions { + key: string; + icon: IconDefinition; + name: string; + modal?: ModalComponent<{ + selections: FormType.ModifySubtitle[]; + }>; +} + +export function useTools() { + return useMemo( + () => [ + { + key: "sync", + icon: faPlay, + name: "Sync", + }, + { + key: "remove_HI", + icon: faDeaf, + name: "Remove HI Tags", + }, + { + key: "remove_tags", + icon: faCode, + name: "Remove Style Tags", + }, + { + key: "OCR_fixes", + icon: faImage, + name: "OCR Fixes", + }, + { + key: "common", + icon: faMagic, + name: "Common Fixes", + }, + { + key: "fix_uppercase", + icon: faTextHeight, + name: "Fix Uppercase", + }, + { + key: "reverse_rtl", + icon: faExchangeAlt, + name: "Reverse RTL", + }, + { + key: "add_color", + icon: faPaintBrush, + name: "Add Color...", + modal: ColorToolModal, + }, + { + key: "change_frame_rate", + icon: faFilm, + name: "Change Frame Rate...", + modal: FrameRateModal, + }, + { + key: "adjust_time", + icon: faClock, + name: "Adjust Times...", + modal: TimeOffsetModal, + }, + { + key: "translation", + icon: faLanguage, + name: "Translate...", + modal: TranslationModal, + }, + ], + [] + ); +} + +interface Props { + selections: FormType.ModifySubtitle[]; + children?: ReactElement; + menu?: Omit; + onAction?: (action: "delete" | "search") => void; +} + +const SubtitleToolsMenu: FunctionComponent = ({ + selections, + children, + menu, + onAction, +}) => { + const { mutateAsync } = useSubtitleAction(); + + const process = useCallback( + (action: string, name: string) => { + selections.forEach((s) => { + const form: FormType.ModifySubtitle = { + id: s.id, + type: s.type, + language: s.language, + path: s.path, + }; + task.create(s.path, name, mutateAsync, { action, form }); + }); + }, + [mutateAsync, selections] + ); + + const tools = useTools(); + const modals = useModals(); + + const disabledTools = selections.length === 0; + + return ( + + Tools + {tools.map((tool) => ( + } + onClick={() => { + if (tool.modal) { + modals.openContextModal(tool.modal, { selections }); + } else { + process(tool.key, tool.name); + } + }} + > + {tool.name} + + ))} + + Actions + } + onClick={() => { + onAction?.("search"); + }} + > + Search + + } + onClick={() => { + modals.openConfirmModal({ + title: "The following subtitles will be deleted", + size: "lg", + children: ( + + + {selections.map((s) => ( + + {s.path} + + ))} + + + ), + onConfirm: () => { + onAction?.("delete"); + }, + labels: { confirm: "Delete", cancel: "Cancel" }, + confirmProps: { color: "red" }, + }); + }} + > + Delete... + + + ); +}; + +export default SubtitleToolsMenu; diff --git a/frontend/src/components/TextPopover.tsx b/frontend/src/components/TextPopover.tsx new file mode 100644 index 000000000..8fda5913e --- /dev/null +++ b/frontend/src/components/TextPopover.tsx @@ -0,0 +1,30 @@ +import { Tooltip, TooltipProps } from "@mantine/core"; +import { useHover } from "@mantine/hooks"; +import { isNull, isUndefined } from "lodash"; +import { FunctionComponent, ReactElement } from "react"; + +interface TextPopoverProps { + children: ReactElement; + text: string | undefined | null; + tooltip?: Omit; +} + +const TextPopover: FunctionComponent = ({ + children, + text, + tooltip, +}) => { + const { hovered, ref } = useHover(); + + if (isNull(text) || isUndefined(text)) { + return children; + } + + return ( + +
    {children}
    +
    + ); +}; + +export default TextPopover; diff --git a/frontend/src/components/async.tsx b/frontend/src/components/async.tsx deleted file mode 100644 index 7c781707e..000000000 --- a/frontend/src/components/async.tsx +++ /dev/null @@ -1,161 +0,0 @@ -import { - faCheck, - faCircleNotch, - faTimes, -} from "@fortawesome/free-solid-svg-icons"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { - FunctionComponent, - PropsWithChildren, - ReactElement, - useCallback, - useEffect, - useState, -} from "react"; -import { Button, ButtonProps } from "react-bootstrap"; -import { UseQueryResult } from "react-query"; -import { useTimeoutWhen } from "rooks"; -import { LoadingIndicator } from "."; - -interface QueryOverlayProps { - result: UseQueryResult; - children: ReactElement; -} - -export const QueryOverlay: FunctionComponent = ({ - children, - result: { isLoading, isError, error }, -}) => { - if (isLoading) { - return ; - } else if (isError) { - return

    {error as string}

    ; - } - - return children; -}; - -interface PromiseProps { - promise: () => Promise; - children: FunctionComponent; -} - -export function PromiseOverlay({ promise, children }: PromiseProps) { - const [item, setItem] = useState(null); - - useEffect(() => { - promise().then(setItem); - }, [promise]); - - if (item === null) { - return ; - } else { - return children(item); - } -} - -interface AsyncButtonProps { - as?: ButtonProps["as"]; - variant?: ButtonProps["variant"]; - size?: ButtonProps["size"]; - - className?: string; - disabled?: boolean; - onChange?: (v: boolean) => void; - - noReset?: boolean; - animation?: boolean; - - promise: () => Promise | null; - onSuccess?: (result: T) => void; - error?: () => void; -} - -enum RequestState { - Success, - Error, - Invalid, -} - -export function AsyncButton( - props: PropsWithChildren> -): JSX.Element { - const { - children: propChildren, - className, - promise, - onSuccess, - noReset, - animation, - error, - onChange, - disabled, - ...button - } = props; - - const [loading, setLoading] = useState(false); - - const [state, setState] = useState(RequestState.Invalid); - - const needFire = state !== RequestState.Invalid && !noReset; - - useTimeoutWhen( - () => { - setState(RequestState.Invalid); - }, - 2 * 1000, - needFire - ); - - const click = useCallback(() => { - if (state !== RequestState.Invalid) { - return; - } - - const result = promise(); - - if (result) { - setLoading(true); - onChange && onChange(true); - result - .then((res) => { - setState(RequestState.Success); - onSuccess && onSuccess(res); - }) - .catch(() => { - setState(RequestState.Error); - error && error(); - }) - .finally(() => { - setLoading(false); - onChange && onChange(false); - }); - } - }, [error, onChange, promise, onSuccess, state]); - - const showAnimation = animation ?? true; - - let children = propChildren; - if (showAnimation) { - if (loading) { - children = ; - } - - if (state === RequestState.Success) { - children = ; - } else if (state === RequestState.Error) { - children = ; - } - } - - return ( - - ); -} diff --git a/frontend/src/components/Lazy.tsx b/frontend/src/components/async/Lazy.tsx similarity index 50% rename from frontend/src/components/Lazy.tsx rename to frontend/src/components/async/Lazy.tsx index a22dfd15a..5edb55c5b 100644 --- a/frontend/src/components/Lazy.tsx +++ b/frontend/src/components/async/Lazy.tsx @@ -1,8 +1,8 @@ +import { LoadingOverlay } from "@mantine/core"; import { FunctionComponent, Suspense } from "react"; -import { LoadingIndicator } from "."; const Lazy: FunctionComponent = ({ children }) => { - return }>{children}; + return }>{children}; }; export default Lazy; diff --git a/frontend/src/components/async/MutateAction.tsx b/frontend/src/components/async/MutateAction.tsx new file mode 100644 index 000000000..920fe4ff3 --- /dev/null +++ b/frontend/src/components/async/MutateAction.tsx @@ -0,0 +1,48 @@ +import { useCallback, useState } from "react"; +import { UseMutationResult } from "react-query"; +import { Action } from "../inputs"; +import { ActionProps } from "../inputs/Action"; + +type MutateActionProps = Omit< + ActionProps, + "onClick" | "loading" | "color" +> & { + mutation: UseMutationResult; + args: () => VAR | null; + onSuccess?: (args: DATA) => void; + onError?: () => void; + noReset?: boolean; +}; + +function MutateAction({ + mutation, + noReset, + onSuccess, + onError, + args, + ...props +}: MutateActionProps) { + const { mutateAsync } = mutation; + + const [isLoading, setLoading] = useState(false); + + const onClick = useCallback(async () => { + setLoading(true); + try { + const argument = args(); + if (argument !== null) { + const data = await mutateAsync(argument); + onSuccess?.(data); + } else { + onError?.(); + } + } catch (error) { + onError?.(); + } + setLoading(false); + }, [args, mutateAsync, onError, onSuccess]); + + return ; +} + +export default MutateAction; diff --git a/frontend/src/components/async/MutateButton.tsx b/frontend/src/components/async/MutateButton.tsx new file mode 100644 index 000000000..af301773b --- /dev/null +++ b/frontend/src/components/async/MutateButton.tsx @@ -0,0 +1,47 @@ +import { Button, ButtonProps } from "@mantine/core"; +import { useCallback, useState } from "react"; +import { UseMutationResult } from "react-query"; + +type MutateButtonProps = Omit< + ButtonProps<"button">, + "onClick" | "loading" | "color" +> & { + mutation: UseMutationResult; + args: () => VAR | null; + onSuccess?: (args: DATA) => void; + onError?: () => void; + noReset?: boolean; +}; + +function MutateButton({ + mutation, + noReset, + onSuccess, + onError, + args, + ...props +}: MutateButtonProps) { + const { mutateAsync } = mutation; + + const [isLoading, setLoading] = useState(false); + + const onClick = useCallback(async () => { + setLoading(true); + try { + const argument = args(); + if (argument !== null) { + const data = await mutateAsync(argument); + onSuccess?.(data); + } else { + onError?.(); + } + } catch (error) { + onError?.(); + } + setLoading(false); + }, [args, mutateAsync, onError, onSuccess]); + + return ; +} + +export default MutateButton; diff --git a/frontend/src/components/async/QueryOverlay.tsx b/frontend/src/components/async/QueryOverlay.tsx new file mode 100644 index 000000000..24b95ab18 --- /dev/null +++ b/frontend/src/components/async/QueryOverlay.tsx @@ -0,0 +1,25 @@ +import { LoadingProvider } from "@/contexts"; +import { LoadingOverlay } from "@mantine/core"; +import { FunctionComponent, ReactNode } from "react"; +import { UseQueryResult } from "react-query"; + +interface QueryOverlayProps { + result: UseQueryResult; + global?: boolean; + children: ReactNode; +} + +const QueryOverlay: FunctionComponent = ({ + children, + global = false, + result: { isLoading, isError, error }, +}) => { + return ( + + + {children} + + ); +}; + +export default QueryOverlay; diff --git a/frontend/src/components/async/index.ts b/frontend/src/components/async/index.ts new file mode 100644 index 000000000..77dba76df --- /dev/null +++ b/frontend/src/components/async/index.ts @@ -0,0 +1,3 @@ +export { default as Lazy } from "./Lazy"; +export { default as MutateAction } from "./MutateAction"; +export { default as QueryOverlay } from "./QueryOverlay"; diff --git a/frontend/src/components/bazarr/AudioList.tsx b/frontend/src/components/bazarr/AudioList.tsx new file mode 100644 index 000000000..9b88de9dc --- /dev/null +++ b/frontend/src/components/bazarr/AudioList.tsx @@ -0,0 +1,26 @@ +import { BuildKey } from "@/utilities"; +import { Badge, BadgeProps, Group, GroupProps } from "@mantine/core"; +import { FunctionComponent } from "react"; + +export type AudioListProps = GroupProps & { + audios: Language.Info[]; + badgeProps?: BadgeProps<"div">; +}; + +const AudioList: FunctionComponent = ({ + audios, + badgeProps, + ...group +}) => { + return ( + + {audios.map((audio, idx) => ( + + {audio.name} + + ))} + + ); +}; + +export default AudioList; diff --git a/frontend/src/components/bazarr/HistoryIcon.tsx b/frontend/src/components/bazarr/HistoryIcon.tsx new file mode 100644 index 000000000..9a0322bf8 --- /dev/null +++ b/frontend/src/components/bazarr/HistoryIcon.tsx @@ -0,0 +1,54 @@ +import { + faClock, + faCloudUploadAlt, + faDownload, + faRecycle, + faTrash, + faUser, +} from "@fortawesome/free-solid-svg-icons"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { FunctionComponent } from "react"; + +enum HistoryAction { + Delete = 0, + Download, + Manual, + Upgrade, + Upload, + Sync, +} + +const HistoryIcon: FunctionComponent<{ + action: number; + title?: string; +}> = ({ action, title }) => { + let icon = null; + switch (action) { + case HistoryAction.Delete: + icon = faTrash; + break; + case HistoryAction.Download: + icon = faDownload; + break; + case HistoryAction.Manual: + icon = faUser; + break; + case HistoryAction.Sync: + icon = faClock; + break; + case HistoryAction.Upgrade: + icon = faRecycle; + break; + case HistoryAction.Upload: + icon = faCloudUploadAlt; + break; + } + + if (icon) { + return ; + } else { + return null; + } +}; + +export default HistoryIcon; diff --git a/frontend/src/components/bazarr/Language.tsx b/frontend/src/components/bazarr/Language.tsx index ad60a7b65..6897a3752 100644 --- a/frontend/src/components/bazarr/Language.tsx +++ b/frontend/src/components/bazarr/Language.tsx @@ -1,22 +1,21 @@ -import { useLanguages } from "@/apis/hooks"; -import { Selector, SelectorOption, SelectorProps } from "@/components"; +import { BuildKey } from "@/utilities"; +import { Badge, Group, Text, TextProps } from "@mantine/core"; import { FunctionComponent, useMemo } from "react"; -interface TextProps { +type LanguageTextProps = TextProps<"div"> & { value: Language.Info; - className?: string; long?: boolean; -} +}; declare type LanguageComponent = { Text: typeof LanguageText; - Selector: typeof LanguageSelector; + List: typeof LanguageList; }; -const LanguageText: FunctionComponent = ({ +const LanguageText: FunctionComponent = ({ value, - className, long, + ...props }) => { const result = useMemo(() => { let lang = value.code2; @@ -38,51 +37,29 @@ const LanguageText: FunctionComponent = ({ }, [value, long]); return ( - + {result} - + ); }; -type LanguageSelectorProps = Omit< - SelectorProps, - "label" | "options" -> & { - history?: boolean; +type LanguageListProps = { + value: Language.Info[]; }; -function getLabel(lang: Language.Info) { - return lang.name; -} - -export function LanguageSelector( - props: LanguageSelectorProps -) { - const { history, ...rest } = props; - const { data: options } = useLanguages(history); - - const items = useMemo[]>( - () => - options?.map((v) => ({ - label: v.name, - value: v, - })) ?? [], - [options] - ); - +const LanguageList: FunctionComponent = ({ value }) => { return ( - + + {value.map((v) => ( + {v.name} + ))} + ); -} +}; const Components: LanguageComponent = { Text: LanguageText, - Selector: LanguageSelector, + List: LanguageList, }; export default Components; diff --git a/frontend/src/components/bazarr/LanguageProfile.tsx b/frontend/src/components/bazarr/LanguageProfile.tsx index c3724dc89..03ca6255a 100644 --- a/frontend/src/components/bazarr/LanguageProfile.tsx +++ b/frontend/src/components/bazarr/LanguageProfile.tsx @@ -3,13 +3,11 @@ import { FunctionComponent, useMemo } from "react"; interface Props { index: number | null; - className?: string; empty?: string; } -const LanguageProfile: FunctionComponent = ({ +const LanguageProfileName: FunctionComponent = ({ index, - className, empty = "Unknown Profile", }) => { const { data } = useLanguageProfiles(); @@ -19,7 +17,7 @@ const LanguageProfile: FunctionComponent = ({ [data, empty, index] ); - return {name}; + return <>{name}; }; -export default LanguageProfile; +export default LanguageProfileName; diff --git a/frontend/src/components/bazarr/index.ts b/frontend/src/components/bazarr/index.ts new file mode 100644 index 000000000..848ac3e68 --- /dev/null +++ b/frontend/src/components/bazarr/index.ts @@ -0,0 +1,4 @@ +export { default as AudioList } from "./AudioList"; +export { default as HistoryIcon } from "./HistoryIcon"; +export { default as Language } from "./Language"; +export { default as LanguageProfile } from "./LanguageProfile"; diff --git a/frontend/src/components/buttons.tsx b/frontend/src/components/buttons.tsx deleted file mode 100644 index db8b9836a..000000000 --- a/frontend/src/components/buttons.tsx +++ /dev/null @@ -1,80 +0,0 @@ -import { IconDefinition } from "@fortawesome/fontawesome-common-types"; -import { faCircleNotch } from "@fortawesome/free-solid-svg-icons"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { FunctionComponent, MouseEvent } from "react"; -import { Badge, Button, ButtonProps } from "react-bootstrap"; - -export const ActionBadge: FunctionComponent<{ - icon: IconDefinition; - onClick?: (e: MouseEvent) => void; -}> = ({ icon, onClick }) => { - return ( - - ); -}; - -interface ActionButtonProps extends ActionButtonItemProps { - disabled?: boolean; - destructive?: boolean; - variant?: string; - onClick?: (e: MouseEvent) => void; - className?: string; - size?: ButtonProps["size"]; -} - -export const ActionButton: FunctionComponent = ({ - onClick, - destructive, - disabled, - variant, - className, - size, - ...other -}) => { - return ( - - ); -}; - -interface ActionButtonItemProps { - loading?: boolean; - alwaysShowText?: boolean; - icon: IconDefinition; - children?: string; -} - -export const ActionButtonItem: FunctionComponent = ({ - icon, - children, - loading, - alwaysShowText, -}) => { - const showText = alwaysShowText === true || loading !== true; - return ( - <> - - {children && showText ? ( - {children} - ) : null} - - ); -}; diff --git a/frontend/src/components/forms/ColorToolForm.tsx b/frontend/src/components/forms/ColorToolForm.tsx new file mode 100644 index 000000000..ac15e250a --- /dev/null +++ b/frontend/src/components/forms/ColorToolForm.tsx @@ -0,0 +1,133 @@ +import { useSubtitleAction } from "@/apis/hooks"; +import { Selector, SelectorOption } from "@/components"; +import { useModals, withModal } from "@/modules/modals"; +import { task } from "@/modules/task"; +import { Button, Divider, Stack } from "@mantine/core"; +import { useForm } from "@mantine/hooks"; +import { FunctionComponent } from "react"; + +const TaskName = "Changing Color"; + +function convertToAction(color: string) { + return `color(name=${color})`; +} + +export const colorOptions: SelectorOption[] = [ + { + label: "White", + value: "white", + }, + { + label: "Light Gray", + value: "light-gray", + }, + { + label: "Red", + value: "red", + }, + { + label: "Green", + value: "green", + }, + { + label: "Yellow", + value: "yellow", + }, + { + label: "Blue", + value: "blue", + }, + { + label: "Magenta", + value: "magenta", + }, + { + label: "Cyan", + value: "cyan", + }, + { + label: "Black", + value: "black", + }, + { + label: "Dark Red", + value: "dark-red", + }, + { + label: "Dark Green", + value: "dark-green", + }, + { + label: "Dark Yellow", + value: "dark-yellow", + }, + { + label: "Dark Blue", + value: "dark-blue", + }, + { + label: "Dark Magenta", + value: "dark-magenta", + }, + { + label: "Dark Cyan", + value: "dark-cyan", + }, + { + label: "Dark Grey", + value: "dark-grey", + }, +]; + +interface Props { + selections: FormType.ModifySubtitle[]; + onSubmit?: VoidFunction; +} + +const ColorToolForm: FunctionComponent = ({ selections, onSubmit }) => { + const { mutateAsync } = useSubtitleAction(); + const modals = useModals(); + + const form = useForm({ + initialValues: { + color: "", + }, + validationRules: { + color: (c) => colorOptions.find((op) => op.value === c) !== undefined, + }, + }); + + return ( +
    { + const action = convertToAction(color); + + selections.forEach((s) => + task.create(s.path, TaskName, mutateAsync, { + action, + form: s, + }) + ); + + onSubmit?.(); + modals.closeSelf(); + })} + > + + + + + +
    + ); +}; + +export const ColorToolModal = withModal(ColorToolForm, "color-tool", { + title: "Change Color", +}); + +export default ColorToolForm; diff --git a/frontend/src/components/forms/FrameRateForm.tsx b/frontend/src/components/forms/FrameRateForm.tsx new file mode 100644 index 000000000..1ae250871 --- /dev/null +++ b/frontend/src/components/forms/FrameRateForm.tsx @@ -0,0 +1,72 @@ +import { useSubtitleAction } from "@/apis/hooks"; +import { useModals, withModal } from "@/modules/modals"; +import { task } from "@/modules/task"; +import { Button, Divider, Group, NumberInput, Stack } from "@mantine/core"; +import { useForm } from "@mantine/hooks"; +import { FunctionComponent } from "react"; + +const TaskName = "Changing Frame Rate"; + +function convertToAction(from: number, to: number) { + return `change_FPS(from=${from},to=${to})`; +} + +interface Props { + selections: FormType.ModifySubtitle[]; + onSubmit?: VoidFunction; +} + +const FrameRateForm: FunctionComponent = ({ selections, onSubmit }) => { + const { mutateAsync } = useSubtitleAction(); + const modals = useModals(); + + const form = useForm({ + initialValues: { + from: 0, + to: 0, + }, + validationRules: { + from: (v) => v > 0, + to: (v) => v > 0, + }, + }); + + return ( +
    { + const action = convertToAction(from, to); + + selections.forEach((s) => + task.create(s.path, TaskName, mutateAsync, { + action, + form: s, + }) + ); + + onSubmit?.(); + modals.closeSelf(); + })} + > + + + + + + + + +
    + ); +}; + +export const FrameRateModal = withModal(FrameRateForm, "frame-rate-tool", { + title: "Change Frame Rate", +}); + +export default FrameRateForm; diff --git a/frontend/src/components/forms/ItemEditForm.tsx b/frontend/src/components/forms/ItemEditForm.tsx new file mode 100644 index 000000000..42f84cb84 --- /dev/null +++ b/frontend/src/components/forms/ItemEditForm.tsx @@ -0,0 +1,109 @@ +import { useLanguageProfiles } from "@/apis/hooks"; +import { MultiSelector, Selector } from "@/components/inputs"; +import { useModals, withModal } from "@/modules/modals"; +import { GetItemId, useSelectorOptions } from "@/utilities"; +import { Button, Divider, Group, LoadingOverlay, Stack } from "@mantine/core"; +import { useForm } from "@mantine/hooks"; +import { FunctionComponent, useMemo } from "react"; +import { UseMutationResult } from "react-query"; + +interface Props { + mutation: UseMutationResult; + item: Item.Base | null; + onComplete?: () => void; + onCancel?: () => void; +} + +const ItemEditForm: FunctionComponent = ({ + mutation, + item, + onComplete, + onCancel, +}) => { + const { data, isFetching } = useLanguageProfiles(); + const { isLoading, mutate } = mutation; + const modals = useModals(); + + const profileOptions = useSelectorOptions( + data ?? [], + (v) => v.name ?? "Unknown", + (v) => v.profileId.toString() ?? "-1" + ); + + const profile = useMemo( + () => data?.find((v) => v.profileId === item?.profileId) ?? null, + [data, item?.profileId] + ); + + const form = useForm({ + initialValues: { + profile: profile ?? null, + }, + }); + + const options = useSelectorOptions( + item?.audio_language ?? [], + (v) => v.name, + (v) => v.code2 + ); + + const isOverlayVisible = isLoading || isFetching || item === null; + + return ( +
    { + if (item) { + const itemId = GetItemId(item); + if (itemId) { + mutate({ id: [itemId], profileid: [profile?.profileId ?? null] }); + onComplete?.(); + modals.closeSelf(); + return; + } + } + + form.setErrors({ profile: "Invalid profile" }); + })} + > + + + + + + + + + + +
    + ); +}; + +export const ItemEditModal = withModal(ItemEditForm, "item-editor", { + title: "Editor", + size: "md", +}); + +export default ItemEditForm; diff --git a/frontend/src/components/forms/MovieUploadForm.tsx b/frontend/src/components/forms/MovieUploadForm.tsx new file mode 100644 index 000000000..b9ac9fa6c --- /dev/null +++ b/frontend/src/components/forms/MovieUploadForm.tsx @@ -0,0 +1,276 @@ +import { useMovieSubtitleModification } from "@/apis/hooks"; +import { useModals, withModal } from "@/modules/modals"; +import { task, TaskGroup } from "@/modules/task"; +import { useTableStyles } from "@/styles"; +import { useArrayAction, useSelectorOptions } from "@/utilities"; +import { + useLanguageProfileBy, + useProfileItemsToLanguages, +} from "@/utilities/languages"; +import { + faCheck, + faCircleNotch, + faInfoCircle, + faTimes, + faXmark, +} from "@fortawesome/free-solid-svg-icons"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { Button, Checkbox, Divider, Stack, Text } from "@mantine/core"; +import { useForm } from "@mantine/hooks"; +import { isString } from "lodash"; +import { FunctionComponent, useEffect, useMemo } from "react"; +import { Column } from "react-table"; +import { Action, Selector } from "../inputs"; +import { SimpleTable } from "../tables"; +import TextPopover from "../TextPopover"; + +type SubtitleFile = { + file: File; + language: Language.Info | null; + forced: boolean; + hi: boolean; + validateResult?: SubtitleValidateResult; +}; + +type SubtitleValidateResult = { + state: "valid" | "warning" | "error"; + messages?: string; +}; + +const validator = ( + movie: Item.Movie, + file: SubtitleFile +): SubtitleValidateResult => { + if (file.language === null) { + return { + state: "error", + messages: "Language is not selected", + }; + } else { + const { subtitles } = movie; + const existing = subtitles.find( + (v) => v.code2 === file.language?.code2 && isString(v.path) + ); + if (existing !== undefined) { + return { + state: "warning", + messages: "Override existing subtitle", + }; + } + } + + return { + state: "valid", + }; +}; + +interface Props { + files: File[]; + movie: Item.Movie; + onComplete?: () => void; +} + +const MovieUploadForm: FunctionComponent = ({ + files, + movie, + onComplete, +}) => { + const modals = useModals(); + + const profile = useLanguageProfileBy(movie.profileId); + + const languages = useProfileItemsToLanguages(profile); + const languageOptions = useSelectorOptions( + languages, + (v) => v.name, + (v) => v.code2 + ); + + const defaultLanguage = useMemo( + () => (languages.length > 0 ? languages[0] : null), + [languages] + ); + + const form = useForm({ + initialValues: { + files: files + .map((file) => ({ + file, + language: defaultLanguage, + forced: defaultLanguage?.forced ?? false, + hi: defaultLanguage?.hi ?? false, + })) + .map((v) => ({ + ...v, + validateResult: validator(movie, v), + })), + }, + validationRules: { + files: (values) => { + return ( + values.find( + (v) => + v.language === null || + v.validateResult === undefined || + v.validateResult.state === "error" + ) === undefined + ); + }, + }, + }); + + useEffect(() => { + if (form.values.files.length <= 0) { + modals.closeSelf(); + } + }, [form.values.files.length, modals]); + + const action = useArrayAction((fn) => { + form.setValues(({ files, ...rest }) => { + const newFiles = fn(files); + newFiles.forEach((v) => { + v.validateResult = validator(movie, v); + }); + return { ...rest, files: newFiles }; + }); + }); + + const columns = useMemo[]>( + () => [ + { + accessor: "validateResult", + Cell: ({ cell: { value } }) => { + const icon = useMemo(() => { + switch (value?.state) { + case "valid": + return faCheck; + case "warning": + return faInfoCircle; + case "error": + return faTimes; + default: + return faCircleNotch; + } + }, [value?.state]); + + return ( + + {/* TODO: Color */} + + + ); + }, + }, + { + Header: "File", + id: "filename", + accessor: "file", + Cell: ({ value }) => { + const { classes } = useTableStyles(); + + return {value.name}; + }, + }, + { + Header: "Forced", + accessor: "forced", + Cell: ({ row: { original, index }, value }) => { + return ( + { + action.mutate(index, { ...original, forced: checked }); + }} + > + ); + }, + }, + { + Header: "HI", + accessor: "hi", + Cell: ({ row: { original, index }, value }) => { + return ( + { + action.mutate(index, { ...original, hi: checked }); + }} + > + ); + }, + }, + { + Header: "Language", + accessor: "language", + Cell: ({ row: { original, index }, value }) => { + const { classes } = useTableStyles(); + return ( + { + action.mutate(index, { ...original, language: item }); + }} + > + ); + }, + }, + { + id: "action", + accessor: "file", + Cell: ({ row: { index } }) => { + return ( + action.remove(index)} + > + ); + }, + }, + ], + [action, languageOptions] + ); + + const { upload } = useMovieSubtitleModification(); + + return ( +
    { + const { radarrId } = movie; + + files.forEach(({ file, language, hi, forced }) => { + if (language === null) { + throw new Error("Language is not selected"); + } + + task.create(file.name, TaskGroup.UploadSubtitle, upload.mutateAsync, { + radarrId, + form: { file, language: language.code2, hi, forced }, + }); + }); + + onComplete?.(); + modals.closeSelf(); + })} + > + + + + + +
    + ); +}; + +export const MovieUploadModal = withModal( + MovieUploadForm, + "upload-movie-subtitle", + { + title: "Upload Subtitles", + size: "xl", + } +); + +export default MovieUploadForm; diff --git a/frontend/src/components/forms/ProfileEditForm.tsx b/frontend/src/components/forms/ProfileEditForm.tsx new file mode 100644 index 000000000..985a97d26 --- /dev/null +++ b/frontend/src/components/forms/ProfileEditForm.tsx @@ -0,0 +1,311 @@ +import { Action, Selector, SelectorOption, SimpleTable } from "@/components"; +import { useModals, withModal } from "@/modules/modals"; +import { useTableStyles } from "@/styles"; +import { useArrayAction, useSelectorOptions } from "@/utilities"; +import { faXmark } from "@fortawesome/free-solid-svg-icons"; +import { + Accordion, + Alert, + Button, + Checkbox, + Stack, + Switch, + Text, + TextInput, +} from "@mantine/core"; +import { useForm } from "@mantine/hooks"; +import { FunctionComponent, useCallback, useMemo } from "react"; +import { Column } from "react-table"; +import ChipInput from "../inputs/ChipInput"; + +export const anyCutoff = 65535; + +const defaultCutoffOptions: SelectorOption[] = [ + { + label: "Any", + value: { + id: anyCutoff, + audio_exclude: "False", + forced: "False", + hi: "False", + language: "any", + }, + }, +]; + +interface Props { + onComplete?: (profile: Language.Profile) => void; + languages: readonly Language.Info[]; + profile: Language.Profile; +} + +const ProfileEditForm: FunctionComponent = ({ + onComplete, + languages, + profile, +}) => { + const modals = useModals(); + + const form = useForm({ + initialValues: profile, + validationRules: { + name: (value) => value.length > 0, + items: (value) => value.length > 0, + }, + errorMessages: { + items: ( + + Must contain at lease 1 language + + ), + }, + }); + + const languageOptions = useSelectorOptions(languages, (l) => l.name); + + const itemCutoffOptions = useSelectorOptions( + form.values.items, + (v) => v.language + ); + + const cutoffOptions = useMemo( + () => ({ + ...itemCutoffOptions, + options: [...itemCutoffOptions.options, ...defaultCutoffOptions], + }), + [itemCutoffOptions] + ); + + const mustContainOptions = useSelectorOptions( + form.values.mustContain, + (v) => v + ); + + const mustNotContainOptions = useSelectorOptions( + form.values.mustNotContain, + (v) => v + ); + + const action = useArrayAction((fn) => { + form.setValues((values) => ({ ...values, items: fn(values.items) })); + }); + + const addItem = useCallback(() => { + const id = + 1 + + form.values.items.reduce( + (val, item) => Math.max(item.id, val), + 0 + ); + + if (languages.length > 0) { + const language = languages[0].code2; + + const item: Language.ProfileItem = { + id, + language, + audio_exclude: "False", + hi: "False", + forced: "False", + }; + + const list = [...form.values.items, item]; + form.setValues((values) => ({ ...values, items: list })); + } + }, [form, languages]); + + const columns = useMemo[]>( + () => [ + { + Header: "ID", + accessor: "id", + }, + { + Header: "Language", + accessor: "language", + Cell: ({ value: code, row: { original: item, index } }) => { + const language = useMemo( + () => + languageOptions.options.find((l) => l.value.code2 === code) + ?.value ?? null, + [code] + ); + + const { classes } = useTableStyles(); + + return ( + { + if (value) { + item.language = value.code2; + action.mutate(index, { ...item, language: value.code2 }); + } + }} + > + ); + }, + }, + { + Header: "Forced", + accessor: "forced", + Cell: ({ row: { original: item, index }, value }) => { + return ( + { + action.mutate(index, { + ...item, + forced: checked ? "True" : "False", + hi: checked ? "False" : item.hi, + }); + }} + > + ); + }, + }, + { + Header: "HI", + accessor: "hi", + Cell: ({ row: { original: item, index }, value }) => { + return ( + { + action.mutate(index, { + ...item, + hi: checked ? "True" : "False", + forced: checked ? "False" : item.forced, + }); + }} + > + ); + }, + }, + { + Header: "Exclude Audio", + accessor: "audio_exclude", + Cell: ({ row: { original: item, index }, value }) => { + return ( + { + action.mutate(index, { + ...item, + audio_exclude: checked ? "True" : "False", + }); + }} + > + ); + }, + }, + { + id: "action", + accessor: "id", + Cell: ({ row }) => { + return ( + action.remove(row.index)} + > + ); + }, + }, + ], + [action, languageOptions] + ); + + return ( +
    { + onComplete?.(value); + modals.closeSelf(); + })} + > + + + ({ + contentInner: { + [theme.fn.smallerThan("md")]: { + padding: 0, + }, + }, + })} + > + + + {form.errors.items} + + + + + + + + + + Subtitles release info must include one of those words or they + will be excluded from search results (regex supported). + + + + Subtitles release info including one of those words (case + insensitive) will be excluded from search results (regex + supported). + + + + + + + + Download subtitle file without format conversion + + + + + + +
    + ); +}; + +export const ProfileEditModal = withModal( + ProfileEditForm, + "languages-profile-editor", + { + title: "Edit Languages Profile", + size: "lg", + } +); + +export default ProfileEditForm; diff --git a/frontend/src/components/forms/SeriesUploadForm.tsx b/frontend/src/components/forms/SeriesUploadForm.tsx new file mode 100644 index 000000000..a3746c4c2 --- /dev/null +++ b/frontend/src/components/forms/SeriesUploadForm.tsx @@ -0,0 +1,349 @@ +import { + useEpisodesBySeriesId, + useEpisodeSubtitleModification, + useSubtitleInfos, +} from "@/apis/hooks"; +import { useModals, withModal } from "@/modules/modals"; +import { task, TaskGroup } from "@/modules/task"; +import { useTableStyles } from "@/styles"; +import { useArrayAction, useSelectorOptions } from "@/utilities"; +import { + useLanguageProfileBy, + useProfileItemsToLanguages, +} from "@/utilities/languages"; +import { + faCheck, + faCircleNotch, + faInfoCircle, + faTimes, + faXmark, +} from "@fortawesome/free-solid-svg-icons"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { Button, Checkbox, Divider, Stack, Text } from "@mantine/core"; +import { useForm } from "@mantine/hooks"; +import { isString } from "lodash"; +import { FunctionComponent, useEffect, useMemo } from "react"; +import { Column } from "react-table"; +import { Action, Selector } from "../inputs"; +import { SimpleTable } from "../tables"; +import TextPopover from "../TextPopover"; + +type SubtitleFile = { + file: File; + language: Language.Info | null; + forced: boolean; + hi: boolean; + episode: Item.Episode | null; + validateResult?: SubtitleValidateResult; +}; + +type SubtitleValidateResult = { + state: "valid" | "warning" | "error"; + messages?: string; +}; + +const validator = (file: SubtitleFile): SubtitleValidateResult => { + if (file.language === null) { + return { + state: "error", + messages: "Language is not selected", + }; + } else if (file.episode === null) { + return { + state: "error", + messages: "Episode is not selected", + }; + } else { + const { subtitles } = file.episode; + const existing = subtitles.find( + (v) => v.code2 === file.language?.code2 && isString(v.path) + ); + if (existing !== undefined) { + return { + state: "warning", + messages: "Override existing subtitle", + }; + } + } + + return { + state: "valid", + }; +}; + +interface Props { + files: File[]; + series: Item.Series; + onComplete?: VoidFunction; +} + +const SeriesUploadForm: FunctionComponent = ({ + series, + files, + onComplete, +}) => { + const modals = useModals(); + const episodes = useEpisodesBySeriesId(series.sonarrSeriesId); + const episodeOptions = useSelectorOptions( + episodes.data ?? [], + (v) => `(${v.season}x${v.episode}) ${v.title}`, + (v) => v.sonarrEpisodeId.toString() + ); + + const profile = useLanguageProfileBy(series.profileId); + const languages = useProfileItemsToLanguages(profile); + const languageOptions = useSelectorOptions( + languages, + (v) => v.name, + (v) => v.code2 + ); + + const defaultLanguage = useMemo( + () => (languages.length > 0 ? languages[0] : null), + [languages] + ); + + const form = useForm({ + initialValues: { + files: files + .map((file) => ({ + file, + language: defaultLanguage, + forced: defaultLanguage?.forced ?? false, + hi: defaultLanguage?.hi ?? false, + episode: null, + })) + .map((file) => ({ + ...file, + validateResult: validator(file), + })), + }, + validationRules: { + files: (values) => + values.find( + (v) => + v.language === null || + v.episode === null || + v.validateResult === undefined || + v.validateResult.state === "error" + ) === undefined, + }, + }); + + const action = useArrayAction((fn) => { + form.setValues(({ files, ...rest }) => { + const newFiles = fn(files); + newFiles.forEach((v) => { + v.validateResult = validator(v); + }); + return { ...rest, files: newFiles }; + }); + }); + + const names = useMemo(() => files.map((v) => v.name), [files]); + const infos = useSubtitleInfos(names); + + // Auto assign episode if available + useEffect(() => { + if (infos.data !== undefined) { + action.update((item) => { + const info = infos.data.find((v) => v.filename === item.file.name); + if (info) { + item.episode = + episodes.data?.find( + (v) => v.season === info.season && v.episode === info.episode + ) ?? item.episode; + } + return item; + }); + } + }, [action, episodes.data, infos.data]); + + const columns = useMemo[]>( + () => [ + { + accessor: "validateResult", + Cell: ({ cell: { value } }) => { + const icon = useMemo(() => { + switch (value?.state) { + case "valid": + return faCheck; + case "warning": + return faInfoCircle; + case "error": + return faTimes; + default: + return faCircleNotch; + } + }, [value?.state]); + + return ( + + {/* TODO: Color */} + + + ); + }, + }, + { + Header: "File", + id: "filename", + accessor: "file", + Cell: ({ value: { name } }) => { + const { classes } = useTableStyles(); + return {name}; + }, + }, + { + Header: "Forced", + accessor: "forced", + Cell: ({ row: { original, index }, value }) => { + return ( + { + action.mutate(index, { + ...original, + forced: checked, + hi: checked ? false : original.hi, + }); + }} + > + ); + }, + }, + { + Header: "HI", + accessor: "hi", + Cell: ({ row: { original, index }, value }) => { + return ( + { + action.mutate(index, { + ...original, + hi: checked, + forced: checked ? false : original.forced, + }); + }} + > + ); + }, + }, + { + Header: ( + { + if (value) { + action.update((item) => { + item.language = value; + return item; + }); + } + }} + > + ), + accessor: "language", + Cell: ({ row: { original, index }, value }) => { + const { classes } = useTableStyles(); + return ( + { + action.mutate(index, { ...original, language: item }); + }} + > + ); + }, + }, + { + id: "episode", + Header: "Episode", + accessor: "episode", + Cell: ({ value, row }) => { + const { classes } = useTableStyles(); + return ( + { + action.mutate(row.index, { ...row.original, episode: item }); + }} + > + ); + }, + }, + { + id: "action", + accessor: "file", + Cell: ({ row: { index } }) => { + return ( + action.remove(index)} + > + ); + }, + }, + ], + [action, episodeOptions, languageOptions] + ); + + const { upload } = useEpisodeSubtitleModification(); + + return ( +
    { + const { sonarrSeriesId: seriesId } = series; + + files.forEach((value) => { + const { file, hi, forced, language, episode } = value; + + if (language === null || episode === null) { + throw new Error( + "Invalid language or episode. This shouldn't happen, please report this bug." + ); + } + + const { code2 } = language; + const { sonarrEpisodeId: episodeId } = episode; + + task.create(file.name, TaskGroup.UploadSubtitle, upload.mutateAsync, { + seriesId, + episodeId, + form: { + file, + language: code2, + hi, + forced, + }, + }); + }); + + onComplete?.(); + modals.closeSelf(); + })} + > + + + + + +
    + ); +}; + +export const SeriesUploadModal = withModal( + SeriesUploadForm, + "upload-series-subtitles", + { title: "Upload Subtitles", size: "xl" } +); + +export default SeriesUploadForm; diff --git a/frontend/src/components/forms/TimeOffsetForm.tsx b/frontend/src/components/forms/TimeOffsetForm.tsx new file mode 100644 index 000000000..cdd095bdc --- /dev/null +++ b/frontend/src/components/forms/TimeOffsetForm.tsx @@ -0,0 +1,97 @@ +import { useSubtitleAction } from "@/apis/hooks"; +import { useModals, withModal } from "@/modules/modals"; +import { task } from "@/modules/task"; +import { faMinus, faPlus } from "@fortawesome/free-solid-svg-icons"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { Button, Divider, Group, NumberInput, Stack } from "@mantine/core"; +import { useForm } from "@mantine/hooks"; +import { FunctionComponent } from "react"; + +const TaskName = "Changing Time"; + +function convertToAction(h: number, m: number, s: number, ms: number) { + return `shift_offset(h=${h},m=${m},s=${s},ms=${ms})`; +} + +interface Props { + selections: FormType.ModifySubtitle[]; + onSubmit?: VoidFunction; +} + +const TimeOffsetForm: FunctionComponent = ({ selections, onSubmit }) => { + const { mutateAsync } = useSubtitleAction(); + const modals = useModals(); + + const form = useForm({ + initialValues: { + positive: true, + hour: 0, + min: 0, + sec: 0, + ms: 0, + }, + validationRules: { + hour: (v) => v >= 0, + min: (v) => v >= 0, + sec: (v) => v >= 0, + ms: (v) => v >= 0, + }, + }); + + const enabled = + form.values.hour > 0 || + form.values.min > 0 || + form.values.sec > 0 || + form.values.ms > 0; + + return ( +
    { + const action = convertToAction(hour, min, sec, ms); + + selections.forEach((s) => + task.create(s.path, TaskName, mutateAsync, { + action, + form: s, + }) + ); + + onSubmit?.(); + modals.closeSelf(); + })} + > + + + + + + + + + + + +
    + ); +}; + +export const TimeOffsetModal = withModal(TimeOffsetForm, "time-offset", { + title: "Change Time", +}); + +export default TimeOffsetForm; diff --git a/frontend/src/components/forms/TranslationForm.tsx b/frontend/src/components/forms/TranslationForm.tsx new file mode 100644 index 000000000..37668b36c --- /dev/null +++ b/frontend/src/components/forms/TranslationForm.tsx @@ -0,0 +1,192 @@ +import { useSubtitleAction } from "@/apis/hooks"; +import { useModals, withModal } from "@/modules/modals"; +import { task } from "@/modules/task"; +import { useSelectorOptions } from "@/utilities"; +import { useEnabledLanguages } from "@/utilities/languages"; +import { Alert, Button, Divider, Stack } from "@mantine/core"; +import { useForm } from "@mantine/hooks"; +import { isObject } from "lodash"; +import { FunctionComponent, useMemo } from "react"; +import { Selector } from "../inputs"; + +const TaskName = "Translating Subtitles"; + +const translations = { + af: "afrikaans", + sq: "albanian", + am: "amharic", + ar: "arabic", + hy: "armenian", + az: "azerbaijani", + eu: "basque", + be: "belarusian", + bn: "bengali", + bs: "bosnian", + bg: "bulgarian", + ca: "catalan", + ceb: "cebuano", + ny: "chichewa", + zh: "chinese (simplified)", + zt: "chinese (traditional)", + co: "corsican", + hr: "croatian", + cs: "czech", + da: "danish", + nl: "dutch", + en: "english", + eo: "esperanto", + et: "estonian", + tl: "filipino", + fi: "finnish", + fr: "french", + fy: "frisian", + gl: "galician", + ka: "georgian", + de: "german", + el: "greek", + gu: "gujarati", + ht: "haitian creole", + ha: "hausa", + haw: "hawaiian", + iw: "hebrew", + hi: "hindi", + hmn: "hmong", + hu: "hungarian", + is: "icelandic", + ig: "igbo", + id: "indonesian", + ga: "irish", + it: "italian", + ja: "japanese", + jw: "javanese", + kn: "kannada", + kk: "kazakh", + km: "khmer", + ko: "korean", + ku: "kurdish (kurmanji)", + ky: "kyrgyz", + lo: "lao", + la: "latin", + lv: "latvian", + lt: "lithuanian", + lb: "luxembourgish", + mk: "macedonian", + mg: "malagasy", + ms: "malay", + ml: "malayalam", + mt: "maltese", + mi: "maori", + mr: "marathi", + mn: "mongolian", + my: "myanmar (burmese)", + ne: "nepali", + no: "norwegian", + ps: "pashto", + fa: "persian", + pl: "polish", + pt: "portuguese", + pa: "punjabi", + ro: "romanian", + ru: "russian", + sm: "samoan", + gd: "scots gaelic", + sr: "serbian", + st: "sesotho", + sn: "shona", + sd: "sindhi", + si: "sinhala", + sk: "slovak", + sl: "slovenian", + so: "somali", + es: "spanish", + su: "sundanese", + sw: "swahili", + sv: "swedish", + tg: "tajik", + ta: "tamil", + te: "telugu", + th: "thai", + tr: "turkish", + uk: "ukrainian", + ur: "urdu", + uz: "uzbek", + vi: "vietnamese", + cy: "welsh", + xh: "xhosa", + yi: "yiddish", + yo: "yoruba", + zu: "zulu", + fil: "Filipino", + he: "Hebrew", +}; + +interface Props { + selections: FormType.ModifySubtitle[]; + onSubmit?: VoidFunction; +} + +const TranslationForm: FunctionComponent = ({ + selections, + onSubmit, +}) => { + const { mutateAsync } = useSubtitleAction(); + const modals = useModals(); + + const { data: languages } = useEnabledLanguages(); + + const form = useForm({ + initialValues: { + language: null as Language.Info | null, + }, + validationRules: { + language: isObject, + }, + }); + + const available = useMemo( + () => languages.filter((v) => v.code2 in translations), + [languages] + ); + + const options = useSelectorOptions( + available, + (v) => v.name, + (v) => v.code2 + ); + + return ( +
    { + if (language) { + selections.forEach((s) => + task.create(s.path, TaskName, mutateAsync, { + action: "translate", + form: { + ...s, + language: language.code2, + }, + }) + ); + + onSubmit?.(); + modals.closeSelf(); + } + })} + > + + + Enabled languages not listed here are unsupported by Google Translate. + + + + + +
    + ); +}; + +export const TranslationModal = withModal(TranslationForm, "translation-tool", { + title: "Translate Subtitle(s)", +}); + +export default TranslationForm; diff --git a/frontend/src/components/header/Button.tsx b/frontend/src/components/header/Button.tsx deleted file mode 100644 index 7cd952876..000000000 --- a/frontend/src/components/header/Button.tsx +++ /dev/null @@ -1,78 +0,0 @@ -import { IconDefinition } from "@fortawesome/fontawesome-svg-core"; -import { faSpinner } from "@fortawesome/free-solid-svg-icons"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { - FunctionComponent, - MouseEvent, - PropsWithChildren, - useCallback, - useState, -} from "react"; -import { Button } from "react-bootstrap"; - -interface CHButtonProps { - disabled?: boolean; - hidden?: boolean; - icon: IconDefinition; - updating?: boolean; - updatingIcon?: IconDefinition; - onClick?: (e: MouseEvent) => void; -} - -const ContentHeaderButton: FunctionComponent = (props) => { - const { children, icon, disabled, updating, updatingIcon, onClick } = props; - - let displayIcon = icon; - if (updating) { - displayIcon = updatingIcon ? updatingIcon : faSpinner; - } - - return ( - - ); -}; - -type CHAsyncButtonProps Promise> = { - promise: T; - onSuccess?: (item: R) => void; -} & Omit; - -export function ContentHeaderAsyncButton Promise>( - props: PropsWithChildren> -): JSX.Element { - const { promise, onSuccess, ...button } = props; - - const [updating, setUpdate] = useState(false); - - const click = useCallback(() => { - setUpdate(true); - promise().then((val) => { - setUpdate(false); - onSuccess && onSuccess(val); - }); - }, [onSuccess, promise]); - - return ( - - ); -} - -export default ContentHeaderButton; diff --git a/frontend/src/components/header/Group.tsx b/frontend/src/components/header/Group.tsx deleted file mode 100644 index 085065631..000000000 --- a/frontend/src/components/header/Group.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import { FunctionComponent } from "react"; - -type GroupPosition = "start" | "end"; -interface GroupProps { - pos: GroupPosition; -} - -const ContentHeaderGroup: FunctionComponent = (props) => { - const { children, pos } = props; - - const className = `d-flex flex-grow-1 align-items-center justify-content-${pos}`; - return
    {children}
    ; -}; - -export default ContentHeaderGroup; diff --git a/frontend/src/components/header/index.tsx b/frontend/src/components/header/index.tsx deleted file mode 100644 index 200f9e343..000000000 --- a/frontend/src/components/header/index.tsx +++ /dev/null @@ -1,47 +0,0 @@ -import { FunctionComponent, ReactNode, useMemo } from "react"; -import { Row } from "react-bootstrap"; -import ContentHeaderButton, { ContentHeaderAsyncButton } from "./Button"; -import ContentHeaderGroup from "./Group"; - -interface Props { - scroll?: boolean; - className?: string; -} - -declare type Header = FunctionComponent & { - Button: typeof ContentHeaderButton; - AsyncButton: typeof ContentHeaderAsyncButton; - Group: typeof ContentHeaderGroup; -}; - -export const ContentHeader: Header = ({ children, scroll, className }) => { - const cls = useMemo(() => { - const rowCls = ["content-header", "bg-dark", "p-2"]; - - if (className !== undefined) { - rowCls.push(className); - } - - if (scroll !== false) { - rowCls.push("scroll"); - } - return rowCls.join(" "); - }, [scroll, className]); - - let childItem: ReactNode; - - if (scroll !== false) { - childItem = ( -
    {children}
    - ); - } else { - childItem = children; - } - return {childItem}; -}; - -ContentHeader.Button = ContentHeaderButton; -ContentHeader.Group = ContentHeaderGroup; -ContentHeader.AsyncButton = ContentHeaderAsyncButton; - -export default ContentHeader; diff --git a/frontend/src/components/index.tsx b/frontend/src/components/index.tsx index 054498626..f9ebf40d1 100644 --- a/frontend/src/components/index.tsx +++ b/frontend/src/components/index.tsx @@ -1,135 +1,4 @@ -import { - faClock, - faCloudUploadAlt, - faDownload, - faRecycle, - faTrash, - faUser, -} from "@fortawesome/free-solid-svg-icons"; -import { - FontAwesomeIcon, - FontAwesomeIconProps, -} from "@fortawesome/react-fontawesome"; -import { isNull, isUndefined } from "lodash"; -import { FunctionComponent, ReactElement } from "react"; -import { - OverlayTrigger, - OverlayTriggerProps, - Popover, - Spinner, - SpinnerProps, -} from "react-bootstrap"; - -enum HistoryAction { - Delete = 0, - Download, - Manual, - Upgrade, - Upload, - Sync, -} - -export const HistoryIcon: FunctionComponent<{ - action: number; - title?: string; -}> = (props) => { - const { action, title } = props; - let icon = null; - switch (action) { - case HistoryAction.Delete: - icon = faTrash; - break; - case HistoryAction.Download: - icon = faDownload; - break; - case HistoryAction.Manual: - icon = faUser; - break; - case HistoryAction.Sync: - icon = faClock; - break; - case HistoryAction.Upgrade: - icon = faRecycle; - break; - case HistoryAction.Upload: - icon = faCloudUploadAlt; - break; - } - if (icon) { - return ; - } else { - return null; - } -}; - -interface MessageIconProps extends FontAwesomeIconProps { - messages: string[]; -} - -export const MessageIcon: FunctionComponent = (props) => { - const { messages, ...iconProps } = props; - - const popover = ( - - ); - - return ( - - - - ); -}; - -export const LoadingIndicator: FunctionComponent<{ - animation?: SpinnerProps["animation"]; -}> = ({ children, animation: style }) => { - return ( -
    - - {children} -
    - ); -}; - -interface TextPopoverProps { - children: ReactElement; - text: string | undefined | null; - placement?: OverlayTriggerProps["placement"]; - delay?: number; -} - -export const TextPopover: FunctionComponent = ({ - children, - text, - placement, - delay, -}) => { - if (isNull(text) || isUndefined(text)) { - return children; - } - - const popover = ( - - {text} - - ); - return ( - - {children} - - ); -}; - -export * from "./async"; -export * from "./buttons"; -export * from "./header"; export * from "./inputs"; -export * from "./LanguageSelector"; -export * from "./SearchBar"; +export { default as Search } from "./Search"; export * from "./tables"; +export { default as Toolbox } from "./toolbox"; diff --git a/frontend/src/components/inputs/Action.tsx b/frontend/src/components/inputs/Action.tsx new file mode 100644 index 000000000..79159d326 --- /dev/null +++ b/frontend/src/components/inputs/Action.tsx @@ -0,0 +1,24 @@ +import { IconDefinition } from "@fortawesome/fontawesome-common-types"; +import { + FontAwesomeIcon, + FontAwesomeIconProps, +} from "@fortawesome/react-fontawesome"; +import { ActionIcon, ActionIconProps } from "@mantine/core"; +import { forwardRef } from "react"; + +export type ActionProps = ActionIconProps<"button"> & { + icon: IconDefinition; + iconProps?: Omit; +}; + +const Action = forwardRef( + ({ icon, iconProps, ...props }, ref) => { + return ( + + + + ); + } +); + +export default Action; diff --git a/frontend/src/components/inputs/ChipInput.tsx b/frontend/src/components/inputs/ChipInput.tsx new file mode 100644 index 000000000..0775a7ab6 --- /dev/null +++ b/frontend/src/components/inputs/ChipInput.tsx @@ -0,0 +1,34 @@ +import { useSelectorOptions } from "@/utilities"; +import { FunctionComponent } from "react"; +import { MultiSelector, MultiSelectorProps } from "./Selector"; + +export type ChipInputProps = Omit< + MultiSelectorProps, + | "searchable" + | "creatable" + | "getCreateLabel" + | "onCreate" + | "options" + | "getkey" +>; + +const ChipInput: FunctionComponent = ({ ...props }) => { + const { value, onChange } = props; + + const options = useSelectorOptions(value ?? [], (v) => v); + + return ( + `Add "${query}"`} + onCreate={(query) => { + onChange?.([...(value ?? []), query]); + }} + > + ); +}; + +export default ChipInput; diff --git a/frontend/src/components/inputs/Chips.tsx b/frontend/src/components/inputs/Chips.tsx deleted file mode 100644 index e52f751d7..000000000 --- a/frontend/src/components/inputs/Chips.tsx +++ /dev/null @@ -1,147 +0,0 @@ -import { - FocusEvent, - FunctionComponent, - KeyboardEvent, - useCallback, - useEffect, - useMemo, - useRef, - useState, -} from "react"; - -const SplitKeys = ["Tab", "Enter", " ", ",", ";"]; - -export interface ChipsProps { - disabled?: boolean; - defaultValue?: readonly string[]; - value?: readonly string[]; - onChange?: (v: string[]) => void; -} - -export const Chips: FunctionComponent = ({ - defaultValue, - value, - disabled, - onChange, -}) => { - const [chips, setChips] = useState>(() => { - if (value) { - return value; - } - if (defaultValue) { - return defaultValue; - } - return []; - }); - - useEffect(() => { - if (value) { - setChips(value); - } - }, [value]); - - const input = useRef(null); - - const addChip = useCallback( - (value: string) => { - setChips((cp) => { - const newChips = [...cp, value]; - onChange && onChange(newChips); - return newChips; - }); - }, - [onChange] - ); - - const removeChip = useCallback( - (idx?: number) => { - setChips((cp) => { - const index = idx ?? cp.length - 1; - if (index !== -1) { - const newChips = [...cp]; - newChips.splice(index, 1); - onChange && onChange(newChips); - return newChips; - } else { - return cp; - } - }); - }, - [onChange] - ); - - const clearInput = useCallback(() => { - if (input.current) { - input.current.value = ""; - } - }, [input]); - - const onKeyUp = useCallback( - (event: KeyboardEvent) => { - const pressed = event.key; - const value = event.currentTarget.value; - if (SplitKeys.includes(pressed) && value.length !== 0) { - event.preventDefault(); - addChip(value); - clearInput(); - } else if (pressed === "Backspace" && value.length === 0) { - event.preventDefault(); - removeChip(); - } - }, - [addChip, removeChip, clearInput] - ); - - const onKeyDown = useCallback((event: KeyboardEvent) => { - const pressed = event.key; - const value = event.currentTarget.value; - if (SplitKeys.includes(pressed) && value.length !== 0) { - event.preventDefault(); - } - }, []); - - const onBlur = useCallback( - (event: FocusEvent) => { - const value = event.currentTarget.value; - if (value.length !== 0) { - event.preventDefault(); - addChip(value); - clearInput(); - } - }, - [addChip, clearInput] - ); - - const chipElements = useMemo( - () => - chips.map((v, idx) => ( - { - if (!disabled) { - removeChip(idx); - } - }} - > - {v} - - )), - [chips, removeChip, disabled] - ); - - return ( -
    -
    {chipElements}
    - -
    - ); -}; diff --git a/frontend/src/components/inputs/File.tsx b/frontend/src/components/inputs/File.tsx new file mode 100644 index 000000000..5829e68b2 --- /dev/null +++ b/frontend/src/components/inputs/File.tsx @@ -0,0 +1,78 @@ +import { + faArrowUp, + faFileCirclePlus, + faXmark, +} from "@fortawesome/free-solid-svg-icons"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { Box, Stack, Text } from "@mantine/core"; +import { + Dropzone, + DropzoneProps, + DropzoneStatus, + FullScreenDropzone, + FullScreenDropzoneProps, +} from "@mantine/dropzone"; +import { FunctionComponent, useMemo } from "react"; + +export type FileProps = Omit & { + inner?: FileInnerComponent; +}; + +const File: FunctionComponent = ({ + inner: Inner = FileInner, + ...props +}) => { + return ( + + {(status) => } + + ); +}; + +export type FileOverlayProps = Omit & { + inner?: FileInnerComponent; +}; + +export const FileOverlay: FunctionComponent = ({ + inner: Inner = FileInner, + ...props +}) => { + return ( + + {(status) => } + + ); +}; + +export type FileInnerProps = { + status: DropzoneStatus; +}; + +type FileInnerComponent = FunctionComponent; + +const FileInner: FileInnerComponent = ({ status }) => { + const { accepted, rejected } = status; + const icon = useMemo(() => { + if (accepted) { + return faArrowUp; + } else if (rejected) { + return faXmark; + } else { + return faFileCirclePlus; + } + }, [accepted, rejected]); + + return ( + + + + + Upload files here + + Drag and drop, or click to select + + + ); +}; + +export default File; diff --git a/frontend/src/components/inputs/FileBrowser.tsx b/frontend/src/components/inputs/FileBrowser.tsx index 5bf289de7..96325cda6 100644 --- a/frontend/src/components/inputs/FileBrowser.tsx +++ b/frontend/src/components/inputs/FileBrowser.tsx @@ -1,18 +1,11 @@ import { useFileSystem } from "@/apis/hooks"; -import { faFile, faFolder } from "@fortawesome/free-regular-svg-icons"; -import { faReply } from "@fortawesome/free-solid-svg-icons"; +import { faFolder } from "@fortawesome/free-regular-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { - ChangeEvent, - FunctionComponent, - useEffect, - useMemo, - useRef, - useState, -} from "react"; -import { Dropdown, DropdownProps, Form, Spinner } from "react-bootstrap"; +import { Autocomplete, AutocompleteProps } from "@mantine/core"; +import { FunctionComponent, useEffect, useMemo, useRef, useState } from "react"; -const backKey = "--back--"; +// TODO: use fortawesome icons +const backKey = "⏎ Back"; function getLastSeparator(path: string): number { let idx = path.lastIndexOf("/"); @@ -31,134 +24,81 @@ function extractPath(raw: string) { } } -export interface FileBrowserProps { - defaultValue?: string; +export type FileBrowserProps = Omit & { type: "sonarr" | "radarr" | "bazarr"; - onChange?: (path: string) => void; - drop?: DropdownProps["drop"]; -} +}; + +type FileTreeItem = { + value: string; + item?: FileTree; +}; export const FileBrowser: FunctionComponent = ({ defaultValue, type, onChange, - drop, + ...props }) => { - const [show, canShow] = useState(false); - const [text, setText] = useState(defaultValue ?? ""); - const [path, setPath] = useState(() => extractPath(text)); - - const { data: tree, isFetching } = useFileSystem(type, path, show); - - const filter = useMemo(() => { - const idx = getLastSeparator(text); - return text.slice(idx + 1); - }, [text]); + const [isShow, setIsShow] = useState(false); + const [value, setValue] = useState(defaultValue ?? ""); + const [path, setPath] = useState(() => extractPath(value)); + + const { data: tree } = useFileSystem(type, path, isShow); + + const data = useMemo( + () => [ + { value: backKey }, + ...(tree?.map((v) => ({ + value: v.path, + item: v, + })) ?? []), + ], + [tree] + ); - const previous = useMemo(() => { + const parent = useMemo(() => { const idx = getLastSeparator(path.slice(0, -1)); return path.slice(0, idx + 1); }, [path]); - const requestItems = () => { - if (isFetching) { - return ( - - - - ); - } - - const elements = []; - - if (tree) { - elements.push( - ...tree - .filter((v) => v.name.startsWith(filter)) - .map((v) => ( - - - {v.name} - - )) - ); - } - - if (elements.length === 0) { - elements.push(No Files); - } - - if (previous.length !== 0) { - return [ - - - Back - , - , - ...elements, - ]; - } else { - return elements; - } - }; - useEffect(() => { - if (text === path) { + if (value === path) { return; } - const newPath = extractPath(text); + const newPath = extractPath(value); if (newPath !== path) { setPath(newPath); onChange && onChange(newPath); } - }, [path, text, onChange]); + }, [path, value, onChange]); - const input = useRef(null); + const ref = useRef(null); return ( - { - if (!key) { - return; - } - - if (key !== backKey) { - setText(key); +
    } + placeholder="Click to start" + data={data} + value={value} + filter={(value, item) => { + if (item.value === backKey) { + return true; } else { - setText(previous); + return item.value.includes(value); } - input.current?.focus(); }} - onToggle={(open, _, meta) => { - if (!open && meta.source !== "select") { - canShow(false); - } else if (open) { - canShow(true); + onChange={(val) => { + if (val !== backKey) { + setValue(val); + } else { + setValue(parent); } }} - > - ) => { - setText(e.currentTarget.value); - }} - ref={input} - > - - {requestItems()} - -
    + onFocus={() => setIsShow(true)} + onBlur={() => setIsShow(false)} + > ); }; diff --git a/frontend/src/components/inputs/FileForm.tsx b/frontend/src/components/inputs/FileForm.tsx deleted file mode 100644 index af7a6a238..000000000 --- a/frontend/src/components/inputs/FileForm.tsx +++ /dev/null @@ -1,73 +0,0 @@ -import { - ChangeEvent, - FunctionComponent, - useEffect, - useMemo, - useRef, - useState, -} from "react"; -import { Form } from "react-bootstrap"; - -export interface FileFormProps { - disabled?: boolean; - multiple?: boolean; - emptyText: string; - value?: File[]; - onChange?: (files: File[]) => void; -} - -export const FileForm: FunctionComponent = ({ - value: files, - emptyText, - multiple, - disabled, - onChange, -}) => { - const [fileList, setFileList] = useState([]); - - const input = useRef(null); - - useEffect(() => { - if (files) { - setFileList(files); - - if (files.length === 0 && input.current) { - // Manual reset file input - input.current.value = ""; - } - } - }, [files]); - - const label = useMemo(() => { - if (fileList.length === 0) { - return emptyText; - } else { - if (multiple) { - return `${fileList.length} Files`; - } else { - return fileList[0].name; - } - } - }, [fileList, emptyText, multiple]); - - return ( - ) => { - const { files } = e.target; - if (files) { - const list: File[] = []; - for (const file of files) { - list.push(file); - } - setFileList(list); - onChange && onChange(list); - } - }} - > - ); -}; diff --git a/frontend/src/components/inputs/Selector.tsx b/frontend/src/components/inputs/Selector.tsx index fa08e77da..38b48722b 100644 --- a/frontend/src/components/inputs/Selector.tsx +++ b/frontend/src/components/inputs/Selector.tsx @@ -1,141 +1,169 @@ -import clsx from "clsx"; -import { FocusEvent, useCallback, useMemo, useRef } from "react"; -import Select, { GroupBase, OnChangeValue } from "react-select"; -import { SelectComponents } from "react-select/dist/declarations/src/components"; - -export type SelectorOption = { - label: string; - value: T; -}; +import { LOG } from "@/utilities/console"; +import { + MultiSelect, + MultiSelectProps, + Select, + SelectItem, + SelectProps, +} from "@mantine/core"; +import { isNull, isUndefined } from "lodash"; +import { useCallback, useMemo, useRef } from "react"; -export type SelectorComponents = SelectComponents< - SelectorOption, - M, - GroupBase> +export type SelectorOption = Override< + { + value: T; + label: string; + }, + SelectItem >; -export type SelectorValueType = M extends true - ? ReadonlyArray - : Nullable; - -export interface SelectorProps { - className?: string; - placeholder?: string; - options: readonly SelectorOption[]; - disabled?: boolean; - clearable?: boolean; - loading?: boolean; - multiple?: M; - onChange?: (k: SelectorValueType) => void; - onFocus?: (e: FocusEvent) => void; - label?: (item: T) => string; - defaultValue?: SelectorValueType; - value?: SelectorValueType; - components?: Partial< - SelectComponents, M, GroupBase>> - >; +type SelectItemWithPayload = SelectItem & { + payload: T; +}; + +function DefaultKeyBuilder(value: T) { + if (typeof value === "string") { + return value; + } else if (typeof value === "number") { + return value.toString(); + } else { + LOG("error", "Unknown value type", value); + throw new Error( + `Invalid type (${typeof value}) in the SelectorOption, please provide a label builder` + ); + } } -export function Selector( - props: SelectorProps -) { - const { - className, - placeholder, - label, - disabled, - clearable, - loading, - options, - multiple, - onChange, - onFocus, - defaultValue, - components, - value, - } = props; - - const labelRef = useRef(label); - - const getName = useCallback( - (item: T) => { - if (labelRef.current) { - return labelRef.current(item); - } +export type SelectorProps = Override< + { + value?: T | null; + defaultValue?: T | null; + options: SelectorOption[]; + onChange?: (value: T | null) => void; + getkey?: (value: T) => string; + }, + Omit +>; + +export function Selector({ + value, + defaultValue, + options, + onChange, + getkey = DefaultKeyBuilder, + ...select +}: SelectorProps) { + const keyRef = useRef(getkey); + keyRef.current = getkey; + + const data = useMemo( + () => + options.map>(({ value, label, ...option }) => ({ + label, + value: keyRef.current(value), + payload: value, + ...option, + })), + [keyRef, options] + ); - return options.find((v) => v.value === item)?.label ?? "Unknown"; + const wrappedValue = useMemo(() => { + if (isNull(value) || isUndefined(value)) { + return value; + } else { + return keyRef.current(value); + } + }, [keyRef, value]); + + const wrappedDefaultValue = useMemo(() => { + if (isNull(defaultValue) || isUndefined(defaultValue)) { + return defaultValue; + } else { + return keyRef.current(defaultValue); + } + }, [defaultValue, keyRef]); + + const wrappedOnChange = useCallback( + (value: string) => { + const payload = data.find((v) => v.value === value)?.payload ?? null; + onChange?.(payload); }, + [data, onChange] + ); + + return ( + + ); +} + +export type MultiSelectorProps = Override< + { + value?: readonly T[]; + defaultValue?: readonly T[]; + options: readonly SelectorOption[]; + onChange?: (value: T[]) => void; + getkey?: (value: T) => string; + }, + Omit +>; + +export function MultiSelector({ + value, + defaultValue, + options, + onChange, + getkey = DefaultKeyBuilder, + ...select +}: MultiSelectorProps) { + const labelRef = useRef(getkey); + labelRef.current = getkey; + + const data = useMemo( + () => + options.map>(({ value, ...option }) => ({ + value: labelRef.current(value), + payload: value, + ...option, + })), [options] ); - const wrapper = useCallback( - ( - value: SelectorValueType | undefined | null - ): - | SelectorOption - | ReadonlyArray> - | null - | undefined => { - if (value === null || value === undefined) { - return value as null | undefined; - } else { - if (multiple === true) { - return (value as SelectorValueType).map((v) => ({ - label: getName(v), - value: v, - })); - } else { - const v = value as T; - return { - label: getName(v), - value: v, - }; + const wrappedValue = useMemo( + () => value && value.map(labelRef.current), + [value] + ); + const wrappedDefaultValue = useMemo( + () => defaultValue && defaultValue.map(labelRef.current), + [defaultValue] + ); + + const wrappedOnChange = useCallback( + (values: string[]) => { + const payloads: T[] = []; + for (const value of values) { + const payload = data.find((v) => v.value === value)?.payload; + if (payload) { + payloads.push(payload); } } + onChange?.(payloads); }, - [multiple, getName] - ); - - const defaultWrapper = useMemo( - () => wrapper(defaultValue), - [defaultValue, wrapper] + [data, onChange] ); - const valueWrapper = useMemo(() => wrapper(value), [wrapper, value]); - return ( - + ); } diff --git a/frontend/src/components/inputs/Slider.tsx b/frontend/src/components/inputs/Slider.tsx deleted file mode 100644 index ab3fb0996..000000000 --- a/frontend/src/components/inputs/Slider.tsx +++ /dev/null @@ -1,83 +0,0 @@ -import RcSlider from "rc-slider"; -import "rc-slider/assets/index.css"; -import { FunctionComponent, useMemo, useState } from "react"; - -type TooltipsOptions = boolean | "Always"; - -export interface SliderProps { - tooltips?: TooltipsOptions; - min?: number; - max?: number; - step?: number; - start?: number; - defaultValue?: number; - onAfterChange?: (value: number) => void; - onChange?: (value: number) => void; -} - -export const Slider: FunctionComponent = ({ - min, - max, - step, - tooltips, - defaultValue, - onChange, - onAfterChange, -}) => { - max = max ?? 100; - min = min ?? 0; - step = step ?? 1; - - const [curr, setValue] = useState(defaultValue); - - return ( -
    - {`${min} / ${curr}`} - { - setValue(v); - onChange && onChange(v); - }} - onAfterChange={onAfterChange} - handle={(props) => ( -
    - -
    - )} - >
    - {max} -
    - ); -}; - -const SliderTooltips: FunctionComponent<{ - tooltips?: TooltipsOptions; - value: number; -}> = ({ tooltips, value }) => { - const cls = useMemo(() => { - const tipsCls = ["rc-slider-handle-tips"]; - if (tooltips !== undefined) { - if (typeof tooltips === "string") { - tipsCls.push("rc-slider-handle-tips-always"); - } else if (tooltips === false) { - tipsCls.push("rc-slider-handle-tips-hidden"); - } - } - return tipsCls.join(" "); - }, [tooltips]); - - return {value}; -}; diff --git a/frontend/src/components/inputs/blacklist.tsx b/frontend/src/components/inputs/blacklist.tsx deleted file mode 100644 index d55e843ec..000000000 --- a/frontend/src/components/inputs/blacklist.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import { faFileExcel } from "@fortawesome/free-solid-svg-icons"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { FunctionComponent } from "react"; -import { AsyncButton } from ".."; - -interface Props { - history: History.Base; - update?: () => void; - promise: (form: FormType.AddBlacklist) => Promise; -} - -export const BlacklistButton: FunctionComponent = ({ - history, - update, - promise, -}) => { - const { provider, subs_id, language, subtitles_path, blacklisted } = history; - - if (subs_id && provider && language) { - return ( - { - const { code2 } = language; - const form: FormType.AddBlacklist = { - provider, - subs_id, - subtitles_path, - language: code2, - }; - return promise(form); - }} - onSuccess={update} - > - - - ); - } else { - return null; - } -}; diff --git a/frontend/src/components/inputs/index.ts b/frontend/src/components/inputs/index.ts index ced446f59..fc2b3e879 100644 --- a/frontend/src/components/inputs/index.ts +++ b/frontend/src/components/inputs/index.ts @@ -1,5 +1,3 @@ -export * from "./Chips"; +export { default as Action } from "./Action"; export * from "./FileBrowser"; -export * from "./FileForm"; export * from "./Selector"; -export * from "./Slider"; diff --git a/frontend/src/components/modals/HistoryModal.tsx b/frontend/src/components/modals/HistoryModal.tsx index 58e47cd90..893bd79d5 100644 --- a/frontend/src/components/modals/HistoryModal.tsx +++ b/frontend/src/components/modals/HistoryModal.tsx @@ -4,19 +4,26 @@ import { useMovieAddBlacklist, useMovieHistory, } from "@/apis/hooks"; -import { useModal, usePayload, withModal } from "@/modules/modals"; +import { withModal } from "@/modules/modals"; +import { faFileExcel } from "@fortawesome/free-solid-svg-icons"; +import { Badge, Center, Text } from "@mantine/core"; import { FunctionComponent, useMemo } from "react"; import { Column } from "react-table"; -import { HistoryIcon, PageTable, QueryOverlay, TextPopover } from ".."; +import { PageTable } from ".."; +import MutateAction from "../async/MutateAction"; +import QueryOverlay from "../async/QueryOverlay"; +import { HistoryIcon } from "../bazarr"; import Language from "../bazarr/Language"; -import { BlacklistButton } from "../inputs/blacklist"; +import TextPopover from "../TextPopover"; -const MovieHistoryView: FunctionComponent = () => { - const movie = usePayload(); +interface MovieHistoryViewProps { + movie: Item.Movie; +} - const Modal = useModal({ size: "lg" }); - - const history = useMovieHistory(movie?.radarrId); +const MovieHistoryView: FunctionComponent = ({ + movie, +}) => { + const history = useMovieHistory(movie.radarrId); const { data } = history; @@ -24,17 +31,22 @@ const MovieHistoryView: FunctionComponent = () => { () => [ { accessor: "action", - className: "text-center", - Cell: (row) => { - return ; - }, + Cell: (row) => ( +
    + +
    + ), }, { Header: "Language", accessor: "language", Cell: ({ value }) => { if (value) { - return ; + return ( + + + + ); } else { return null; } @@ -51,58 +63,72 @@ const MovieHistoryView: FunctionComponent = () => { { Header: "Date", accessor: "timestamp", - Cell: (row) => { - if (row.value) { - return ( - - {row.value} - - ); - } else { - return null; - } + Cell: ({ value, row }) => { + return ( + + {value} + + ); }, }, { // Actions accessor: "blacklisted", - Cell: ({ row }) => { - const { radarrId } = row.original; - const { mutateAsync } = useMovieAddBlacklist(); - return ( - mutateAsync({ id: radarrId, form })} - history={row.original} - > - ); + Cell: ({ row, value }) => { + const add = useMovieAddBlacklist(); + const { radarrId, provider, subs_id, language, subtitles_path } = + row.original; + + if (subs_id && provider && language) { + return ( + ({ + id: radarrId, + form: { + provider, + subs_id, + subtitles_path, + language: language.code2, + }, + })} + > + ); + } else { + return null; + } }, }, ], - [history.refetch] + [] ); return ( - - - - - + + + ); }; -export const MovieHistoryModal = withModal(MovieHistoryView, "movie-history"); - -const EpisodeHistoryView: FunctionComponent = () => { - const episode = usePayload(); +export const MovieHistoryModal = withModal(MovieHistoryView, "movie-history", { + size: "xl", + title: "Movie History", +}); - const Modal = useModal({ size: "lg" }); +interface EpisodeHistoryViewProps { + episode: Item.Episode; +} - const history = useEpisodeHistory(episode?.sonarrEpisodeId); +const EpisodeHistoryView: FunctionComponent = ({ + episode, +}) => { + const history = useEpisodeHistory(episode.sonarrEpisodeId); const { data } = history; @@ -110,17 +136,22 @@ const EpisodeHistoryView: FunctionComponent = () => { () => [ { accessor: "action", - className: "text-center", - Cell: (row) => { - return ; - }, + Cell: (row) => ( +
    + +
    + ), }, { Header: "Language", accessor: "language", Cell: ({ value }) => { if (value) { - return ; + return ( + + + + ); } else { return null; } @@ -137,38 +168,49 @@ const EpisodeHistoryView: FunctionComponent = () => { { Header: "Date", accessor: "timestamp", - Cell: (row) => { - if (row.value) { - return ( - - {row.value} - - ); - } else { - return null; - } + Cell: ({ row, value }) => { + return ( + + {value} + + ); }, }, { // Actions accessor: "blacklisted", - Cell: ({ row }) => { - const original = row.original; + Cell: ({ row, value }) => { + const { + sonarrEpisodeId, + sonarrSeriesId, + provider, + subs_id, + language, + subtitles_path, + } = row.original; + const add = useEpisodeAddBlacklist(); - const { sonarrEpisodeId, sonarrSeriesId } = original; - const { mutateAsync } = useEpisodeAddBlacklist(); - return ( - - mutateAsync({ + if (subs_id && provider && language) { + return ( + ({ seriesId: sonarrSeriesId, episodeId: sonarrEpisodeId, - form, - }) - } - > - ); + form: { + provider, + subs_id, + subtitles_path, + language: language.code2, + }, + })} + > + ); + } else { + return null; + } }, }, ], @@ -176,19 +218,18 @@ const EpisodeHistoryView: FunctionComponent = () => { ); return ( - - - - - + + + ); }; export const EpisodeHistoryModal = withModal( EpisodeHistoryView, - "episode-history" + "episode-history", + { size: "xl" } ); diff --git a/frontend/src/components/modals/ItemEditorModal.tsx b/frontend/src/components/modals/ItemEditorModal.tsx deleted file mode 100644 index ffe44feb5..000000000 --- a/frontend/src/components/modals/ItemEditorModal.tsx +++ /dev/null @@ -1,100 +0,0 @@ -import { useIsAnyActionRunning, useLanguageProfiles } from "@/apis/hooks"; -import { - useModal, - useModalControl, - usePayload, - withModal, -} from "@/modules/modals"; -import { GetItemId } from "@/utilities"; -import { FunctionComponent, useMemo, useState } from "react"; -import { Container, Form } from "react-bootstrap"; -import { UseMutationResult } from "react-query"; -import { AsyncButton, Selector, SelectorOption } from ".."; - -interface Props { - mutation: UseMutationResult; -} - -const Editor: FunctionComponent = ({ mutation }) => { - const { data: profiles } = useLanguageProfiles(); - - const payload = usePayload(); - const { mutateAsync, isLoading } = mutation; - - const { hide } = useModalControl(); - - const hasTask = useIsAnyActionRunning(); - - const profileOptions = useMemo[]>( - () => - profiles?.map((v) => { - return { label: v.name, value: v.profileId }; - }) ?? [], - [profiles] - ); - - const [id, setId] = useState>(payload?.profileId ?? null); - - const Modal = useModal({ - closeable: !isLoading, - onMounted: () => { - setId(payload?.profileId ?? null); - }, - }); - - const footer = ( - { - if (payload) { - const itemId = GetItemId(payload); - if (!itemId) { - return null; - } - - return mutateAsync({ - id: [itemId], - profileid: [id], - }); - } else { - return null; - } - }} - onSuccess={() => hide()} - > - Save - - ); - - return ( - - -
    - - Audio - v.name) - .join(", ")} - > - - - Languages Profiles - setId(v === undefined ? null : v)} - > - -
    -
    -
    - ); -}; - -export default withModal(Editor, "edit"); diff --git a/frontend/src/components/modals/ManualSearchModal.tsx b/frontend/src/components/modals/ManualSearchModal.tsx index 17e5a786b..e1c9d2592 100644 --- a/frontend/src/components/modals/ManualSearchModal.tsx +++ b/frontend/src/components/modals/ManualSearchModal.tsx @@ -1,29 +1,35 @@ -import { useModal, usePayload, withModal } from "@/modules/modals"; -import { createAndDispatchTask } from "@/modules/task/utilities"; -import { GetItemId, isMovie } from "@/utilities"; +import { withModal } from "@/modules/modals"; +import { task, TaskGroup } from "@/modules/task"; +import { useTableStyles } from "@/styles"; +import { BuildKey, GetItemId } from "@/utilities"; import { faCaretDown, faCheck, + faCheckCircle, faDownload, + faExclamationCircle, faInfoCircle, faTimes, } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import clsx from "clsx"; -import { FunctionComponent, useCallback, useMemo, useState } from "react"; import { + Alert, + Anchor, Badge, Button, - Col, Collapse, - Container, - OverlayTrigger, + Divider, + Group, + List, Popover, - Row, -} from "react-bootstrap"; + Stack, + Text, +} from "@mantine/core"; +import { useHover } from "@mantine/hooks"; +import { FunctionComponent, useCallback, useMemo, useState } from "react"; import { UseQueryResult } from "react-query"; import { Column } from "react-table"; -import { LoadingIndicator, PageTable } from ".."; +import { Action, PageTable } from ".."; import Language from "../bazarr/Language"; type SupportType = Item.Movie | Item.Episode; @@ -33,12 +39,11 @@ interface Props { query: ( id?: number ) => UseQueryResult; + item: T; } function ManualSearchView(props: Props) { - const { download, query: useSearch } = props; - - const item = usePayload(); + const { download, query: useSearch, item } = props; const itemId = useMemo(() => GetItemId(item ?? {}), [item]); @@ -49,17 +54,19 @@ function ManualSearchView(props: Props) { const isStale = results.data === undefined; const search = useCallback(() => { - if (itemId !== undefined) { - setId(itemId); - results.refetch(); - } + setId(itemId); + results.refetch(); }, [itemId, results]); const columns = useMemo[]>( () => [ { Header: "Score", - accessor: (d) => `${d.score}%`, + accessor: "score", + Cell: ({ value }) => { + const { classes } = useTableStyles(); + return {value}%; + }, }, { accessor: "language", @@ -71,7 +78,7 @@ function ManualSearchView(props: Props) { name: "", }; return ( - + ); @@ -81,13 +88,19 @@ function ManualSearchView(props: Props) { Header: "Provider", accessor: "provider", Cell: (row) => { + const { classes } = useTableStyles(); const value = row.value; const { url } = row.row.original; if (url) { return ( - + {value} - + ); } else { return value; @@ -97,55 +110,44 @@ function ManualSearchView(props: Props) { { Header: "Release", accessor: "release_info", - className: "text-nowrap", - Cell: (row) => { - const value = row.value; - + Cell: ({ value }) => { + const { classes } = useTableStyles(); const [open, setOpen] = useState(false); const items = useMemo( - () => - value.slice(1).map((v, idx) => ( - - {v} - - )), + () => value.slice(1).map((v, idx) => {v}), [value] ); if (value.length === 0) { - return Cannot get release info; + return Cannot get release info; } return ( -
    1 } - )} - onClick={() => setOpen((o) => !o)} - > -
    - {value[0]} - -
    {items}
    -
    -
    - - {value.length > 1 && ( - - )} -
    + setOpen((o) => !o)}> + + {value[0]} + {value.length > 1 && ( + + )} + + + <>{items} + + ); }, }, { Header: "Upload", - accessor: (d) => d.uploader ?? "-", + accessor: "uploader", + Cell: ({ value }) => { + const { classes } = useTableStyles(); + return {value ?? "-"}; + }, }, { accessor: "matches", @@ -159,24 +161,23 @@ function ManualSearchView(props: Props) { Cell: ({ row }) => { const result = row.original; return ( - + > ); }, }, @@ -184,141 +185,84 @@ function ManualSearchView(props: Props) { [download, item] ); - const content = () => { - if (results.isFetching) { - return ; - } else if (isStale) { - return ( -
    -

    {item?.path ?? ""}

    - -
    - ); - } else { - return ( - <> -

    {item?.path ?? ""}

    - - - ); - } - }; - - const title = useMemo(() => { - let title = "Unknown"; - - if (item) { - if (item.sceneName) { - title = item.sceneName; - } else if (isMovie(item)) { - title = item.title; - } else { - title = item.title; - } - } - return `Search - ${title}`; - }, [item]); - - const Modal = useModal({ - size: "xl", - closeable: results.isFetching === false, - onMounted: () => { - // Cleanup the ID when user switches episode / movie - if (itemId !== id) { - setId(undefined); - } - }, - }); - - const footer = ( - - ); - return ( - - {content()} - + + } + > + {item?.path} + + + + + + + ); } export const MovieSearchModal = withModal>( ManualSearchView, - "movie-manual-search" + "movie-manual-search", + { title: "Search Subtitles", size: "xl" } ); export const EpisodeSearchModal = withModal>( ManualSearchView, - "episode-manual-search" + "episode-manual-search", + { title: "Search Subtitles", size: "xl" } ); const StateIcon: FunctionComponent<{ matches: string[]; dont: string[] }> = ({ matches, dont, }) => { - let icon = faCheck; - let color = "var(--success)"; - if (dont.length > 0) { - icon = faInfoCircle; - color = "var(--warning)"; - } + const hasIssues = dont.length > 0; - const matchElements = useMemo( - () => - matches.map((v, idx) => ( -

    - {v} -

    - )), - [matches] - ); - const dontElements = useMemo( - () => - dont.map((v, idx) => ( -

    - {v} -

    - )), - [dont] - ); - - const popover = useMemo( - () => ( - - - - - - - {matchElements} - - - - {dontElements} - - - - - - ), - [matchElements, dontElements] - ); + const { ref, hovered } = useHover(); return ( - - - + + + + } + > + + + + + + + {matches.map((v, idx) => ( + {v} + ))} + + + + + + + + {dont.map((v, idx) => ( + {v} + ))} + + + + ); }; diff --git a/frontend/src/components/modals/MovieUploadModal.tsx b/frontend/src/components/modals/MovieUploadModal.tsx deleted file mode 100644 index 464c055dc..000000000 --- a/frontend/src/components/modals/MovieUploadModal.tsx +++ /dev/null @@ -1,99 +0,0 @@ -import { useMovieSubtitleModification } from "@/apis/hooks"; -import { usePayload, withModal } from "@/modules/modals"; -import { createTask, dispatchTask } from "@/modules/task/utilities"; -import { - useLanguageProfileBy, - useProfileItemsToLanguages, -} from "@/utilities/languages"; -import { FunctionComponent, useCallback } from "react"; -import SubtitleUploader, { - PendingSubtitle, - Validator, -} from "./SubtitleUploadModal"; - -const MovieUploadModal: FunctionComponent = () => { - const payload = usePayload(); - - const profile = useLanguageProfileBy(payload?.profileId); - - const availableLanguages = useProfileItemsToLanguages(profile); - - const update = useCallback(async (list: PendingSubtitle[]) => { - return list; - }, []); - - const { - upload: { mutateAsync }, - } = useMovieSubtitleModification(); - - const validate = useCallback>( - (item) => { - if (item.language === null) { - return { - state: "error", - messages: ["Language is not selected"], - }; - } else if ( - payload?.subtitles.find((v) => v.code2 === item.language?.code2) !== - undefined - ) { - return { - state: "warning", - messages: ["Override existing subtitle"], - }; - } - return { - state: "valid", - messages: [], - }; - }, - [payload?.subtitles] - ); - - const upload = useCallback( - (items: PendingSubtitle[]) => { - if (payload === null) { - return; - } - - const { radarrId } = payload; - - const tasks = items - .filter((v) => v.language !== null) - .map((v) => { - const { file, language, forced, hi } = v; - - if (language === null) { - throw new Error("Language is not selected"); - } - - return createTask(file.name, mutateAsync, { - radarrId, - form: { - file, - forced, - hi, - language: language.code2, - }, - }); - }); - - dispatchTask(tasks, "upload-subtitles"); - }, - [mutateAsync, payload] - ); - - return ( - - ); -}; - -export default withModal(MovieUploadModal, "movie-upload"); diff --git a/frontend/src/components/modals/SeriesUploadModal.tsx b/frontend/src/components/modals/SeriesUploadModal.tsx deleted file mode 100644 index 89a033e51..000000000 --- a/frontend/src/components/modals/SeriesUploadModal.tsx +++ /dev/null @@ -1,175 +0,0 @@ -import { useEpisodeSubtitleModification } from "@/apis/hooks"; -import api from "@/apis/raw"; -import { usePayload, withModal } from "@/modules/modals"; -import { createTask, dispatchTask } from "@/modules/task/utilities"; -import { - useLanguageProfileBy, - useProfileItemsToLanguages, -} from "@/utilities/languages"; -import { FunctionComponent, useCallback, useMemo } from "react"; -import { Column } from "react-table"; -import { Selector, SelectorOption } from "../inputs"; -import SubtitleUploader, { - PendingSubtitle, - useRowMutation, - Validator, -} from "./SubtitleUploadModal"; - -interface Payload { - instance: Item.Episode | null; -} - -interface SeriesProps { - episodes: readonly Item.Episode[]; -} - -const SeriesUploadModal: FunctionComponent = ({ episodes }) => { - const payload = usePayload(); - - const profile = useLanguageProfileBy(payload?.profileId); - - const availableLanguages = useProfileItemsToLanguages(profile); - - const { - upload: { mutateAsync }, - } = useEpisodeSubtitleModification(); - - const update = useCallback( - async (list: PendingSubtitle[]) => { - const newList = [...list]; - const names = list.map((v) => v.file.name); - - if (names.length > 0) { - const results = await api.subtitles.info(names); - - // TODO: Optimization - newList.forEach((v) => { - const info = results.find((f) => f.filename === v.file.name); - if (info) { - v.payload.instance = - episodes.find( - (e) => e.season === info.season && e.episode === info.episode - ) ?? null; - } - }); - } - - return newList; - }, - [episodes] - ); - - const validate = useCallback>((item) => { - const { language } = item; - const { instance } = item.payload; - if (language === null || instance === null) { - return { - state: "error", - messages: ["Language or Episode is not selected"], - }; - } else if ( - instance.subtitles.find((v) => v.code2 === language.code2) !== undefined - ) { - return { - state: "warning", - messages: ["Override existing subtitle"], - }; - } - return { - state: "valid", - messages: [], - }; - }, []); - - const upload = useCallback( - (items: PendingSubtitle[]) => { - if (payload === null) { - return; - } - - const { sonarrSeriesId: seriesId } = payload; - - const tasks = items - .filter((v) => v.payload.instance !== undefined) - .map((v) => { - const { - hi, - forced, - payload: { instance }, - language, - } = v; - - if (language === null || instance === null) { - throw new Error("Invalid state"); - } - - const { code2 } = language; - const { sonarrEpisodeId: episodeId } = instance; - - const form: FormType.UploadSubtitle = { - file: v.file, - language: code2, - hi: hi, - forced: forced, - }; - - return createTask(v.file.name, mutateAsync, { - seriesId, - episodeId, - form, - }); - }); - - dispatchTask(tasks, "upload-subtitles"); - }, - [mutateAsync, payload] - ); - - const columns = useMemo>[]>( - () => [ - { - id: "instance", - Header: "Episode", - accessor: "payload", - className: "vw-1", - Cell: ({ value, row }) => { - const options = episodes.map>((ep) => ({ - label: `(${ep.season}x${ep.episode}) ${ep.title}`, - value: ep, - })); - - const mutate = useRowMutation(); - - return ( - ) => { - if (ep) { - const newInfo = { ...row.original }; - newInfo.payload.instance = ep; - mutate(row.index, newInfo); - } - }} - > - ); - }, - }, - ], - [episodes] - ); - - return ( - - ); -}; - -export default withModal(SeriesUploadModal, "series-upload"); diff --git a/frontend/src/components/modals/SubtitleToolsModal.tsx b/frontend/src/components/modals/SubtitleToolsModal.tsx new file mode 100644 index 000000000..2f49bccac --- /dev/null +++ b/frontend/src/components/modals/SubtitleToolsModal.tsx @@ -0,0 +1,123 @@ +import Language from "@/components/bazarr/Language"; +import SubtitleToolsMenu from "@/components/SubtitleToolsMenu"; +import { SimpleTable } from "@/components/tables"; +import { useCustomSelection } from "@/components/tables/plugins"; +import { withModal } from "@/modules/modals"; +import { isMovie } from "@/utilities"; +import { Badge, Button, Divider, Group, Stack } from "@mantine/core"; +import { FunctionComponent, useMemo, useState } from "react"; +import { Column, useRowSelect } from "react-table"; + +type SupportType = Item.Episode | Item.Movie; + +type TableColumnType = FormType.ModifySubtitle & { + raw_language: Language.Info; +}; + +function getIdAndType(item: SupportType): [number, "episode" | "movie"] { + if (isMovie(item)) { + return [item.radarrId, "movie"]; + } else { + return [item.sonarrEpisodeId, "episode"]; + } +} + +const CanSelectSubtitle = (item: TableColumnType) => { + return item.path.endsWith(".srt"); +}; + +interface SubtitleToolViewProps { + payload: SupportType[]; +} + +const SubtitleToolView: FunctionComponent = ({ + payload, +}) => { + const [selections, setSelections] = useState([]); + + const columns: Column[] = useMemo[]>( + () => [ + { + Header: "Language", + accessor: "raw_language", + Cell: ({ value }) => ( + + + + ), + }, + { + id: "file", + Header: "File", + accessor: "path", + Cell: ({ value }) => { + const path = value; + + let idx = path.lastIndexOf("/"); + + if (idx === -1) { + idx = path.lastIndexOf("\\"); + } + + if (idx !== -1) { + return path.slice(idx + 1); + } else { + return path; + } + }, + }, + ], + [] + ); + + const data = useMemo( + () => + payload.flatMap((item) => { + const [id, type] = getIdAndType(item); + return item.subtitles.flatMap((v) => { + if (v.path) { + return [ + { + id, + type, + language: v.code2, + path: v.path, + raw_language: v, + }, + ]; + } else { + return []; + } + }); + }), + [payload] + ); + + const plugins = [useRowSelect, useCustomSelection]; + + return ( + + + + + + + + + + ); +}; + +export default withModal(SubtitleToolView, "subtitle-tools", { + title: "Subtitle Tools", + size: "xl", +}); diff --git a/frontend/src/components/modals/SubtitleUploadModal.tsx b/frontend/src/components/modals/SubtitleUploadModal.tsx deleted file mode 100644 index c14f0b23e..000000000 --- a/frontend/src/components/modals/SubtitleUploadModal.tsx +++ /dev/null @@ -1,362 +0,0 @@ -import { useModal, useModalControl } from "@/modules/modals"; -import { BuildKey } from "@/utilities"; -import { LOG } from "@/utilities/console"; -import { - faCheck, - faCircleNotch, - faInfoCircle, - faTimes, - faTrash, -} from "@fortawesome/free-solid-svg-icons"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { - createContext, - useCallback, - useContext, - useEffect, - useMemo, - useRef, - useState, -} from "react"; -import { Button, Container, Form } from "react-bootstrap"; -import { Column } from "react-table"; -import { LanguageSelector, MessageIcon } from ".."; -import { FileForm } from "../inputs"; -import { SimpleTable } from "../tables"; - -type ModifyFn = (index: number, info?: PendingSubtitle) => void; - -const RowContext = createContext>(() => { - LOG("error", "RowContext not initialized"); -}); - -export function useRowMutation() { - return useContext(RowContext); -} - -export interface PendingSubtitle

    { - file: File; - state: "valid" | "fetching" | "warning" | "error"; - messages: string[]; - language: Language.Info | null; - forced: boolean; - hi: boolean; - payload: P; -} - -export type Validator = ( - item: PendingSubtitle -) => Pick, "state" | "messages">; - -interface Props { - initial: T; - availableLanguages: Language.Info[]; - upload: (items: PendingSubtitle[]) => void; - update: (items: PendingSubtitle[]) => Promise[]>; - validate: Validator; - columns: Column>[]; - hideAllLanguages?: boolean; -} - -function SubtitleUploader(props: Props) { - const { - initial, - columns, - upload, - update, - validate, - availableLanguages, - hideAllLanguages, - } = props; - - const [pending, setPending] = useState[]>([]); - - const showTable = pending.length > 0; - - const Modal = useModal({ - size: showTable ? "xl" : "lg", - }); - - const { hide } = useModalControl(); - - const fileList = useMemo(() => pending.map((v) => v.file), [pending]); - - const initialRef = useRef(initial); - - const setFiles = useCallback( - async (files: File[]) => { - const initialLanguage = - availableLanguages.length > 0 ? availableLanguages[0] : null; - let list = files.map>((file) => ({ - file, - state: "fetching", - messages: [], - language: initialLanguage, - forced: false, - hi: false, - payload: { ...initialRef.current }, - })); - - if (update) { - setPending(list); - list = await update(list); - } else { - list = list.map>((v) => ({ - ...v, - state: "valid", - })); - } - - list = list.map((v) => ({ - ...v, - ...validate(v), - })); - - setPending(list); - }, - [update, validate, availableLanguages] - ); - - const modify = useCallback( - (index: number, info?: PendingSubtitle) => { - setPending((pd) => { - const newPending = [...pd]; - if (info) { - info = { ...info, ...validate(info) }; - newPending[index] = info; - } else { - newPending.splice(index, 1); - } - return newPending; - }); - }, - [validate] - ); - - useEffect(() => { - setPending((pd) => { - const newPd = pd.map((v) => { - if (v.state !== "fetching") { - return { ...v, ...validate(v) }; - } else { - return v; - } - }); - - return newPd; - }); - }, [validate]); - - const columnsWithAction = useMemo>[]>( - () => [ - { - id: "icon", - accessor: "state", - className: "text-center", - Cell: ({ value, row }) => { - let icon = faCircleNotch; - let color: string | undefined = undefined; - let spin = false; - - switch (value) { - case "fetching": - spin = true; - break; - case "warning": - icon = faInfoCircle; - color = "var(--warning)"; - break; - case "valid": - icon = faCheck; - color = "var(--success)"; - break; - default: - icon = faTimes; - color = "var(--danger)"; - break; - } - - const messages = row.original.messages; - - return ( - - ); - }, - }, - { - Header: "File", - accessor: (d) => d.file.name, - }, - { - id: "hi", - Header: "HI", - accessor: "hi", - Cell: ({ row, value }) => { - const { original, index } = row; - const mutate = useRowMutation(); - return ( - { - const newInfo = { ...row.original }; - newInfo.hi = v.target.checked; - mutate(row.index, newInfo); - }} - > - ); - }, - }, - { - id: "forced", - Header: "Forced", - accessor: "forced", - Cell: ({ row, value }) => { - const { original, index } = row; - const mutate = useRowMutation(); - return ( - { - const newInfo = { ...row.original }; - newInfo.forced = v.target.checked; - mutate(row.index, newInfo); - }} - > - ); - }, - }, - { - id: "language", - Header: "Language", - accessor: "language", - className: "w-25", - Cell: ({ row, value }) => { - const mutate = useRowMutation(); - return ( - { - if (lang) { - const newInfo = { ...row.original }; - newInfo.language = lang; - mutate(row.index, newInfo); - } - }} - > - ); - }, - }, - ...columns, - { - id: "action", - accessor: "file", - Cell: ({ row }) => { - const mutate = useRowMutation(); - return ( - - ); - }, - }, - ], - [columns, availableLanguages] - ); - - const canUpload = useMemo( - () => - pending.length > 0 && - pending.every((v) => v.state === "valid" || v.state === "warning"), - [pending] - ); - - const footer = ( -

    -
    - - -
    - -
    - ); - - return ( - - -
    - - - -
    - -
    -
    - ); -} - -export default SubtitleUploader; diff --git a/frontend/src/components/modals/index.ts b/frontend/src/components/modals/index.ts index b5b223abf..526f785dd 100644 --- a/frontend/src/components/modals/index.ts +++ b/frontend/src/components/modals/index.ts @@ -1,4 +1,2 @@ export * from "./HistoryModal"; -export { default as ItemEditorModal } from "./ItemEditorModal"; -export { default as MovieUploadModal } from "./MovieUploadModal"; -export { default as SeriesUploadModal } from "./SeriesUploadModal"; +export { default as SubtitleToolsModal } from "./SubtitleToolsModal"; diff --git a/frontend/src/components/modals/subtitle-tools/ColorTool.tsx b/frontend/src/components/modals/subtitle-tools/ColorTool.tsx deleted file mode 100644 index f110164d4..000000000 --- a/frontend/src/components/modals/subtitle-tools/ColorTool.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import { Selector } from "@/components"; -import { useModal, withModal } from "@/modules/modals"; -import { submodProcessColor } from "@/utilities"; -import { FunctionComponent, useCallback, useState } from "react"; -import { Button } from "react-bootstrap"; -import { useProcess } from "./ToolContext"; -import { colorOptions } from "./tools"; - -const ColorTool: FunctionComponent = () => { - const [selection, setSelection] = useState>(null); - - const Modal = useModal(); - - const process = useProcess(); - - const submit = useCallback(() => { - if (selection) { - const action = submodProcessColor(selection); - process(action); - } - }, [process, selection]); - - const footer = ( - - ); - - return ( - - - - ); -}; - -export default withModal(ColorTool, "color-tool"); diff --git a/frontend/src/components/modals/subtitle-tools/FrameRateTool.tsx b/frontend/src/components/modals/subtitle-tools/FrameRateTool.tsx deleted file mode 100644 index 4c72e4d1b..000000000 --- a/frontend/src/components/modals/subtitle-tools/FrameRateTool.tsx +++ /dev/null @@ -1,65 +0,0 @@ -import { useModal, withModal } from "@/modules/modals"; -import { FunctionComponent, useCallback, useState } from "react"; -import { Button, Form, InputGroup } from "react-bootstrap"; -import { useProcess } from "./ToolContext"; - -function submodProcessFrameRate(from: number, to: number) { - return `change_FPS(from=${from},to=${to})`; -} - -const FrameRateTool: FunctionComponent = () => { - const [from, setFrom] = useState>(null); - const [to, setTo] = useState>(null); - - const canSave = from !== null && to !== null && from !== to; - - const Modal = useModal(); - - const process = useProcess(); - - const submit = useCallback(() => { - if (canSave) { - const action = submodProcessFrameRate(from, to); - process(action); - } - }, [canSave, from, process, to]); - - const footer = ( - - ); - - return ( - - - { - const value = parseFloat(e.currentTarget.value); - if (isNaN(value)) { - setFrom(null); - } else { - setFrom(value); - } - }} - > - { - const value = parseFloat(e.currentTarget.value); - if (isNaN(value)) { - setTo(null); - } else { - setTo(value); - } - }} - > - - - ); -}; - -export default withModal(FrameRateTool, "frame-rate-tool"); diff --git a/frontend/src/components/modals/subtitle-tools/TimeTool.tsx b/frontend/src/components/modals/subtitle-tools/TimeTool.tsx deleted file mode 100644 index 6cbf62f4a..000000000 --- a/frontend/src/components/modals/subtitle-tools/TimeTool.tsx +++ /dev/null @@ -1,100 +0,0 @@ -import { useModal, withModal } from "@/modules/modals"; -import { faMinus, faPlus } from "@fortawesome/free-solid-svg-icons"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { - ChangeEventHandler, - FunctionComponent, - useCallback, - useState, -} from "react"; -import { Button, Form, InputGroup } from "react-bootstrap"; -import { useProcess } from "./ToolContext"; - -function submodProcessOffset(h: number, m: number, s: number, ms: number) { - return `shift_offset(h=${h},m=${m},s=${s},ms=${ms})`; -} - -const TimeAdjustmentTool: FunctionComponent = () => { - const [isPlus, setPlus] = useState(true); - const [offset, setOffset] = useState<[number, number, number, number]>([ - 0, 0, 0, 0, - ]); - - const Modal = useModal(); - - const updateOffset = useCallback( - (idx: number): ChangeEventHandler => { - return (e) => { - let value = parseFloat(e.currentTarget.value); - if (isNaN(value)) { - value = 0; - } - const newOffset = [...offset] as [number, number, number, number]; - newOffset[idx] = value; - setOffset(newOffset); - }; - }, - [offset] - ); - - const canSave = offset.some((v) => v !== 0); - - const process = useProcess(); - - const submit = useCallback(() => { - if (canSave) { - const newOffset = offset.map((v) => (isPlus ? v : -v)); - const action = submodProcessOffset( - newOffset[0], - newOffset[1], - newOffset[2], - newOffset[3] - ); - process(action); - } - }, [canSave, offset, process, isPlus]); - - const footer = ( - - ); - - return ( - - - - - - - - - - - - ); -}; - -export default withModal(TimeAdjustmentTool, "time-adjustment"); diff --git a/frontend/src/components/modals/subtitle-tools/ToolContext.ts b/frontend/src/components/modals/subtitle-tools/ToolContext.ts deleted file mode 100644 index 5f1aecaa7..000000000 --- a/frontend/src/components/modals/subtitle-tools/ToolContext.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { createContext, useContext } from "react"; - -export type ProcessSubtitleType = ( - action: string, - override?: Partial -) => void; - -export const ProcessSubtitleContext = createContext(() => { - throw new Error("ProcessSubtitleContext not initialized"); -}); - -export function useProcess() { - return useContext(ProcessSubtitleContext); -} diff --git a/frontend/src/components/modals/subtitle-tools/Translation.tsx b/frontend/src/components/modals/subtitle-tools/Translation.tsx deleted file mode 100644 index f759f5c29..000000000 --- a/frontend/src/components/modals/subtitle-tools/Translation.tsx +++ /dev/null @@ -1,48 +0,0 @@ -import { LanguageSelector } from "@/components/LanguageSelector"; -import { useModal, withModal } from "@/modules/modals"; -import { useEnabledLanguages } from "@/utilities/languages"; -import { FunctionComponent, useCallback, useMemo, useState } from "react"; -import { Button, Form } from "react-bootstrap"; -import { useProcess } from "./ToolContext"; -import { availableTranslation } from "./tools"; - -const TranslationTool: FunctionComponent = () => { - const { data: languages } = useEnabledLanguages(); - - const available = useMemo( - () => languages.filter((v) => v.code2 in availableTranslation), - [languages] - ); - - const Modal = useModal(); - - const [selectedLanguage, setLanguage] = - useState>(null); - - const process = useProcess(); - - const submit = useCallback(() => { - if (selectedLanguage) { - process("translate", { language: selectedLanguage.code2 }); - } - }, [process, selectedLanguage]); - - const footer = ( - - ); - return ( - - - Enabled languages not listed here are unsupported by Google Translate. - - - - ); -}; - -export default withModal(TranslationTool, "translation-tool"); diff --git a/frontend/src/components/modals/subtitle-tools/index.tsx b/frontend/src/components/modals/subtitle-tools/index.tsx deleted file mode 100644 index e46cb519e..000000000 --- a/frontend/src/components/modals/subtitle-tools/index.tsx +++ /dev/null @@ -1,230 +0,0 @@ -import { useSubtitleAction } from "@/apis/hooks"; -import Language from "@/components/bazarr/Language"; -import { ActionButton, ActionButtonItem } from "@/components/buttons"; -import { SimpleTable } from "@/components/tables"; -import { useCustomSelection } from "@/components/tables/plugins"; -import { - useModal, - useModalControl, - usePayload, - withModal, -} from "@/modules/modals"; -import { createTask, dispatchTask } from "@/modules/task/utilities"; -import { isMovie } from "@/utilities"; -import { LOG } from "@/utilities/console"; -import { isObject } from "lodash"; -import { FunctionComponent, useCallback, useMemo, useState } from "react"; -import { Badge, ButtonGroup, Dropdown } from "react-bootstrap"; -import { Column, useRowSelect } from "react-table"; -import { - ProcessSubtitleContext, - ProcessSubtitleType, - useProcess, -} from "./ToolContext"; -import { tools } from "./tools"; -import { ToolOptions } from "./types"; - -type SupportType = Item.Episode | Item.Movie; - -type TableColumnType = FormType.ModifySubtitle & { - raw_language: Language.Info; -}; - -function getIdAndType(item: SupportType): [number, "episode" | "movie"] { - if (isMovie(item)) { - return [item.radarrId, "movie"]; - } else { - return [item.sonarrEpisodeId, "episode"]; - } -} - -const CanSelectSubtitle = (item: TableColumnType) => { - return item.path.endsWith(".srt"); -}; - -function isElement(value: unknown): value is JSX.Element { - return isObject(value); -} - -interface SubtitleToolViewProps { - count: number; - tools: ToolOptions[]; - select: (items: TableColumnType[]) => void; -} - -const SubtitleToolView: FunctionComponent = ({ - tools, - count, - select, -}) => { - const payload = usePayload(); - - const Modal = useModal({ - size: "lg", - }); - const { show } = useModalControl(); - - const columns: Column[] = useMemo[]>( - () => [ - { - Header: "Language", - accessor: "raw_language", - Cell: ({ value }) => ( - - - - ), - }, - { - id: "file", - Header: "File", - accessor: "path", - Cell: ({ value }) => { - const path = value; - - let idx = path.lastIndexOf("/"); - - if (idx === -1) { - idx = path.lastIndexOf("\\"); - } - - if (idx !== -1) { - return path.slice(idx + 1); - } else { - return path; - } - }, - }, - ], - [] - ); - - const data = useMemo( - () => - payload?.flatMap((item) => { - const [id, type] = getIdAndType(item); - return item.subtitles.flatMap((v) => { - if (v.path !== null) { - return [ - { - id, - type, - language: v.code2, - path: v.path, - raw_language: v, - }, - ]; - } else { - return []; - } - }); - }) ?? [], - [payload] - ); - - const plugins = [useRowSelect, useCustomSelection]; - - const process = useProcess(); - - const footer = useMemo(() => { - const action = tools[0]; - const others = tools.slice(1); - - return ( - k && process(k)}> - process(action.key)} - > - {action.name} - - - - {others.map((v) => ( - { - if (v.modal) { - show(v.modal); - } - }} - > - {v.name} - - ))} - - - ); - }, [count, process, show, tools]); - - return ( - - - - ); -}; - -export const SubtitleToolModal = withModal(SubtitleToolView, "subtitle-tools"); - -const SubtitleTools: FunctionComponent = () => { - const modals = useMemo( - () => - tools - .map((t) => t.modal && ) - .filter(isElement), - [] - ); - - const { hide } = useModalControl(); - const [selections, setSelections] = useState([]); - const { mutateAsync } = useSubtitleAction(); - - const process = useCallback( - (action, override) => { - LOG("info", "executing action", action); - hide(SubtitleToolModal.modalKey); - const tasks = selections.map((s) => { - const form: FormType.ModifySubtitle = { - id: s.id, - type: s.type, - language: s.language, - path: s.path, - ...override, - }; - return createTask(s.path, mutateAsync, { action, form }); - }); - - dispatchTask(tasks, "modify-subtitles"); - }, - [hide, selections, mutateAsync] - ); - - return ( - - - {modals} - - ); -}; - -export default SubtitleTools; diff --git a/frontend/src/components/modals/subtitle-tools/tools.ts b/frontend/src/components/modals/subtitle-tools/tools.ts deleted file mode 100644 index 3b2e86719..000000000 --- a/frontend/src/components/modals/subtitle-tools/tools.ts +++ /dev/null @@ -1,257 +0,0 @@ -import { SelectorOption } from "@/components"; -import { - faClock, - faCode, - faDeaf, - faExchangeAlt, - faFilm, - faImage, - faLanguage, - faMagic, - faPaintBrush, - faPlay, - faTextHeight, -} from "@fortawesome/free-solid-svg-icons"; -import ColorTool from "./ColorTool"; -import FrameRateTool from "./FrameRateTool"; -import TimeTool from "./TimeTool"; -import Translation from "./Translation"; -import { ToolOptions } from "./types"; - -export const tools: ToolOptions[] = [ - { - key: "sync", - icon: faPlay, - name: "Sync", - }, - { - key: "remove_HI", - icon: faDeaf, - name: "Remove HI Tags", - }, - { - key: "remove_tags", - icon: faCode, - name: "Remove Style Tags", - }, - { - key: "OCR_fixes", - icon: faImage, - name: "OCR Fixes", - }, - { - key: "common", - icon: faMagic, - name: "Common Fixes", - }, - { - key: "fix_uppercase", - icon: faTextHeight, - name: "Fix Uppercase", - }, - { - key: "reverse_rtl", - icon: faExchangeAlt, - name: "Reverse RTL", - }, - { - key: "add_color", - icon: faPaintBrush, - name: "Add Color", - modal: ColorTool, - }, - { - key: "change_frame_rate", - icon: faFilm, - name: "Change Frame Rate", - modal: FrameRateTool, - }, - { - key: "adjust_time", - icon: faClock, - name: "Adjust Times", - modal: TimeTool, - }, - { - key: "translation", - icon: faLanguage, - name: "Translate", - modal: Translation, - }, -]; - -export const availableTranslation = { - af: "afrikaans", - sq: "albanian", - am: "amharic", - ar: "arabic", - hy: "armenian", - az: "azerbaijani", - eu: "basque", - be: "belarusian", - bn: "bengali", - bs: "bosnian", - bg: "bulgarian", - ca: "catalan", - ceb: "cebuano", - ny: "chichewa", - zh: "chinese (simplified)", - zt: "chinese (traditional)", - co: "corsican", - hr: "croatian", - cs: "czech", - da: "danish", - nl: "dutch", - en: "english", - eo: "esperanto", - et: "estonian", - tl: "filipino", - fi: "finnish", - fr: "french", - fy: "frisian", - gl: "galician", - ka: "georgian", - de: "german", - el: "greek", - gu: "gujarati", - ht: "haitian creole", - ha: "hausa", - haw: "hawaiian", - iw: "hebrew", - hi: "hindi", - hmn: "hmong", - hu: "hungarian", - is: "icelandic", - ig: "igbo", - id: "indonesian", - ga: "irish", - it: "italian", - ja: "japanese", - jw: "javanese", - kn: "kannada", - kk: "kazakh", - km: "khmer", - ko: "korean", - ku: "kurdish (kurmanji)", - ky: "kyrgyz", - lo: "lao", - la: "latin", - lv: "latvian", - lt: "lithuanian", - lb: "luxembourgish", - mk: "macedonian", - mg: "malagasy", - ms: "malay", - ml: "malayalam", - mt: "maltese", - mi: "maori", - mr: "marathi", - mn: "mongolian", - my: "myanmar (burmese)", - ne: "nepali", - no: "norwegian", - ps: "pashto", - fa: "persian", - pl: "polish", - pt: "portuguese", - pa: "punjabi", - ro: "romanian", - ru: "russian", - sm: "samoan", - gd: "scots gaelic", - sr: "serbian", - st: "sesotho", - sn: "shona", - sd: "sindhi", - si: "sinhala", - sk: "slovak", - sl: "slovenian", - so: "somali", - es: "spanish", - su: "sundanese", - sw: "swahili", - sv: "swedish", - tg: "tajik", - ta: "tamil", - te: "telugu", - th: "thai", - tr: "turkish", - uk: "ukrainian", - ur: "urdu", - uz: "uzbek", - vi: "vietnamese", - cy: "welsh", - xh: "xhosa", - yi: "yiddish", - yo: "yoruba", - zu: "zulu", - fil: "Filipino", - he: "Hebrew", -}; - -export const colorOptions: SelectorOption[] = [ - { - label: "White", - value: "white", - }, - { - label: "Light Gray", - value: "light-gray", - }, - { - label: "Red", - value: "red", - }, - { - label: "Green", - value: "green", - }, - { - label: "Yellow", - value: "yellow", - }, - { - label: "Blue", - value: "blue", - }, - { - label: "Magenta", - value: "magenta", - }, - { - label: "Cyan", - value: "cyan", - }, - { - label: "Black", - value: "black", - }, - { - label: "Dark Red", - value: "dark-red", - }, - { - label: "Dark Green", - value: "dark-green", - }, - { - label: "Dark Yellow", - value: "dark-yellow", - }, - { - label: "Dark Blue", - value: "dark-blue", - }, - { - label: "Dark Magenta", - value: "dark-magenta", - }, - { - label: "Dark Cyan", - value: "dark-cyan", - }, - { - label: "Dark Grey", - value: "dark-grey", - }, -]; diff --git a/frontend/src/components/modals/subtitle-tools/types.d.ts b/frontend/src/components/modals/subtitle-tools/types.d.ts deleted file mode 100644 index 338ba2231..000000000 --- a/frontend/src/components/modals/subtitle-tools/types.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { ModalComponent } from "@/modules/modals/WithModal"; -import { IconDefinition } from "@fortawesome/free-solid-svg-icons"; - -export interface ToolOptions { - key: string; - icon: IconDefinition; - name: string; - modal?: ModalComponent; -} diff --git a/frontend/src/components/tables/BaseTable.tsx b/frontend/src/components/tables/BaseTable.tsx index e2203128a..a3ba1a2f3 100644 --- a/frontend/src/components/tables/BaseTable.tsx +++ b/frontend/src/components/tables/BaseTable.tsx @@ -1,77 +1,44 @@ -import { useMemo } from "react"; -import { Table } from "react-bootstrap"; -import { - HeaderGroup, - Row, - TableBodyProps, - TableOptions, - TableProps, -} from "react-table"; +import { useIsLoading } from "@/contexts"; +import { usePageSize } from "@/utilities/storage"; +import { Box, createStyles, Skeleton, Table, Text } from "@mantine/core"; +import { ReactNode, useMemo } from "react"; +import { HeaderGroup, Row, TableInstance } from "react-table"; -export interface BaseTableProps extends TableStyleProps { - // Table Options - headers: HeaderGroup[]; - rows: Row[]; - headersRenderer?: (headers: HeaderGroup[]) => JSX.Element[]; - rowRenderer?: (row: Row) => Nullable; - prepareRow: (row: Row) => void; - tableProps: TableProps; - tableBodyProps: TableBodyProps; -} +export type BaseTableProps = TableInstance & { + tableStyles?: TableStyleProps; +}; export interface TableStyleProps { emptyText?: string; - responsive?: boolean; - hoverable?: boolean; striped?: boolean; - borderless?: boolean; - small?: boolean; + placeholder?: number; hideHeader?: boolean; + fixHeader?: boolean; headersRenderer?: (headers: HeaderGroup[]) => JSX.Element[]; rowRenderer?: (row: Row) => Nullable; } -interface ExtractResult { - style: TableStyleProps; - options: TableOptions; -} - -export function useStyleAndOptions( - props: TableStyleProps & TableOptions -): ExtractResult { - const { - emptyText, - responsive, - hoverable, - striped, - borderless, - small, - hideHeader, - headersRenderer, - rowRenderer, - ...options - } = props; +const useStyles = createStyles((theme) => { return { - style: { - emptyText, - responsive, - hoverable, - striped, - borderless, - small, - hideHeader, - headersRenderer, - rowRenderer, + container: { + display: "block", + maxWidth: "100%", + overflowX: "auto", + }, + table: { + borderCollapse: "collapse", }, - options, + header: {}, }; -} +}); function DefaultHeaderRenderer( headers: HeaderGroup[] ): JSX.Element[] { return headers.map((col) => ( - {col.render("Header")} + + {col.render("Header")} + )); } @@ -79,9 +46,7 @@ function DefaultRowRenderer(row: Row): JSX.Element | null { return ( {row.cells.map((cell) => ( - - {cell.render("Cell")} - + {cell.render("Cell")} ))} ); @@ -89,65 +54,73 @@ function DefaultRowRenderer(row: Row): JSX.Element | null { export default function BaseTable(props: BaseTableProps) { const { - emptyText, - responsive, - hoverable, - striped, - borderless, - small, - hideHeader, - - headers, + headerGroups, rows, - headersRenderer, - rowRenderer, prepareRow, - tableProps, - tableBodyProps, + getTableProps, + getTableBodyProps, + tableStyles, } = props; + const headersRenderer = tableStyles?.headersRenderer ?? DefaultHeaderRenderer; + const rowRenderer = tableStyles?.rowRenderer ?? DefaultRowRenderer; + + const { classes } = useStyles(); + const colCount = useMemo(() => { - return headers.reduce( + return headerGroups.reduce( (prev, curr) => (curr.headers.length > prev ? curr.headers.length : prev), 0 ); - }, [headers]); + }, [headerGroups]); const empty = rows.length === 0; - const hRenderer = headersRenderer ?? DefaultHeaderRenderer; - const rRenderer = rowRenderer ?? DefaultRowRenderer; + const [pageSize] = usePageSize(); + const isLoading = useIsLoading(); + + let body: ReactNode; + if (isLoading) { + body = Array(tableStyles?.placeholder ?? pageSize) + .fill(0) + .map((_, i) => ( + + + + + + )); + } else if (empty && tableStyles?.emptyText) { + body = ( + + + {tableStyles.emptyText} + + + ); + } else { + body = rows.map((row) => { + prepareRow(row); + return rowRenderer(row); + }); + } return ( - - - {headers.map((headerGroup) => ( - - {hRenderer(headerGroup.headers)} - - ))} - - - {emptyText && empty ? ( - - - - ) : ( - rows.map((row) => { - prepareRow(row); - return rRenderer(row); - }) - )} - -
    - {emptyText} -
    + + + + {headerGroups.map((headerGroup) => ( + + {headersRenderer(headerGroup.headers)} + + ))} + + {body} +
    +
    ); } diff --git a/frontend/src/components/tables/GroupTable.tsx b/frontend/src/components/tables/GroupTable.tsx index 6940b95a1..3d31bfcf2 100644 --- a/frontend/src/components/tables/GroupTable.tsx +++ b/frontend/src/components/tables/GroupTable.tsx @@ -1,21 +1,20 @@ import { faChevronCircleRight } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { Box, Text } from "@mantine/core"; import { Cell, HeaderGroup, Row, - TableOptions, useExpanded, useGroupBy, useSortBy, } from "react-table"; -import { TableStyleProps } from "./BaseTable"; -import SimpleTable from "./SimpleTable"; +import SimpleTable, { SimpleTableProps } from "./SimpleTable"; function renderCell(cell: Cell, row: Row) { if (cell.isGrouped) { return ( - {cell.render("Cell")} +
    {cell.render("Cell")}
    ); } else if (row.canExpand || cell.isAggregated) { return null; @@ -31,22 +30,16 @@ function renderRow(row: Row) { const rotation = row.isExpanded ? 90 : undefined; return ( - - + + {cell.render("Cell")} - - + + + + ); @@ -59,9 +52,7 @@ function renderRow(row: Row) { {row.cells .filter((cell) => !cell.isPlaceholder) .map((cell) => ( - - {renderCell(cell, row)} - + {renderCell(cell, row)} ))} ); @@ -76,16 +67,19 @@ function renderHeaders( .map((col) => {col.render("Header")}); } -type Props = TableOptions & TableStyleProps; +type Props = Omit< + SimpleTableProps, + "plugins" | "headersRenderer" | "rowRenderer" +>; + +const plugins = [useGroupBy, useSortBy, useExpanded]; function GroupTable(props: Props) { - const plugins = [useGroupBy, useSortBy, useExpanded]; return ( ); } diff --git a/frontend/src/components/tables/PageControl.tsx b/frontend/src/components/tables/PageControl.tsx index 3408341a2..5c7bb41ba 100644 --- a/frontend/src/components/tables/PageControl.tsx +++ b/frontend/src/components/tables/PageControl.tsx @@ -1,17 +1,12 @@ -import { FunctionComponent, useMemo } from "react"; -import { Col, Container, Pagination, Row } from "react-bootstrap"; -import { PageControlAction } from "./types"; +import { useIsLoading } from "@/contexts"; +import { Group, Pagination, Text } from "@mantine/core"; +import { FunctionComponent } from "react"; interface Props { count: number; index: number; size: number; total: number; - canPrevious: boolean; - previous: () => void; - canNext: boolean; - next: () => void; goto: (idx: number) => void; - loadState?: PageControlAction; } const PageControl: FunctionComponent = ({ @@ -19,77 +14,28 @@ const PageControl: FunctionComponent = ({ index, size, total, - canPrevious, - previous, - canNext, - next, goto, - loadState, }) => { const empty = total === 0; const start = empty ? 0 : size * index + 1; const end = Math.min(size * (index + 1), total); - const loading = loadState !== undefined; - - const pageButtons = useMemo( - () => - [...Array(count).keys()] - .map((idx) => { - if (Math.abs(idx - index) >= 4 && idx !== 0 && idx !== count - 1) { - return null; - } else { - return ( - goto(idx)} - > - {idx + 1} - - ); - } - }) - .flatMap((item, idx, arr) => { - if (item === null) { - if (arr[idx + 1] === null) { - return []; - } else { - return ( - - ); - } - } else { - return [item]; - } - }), - [count, index, goto, loading] - ); + const isLoading = useIsLoading(); return ( - - - - - Show {start} to {end} of {total} entries - - - - - - - + + + Show {start} to {end} of {total} entries + + goto(page - 1)} + hidden={count <= 1} + total={count} + > + ); }; diff --git a/frontend/src/components/tables/PageTable.tsx b/frontend/src/components/tables/PageTable.tsx index 30a18fff8..0df1959e4 100644 --- a/frontend/src/components/tables/PageTable.tsx +++ b/frontend/src/components/tables/PageTable.tsx @@ -1,74 +1,44 @@ import { ScrollToTop } from "@/utilities"; -import { useEffect } from "react"; -import { PluginHook, TableOptions, usePagination, useTable } from "react-table"; -import BaseTable, { TableStyleProps, useStyleAndOptions } from "./BaseTable"; +import { useEffect, useRef } from "react"; +import { TableInstance, usePagination } from "react-table"; import PageControl from "./PageControl"; import { useDefaultSettings } from "./plugins"; +import SimpleTable, { SimpleTableProps } from "./SimpleTable"; -type Props = TableOptions & - TableStyleProps & { - autoScroll?: boolean; - plugins?: PluginHook[]; - }; +type Props = SimpleTableProps & { + autoScroll?: boolean; +}; + +const tablePlugins = [useDefaultSettings, usePagination]; export default function PageTable(props: Props) { const { autoScroll, plugins, ...remain } = props; - const { style, options } = useStyleAndOptions(remain); - - const allPlugins: PluginHook[] = [useDefaultSettings, usePagination]; - - if (plugins) { - allPlugins.push(...plugins); - } - - const instance = useTable(options, ...allPlugins); - - const { - getTableProps, - getTableBodyProps, - headerGroups, - rows, - prepareRow, - // page - page, - canNextPage, - canPreviousPage, - pageCount, - gotoPage, - nextPage, - previousPage, - state: { pageIndex, pageSize }, - } = instance; + const instance = useRef | null>(null); // Scroll to top when page is changed useEffect(() => { if (autoScroll) { ScrollToTop(); } - }, [pageIndex, autoScroll]); + }, [instance.current?.state.pageIndex, autoScroll]); return ( <> - - + + {instance.current && ( + + )} ); } diff --git a/frontend/src/components/tables/QueryPageTable.tsx b/frontend/src/components/tables/QueryPageTable.tsx index 0ca26dd3b..81eccee13 100644 --- a/frontend/src/components/tables/QueryPageTable.tsx +++ b/frontend/src/components/tables/QueryPageTable.tsx @@ -1,77 +1,37 @@ import { UsePaginationQueryResult } from "@/apis/queries/hooks"; +import { LoadingProvider } from "@/contexts"; import { ScrollToTop } from "@/utilities"; import { useEffect } from "react"; -import { PluginHook, TableOptions, useTable } from "react-table"; -import { LoadingIndicator } from ".."; -import BaseTable, { TableStyleProps, useStyleAndOptions } from "./BaseTable"; import PageControl from "./PageControl"; -import { useDefaultSettings } from "./plugins"; +import SimpleTable, { SimpleTableProps } from "./SimpleTable"; -type Props = TableOptions & - TableStyleProps & { - plugins?: PluginHook[]; - query: UsePaginationQueryResult; - }; +type Props = Omit, "data"> & { + query: UsePaginationQueryResult; +}; export default function QueryPageTable(props: Props) { - const { plugins, query, ...remain } = props; - const { style, options } = useStyleAndOptions(remain); + const { query, ...remain } = props; const { - data, - isLoading, - paginationStatus: { - page, - pageCount, - totalCount, - canPrevious, - canNext, - pageSize, - }, - controls: { previousPage, nextPage, gotoPage }, + data = { data: [], total: 0 }, + paginationStatus: { page, pageCount, totalCount, pageSize, isPageLoading }, + controls: { gotoPage }, } = query; - const instance = useTable( - { - ...options, - data: data?.data ?? [], - }, - useDefaultSettings, - ...(plugins ?? []) - ); - - const { getTableProps, getTableBodyProps, headerGroups, rows, prepareRow } = - instance; - useEffect(() => { ScrollToTop(); }, [page]); - if (isLoading) { - return ; - } - return ( - <> - + + - + ); } diff --git a/frontend/src/components/tables/SimpleTable.tsx b/frontend/src/components/tables/SimpleTable.tsx index 70b57381c..d2beb9630 100644 --- a/frontend/src/components/tables/SimpleTable.tsx +++ b/frontend/src/components/tables/SimpleTable.tsx @@ -1,29 +1,23 @@ -import { PluginHook, TableOptions, useTable } from "react-table"; -import BaseTable, { TableStyleProps, useStyleAndOptions } from "./BaseTable"; +import { PluginHook, TableInstance, TableOptions, useTable } from "react-table"; +import BaseTable, { TableStyleProps } from "./BaseTable"; import { useDefaultSettings } from "./plugins"; -type Props = TableOptions & - TableStyleProps & { - plugins?: PluginHook[]; - }; +export type SimpleTableProps = TableOptions & { + plugins?: PluginHook[]; + instanceRef?: React.MutableRefObject | null>; + tableStyles?: TableStyleProps; +}; -export default function SimpleTable(props: Props) { - const { plugins, ...other } = props; - const { style, options } = useStyleAndOptions(other); +export default function SimpleTable( + props: SimpleTableProps +) { + const { plugins, instanceRef, tableStyles, ...options } = props; const instance = useTable(options, useDefaultSettings, ...(plugins ?? [])); - const { getTableProps, getTableBodyProps, headerGroups, rows, prepareRow } = - instance; + if (instanceRef) { + instanceRef.current = instance; + } - return ( - - ); + return ; } diff --git a/frontend/src/components/tables/plugins/useCustomSelection.tsx b/frontend/src/components/tables/plugins/useCustomSelection.tsx index 650c161fd..9099da677 100644 --- a/frontend/src/components/tables/plugins/useCustomSelection.tsx +++ b/frontend/src/components/tables/plugins/useCustomSelection.tsx @@ -1,5 +1,5 @@ +import { Checkbox as MantineCheckbox } from "@mantine/core"; import { forwardRef, useEffect, useRef } from "react"; -import { Form } from "react-bootstrap"; import { CellProps, Column, @@ -41,13 +41,12 @@ const Checkbox = forwardRef< }, [resolvedRef, indeterminate, checked, disabled]); return ( - + > ); }); diff --git a/frontend/src/components/tables/types.d.ts b/frontend/src/components/tables/types.d.ts deleted file mode 100644 index 611fe387a..000000000 --- a/frontend/src/components/tables/types.d.ts +++ /dev/null @@ -1 +0,0 @@ -export type PageControlAction = "prev" | "next" | number; diff --git a/frontend/src/components/toolbox/Button.tsx b/frontend/src/components/toolbox/Button.tsx new file mode 100644 index 000000000..b167ef119 --- /dev/null +++ b/frontend/src/components/toolbox/Button.tsx @@ -0,0 +1,65 @@ +import { IconDefinition } from "@fortawesome/fontawesome-svg-core"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { Button, ButtonProps, Text } from "@mantine/core"; +import { + FunctionComponent, + PropsWithChildren, + useCallback, + useState, +} from "react"; + +type ToolboxButtonProps = Omit< + ButtonProps<"button">, + "color" | "variant" | "leftIcon" +> & { + icon: IconDefinition; + children: string; +}; + +const ToolboxButton: FunctionComponent = ({ + icon, + children, + ...props +}) => { + return ( + + ); +}; + +type ToolboxMutateButtonProps Promise> = { + promise: T; + onSuccess?: (item: R) => void; +} & Omit; + +export function ToolboxMutateButton Promise>( + props: PropsWithChildren> +): JSX.Element { + const { promise, onSuccess, ...button } = props; + + const [loading, setLoading] = useState(false); + + const click = useCallback(() => { + setLoading(true); + promise().then((val) => { + setLoading(false); + onSuccess && onSuccess(val); + }); + }, [onSuccess, promise]); + + return ( + + ); +} + +export default ToolboxButton; diff --git a/frontend/src/components/toolbox/index.tsx b/frontend/src/components/toolbox/index.tsx new file mode 100644 index 000000000..56f3463de --- /dev/null +++ b/frontend/src/components/toolbox/index.tsx @@ -0,0 +1,31 @@ +import { createStyles, Group } from "@mantine/core"; +import { FunctionComponent } from "react"; +import ToolboxButton, { ToolboxMutateButton } from "./Button"; + +const useStyles = createStyles((theme) => ({ + group: { + backgroundColor: + theme.colorScheme === "light" + ? theme.colors.gray[3] + : theme.colors.dark[5], + }, +})); + +declare type ToolboxComp = FunctionComponent & { + Button: typeof ToolboxButton; + MutateButton: typeof ToolboxMutateButton; +}; + +const Toolbox: ToolboxComp = ({ children }) => { + const { classes } = useStyles(); + return ( + + {children} + + ); +}; + +Toolbox.Button = ToolboxButton; +Toolbox.MutateButton = ToolboxMutateButton; + +export default Toolbox; diff --git a/frontend/src/components/views/HistoryView.tsx b/frontend/src/components/views/HistoryView.tsx deleted file mode 100644 index fa0bf625f..000000000 --- a/frontend/src/components/views/HistoryView.tsx +++ /dev/null @@ -1,35 +0,0 @@ -import { UsePaginationQueryResult } from "@/apis/queries/hooks"; -import { Container, Row } from "react-bootstrap"; -import { Helmet } from "react-helmet"; -import { Column } from "react-table"; -import { QueryPageTable } from ".."; - -interface Props { - name: string; - query: UsePaginationQueryResult; - columns: Column[]; -} - -function HistoryView({ - columns, - name, - query, -}: Props) { - return ( - - - {name} History - Bazarr - - - - - - ); -} - -export default HistoryView; diff --git a/frontend/src/constants.ts b/frontend/src/constants.ts new file mode 100644 index 000000000..8defd1ad9 --- /dev/null +++ b/frontend/src/constants.ts @@ -0,0 +1,9 @@ +import { MantineNumberSize } from "@mantine/core"; + +export const GithubRepoRoot = "https://github.com/morpheus65535/bazarr"; + +export const Layout = { + NAVBAR_WIDTH: 200, + HEADER_HEIGHT: 64, + MOBILE_BREAKPOINT: "sm" as MantineNumberSize, +}; diff --git a/frontend/src/contexts/Loading.ts b/frontend/src/contexts/Loading.ts new file mode 100644 index 000000000..cb6a9f975 --- /dev/null +++ b/frontend/src/contexts/Loading.ts @@ -0,0 +1,11 @@ +import { createContext, useContext } from "react"; + +const LoadingContext = createContext(false); + +export function useIsLoading() { + const context = useContext(LoadingContext); + + return context; +} + +export default LoadingContext.Provider; diff --git a/frontend/src/contexts/Navbar.ts b/frontend/src/contexts/Navbar.ts new file mode 100644 index 000000000..83e36fddb --- /dev/null +++ b/frontend/src/contexts/Navbar.ts @@ -0,0 +1,18 @@ +import { createContext, useContext } from "react"; + +const NavbarContext = createContext<{ + showed: boolean; + show: (showed: boolean) => void; +} | null>(null); + +export function useNavbar() { + const context = useContext(NavbarContext); + + if (context === null) { + throw new Error("NavbarShowedContext not initialized"); + } + + return context; +} + +export default NavbarContext.Provider; diff --git a/frontend/src/contexts/Online.ts b/frontend/src/contexts/Online.ts new file mode 100644 index 000000000..5759a814c --- /dev/null +++ b/frontend/src/contexts/Online.ts @@ -0,0 +1,28 @@ +import { createContext, useContext } from "react"; + +const OnlineContext = createContext<{ + online: boolean; + setOnline: (online: boolean) => void; +} | null>(null); + +export function useIsOnline() { + const context = useContext(OnlineContext); + + if (context === null) { + throw new Error("useIsOnline must be used within a OnlineProvider"); + } + + return context.online; +} + +export function useSetOnline() { + const context = useContext(OnlineContext); + + if (context === null) { + throw new Error("useSetOnline must be used within a OnlineProvider"); + } + + return context.setOnline; +} + +export default OnlineContext.Provider; diff --git a/frontend/src/contexts/index.ts b/frontend/src/contexts/index.ts new file mode 100644 index 000000000..969ff6c6b --- /dev/null +++ b/frontend/src/contexts/index.ts @@ -0,0 +1,2 @@ +export * from "./Loading"; +export { default as LoadingProvider } from "./Loading"; diff --git a/frontend/src/dom.tsx b/frontend/src/dom.tsx index f7bd13f90..8af806070 100644 --- a/frontend/src/dom.tsx +++ b/frontend/src/dom.tsx @@ -1,4 +1,10 @@ +import { StrictMode } from "react"; import ReactDOM from "react-dom"; -import { Entrance } from "."; +import { Main } from "./main"; -ReactDOM.render(, document.getElementById("root")); +ReactDOM.render( + +
    + , + document.getElementById("root") +); diff --git a/frontend/src/index.tsx b/frontend/src/index.tsx deleted file mode 100644 index 5a99d2f48..000000000 --- a/frontend/src/index.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import queryClient from "@/apis/queries"; -import store from "@/modules/redux/store"; -import "@/styles/index.scss"; -import "@fontsource/roboto/300.css"; -import { QueryClientProvider } from "react-query"; -import { ReactQueryDevtools } from "react-query/devtools"; -import { Provider } from "react-redux"; -import { useRoutes } from "react-router-dom"; -import { Router, useRouteItems } from "./Router"; -import { Environment } from "./utilities"; - -const RouteApp = () => { - const items = useRouteItems(); - - return useRoutes(items); -}; - -export const Entrance = () => ( - - - - {/* TODO: Enabled Strict Mode after react-bootstrap upgrade to bootstrap 5 */} - {/* */} - {Environment.queryDev && } - - {/* */} - - - -); diff --git a/frontend/src/main.tsx b/frontend/src/main.tsx new file mode 100644 index 000000000..aceab4752 --- /dev/null +++ b/frontend/src/main.tsx @@ -0,0 +1,35 @@ +import queryClient from "@/apis/queries"; +import ThemeProvider from "@/App/theme"; +import { ModalsProvider } from "@/modules/modals"; +import "@fontsource/roboto/300.css"; +import { NotificationsProvider } from "@mantine/notifications"; +import { QueryClientProvider } from "react-query"; +import { ReactQueryDevtools } from "react-query/devtools"; +import { useRoutes } from "react-router-dom"; +import { Router, useRouteItems } from "./Router"; +import { Environment } from "./utilities"; + +const RouteApp = () => { + const items = useRouteItems(); + + return useRoutes(items); +}; + +export const Main = () => { + return ( + + + + + + {Environment.queryDev && ( + + )} + + + + + + + ); +}; diff --git a/frontend/src/modules/modals/ModalContext.ts b/frontend/src/modules/modals/ModalContext.ts deleted file mode 100644 index 81e7fba86..000000000 --- a/frontend/src/modules/modals/ModalContext.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { createContext, Dispatch, SetStateAction } from "react"; - -export interface ModalData { - key: string; - closeable: boolean; - size: "sm" | "lg" | "xl" | undefined; -} - -export type ModalSetter = { - [P in keyof Omit]: Dispatch>; -}; - -export const ModalDataContext = createContext(null); -export const ModalSetterContext = createContext(null); diff --git a/frontend/src/modules/modals/ModalWrapper.tsx b/frontend/src/modules/modals/ModalWrapper.tsx deleted file mode 100644 index aeb176604..000000000 --- a/frontend/src/modules/modals/ModalWrapper.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import clsx from "clsx"; -import { FunctionComponent, useCallback, useState } from "react"; -import { Modal } from "react-bootstrap"; -import { useCurrentLayer, useModalControl, useModalData } from "./hooks"; - -interface Props {} - -export const ModalWrapper: FunctionComponent = ({ children }) => { - const { size, closeable, key } = useModalData(); - const [needExit, setExit] = useState(false); - - const { hide: hideModal } = useModalControl(); - - const layer = useCurrentLayer(); - const isShowed = layer !== -1; - - const hide = useCallback(() => { - setExit(true); - }, []); - - const exit = useCallback(() => { - if (isShowed) { - hideModal(key); - } - setExit(false); - }, [isShowed, hideModal, key]); - - return ( - - {children} - - ); -}; - -export default ModalWrapper; diff --git a/frontend/src/modules/modals/ModalsProvider.tsx b/frontend/src/modules/modals/ModalsProvider.tsx new file mode 100644 index 000000000..d7724542c --- /dev/null +++ b/frontend/src/modules/modals/ModalsProvider.tsx @@ -0,0 +1,34 @@ +import { + ModalsProvider as MantineModalsProvider, + ModalsProviderProps as MantineModalsProviderProps, +} from "@mantine/modals"; +import { FunctionComponent, useMemo } from "react"; +import { ModalComponent, StaticModals } from "./WithModal"; + +const DefaultModalProps: MantineModalsProviderProps["modalProps"] = { + centered: true, + styles: { + modal: { + maxWidth: "100%", + }, + }, +}; + +const ModalsProvider: FunctionComponent = ({ children }) => { + const modals = useMemo( + () => + StaticModals.reduce>((prev, curr) => { + prev[curr.modalKey] = curr; + return prev; + }, {}), + [] + ); + + return ( + + {children} + + ); +}; + +export default ModalsProvider; diff --git a/frontend/src/modules/modals/WithModal.tsx b/frontend/src/modules/modals/WithModal.tsx index 0d09e14e2..c8de266f9 100644 --- a/frontend/src/modules/modals/WithModal.tsx +++ b/frontend/src/modules/modals/WithModal.tsx @@ -1,52 +1,36 @@ -import { FunctionComponent, useMemo, useState } from "react"; -import { - ModalData, - ModalDataContext, - ModalSetter, - ModalSetterContext, -} from "./ModalContext"; -import ModalWrapper from "./ModalWrapper"; +/* eslint-disable @typescript-eslint/ban-types */ -export interface ModalProps {} +import { ContextModalProps } from "@mantine/modals"; +import { ModalSettings } from "@mantine/modals/lib/context"; +import { createContext, FunctionComponent } from "react"; -export type ModalComponent

    = FunctionComponent

    & { - modalKey: string; -}; +export type ModalComponent

    = {}> = + FunctionComponent> & { + modalKey: string; + settings?: ModalSettings; + }; + +export const StaticModals: ModalComponent[] = []; -export default function withModal( +export const ModalIdContext = createContext(null); + +export default function withModal( Content: FunctionComponent, - key: string + key: string, + defaultSettings?: ModalSettings ) { - const Comp: ModalComponent = (props: ModalProps & T) => { - const [closeable, setCloseable] = useState(true); - const [size, setSize] = useState(undefined); - const data: ModalData = useMemo( - () => ({ - key, - size, - closeable, - }), - [closeable, size] - ); - - const setter: ModalSetter = useMemo( - () => ({ - closeable: setCloseable, - size: setSize, - }), - [] - ); + const Comp: ModalComponent = (props) => { + const { id, innerProps } = props; return ( - - - - - - - + + + ); }; Comp.modalKey = key; + Comp.settings = defaultSettings; + + StaticModals.push(Comp as ModalComponent); return Comp; } diff --git a/frontend/src/modules/modals/components.tsx b/frontend/src/modules/modals/components.tsx deleted file mode 100644 index 171f19d3c..000000000 --- a/frontend/src/modules/modals/components.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import { FunctionComponent, ReactNode } from "react"; -import { Modal } from "react-bootstrap"; -import { useModalData } from "./hooks"; - -interface StandardModalProps { - title: string; - footer?: ReactNode; -} - -export const StandardModalView: FunctionComponent = ({ - children, - footer, - title, -}) => { - const { closeable } = useModalData(); - return ( - <> - {title} - {children} - - - ); -}; diff --git a/frontend/src/modules/modals/hooks.ts b/frontend/src/modules/modals/hooks.ts index 03ffe0d9c..3ebdbc0a8 100644 --- a/frontend/src/modules/modals/hooks.ts +++ b/frontend/src/modules/modals/hooks.ts @@ -1,90 +1,46 @@ -import { - hideModalAction, - showModalAction, -} from "@/modules/redux/actions/modal"; -import { useReduxAction, useReduxStore } from "@/modules/redux/hooks/base"; -import { useCallback, useContext, useEffect, useMemo, useRef } from "react"; -import { StandardModalView } from "./components"; -import { - ModalData, - ModalDataContext, - ModalSetterContext, -} from "./ModalContext"; -import { ModalComponent } from "./WithModal"; - -type ModalProps = Partial> & { - onMounted?: () => void; -}; - -export function useModal(props?: ModalProps): typeof StandardModalView { - const setter = useContext(ModalSetterContext); - - useEffect(() => { - if (setter && props) { - setter.closeable(props.closeable ?? true); - setter.size(props.size); - } - }, [props, setter]); - - const ref = useRef(props?.onMounted); - ref.current = props?.onMounted; - - const layer = useCurrentLayer(); - - useEffect(() => { - if (layer !== -1 && ref.current) { - ref.current(); - } - }, [layer]); - - return StandardModalView; -} - -export function useModalControl() { - const showAction = useReduxAction(showModalAction); - - const show = useCallback( -

    (comp: ModalComponent

    , payload?: unknown) => { - showAction({ key: comp.modalKey, payload }); +/* eslint-disable @typescript-eslint/ban-types */ +import { useModals as useMantineModals } from "@mantine/modals"; +import { ModalSettings } from "@mantine/modals/lib/context"; +import { useCallback, useContext, useMemo } from "react"; +import { ModalComponent, ModalIdContext } from "./WithModal"; + +export function useModals() { + const { openContextModal: openMantineContextModal, ...rest } = + useMantineModals(); + + const openContextModal = useCallback( + ( + modal: ModalComponent, + props: ARGS, + settings?: ModalSettings + ) => { + openMantineContextModal(modal.modalKey, { + ...modal.settings, + ...settings, + innerProps: props, + }); }, - [showAction] + [openMantineContextModal] ); - const hideAction = useReduxAction(hideModalAction); - - const hide = useCallback( - (key?: string) => { - hideAction(key); + const closeContextModal = useCallback( + (modal: ModalComponent) => { + rest.closeModal(modal.modalKey); }, - [hideAction] + [rest] ); - return { show, hide }; -} - -export function useModalData(): ModalData { - const data = useContext(ModalDataContext); - - if (data === null) { - throw new Error("useModalData should be used inside Modal"); - } + const id = useContext(ModalIdContext); - return data; -} - -export function usePayload(): T | null { - const { key } = useModalData(); - const stack = useReduxStore((s) => s.modal.stack); + const closeSelf = useCallback(() => { + if (id) { + rest.closeModal(id); + } + }, [id, rest]); + // TODO: Performance return useMemo( - () => (stack.find((m) => m.key === key)?.payload as T) ?? null, - [stack, key] + () => ({ openContextModal, closeContextModal, closeSelf, ...rest }), + [closeContextModal, closeSelf, openContextModal, rest] ); } - -export function useCurrentLayer() { - const { key } = useModalData(); - const stack = useReduxStore((s) => s.modal.stack); - - return useMemo(() => stack.findIndex((m) => m.key === key), [stack, key]); -} diff --git a/frontend/src/modules/modals/index.ts b/frontend/src/modules/modals/index.ts index baaee48b7..852458acd 100644 --- a/frontend/src/modules/modals/index.ts +++ b/frontend/src/modules/modals/index.ts @@ -1,3 +1,3 @@ -export * from "./components"; export * from "./hooks"; +export { default as ModalsProvider } from "./ModalsProvider"; export { default as withModal } from "./WithModal"; diff --git a/frontend/src/modules/modals/modal.test.ts b/frontend/src/modules/modals/modal.test.ts new file mode 100644 index 000000000..b4c80f71f --- /dev/null +++ b/frontend/src/modules/modals/modal.test.ts @@ -0,0 +1,12 @@ +import { describe, it } from "vitest"; +import { StaticModals } from "./WithModal"; + +describe("modal tests", () => { + it.skip("no duplicated modals", () => { + const existedKeys = new Set(); + StaticModals.forEach(({ modalKey }) => { + expect(existedKeys.has(modalKey)).toBeFalsy(); + existedKeys.add(modalKey); + }); + }); +}); diff --git a/frontend/src/modules/redux/actions/index.ts b/frontend/src/modules/redux/actions/index.ts deleted file mode 100644 index d318694c0..000000000 --- a/frontend/src/modules/redux/actions/index.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { createAction, createAsyncThunk } from "@reduxjs/toolkit"; -import { waitFor } from "../../../utilities"; - -export const setSiteStatus = createAction("site/status/update"); - -export const setUnauthenticated = createAction("site/unauthenticated"); - -export const setOfflineStatus = createAction("site/offline/update"); - -export const addNotifications = createAction( - "site/notifications/add" -); - -export const removeNotification = createAction( - "site/notifications/remove" -); - -export const siteAddProgress = - createAction("site/progress/add"); - -export const siteUpdateProgressCount = createAction<{ - id: string; - count: number; -}>("site/progress/update_count"); - -export const siteRemoveProgress = createAsyncThunk( - "site/progress/remove", - async (ids: string[]) => { - await waitFor(3 * 1000); - return ids; - } -); - -export const siteUpdateNotifier = createAction( - "site/progress/update_notifier" -); - -export const setSidebar = createAction("site/sidebar/update"); diff --git a/frontend/src/modules/redux/actions/modal.ts b/frontend/src/modules/redux/actions/modal.ts deleted file mode 100644 index 339642559..000000000 --- a/frontend/src/modules/redux/actions/modal.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { createAction } from "@reduxjs/toolkit"; - -export const showModalAction = createAction("modal/show"); - -export const hideModalAction = createAction("modal/hide"); diff --git a/frontend/src/modules/redux/actions/types.d.ts b/frontend/src/modules/redux/actions/types.d.ts deleted file mode 100644 index 8d74e4a1f..000000000 --- a/frontend/src/modules/redux/actions/types.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { ActionCreator } from "@reduxjs/toolkit"; - -// eslint-disable-next-line @typescript-eslint/no-explicit-any -type AnyActionCreator = ActionCreator; diff --git a/frontend/src/modules/redux/hooks/base.ts b/frontend/src/modules/redux/hooks/base.ts deleted file mode 100644 index 460442b05..000000000 --- a/frontend/src/modules/redux/hooks/base.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { useCallback } from "react"; -import { useDispatch, useSelector } from "react-redux"; -import { AnyActionCreator } from "../actions/types"; -import { AppDispatch, RootState } from "../store"; - -export function useReduxStore(selector: (store: S) => R) { - return useSelector(selector); -} - -export function useAppDispatch() { - return useDispatch(); -} - -export function useReduxAction(action: A) { - const dispatch = useAppDispatch(); - return useCallback( - (...args: Parameters) => dispatch(action(...args)), - [action, dispatch] - ); -} diff --git a/frontend/src/modules/redux/hooks/index.ts b/frontend/src/modules/redux/hooks/index.ts deleted file mode 100644 index ecefb0a86..000000000 --- a/frontend/src/modules/redux/hooks/index.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { useSystemSettings } from "@/apis/hooks"; -import { useCallback } from "react"; -import { addNotifications } from "../actions"; -import { useReduxAction, useReduxStore } from "./base"; - -export function useNotification(id: string, timeout = 5000) { - const add = useReduxAction(addNotifications); - - return useCallback( - (msg: Omit) => { - const notification: Server.Notification = { - ...msg, - id, - timeout, - }; - add([notification]); - }, - [add, timeout, id] - ); -} - -export function useIsOffline() { - return useReduxStore((s) => s.site.offline); -} - -export function useEnabledStatus() { - const { data } = useSystemSettings(); - - return { - sonarr: data?.general.use_sonarr ?? false, - radarr: data?.general.use_radarr ?? false, - }; -} - -export function useShowOnlyDesired() { - const { data } = useSystemSettings(); - return data?.general.embedded_subs_show_desired ?? false; -} diff --git a/frontend/src/modules/redux/reducers/index.ts b/frontend/src/modules/redux/reducers/index.ts deleted file mode 100644 index 4ff710f58..000000000 --- a/frontend/src/modules/redux/reducers/index.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { combineReducers } from "@reduxjs/toolkit"; -import modalReducer from "./modal"; -import siteReducer from "./site"; - -const reducers = combineReducers({ - site: siteReducer, - modal: modalReducer, -}); - -export default reducers; diff --git a/frontend/src/modules/redux/reducers/modal.ts b/frontend/src/modules/redux/reducers/modal.ts deleted file mode 100644 index a7c54684c..000000000 --- a/frontend/src/modules/redux/reducers/modal.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { createReducer } from "@reduxjs/toolkit"; -import { hideModalAction, showModalAction } from "../actions/modal"; - -interface ModalReducer { - stack: Modal.Frame[]; -} - -const reducer = createReducer({ stack: [] }, (builder) => { - builder.addCase(showModalAction, (state, action) => { - state.stack.push(action.payload); - }); - - builder.addCase(hideModalAction, (state, action) => { - const { payload } = action; - if (payload === undefined) { - state.stack.pop(); - } else { - const index = state.stack.findIndex((fr) => fr.key === payload); - if (index !== -1) { - state.stack.splice(index); - } - } - }); -}); - -export default reducer; diff --git a/frontend/src/modules/redux/reducers/site.ts b/frontend/src/modules/redux/reducers/site.ts deleted file mode 100644 index 0fe47baf6..000000000 --- a/frontend/src/modules/redux/reducers/site.ts +++ /dev/null @@ -1,110 +0,0 @@ -import { createReducer } from "@reduxjs/toolkit"; -import { intersectionWith, pullAllWith, remove, sortBy, uniqBy } from "lodash"; -import apis from "../../../apis/queries/client"; -import { isProdEnv } from "../../../utilities"; -import { - addNotifications, - removeNotification, - setOfflineStatus, - setSidebar, - setSiteStatus, - setUnauthenticated, - siteAddProgress, - siteRemoveProgress, - siteUpdateNotifier, - siteUpdateProgressCount, -} from "../actions"; - -interface Site { - // Initialization state or error message - status: Site.Status; - offline: boolean; - progress: Site.Progress[]; - notifier: { - content: string | null; - timestamp: string; - }; - notifications: Server.Notification[]; - showSidebar: boolean; -} - -const defaultSite: Site = { - status: "uninitialized", - progress: [], - notifier: { - content: null, - timestamp: String(Date.now()), - }, - notifications: [], - showSidebar: false, - offline: false, -}; - -const reducer = createReducer(defaultSite, (builder) => { - builder - .addCase(setUnauthenticated, (state) => { - if (!isProdEnv) { - apis._resetApi("NEED_AUTH"); - } - state.status = "unauthenticated"; - }) - .addCase(setSiteStatus, (state, action) => { - state.status = action.payload; - }); - - builder - .addCase(addNotifications, (state, action) => { - state.notifications = uniqBy( - [...action.payload, ...state.notifications], - (v) => v.id - ); - state.notifications = sortBy(state.notifications, (v) => v.id); - }) - .addCase(removeNotification, (state, action) => { - remove(state.notifications, (n) => n.id === action.payload); - }); - - builder - .addCase(siteAddProgress, (state, action) => { - state.progress = uniqBy( - [...action.payload, ...state.progress], - (n) => n.id - ); - state.progress = sortBy(state.progress, (v) => v.id); - }) - .addCase(siteRemoveProgress.pending, (state, action) => { - // Mark completed - intersectionWith( - state.progress, - action.meta.arg, - (l, r) => l.id === r - ).forEach((v) => { - v.value = v.count + 1; - }); - }) - .addCase(siteRemoveProgress.fulfilled, (state, action) => { - pullAllWith(state.progress, action.payload, (l, r) => l.id === r); - }) - .addCase(siteUpdateProgressCount, (state, action) => { - const { id, count } = action.payload; - const progress = state.progress.find((v) => v.id === id); - if (progress) { - progress.count = count; - } - }); - - builder.addCase(siteUpdateNotifier, (state, action) => { - state.notifier.content = action.payload; - state.notifier.timestamp = String(Date.now()); - }); - - builder - .addCase(setSidebar, (state, action) => { - state.showSidebar = action.payload; - }) - .addCase(setOfflineStatus, (state, action) => { - state.offline = action.payload; - }); -}); - -export default reducer; diff --git a/frontend/src/modules/redux/store/index.ts b/frontend/src/modules/redux/store/index.ts deleted file mode 100644 index 0004745e7..000000000 --- a/frontend/src/modules/redux/store/index.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { configureStore } from "@reduxjs/toolkit"; -import apis from "../../../apis/queries/client"; -import reducer from "../reducers"; - -const store = configureStore({ - reducer, -}); - -// FIXME -apis.dispatch = store.dispatch; - -export type AppDispatch = typeof store.dispatch; -export type RootState = ReturnType; - -export default store; diff --git a/frontend/src/modules/socketio/reducer.ts b/frontend/src/modules/socketio/reducer.ts index 4292beaa5..523c71506 100644 --- a/frontend/src/modules/socketio/reducer.ts +++ b/frontend/src/modules/socketio/reducer.ts @@ -1,72 +1,37 @@ +import queryClient from "@/apis/queries"; import { QueryKeys } from "@/apis/queries/keys"; -import queryClient from "../../apis/queries"; -import { - addNotifications, - setOfflineStatus, - setSiteStatus, - siteAddProgress, - siteRemoveProgress, -} from "../redux/actions"; -import { AnyActionCreator } from "../redux/actions/types"; -import reduxStore from "../redux/store"; - -function bindReduxAction(action: T) { - return (...args: Parameters) => { - reduxStore.dispatch(action(...args)); - }; -} - -function bindReduxActionWithParam( - action: T, - ...param: Parameters -) { - return () => { - reduxStore.dispatch(action(...param)); - }; -} +import { setCriticalError, setOnlineStatus } from "@/utilities/event"; +import { showNotification } from "@mantine/notifications"; +import { notification, task } from "../task"; export function createDefaultReducer(): SocketIO.Reducer[] { return [ { key: "connect", - any: bindReduxActionWithParam(setOfflineStatus, false), - }, - { - key: "connect", - any: () => { - // init - reduxStore.dispatch(setSiteStatus("initialized")); - }, + any: () => setOnlineStatus(true), }, { key: "connect_error", any: () => { - reduxStore.dispatch(setSiteStatus("error")); + setCriticalError("Cannot connect to backend"); }, }, { key: "disconnect", - any: bindReduxActionWithParam(setOfflineStatus, true), + any: () => setOnlineStatus(false), }, { key: "message", update: (msg) => { - if (msg) { - const notifications = msg.map((message) => ({ - message, - type: "info", - id: "backend-message", - timeout: 5 * 1000, - })); - - reduxStore.dispatch(addNotifications(notifications)); - } + msg + .map((message) => notification.info("Notification", message)) + .forEach(showNotification); }, }, { key: "progress", - update: bindReduxAction(siteAddProgress), - delete: bindReduxAction(siteRemoveProgress), + update: task.updateProgress.bind(task), + delete: task.removeProgress.bind(task), }, { key: "series", diff --git a/frontend/src/modules/task/group.ts b/frontend/src/modules/task/group.ts index b9cc5115f..cbcbea15b 100644 --- a/frontend/src/modules/task/group.ts +++ b/frontend/src/modules/task/group.ts @@ -1,35 +1,7 @@ -export type GroupName = - | "scan-disk" - | "search-subtitles" - | "download-subtitles" - | "upload-subtitles" - | "modify-subtitles"; - -type TaskGroup = { - [key in GroupName]: Task.Group; -}; - -const TaskGroups: TaskGroup = { - "scan-disk": { - description: "Scanning Disk...", - notify: "Scanning...", - }, - "search-subtitles": { - description: "Searching Subtitles...", - notify: "Searching...", - }, - "download-subtitles": { - description: "Downloading Subtitles...", - notify: "Downloading...", - }, - "upload-subtitles": { - description: "Uploading Subtitles...", - notify: "Uploading...", - }, - "modify-subtitles": { - description: "Modifying Subtitles...", - notify: "Modifying...", - }, -}; - -export default TaskGroups; +export enum TaskGroup { + UploadSubtitle = "Uploading subtitles...", + DownloadSubtitle = "Downloading subtitles...", + DeleteSubtitle = "Deleting subtitles...", + SearchSubtitle = "Searching subtitles...", + ScanDisk = "Scanning disk...", +} diff --git a/frontend/src/modules/task/index.ts b/frontend/src/modules/task/index.ts index 8580ca05c..a1439148c 100644 --- a/frontend/src/modules/task/index.ts +++ b/frontend/src/modules/task/index.ts @@ -1,15 +1,27 @@ -// A background task manager, use for dispatching task one by one -class TaskManager { - private tasks: Task.Callable[] = []; +import { LOG } from "@/utilities/console"; +import { + hideNotification, + showNotification, + updateNotification, +} from "@mantine/notifications"; +import { uniqueId } from "lodash"; +import { notification } from "./notification"; + +class TaskDispatcher { + private running: boolean; + private tasks: Record = {}; + constructor() { - this.tasks = []; + this.running = false; + this.tasks = {}; + window.addEventListener("beforeunload", this.onBeforeUnload.bind(this)); } private onBeforeUnload(e: BeforeUnloadEvent) { const message = "Background tasks are still running"; - if (this.tasks.some((t) => t.status === "running")) { + if (Object.keys(this.tasks).length > 0) { e.preventDefault(); e.returnValue = message; return; @@ -17,45 +29,111 @@ class TaskManager { delete e["returnValue"]; } - private findTask(ref: Task.TaskRef): Task.Callable | undefined { - return this.tasks.find((t) => t.id === ref.callableId); - } + private update() { + if (this.running) { + return; + } - create(fn: T, parameters: Parameters): symbol { - // Clone this function - const newTask = fn.bind({}) as Task.Callable; - newTask.status = "idle"; - newTask.parameters = parameters; - newTask.id = Symbol(this.tasks.length); + LOG("info", "Starting background task queue"); + + this.running = true; + + const queue = window.queueMicrotask?.bind(window) ?? setTimeout; + + queue(async () => { + while (Object.keys(this.tasks).length > 0) { + const groups = Object.keys(this.tasks); + + for await (const group of groups) { + const tasks = this.tasks[group]; + + const taskId = group; + + for (let index = 0; index < tasks.length; index++) { + const task = tasks[index]; - this.tasks.push(newTask); + const notifyInProgress = notification.progress.update( + taskId, + group, + task.description, + index, + tasks.length + ); + updateNotification(notifyInProgress); - return newTask.id; + try { + await task(...task.parameters); + } catch (error) { + // TODO + } + } + + const notifyEnd = notification.progress.end(taskId, group); + updateNotification(notifyEnd); + + delete this.tasks[group]; + } + } + this.running = false; + }); } - async run(taskRef: Task.TaskRef) { - const task = this.findTask(taskRef); + public create( + name: string, + group: string, + callable: T, + ...parameters: Parameters + ): Task.Ref { + // Clone this function + const task = callable.bind({}) as Task.Callable; + task.parameters = parameters; + task.description = name; + task.id = uniqueId("task"); - if (task === undefined) { - throw new Error(`Task ${taskRef.name} not found`); + if (this.tasks[group] === undefined) { + this.tasks[group] = []; + const notifyStart = notification.progress.pending(group, group); + showNotification(notifyStart); } - if (task.status !== "idle") { - return; - } + this.tasks[group].push(task); - task.status = "running"; + this.update(); - try { - await task(...task.parameters); - task.status = "success"; - } catch (err) { - task.status = "failure"; - throw err; - } + return task.id; + } + + public updateProgress(items: Site.Progress[]) { + items.forEach((item) => { + // TODO: FIX ME! + item.value += 1; + + if (item.value >= item.count) { + updateNotification(notification.progress.end(item.id, item.header)); + } else if (item.value > 1) { + updateNotification( + notification.progress.update( + item.id, + item.header, + item.name, + item.value, + item.count + ) + ); + } else { + showNotification(notification.progress.pending(item.id, item.header)); + } + }); } -} -const taskManager = new TaskManager(); + public removeProgress(ids: string[]) { + setTimeout( + () => ids.forEach(hideNotification), + notification.PROGRESS_TIMEOUT + ); + } +} -export default taskManager; +export const task = new TaskDispatcher(); +export * from "./group"; +export * from "./notification"; diff --git a/frontend/src/modules/task/notification.ts b/frontend/src/modules/task/notification.ts new file mode 100644 index 000000000..c2095ab98 --- /dev/null +++ b/frontend/src/modules/task/notification.ts @@ -0,0 +1,61 @@ +import { NotificationProps } from "@mantine/notifications"; + +export const notification = { + info: (title: string, message: string): NotificationProps => { + return { + title, + message, + autoClose: 5 * 1000, + }; + }, + + warn: (title: string, message: string): NotificationProps => { + return { + title, + message, + color: "yellow", + autoClose: 6 * 1000, + }; + }, + + PROGRESS_TIMEOUT: 10 * 1000, + + progress: { + pending: ( + id: string, + header: string + ): NotificationProps & { id: string } => { + return { + id, + title: header, + message: "Starting Tasks...", + color: "gray", + loading: true, + }; + }, + update: ( + id: string, + header: string, + body: string, + current: number, + total: number + ): NotificationProps & { id: string } => { + return { + id, + title: header, + message: `[${current}/${total}] ${body}`, + loading: true, + autoClose: 2 * 60 * 1000, + }; + }, + end: (id: string, header: string): NotificationProps & { id: string } => { + return { + id, + title: header, + message: "All Tasks Completed", + color: "green", + autoClose: 2 * 1000, + }; + }, + }, +}; diff --git a/frontend/src/modules/task/task.d.ts b/frontend/src/modules/task/task.d.ts index 4c7e2add1..507e0b153 100644 --- a/frontend/src/modules/task/task.d.ts +++ b/frontend/src/modules/task/task.d.ts @@ -1,22 +1,11 @@ declare namespace Task { - type Status = "idle" | "running" | "success" | "failure"; - // eslint-disable-next-line @typescript-eslint/no-explicit-any type AnyCallable = (...args: any[]) => Promise; export type Callable = T & { parameters: Parameters; - id: symbol; - status: Status; + description: string; + id: string; }; - export interface TaskRef { - name: string; - callableId: symbol; - description?: string; - } - - export interface Group { - description: string; - notify: string; - } + export type Ref = string; } diff --git a/frontend/src/modules/task/utilities.ts b/frontend/src/modules/task/utilities.ts deleted file mode 100644 index d1deae3a0..000000000 --- a/frontend/src/modules/task/utilities.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { LOG } from "@/utilities/console"; -import taskManager from "."; -import { siteAddProgress, siteRemoveProgress } from "../redux/actions"; -import store from "../redux/store"; -import { GroupName } from "./group"; - -export function createTask( - name: string, - callable: T, - ...parameters: Parameters -): Task.TaskRef { - const callableId = taskManager.create(callable, parameters); - - LOG("info", "task created", name); - - return { - name, - callableId, - }; -} - -export function dispatchTask(tasks: Task.TaskRef[], group: GroupName) { - setTimeout(async () => { - for (let index = 0; index < tasks.length; index++) { - const ref = tasks[index]; - LOG("info", "dispatching task", ref.name); - - store.dispatch( - siteAddProgress([ - { - id: group, - header: group, - name: ref.name, - value: index, - count: tasks.length, - }, - ]) - ); - - await taskManager.run(ref); - } - - // TODO: Also remove from taskManager - store.dispatch(siteRemoveProgress([group])); - }); -} - -export function createAndDispatchTask( - name: string, - group: GroupName, - callable: T, - ...parameters: Parameters -) { - const task = createTask(name, callable, ...parameters); - dispatchTask([task], group); -} diff --git a/frontend/src/pages/404.tsx b/frontend/src/pages/404.tsx deleted file mode 100644 index 12fe005c7..000000000 --- a/frontend/src/pages/404.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import { faEyeSlash as fasEyeSlash } from "@fortawesome/free-regular-svg-icons"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { FunctionComponent } from "react"; -import { Container } from "react-bootstrap"; - -const NotFound: FunctionComponent = () => { - return ( - -

    - - 404 -

    -

    The Request URL No Found

    - - ); -}; - -export default NotFound; diff --git a/frontend/src/pages/Authentication.tsx b/frontend/src/pages/Authentication.tsx index 7139f7b99..efdd1f3ec 100644 --- a/frontend/src/pages/Authentication.tsx +++ b/frontend/src/pages/Authentication.tsx @@ -1,81 +1,59 @@ import { useSystem } from "@/apis/hooks"; -import { useReduxStore } from "@/modules/redux/hooks/base"; import { Environment } from "@/utilities"; -import { FunctionComponent, useState } from "react"; -import { Button, Card, Form, Image, Spinner } from "react-bootstrap"; -import { Navigate } from "react-router-dom"; +import { + Avatar, + Button, + Card, + Container, + Divider, + PasswordInput, + Stack, + TextInput, +} from "@mantine/core"; +import { useForm } from "@mantine/hooks"; +import { FunctionComponent } from "react"; const Authentication: FunctionComponent = () => { - const [username, setUsername] = useState(""); - const [password, setPassword] = useState(""); + const { login } = useSystem(); - const { login, isWorking } = useSystem(); - - const authenticated = useReduxStore( - (s) => s.site.status !== "unauthenticated" - ); - - if (authenticated) { - return ; - } + const form = useForm({ + initialValues: { + username: "", + password: "", + }, + }); return ( -
    - -
    { - e.preventDefault(); - login({ username, password }); - }} - > - - - - - - + + + + + + + setUsername(e.currentTarget.value)} - > - - - + setPassword(e.currentTarget.value)} - > - - {/* -
    - - {error} - -
    -
    */} -
    - - - -
    + placeholder="Password" + {...form.getInputProps("password")} + > + + + + +
    -
    + ); }; diff --git a/frontend/src/pages/Blacklist/Movies/index.tsx b/frontend/src/pages/Blacklist/Movies/index.tsx index 063dab308..67c6a2a7d 100644 --- a/frontend/src/pages/Blacklist/Movies/index.tsx +++ b/frontend/src/pages/Blacklist/Movies/index.tsx @@ -2,11 +2,12 @@ import { useMovieBlacklist, useMovieDeleteBlacklist, } from "@/apis/hooks/movies"; -import { ContentHeader, QueryOverlay } from "@/components"; +import { Toolbox } from "@/components"; +import { QueryOverlay } from "@/components/async"; import { faTrash } from "@fortawesome/free-solid-svg-icons"; +import { Container, Stack } from "@mantine/core"; +import { useDocumentTitle } from "@mantine/hooks"; import { FunctionComponent } from "react"; -import { Container, Row } from "react-bootstrap"; -import { Helmet } from "react-helmet"; import Table from "./table"; const BlacklistMoviesView: FunctionComponent = () => { @@ -15,26 +16,25 @@ const BlacklistMoviesView: FunctionComponent = () => { const { mutateAsync } = useMovieDeleteBlacklist(); + useDocumentTitle("Movies Blacklist - Bazarr"); + return ( - - - - Movies Blacklist - Bazarr - - - mutateAsync({ all: true })} - > - Remove All - - - + + + + + mutateAsync({ all: true })} + > + Remove All + +
    -
    -
    -
    + + + ); }; diff --git a/frontend/src/pages/Blacklist/Movies/table.tsx b/frontend/src/pages/Blacklist/Movies/table.tsx index d87740d7b..bc29f3f03 100644 --- a/frontend/src/pages/Blacklist/Movies/table.tsx +++ b/frontend/src/pages/Blacklist/Movies/table.tsx @@ -1,8 +1,11 @@ import { useMovieDeleteBlacklist } from "@/apis/hooks"; -import { AsyncButton, PageTable, TextPopover } from "@/components"; +import { PageTable } from "@/components"; +import MutateAction from "@/components/async/MutateAction"; import Language from "@/components/bazarr/Language"; +import TextPopover from "@/components/TextPopover"; +import { useTableStyles } from "@/styles"; import { faTrash } from "@fortawesome/free-solid-svg-icons"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { Anchor, Text } from "@mantine/core"; import { FunctionComponent, useMemo } from "react"; import { Link } from "react-router-dom"; import { Column } from "react-table"; @@ -17,13 +20,13 @@ const Table: FunctionComponent = ({ blacklist }) => { { Header: "Name", accessor: "title", - className: "text-nowrap", Cell: (row) => { const target = `/movies/${row.row.original.radarrId}`; + const { classes } = useTableStyles(); return ( - - {row.value} - + + {row.value} + ); }, }, @@ -48,8 +51,8 @@ const Table: FunctionComponent = ({ blacklist }) => { Cell: (row) => { if (row.value) { return ( - - {row.value} + + {row.value} ); } else { @@ -60,25 +63,21 @@ const Table: FunctionComponent = ({ blacklist }) => { { accessor: "subs_id", Cell: ({ row, value }) => { - const { mutateAsync } = useMovieDeleteBlacklist(); + const remove = useMovieDeleteBlacklist(); return ( - - mutateAsync({ - all: false, - form: { - provider: row.original.provider, - subs_id: value, - }, - }) - } - > - - + icon={faTrash} + mutation={remove} + args={() => ({ + all: false, + form: { + provider: row.original.provider, + subs_id: value, + }, + })} + > ); }, }, @@ -87,7 +86,7 @@ const Table: FunctionComponent = ({ blacklist }) => { ); return ( diff --git a/frontend/src/pages/Blacklist/Series/index.tsx b/frontend/src/pages/Blacklist/Series/index.tsx index b9441f808..a4a6d3638 100644 --- a/frontend/src/pages/Blacklist/Series/index.tsx +++ b/frontend/src/pages/Blacklist/Series/index.tsx @@ -1,34 +1,34 @@ import { useEpisodeBlacklist, useEpisodeDeleteBlacklist } from "@/apis/hooks"; -import { ContentHeader, QueryOverlay } from "@/components"; +import { Toolbox } from "@/components"; +import { QueryOverlay } from "@/components/async"; import { faTrash } from "@fortawesome/free-solid-svg-icons"; +import { Container, Stack } from "@mantine/core"; +import { useDocumentTitle } from "@mantine/hooks"; import { FunctionComponent } from "react"; -import { Container, Row } from "react-bootstrap"; -import { Helmet } from "react-helmet"; import Table from "./table"; const BlacklistSeriesView: FunctionComponent = () => { const blacklist = useEpisodeBlacklist(); const { mutateAsync } = useEpisodeDeleteBlacklist(); + useDocumentTitle("Series Blacklist - Bazarr"); + const { data } = blacklist; return ( - - - Series Blacklist - Bazarr - - - mutateAsync({ all: true })} - > - Remove All - - - + + + + mutateAsync({ all: true })} + > + Remove All + +
    -
    +
    ); diff --git a/frontend/src/pages/Blacklist/Series/table.tsx b/frontend/src/pages/Blacklist/Series/table.tsx index 43a86959b..8722ce123 100644 --- a/frontend/src/pages/Blacklist/Series/table.tsx +++ b/frontend/src/pages/Blacklist/Series/table.tsx @@ -1,8 +1,11 @@ import { useEpisodeDeleteBlacklist } from "@/apis/hooks"; -import { AsyncButton, PageTable, TextPopover } from "@/components"; +import { PageTable } from "@/components"; +import MutateAction from "@/components/async/MutateAction"; import Language from "@/components/bazarr/Language"; +import TextPopover from "@/components/TextPopover"; +import { useTableStyles } from "@/styles"; import { faTrash } from "@fortawesome/free-solid-svg-icons"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { Anchor, Text } from "@mantine/core"; import { FunctionComponent, useMemo } from "react"; import { Link } from "react-router-dom"; import { Column } from "react-table"; @@ -17,13 +20,13 @@ const Table: FunctionComponent = ({ blacklist }) => { { Header: "Series", accessor: "seriesTitle", - className: "text-nowrap", Cell: (row) => { + const { classes } = useTableStyles(); const target = `/series/${row.row.original.sonarrSeriesId}`; return ( - - {row.value} - + + {row.value} + ); }, }, @@ -55,8 +58,8 @@ const Table: FunctionComponent = ({ blacklist }) => { Cell: (row) => { if (row.value) { return ( - - {row.value} + + {row.value} ); } else { @@ -67,25 +70,21 @@ const Table: FunctionComponent = ({ blacklist }) => { { accessor: "subs_id", Cell: ({ row, value }) => { - const { mutateAsync } = useEpisodeDeleteBlacklist(); + const remove = useEpisodeDeleteBlacklist(); return ( - - mutateAsync({ - all: false, - form: { - provider: row.original.provider, - subs_id: value, - }, - }) - } - > - - + icon={faTrash} + mutation={remove} + args={() => ({ + all: false, + form: { + provider: row.original.provider, + subs_id: value, + }, + })} + > ); }, }, @@ -94,7 +93,7 @@ const Table: FunctionComponent = ({ blacklist }) => { ); return ( diff --git a/frontend/src/pages/CriticalError.tsx b/frontend/src/pages/CriticalError.tsx new file mode 100644 index 000000000..2c8d0202b --- /dev/null +++ b/frontend/src/pages/CriticalError.tsx @@ -0,0 +1,26 @@ +import { Reload } from "@/utilities"; +import { faExclamationTriangle } from "@fortawesome/free-solid-svg-icons"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { Alert, Container, Text } from "@mantine/core"; +import { FunctionComponent } from "react"; + +interface Props { + message: string; +} + +const CriticalError: FunctionComponent = ({ message }) => ( + + } + withCloseButton + closeButtonLabel="Reload" + onClose={Reload} + > + {message} + + +); + +export default CriticalError; diff --git a/frontend/src/pages/Episodes/components.tsx b/frontend/src/pages/Episodes/components.tsx index 7e6962699..1184be58b 100644 --- a/frontend/src/pages/Episodes/components.tsx +++ b/frontend/src/pages/Episodes/components.tsx @@ -1,10 +1,9 @@ import { useEpisodeSubtitleModification } from "@/apis/hooks"; -import { AsyncButton } from "@/components"; import Language from "@/components/bazarr/Language"; -import { faSearch, faTrash } from "@fortawesome/free-solid-svg-icons"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { FunctionComponent } from "react"; -import { Badge } from "react-bootstrap"; +import SubtitleToolsMenu from "@/components/SubtitleToolsMenu"; +import { task, TaskGroup } from "@/modules/task"; +import { Badge, DefaultMantineColor } from "@mantine/core"; +import { FunctionComponent, useMemo } from "react"; interface Props { seriesId: number; @@ -13,58 +12,81 @@ interface Props { subtitle: Subtitle; } -export const SubtitleAction: FunctionComponent = ({ +export const Subtitle: FunctionComponent = ({ seriesId, episodeId, - missing, + missing = false, subtitle, }) => { - const { hi, forced } = subtitle; + const { remove, download } = useEpisodeSubtitleModification(); + const color: DefaultMantineColor | undefined = useMemo(() => { + if (missing) { + return "yellow"; + } else if (subtitle.path === null) { + return "gray"; + } + }, [missing, subtitle.path]); - const path = subtitle.path; + const selections = useMemo(() => { + const list: FormType.ModifySubtitle[] = []; - const { download, remove } = useEpisodeSubtitleModification(); + if (subtitle.path) { + list.push({ + id: episodeId, + type: "episode", + language: subtitle.code2, + path: subtitle.path, + }); + } - if (missing || path) { - return ( - { - if (missing) { - return download.mutateAsync({ + return list; + }, [episodeId, subtitle.code2, subtitle.path]); + + return ( + { + if (action === "search") { + task.create( + subtitle.name, + TaskGroup.SearchSubtitle, + download.mutateAsync, + { seriesId, episodeId, form: { - hi, - forced, language: subtitle.code2, + hi: subtitle.hi, + forced: subtitle.forced, }, - }); - } else if (path) { - return remove.mutateAsync({ + } + ); + } else if (action === "delete" && subtitle.path) { + task.create( + subtitle.name, + TaskGroup.DeleteSubtitle, + remove.mutateAsync, + { seriesId, episodeId, - form: { hi, forced, path, language: subtitle.code2 }, - }); - } else { - return null; - } - }} - as={Badge} - className="mr-1" - variant={missing ? "primary" : "secondary"} - > - - - - ); - } else { - return ( - + form: { + language: subtitle.code2, + hi: subtitle.hi, + forced: subtitle.forced, + path: subtitle.path, + }, + } + ); + } + }} + > + - ); - } + + ); }; diff --git a/frontend/src/pages/Episodes/index.tsx b/frontend/src/pages/Episodes/index.tsx index f61bba3f0..12c0f7c67 100644 --- a/frontend/src/pages/Episodes/index.tsx +++ b/frontend/src/pages/Episodes/index.tsx @@ -5,12 +5,15 @@ import { useSeriesById, useSeriesModification, } from "@/apis/hooks"; -import { ContentHeader, LoadingIndicator } from "@/components"; -import ItemOverview from "@/components/ItemOverview"; -import { ItemEditorModal, SeriesUploadModal } from "@/components/modals"; -import { SubtitleToolModal } from "@/components/modals/subtitle-tools"; -import { useModalControl } from "@/modules/modals"; -import { createAndDispatchTask } from "@/modules/task/utilities"; +import { Toolbox } from "@/components"; +import { QueryOverlay } from "@/components/async"; +import { ItemEditModal } from "@/components/forms/ItemEditForm"; +import { SeriesUploadModal } from "@/components/forms/SeriesUploadForm"; +import File, { FileOverlay } from "@/components/inputs/File"; +import { SubtitleToolsModal } from "@/components/modals"; +import { useModals } from "@/modules/modals"; +import { task, TaskGroup } from "@/modules/task"; +import ItemOverview from "@/pages/views/ItemOverview"; import { useLanguageProfileBy } from "@/utilities/languages"; import { faAdjust, @@ -21,17 +24,21 @@ import { faSync, faWrench, } from "@fortawesome/free-solid-svg-icons"; -import { FunctionComponent, useMemo } from "react"; -import { Alert, Container, Row } from "react-bootstrap"; -import { Helmet } from "react-helmet"; +import { Container, Group, Stack } from "@mantine/core"; +import { useDocumentTitle } from "@mantine/hooks"; +import { FunctionComponent, useCallback, useMemo, useRef } from "react"; import { Navigate, useParams } from "react-router-dom"; import Table from "./table"; const SeriesEpisodesView: FunctionComponent = () => { const params = useParams(); const id = Number.parseInt(params.id as string); - const { data: series, isFetched } = useSeriesById(id); - const { data: episodes } = useEpisodesBySeriesId(id); + + const seriesQuery = useSeriesById(id); + const episodesQuery = useEpisodesBySeriesId(id); + + const { data: episodes } = episodesQuery; + const { data: series, isFetched } = seriesQuery; const mutation = useSeriesModification(); const { mutateAsync: action } = useSeriesAction(); @@ -52,111 +59,146 @@ const SeriesEpisodesView: FunctionComponent = () => { [series] ); - const { show } = useModalControl(); + const modals = useModals(); const profile = useLanguageProfileBy(series?.profileId); const hasTask = useIsAnyActionRunning(); + const dialogRef = useRef(null); + const onDrop = useCallback( + (files: File[]) => { + if (series && profile) { + modals.openContextModal(SeriesUploadModal, { + files, + series, + }); + } + }, + [modals, profile, series] + ); + + useDocumentTitle(`${series?.title ?? "Unknown Series"} - Bazarr (Series)`); + if (isNaN(id) || (isFetched && !series)) { return ; } - if (!series) { - return ; - } - return ( - - - {series.title} - Bazarr (Series) - - - - { - createAndDispatchTask(series.title, "scan-disk", action, { - action: "scan-disk", - seriesid: id, - }); - }} - > - Scan Disk - - { - createAndDispatchTask(series.title, "search-subtitles", action, { - action: "search-missing", - seriesid: id, - }); - }} - disabled={ - series.episodeFileCount === 0 || - series.profileId === null || - !available - } - > - Search - - - - show(SubtitleToolModal, episodes)} - > - Tools - - show(SeriesUploadModal, series)} - > - Upload - - show(ItemEditorModal, series)} - > - Edit Series - - - - - - A background task is running for this show, actions are unavailable - - - - - - - {episodes === undefined ? ( - - ) : ( -
    - )} -
    - - + + + + + + + { + if (series) { + task.create(series.title, TaskGroup.ScanDisk, action, { + action: "scan-disk", + seriesid: id, + }); + } + }} + > + Scan Disk + + { + if (series) { + task.create(series.title, TaskGroup.SearchSubtitle, action, { + action: "search-missing", + seriesid: id, + }); + } + }} + disabled={ + series === undefined || + series.episodeFileCount === 0 || + series.profileId === null || + !available + } + > + Search + + + + { + if (episodes) { + modals.openContextModal(SubtitleToolsModal, { + payload: episodes, + }); + } + }} + > + Tools + + dialogRef.current?.()} + > + Upload + + { + if (series) { + modals.openContextModal( + ItemEditModal, + { + item: series, + mutation, + }, + { title: series.title } + ); + } + }} + > + Edit Series + + + + + + +
    +
    +
    +
    ); }; diff --git a/frontend/src/pages/Episodes/table.tsx b/frontend/src/pages/Episodes/table.tsx index 996755227..8dfcccf5a 100644 --- a/frontend/src/pages/Episodes/table.tsx +++ b/frontend/src/pages/Episodes/table.tsx @@ -1,40 +1,39 @@ import { useDownloadEpisodeSubtitles, useEpisodesProvider } from "@/apis/hooks"; -import { ActionButton, GroupTable, TextPopover } from "@/components"; +import { useShowOnlyDesired } from "@/apis/hooks/site"; +import { Action, GroupTable } from "@/components"; +import { AudioList } from "@/components/bazarr"; import { EpisodeHistoryModal } from "@/components/modals"; import { EpisodeSearchModal } from "@/components/modals/ManualSearchModal"; -import SubtitleTools, { - SubtitleToolModal, -} from "@/components/modals/subtitle-tools"; -import { useModalControl } from "@/modules/modals"; -import { useShowOnlyDesired } from "@/modules/redux/hooks"; +import TextPopover from "@/components/TextPopover"; +import { useModals } from "@/modules/modals"; +import { useTableStyles } from "@/styles"; import { BuildKey, filterSubtitleBy } from "@/utilities"; import { useProfileItemsToLanguages } from "@/utilities/languages"; import { faBookmark as farBookmark } from "@fortawesome/free-regular-svg-icons"; import { faBookmark, - faBriefcase, faHistory, faUser, } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { FunctionComponent, useCallback, useMemo } from "react"; -import { Badge, ButtonGroup } from "react-bootstrap"; -import { Column } from "react-table"; -import { SubtitleAction } from "./components"; +import { Group, Text } from "@mantine/core"; +import { + FunctionComponent, + useCallback, + useEffect, + useMemo, + useRef, +} from "react"; +import { Column, TableInstance } from "react-table"; +import { Subtitle } from "./components"; interface Props { - series?: Item.Series; - episodes: Item.Episode[]; + episodes: Item.Episode[] | null; disabled?: boolean; profile?: Language.Profile; } -const Table: FunctionComponent = ({ - series, - episodes, - profile, - disabled, -}) => { +const Table: FunctionComponent = ({ episodes, profile, disabled }) => { const onlyDesired = useShowOnlyDesired(); const profileItems = useProfileItemsToLanguages(profile); @@ -61,7 +60,7 @@ const Table: FunctionComponent = ({ forced, provider, subtitle, - original_format: original_format, + original_format, }, }); }, @@ -94,23 +93,20 @@ const Table: FunctionComponent = ({ { Header: "Title", accessor: "title", - className: "text-nowrap", - Cell: ({ value, row }) => ( - - {value} - - ), + Cell: ({ value, row }) => { + const { classes } = useTableStyles(); + + return ( + + {value} + + ); + }, }, { Header: "Audio", accessor: "audio_language", - Cell: (row) => { - return row.value.map((v) => ( - - {v.name} - - )); - }, + Cell: ({ value }) => , }, { Header: "Subtitles", @@ -118,19 +114,19 @@ const Table: FunctionComponent = ({ Cell: ({ row }) => { const episode = row.original; - const seriesid = episode.sonarrSeriesId; + const seriesId = episode.sonarrSeriesId; const elements = useMemo(() => { - const episodeid = episode.sonarrEpisodeId; + const episodeId = episode.sonarrEpisodeId; const missing = episode.missing_subtitles.map((val, idx) => ( - + > )); let raw_subtitles = episode.subtitles; @@ -139,86 +135,96 @@ const Table: FunctionComponent = ({ } const subtitles = raw_subtitles.map((val, idx) => ( - + > )); return [...missing, ...subtitles]; - }, [episode, seriesid]); + }, [episode, seriesId]); - return elements; + return ( + + {elements} + + ); }, }, { Header: "Actions", accessor: "sonarrEpisodeId", Cell: ({ row }) => { - const { show } = useModalControl(); + const modals = useModals(); return ( - - { - show(EpisodeSearchModal, row.original); - }} - > - + { - show(EpisodeHistoryModal, row.original); + modals.openContextModal(EpisodeSearchModal, { + item: row.original, + download, + query: useEpisodesProvider, + }); }} - > - + { - show(SubtitleToolModal, [row.original]); + modals.openContextModal( + EpisodeHistoryModal, + { + episode: row.original, + }, + { + title: `History - ${row.original.title}`, + } + ); }} - > - + icon={faHistory} + > + ); }, }, ], - [onlyDesired, profileItems, series, disabled] + [onlyDesired, profileItems, disabled, download] ); const maxSeason = useMemo( () => - episodes.reduce((prev, curr) => Math.max(prev, curr.season), 0), + episodes?.reduce( + (prev, curr) => Math.max(prev, curr.season), + 0 + ) ?? 0, [episodes] ); + const instance = useRef | null>(null); + + useEffect(() => { + if (instance.current) { + instance.current.toggleRowExpanded([`season:${maxSeason}`], true); + } + }, [maxSeason]); + return ( - <> - - - - - + ); }; diff --git a/frontend/src/pages/History/Movies/index.tsx b/frontend/src/pages/History/Movies/index.tsx index cbfaba78f..210f0b783 100644 --- a/frontend/src/pages/History/Movies/index.tsx +++ b/frontend/src/pages/History/Movies/index.tsx @@ -1,12 +1,18 @@ import { useMovieAddBlacklist, useMovieHistoryPagination } from "@/apis/hooks"; -import { HistoryIcon, TextPopover } from "@/components"; +import { MutateAction } from "@/components/async"; +import { HistoryIcon } from "@/components/bazarr"; import Language from "@/components/bazarr/Language"; -import { BlacklistButton } from "@/components/inputs/blacklist"; -import HistoryView from "@/components/views/HistoryView"; -import { faInfoCircle, faRecycle } from "@fortawesome/free-solid-svg-icons"; +import TextPopover from "@/components/TextPopover"; +import HistoryView from "@/pages/views/HistoryView"; +import { useTableStyles } from "@/styles"; +import { + faFileExcel, + faInfoCircle, + faRecycle, +} from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { Anchor, Badge, Text } from "@mantine/core"; import { FunctionComponent, useMemo } from "react"; -import { Badge, OverlayTrigger, Popover } from "react-bootstrap"; import { Link } from "react-router-dom"; import { Column } from "react-table"; @@ -15,20 +21,18 @@ const MoviesHistoryView: FunctionComponent = () => { () => [ { accessor: "action", - className: "text-center", Cell: (row) => , }, { Header: "Name", accessor: "title", - className: "text-nowrap", - Cell: (row) => { - const target = `/movies/${row.row.original.radarrId}`; - + Cell: ({ row, value }) => { + const { classes } = useTableStyles(); + const target = `/movies/${row.original.radarrId}`; return ( - - {row.value} - + + {value} + ); }, }, @@ -38,7 +42,7 @@ const MoviesHistoryView: FunctionComponent = () => { Cell: ({ value }) => { if (value) { return ( - + ); @@ -57,8 +61,8 @@ const MoviesHistoryView: FunctionComponent = () => { Cell: (row) => { if (row.value) { return ( - - {row.value} + + {row.value} ); } else { @@ -68,34 +72,22 @@ const MoviesHistoryView: FunctionComponent = () => { }, { accessor: "description", - Cell: ({ row, value }) => { - const overlay = ( - - {value} - - ); + Cell: ({ value }) => { return ( - + - + ); }, }, { accessor: "upgradable", Cell: (row) => { - const overlay = ( - - - This Subtitles File Is Eligible For An Upgrade. - - - ); if (row.value) { return ( - + - +
    ); } else { return null; @@ -104,15 +96,31 @@ const MoviesHistoryView: FunctionComponent = () => { }, { accessor: "blacklisted", - Cell: ({ row }) => { - const { radarrId } = row.original; - const { mutateAsync } = useMovieAddBlacklist(); - return ( - mutateAsync({ id: radarrId, form })} - > - ); + Cell: ({ row, value }) => { + const add = useMovieAddBlacklist(); + const { radarrId, provider, subs_id, language, subtitles_path } = + row.original; + + if (subs_id && provider && language) { + return ( + ({ + id: radarrId, + form: { + provider, + subs_id, + subtitles_path, + language: language.code2, + }, + })} + > + ); + } else { + return null; + } }, }, ], diff --git a/frontend/src/pages/History/Series/index.tsx b/frontend/src/pages/History/Series/index.tsx index e64e798d7..9ddfa3d69 100644 --- a/frontend/src/pages/History/Series/index.tsx +++ b/frontend/src/pages/History/Series/index.tsx @@ -2,14 +2,20 @@ import { useEpisodeAddBlacklist, useEpisodeHistoryPagination, } from "@/apis/hooks"; -import { HistoryIcon, TextPopover } from "@/components"; +import { MutateAction } from "@/components/async"; +import { HistoryIcon } from "@/components/bazarr"; import Language from "@/components/bazarr/Language"; -import { BlacklistButton } from "@/components/inputs/blacklist"; -import HistoryView from "@/components/views/HistoryView"; -import { faInfoCircle, faRecycle } from "@fortawesome/free-solid-svg-icons"; +import TextPopover from "@/components/TextPopover"; +import HistoryView from "@/pages/views/HistoryView"; +import { useTableStyles } from "@/styles"; +import { + faFileExcel, + faInfoCircle, + faRecycle, +} from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { Anchor, Badge, Text } from "@mantine/core"; import { FunctionComponent, useMemo } from "react"; -import { Badge, OverlayTrigger, Popover } from "react-bootstrap"; import { Link } from "react-router-dom"; import { Column } from "react-table"; @@ -18,19 +24,19 @@ const SeriesHistoryView: FunctionComponent = () => { () => [ { accessor: "action", - className: "text-center", Cell: ({ value }) => , }, { Header: "Series", accessor: "seriesTitle", Cell: (row) => { + const { classes } = useTableStyles(); const target = `/series/${row.row.original.sonarrSeriesId}`; return ( - - {row.value} - + + {row.value} + ); }, }, @@ -41,6 +47,10 @@ const SeriesHistoryView: FunctionComponent = () => { { Header: "Title", accessor: "episodeTitle", + Cell: ({ value }) => { + const { classes } = useTableStyles(); + return {value}; + }, }, { Header: "Language", @@ -48,7 +58,7 @@ const SeriesHistoryView: FunctionComponent = () => { Cell: ({ value }) => { if (value) { return ( - + ); @@ -67,8 +77,8 @@ const SeriesHistoryView: FunctionComponent = () => { Cell: (row) => { if (row.value) { return ( - - {row.value} + + {row.value} ); } else { @@ -79,33 +89,21 @@ const SeriesHistoryView: FunctionComponent = () => { { accessor: "description", Cell: ({ row, value }) => { - const overlay = ( - - {value} - - ); return ( - + - + ); }, }, { accessor: "upgradable", Cell: (row) => { - const overlay = ( - - - This Subtitles File Is Eligible For An Upgrade. - - - ); if (row.value) { return ( - + - +
    ); } else { return null; @@ -114,23 +112,38 @@ const SeriesHistoryView: FunctionComponent = () => { }, { accessor: "blacklisted", - Cell: ({ row }) => { - const original = row.original; + Cell: ({ row, value }) => { + const { + sonarrEpisodeId, + sonarrSeriesId, + provider, + subs_id, + language, + subtitles_path, + } = row.original; + const add = useEpisodeAddBlacklist(); - const { sonarrEpisodeId, sonarrSeriesId } = original; - const { mutateAsync } = useEpisodeAddBlacklist(); - return ( - - mutateAsync({ + if (subs_id && provider && language) { + return ( + ({ seriesId: sonarrSeriesId, episodeId: sonarrEpisodeId, - form, - }) - } - > - ); + form: { + provider, + subs_id, + subtitles_path, + language: language.code2, + }, + })} + > + ); + } else { + return null; + } }, }, ], diff --git a/frontend/src/pages/History/Statistics/index.tsx b/frontend/src/pages/History/Statistics/index.tsx index aee2c0b54..f8caf4916 100644 --- a/frontend/src/pages/History/Statistics/index.tsx +++ b/frontend/src/pages/History/Statistics/index.tsx @@ -1,15 +1,23 @@ -import { useHistoryStats, useSystemProviders } from "@/apis/hooks"; import { - ContentHeader, - QueryOverlay, - Selector, - SelectorOption, -} from "@/components"; + useHistoryStats, + useLanguages, + useSystemProviders, +} from "@/apis/hooks"; +import { Selector, Toolbox } from "@/components"; +import { QueryOverlay } from "@/components/async"; import Language from "@/components/bazarr/Language"; +import { Layout } from "@/constants"; +import { useSelectorOptions } from "@/utilities"; +import { + Box, + Container, + createStyles, + SimpleGrid, + useMantineTheme, +} from "@mantine/core"; +import { useDocumentTitle } from "@mantine/hooks"; import { merge } from "lodash"; import { FunctionComponent, useMemo, useState } from "react"; -import { Col, Container } from "react-bootstrap"; -import { Helmet } from "react-helmet"; import { Bar, BarChart, @@ -22,23 +30,32 @@ import { } from "recharts"; import { actionOptions, timeFrameOptions } from "./options"; -const SelectorContainer: FunctionComponent = ({ children }) => ( - - {children} - -); +const useStyles = createStyles((theme) => ({ + container: { + display: "flex", + flexDirection: "column", + height: `calc(100vh - ${Layout.HEADER_HEIGHT}px)`, + }, + chart: { + height: "90%", + }, +})); const HistoryStats: FunctionComponent = () => { const { data: providers } = useSystemProviders(true); - const providerOptions = useMemo[]>( - () => providers?.map((value) => ({ label: value.name, value })) ?? [], - [providers] + const providerOptions = useSelectorOptions(providers ?? [], (v) => v.name); + + const { data: historyLanguages } = useLanguages(true); + + const languageOptions = useSelectorOptions( + historyLanguages ?? [], + (value) => value.name ); const [timeFrame, setTimeFrame] = useState("month"); const [action, setAction] = useState>(null); - const [lang, setLanguage] = useState>(null); + const [lang, setLanguage] = useState>(null); const [provider, setProvider] = useState>(null); const stats = useHistoryStats(timeFrame, action, provider, lang); @@ -61,61 +78,71 @@ const HistoryStats: FunctionComponent = () => { } }, [data]); + useDocumentTitle("History Statistics - Bazarr"); + + const { classes } = useStyles(); + const theme = useMantineTheme(); + return ( - - - History Statistics - Bazarr - + -
    - - - setTimeFrame(v ?? "month")} - > - - - - - - - - - - - - - + + + setTimeFrame(v ?? "month")} + > + + + + + + + + - - + + -
    +
    ); diff --git a/frontend/src/pages/LaunchError.tsx b/frontend/src/pages/LaunchError.tsx deleted file mode 100644 index 910b01ccd..000000000 --- a/frontend/src/pages/LaunchError.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import { Reload } from "@/utilities"; -import { faExclamationTriangle } from "@fortawesome/free-solid-svg-icons"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { FunctionComponent } from "react"; -import { Alert, Button, Container } from "react-bootstrap"; - -interface Props { - children: string; -} - -const LaunchError: FunctionComponent = ({ children }) => ( - - -
    - - {children} -
    - -
    -
    -); - -export default LaunchError; diff --git a/frontend/src/pages/Movies/Details/index.tsx b/frontend/src/pages/Movies/Details/index.tsx index ca0a56ee3..70f80b2f7 100644 --- a/frontend/src/pages/Movies/Details/index.tsx +++ b/frontend/src/pages/Movies/Details/index.tsx @@ -8,22 +8,20 @@ import { useMovieById, useMovieModification, } from "@/apis/hooks/movies"; -import { ContentHeader, LoadingIndicator } from "@/components"; -import ItemOverview from "@/components/ItemOverview"; -import { - ItemEditorModal, - MovieHistoryModal, - MovieUploadModal, -} from "@/components/modals"; +import { Action, Toolbox } from "@/components"; +import { QueryOverlay } from "@/components/async"; +import { ItemEditModal } from "@/components/forms/ItemEditForm"; +import { MovieUploadModal } from "@/components/forms/MovieUploadForm"; +import File, { FileOverlay } from "@/components/inputs/File"; +import { MovieHistoryModal, SubtitleToolsModal } from "@/components/modals"; import { MovieSearchModal } from "@/components/modals/ManualSearchModal"; -import SubtitleTools, { - SubtitleToolModal, -} from "@/components/modals/subtitle-tools"; -import { useModalControl } from "@/modules/modals"; -import { createAndDispatchTask } from "@/modules/task/utilities"; +import { useModals } from "@/modules/modals"; +import { task, TaskGroup } from "@/modules/task"; +import ItemOverview from "@/pages/views/ItemOverview"; import { useLanguageProfileBy } from "@/utilities/languages"; import { faCloudUploadAlt, + faEllipsis, faHistory, faSearch, faSync, @@ -31,20 +29,23 @@ import { faUser, faWrench, } from "@fortawesome/free-solid-svg-icons"; -import { FunctionComponent, useCallback } from "react"; -import { Alert, Container, Row } from "react-bootstrap"; -import { Helmet } from "react-helmet"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { Container, Group, Menu, Stack } from "@mantine/core"; +import { useDocumentTitle } from "@mantine/hooks"; +import { isNumber } from "lodash"; +import { FunctionComponent, useCallback, useRef } from "react"; import { Navigate, useParams } from "react-router-dom"; import Table from "./table"; const MovieDetailView: FunctionComponent = () => { const param = useParams(); const id = Number.parseInt(param.id ?? ""); - const { data: movie, isFetched } = useMovieById(id); + const movieQuery = useMovieById(id); + const { data: movie, isFetched } = movieQuery; const profile = useLanguageProfileBy(movie?.profileId); - const { show } = useModalControl(); + const modals = useModals(); const mutation = useMovieModification(); const { mutateAsync: action } = useMovieAction(); @@ -77,112 +78,155 @@ const MovieDetailView: FunctionComponent = () => { [downloadAsync] ); + const dialogRef = useRef(null); + const onDrop = useCallback( + (files: File[]) => { + if (movie && profile) { + modals.openContextModal(MovieUploadModal, { + files, + movie, + }); + } + }, + [modals, movie, profile] + ); + const hasTask = useIsMovieActionRunning(); + useDocumentTitle(`${movie?.title ?? "Unknown Movie"} - Bazarr (Movies)`); + if (isNaN(id) || (isFetched && !movie)) { return ; } - if (!movie) { - return ; - } - - const allowEdit = movie.profileId !== undefined; + const allowEdit = movie?.profileId !== undefined; return ( - - - {movie.title} - Bazarr (Movies) - - - - { - createAndDispatchTask(movie.title, "scan-disk", action, { - action: "scan-disk", - radarrid: id, - }); - }} - > - Scan Disk - - { - createAndDispatchTask(movie.title, "search-subtitles", action, { - action: "search-missing", - radarrid: id, - }); - }} - > - Search - - show(MovieSearchModal, movie)} - > - Manual - - show(MovieHistoryModal, movie)} - > - History - - show(SubtitleToolModal, [movie])} - > - Tools - - - - - show(MovieUploadModal, movie)} - > - Upload - - + + + + + + { + if (movie) { + task.create(movie.title, TaskGroup.ScanDisk, action, { + action: "scan-disk", + radarrid: id, + }); + } + }} + > + Scan Disk + + { + if (movie) { + task.create(movie.title, TaskGroup.SearchSubtitle, action, { + action: "search-missing", + radarrid: id, + }); + } + }} + > + Search + + { + if (movie) { + modals.openContextModal(MovieSearchModal, { + item: movie, + download, + query: useMoviesProvider, + }); + } + }} + > + Manual + + + + { + dialogRef.current?.(); + }} + > + Upload + + { + if (movie) { + modals.openContextModal( + ItemEditModal, + { + item: movie, + mutation, + }, + { title: movie.title } + ); + } + }} + > + Edit Movie + + }> + } + onClick={() => { + if (movie) { + modals.openContextModal(SubtitleToolsModal, { + payload: [movie], + }); + } + }} + > + Tools + + } + onClick={() => { + if (movie) { + modals.openContextModal(MovieHistoryModal, { movie }); + } + }} + > + History + + + + + + + show(ItemEditorModal, movie)} - > - Edit Movie - - - - - - A background task is running for this movie, actions are unavailable - - - - - - -
    - - - - - - + > +
    +
    ); }; diff --git a/frontend/src/pages/Movies/Details/table.tsx b/frontend/src/pages/Movies/Details/table.tsx index c87651e77..72784045c 100644 --- a/frontend/src/pages/Movies/Details/table.tsx +++ b/frontend/src/pages/Movies/Details/table.tsx @@ -1,23 +1,34 @@ import { useMovieSubtitleModification } from "@/apis/hooks"; -import { AsyncButton, SimpleTable } from "@/components"; +import { useShowOnlyDesired } from "@/apis/hooks/site"; +import { Action, SimpleTable } from "@/components"; import Language from "@/components/bazarr/Language"; -import { useShowOnlyDesired } from "@/modules/redux/hooks"; +import SubtitleToolsMenu from "@/components/SubtitleToolsMenu"; +import { task, TaskGroup } from "@/modules/task"; +import { useTableStyles } from "@/styles"; import { filterSubtitleBy } from "@/utilities"; import { useProfileItemsToLanguages } from "@/utilities/languages"; -import { faSearch, faTrash } from "@fortawesome/free-solid-svg-icons"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { faEllipsis, faSearch } from "@fortawesome/free-solid-svg-icons"; +import { Badge, Text, TextProps } from "@mantine/core"; +import { isString } from "lodash"; import { FunctionComponent, useMemo } from "react"; -import { Badge } from "react-bootstrap"; import { Column } from "react-table"; const missingText = "Missing Subtitles"; interface Props { - movie: Item.Movie; + movie: Item.Movie | null; disabled?: boolean; profile?: Language.Profile; } +function isSubtitleTrack(path: string | undefined | null) { + return !isString(path) || path.length === 0; +} + +function isSubtitleMissing(path: string | undefined | null) { + return path === missingText; +} + const Table: FunctionComponent = ({ movie, profile, disabled }) => { const onlyDesired = useShowOnlyDesired(); @@ -29,12 +40,22 @@ const Table: FunctionComponent = ({ movie, profile, disabled }) => { Header: "Subtitle Path", accessor: "path", Cell: ({ value }) => { - if (value === null || value.length === 0) { - return "Video File Subtitle Track"; - } else if (value === missingText) { - return {value}; + const { classes } = useTableStyles(); + + const props: TextProps<"div"> = { + className: classes.primary, + }; + + if (isSubtitleTrack(value)) { + return Video File Subtitle Track; + } else if (isSubtitleMissing(value)) { + return ( + + {value} + + ); } else { - return value; + return {value}; } }, }, @@ -44,13 +65,13 @@ const Table: FunctionComponent = ({ movie, profile, disabled }) => { Cell: ({ row }) => { if (row.original.path === missingText) { return ( - + ); } else { return ( - + ); @@ -59,58 +80,90 @@ const Table: FunctionComponent = ({ movie, profile, disabled }) => { }, { accessor: "code2", - Cell: (row) => { + Cell: ({ row }) => { const { - original: { code2, hi, forced, path }, - } = row.row; + original: { code2, path, hi, forced }, + } = row; const { download, remove } = useMovieSubtitleModification(); - const { radarrId } = movie; - if (path === null || path.length === 0) { + const selections = useMemo(() => { + const list: FormType.ModifySubtitle[] = []; + + if (path && !isSubtitleMissing(path) && movie !== null) { + list.push({ + type: "movie", + path, + id: movie.radarrId, + language: code2, + }); + } + + return list; + }, [code2, path]); + + if (movie === null) { return null; - } else if (path === missingText) { - return ( - - download.mutateAsync({ - radarrId, - form: { - language: code2, - hi, - forced, - }, - }) - } - variant="light" - size="sm" - > - - - ); - } else { + } + + const { radarrId } = movie; + + if (isSubtitleMissing(path)) { return ( - - remove.mutateAsync({ - radarrId, - form: { - language: code2, - hi, - forced, - path, - }, - }) - } - > - - + onClick={() => { + task.create( + movie.title, + TaskGroup.SearchSubtitle, + download.mutateAsync, + { + radarrId, + form: { + language: code2, + forced, + hi, + }, + } + ); + }} + > ); } + + return ( + { + if (action === "delete" && path) { + task.create( + movie.title, + TaskGroup.DeleteSubtitle, + remove.mutateAsync, + { + radarrId, + form: { + language: code2, + forced, + hi, + path, + }, + } + ); + } else if (action === "search") { + throw new Error( + "This shouldn't happen, please report the bug" + ); + } + }} + > + + + ); }, }, ], @@ -118,24 +171,25 @@ const Table: FunctionComponent = ({ movie, profile, disabled }) => { ); const data: Subtitle[] = useMemo(() => { - const missing = movie.missing_subtitles.map((item) => ({ - ...item, - path: missingText, - })); + const missing = + movie?.missing_subtitles.map((item) => ({ + ...item, + path: missingText, + })) ?? []; - let raw_subtitles = movie.subtitles; + let raw_subtitles = movie?.subtitles ?? []; if (onlyDesired) { raw_subtitles = filterSubtitleBy(raw_subtitles, profileItems); } return [...raw_subtitles, ...missing]; - }, [movie.missing_subtitles, movie.subtitles, onlyDesired, profileItems]); + }, [movie, onlyDesired, profileItems]); return ( ); }; diff --git a/frontend/src/pages/Movies/Editor.tsx b/frontend/src/pages/Movies/Editor.tsx index 97b863a1f..4a86c6c45 100644 --- a/frontend/src/pages/Movies/Editor.tsx +++ b/frontend/src/pages/Movies/Editor.tsx @@ -1,11 +1,10 @@ import { useMovieModification, useMovies } from "@/apis/hooks"; -import { QueryOverlay } from "@/components"; -import LanguageProfile from "@/components/bazarr/LanguageProfile"; -import MassEditor from "@/components/MassEditor"; -import { BuildKey } from "@/utilities"; +import { QueryOverlay } from "@/components/async"; +import { AudioList } from "@/components/bazarr"; +import LanguageProfileName from "@/components/bazarr/LanguageProfile"; +import MassEditor from "@/pages/views/MassEditor"; +import { useDocumentTitle } from "@mantine/hooks"; import { FunctionComponent, useMemo } from "react"; -import { Badge } from "react-bootstrap"; -import { Helmet } from "react-helmet"; import { Column } from "react-table"; const MovieMassEditor: FunctionComponent = () => { @@ -17,46 +16,34 @@ const MovieMassEditor: FunctionComponent = () => { { Header: "Name", accessor: "title", - className: "text-nowrap", }, { Header: "Audio", accessor: "audio_language", - Cell: (row) => { - return row.value.map((v) => ( - - {v.name} - - )); + Cell: ({ value }) => { + return ; }, }, { Header: "Languages Profile", accessor: "profileId", Cell: ({ value }) => { - return ; + return ; }, }, ], [] ); + useDocumentTitle("Movies - Bazarr (Mass Editor)"); + return ( - <> - - Movies - Bazarr (Mass Editor) - - - + ); }; diff --git a/frontend/src/pages/Movies/index.tsx b/frontend/src/pages/Movies/index.tsx index 5daac19f6..868fa3b50 100644 --- a/frontend/src/pages/Movies/index.tsx +++ b/frontend/src/pages/Movies/index.tsx @@ -1,23 +1,23 @@ import { useMovieModification, useMoviesPagination } from "@/apis/hooks"; -import { ActionBadge, TextPopover } from "@/components"; +import { Action } from "@/components"; +import { AudioList } from "@/components/bazarr"; import Language from "@/components/bazarr/Language"; -import LanguageProfile from "@/components/bazarr/LanguageProfile"; -import { ItemEditorModal } from "@/components/modals"; -import ItemView from "@/components/views/ItemView"; -import { useModalControl } from "@/modules/modals"; +import LanguageProfileName from "@/components/bazarr/LanguageProfile"; +import { ItemEditModal } from "@/components/forms/ItemEditForm"; +import { useModals } from "@/modules/modals"; +import ItemView from "@/pages/views/ItemView"; +import { useTableStyles } from "@/styles"; import { BuildKey } from "@/utilities"; import { faBookmark as farBookmark } from "@fortawesome/free-regular-svg-icons"; import { faBookmark, faWrench } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { Anchor, Badge, Container } from "@mantine/core"; +import { useDocumentTitle } from "@mantine/hooks"; import { FunctionComponent, useMemo } from "react"; -import { Badge, Container } from "react-bootstrap"; -import { Helmet } from "react-helmet"; import { Link } from "react-router-dom"; import { Column } from "react-table"; const MovieView: FunctionComponent = () => { - const mutation = useMovieModification(); - const query = useMoviesPagination(); const columns: Column[] = useMemo[]>( @@ -34,38 +34,30 @@ const MovieView: FunctionComponent = () => { { Header: "Name", accessor: "title", - className: "text-nowrap", Cell: ({ row, value }) => { + const { classes } = useTableStyles(); const target = `/movies/${row.original.radarrId}`; return ( - - - {value} - - + + {value} + ); }, }, { Header: "Audio", accessor: "audio_language", - Cell: (row) => { - return row.value.map((v) => ( - - {v.name} - - )); + Cell: ({ value }) => { + return ; }, }, { Header: "Languages Profile", accessor: "profileId", Cell: ({ value }) => { - return ; + return ( + + ); }, }, { @@ -75,8 +67,8 @@ const MovieView: FunctionComponent = () => { const missing = row.value; return missing.map((v) => ( @@ -87,12 +79,25 @@ const MovieView: FunctionComponent = () => { { accessor: "radarrId", Cell: ({ row }) => { - const { show } = useModalControl(); + const modals = useModals(); + const mutation = useMovieModification(); return ( - + modals.openContextModal( + ItemEditModal, + { + mutation, + item: row.original, + }, + { + title: row.original.title, + } + ) + } icon={faWrench} - onClick={() => show(ItemEditorModal, row.original)} - > + > ); }, }, @@ -100,13 +105,11 @@ const MovieView: FunctionComponent = () => { [] ); + useDocumentTitle("Movies - Bazarr"); + return ( - - - Movies - Bazarr - + - ); }; diff --git a/frontend/src/pages/NotFound.tsx b/frontend/src/pages/NotFound.tsx new file mode 100644 index 000000000..d81c31d7f --- /dev/null +++ b/frontend/src/pages/NotFound.tsx @@ -0,0 +1,24 @@ +import { faEyeSlash as fasEyeSlash } from "@fortawesome/free-regular-svg-icons"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { Box, Center, Container, Text, Title } from "@mantine/core"; +import { FunctionComponent } from "react"; + +const NotFound: FunctionComponent = () => { + return ( + +
    + + <Box component="span" mr="md"> + <FontAwesomeIcon icon={fasEyeSlash}></FontAwesomeIcon> + </Box> + 404 + +
    +
    + The Request URL No Found +
    +
    + ); +}; + +export default NotFound; diff --git a/frontend/src/pages/Series/Editor.tsx b/frontend/src/pages/Series/Editor.tsx index 9cfc4e855..cd6c1722e 100644 --- a/frontend/src/pages/Series/Editor.tsx +++ b/frontend/src/pages/Series/Editor.tsx @@ -1,11 +1,10 @@ import { useSeries, useSeriesModification } from "@/apis/hooks"; -import { QueryOverlay } from "@/components"; -import LanguageProfile from "@/components/bazarr/LanguageProfile"; -import MassEditor from "@/components/MassEditor"; -import { BuildKey } from "@/utilities"; +import { QueryOverlay } from "@/components/async"; +import { AudioList } from "@/components/bazarr"; +import LanguageProfileName from "@/components/bazarr/LanguageProfile"; +import MassEditor from "@/pages/views/MassEditor"; +import { useDocumentTitle } from "@mantine/hooks"; import { FunctionComponent, useMemo } from "react"; -import { Badge } from "react-bootstrap"; -import { Helmet } from "react-helmet"; import { Column } from "react-table"; const SeriesMassEditor: FunctionComponent = () => { @@ -17,46 +16,34 @@ const SeriesMassEditor: FunctionComponent = () => { { Header: "Name", accessor: "title", - className: "text-nowrap", }, { Header: "Audio", accessor: "audio_language", - Cell: (row) => { - return row.value.map((v) => ( - - {v.name} - - )); + Cell: ({ value }) => { + return ; }, }, { Header: "Languages Profile", accessor: "profileId", Cell: ({ value }) => { - return ; + return ; }, }, ], [] ); + useDocumentTitle("Series - Bazarr (Mass Editor)"); + return ( - <> - - Series - Bazarr (Mass Editor) - - - + ); }; diff --git a/frontend/src/pages/Series/index.tsx b/frontend/src/pages/Series/index.tsx index e03807a7f..f56d3fe47 100644 --- a/frontend/src/pages/Series/index.tsx +++ b/frontend/src/pages/Series/index.tsx @@ -1,14 +1,15 @@ import { useSeriesModification, useSeriesPagination } from "@/apis/hooks"; -import { ActionBadge } from "@/components"; -import LanguageProfile from "@/components/bazarr/LanguageProfile"; -import { ItemEditorModal } from "@/components/modals"; -import ItemView from "@/components/views/ItemView"; -import { useModalControl } from "@/modules/modals"; -import { BuildKey } from "@/utilities"; +import { Action } from "@/components"; +import { AudioList } from "@/components/bazarr"; +import LanguageProfileName from "@/components/bazarr/LanguageProfile"; +import { ItemEditModal } from "@/components/forms/ItemEditForm"; +import { useModals } from "@/modules/modals"; +import ItemView from "@/pages/views/ItemView"; +import { useTableStyles } from "@/styles"; import { faWrench } from "@fortawesome/free-solid-svg-icons"; +import { Anchor, Container, Progress } from "@mantine/core"; +import { useDocumentTitle } from "@mantine/hooks"; import { FunctionComponent, useMemo } from "react"; -import { Badge, Container, ProgressBar } from "react-bootstrap"; -import { Helmet } from "react-helmet"; import { Link } from "react-router-dom"; import { Column } from "react-table"; @@ -22,36 +23,30 @@ const SeriesView: FunctionComponent = () => { { Header: "Name", accessor: "title", - className: "text-nowrap", Cell: ({ row, value }) => { + const { classes } = useTableStyles(); const target = `/series/${row.original.sonarrSeriesId}`; return ( - - {value} - + + {value} + ); }, }, { Header: "Audio", accessor: "audio_language", - Cell: (row) => { - return row.value.map((v) => ( - - {v.name} - - )); + Cell: ({ value }) => { + return ; }, }, { Header: "Languages Profile", accessor: "profileId", Cell: ({ value }) => { - return ; + return ( + + ); }, }, { @@ -65,50 +60,56 @@ const SeriesView: FunctionComponent = () => { if (episodeFileCount === 0 || !profileId) { progress = 0.0; } else { - progress = episodeFileCount - episodeMissingCount; + progress = (1.0 - episodeMissingCount / episodeFileCount) * 100.0; label = `${ episodeFileCount - episodeMissingCount }/${episodeFileCount}`; } - const color = episodeMissingCount === 0 ? "primary" : "warning"; - return ( - + > ); }, }, { accessor: "sonarrSeriesId", Cell: ({ row: { original } }) => { - const { show } = useModalControl(); + const modals = useModals(); return ( - + modals.openContextModal( + ItemEditModal, + { + mutation, + item: original, + }, + { + title: original.title, + } + ) + } icon={faWrench} - onClick={() => show(ItemEditorModal, original)} - > + > ); }, }, ], - [] + [mutation] ); + useDocumentTitle("Series - Bazarr"); + return ( - - - Series - Bazarr - + - ); }; diff --git a/frontend/src/pages/Settings/General/index.tsx b/frontend/src/pages/Settings/General/index.tsx index 86b271834..35994a539 100644 --- a/frontend/src/pages/Settings/General/index.tsx +++ b/frontend/src/pages/Settings/General/index.tsx @@ -1,22 +1,23 @@ -import { copyToClipboard, Environment, toggleState } from "@/utilities"; +import { Environment, toggleState } from "@/utilities"; import { faCheck, faClipboard, faSync, } from "@fortawesome/free-solid-svg-icons"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { Group as MantineGroup, Text as MantineText } from "@mantine/core"; +import { useClipboard } from "@mantine/hooks"; import { FunctionComponent, useState } from "react"; -import { InputGroup } from "react-bootstrap"; import { - Button, + Action, Check, Chips, CollapseBox, File, - Group, - Input, Layout, Message, + Number, + Password, + Section, Selector, Text, } from "../components"; @@ -38,181 +39,164 @@ const baseUrlOverride = (settings: Settings) => const SettingsGeneralView: FunctionComponent = () => { const [copied, setCopy] = useState(false); + const clipboard = useClipboard(); + return ( - - - - Valid IPv4 address or '0.0.0.0' for all interfaces - - - - - - - - / - - "/" + v} - > - - Reverse proxy support - - - +
    + + Valid IPv4 address or '0.0.0.0' for all interfaces + + "/" + v} + > + Reverse proxy support +
    +
    - - (v === null ? "None" : v)} - > - + (v === null ? "None" : v)} + > k !== "" && k !== "None"}> - - - - - - + + - - - - - - - - - - - + > + + } + settingKey={settingApiKey} + > +
    +
    - - (v === null ? "None" : v)} - > - + (v === null ? "None" : v)} + > k !== "" && k !== "None"}> - - - - - - - - - - - - - You only need to enter a username and password if one is - required. Leave them blank otherwise - - - - - - List of excluded domains or IP addresses. Asterisk(wildcard), - regex and CIDR are unsupported. You can use '.domain.com' to - include all subdomains. - - + + + + + + You only need to enter a username and password if one is required. + Leave them blank otherwise + + + + List of excluded domains or IP addresses. Asterisk(wildcard), + regex and CIDR are unsupported. You can use '.domain.com' to + include all subdomains. + - - - - - - Debug logging should only be enabled temporarily - - - - - - Absolute path to the backup directory - - - - - - Days - - - - - - - - - Send anonymous usage information, nothing that can identify you. - This includes information on which providers you use, what languages - you search for, Bazarr, Python, Sonarr, Radarr and what OS version - you are using. We will use this information to prioritize features - and bug fixes. Please, keep this enabled as this is the only way we - have to better understand how you use Bazarr. - - - +
    + +
    + + Debug logging should only be enabled temporarily +
    +
    + + Absolute path to the backup directory + + Days + + } + > +
    +
    + + + Send anonymous usage information, nothing that can identify you. This + includes information on which providers you use, what languages you + search for, Bazarr, Python, Sonarr, Radarr and what OS version you are + using. We will use this information to prioritize features and bug + fixes. Please, keep this enabled as this is the only way we have to + better understand how you use Bazarr. + +
    ); }; diff --git a/frontend/src/pages/Settings/Languages/components.tsx b/frontend/src/pages/Settings/Languages/components.tsx index 473e7a6a0..d5a3f84f6 100644 --- a/frontend/src/pages/Settings/Languages/components.tsx +++ b/frontend/src/pages/Settings/Languages/components.tsx @@ -1,36 +1,45 @@ import { - LanguageSelector as CLanguageSelector, + MultiSelector, + MultiSelectorProps, SelectorOption, } from "@/components"; +import { Language } from "@/components/bazarr"; +import { useSelectorOptions } from "@/utilities"; import { FunctionComponent, useMemo } from "react"; import { useLatestEnabledLanguages, useLatestProfiles } from "."; -import { BaseInput, Selector, useSingleUpdate } from "../components"; +import { BaseInput, Selector, SelectorProps } from "../components"; +import { useFormActions } from "../utilities/FormValues"; -interface LanguageSelectorProps { +type LanguageSelectorProps = Omit< + MultiSelectorProps, + "options" | "value" | "onChange" +> & { options: readonly Language.Info[]; -} +}; export const LanguageSelector: FunctionComponent< LanguageSelectorProps & BaseInput > = ({ settingKey, options }) => { const enabled = useLatestEnabledLanguages(); - const update = useSingleUpdate(); + const { setValue } = useFormActions(); + + const wrappedOptions = useSelectorOptions(options, (value) => value.name); return ( - { - update(val, settingKey); + setValue(val, settingKey); }} - > + > ); }; export const ProfileSelector: FunctionComponent< - BaseInput -> = ({ settingKey }) => { + Omit, "beforeStaged" | "options" | "clearable"> +> = ({ ...props }) => { const profiles = useLatestProfiles(); const profileOptions = useMemo[]>( @@ -43,9 +52,9 @@ export const ProfileSelector: FunctionComponent< return ( (v === null ? "" : v)} > ); diff --git a/frontend/src/pages/Settings/Languages/index.tsx b/frontend/src/pages/Settings/Languages/index.tsx index 25b2b773d..369d911f4 100644 --- a/frontend/src/pages/Settings/Languages/index.tsx +++ b/frontend/src/pages/Settings/Languages/index.tsx @@ -1,15 +1,13 @@ import { useLanguageProfiles, useLanguages } from "@/apis/hooks"; import { useEnabledLanguages } from "@/utilities/languages"; -import { isArray } from "lodash"; import { FunctionComponent } from "react"; import { Check, CollapseBox, - Group, - Input, Layout, Message, - useLatest, + Section, + useSettingValue, } from "../components"; import { enabledLanguageKey, languageProfileKey } from "../keys"; import { LanguageSelector, ProfileSelector } from "./components"; @@ -17,7 +15,7 @@ import Table from "./table"; export function useLatestEnabledLanguages() { const { data } = useEnabledLanguages(); - const latest = useLatest(enabledLanguageKey, isArray); + const latest = useSettingValue(enabledLanguageKey); if (latest) { return latest; @@ -28,7 +26,7 @@ export function useLatestEnabledLanguages() { export function useLatestProfiles() { const { data = [] } = useLanguageProfiles(); - const latest = useLatest(languageProfileKey, isArray); + const latest = useSettingValue(languageProfileKey); if (latest) { return latest; @@ -41,70 +39,65 @@ const SettingsLanguagesView: FunctionComponent = () => { const { data: languages } = useLanguages(); return ( - - - - - Download a single Subtitles file without adding the language code to - the filename. - - - We don't recommend enabling this option unless absolutely required - (ie: media player not supporting language code in subtitles - filename). Results may vary. - - - - - - - +
    + + + Download a single Subtitles file without adding the language code to + the filename. + + + We don't recommend enabling this option unless absolutely required + (ie: media player not supporting language code in subtitles filename). + Results may vary. + + +
    +
    - - +
    +
    - - - - Apply only to Series added to Bazarr after enabling this option. - - + + + Apply only to Series added to Bazarr after enabling this option. + - - - + - - - - Apply only to Movies added to Bazarr after enabling this option. - - + + + Apply only to Movies added to Bazarr after enabling this option. + - - - + - +
    ); }; diff --git a/frontend/src/pages/Settings/Languages/modal.tsx b/frontend/src/pages/Settings/Languages/modal.tsx deleted file mode 100644 index ce807cceb..000000000 --- a/frontend/src/pages/Settings/Languages/modal.tsx +++ /dev/null @@ -1,329 +0,0 @@ -import { - ActionButton, - Chips, - LanguageSelector, - Selector, - SelectorOption, - SimpleTable, -} from "@/components"; -import { - useModal, - useModalControl, - usePayload, - withModal, -} from "@/modules/modals"; -import { BuildKey } from "@/utilities"; -import { LOG } from "@/utilities/console"; -import { faTrash } from "@fortawesome/free-solid-svg-icons"; -import { - createContext, - FunctionComponent, - useCallback, - useContext, - useMemo, - useState, -} from "react"; -import { Button, Form } from "react-bootstrap"; -import { Column } from "react-table"; -import { useLatestEnabledLanguages } from "."; -import { Input, Message } from "../components"; -import { cutoffOptions } from "./options"; - -type ModifyFn = (index: number, item?: Language.ProfileItem) => void; - -const RowContext = createContext(() => { - LOG("error", "RowContext not initialized"); -}); - -function useRowMutation() { - return useContext(RowContext); -} - -interface Props { - update: (profile: Language.Profile) => void; -} - -function createDefaultProfile(): Language.Profile { - return { - profileId: -1, - name: "", - items: [], - cutoff: null, - mustContain: [], - mustNotContain: [], - originalFormat: false, - }; -} - -const LanguagesProfileModal: FunctionComponent = ({ update }) => { - const profile = usePayload(); - - const { hide } = useModalControl(); - - const languages = useLatestEnabledLanguages(); - - const [current, setProfile] = useState(createDefaultProfile); - - const Modal = useModal({ - size: "lg", - onMounted: () => { - setProfile(profile ?? createDefaultProfile); - }, - }); - - const cutoff: SelectorOption[] = useMemo(() => { - const options = [...cutoffOptions]; - - const newOptions = current.items.map>((v) => ({ - label: `ID ${v.id} (${v.language})`, - value: v.id, - })); - - options.push(...newOptions); - - return options; - }, [current.items]); - - const updateProfile = useCallback( - (key: K, value: Language.Profile[K]) => { - const newProfile = { ...current }; - newProfile[key] = value; - setProfile(newProfile); - }, - [current] - ); - - const mutateRow = useCallback( - (index: number, item?: Language.ProfileItem) => { - const list = [...current.items]; - if (item) { - list[index] = item; - } else { - list.splice(index, 1); - } - updateProfile("items", list); - }, - [current.items, updateProfile] - ); - - const addItem = useCallback(() => { - const id = - 1 + - current.items.reduce((val, item) => Math.max(item.id, val), 0); - - if (languages.length > 0) { - const language = languages[0].code2; - - const item: Language.ProfileItem = { - id, - language, - audio_exclude: "False", - hi: "False", - forced: "False", - }; - - const list = [...current.items]; - - list.push(item); - updateProfile("items", list); - } - }, [current.items, updateProfile, languages]); - - const canSave = current.name.length > 0 && current.items.length > 0; - - const columns = useMemo[]>( - () => [ - { - Header: "ID", - accessor: "id", - }, - { - Header: "Language", - accessor: "language", - Cell: ({ value, row }) => { - const code = value; - const item = row.original; - const lang = useMemo( - () => languages.find((l) => l.code2 === code) ?? null, - [code] - ); - const mutate = useRowMutation(); - return ( -
    - { - if (l) { - item.language = l.code2; - mutate(row.index, { ...item, language: l.code2 }); - } - }} - > -
    - ); - }, - }, - { - Header: "Forced", - accessor: "forced", - Cell: ({ row, value }) => { - const item = row.original; - const mutate = useRowMutation(); - return ( - { - mutate(row.index, { - ...item, - forced: v.target.checked ? "True" : "False", - }); - }} - > - ); - }, - }, - { - Header: "HI", - accessor: "hi", - Cell: ({ row, value }) => { - const item = row.original; - const mutate = useRowMutation(); - return ( - { - mutate(row.index, { - ...item, - hi: v.target.checked ? "True" : "False", - }); - }} - > - ); - }, - }, - { - Header: "Exclude Audio", - accessor: "audio_exclude", - Cell: ({ row, value }) => { - const item = row.original; - const mutate = useRowMutation(); - return ( - { - mutate(row.index, { - ...item, - audio_exclude: v.target.checked ? "True" : "False", - }); - }} - > - ); - }, - }, - { - id: "action", - accessor: "id", - Cell: ({ row }) => { - const mutate = useRowMutation(); - return ( - mutate(row.index)} - > - ); - }, - }, - ], - [languages] - ); - - const footer = ( - - ); - - return ( - - - { - updateProfile("name", v.target.value); - }} - > - - - - - - - - - updateProfile("cutoff", num)} - > - Ignore others if existing - - - updateProfile("mustContain", mc)} - > - - Subtitles release info must include one of those words or they will be - excluded from search results (regex supported). - - - - { - updateProfile("mustNotContain", mnc); - }} - > - - Subtitles release info including one of those words (case insensitive) - will be excluded from search results (regex supported). - - - - updateProfile("originalFormat", value)} - > - Download subtitle file without format conversion - - - ); -}; - -export default withModal(LanguagesProfileModal, "languages-profile-editor"); diff --git a/frontend/src/pages/Settings/Languages/options.ts b/frontend/src/pages/Settings/Languages/options.ts deleted file mode 100644 index fc9021b79..000000000 --- a/frontend/src/pages/Settings/Languages/options.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { SelectorOption } from "@/components"; - -export const anyCutoff = 65535; - -export const cutoffOptions: SelectorOption[] = [ - { - label: "Any", - value: anyCutoff, - }, -]; diff --git a/frontend/src/pages/Settings/Languages/table.tsx b/frontend/src/pages/Settings/Languages/table.tsx index bc2cd2c4e..e4cb54e88 100644 --- a/frontend/src/pages/Settings/Languages/table.tsx +++ b/frontend/src/pages/Settings/Languages/table.tsx @@ -1,32 +1,18 @@ -import { ActionButton, SimpleTable } from "@/components"; -import { useModalControl } from "@/modules/modals"; -import { LOG } from "@/utilities/console"; -import { faTrash, faWrench } from "@fortawesome/free-solid-svg-icons"; -import { cloneDeep } from "lodash"; +import { Action, SimpleTable } from "@/components"; import { - createContext, - FunctionComponent, - useCallback, - useContext, - useMemo, -} from "react"; -import { Badge, Button, ButtonGroup } from "react-bootstrap"; + anyCutoff, + ProfileEditModal, +} from "@/components/forms/ProfileEditForm"; +import { useModals } from "@/modules/modals"; +import { BuildKey, useArrayAction } from "@/utilities"; +import { faWrench, faXmark } from "@fortawesome/free-solid-svg-icons"; +import { Badge, Button, Group } from "@mantine/core"; +import { cloneDeep } from "lodash"; +import { FunctionComponent, useCallback, useMemo } from "react"; import { Column } from "react-table"; import { useLatestEnabledLanguages, useLatestProfiles } from "."; -import { useSingleUpdate } from "../components"; import { languageProfileKey } from "../keys"; -import Modal from "./modal"; -import { anyCutoff } from "./options"; - -type ModifyFn = (index: number, item?: Language.Profile) => void; - -const RowContext = createContext(() => { - LOG("error", "RowContext not initialized"); -}); - -function useRowMutation() { - return useContext(RowContext); -} +import { useFormActions } from "../utilities/FormValues"; const Table: FunctionComponent = () => { const profiles = useLatestProfiles(); @@ -40,15 +26,15 @@ const Table: FunctionComponent = () => { [profiles] ); - const update = useSingleUpdate(); + const { setValue } = useFormActions(); - const { show } = useModalControl(); + const modals = useModals(); const submitProfiles = useCallback( (list: Language.Profile[]) => { - update(list, languageProfileKey); + setValue(list, languageProfileKey); }, - [update] + [setValue] ); const updateProfile = useCallback( @@ -66,18 +52,10 @@ const Table: FunctionComponent = () => { [profiles, submitProfiles] ); - const mutateRow = useCallback( - (index, item) => { - if (item) { - show(Modal, cloneDeep(item)); - } else { - const list = [...profiles]; - list.splice(index, 1); - submitProfiles(list); - } - }, - [show, profiles, submitProfiles] - ); + const action = useArrayAction((fn) => { + const list = [...profiles]; + submitProfiles(fn(list)); + }); const columns = useMemo[]>( () => [ @@ -91,17 +69,16 @@ const Table: FunctionComponent = () => { Cell: (row) => { const items = row.value; const cutoff = row.row.original.cutoff; - return items.map((v) => { - const isCutoff = v.id === cutoff || cutoff === anyCutoff; - return ( - - ); - }); + return ( + + {items.map((v) => { + const isCutoff = v.id === cutoff || cutoff === anyCutoff; + return ( + + ); + })} + + ); }, }, { @@ -112,9 +89,9 @@ const Table: FunctionComponent = () => { if (!items) { return false; } - return items.map((v) => { + return items.map((v, idx) => { return ( - + {v} ); @@ -129,9 +106,9 @@ const Table: FunctionComponent = () => { if (!items) { return false; } - return items.map((v) => { + return items.map((v, idx) => { return ( - + {v} ); @@ -142,39 +119,41 @@ const Table: FunctionComponent = () => { accessor: "profileId", Cell: ({ row }) => { const profile = row.original; - const mutate = useRowMutation(); - return ( - - + { - mutate(row.index, profile); + modals.openContextModal(ProfileEditModal, { + languages, + profile: cloneDeep(profile), + onComplete: updateProfile, + }); }} - > - mutate(row.index)} - > - + > + action.remove(row.index)} + > + ); }, }, ], - [] + // TODO: Optimize this + [action, languages, modals, updateProfile] ); const canAdd = languages.length !== 0; return ( <> - - - + - ); }; interface ItemProps { - className?: string; item: Language.ProfileItem; cutoff: boolean; } -const ItemBadge: FunctionComponent = ({ - cutoff, - item, - className, -}) => { +const ItemBadge: FunctionComponent = ({ cutoff, item }) => { const text = useMemo(() => { let result = item.language; if (item.hi === "True") { @@ -217,9 +194,8 @@ const ItemBadge: FunctionComponent = ({ }, [item.hi, item.forced, item.language]); return ( {text} diff --git a/frontend/src/pages/Settings/Notifications/components.tsx b/frontend/src/pages/Settings/Notifications/components.tsx index fff722c19..e6185dc9b 100644 --- a/frontend/src/pages/Settings/Notifications/components.tsx +++ b/frontend/src/pages/Settings/Notifications/components.tsx @@ -1,145 +1,103 @@ import api from "@/apis/raw"; -import { AsyncButton, Selector, SelectorOption } from "@/components"; +import { Selector } from "@/components"; +import MutateButton from "@/components/async/MutateButton"; +import { useModals, withModal } from "@/modules/modals"; +import { BuildKey, useSelectorOptions } from "@/utilities"; import { - useModal, - useModalControl, - usePayload, - withModal, -} from "@/modules/modals"; -import { BuildKey } from "@/utilities"; -import { FunctionComponent, useCallback, useMemo, useState } from "react"; -import { Button, Col, Container, Form, Row } from "react-bootstrap"; -import { ColCard, useLatestArray, useUpdateArray } from "../components"; + Button, + Divider, + Group, + SimpleGrid, + Stack, + Textarea, +} from "@mantine/core"; +import { useForm } from "@mantine/hooks"; +import { FunctionComponent, useMemo } from "react"; +import { useMutation } from "react-query"; +import { Card, useLatestArray, useUpdateArray } from "../components"; import { notificationsKey } from "../keys"; interface Props { selections: readonly Settings.NotificationInfo[]; + payload: Settings.NotificationInfo | null; + onComplete: (info: Settings.NotificationInfo) => void; } -const NotificationTool: FunctionComponent = ({ selections }) => { - const options = useMemo[]>( - () => - selections - .filter((v) => !v.enabled) - .map((v) => ({ - label: v.name, - value: v, - })), - [selections] +const NotificationForm: FunctionComponent = ({ + selections, + payload, + onComplete, +}) => { + const availableSelections = useMemo( + () => selections.filter((v) => !v.enabled || v.name === payload?.name), + [payload?.name, selections] ); + const options = useSelectorOptions(availableSelections, (v) => v.name); - const update = useUpdateArray( - notificationsKey, - "name" - ); - - const payload = usePayload(); - - const [current, setCurrent] = - useState>(payload); + const modals = useModals(); - const updateUrl = useCallback((url: string) => { - setCurrent((current) => { - if (current) { - return { - ...current, - url, - }; - } else { - return current; - } - }); - }, []); - - const canSave = - current !== null && current?.url !== null && current?.url.length !== 0; - - const getLabel = useCallback((v: Settings.NotificationInfo) => v.name, []); - - const Modal = useModal({ - onMounted: () => { - setCurrent(payload); + const form = useForm({ + initialValues: { + selection: payload, + url: payload?.url ?? "", + }, + validationRules: { + selection: (value) => value !== null, + url: (value) => value.trim() !== "", }, }); - const { hide } = useModalControl(); - - const footer = ( - <> - { - if (current && current.url) { - return api.system.testNotification(current.url); - } else { - return null; - } - }} - > - Test - - - - - ); + const test = useMutation((url: string) => api.system.testNotification(url)); return ( - - - - - - - - - { - const value = e.currentTarget.value; - updateUrl(value); - }} - > - - - - - +
    { + if (selection) { + onComplete({ ...selection, enabled: true, url }); + } + modals.closeSelf(); + })} + > + + + + + + form.values.url}> + Test + + + + + +
    ); }; -const NotificationModal = withModal(NotificationTool, "notification-tool"); +const NotificationModal = withModal(NotificationForm, "notification-tool", { + title: "Notification", +}); export const NotificationView: FunctionComponent = () => { const notifications = useLatestArray( @@ -148,27 +106,44 @@ export const NotificationView: FunctionComponent = () => { (s) => s.notifications.providers ); - const { show } = useModalControl(); + const update = useUpdateArray( + notificationsKey, + "name" + ); + + const modals = useModals(); const elements = useMemo(() => { return notifications ?.filter((v) => v.enabled) - .map((v, idx) => ( - show(NotificationModal, v)} - > + .map((payload, idx) => ( + + modals.openContextModal(NotificationModal, { + payload, + selections: notifications, + onComplete: update, + }) + } + > )); - }, [notifications, show]); + }, [modals, notifications, update]); return ( - - - {elements}{" "} - show(NotificationModal)}> - - - + + {elements} + + modals.openContextModal(NotificationModal, { + payload: null, + selections: notifications ?? [], + onComplete: update, + }) + } + > + ); }; diff --git a/frontend/src/pages/Settings/Notifications/index.tsx b/frontend/src/pages/Settings/Notifications/index.tsx index 325950805..f764bbd61 100644 --- a/frontend/src/pages/Settings/Notifications/index.tsx +++ b/frontend/src/pages/Settings/Notifications/index.tsx @@ -1,47 +1,47 @@ +import { Anchor, Blockquote, Text } from "@mantine/core"; import { FunctionComponent } from "react"; -import { Alert } from "react-bootstrap"; -import { Check, Group, Input, Layout, Message } from "../components"; +import { Check, Layout, Message, Section } from "../components"; import { NotificationView } from "./components"; const SettingsNotificationsView: FunctionComponent = () => { return ( - - Thanks to caronc for his work on{" "} -
    - apprise - - , the core of the Bazarr notification system. - - - Please follow instructions on his{" "} - - Wiki - {" "} - to configure your notification providers. - - +
    + + Thanks to caronc for his work on{" "} + + apprise + + , the core of the Bazarr notification system. + + + Please follow instructions on his{" "} + + Wiki + {" "} + to configure your notification providers. + +
    +
    - - - - - - Suppress notifications when manually download/upload subtitles. - - - +
    +
    + + + Suppress notifications when manually download/upload subtitles. + +
    ); }; diff --git a/frontend/src/pages/Settings/Providers/components.tsx b/frontend/src/pages/Settings/Providers/components.tsx index f01012ba3..93602e78a 100644 --- a/frontend/src/pages/Settings/Providers/components.tsx +++ b/frontend/src/pages/Settings/Providers/components.tsx @@ -1,44 +1,63 @@ -import { Selector, SelectorComponents, SelectorOption } from "@/components"; +import { Selector } from "@/components"; +import { useModals, withModal } from "@/modules/modals"; +import { BuildKey, isReactText, useSelectorOptions } from "@/utilities"; import { - useModal, - useModalControl, - usePayload, - withModal, -} from "@/modules/modals"; -import { BuildKey, isReactText } from "@/utilities"; -import { capitalize, isArray, isBoolean } from "lodash"; + Button, + Divider, + Group, + SimpleGrid, + Stack, + Text as MantineText, +} from "@mantine/core"; +import { useForm } from "@mantine/hooks"; +import { capitalize, isBoolean } from "lodash"; import { + forwardRef, FunctionComponent, useCallback, - useEffect, useMemo, + useRef, useState, } from "react"; -import { Button, Col, Container, Row } from "react-bootstrap"; -import { components } from "react-select"; import { + Card, Check, - ColCard, Message, - StagedChangesContext, + Password, Text, - useLatest, - useMultiUpdate, + useSettingValue, } from "../components"; +import { + FormContext, + FormValues, + useFormActions, + useStagedValues, +} from "../utilities/FormValues"; +import { SettingsProvider, useSettings } from "../utilities/SettingsProvider"; import { ProviderInfo, ProviderList } from "./list"; const ProviderKey = "settings-general-enabled_providers"; export const ProviderView: FunctionComponent = () => { - const providers = useLatest(ProviderKey, isArray); + const settings = useSettings(); + const staged = useStagedValues(); + const providers = useSettingValue(ProviderKey); + + const { update } = useFormActions(); - const { show } = useModalControl(); + const modals = useModals(); const select = useCallback( (v?: ProviderInfo) => { - show(ProviderModal, v ?? null); + modals.openContextModal(ProviderModal, { + payload: v ?? null, + enabledProviders: providers ?? [], + staged, + settings, + onChange: update, + }); }, - [show] + [modals, providers, settings, staged, update] ); const cards = useMemo(() => { @@ -53,12 +72,12 @@ export const ProviderView: FunctionComponent = () => { } }) .map((v, idx) => ( - select(v)} - > + > )); } else { return []; @@ -66,59 +85,84 @@ export const ProviderView: FunctionComponent = () => { }, [providers, select]); return ( - - - {cards} - - - - + + {cards} + select()}> + ); }; -const ProviderTool: FunctionComponent = () => { - const payload = usePayload(); - const Modal = useModal(); - const { hide } = useModalControl(); +interface ProviderToolProps { + payload: ProviderInfo | null; + // TODO: Find a better solution to pass this info to modal + enabledProviders: readonly string[]; + staged: LooseObject; + settings: Settings; + onChange: (v: LooseObject) => void; +} + +const SelectItem = forwardRef< + HTMLDivElement, + { payload: ProviderInfo; label: string } +>(({ payload: { description }, label, ...other }, ref) => { + return ( + + {label} + {description} + + ); +}); - const [staged, setChange] = useState({}); +const ProviderTool: FunctionComponent = ({ + payload, + enabledProviders, + staged, + settings, + onChange, +}) => { + const modals = useModals(); - useEffect(() => { - setInfo(payload); - }, [payload]); + const onChangeRef = useRef(onChange); + onChangeRef.current = onChange; const [info, setInfo] = useState>(payload); - const providers = useLatest(ProviderKey, isArray); - - const updateGlobal = useMultiUpdate(); + const form = useForm({ + initialValues: { + settings: staged, + storages: {}, + }, + }); const deletePayload = useCallback(() => { - if (payload && providers) { - const idx = providers.findIndex((v) => v === payload.key); + if (payload && enabledProviders) { + const idx = enabledProviders.findIndex((v) => v === payload.key); if (idx !== -1) { - const newProviders = [...providers]; + const newProviders = [...enabledProviders]; newProviders.splice(idx, 1); - updateGlobal({ [ProviderKey]: newProviders }); - hide(); + onChangeRef.current({ [ProviderKey]: newProviders }); + modals.closeAll(); } } - }, [payload, providers, updateGlobal, hide]); + }, [payload, enabledProviders, modals]); - const addProvider = useCallback(() => { - if (info && providers) { - const changes = { ...staged }; + const submit = useCallback( + (values: FormValues) => { + if (info && enabledProviders) { + const changes = { ...values.settings }; - // Add this provider if not exist - if (providers.find((v) => v === info.key) === undefined) { - const newProviders = [...providers, info.key]; - changes[ProviderKey] = newProviders; - } + // Add this provider if not exist + if (enabledProviders.find((v) => v === info.key) === undefined) { + const newProviders = [...enabledProviders, info.key]; + changes[ProviderKey] = newProviders; + } - updateGlobal(changes); - hide(); - } - }, [info, providers, staged, updateGlobal, hide]); + onChangeRef.current(changes); + modals.closeAll(); + } + }, + [info, enabledProviders, modals] + ); const canSave = info !== null; @@ -133,15 +177,19 @@ const ProviderTool: FunctionComponent = () => { } }, []); - const options = useMemo[]>( + const availableOptions = useMemo( () => ProviderList.filter( - (v) => providers?.find((p) => p === v.key) === undefined - ).map((v) => ({ - label: v.name ?? capitalize(v.key), - value: v, - })), - [providers] + (v) => + enabledProviders?.find((p) => p === v.key && p !== info?.key) === + undefined + ), + [info?.key, enabledProviders] + ); + + const options = useSelectorOptions( + availableOptions, + (v) => v.name ?? capitalize(v.key) ); const modification = useMemo(() => { @@ -162,30 +210,38 @@ const ProviderTool: FunctionComponent = () => { for (const key in defaultKey) { const value = defaultKey[key]; - let visibleKey = key; + let label = key; - if (visibleKey in override) { - visibleKey = override[visibleKey]; + if (label in override) { + label = override[label]; } else { - visibleKey = capitalize(key); + label = capitalize(key); } if (isReactText(value)) { - elements.push( - + if (key === "password") { + elements.push( + + ); + } else { + elements.push( - - ); + ); + } } else if (isBoolean(value)) { checks.push( ); @@ -193,79 +249,46 @@ const ProviderTool: FunctionComponent = () => { } return ( - + {elements} - - {checks} - - + + ); }, [info]); - const selectorComponents = useMemo< - Partial> - >( - () => ({ - Option: ({ data, ...other }) => { - const { label, value } = data; - return ( - - {label} -

    {value.description}

    -
    - ); - }, - }), - [] - ); - - const getLabel = useCallback( - (v: ProviderInfo) => v.name ?? capitalize(v.key), - [] - ); - - const footer = ( - <> - - - - ); - return ( - - - - - - - - - - - {info?.description} - - - {modification} -
    ); }, }, @@ -60,13 +94,7 @@ const Table: FunctionComponent = ({ backups }) => { [] ); - return ( - - - - - - ); + return ; }; export default Table; diff --git a/frontend/src/pages/System/Logs/index.tsx b/frontend/src/pages/System/Logs/index.tsx index 86cc96df1..8d12847d7 100644 --- a/frontend/src/pages/System/Logs/index.tsx +++ b/frontend/src/pages/System/Logs/index.tsx @@ -1,10 +1,11 @@ import { useDeleteLogs, useSystemLogs } from "@/apis/hooks"; -import { ContentHeader, QueryOverlay } from "@/components"; +import { Toolbox } from "@/components"; +import { QueryOverlay } from "@/components/async"; import { Environment } from "@/utilities"; import { faDownload, faSync, faTrash } from "@fortawesome/free-solid-svg-icons"; +import { Container, Group } from "@mantine/core"; +import { useDocumentTitle } from "@mantine/hooks"; import { FunctionComponent, useCallback } from "react"; -import { Container, Row } from "react-bootstrap"; -import { Helmet } from "react-helmet"; import Table from "./table"; const SystemLogsView: FunctionComponent = () => { @@ -17,36 +18,35 @@ const SystemLogsView: FunctionComponent = () => { window.open(`${Environment.baseUrl}/bazarr.log`); }, []); + useDocumentTitle("Logs - Bazarr (System)"); + return ( - - - - Logs - Bazarr (System) - - - refetch()} - > - Refresh - - - Download - - mutate()} - > - Empty - - - -
    -
    -
    -
    + + + + + refetch()} + > + Refresh + + + Download + + mutate()} + > + Empty + + + +
    +
    +
    ); }; diff --git a/frontend/src/pages/System/Logs/modal.tsx b/frontend/src/pages/System/Logs/modal.tsx index 5632eb412..0ecceb742 100644 --- a/frontend/src/pages/System/Logs/modal.tsx +++ b/frontend/src/pages/System/Logs/modal.tsx @@ -1,28 +1,26 @@ -import { useModal, usePayload, withModal } from "@/modules/modals"; +import { withModal } from "@/modules/modals"; +import { Code, Text } from "@mantine/core"; import { FunctionComponent, useMemo } from "react"; -const SystemLogModal: FunctionComponent = () => { - const stack = usePayload(); - - const Modal = useModal(); +interface Props { + stack: string; +} +const SystemLogModal: FunctionComponent = ({ stack }) => { const result = useMemo( () => - stack?.split("\\n").map((v, idx) => ( -

    + stack.split("\\n").map((v, idx) => ( + {v} -

    + )), [stack] ); - return ( - -
    -        {result}
    -      
    -
    - ); + return {result}; }; -export default withModal(SystemLogModal, "system-log"); +export default withModal(SystemLogModal, "system-log", { + title: "Stack Traceback", + size: "xl", +}); diff --git a/frontend/src/pages/System/Logs/table.tsx b/frontend/src/pages/System/Logs/table.tsx index d08c7fcbf..9f0d7110d 100644 --- a/frontend/src/pages/System/Logs/table.tsx +++ b/frontend/src/pages/System/Logs/table.tsx @@ -1,5 +1,5 @@ -import { ActionButton, PageTable } from "@/components"; -import { useModalControl } from "@/modules/modals"; +import { Action, PageTable } from "@/components"; +import { useModals } from "@/modules/modals"; import { IconDefinition } from "@fortawesome/fontawesome-svg-core"; import { faBug, @@ -50,18 +50,19 @@ const Table: FunctionComponent = ({ logs }) => { { Header: "Date", accessor: "timestamp", - className: "text-nowrap", }, { accessor: "exception", Cell: ({ value }) => { - const { show } = useModalControl(); + const modals = useModals(); if (!isUndefined(value)) { return ( - show(SystemLogModal, value)} - > + onClick={() => + modals.openContextModal(SystemLogModal, { stack: value }) + } + > ); } else { return null; @@ -75,7 +76,6 @@ const Table: FunctionComponent = ({ logs }) => { return ( <> - ); }; diff --git a/frontend/src/pages/System/Providers/index.tsx b/frontend/src/pages/System/Providers/index.tsx index a468c4638..cd7086221 100644 --- a/frontend/src/pages/System/Providers/index.tsx +++ b/frontend/src/pages/System/Providers/index.tsx @@ -1,9 +1,10 @@ import { useResetProvider, useSystemProviders } from "@/apis/hooks"; -import { ContentHeader, QueryOverlay } from "@/components"; +import { Toolbox } from "@/components"; +import { QueryOverlay } from "@/components/async"; import { faSync, faTrash } from "@fortawesome/free-solid-svg-icons"; +import { Container, Group } from "@mantine/core"; +import { useDocumentTitle } from "@mantine/hooks"; import { FunctionComponent } from "react"; -import { Container, Row } from "react-bootstrap"; -import { Helmet } from "react-helmet"; import Table from "./table"; const SystemProvidersView: FunctionComponent = () => { @@ -13,31 +14,30 @@ const SystemProvidersView: FunctionComponent = () => { const { mutate: reset, isLoading: isResetting } = useResetProvider(); + useDocumentTitle("Providers - Bazarr (System)"); + return ( - - - Providers - Bazarr (System) - - - refetch()} - > - Refresh - - reset()} - > - Reset - - - -
    -
    + + + + refetch()} + > + Refresh + + reset()} + > + Reset + + + +
    ); diff --git a/frontend/src/pages/System/Releases/index.tsx b/frontend/src/pages/System/Releases/index.tsx index 32c8bd3e0..93768b015 100644 --- a/frontend/src/pages/System/Releases/index.tsx +++ b/frontend/src/pages/System/Releases/index.tsx @@ -1,37 +1,39 @@ import { useSystemReleases } from "@/apis/hooks"; -import { QueryOverlay } from "@/components"; +import { QueryOverlay } from "@/components/async"; import { BuildKey } from "@/utilities"; +import { + Badge, + Card, + Container, + Divider, + Group, + List, + Stack, + Text, +} from "@mantine/core"; +import { useDocumentTitle } from "@mantine/hooks"; import { FunctionComponent, useMemo } from "react"; -import { Badge, Card, Col, Container, Row } from "react-bootstrap"; -import { Helmet } from "react-helmet"; const SystemReleasesView: FunctionComponent = () => { const releases = useSystemReleases(); const { data } = releases; + useDocumentTitle("Releases - Bazarr (System)"); + return ( - - - Releases - Bazarr (System) - - - - <> - {data?.map((v, idx) => ( - - - - ))} - - - + + + + {data?.map((v, idx) => ( + + ))} + + ); }; -const headerBadgeCls = "mr-2"; - -const InfoElement: FunctionComponent = ({ +const ReleaseCard: FunctionComponent = ({ name, body, date, @@ -43,32 +45,24 @@ const InfoElement: FunctionComponent = ({ [body] ); return ( - - - {name} - - {date} - - + + + {name} + {date} + {prerelease ? "Development" : "Master"} - - - - From newest to oldest: -
    - {infos.map((v, idx) => ( -
  • {v}
  • - ))} -
    -
    -
    + + + From newest to oldest: + + {infos.map((v, idx) => ( + {v} + ))} +
    ); }; diff --git a/frontend/src/pages/System/Status/index.tsx b/frontend/src/pages/System/Status/index.tsx index fc7aaa98c..c3352f9e0 100644 --- a/frontend/src/pages/System/Status/index.tsx +++ b/frontend/src/pages/System/Status/index.tsx @@ -1,6 +1,6 @@ import { useSystemHealth, useSystemStatus } from "@/apis/hooks"; -import { QueryOverlay } from "@/components"; -import { GithubRepoRoot } from "@/utilities/constants"; +import { QueryOverlay } from "@/components/async"; +import { GithubRepoRoot } from "@/constants"; import { IconDefinition } from "@fortawesome/fontawesome-common-types"; import { faDiscord, @@ -9,11 +9,10 @@ import { } from "@fortawesome/free-brands-svg-icons"; import { faPaperPlane } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { Anchor, Container, Divider, Grid, Stack, Text } from "@mantine/core"; +import { useDocumentTitle, useInterval } from "@mantine/hooks"; import moment from "moment"; -import { FunctionComponent, ReactNode, useState } from "react"; -import { Col, Container, Row } from "react-bootstrap"; -import { Helmet } from "react-helmet"; -import { useIntervalWhen } from "rooks"; +import { FunctionComponent, ReactNode, useEffect, useState } from "react"; import Table from "./table"; interface InfoProps { @@ -21,15 +20,17 @@ interface InfoProps { children: ReactNode; } -function CRow(props: InfoProps): JSX.Element { +function Row(props: InfoProps): JSX.Element { const { title, children } = props; return ( - - - {title} - - {children} - + + + {title} + + + {children} + + ); } @@ -44,9 +45,9 @@ function Label(props: IconProps): JSX.Element { return ( <> - + {children} - + ); } @@ -56,11 +57,11 @@ const InfoContainer: FunctionComponent<{ title: string }> = ({ children, }) => { return ( - +

    {title}

    -
    + {children} -
    + ); }; @@ -68,97 +69,76 @@ const SystemStatusView: FunctionComponent = () => { const health = useSystemHealth(); const { data: status } = useSystemStatus(); - const [uptime, setState] = useState(); - const [intervalWhenState] = useState(true); + const [uptime, setUptime] = useState(); - useIntervalWhen( - () => { - if (status) { - const duration = moment.duration( - moment().utc().unix() - status.start_time, - "seconds" - ), - days = duration.days(), - hours = duration.hours().toString().padStart(2, "0"), - minutes = duration.minutes().toString().padStart(2, "0"), - seconds = duration.seconds().toString().padStart(2, "0"); - setState(days + "d " + hours + ":" + minutes + ":" + seconds); - } - }, - 1000, - intervalWhenState, - true - ); + const interval = useInterval(() => { + if (status) { + const duration = moment.duration( + moment().utc().unix() - status.start_time, + "seconds" + ), + days = duration.days(), + hours = duration.hours().toString().padStart(2, "0"), + minutes = duration.minutes().toString().padStart(2, "0"), + seconds = duration.seconds().toString().padStart(2, "0"); + setUptime(days + "d " + hours + ":" + minutes + ":" + seconds); + } + }, 1000); + + useEffect(() => { + interval.start(); + return interval.stop(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + useDocumentTitle("Status - Bazarr (System)"); return ( - - - Status - Bazarr (System) - - + +
    -
    - - - {status?.bazarr_version} - + {status?.bazarr_version} {status?.package_version !== "" && ( - - {status?.package_version} - + {status?.package_version} )} - - {status?.sonarr_version} - - - {status?.radarr_version} - - - {status?.operating_system} - - - {status?.python_version} - - - {status?.bazarr_directory} - - - {status?.bazarr_config_directory} - - - {uptime} - + {status?.sonarr_version} + {status?.radarr_version} + {status?.operating_system} + {status?.python_version} + {status?.bazarr_directory} + + {status?.bazarr_config_directory} + + {uptime} - - - + - - + + - - + + - - + + - + - +
    ); }; diff --git a/frontend/src/pages/System/Status/table.tsx b/frontend/src/pages/System/Status/table.tsx index 18b3588f3..c570fbabf 100644 --- a/frontend/src/pages/System/Status/table.tsx +++ b/frontend/src/pages/System/Status/table.tsx @@ -1,4 +1,6 @@ import { SimpleTable } from "@/components"; +import { useTableStyles } from "@/styles"; +import { Text } from "@mantine/core"; import { FunctionComponent, useMemo } from "react"; import { Column } from "react-table"; @@ -12,11 +14,18 @@ const Table: FunctionComponent = ({ health }) => { { Header: "Object", accessor: "object", + Cell: ({ value }) => { + const { classes } = useTableStyles(); + return {value}; + }, }, { Header: "Issue", accessor: "issue", - className: "status-issue", + Cell: ({ value }) => { + const { classes } = useTableStyles(); + return {value}; + }, }, ], [] @@ -24,10 +33,9 @@ const Table: FunctionComponent = ({ health }) => { return ( ); }; diff --git a/frontend/src/pages/System/Tasks/index.tsx b/frontend/src/pages/System/Tasks/index.tsx index f639ae5c6..17e429152 100644 --- a/frontend/src/pages/System/Tasks/index.tsx +++ b/frontend/src/pages/System/Tasks/index.tsx @@ -1,9 +1,10 @@ import { useSystemTasks } from "@/apis/hooks"; -import { ContentHeader, QueryOverlay } from "@/components"; +import { Toolbox } from "@/components"; +import { QueryOverlay } from "@/components/async"; import { faSync } from "@fortawesome/free-solid-svg-icons"; +import { Container } from "@mantine/core"; +import { useDocumentTitle } from "@mantine/hooks"; import { FunctionComponent } from "react"; -import { Container, Row } from "react-bootstrap"; -import { Helmet } from "react-helmet"; import Table from "./table"; const SystemTasksView: FunctionComponent = () => { @@ -11,24 +12,21 @@ const SystemTasksView: FunctionComponent = () => { const { isFetching, data, refetch } = tasks; + useDocumentTitle("Tasks - Bazarr (System)"); + return ( - - - Tasks - Bazarr (System) - - - + + refetch()} > Refresh - - - -
    -
    + + +
    ); diff --git a/frontend/src/pages/System/Tasks/table.tsx b/frontend/src/pages/System/Tasks/table.tsx index d41217efe..efb10e952 100644 --- a/frontend/src/pages/System/Tasks/table.tsx +++ b/frontend/src/pages/System/Tasks/table.tsx @@ -1,7 +1,9 @@ import { useRunTask } from "@/apis/hooks"; -import { AsyncButton, SimpleTable } from "@/components"; +import { SimpleTable } from "@/components"; +import MutateAction from "@/components/async/MutateAction"; +import { useTableStyles } from "@/styles"; import { faSync } from "@fortawesome/free-solid-svg-icons"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { Text } from "@mantine/core"; import { FunctionComponent, useMemo } from "react"; import { Column, useSortBy } from "react-table"; @@ -15,33 +17,36 @@ const Table: FunctionComponent = ({ tasks }) => { { Header: "Name", accessor: "name", - className: "text-nowrap", + Cell: ({ value }) => { + const { classes } = useTableStyles(); + return {value}; + }, }, { Header: "Interval", accessor: "interval", - className: "text-nowrap", + Cell: ({ value }) => { + const { classes } = useTableStyles(); + return {value}; + }, }, { Header: "Next Execution", accessor: "next_run_in", - className: "text-nowrap", }, { accessor: "job_running", - Cell: (row) => { - const { job_id } = row.row.original; - const { mutateAsync } = useRunTask(); + Cell: ({ row, value }) => { + const { job_id } = row.original; + const runTask = useRunTask(); + return ( - mutateAsync(job_id)} - variant="light" - size="sm" - disabled={row.value} - animation={false} - > - - + job_id} + > ); }, }, diff --git a/frontend/src/pages/UIError.tsx b/frontend/src/pages/UIError.tsx index 4d86dc71b..22def326b 100644 --- a/frontend/src/pages/UIError.tsx +++ b/frontend/src/pages/UIError.tsx @@ -1,34 +1,46 @@ +import { GithubRepoRoot } from "@/constants"; import { Reload } from "@/utilities"; -import { GithubRepoRoot } from "@/utilities/constants"; import { faDizzy } from "@fortawesome/free-regular-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { + Anchor, + Box, + Button, + Center, + Container, + Group, + Text, + Title, +} from "@mantine/core"; import { FunctionComponent } from "react"; -import { Button, Container } from "react-bootstrap"; interface Props { error: Error; } const UIError: FunctionComponent = ({ error }) => ( - -

    - - Oops! UI is crashed! -

    -

    {error.message}

    -
    - - + + -
    +
    ); diff --git a/frontend/src/pages/Wanted/Movies/index.tsx b/frontend/src/pages/Wanted/Movies/index.tsx index 1be04cee0..d4334c9cd 100644 --- a/frontend/src/pages/Wanted/Movies/index.tsx +++ b/frontend/src/pages/Wanted/Movies/index.tsx @@ -3,14 +3,14 @@ import { useMovieSubtitleModification, useMovieWantedPagination, } from "@/apis/hooks"; -import { AsyncButton } from "@/components"; import Language from "@/components/bazarr/Language"; -import WantedView from "@/components/views/WantedView"; +import { task, TaskGroup } from "@/modules/task"; +import WantedView from "@/pages/views/WantedView"; import { BuildKey } from "@/utilities"; import { faSearch } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { Anchor, Badge, Group } from "@mantine/core"; import { FunctionComponent, useMemo } from "react"; -import { Badge } from "react-bootstrap"; import { Link } from "react-router-dom"; import { Column } from "react-table"; @@ -23,9 +23,9 @@ const WantedMoviesView: FunctionComponent = () => { Cell: (row) => { const target = `/movies/${row.row.original.radarrId}`; return ( - - {row.value} - + + {row.value} + ); }, }, @@ -38,27 +38,35 @@ const WantedMoviesView: FunctionComponent = () => { const { download } = useMovieSubtitleModification(); - return value.map((item, idx) => ( - - download.mutateAsync({ - radarrId, - form: { - language: item.code2, - hi, - forced: false, - }, - }) - } - > - - - - )); + return ( + + {value.map((item, idx) => ( + } + key={BuildKey(idx, item.code2)} + style={{ cursor: "pointer" }} + onClick={() => { + task.create( + item.name, + TaskGroup.SearchSubtitle, + download.mutateAsync, + { + radarrId, + form: { + language: item.code2, + hi, + forced: false, + }, + } + ); + }} + > + + + ))} + + ); }, }, ], diff --git a/frontend/src/pages/Wanted/Series/index.tsx b/frontend/src/pages/Wanted/Series/index.tsx index e9d6ccd70..e04f91dca 100644 --- a/frontend/src/pages/Wanted/Series/index.tsx +++ b/frontend/src/pages/Wanted/Series/index.tsx @@ -3,14 +3,15 @@ import { useEpisodeWantedPagination, useSeriesAction, } from "@/apis/hooks"; -import { AsyncButton } from "@/components"; import Language from "@/components/bazarr/Language"; -import WantedView from "@/components/views/WantedView"; +import { task, TaskGroup } from "@/modules/task"; +import WantedView from "@/pages/views/WantedView"; +import { useTableStyles } from "@/styles"; import { BuildKey } from "@/utilities"; import { faSearch } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { Anchor, Badge, Group, Text } from "@mantine/core"; import { FunctionComponent, useMemo } from "react"; -import { Badge } from "react-bootstrap"; import { Link } from "react-router-dom"; import { Column } from "react-table"; @@ -22,10 +23,11 @@ const WantedSeriesView: FunctionComponent = () => { accessor: "seriesTitle", Cell: (row) => { const target = `/series/${row.row.original.sonarrSeriesId}`; + const { classes } = useTableStyles(); return ( - - {row.value} - + + {row.value} + ); }, }, @@ -35,6 +37,11 @@ const WantedSeriesView: FunctionComponent = () => { }, { accessor: "episodeTitle", + Cell: ({ value }) => { + const { classes } = useTableStyles(); + + return {value}; + }, }, { Header: "Missing", @@ -47,28 +54,36 @@ const WantedSeriesView: FunctionComponent = () => { const { download } = useEpisodeSubtitleModification(); - return value.map((item, idx) => ( - - download.mutateAsync({ - seriesId, - episodeId, - form: { - language: item.code2, - hi, - forced: false, - }, - }) - } - > - - - - )); + return ( + + {value.map((item, idx) => ( + } + key={BuildKey(idx, item.code2)} + style={{ cursor: "pointer" }} + onClick={() => { + task.create( + item.name, + TaskGroup.SearchSubtitle, + download.mutateAsync, + { + seriesId, + episodeId, + form: { + language: item.code2, + hi, + forced: false, + }, + } + ); + }} + > + + + ))} + + ); }, }, ], diff --git a/frontend/src/pages/views/HistoryView.tsx b/frontend/src/pages/views/HistoryView.tsx new file mode 100644 index 000000000..2ecc74afb --- /dev/null +++ b/frontend/src/pages/views/HistoryView.tsx @@ -0,0 +1,30 @@ +import { UsePaginationQueryResult } from "@/apis/queries/hooks"; +import { QueryPageTable } from "@/components"; +import { Container } from "@mantine/core"; +import { useDocumentTitle } from "@mantine/hooks"; +import { Column } from "react-table"; + +interface Props { + name: string; + query: UsePaginationQueryResult; + columns: Column[]; +} + +function HistoryView({ + columns, + name, + query, +}: Props) { + useDocumentTitle(`${name} History - Bazarr`); + return ( + + + + ); +} + +export default HistoryView; diff --git a/frontend/src/pages/views/ItemOverview.tsx b/frontend/src/pages/views/ItemOverview.tsx new file mode 100644 index 000000000..8d3d4135e --- /dev/null +++ b/frontend/src/pages/views/ItemOverview.tsx @@ -0,0 +1,237 @@ +import { Language } from "@/components/bazarr"; +import { BuildKey, isMovie } from "@/utilities"; +import { + useLanguageProfileBy, + useProfileItemsToLanguages, +} from "@/utilities/languages"; +import { + faBookmark as farBookmark, + faFolder, +} from "@fortawesome/free-regular-svg-icons"; +import { + faBookmark, + faClone, + faLanguage, + faMusic, + faStream, + faTags, + IconDefinition, +} from "@fortawesome/free-solid-svg-icons"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { + BackgroundImage, + Badge, + BadgeProps, + Box, + createStyles, + Grid, + Group, + Image, + List, + MediaQuery, + Popover, + Stack, + Text, + Title, +} from "@mantine/core"; +import { useHover } from "@mantine/hooks"; +import { FunctionComponent, useMemo } from "react"; + +interface Props { + item: Item.Base | null; + details?: { icon: IconDefinition; text: string }[]; +} + +const useStyles = createStyles((theme) => { + return { + poster: { + maxWidth: "250px", + }, + col: { + maxWidth: "100%", + }, + group: { + maxWidth: "100%", + }, + }; +}); + +const ItemOverview: FunctionComponent = (props) => { + const { item, details } = props; + + const { classes } = useStyles(); + + const detailBadges = useMemo(() => { + const badges: (JSX.Element | null)[] = []; + + if (item) { + badges.push( + + {item.path} + + ); + + badges.push( + ...(details?.map((val, idx) => ( + + {val.text} + + )) ?? []) + ); + + if (item.tags.length > 0) { + badges.push( + + {item.tags.join("|")} + + ); + } + } + + return badges; + }, [details, item]); + + const audioBadges = useMemo( + () => + item?.audio_language.map((v, idx) => ( + + {v.name} + + )) ?? [], + [item?.audio_language] + ); + + const profile = useLanguageProfileBy(item?.profileId); + const profileItems = useProfileItemsToLanguages(profile); + + const languageBadges = useMemo(() => { + const badges: (JSX.Element | null)[] = []; + + if (profile) { + badges.push( + + {profile.name} + + ); + + badges.push( + ...profileItems.map((v, idx) => ( + + + + )) + ); + } + + return badges; + }, [profile, profileItems]); + + const { ref, hovered } = useHover(); + + return ( + + + + + + + + + + + + <Text inherit color="white"> + {item && isMovie(item) ? ( + <Box component="span" mr={12}> + <FontAwesomeIcon + title={item.monitored ? "monitored" : "unmonitored"} + icon={item.monitored ? faBookmark : farBookmark} + ></FontAwesomeIcon> + </Box> + ) : null} + {item?.title} + </Text> + + + + + {detailBadges} + + + {audioBadges} + + + {languageBadges} + + + {item?.overview} + + + + + + ); +}; + +type ItemBadgeProps = Omit, "leftSection"> & { + icon: IconDefinition; +}; + +const ItemBadge: FunctionComponent = ({ icon, ...props }) => ( + } + radius="sm" + color="dark" + size="sm" + style={{ textTransform: "none" }} + {...props} + > +); + +export default ItemOverview; diff --git a/frontend/src/components/views/ItemView.tsx b/frontend/src/pages/views/ItemView.tsx similarity index 50% rename from frontend/src/components/views/ItemView.tsx rename to frontend/src/pages/views/ItemView.tsx index 8c48e243d..8fdaf83c8 100644 --- a/frontend/src/components/views/ItemView.tsx +++ b/frontend/src/pages/views/ItemView.tsx @@ -1,10 +1,8 @@ import { UsePaginationQueryResult } from "@/apis/queries/hooks"; -import { TableStyleProps } from "@/components/tables/BaseTable"; +import { QueryPageTable, Toolbox } from "@/components"; import { faList } from "@fortawesome/free-solid-svg-icons"; -import { Row } from "react-bootstrap"; import { useNavigate } from "react-router-dom"; -import { Column, TableOptions } from "react-table"; -import { ContentHeader, QueryPageTable } from ".."; +import { Column } from "react-table"; interface Props { query: UsePaginationQueryResult; @@ -14,29 +12,22 @@ interface Props { function ItemView({ query, columns }: Props) { const navigate = useNavigate(); - const options: Partial & TableStyleProps> = { - emptyText: `No Items Found`, - }; - return ( <> - - + navigate("edit")} > Mass Edit - - - - - + + + ); } diff --git a/frontend/src/components/MassEditor.tsx b/frontend/src/pages/views/MassEditor.tsx similarity index 53% rename from frontend/src/components/MassEditor.tsx rename to frontend/src/pages/views/MassEditor.tsx index 9a6fdb0e3..3e6fa1035 100644 --- a/frontend/src/components/MassEditor.tsx +++ b/frontend/src/pages/views/MassEditor.tsx @@ -1,14 +1,15 @@ import { useIsAnyMutationRunning, useLanguageProfiles } from "@/apis/hooks"; -import { GetItemId } from "@/utilities"; +import { SimpleTable, Toolbox } from "@/components"; +import { Selector } from "@/components/inputs"; +import { useCustomSelection } from "@/components/tables/plugins"; +import { GetItemId, useSelectorOptions } from "@/utilities"; import { faCheck, faUndo } from "@fortawesome/free-solid-svg-icons"; +import { Container } from "@mantine/core"; import { uniqBy } from "lodash"; import { useCallback, useMemo, useState } from "react"; -import { Container, Dropdown, Row } from "react-bootstrap"; import { UseMutationResult } from "react-query"; import { useNavigate } from "react-router-dom"; import { Column, useRowSelect } from "react-table"; -import { ContentHeader, SimpleTable } from "."; -import { useCustomSelection } from "./tables/plugins"; interface MassEditorProps { columns: Column[]; @@ -33,24 +34,7 @@ function MassEditor(props: MassEditorProps) { [dirties, raw] ); - const profileOptions = useMemo(() => { - const items: JSX.Element[] = []; - if (profiles) { - items.push( - Clear Profile - ); - items.push(); - items.push( - ...profiles.map((v) => ( - - {v.name} - - )) - ); - } - - return items; - }, [profiles]); + const profileOptions = useSelectorOptions(profiles ?? [], (v) => v.name); const { mutateAsync } = mutation; @@ -70,9 +54,8 @@ function MassEditor(props: MassEditorProps) { }, [dirties, mutateAsync]); const setProfiles = useCallback( - (key: Nullable) => { - const id = key ? parseInt(key) : null; - + (profile: Language.Profile | null) => { + const id = profile?.profileId ?? null; const newItems = selections.map((v) => ({ ...v, profileId: id })); setDirties((dirty) => { @@ -82,38 +65,36 @@ function MassEditor(props: MassEditorProps) { [selections] ); return ( - - - - - - Change Profile - - {profileOptions} - - - - + + +
    + +
    +
    + Cancel - - + Save - - - - - - + +
    +
    +
    ); } diff --git a/frontend/src/components/views/WantedView.tsx b/frontend/src/pages/views/WantedView.tsx similarity index 50% rename from frontend/src/components/views/WantedView.tsx rename to frontend/src/pages/views/WantedView.tsx index 93da3302a..5605bf337 100644 --- a/frontend/src/components/views/WantedView.tsx +++ b/frontend/src/pages/views/WantedView.tsx @@ -1,11 +1,10 @@ import { useIsAnyActionRunning } from "@/apis/hooks"; import { UsePaginationQueryResult } from "@/apis/queries/hooks"; -import { createAndDispatchTask } from "@/modules/task/utilities"; +import { QueryPageTable, Toolbox } from "@/components"; import { faSearch } from "@fortawesome/free-solid-svg-icons"; -import { Container, Row } from "react-bootstrap"; -import { Helmet } from "react-helmet"; +import { Container } from "@mantine/core"; +import { useDocumentTitle } from "@mantine/hooks"; import { Column } from "react-table"; -import { ContentHeader, QueryPageTable } from ".."; interface Props { name: string; @@ -20,34 +19,27 @@ function WantedView({ query, searchAll, }: Props) { - // TODO const dataCount = query.paginationStatus.totalCount; const hasTask = useIsAnyActionRunning(); + useDocumentTitle(`Wanted ${name} - Bazarr`); + return ( - - - Wanted {name} - Bazarr - - - + + { - createAndDispatchTask(name, "search-subtitles", searchAll); - }} + onClick={searchAll} icon={faSearch} > Search All - - - - - + + + ); } diff --git a/frontend/src/styles/_custom-bootstrap.scss b/frontend/src/styles/_custom-bootstrap.scss deleted file mode 100644 index dc4fac3ef..000000000 --- a/frontend/src/styles/_custom-bootstrap.scss +++ /dev/null @@ -1,20 +0,0 @@ -@use "variables" as vars; - -$primary: #911f93; -$dark: #4f566f; - -@import "bootstrap"; - -.progress-bar { - cursor: default; - text-shadow: -0.16rem -0.16rem 0.24rem $primary, - 0.16rem -0.16rem 0.24rem $primary, -0.16rem 0.16rem 0.24rem $primary, - 0.16rem 0.16rem 0.24rem $primary; - overflow: visible; -} - -.dropdown-toggle { - &.hide-arrow::after { - display: none; - } -} diff --git a/frontend/src/styles/_global.scss b/frontend/src/styles/_global.scss deleted file mode 100644 index d5de64ae6..000000000 --- a/frontend/src/styles/_global.scss +++ /dev/null @@ -1,38 +0,0 @@ -@use "custom-bootstrap" as bs; - -// Reduce padding of cells in react-table -.table td, -.table th { - padding: 0.4rem !important; -} - -a { - color: bs.$primary; - text-decoration: none; - background-color: transparent; - - &:hover { - color: bs.$primary; - text-decoration: underline; - } -} - -:root { - .form-control { - &:focus { - outline-color: none !important; - box-shadow: none !important; - border-color: bs.$primary !important; - } - } -} - -td { - vertical-align: middle !important; -} - -body { - font-family: "Roboto", "open sans", "Helvetica Neue", "Helvetica", "Arial", - sans-serif !important; - font-weight: 300 !important; -} diff --git a/frontend/src/styles/_layout.scss b/frontend/src/styles/_layout.scss deleted file mode 100644 index c6a34f2c8..000000000 --- a/frontend/src/styles/_layout.scss +++ /dev/null @@ -1,170 +0,0 @@ -@use "variables" as vars; -@use "custom-bootstrap" as bs; - -@mixin sidebar-animation { - transition: { - duration: 0.2s; - timing-function: ease-in-out; - } -} - -@include bs.media-breakpoint-up(sm) { - .main-router { - max-width: calc(100% - #{vars.$sidebar-width}); - } - - .header-icon { - min-width: vars.$sidebar-width; - } - - .sidebar-container { - position: sticky; - } -} - -@include bs.media-breakpoint-down(sm) { - .main-router { - max-width: 100%; - } - - .header-icon { - min-width: 0; - } - - .sidebar-container { - position: fixed !important; - transform: translateX(-100%); - - @include sidebar-animation(); - - &.open { - transform: translateX(0) !important; - } - } - - .sidebar-overlay { - @include sidebar-animation(); - - &.open { - display: block !important; - opacity: 0.6; - } - } -} - -@mixin border($side) { - border: { - #{$side}: { - color: rgba(0, 0, 0, 0.125); - style: solid; - width: 0.08rem; - } - } -} - -$sidebar-bg-color: #3a3f51; -$sidebar-active-color: #252833; - -.sidebar-overlay { - display: none; - position: fixed; - top: 0; - bottom: 0; - left: 0; - right: 0; - background-color: black; - opacity: 0; - z-index: 1000; -} - -.sidebar-container { - top: 0; - height: 100vh; - overflow-y: auto; - background-color: $sidebar-bg-color; - - z-index: 1001; - - min-width: vars.$sidebar-width; - max-width: vars.$sidebar-width; - - flex-grow: 2; - - span { - font-size: 0.85rem; - letter-spacing: 0.04rem; - } - - scrollbar-width: none; - &::-webkit-scrollbar { - width: 0; - height: 0; - } - - .title { - height: vars.$header-height; - } - - @mixin active { - content: ""; - display: block; - position: absolute; - top: 0; - bottom: 0; - left: 0; - width: 0.1rem; - z-index: 10; - background-color: bs.$primary; - } - - .sidebar-collapse-box { - position: relative; - &.active { - &::before { - @include active(); - } - } - } - - .indent > * { - padding-left: 2.5rem; - } - - .button { - display: flex; - align-items: center; - flex-wrap: nowrap; - - border: none; - outline: none; - - color: white !important; - background-color: $sidebar-bg-color; - - &:hover { - background-color: $sidebar-active-color !important; - } - - &:active, - &:focus { - color: white; - background-color: $sidebar-bg-color; - } - - .icon { - margin-right: 1rem; - width: 1.5rem; - } - - &.active { - background-color: $sidebar-active-color; - &::before { - @include active(); - } - } - - &.collapse { - padding-left: 3rem; - } - } -} diff --git a/frontend/src/styles/_variables.scss b/frontend/src/styles/_variables.scss deleted file mode 100644 index d67450e97..000000000 --- a/frontend/src/styles/_variables.scss +++ /dev/null @@ -1,2 +0,0 @@ -$sidebar-width: 12.6rem; -$header-height: 3.6rem; diff --git a/frontend/src/styles/components/_auth.scss b/frontend/src/styles/components/_auth.scss deleted file mode 100644 index 26b2bb602..000000000 --- a/frontend/src/styles/components/_auth.scss +++ /dev/null @@ -1,3 +0,0 @@ -.auth-card { - width: 24rem; -} diff --git a/frontend/src/styles/components/_chart.scss b/frontend/src/styles/components/_chart.scss deleted file mode 100644 index 160e505b4..000000000 --- a/frontend/src/styles/components/_chart.scss +++ /dev/null @@ -1,6 +0,0 @@ -@use "../variables" as vars; - -.chart-container { - height: calc(100vh - #{vars.$header-height}); - padding-bottom: 0.6rem; -} diff --git a/frontend/src/styles/components/_chip.scss b/frontend/src/styles/components/_chip.scss deleted file mode 100644 index de27623f5..000000000 --- a/frontend/src/styles/components/_chip.scss +++ /dev/null @@ -1,45 +0,0 @@ -@use "../custom-bootstrap" as bs; - -.custom-chip-input { - overflow: hidden; - &:focus-within { - border-color: bs.$primary; - } - .main-input { - border: hidden; - outline: none; - width: 100%; - flex-grow: 2; - } - - .chip-container { - display: flex; - flex-wrap: nowrap; - flex-grow: 1; - } - - .custom-chip { - padding: 0 0.5rem; - margin-right: 0.25rem; - background-color: bs.$light; - border-radius: 0.25rem; - - max-width: 10rem; - - overflow-x: hidden; - text-overflow: ellipsis; - - transition: { - duration: 0.1s; - timing-function: ease-in-out; - } - - &.active { - &:hover { - cursor: pointer; - background-color: bs.$danger; - color: white; - } - } - } -} diff --git a/frontend/src/styles/components/_content-header.scss b/frontend/src/styles/components/_content-header.scss deleted file mode 100644 index 7ce71bb36..000000000 --- a/frontend/src/styles/components/_content-header.scss +++ /dev/null @@ -1,9 +0,0 @@ -.content-header { - position: sticky; - top: 0; - z-index: 99; - - &.scroll { - overflow-x: auto; - } -} diff --git a/frontend/src/styles/components/_flat-card.scss b/frontend/src/styles/components/_flat-card.scss deleted file mode 100644 index 26f22743f..000000000 --- a/frontend/src/styles/components/_flat-card.scss +++ /dev/null @@ -1,16 +0,0 @@ -@use "../custom-bootstrap" as bs; - -.settings-card { - cursor: pointer; - - min-height: 5.4rem; - - transition: { - duration: 0.2s; - timing-function: ease-in-out; - } - - &:hover { - border-color: bs.$primary; - } -} diff --git a/frontend/src/styles/components/_header.scss b/frontend/src/styles/components/_header.scss deleted file mode 100644 index 65e3f0274..000000000 --- a/frontend/src/styles/components/_header.scss +++ /dev/null @@ -1,30 +0,0 @@ -@use "@/styles/variables.scss" as vars; - -.header-container { - height: vars.$header-height; - - input { - &[type="text"] { - // Fake Material Design Style - padding: 0; - transition: none; - color: white; - border-radius: 0; - border: none; - border-bottom: { - color: white !important; - width: 0.08rem !important; - style: solid !important; - } - background-color: transparent; - - &::placeholder { - color: lightgray; - } - - &:focus { - box-shadow: none; - } - } - } -} diff --git a/frontend/src/styles/components/_modal.scss b/frontend/src/styles/components/_modal.scss deleted file mode 100644 index 7a46db7f7..000000000 --- a/frontend/src/styles/components/_modal.scss +++ /dev/null @@ -1,18 +0,0 @@ -$modal-root-index: 1040; - -@mixin modal-hierarchical($index) { - .modal-backdrop { - &.index-#{$index} { - z-index: $modal-root-index + $index * 10; - } - } - .modal { - &.index-#{$index} { - z-index: $modal-root-index + $index * 10 + 1; - } - } -} - -@for $index from 0 through 10 { - @include modal-hierarchical($index); -} diff --git a/frontend/src/styles/components/_notification.scss b/frontend/src/styles/components/_notification.scss deleted file mode 100644 index 4690f0b97..000000000 --- a/frontend/src/styles/components/_notification.scss +++ /dev/null @@ -1,41 +0,0 @@ -@use "../variables"; -@use "../custom-bootstrap" as bs; - -.notification-btn { - &.new-item { - &::after { - position: absolute; - background-color: red; - content: ""; - border-radius: 50%; - height: 0.4rem; - width: 0.4rem; - right: 10%; - top: 10%; - } - } - - .dropdown-menu { - max-height: 85vh; - overflow-y: auto; - } - - $content-width: 14rem; - - .notification-center-progress { - width: $content-width; - max-width: $content-width; - - .progress-name { - word-wrap: break-word; - white-space: normal; - } - } - - .notification-center-notification { - word-wrap: break-word; - white-space: normal; - width: $content-width; - max-width: $content-width; - } -} diff --git a/frontend/src/styles/components/_search-modal.scss b/frontend/src/styles/components/_search-modal.scss deleted file mode 100644 index 3c3c7409c..000000000 --- a/frontend/src/styles/components/_search-modal.scss +++ /dev/null @@ -1,20 +0,0 @@ -.release-container { - flex-wrap: nowrap; - overflow: hidden; - .text-container { - max-width: 36rem; - .release-text { - text-overflow: ellipsis; - overflow-wrap: break-word; - word-wrap: break-word; - white-space: pre-wrap; - - &.hidden-item { - color: gray; - } - } - } - &.release-multi { - cursor: zoom-in; - } -} diff --git a/frontend/src/styles/components/_selector.scss b/frontend/src/styles/components/_selector.scss deleted file mode 100644 index 9b1ec2831..000000000 --- a/frontend/src/styles/components/_selector.scss +++ /dev/null @@ -1,31 +0,0 @@ -@use "../variables.scss"; -@use "../custom-bootstrap" as bs; - -.custom-selector { - .selector__control { - outline: none !important; - box-shadow: none !important; - border-radius: 0.25rem; - } - .selector__control--is-focused { - border-color: bs.$primary !important; - } - .selector__menu { - z-index: 1000; - } - - .selector__option--is-focused { - background-color: transparentize(bs.$primary, 0.85); - &:focus, - &:active { - background-color: transparentize(bs.$primary, 0.65); - } - } - - .selector__option--is-selected { - background-color: bs.$primary; - &:active { - background-color: darken(bs.$primary, 10); - } - } -} diff --git a/frontend/src/styles/components/_slider.scss b/frontend/src/styles/components/_slider.scss deleted file mode 100644 index 042a64787..000000000 --- a/frontend/src/styles/components/_slider.scss +++ /dev/null @@ -1,51 +0,0 @@ -@use "../custom-bootstrap" as bs; - -.custom-rc-slider { - .rc-slider-track { - background-color: bs.$primary; - } - .rc-slider-step { - cursor: pointer; - } - .rc-slider-handle { - border: 0.2rem solid bs.$primary; - margin-top: 0; - top: 50%; - transform: translate(-50%, -50%) !important; - width: 1.2rem; - height: 1.2rem; - cursor: pointer; - - .rc-slider-handle-tips-always { - display: block !important; - } - - .rc-slider-handle-tips-hidden { - display: none !important; - } - - .rc-slider-handle-tips { - font-size: medium; - display: none; - position: absolute; - top: -1.1rem; - left: 50%; - transform: translate(-50%, -50%); - } - - &:hover { - border-color: bs.$primary; - .rc-slider-handle-tips { - display: block; - } - } - - &:active { - border-color: bs.$primary; - box-shadow: none; - .rc-slider-handle-tips { - display: block; - } - } - } -} diff --git a/frontend/src/styles/components/_system-status.scss b/frontend/src/styles/components/_system-status.scss deleted file mode 100644 index b3f9bbe50..000000000 --- a/frontend/src/styles/components/_system-status.scss +++ /dev/null @@ -1,3 +0,0 @@ -.status-issue { - min-width: 16rem; -} diff --git a/frontend/src/styles/index.scss b/frontend/src/styles/index.scss deleted file mode 100644 index c26a662b0..000000000 --- a/frontend/src/styles/index.scss +++ /dev/null @@ -1,19 +0,0 @@ -@use "variables"; -@use "custom-bootstrap"; -@use "global"; -@use "layout"; - -// Components - -@use "components/header"; -@use "components/content-header"; -@use "components/chip"; -@use "components/notification"; -@use "components/selector"; -@use "components/slider"; -@use "components/flat-card"; -@use "components/search-modal"; -@use "components/modal"; -@use "components/chart"; -@use "components/auth"; -@use "components/system-status"; diff --git a/frontend/src/styles/index.ts b/frontend/src/styles/index.ts new file mode 100644 index 000000000..0e948df9e --- /dev/null +++ b/frontend/src/styles/index.ts @@ -0,0 +1 @@ +export * from "./table"; diff --git a/frontend/src/styles/table.ts b/frontend/src/styles/table.ts new file mode 100644 index 000000000..40d533401 --- /dev/null +++ b/frontend/src/styles/table.ts @@ -0,0 +1,19 @@ +import { createStyles } from "@mantine/core"; + +export const useTableStyles = createStyles((theme) => ({ + primary: { + display: "inline-block", + [theme.fn.smallerThan("sm")]: { + minWidth: "12rem", + }, + }, + noWrap: { + whiteSpace: "nowrap", + }, + select: { + display: "inline-block", + [theme.fn.smallerThan("sm")]: { + minWidth: "10rem", + }, + }, +})); diff --git a/frontend/src/types/api.d.ts b/frontend/src/types/api.d.ts index c15996176..8dff5e5ec 100644 --- a/frontend/src/types/api.d.ts +++ b/frontend/src/types/api.d.ts @@ -44,7 +44,7 @@ interface Subtitle { name: string; forced: boolean; hi: boolean; - path: string | null; + path: string | null | undefined; // TODO: FIX ME!!!!!! } interface PathType { diff --git a/frontend/src/types/react-table.d.ts b/frontend/src/types/react-table.d.ts index b19f07ea9..4e4405711 100644 --- a/frontend/src/types/react-table.d.ts +++ b/frontend/src/types/react-table.d.ts @@ -99,9 +99,7 @@ declare module "react-table" { // UseGlobalFiltersColumnOptions, UseGroupByColumnOptions, // UseResizeColumnsColumnOptions, - UseSortByColumnOptions { - className?: string; - } + UseSortByColumnOptions {} export interface ColumnInstance< D extends Record = Record diff --git a/frontend/src/types/utilities.d.ts b/frontend/src/types/utilities.d.ts index e1425bdce..b6b63f6a7 100644 --- a/frontend/src/types/utilities.d.ts +++ b/frontend/src/types/utilities.d.ts @@ -13,19 +13,6 @@ type StrictObject = { [key: string]: T; }; -type Pair = { - key: string; - value: T; -}; - -type EntityStruct = { - keyName: keyof T; - ids: (string | null)[]; - entities: { - [id: string]: T; - }; -}; - interface DataWrapper { data: T; } @@ -37,10 +24,5 @@ interface DataWrapperWithTotal { type Override = T & Omit; -type Comparer = (lhs: T, rhs: T) => boolean; - -type OptionalRecord = { [P in T]?: D }; - -interface IdState { - [key: number]: Readonly; -} +// eslint-disable-next-line @typescript-eslint/no-explicit-any +type GenericFunction = (...args: any[]) => T; diff --git a/frontend/src/types/window.d.ts b/frontend/src/types/window.d.ts index 8f421d90b..6cd614a98 100644 --- a/frontend/src/types/window.d.ts +++ b/frontend/src/types/window.d.ts @@ -8,6 +8,12 @@ declare global { Bazarr: BazarrServer; _socketio: SocketIODebugger; } + + interface WindowEventMap { + "app-critical-error": CustomEvent<{ message: string }>; + "app-login-required": CustomEvent; + "app-online-status": CustomEvent<{ online: boolean }>; + } } export interface BazarrServer { diff --git a/frontend/src/utilities/constants.ts b/frontend/src/utilities/constants.ts deleted file mode 100644 index 6320fa4f3..000000000 --- a/frontend/src/utilities/constants.ts +++ /dev/null @@ -1 +0,0 @@ -export const GithubRepoRoot = "https://github.com/morpheus65535/bazarr"; diff --git a/frontend/src/utilities/event.ts b/frontend/src/utilities/event.ts new file mode 100644 index 000000000..b75fc83e7 --- /dev/null +++ b/frontend/src/utilities/event.ts @@ -0,0 +1,24 @@ +type CustomEventDetail = T extends CustomEvent ? D : never; + +function createEvent< + K extends keyof WindowEventMap, + P extends CustomEventDetail +>(event: K, payload: P) { + return new CustomEvent

    (event, { bubbles: true, detail: payload }); +} + +export function setLoginRequired() { + const event = createEvent("app-login-required", {}); + window.dispatchEvent(event); +} + +export function setCriticalError(message: string) { + const event = createEvent("app-critical-error", { message }); + + window.dispatchEvent(event); +} + +export function setOnlineStatus(online: boolean) { + const event = createEvent("app-online-status", { online }); + window.dispatchEvent(event); +} diff --git a/frontend/src/utilities/hooks.ts b/frontend/src/utilities/hooks.ts index d6f68afb9..310a8763a 100644 --- a/frontend/src/utilities/hooks.ts +++ b/frontend/src/utilities/hooks.ts @@ -1,24 +1,152 @@ -import { useCallback, useState } from "react"; +import { SelectorOption, SelectorProps } from "@/components"; +import { SliderProps } from "@mantine/core"; +import { + Dispatch, + useCallback, + useEffect, + useMemo, + useRef, + useState, +} from "react"; import { useNavigate } from "react-router-dom"; -import { useDidUpdate, useMediaMatch } from "rooks"; export function useGotoHomepage() { const navigate = useNavigate(); return useCallback(() => navigate("/"), [navigate]); } -export function useIsMobile() { - return useMediaMatch("(max-width: 576px)"); +export function useSelectorOptions( + options: readonly T[], + label: (value: T) => string, + key?: (value: T) => string +): Pick, "options" | "getkey"> { + const labelRef = useRef(label); + labelRef.current = label; + + const keyRef = useRef(key); + keyRef.current = key; + + const wrappedOptions = useMemo( + () => + options.map>((value) => ({ + value, + label: labelRef.current(value), + })), + [options] + ); + + return useMemo( + () => ({ + options: wrappedOptions, + getkey: keyRef.current ?? labelRef.current, + }), + [wrappedOptions] + ); +} + +export function useSliderMarks(values: number[]): SliderProps["marks"] { + return useMemo( + () => + values.map((value) => ({ + value: value, + label: value.toString(), + })), + [values] + ); +} + +// High performance action wrapper for array, typically used for table updates +export function useArrayAction(setData: Dispatch<(prev: T[]) => T[]>) { + const setDataRef = useRef(setData); + setDataRef.current = setData; + + const add = useCallback((row: T) => { + setDataRef.current((data) => { + return [...data, row]; + }); + }, []); + + const mutate = useCallback((index: number, row: T) => { + setDataRef.current((data) => { + if (index !== -1) { + const list = [...data]; + list[index] = row; + return list; + } + + return data; + }); + }, []); + + const remove = useCallback((index: number) => { + setDataRef.current((data) => { + if (index !== -1) { + const list = [...data]; + list.splice(index, 1); + return list; + } + + return data; + }); + }, []); + + const update = useCallback((fn: (item: T) => T) => { + setDataRef.current((data) => { + return data.map(fn); + }); + }, []); + + return useMemo( + () => ({ + add, + mutate, + remove, + update, + }), + [add, mutate, remove, update] + ); +} + +export function useThrottle(fn: F, ms: number) { + const fnRef = useRef(fn); + fnRef.current = fn; + + const timer = useRef(); + + return useCallback( + (...args: Parameters) => { + if (timer.current) { + clearTimeout(timer.current); + timer.current = undefined; + } + timer.current = window.setTimeout(() => fnRef.current(...args), ms); + }, + [ms] + ); +} + +export function useDebouncedValue(item: T, ms: number) { + const [value, setValue] = useState(item); + + const debouncedSetValue = useThrottle(setValue, ms); + + useEffect(() => { + debouncedSetValue(item); + }, [debouncedSetValue, item]); + + return value; } -export function useIsArrayExtended(arr: unknown[]) { - const [size, setSize] = useState(arr.length); - const [isExtended, setExtended] = useState(arr.length !== 0); +export function useOnValueChange(value: T, onChange: (value: T) => void) { + const valueRef = useRef(null); - useDidUpdate(() => { - setExtended(arr.length > size); - setSize(arr.length); - }, [arr.length]); + const onChangeRef = useRef(onChange); + onChangeRef.current = onChange; - return isExtended; + useEffect(() => { + if (valueRef.current !== value) { + valueRef.current = value; + onChangeRef.current(value); + } + }, [value]); } diff --git a/frontend/src/utilities/index.ts b/frontend/src/utilities/index.ts index cba997eca..8fa53a60b 100644 --- a/frontend/src/utilities/index.ts +++ b/frontend/src/utilities/index.ts @@ -2,16 +2,6 @@ import { difference, differenceWith } from "lodash"; import { Dispatch } from "react"; import { isEpisode, isMovie, isSeries } from "./validate"; -export function copyToClipboard(s: string) { - const field = document.createElement("textarea"); - field.innerText = s; - document.body.appendChild(field); - field.select(); - field.setSelectionRange(0, 9999); - document.execCommand("copy"); - field.remove(); -} - export function toggleState( dispatch: Dispatch, wait: number, @@ -21,10 +11,6 @@ export function toggleState( setTimeout(() => dispatch(start), wait); } -export function submodProcessColor(s: string) { - return `color(name=${s})`; -} - export function GetItemId(item: T): number | undefined { if (isMovie(item)) { return item.radarrId; @@ -73,12 +59,6 @@ export function filterSubtitleBy( } } -export async function waitFor(time: number) { - return new Promise((resolved) => { - setTimeout(resolved, time); - }); -} - export * from "./env"; export * from "./hooks"; export * from "./validate"; diff --git a/frontend/src/utilities/languages.ts b/frontend/src/utilities/languages.ts index cb7cdb74e..f80383797 100644 --- a/frontend/src/utilities/languages.ts +++ b/frontend/src/utilities/languages.ts @@ -24,11 +24,6 @@ export function useEnabledLanguages() { return enabled; } -export function useLanguageBy(code?: string) { - const { data } = useLanguages(); - return useMemo(() => data?.find((v) => v.code2 === code), [data, code]); -} - // Convert languageprofile items to language export function useProfileItemsToLanguages(profile?: Language.Profile) { const { data } = useLanguages(); diff --git a/frontend/src/utilities/storage.ts b/frontend/src/utilities/storage.ts index 1d7e39d97..737b76ca3 100644 --- a/frontend/src/utilities/storage.ts +++ b/frontend/src/utilities/storage.ts @@ -1,5 +1,5 @@ +import { useLocalStorage } from "@mantine/hooks"; import { useCallback } from "react"; -import { useLocalstorageState } from "rooks"; export const uiPageSizeKey = "storage-ui-pageSize"; @@ -13,5 +13,5 @@ export function useUpdateLocalStorage() { } export function usePageSize() { - return useLocalstorageState(uiPageSizeKey, 50); + return useLocalStorage({ key: uiPageSizeKey, defaultValue: 50 }); } diff --git a/frontend/test/render.test.tsx b/frontend/test/render.test.tsx index 752ef9d8f..c3f4ea968 100644 --- a/frontend/test/render.test.tsx +++ b/frontend/test/render.test.tsx @@ -1,9 +1,31 @@ import { render } from "@testing-library/react"; -import { describe, it } from "vitest"; -import { Entrance } from "../src"; +import { StrictMode } from "react"; +import { describe, it, vitest } from "vitest"; +import { Main } from "../src/main"; describe("render test", () => { + beforeAll(() => { + // From https://stackoverflow.com/questions/39830580/jest-test-fails-typeerror-window-matchmedia-is-not-a-function + Object.defineProperty(window, "matchMedia", { + writable: true, + value: vitest.fn().mockImplementation((query) => ({ + matches: false, + media: query, + onchange: null, + addListener: vitest.fn(), // Deprecated + removeListener: vitest.fn(), // Deprecated + addEventListener: vitest.fn(), + removeEventListener: vitest.fn(), + dispatchEvent: vitest.fn(), + })), + }); + }); + it("render without crashing", () => { - render(); + render( + +

    + + ); }); }); diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts index ed1655a32..600cc8f37 100644 --- a/frontend/vite.config.ts +++ b/frontend/vite.config.ts @@ -62,6 +62,7 @@ export default defineConfig(async ({ mode, command }) => { }, }, host: true, + open: "/", }, }; });