From 39c1b0f8d199cadc58c42d002b28ac97204d2e4e Mon Sep 17 00:00:00 2001 From: Yury Molodov <yurymolodov@gmail.com> Date: Tue, 16 May 2023 15:41:06 +0200 Subject: [PATCH] vmui: refactor code using custom hooks (#4145) * refactor: replace boolean useState with useBoolean * refactor: replace useResize with useWindowSize/useElementSize * refactor: replace addEventListener with useEventListener * refactor: replace navigator.clipboard.writeText with useCopyToClipboard * fix: prevent redirect loop --- app/vmui/packages/vmui/package-lock.json | 1882 +++++++++-------- .../components/Chart/BarChart/BarChart.tsx | 4 +- .../src/components/Chart/BarChart/types.ts | 3 +- .../ChartTooltipHeatmap.tsx | 28 +- .../Heatmap/HeatmapChart/HeatmapChart.tsx | 60 +- .../Chart/Line/ChartTooltip/ChartTooltip.tsx | 26 +- .../Line/Legend/LegendItem/LegendItem.tsx | 7 +- .../Chart/Line/LineChart/LineChart.tsx | 50 +- .../Chart/SimpleBarChart/style.scss | 4 +- .../AdditionalSettings/AdditionalSettings.tsx | 16 +- .../GlobalSettings/GlobalSettings.tsx | 22 +- .../TenantsConfiguration.tsx | 16 +- .../GlobalSettings/Timezones/Timezones.tsx | 16 +- .../GraphSettings/GraphSettings.tsx | 16 +- .../StepConfigurator/StepConfigurator.tsx | 16 +- .../ExecutionControls/ExecutionControls.tsx | 21 +- .../TimeSelector/TimeSelector.tsx | 28 +- .../ExploreMetricItemGraph.tsx | 10 +- .../ExploreMetricItem/ExploreMetricItem.tsx | 4 +- .../ExploreMetricItemHeader.tsx | 18 +- .../src/components/Layout/Header/Header.tsx | 4 +- .../Header/HeaderControls/HeaderControls.tsx | 18 +- .../Layout/Header/HeaderNav/NavSubItem.tsx | 16 +- .../Header/SidebarNav/SidebarHeader.tsx | 16 +- .../vmui/src/components/Layout/Layout.tsx | 11 +- .../Main/Autocomplete/Autocomplete.tsx | 29 +- .../components/Main/DatePicker/DatePicker.tsx | 34 +- .../components/Main/Icons/PreviewIcons.tsx | 13 +- .../vmui/src/components/Main/Modal/Modal.tsx | 27 +- .../src/components/Main/Popper/Popper.tsx | 47 +- .../src/components/Main/Select/Select.tsx | 9 +- .../Main/ShortcutKeys/ShortcutKeys.tsx | 29 +- .../components/Main/ShortcutKeys/style.scss | 1 + .../vmui/src/components/Main/Tabs/Tabs.tsx | 4 +- .../Main/ThemeProvider/ThemeProvider.ts | 4 +- .../src/components/Main/Tooltip/Tooltip.tsx | 10 +- .../components/Views/GraphView/GraphView.tsx | 13 +- .../components/Views/JsonView/JsonView.tsx | 9 +- .../components/Views/TableView/TableView.tsx | 32 +- .../vmui/src/hooks/useClickOutside.ts | 33 +- .../vmui/src/hooks/useCopyToClipboard.ts | 32 + .../vmui/src/hooks/useDeviceDetect.ts | 4 +- .../packages/vmui/src/hooks/useDropzone.ts | 27 +- .../packages/vmui/src/hooks/useElementSize.ts | 36 + .../vmui/src/hooks/useEventListener.ts | 81 + .../src/hooks/useIsomorphicLayoutEffect.ts | 5 + app/vmui/packages/vmui/src/hooks/useResize.ts | 21 - .../packages/vmui/src/hooks/useWindowSize.ts | 31 + .../Table/TableSettings/TableSettings.tsx | 19 +- .../vmui/src/pages/CustomPanel/index.tsx | 16 +- .../PredefinedDashboard.tsx | 30 +- .../PredefinedDashboard/style.scss | 2 +- .../src/pages/TracePage/JsonForm/JsonForm.tsx | 7 +- .../vmui/src/pages/TracePage/index.tsx | 16 +- 54 files changed, 1572 insertions(+), 1361 deletions(-) create mode 100644 app/vmui/packages/vmui/src/hooks/useCopyToClipboard.ts create mode 100644 app/vmui/packages/vmui/src/hooks/useElementSize.ts create mode 100644 app/vmui/packages/vmui/src/hooks/useEventListener.ts create mode 100644 app/vmui/packages/vmui/src/hooks/useIsomorphicLayoutEffect.ts delete mode 100644 app/vmui/packages/vmui/src/hooks/useResize.ts create mode 100644 app/vmui/packages/vmui/src/hooks/useWindowSize.ts diff --git a/app/vmui/packages/vmui/package-lock.json b/app/vmui/packages/vmui/package-lock.json index e697d80303..d5c3590baf 100644 --- a/app/vmui/packages/vmui/package-lock.json +++ b/app/vmui/packages/vmui/package-lock.json @@ -46,18 +46,18 @@ } }, "node_modules/@adobe/css-tools": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.0.2.tgz", - "integrity": "sha512-Fx6tYjk2wKUgLi8uMANZr8GNZx05u44ArIJldn9VxLvolzlJVgHbTUCbwhMd6bcYky178+WUSxPHO3DAtGLWpw==" + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.2.0.tgz", + "integrity": "sha512-E09FiIft46CmH5Qnjb0wsW54/YQd69LsxeKUOWawmws1XWvyFGURnAChH0mlr7YPFR1ofwvUQfcL0J3lMxXqPA==" }, "node_modules/@ampproject/remapping": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", - "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", + "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", "dev": true, "peer": true, "dependencies": { - "@jridgewell/gen-mapping": "^0.1.0", + "@jridgewell/gen-mapping": "^0.3.0", "@jridgewell/trace-mapping": "^0.3.9" }, "engines": { @@ -65,9 +65,9 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", - "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.21.4.tgz", + "integrity": "sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g==", "dependencies": { "@babel/highlight": "^7.18.6" }, @@ -76,9 +76,9 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.20.10", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.10.tgz", - "integrity": "sha512-sEnuDPpOJR/fcafHMjpcpGN5M2jbUGUHwmuWKM/YdPzeEDJg8bgmbcWQFUfE32MQjti1koACvoPVsDe8Uq+idg==", + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.21.4.tgz", + "integrity": "sha512-/DYyDpeCfaVinT40FPGdkkb+lYSKvsVuMjDAG7jPOWWiM1ibOaB9CXJAlc4d1QpP/U2q2P9jbrSlClKSErd55g==", "dev": true, "peer": true, "engines": { @@ -86,22 +86,22 @@ } }, "node_modules/@babel/core": { - "version": "7.20.12", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.12.tgz", - "integrity": "sha512-XsMfHovsUYHFMdrIHkZphTN/2Hzzi78R08NuHfDBehym2VsPDL6Zn/JAD/JQdnRvbSsbQc4mVaU1m6JgtTEElg==", + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.21.4.tgz", + "integrity": "sha512-qt/YV149Jman/6AfmlxJ04LMIu8bMoyl3RB91yTFrxQmgbrSvQMy7cI8Q62FHx1t8wJ8B5fu0UDoLwHAhUo1QA==", "dev": true, "peer": true, "dependencies": { - "@ampproject/remapping": "^2.1.0", - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.20.7", - "@babel/helper-compilation-targets": "^7.20.7", - "@babel/helper-module-transforms": "^7.20.11", - "@babel/helpers": "^7.20.7", - "@babel/parser": "^7.20.7", + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.21.4", + "@babel/generator": "^7.21.4", + "@babel/helper-compilation-targets": "^7.21.4", + "@babel/helper-module-transforms": "^7.21.2", + "@babel/helpers": "^7.21.0", + "@babel/parser": "^7.21.4", "@babel/template": "^7.20.7", - "@babel/traverse": "^7.20.12", - "@babel/types": "^7.20.7", + "@babel/traverse": "^7.21.4", + "@babel/types": "^7.21.4", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -117,9 +117,9 @@ } }, "node_modules/@babel/eslint-parser": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.19.1.tgz", - "integrity": "sha512-AqNf2QWt1rtu2/1rLswy6CDP7H9Oh3mMhk177Y67Rg8d7RD9WfOLLv8CGn6tisFvS2htm86yIe1yLF6I1UDaGQ==", + "version": "7.21.3", + "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.21.3.tgz", + "integrity": "sha512-kfhmPimwo6k4P8zxNs8+T7yR44q1LdpsZdE1NkCsVlfiuTPRfnGgjaF8Qgug9q9Pou17u6wneYF0lDCZJATMFg==", "dev": true, "peer": true, "dependencies": { @@ -146,35 +146,21 @@ } }, "node_modules/@babel/generator": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.7.tgz", - "integrity": "sha512-7wqMOJq8doJMZmP4ApXTzLxSr7+oO2jroJURrVEp6XShrQUObV8Tq/D0NCcoYg2uHqUrjzO0zwBjoYzelxK+sw==", + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.21.4.tgz", + "integrity": "sha512-NieM3pVIYW2SwGzKoqfPrQsf4xGs9M9AIG3ThppsSRmO+m7eQhmI6amajKMUeIO37wFfsvnvcxQFx6x6iqxDnA==", "dev": true, "peer": true, "dependencies": { - "@babel/types": "^7.20.7", + "@babel/types": "^7.21.4", "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/generator/node_modules/@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", - "dev": true, - "peer": true, - "dependencies": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/@babel/helper-annotate-as-pure": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz", @@ -203,14 +189,14 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz", - "integrity": "sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==", + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.21.4.tgz", + "integrity": "sha512-Fa0tTuOXZ1iL8IeDFUWCzjZcn+sJGd9RZdH9esYVjEejGmzf+FFYQpMi/kZUk2kPy/q1H3/GPw7np8qar/stfg==", "dev": true, "peer": true, "dependencies": { - "@babel/compat-data": "^7.20.5", - "@babel/helper-validator-option": "^7.18.6", + "@babel/compat-data": "^7.21.4", + "@babel/helper-validator-option": "^7.21.0", "browserslist": "^4.21.3", "lru-cache": "^5.1.1", "semver": "^6.3.0" @@ -223,16 +209,16 @@ } }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.20.12", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.20.12.tgz", - "integrity": "sha512-9OunRkbT0JQcednL0UFvbfXpAsUXiGjUk0a7sN8fUXX7Mue79cUSMjHGDRRi/Vz9vYlpIhLV5fMD5dKoMhhsNQ==", + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.21.4.tgz", + "integrity": "sha512-46QrX2CQlaFRF4TkwfTt6nJD7IHq8539cCL7SDpqWSDeJKY1xylKKY5F/33mJhLZ3mFvKv2gGrVS6NkyF6qs+Q==", "dev": true, "peer": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.18.6", "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", - "@babel/helper-member-expression-to-functions": "^7.20.7", + "@babel/helper-function-name": "^7.21.0", + "@babel/helper-member-expression-to-functions": "^7.21.0", "@babel/helper-optimise-call-expression": "^7.18.6", "@babel/helper-replace-supers": "^7.20.7", "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", @@ -246,14 +232,14 @@ } }, "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.20.5.tgz", - "integrity": "sha512-m68B1lkg3XDGX5yCvGO0kPx3v9WIYLnzjKfPcQiwntEQa5ZeRkPmo2X/ISJc8qxWGfwUr+kvZAeEzAwLec2r2w==", + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.21.4.tgz", + "integrity": "sha512-M00OuhU+0GyZ5iBBN9czjugzWrEq2vDpf/zCYHxxf93ul/Q5rv+a5h+/+0WnI1AebHNVtl5bFV0qsJoH23DbfA==", "dev": true, "peer": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.18.6", - "regexpu-core": "^5.2.1" + "regexpu-core": "^5.3.1" }, "engines": { "node": ">=6.9.0" @@ -281,13 +267,13 @@ } }, "node_modules/@babel/helper-define-polyfill-provider/node_modules/resolve": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", - "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "version": "1.22.3", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.3.tgz", + "integrity": "sha512-P8ur/gp/AmbEzjr729bZnLjXK5Z+4P0zhIJgBgzqRih7hL7BOukHGtSTA3ACMY467GRFz3duQsi0bDZdR7DKdw==", "dev": true, "peer": true, "dependencies": { - "is-core-module": "^2.9.0", + "is-core-module": "^2.12.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, @@ -322,14 +308,14 @@ } }, "node_modules/@babel/helper-function-name": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", - "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz", + "integrity": "sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==", "dev": true, "peer": true, "dependencies": { - "@babel/template": "^7.18.10", - "@babel/types": "^7.19.0" + "@babel/template": "^7.20.7", + "@babel/types": "^7.21.0" }, "engines": { "node": ">=6.9.0" @@ -349,35 +335,35 @@ } }, "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.20.7.tgz", - "integrity": "sha512-9J0CxJLq315fEdi4s7xK5TQaNYjZw+nDVpVqr1axNGKzdrdwYBD5b4uKv3n75aABG0rCCTK8Im8Ww7eYfMrZgw==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.21.0.tgz", + "integrity": "sha512-Muu8cdZwNN6mRRNG6lAYErJ5X3bRevgYR2O8wN0yn7jJSnGDu6eG59RfT29JHxGUovyfrh6Pj0XzmR7drNVL3Q==", "dev": true, "peer": true, "dependencies": { - "@babel/types": "^7.20.7" + "@babel/types": "^7.21.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", - "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.21.4.tgz", + "integrity": "sha512-orajc5T2PsRYUN3ZryCEFeMDYwyw09c/pZeaQEZPH0MpKzSvn3e0uXsDBu3k03VI+9DBiRo+l22BfKTpKwa/Wg==", "dev": true, "peer": true, "dependencies": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.21.4" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.20.11", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.11.tgz", - "integrity": "sha512-uRy78kN4psmji1s2QtbtcCSaj/LILFDp0f/ymhpQH5QY3nljUZCaNWz9X1dEj/8MBdBEFECs7yRhKn8i7NjZgg==", + "version": "7.21.2", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.21.2.tgz", + "integrity": "sha512-79yj2AR4U/Oqq/WOV7Lx6hUjau1Zfo4cI+JLAVYeMV5XIlbOhmjEk5ulbTc9fMpmlojzZHkUUxAiK+UKn+hNQQ==", "dev": true, "peer": true, "dependencies": { @@ -387,8 +373,8 @@ "@babel/helper-split-export-declaration": "^7.18.6", "@babel/helper-validator-identifier": "^7.19.1", "@babel/template": "^7.20.7", - "@babel/traverse": "^7.20.10", - "@babel/types": "^7.20.7" + "@babel/traverse": "^7.21.2", + "@babel/types": "^7.21.2" }, "engines": { "node": ">=6.9.0" @@ -511,9 +497,9 @@ } }, "node_modules/@babel/helper-validator-option": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", - "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.21.0.tgz", + "integrity": "sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ==", "dev": true, "peer": true, "engines": { @@ -537,15 +523,15 @@ } }, "node_modules/@babel/helpers": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.7.tgz", - "integrity": "sha512-PBPjs5BppzsGaxHQCDKnZ6Gd9s6xl8bBCluz3vEInLGRJmnZan4F6BYCeqtyXqkk4W5IlPmjK4JlOuZkpJ3xZA==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.21.0.tgz", + "integrity": "sha512-XXve0CBtOW0pd7MRzzmoyuSj0e3SEzj8pgyFxnTT1NJZL38BD1MK7yYrm8yefRPIDvNNe14xR4FdbHwpInD4rA==", "dev": true, "peer": true, "dependencies": { "@babel/template": "^7.20.7", - "@babel/traverse": "^7.20.7", - "@babel/types": "^7.20.7" + "@babel/traverse": "^7.21.0", + "@babel/types": "^7.21.0" }, "engines": { "node": ">=6.9.0" @@ -565,9 +551,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.7.tgz", - "integrity": "sha512-T3Z9oHybU+0vZlY9CiDSJQTD5ZapcW18ZctFMi0MOAl/4BjFF4ul7NVSARLdbGO5vDqy9eQiGTV0LtKfvCYvcg==", + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.4.tgz", + "integrity": "sha512-alVJj7k7zIxqBZ7BTRhz0IqJFxW1VJbm6N8JbcYhQ186df9ZBPbZBmWSqAMXwHGsCJdYks7z/voa3ibiS5bCIw==", "dev": true, "peer": true, "bin": { @@ -648,13 +634,13 @@ } }, "node_modules/@babel/plugin-proposal-class-static-block": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.20.7.tgz", - "integrity": "sha512-AveGOoi9DAjUYYuUAG//Ig69GlazLnoyzMw68VCDux+c1tsnnH/OkYcpz/5xzMkEFC6UxjR5Gw1c+iY2wOGVeQ==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.21.0.tgz", + "integrity": "sha512-XP5G9MWNUskFuP30IfFSEFB0Z6HzLIUcjYM4bYOPHXl7eiJ9HFv8tWj6TXTN5QODiEhDZAeI4hLok2iHFFV4hw==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.20.7", + "@babel/helper-create-class-features-plugin": "^7.21.0", "@babel/helper-plugin-utils": "^7.20.2", "@babel/plugin-syntax-class-static-block": "^7.14.5" }, @@ -666,17 +652,17 @@ } }, "node_modules/@babel/plugin-proposal-decorators": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.20.7.tgz", - "integrity": "sha512-JB45hbUweYpwAGjkiM7uCyXMENH2lG+9r3G2E+ttc2PRXAoEkpfd/KW5jDg4j8RS6tLtTG1jZi9LbHZVSfs1/A==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.21.0.tgz", + "integrity": "sha512-MfgX49uRrFUTL/HvWtmx3zmpyzMMr4MTj3d527MLlr/4RTT9G/ytFFP7qet2uM2Ve03b+BkpWUpK+lRXnQ+v9w==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.20.7", + "@babel/helper-create-class-features-plugin": "^7.21.0", "@babel/helper-plugin-utils": "^7.20.2", "@babel/helper-replace-supers": "^7.20.7", "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/plugin-syntax-decorators": "^7.19.0" + "@babel/plugin-syntax-decorators": "^7.21.0" }, "engines": { "node": ">=6.9.0" @@ -824,9 +810,9 @@ } }, "node_modules/@babel/plugin-proposal-optional-chaining": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.20.7.tgz", - "integrity": "sha512-T+A7b1kfjtRM51ssoOfS1+wbyCVqorfyZhT99TvxxLMirPShD8CzKMRepMlCBGM5RpHMbn8s+5MMHnPstJH6mQ==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.21.0.tgz", + "integrity": "sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA==", "dev": true, "peer": true, "dependencies": { @@ -859,14 +845,14 @@ } }, "node_modules/@babel/plugin-proposal-private-property-in-object": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.20.5.tgz", - "integrity": "sha512-Vq7b9dUA12ByzB4EjQTPo25sFhY+08pQDBSZRtUAkj7lb7jahaHR5igera16QZ+3my1nYR4dKsNdYj5IjPHilQ==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0.tgz", + "integrity": "sha512-ha4zfehbJjc5MmXBlHec1igel5TJXXLDDRbuJ4+XT2TJcyD9/V1919BA8gMvsdHcNMBy4WBUBiRb3nw/EQUtBw==", "dev": true, "peer": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-create-class-features-plugin": "^7.20.5", + "@babel/helper-create-class-features-plugin": "^7.21.0", "@babel/helper-plugin-utils": "^7.20.2", "@babel/plugin-syntax-private-property-in-object": "^7.14.5" }, @@ -950,13 +936,13 @@ } }, "node_modules/@babel/plugin-syntax-decorators": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.19.0.tgz", - "integrity": "sha512-xaBZUEDntt4faL1yN8oIFlhfXeQAWJW7CLKYsHTUqriCUbj8xOra8bfxxKGi/UwExPFBuPdH4XfHc9rGQhrVkQ==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.21.0.tgz", + "integrity": "sha512-tIoPpGBR8UuM4++ccWN3gifhVvQu7ZizuR1fklhRJrd5ewgbkUS+0KVFeWWxELtn18NTLoW32XV7zyOgIAiz+w==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.19.0" + "@babel/helper-plugin-utils": "^7.20.2" }, "engines": { "node": ">=6.9.0" @@ -992,13 +978,13 @@ } }, "node_modules/@babel/plugin-syntax-flow": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.18.6.tgz", - "integrity": "sha512-LUbR+KNTBWCUAqRG9ex5Gnzu2IOkt8jRJbHHXFT9q+L9zm7M/QQbEqXyw1n1pohYvOyWC8CjeyjrSaIwiYjK7A==", + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.21.4.tgz", + "integrity": "sha512-l9xd3N+XG4fZRxEP3vXdK6RW7vN1Uf5dxzRC/09wV86wqZ/YYQooBIGNsiRdfNR3/q2/5pPzV4B54J/9ctX5jw==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.20.2" }, "engines": { "node": ">=6.9.0" @@ -1050,13 +1036,13 @@ } }, "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz", - "integrity": "sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==", + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.21.4.tgz", + "integrity": "sha512-5hewiLct5OKyh6PLKEYaFclcqtIgCb6bmELouxjF6up5q3Sov7rOayW4RwhbaBL0dit8rA80GNfY+UuDp2mBbQ==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.20.2" }, "engines": { "node": ">=6.9.0" @@ -1175,13 +1161,13 @@ } }, "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.20.0.tgz", - "integrity": "sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ==", + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.21.4.tgz", + "integrity": "sha512-xz0D39NvhQn4t4RNsHmDnnsaQizIlUkdtYvLs8La1BlfjQ6JEwxkJGeqJMW2tAXx+q6H+WFuUTXNdYVpEya0YA==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.19.0" + "@babel/helper-plugin-utils": "^7.20.2" }, "engines": { "node": ">=6.9.0" @@ -1241,9 +1227,9 @@ } }, "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.20.11", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.20.11.tgz", - "integrity": "sha512-tA4N427a7fjf1P0/2I4ScsHGc5jcHPbb30xMbaTke2gxDuWpUfXDuX1FEymJwKk4tuGUvGcejAR6HdZVqmmPyw==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.21.0.tgz", + "integrity": "sha512-Mdrbunoh9SxwFZapeHVrwFmri16+oYotcZysSzhNIVDwIAb1UV+kvnxULSYq9J3/q5MDG+4X6w8QVgD1zhBXNQ==", "dev": true, "peer": true, "dependencies": { @@ -1257,16 +1243,16 @@ } }, "node_modules/@babel/plugin-transform-classes": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.20.7.tgz", - "integrity": "sha512-LWYbsiXTPKl+oBlXUGlwNlJZetXD5Am+CyBdqhPsDVjM9Jc8jwBJFrKhHf900Kfk2eZG1y9MAG3UNajol7A4VQ==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.21.0.tgz", + "integrity": "sha512-RZhbYTCEUAe6ntPehC4hlslPWosNHDox+vAs4On/mCLRLfoDVHf6hVEd7kuxr1RnHwJmxFfUM3cZiZRmPxJPXQ==", "dev": true, "peer": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.18.6", "@babel/helper-compilation-targets": "^7.20.7", "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", + "@babel/helper-function-name": "^7.21.0", "@babel/helper-optimise-call-expression": "^7.18.6", "@babel/helper-plugin-utils": "^7.20.2", "@babel/helper-replace-supers": "^7.20.7", @@ -1298,9 +1284,9 @@ } }, "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.20.7.tgz", - "integrity": "sha512-Xwg403sRrZb81IVB79ZPqNQME23yhugYVqgTxAhT99h485F4f+GMELFhhOsscDUB7HCswepKeCKLn/GZvUKoBA==", + "version": "7.21.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.21.3.tgz", + "integrity": "sha512-bp6hwMFzuiE4HqYEyoGJ/V2LeIWn+hLVKc4pnj++E5XQptwhtcGmSayM029d/j2X1bPKGTlsyPwAubuU22KhMA==", "dev": true, "peer": true, "dependencies": { @@ -1364,13 +1350,13 @@ } }, "node_modules/@babel/plugin-transform-flow-strip-types": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.19.0.tgz", - "integrity": "sha512-sgeMlNaQVbCSpgLSKP4ZZKfsJVnFnNQlUSk6gPYzR/q7tzCgQF2t8RBKAP6cKJeZdveei7Q7Jm527xepI8lNLg==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.21.0.tgz", + "integrity": "sha512-FlFA2Mj87a6sDkW4gfGrQQqwY/dLlBAyJa2dJEZ+FHXUVHBflO2wyKvg+OOEzXfrKYIa4HWl0mgmbCzt0cMb7w==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.19.0", + "@babel/helper-plugin-utils": "^7.20.2", "@babel/plugin-syntax-flow": "^7.18.6" }, "engines": { @@ -1381,13 +1367,13 @@ } }, "node_modules/@babel/plugin-transform-for-of": { - "version": "7.18.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.18.8.tgz", - "integrity": "sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.21.0.tgz", + "integrity": "sha512-LlUYlydgDkKpIY7mcBWvyPPmMcOphEyYA27Ef4xpbh1IiDNLr0kZsos2nf92vz3IccvJI25QUwp86Eo5s6HmBQ==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.20.2" }, "engines": { "node": ">=6.9.0" @@ -1464,13 +1450,13 @@ } }, "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.20.11", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.20.11.tgz", - "integrity": "sha512-S8e1f7WQ7cimJQ51JkAaDrEtohVEitXjgCGAS2N8S31Y42E+kWwfSz83LYz57QdBm7q9diARVqanIaH2oVgQnw==", + "version": "7.21.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.21.2.tgz", + "integrity": "sha512-Cln+Yy04Gxua7iPdj6nOV96smLGjpElir5YwzF0LBPKoPlLDNJePNlrGGaybAJkd0zKRnOVXOgizSqPYMNYkzA==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-module-transforms": "^7.20.11", + "@babel/helper-module-transforms": "^7.21.2", "@babel/helper-plugin-utils": "^7.20.2", "@babel/helper-simple-access": "^7.20.2" }, @@ -1568,9 +1554,9 @@ } }, "node_modules/@babel/plugin-transform-parameters": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.20.7.tgz", - "integrity": "sha512-WiWBIkeHKVOSYPO0pWkxGPfKeWrCJyD3NJ53+Lrp/QMSZbsVPovrVl2aWZ19D/LTVnaDv5Ap7GJ/B2CTOZdrfA==", + "version": "7.21.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.21.3.tgz", + "integrity": "sha512-Wxc+TvppQG9xWFYatvCGPvZ6+SIUxQ2ZdiBP+PHYMIjnPXD+uThCshaz4NZOnODAtBjjcVQQ/3OKs9LW28purQ==", "dev": true, "peer": true, "dependencies": { @@ -1600,9 +1586,9 @@ } }, "node_modules/@babel/plugin-transform-react-constant-elements": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.20.2.tgz", - "integrity": "sha512-KS/G8YI8uwMGKErLFOHS/ekhqdHhpEloxs43NecQHVgo2QuQSyJhGIY1fL8UGl9wy5ItVwwoUL4YxVqsplGq2g==", + "version": "7.21.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.21.3.tgz", + "integrity": "sha512-4DVcFeWe/yDYBLp0kBmOGFJ6N2UYg7coGid1gdxb4co62dy/xISDMaYBXBVXEDhfgMk7qkbcYiGtwd5Q/hwDDQ==", "dev": true, "peer": true, "dependencies": { @@ -1632,9 +1618,9 @@ } }, "node_modules/@babel/plugin-transform-react-jsx": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.20.7.tgz", - "integrity": "sha512-Tfq7qqD+tRj3EoDhY00nn2uP2hsRxgYGi5mLQ5TimKav0a9Lrpd4deE+fcLXU8zFYRjlKPHZhpCvfEA6qnBxqQ==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.21.0.tgz", + "integrity": "sha512-6OAWljMvQrZjR2DaNhVfRz6dkCAVV+ymcLUmaf8bccGOHn2v5rHJK3tTpij0BuhdYWP4LLaqj5lwcdlpAAPuvg==", "dev": true, "peer": true, "dependencies": { @@ -1642,7 +1628,7 @@ "@babel/helper-module-imports": "^7.18.6", "@babel/helper-plugin-utils": "^7.20.2", "@babel/plugin-syntax-jsx": "^7.18.6", - "@babel/types": "^7.20.7" + "@babel/types": "^7.21.0" }, "engines": { "node": ">=6.9.0" @@ -1718,14 +1704,14 @@ } }, "node_modules/@babel/plugin-transform-runtime": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.19.6.tgz", - "integrity": "sha512-PRH37lz4JU156lYFW1p8OxE5i7d6Sl/zV58ooyr+q1J1lnQPyg5tIiXlIwNVhJaY4W3TmOtdc8jqdXQcB1v5Yw==", + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.21.4.tgz", + "integrity": "sha512-1J4dhrw1h1PqnNNpzwxQ2UBymJUF8KuPjAAnlLwZcGhHAIqUigFW7cdK6GHoB64ubY4qXQNYknoUeks4Wz7CUA==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-plugin-utils": "^7.19.0", + "@babel/helper-module-imports": "^7.21.4", + "@babel/helper-plugin-utils": "^7.20.2", "babel-plugin-polyfill-corejs2": "^0.3.3", "babel-plugin-polyfill-corejs3": "^0.6.0", "babel-plugin-polyfill-regenerator": "^0.4.1", @@ -1820,13 +1806,14 @@ } }, "node_modules/@babel/plugin-transform-typescript": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.20.7.tgz", - "integrity": "sha512-m3wVKEvf6SoszD8pu4NZz3PvfKRCMgk6D6d0Qi9hNnlM5M6CFS92EgF4EiHVLKbU0r/r7ty1hg7NPZwE7WRbYw==", + "version": "7.21.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.21.3.tgz", + "integrity": "sha512-RQxPz6Iqt8T0uw/WsJNReuBpWpBqs/n7mNo18sKLoTbMp+UrEekhH+pKSVC7gWz+DNjo9gryfV8YzCiT45RgMw==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.20.7", + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-create-class-features-plugin": "^7.21.0", "@babel/helper-plugin-utils": "^7.20.2", "@babel/plugin-syntax-typescript": "^7.20.0" }, @@ -1871,32 +1858,32 @@ } }, "node_modules/@babel/preset-env": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.20.2.tgz", - "integrity": "sha512-1G0efQEWR1EHkKvKHqbG+IN/QdgwfByUpM5V5QroDzGV2t3S/WXNQd693cHiHTlCFMpr9B6FkPFXDA2lQcKoDg==", + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.21.4.tgz", + "integrity": "sha512-2W57zHs2yDLm6GD5ZpvNn71lZ0B/iypSdIeq25OurDKji6AdzV07qp4s3n1/x5BqtiGaTrPN3nerlSCaC5qNTw==", "dev": true, "peer": true, "dependencies": { - "@babel/compat-data": "^7.20.1", - "@babel/helper-compilation-targets": "^7.20.0", + "@babel/compat-data": "^7.21.4", + "@babel/helper-compilation-targets": "^7.21.4", "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-validator-option": "^7.18.6", + "@babel/helper-validator-option": "^7.21.0", "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.18.6", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.18.9", - "@babel/plugin-proposal-async-generator-functions": "^7.20.1", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.20.7", + "@babel/plugin-proposal-async-generator-functions": "^7.20.7", "@babel/plugin-proposal-class-properties": "^7.18.6", - "@babel/plugin-proposal-class-static-block": "^7.18.6", + "@babel/plugin-proposal-class-static-block": "^7.21.0", "@babel/plugin-proposal-dynamic-import": "^7.18.6", "@babel/plugin-proposal-export-namespace-from": "^7.18.9", "@babel/plugin-proposal-json-strings": "^7.18.6", - "@babel/plugin-proposal-logical-assignment-operators": "^7.18.9", + "@babel/plugin-proposal-logical-assignment-operators": "^7.20.7", "@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6", "@babel/plugin-proposal-numeric-separator": "^7.18.6", - "@babel/plugin-proposal-object-rest-spread": "^7.20.2", + "@babel/plugin-proposal-object-rest-spread": "^7.20.7", "@babel/plugin-proposal-optional-catch-binding": "^7.18.6", - "@babel/plugin-proposal-optional-chaining": "^7.18.9", + "@babel/plugin-proposal-optional-chaining": "^7.21.0", "@babel/plugin-proposal-private-methods": "^7.18.6", - "@babel/plugin-proposal-private-property-in-object": "^7.18.6", + "@babel/plugin-proposal-private-property-in-object": "^7.21.0", "@babel/plugin-proposal-unicode-property-regex": "^7.18.6", "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-class-properties": "^7.12.13", @@ -1913,40 +1900,40 @@ "@babel/plugin-syntax-optional-chaining": "^7.8.3", "@babel/plugin-syntax-private-property-in-object": "^7.14.5", "@babel/plugin-syntax-top-level-await": "^7.14.5", - "@babel/plugin-transform-arrow-functions": "^7.18.6", - "@babel/plugin-transform-async-to-generator": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.20.7", + "@babel/plugin-transform-async-to-generator": "^7.20.7", "@babel/plugin-transform-block-scoped-functions": "^7.18.6", - "@babel/plugin-transform-block-scoping": "^7.20.2", - "@babel/plugin-transform-classes": "^7.20.2", - "@babel/plugin-transform-computed-properties": "^7.18.9", - "@babel/plugin-transform-destructuring": "^7.20.2", + "@babel/plugin-transform-block-scoping": "^7.21.0", + "@babel/plugin-transform-classes": "^7.21.0", + "@babel/plugin-transform-computed-properties": "^7.20.7", + "@babel/plugin-transform-destructuring": "^7.21.3", "@babel/plugin-transform-dotall-regex": "^7.18.6", "@babel/plugin-transform-duplicate-keys": "^7.18.9", "@babel/plugin-transform-exponentiation-operator": "^7.18.6", - "@babel/plugin-transform-for-of": "^7.18.8", + "@babel/plugin-transform-for-of": "^7.21.0", "@babel/plugin-transform-function-name": "^7.18.9", "@babel/plugin-transform-literals": "^7.18.9", "@babel/plugin-transform-member-expression-literals": "^7.18.6", - "@babel/plugin-transform-modules-amd": "^7.19.6", - "@babel/plugin-transform-modules-commonjs": "^7.19.6", - "@babel/plugin-transform-modules-systemjs": "^7.19.6", + "@babel/plugin-transform-modules-amd": "^7.20.11", + "@babel/plugin-transform-modules-commonjs": "^7.21.2", + "@babel/plugin-transform-modules-systemjs": "^7.20.11", "@babel/plugin-transform-modules-umd": "^7.18.6", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.19.1", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.20.5", "@babel/plugin-transform-new-target": "^7.18.6", "@babel/plugin-transform-object-super": "^7.18.6", - "@babel/plugin-transform-parameters": "^7.20.1", + "@babel/plugin-transform-parameters": "^7.21.3", "@babel/plugin-transform-property-literals": "^7.18.6", - "@babel/plugin-transform-regenerator": "^7.18.6", + "@babel/plugin-transform-regenerator": "^7.20.5", "@babel/plugin-transform-reserved-words": "^7.18.6", "@babel/plugin-transform-shorthand-properties": "^7.18.6", - "@babel/plugin-transform-spread": "^7.19.0", + "@babel/plugin-transform-spread": "^7.20.7", "@babel/plugin-transform-sticky-regex": "^7.18.6", "@babel/plugin-transform-template-literals": "^7.18.9", "@babel/plugin-transform-typeof-symbol": "^7.18.9", "@babel/plugin-transform-unicode-escapes": "^7.18.10", "@babel/plugin-transform-unicode-regex": "^7.18.6", "@babel/preset-modules": "^0.1.5", - "@babel/types": "^7.20.2", + "@babel/types": "^7.21.4", "babel-plugin-polyfill-corejs2": "^0.3.3", "babel-plugin-polyfill-corejs3": "^0.6.0", "babel-plugin-polyfill-regenerator": "^0.4.1", @@ -1999,15 +1986,17 @@ } }, "node_modules/@babel/preset-typescript": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.18.6.tgz", - "integrity": "sha512-s9ik86kXBAnD760aybBucdpnLsAt0jK1xqJn2juOn9lkOvSHV60os5hxoVJsPzMQxvnUJFAlkont2DvvaYEBtQ==", + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.21.4.tgz", + "integrity": "sha512-sMLNWY37TCdRH/bJ6ZeeOH1nPuanED7Ai9Y/vH31IPqalioJ6ZNFUWONsakhv4r4n+I6gm5lmoE0olkgib/j/A==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-validator-option": "^7.18.6", - "@babel/plugin-transform-typescript": "^7.18.6" + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-validator-option": "^7.21.0", + "@babel/plugin-syntax-jsx": "^7.21.4", + "@babel/plugin-transform-modules-commonjs": "^7.21.2", + "@babel/plugin-transform-typescript": "^7.21.3" }, "engines": { "node": ">=6.9.0" @@ -2016,10 +2005,17 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==", + "dev": true, + "peer": true + }, "node_modules/@babel/runtime": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.7.tgz", - "integrity": "sha512-UF0tvkUtxwAgZ5W/KrkHf0Rn0fdnLDU9ScxBrEVNUprE/MzirjK4MJUX1/BVDv00Sv8cljtukVK1aky++X1SjQ==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.21.0.tgz", + "integrity": "sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw==", "dependencies": { "regenerator-runtime": "^0.13.11" }, @@ -2043,20 +2039,20 @@ } }, "node_modules/@babel/traverse": { - "version": "7.20.12", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.12.tgz", - "integrity": "sha512-MsIbFN0u+raeja38qboyF8TIT7K0BFzz/Yd/77ta4MsUsmP2RAnidIlwq7d5HFQrH/OZJecGV6B71C4zAgpoSQ==", + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.21.4.tgz", + "integrity": "sha512-eyKrRHKdyZxqDm+fV1iqL9UAHMoIg0nDaGqfIOd8rKH17m5snv7Gn4qgjBoFfLz9APvjFU/ICT00NVCv1Epp8Q==", "dev": true, "peer": true, "dependencies": { - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.20.7", + "@babel/code-frame": "^7.21.4", + "@babel/generator": "^7.21.4", "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", + "@babel/helper-function-name": "^7.21.0", "@babel/helper-hoist-variables": "^7.18.6", "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7", + "@babel/parser": "^7.21.4", + "@babel/types": "^7.21.4", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -2065,9 +2061,9 @@ } }, "node_modules/@babel/types": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.7.tgz", - "integrity": "sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==", + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.4.tgz", + "integrity": "sha512-rU2oY501qDxE8Pyo7i/Orqma4ziCOrby0/9mvbDUGEfvZjb279Nk9k19e2fiCxHbRRpY2ZyrgW1eq22mvmOIzA==", "dev": true, "peer": true, "dependencies": { @@ -2372,33 +2368,56 @@ } }, "node_modules/@csstools/selector-specificity": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.0.2.tgz", - "integrity": "sha512-IkpVW/ehM1hWKln4fCA3NzJU8KwD+kIOvPZA4cqxoJHtE21CCzjyp+Kxbu0i5I4tBNOlXPL9mjwnWlL0VEG4Fg==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.2.0.tgz", + "integrity": "sha512-+OJ9konv95ClSTOJCmMZqpd5+YGsB2S+x6w3E1oaM8UuR5j8nTNHYSz8c9BEPGDOCMQYIEEGlVPj/VY64iTbGw==", "dev": true, "peer": true, "engines": { - "node": "^12 || ^14 || >=16" + "node": "^14 || ^16 || >=18" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/csstools" }, "peerDependencies": { - "postcss": "^8.2", "postcss-selector-parser": "^6.0.10" } }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.5.0.tgz", + "integrity": "sha512-vITaYzIcNmjn5tF5uxcZ/ft7/RXGrMUIS9HalWckEOF6ESiwXKoMzAQf2UW0aVd6rnOeExTJVd5hmWXucBKGXQ==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, "node_modules/@eslint/eslintrc": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.1.tgz", - "integrity": "sha512-XXrH9Uarn0stsyldqDYq8r++mROmWRI1xKMXa640Bb//SY1+ECYX6VzT6Lcx5frD0V30XieqJ0oX9I2Xj5aoMA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.2.tgz", + "integrity": "sha512-3W4f5tDUra+pA+FzgugqL2pRimUTDJWKr7BINqOpkZrC0uYI0NIc0/JFgBROCU07HR6GieA5m3/rsPIhDmCXTQ==", "dev": true, "peer": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.4.0", + "espree": "^9.5.1", "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", @@ -2414,9 +2433,9 @@ } }, "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "13.19.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.19.0.tgz", - "integrity": "sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==", + "version": "13.20.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", + "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", "dev": true, "peer": true, "dependencies": { @@ -2442,6 +2461,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@eslint/js": { + "version": "8.38.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.38.0.tgz", + "integrity": "sha512-IoD2MfUnOV58ghIHCiil01PcohxjbYR/qCxsoC+xNgUwh1EY8jOOrYmu3d3a71+tJJ23uscEV4X2HJWMsPJu4g==", + "dev": true, + "peer": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.8", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", @@ -3280,14 +3309,15 @@ } }, "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==", + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", "dev": true, "peer": true, "dependencies": { - "@jridgewell/set-array": "^1.0.0", - "@jridgewell/sourcemap-codec": "^1.4.10" + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" }, "engines": { "node": ">=6.0.0" @@ -3314,9 +3344,9 @@ } }, "node_modules/@jridgewell/source-map": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz", - "integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==", + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.3.tgz", + "integrity": "sha512-b+fsZXeLYi9fEULmfBrhxn4IrPlINf8fiNarzTof004v3lFdntdwa9PF7vFJqm3mg7s+ScJMxXaE3Acp1irZcg==", "dev": true, "peer": true, "dependencies": { @@ -3324,32 +3354,17 @@ "@jridgewell/trace-mapping": "^0.3.9" } }, - "node_modules/@jridgewell/source-map/node_modules/@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", - "dev": true, - "peer": true, - "dependencies": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", "dev": true, "peer": true }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.17", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", - "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", + "version": "0.3.18", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz", + "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==", "dev": true, "peer": true, "dependencies": { @@ -3357,6 +3372,13 @@ "@jridgewell/sourcemap-codec": "1.4.14" } }, + "node_modules/@jridgewell/trace-mapping/node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "dev": true, + "peer": true + }, "node_modules/@leichtgewicht/ip-codec": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz", @@ -3461,9 +3483,9 @@ } }, "node_modules/@remix-run/router": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.3.0.tgz", - "integrity": "sha512-nwQoYb3m4DDpHTeOwpJEuDt8lWVcujhYYSFGLluC+9es2PyLjm+jjq3IeRBQbwBtPLJE/lkuHuGHr8uQLgmJRA==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.5.0.tgz", + "integrity": "sha512-bkUDCp8o1MvFO+qxkODcbhSqRa6P2GXgrGZVpt0dCXNW2HCSCqYI0ZoAqEOSAjRWmmlKcYgFvN4B4S+zo/f8kg==", "engines": { "node": ">=14" } @@ -3514,13 +3536,13 @@ } }, "node_modules/@rollup/plugin-node-resolve/node_modules/resolve": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", - "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "version": "1.22.3", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.3.tgz", + "integrity": "sha512-P8ur/gp/AmbEzjr729bZnLjXK5Z+4P0zhIJgBgzqRih7hL7BOukHGtSTA3ACMY467GRFz3duQsi0bDZdR7DKdw==", "dev": true, "peer": true, "dependencies": { - "is-core-module": "^2.9.0", + "is-core-module": "^2.12.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, @@ -3853,9 +3875,10 @@ } }, "node_modules/@testing-library/dom": { - "version": "8.20.0", - "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.20.0.tgz", - "integrity": "sha512-d9ULIT+a4EXLX3UU8FBjauG9NnsZHkHztXoIcTsOKoOw030fyjheN9svkTULjJxtYag9DZz5Jz5qkWZDPxTFwA==", + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-9.2.0.tgz", + "integrity": "sha512-xTEnpUKiV/bMyEsE5bT4oYA0x0Z/colMtxzUY8bKyPXBNLn/e0V4ZjBZkEhms0xE4pv9QsPfSRu9AWS4y5wGvA==", + "peer": true, "dependencies": { "@babel/code-frame": "^7.10.4", "@babel/runtime": "^7.12.5", @@ -3863,17 +3886,18 @@ "aria-query": "^5.0.0", "chalk": "^4.1.0", "dom-accessibility-api": "^0.5.9", - "lz-string": "^1.4.4", + "lz-string": "^1.5.0", "pretty-format": "^27.0.2" }, "engines": { - "node": ">=12" + "node": ">=14" } }, "node_modules/@testing-library/dom/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "peer": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -3888,6 +3912,7 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "peer": true, "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -3903,6 +3928,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "peer": true, "dependencies": { "color-name": "~1.1.4" }, @@ -3913,12 +3939,14 @@ "node_modules/@testing-library/dom/node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "peer": true }, "node_modules/@testing-library/dom/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "peer": true, "engines": { "node": ">=8" } @@ -3927,6 +3955,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "peer": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -4033,6 +4062,88 @@ "react-dom": "^18.0.0" } }, + "node_modules/@testing-library/react/node_modules/@testing-library/dom": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.20.0.tgz", + "integrity": "sha512-d9ULIT+a4EXLX3UU8FBjauG9NnsZHkHztXoIcTsOKoOw030fyjheN9svkTULjJxtYag9DZz5Jz5qkWZDPxTFwA==", + "dependencies": { + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^5.0.1", + "aria-query": "^5.0.0", + "chalk": "^4.1.0", + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.4.4", + "pretty-format": "^27.0.2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@testing-library/react/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@testing-library/react/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@testing-library/react/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@testing-library/react/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/@testing-library/react/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/@testing-library/react/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/@testing-library/user-event": { "version": "14.4.3", "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.4.3.tgz", @@ -4158,9 +4269,9 @@ } }, "node_modules/@types/eslint": { - "version": "8.4.10", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.10.tgz", - "integrity": "sha512-Sl/HOqN8NKPmhWo2VBEPm0nvHnu2LL3v9vKo8MEq0EtbJ4eVzGPl41VNPvn5E1i5poMk4/XD8UriLHpJvEP/Nw==", + "version": "8.37.0", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.37.0.tgz", + "integrity": "sha512-Piet7dG2JBuDIfohBngQ3rCt7MgO9xCO4xIMKxBThCq5PNRB91IjlJ10eJVwfoNtvTErmxLzwBZ7rHZtbOMmFQ==", "dev": true, "peer": true, "dependencies": { @@ -4187,22 +4298,22 @@ "peer": true }, "node_modules/@types/express": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.15.tgz", - "integrity": "sha512-Yv0k4bXGOH+8a+7bELd2PqHQsuiANB+A8a4gnQrkRWzrkKlb6KHaVvyXhqs04sVW/OWlbPyYxRgYlIXLfrufMQ==", + "version": "4.17.17", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.17.tgz", + "integrity": "sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q==", "dev": true, "peer": true, "dependencies": { "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.31", + "@types/express-serve-static-core": "^4.17.33", "@types/qs": "*", "@types/serve-static": "*" } }, "node_modules/@types/express-serve-static-core": { - "version": "4.17.32", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.32.tgz", - "integrity": "sha512-aI5h/VOkxOF2Z1saPy0Zsxs5avets/iaiAJYznQFm5By/pamU31xWKL//epiF4OfUA2qTOc9PV6tCUjhO8wlZA==", + "version": "4.17.33", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.33.tgz", + "integrity": "sha512-TPBqmR/HRYI3eC2E5hmiivIzv+bidAfXofM+sbonAGvyDhySGw9/PQZFt2BLOrjUUR++4eJVpx6KnLQK1Fk9tA==", "dev": true, "peer": true, "dependencies": { @@ -4234,9 +4345,9 @@ "peer": true }, "node_modules/@types/http-proxy": { - "version": "1.17.9", - "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.9.tgz", - "integrity": "sha512-QsbSjA/fSk7xB+UXlCT3wHBy5ai9wOcNDWwZAtud+jXhwOM3l+EYZh8Lng4+/6n8uar0J7xILzqftJdJ/Wdfkw==", + "version": "1.17.10", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.10.tgz", + "integrity": "sha512-Qs5aULi+zV1bwKAg5z1PWnDXWmsn+LxIvUGv6E2+OOMYhclZMO+OXd9pYVf2gLykf2I7IV2u7oTHwChPNsvJ7g==", "dev": true, "peer": true, "dependencies": { @@ -4293,9 +4404,9 @@ "peer": true }, "node_modules/@types/lodash": { - "version": "4.14.191", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.191.tgz", - "integrity": "sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ==" + "version": "4.14.194", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.194.tgz", + "integrity": "sha512-r22s9tAS7imvBt2lyHC9B8AGwWnXaYb1tY09oyLkXDs4vArpYJzw09nj8MLx5VfciBPGIb+ZwG0ssYnEPJxn/g==" }, "node_modules/@types/lodash.debounce": { "version": "4.0.7", @@ -4377,9 +4488,9 @@ "peer": true }, "node_modules/@types/react": { - "version": "18.0.27", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.27.tgz", - "integrity": "sha512-3vtRKHgVxu3Jp9t718R9BuzoD4NcQ8YJ5XRzsSKxNDiDonD2MXIT1TmSkenxuCycZJoQT5d2vE8LwWJxBC1gmA==", + "version": "18.0.35", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.35.tgz", + "integrity": "sha512-6Laome31HpetaIUGFWl1VQ3mdSImwxtFZ39rh059a1MNnKGqBpC88J6NJ8n/Is3Qx7CefDGLgf/KhN/sYCf7ag==", "dependencies": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -4387,9 +4498,9 @@ } }, "node_modules/@types/react-dom": { - "version": "18.0.10", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.0.10.tgz", - "integrity": "sha512-E42GW/JA4Qv15wQdqJq8DL4JhNpB3prJgjgapN3qJT9K2zO5IIAQh4VXvCEDupoqAwnz0cY4RlXeC/ajX5SFHg==", + "version": "18.0.11", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.0.11.tgz", + "integrity": "sha512-O38bPbI2CWtgw/OoQoY+BRelw7uysmXbWvw3nLWO21H1HSh+GOlqPuXshJfjmpNlKiiSDG9cc1JZAaMmVdcTlw==", "dependencies": { "@types/react": "*" } @@ -4439,9 +4550,9 @@ "peer": true }, "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==" + "version": "0.16.3", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.3.tgz", + "integrity": "sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==" }, "node_modules/@types/semver": { "version": "7.3.13", @@ -4460,9 +4571,9 @@ } }, "node_modules/@types/serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-z5xyF6uh8CbjAu9760KDKsH2FcDxZ2tFCsA4HIMWE6IkiYMXfVoa+4f9KX+FN0ZLsaMw1WNG2ETLA6N+/YA+cg==", + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.1.tgz", + "integrity": "sha512-NUo5XNiAdULrJENtJXZZ3fHtfMolzZwczzBbnAeBbqBwG+LaG6YaJtuwzwGSQZ2wsCrxjEhNNjAkKigy3n8teQ==", "dev": true, "peer": true, "dependencies": { @@ -4496,9 +4607,9 @@ } }, "node_modules/@types/trusted-types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.2.tgz", - "integrity": "sha512-F5DIZ36YVLE+PN+Zwws4kJogq47hNgX3Nx6WyDJ3kcplxyke3XIzB8uK5n/Lpm1HBsbGzd6nmGehL8cPekP+Tg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.3.tgz", + "integrity": "sha512-NfQ4gyz38SL8sDNrSixxU2Os1a5xcdFxipAFxYEuLUlvU2uDwS4NUpsImcf1//SlWItCVMMLiylsxbmNMToV/g==", "dev": true, "peer": true }, @@ -4535,18 +4646,19 @@ "peer": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.48.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.48.2.tgz", - "integrity": "sha512-sR0Gja9Ky1teIq4qJOl0nC+Tk64/uYdX+mi+5iB//MH8gwyx8e3SOyhEzeLZEFEEfCaLf8KJq+Bd/6je1t+CAg==", + "version": "5.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.58.0.tgz", + "integrity": "sha512-vxHvLhH0qgBd3/tW6/VccptSfc8FxPQIkmNTVLWcCOVqSBvqpnKkBTYrhcGlXfSnd78azwe+PsjYFj0X34/njA==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.48.2", - "@typescript-eslint/type-utils": "5.48.2", - "@typescript-eslint/utils": "5.48.2", + "@eslint-community/regexpp": "^4.4.0", + "@typescript-eslint/scope-manager": "5.58.0", + "@typescript-eslint/type-utils": "5.58.0", + "@typescript-eslint/utils": "5.58.0", "debug": "^4.3.4", + "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", "natural-compare-lite": "^1.4.0", - "regexpp": "^3.2.0", "semver": "^7.3.7", "tsutils": "^3.21.0" }, @@ -4580,9 +4692,9 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.4.0.tgz", + "integrity": "sha512-RgOxM8Mw+7Zus0+zcLEUn8+JfoLpj/huFTItQy2hsM4khuC1HYRDp0cU482Ewn/Fcy6bCjufD8vAj7voC66KQw==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -4601,13 +4713,13 @@ "dev": true }, "node_modules/@typescript-eslint/experimental-utils": { - "version": "5.48.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.48.2.tgz", - "integrity": "sha512-Iwx8De8dwl6qPaPZWIaEfP1feN/YFlA5FlCxF3zUIm+2AG92C5Tefkugj2L9ytOFrmTYkTE/CqvJFZbYoVZQMg==", + "version": "5.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.58.0.tgz", + "integrity": "sha512-LA/sRPaynZlrlYxdefrZbMx8dqs/1Kc0yNG+XOk5CwwZx7tTv263ix3AJNioF0YBVt7hADpAUR20owl6pv4MIQ==", "dev": true, "peer": true, "dependencies": { - "@typescript-eslint/utils": "5.48.2" + "@typescript-eslint/utils": "5.58.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -4621,14 +4733,14 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "5.48.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.48.2.tgz", - "integrity": "sha512-38zMsKsG2sIuM5Oi/olurGwYJXzmtdsHhn5mI/pQogP+BjYVkK5iRazCQ8RGS0V+YLk282uWElN70zAAUmaYHw==", + "version": "5.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.58.0.tgz", + "integrity": "sha512-ixaM3gRtlfrKzP8N6lRhBbjTow1t6ztfBvQNGuRM8qH1bjFFXIJ35XY+FC0RRBKn3C6cT+7VW1y8tNm7DwPHDQ==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.48.2", - "@typescript-eslint/types": "5.48.2", - "@typescript-eslint/typescript-estree": "5.48.2", + "@typescript-eslint/scope-manager": "5.58.0", + "@typescript-eslint/types": "5.58.0", + "@typescript-eslint/typescript-estree": "5.58.0", "debug": "^4.3.4" }, "engines": { @@ -4648,13 +4760,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "5.48.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.48.2.tgz", - "integrity": "sha512-zEUFfonQid5KRDKoI3O+uP1GnrFd4tIHlvs+sTJXiWuypUWMuDaottkJuR612wQfOkjYbsaskSIURV9xo4f+Fw==", + "version": "5.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.58.0.tgz", + "integrity": "sha512-b+w8ypN5CFvrXWQb9Ow9T4/6LC2MikNf1viLkYTiTbkQl46CnR69w7lajz1icW0TBsYmlpg+mRzFJ4LEJ8X9NA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.48.2", - "@typescript-eslint/visitor-keys": "5.48.2" + "@typescript-eslint/types": "5.58.0", + "@typescript-eslint/visitor-keys": "5.58.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -4665,13 +4777,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "5.48.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.48.2.tgz", - "integrity": "sha512-QVWx7J5sPMRiOMJp5dYshPxABRoZV1xbRirqSk8yuIIsu0nvMTZesKErEA3Oix1k+uvsk8Cs8TGJ6kQ0ndAcew==", + "version": "5.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.58.0.tgz", + "integrity": "sha512-FF5vP/SKAFJ+LmR9PENql7fQVVgGDOS+dq3j+cKl9iW/9VuZC/8CFmzIP0DLKXfWKpRHawJiG70rVH+xZZbp8w==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "5.48.2", - "@typescript-eslint/utils": "5.48.2", + "@typescript-eslint/typescript-estree": "5.58.0", + "@typescript-eslint/utils": "5.58.0", "debug": "^4.3.4", "tsutils": "^3.21.0" }, @@ -4692,9 +4804,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "5.48.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.48.2.tgz", - "integrity": "sha512-hE7dA77xxu7ByBc6KCzikgfRyBCTst6dZQpwaTy25iMYOnbNljDT4hjhrGEJJ0QoMjrfqrx+j1l1B9/LtKeuqA==", + "version": "5.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.58.0.tgz", + "integrity": "sha512-JYV4eITHPzVQMnHZcYJXl2ZloC7thuUHrcUmxtzvItyKPvQ50kb9QXBkgNAt90OYMqwaodQh2kHutWZl1fc+1g==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -4705,13 +4817,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.48.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.48.2.tgz", - "integrity": "sha512-bibvD3z6ilnoVxUBFEgkO0k0aFvUc4Cttt0dAreEr+nrAHhWzkO83PEVVuieK3DqcgL6VAK5dkzK8XUVja5Zcg==", + "version": "5.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.58.0.tgz", + "integrity": "sha512-cRACvGTodA+UxnYM2uwA2KCwRL7VAzo45syNysqlMyNyjw0Z35Icc9ihPJZjIYuA5bXJYiJ2YGUB59BqlOZT1Q==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.48.2", - "@typescript-eslint/visitor-keys": "5.48.2", + "@typescript-eslint/types": "5.58.0", + "@typescript-eslint/visitor-keys": "5.58.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -4744,9 +4856,9 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.4.0.tgz", + "integrity": "sha512-RgOxM8Mw+7Zus0+zcLEUn8+JfoLpj/huFTItQy2hsM4khuC1HYRDp0cU482Ewn/Fcy6bCjufD8vAj7voC66KQw==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -4765,18 +4877,18 @@ "dev": true }, "node_modules/@typescript-eslint/utils": { - "version": "5.48.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.48.2.tgz", - "integrity": "sha512-2h18c0d7jgkw6tdKTlNaM7wyopbLRBiit8oAxoP89YnuBOzCZ8g8aBCaCqq7h208qUTroL7Whgzam7UY3HVLow==", + "version": "5.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.58.0.tgz", + "integrity": "sha512-gAmLOTFXMXOC+zP1fsqm3VceKSBQJNzV385Ok3+yzlavNHZoedajjS4UyS21gabJYcobuigQPs/z71A9MdJFqQ==", "dev": true, "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.48.2", - "@typescript-eslint/types": "5.48.2", - "@typescript-eslint/typescript-estree": "5.48.2", + "@typescript-eslint/scope-manager": "5.58.0", + "@typescript-eslint/types": "5.58.0", + "@typescript-eslint/typescript-estree": "5.58.0", "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0", "semver": "^7.3.7" }, "engines": { @@ -4803,9 +4915,9 @@ } }, "node_modules/@typescript-eslint/utils/node_modules/semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.4.0.tgz", + "integrity": "sha512-RgOxM8Mw+7Zus0+zcLEUn8+JfoLpj/huFTItQy2hsM4khuC1HYRDp0cU482Ewn/Fcy6bCjufD8vAj7voC66KQw==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -4824,12 +4936,12 @@ "dev": true }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.48.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.48.2.tgz", - "integrity": "sha512-z9njZLSkwmjFWUelGEwEbdf4NwKvfHxvGC0OcGN1Hp/XNDIcJ7D5DpPNPv6x6/mFvc1tQHsaWmpD/a4gOvvCJQ==", + "version": "5.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.58.0.tgz", + "integrity": "sha512-/fBraTlPj0jwdyTwLyrRTxv/3lnU2H96pNTVM6z3esTWLtA5MZ9ghSMJ7Rb+TtUAdtEw9EyJzJ0EydIMKxQ9gA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.48.2", + "@typescript-eslint/types": "5.58.0", "eslint-visitor-keys": "^3.3.0" }, "engines": { @@ -5037,9 +5149,9 @@ } }, "node_modules/acorn": { - "version": "8.8.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", - "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", + "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", "dev": true, "peer": true, "bin": { @@ -5093,31 +5205,6 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/acorn-node": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.8.2.tgz", - "integrity": "sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==", - "dev": true, - "peer": true, - "dependencies": { - "acorn": "^7.0.0", - "acorn-walk": "^7.0.0", - "xtend": "^4.0.2" - } - }, - "node_modules/acorn-node/node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true, - "peer": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/acorn-walk": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", @@ -5282,6 +5369,13 @@ "node": ">=4" } }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "dev": true, + "peer": true + }, "node_modules/anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", @@ -5316,6 +5410,19 @@ "deep-equal": "^2.0.5" } }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz", + "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "is-array-buffer": "^3.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/array-flatten": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", @@ -5460,9 +5567,9 @@ } }, "node_modules/autoprefixer": { - "version": "10.4.13", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.13.tgz", - "integrity": "sha512-49vKpMqcZYsJjwotvt4+h/BCjJVnhGwcLpDt5xkcaOG3eLrG/HUYLagrihYsQ+qrIBgIzX1Rw7a6L8I/ZA1Atg==", + "version": "10.4.14", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.14.tgz", + "integrity": "sha512-FQzyfOsTlwVzjHxKEqRIAdJx9niO6VCBCoEwax/VLSoQF29ggECcPuBqUMZ+u8jCZOPSy8b8/8KnuFbp0SaFZQ==", "dev": true, "funding": [ { @@ -5476,8 +5583,8 @@ ], "peer": true, "dependencies": { - "browserslist": "^4.21.4", - "caniuse-lite": "^1.0.30001426", + "browserslist": "^4.21.5", + "caniuse-lite": "^1.0.30001464", "fraction.js": "^4.2.0", "normalize-range": "^0.1.2", "picocolors": "^1.0.0", @@ -5505,9 +5612,9 @@ } }, "node_modules/axe-core": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.6.2.tgz", - "integrity": "sha512-b1WlTV8+XKLj9gZy2DZXgQiyDp9xkkoe2a6U6UbYccScq2wgH/YwCeI2/Jq2mgo0HzQxqJOjWZBLeA/mqsk5Mg==", + "version": "4.6.3", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.6.3.tgz", + "integrity": "sha512-/BQzOX780JhsxDnPpH4ZiyrJAzcd8AfzFPkv+89veFSr1rcMjuq2JDCwypKaPeB6ljHp9KjXhPpjgCvQlWYuqg==", "dev": true, "peer": true, "engines": { @@ -5712,13 +5819,13 @@ } }, "node_modules/babel-plugin-macros/node_modules/resolve": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", - "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "version": "1.22.3", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.3.tgz", + "integrity": "sha512-P8ur/gp/AmbEzjr729bZnLjXK5Z+4P0zhIJgBgzqRih7hL7BOukHGtSTA3ACMY467GRFz3duQsi0bDZdR7DKdw==", "dev": true, "peer": true, "dependencies": { - "is-core-module": "^2.9.0", + "is-core-module": "^2.12.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, @@ -5973,10 +6080,26 @@ "dev": true, "peer": true }, + "node_modules/body-parser/node_modules/qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dev": true, + "peer": true, + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/bonjour-service": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.1.0.tgz", - "integrity": "sha512-LVRinRB3k1/K0XzZ2p58COnWvkQknIY6sf0zF2rpErvcJXpMBttEPQSxK+HEXSS9VmpZlDoDnQWv8ftJT20B0Q==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.1.1.tgz", + "integrity": "sha512-Z/5lQRMOG9k7W+FkeGTNjh7htqn/2LMnfOvBZ8pynNZCM9MwkQkI3zeI4oz09uWdcgmgHugVvBqxGg4VQJ5PCg==", "dev": true, "peer": true, "dependencies": { @@ -6022,9 +6145,9 @@ "peer": true }, "node_modules/browserslist": { - "version": "4.21.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", - "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", + "version": "4.21.5", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz", + "integrity": "sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==", "dev": true, "funding": [ { @@ -6038,10 +6161,10 @@ ], "peer": true, "dependencies": { - "caniuse-lite": "^1.0.30001400", - "electron-to-chromium": "^1.4.251", - "node-releases": "^2.0.6", - "update-browserslist-db": "^1.0.9" + "caniuse-lite": "^1.0.30001449", + "electron-to-chromium": "^1.4.284", + "node-releases": "^2.0.8", + "update-browserslist-db": "^1.0.10" }, "bin": { "browserslist": "cli.js" @@ -6160,9 +6283,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001446", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001446.tgz", - "integrity": "sha512-fEoga4PrImGcwUUGEol/PoFCSBnSkA9drgdkxXkJLsUBOnJ8rs3zDv6ApqYXGQFOyMPsjh79naWhF4DAxbF8rw==", + "version": "1.0.30001480", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001480.tgz", + "integrity": "sha512-q7cpoPPvZYgtyC4VaBSN0Bt+PJ4c4EYRf0DrduInOz2SkFpHD5p3LnvEpqBp7UnJn+8x1Ogl1s38saUxe+ihQQ==", "dev": true, "funding": [ { @@ -6172,6 +6295,10 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ], "peer": true @@ -6264,9 +6391,9 @@ } }, "node_modules/ci-info": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.7.1.tgz", - "integrity": "sha512-4jYS4MOAaCIStSRwiuxc4B8MYhIe676yO1sYGzARnjXkWpmzZMMYxY6zu8WYWDhSuth5zhrQ1rhNSibyyvv4/w==", + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", + "integrity": "sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==", "dev": true, "funding": [ { @@ -6292,9 +6419,9 @@ "integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==" }, "node_modules/clean-css": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.1.tgz", - "integrity": "sha512-lCr8OHhiWCTw4v8POJovCoh4T7I9U11yVsPjMWWnnMmp9ZowCxyad1Pathle/9HjaDp+fdQKjO9fQydE6RHTZg==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.2.tgz", + "integrity": "sha512-JVJbM+f3d3Q704rF4bqQ5UUyTtuJ0JRKNbTKVEeujCCBoMdkEi+V+e8oktO9qGQNSvHrFTM6JZRXrUvGR1czww==", "dev": true, "peer": true, "dependencies": { @@ -6380,9 +6507,9 @@ "peer": true }, "node_modules/colorette": { - "version": "2.0.19", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz", - "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==", + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", "dev": true, "peer": true }, @@ -6526,9 +6653,9 @@ } }, "node_modules/content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", "dev": true, "peer": true, "engines": { @@ -6560,9 +6687,9 @@ "peer": true }, "node_modules/core-js": { - "version": "3.27.2", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.27.2.tgz", - "integrity": "sha512-9ashVQskuh5AZEZ1JdQWp1GqSoC1e1G87MzRqg2gIfVAQ7Qn9K+uFj8EcniUFA4P2NLZfV+TOlX1SzoKfo+s7w==", + "version": "3.30.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.30.1.tgz", + "integrity": "sha512-ZNS5nbiSwDTq4hFosEDqm65izl2CWmLz0hARJMyNQBgkUZMIF51cQiMvIQKA6hvuaeWxQDP3hEedM1JZIgTldQ==", "dev": true, "hasInstallScript": true, "peer": true, @@ -6572,13 +6699,13 @@ } }, "node_modules/core-js-compat": { - "version": "3.27.2", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.27.2.tgz", - "integrity": "sha512-welaYuF7ZtbYKGrIy7y3eb40d37rG1FvzEOfe7hSLd2iD6duMDqUhRfSvCGyC46HhR6Y8JXXdZ2lnRUMkPBpvg==", + "version": "3.30.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.30.1.tgz", + "integrity": "sha512-d690npR7MC6P0gq4npTl5n2VQeNAmUrJ90n+MHiKS7W2+xno4o3F5GDEuylSdi6EJ3VssibSGXOa1r3YXD3Mhw==", "dev": true, "peer": true, "dependencies": { - "browserslist": "^4.21.4" + "browserslist": "^4.21.5" }, "funding": { "type": "opencollective", @@ -6586,9 +6713,9 @@ } }, "node_modules/core-js-pure": { - "version": "3.27.2", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.27.2.tgz", - "integrity": "sha512-Cf2jqAbXgWH3VVzjyaaFkY1EBazxugUepGymDoeteyYr9ByX51kD2jdHZlsEF/xnJMyN3Prua7mQuzwMg6Zc9A==", + "version": "3.30.1", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.30.1.tgz", + "integrity": "sha512-nXBEVpmUnNRhz83cHd9JRQC52cTMcuXAmR56+9dSMpRdpeA4I1PX6yjmhd71Eyc/wXNsdBdUDIj1QTIeZpU5Tg==", "dev": true, "hasInstallScript": true, "peer": true, @@ -6666,9 +6793,9 @@ } }, "node_modules/css-declaration-sorter": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.3.1.tgz", - "integrity": "sha512-fBffmak0bPAnyqc/HO8C3n2sHrp9wcqQz6ES9koRF2/mLOVAx9zIQ3Y7R29sYCteTPqMCwns4WYQoCX91Xl3+w==", + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.4.0.tgz", + "integrity": "sha512-jDfsatwWMWN0MODAFuHszfjphEXfNw9JUAhmY4pLu3TyTU+ohUpsbVtbU+1MZn4a47D9kqh03i4eyOm+74+zew==", "dev": true, "peer": true, "engines": { @@ -6738,9 +6865,9 @@ } }, "node_modules/css-loader/node_modules/semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.4.0.tgz", + "integrity": "sha512-RgOxM8Mw+7Zus0+zcLEUn8+JfoLpj/huFTItQy2hsM4khuC1HYRDp0cU482Ewn/Fcy6bCjufD8vAj7voC66KQw==", "dev": true, "peer": true, "dependencies": { @@ -6837,16 +6964,16 @@ "peer": true }, "node_modules/css-minimizer-webpack-plugin/node_modules/schema-utils": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", - "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.1.tgz", + "integrity": "sha512-lELhBAAly9NowEsX0yZBlw9ahZG+sK/1RJ21EpzdYHKEs13Vku3LJ+MIPhh4sMs0oCCeufZQEQbMekiA4vuVIQ==", "dev": true, "peer": true, "dependencies": { "@types/json-schema": "^7.0.9", - "ajv": "^8.8.0", + "ajv": "^8.9.0", "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.0.0" + "ajv-keywords": "^5.1.0" }, "engines": { "node": ">= 12.13.0" @@ -6949,9 +7076,9 @@ "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==" }, "node_modules/cssdb": { - "version": "7.2.1", - "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-7.2.1.tgz", - "integrity": "sha512-btohrCpVaLqOoMt90aumHe6HU4c06duiYA8ymwtpGfwuZAhWKDBve/c2k+E85Jeq5iojPkeonqiKV+aLeY8QlA==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-7.5.4.tgz", + "integrity": "sha512-fGD+J6Jlq+aurfE1VDXlLS4Pt0VtNlu2+YgfGOdMxRyl/HQ9bDiHTwSck1Yz8A97Dt/82izSK6Bp/4nVqacOsg==", "dev": true, "peer": true, "funding": { @@ -6973,13 +7100,13 @@ } }, "node_modules/cssnano": { - "version": "5.1.14", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.1.14.tgz", - "integrity": "sha512-Oou7ihiTocbKqi0J1bB+TRJIQX5RMR3JghA8hcWSw9mjBLQ5Y3RWqEDoYG3sRNlAbCIXpqMoZGbq5KDR3vdzgw==", + "version": "5.1.15", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.1.15.tgz", + "integrity": "sha512-j+BKgDcLDQA+eDifLx0EO4XSA56b7uut3BQFH+wbSaSTuGLuiyTa/wbRYthUXX8LC9mLg+WWKe8h+qJuwTAbHw==", "dev": true, "peer": true, "dependencies": { - "cssnano-preset-default": "^5.2.13", + "cssnano-preset-default": "^5.2.14", "lilconfig": "^2.0.3", "yaml": "^1.10.2" }, @@ -6995,23 +7122,23 @@ } }, "node_modules/cssnano-preset-default": { - "version": "5.2.13", - "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.2.13.tgz", - "integrity": "sha512-PX7sQ4Pb+UtOWuz8A1d+Rbi+WimBIxJTRyBdgGp1J75VU0r/HFQeLnMYgHiCAp6AR4rqrc7Y4R+1Rjk3KJz6DQ==", + "version": "5.2.14", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.2.14.tgz", + "integrity": "sha512-t0SFesj/ZV2OTylqQVOrFgEh5uanxbO6ZAdeCrNsUQ6fVuXwYTxJPNAGvGTxHbD68ldIJNec7PyYZDBrfDQ+6A==", "dev": true, "peer": true, "dependencies": { "css-declaration-sorter": "^6.3.1", "cssnano-utils": "^3.1.0", "postcss-calc": "^8.2.3", - "postcss-colormin": "^5.3.0", + "postcss-colormin": "^5.3.1", "postcss-convert-values": "^5.1.3", "postcss-discard-comments": "^5.1.2", "postcss-discard-duplicates": "^5.1.0", "postcss-discard-empty": "^5.1.1", "postcss-discard-overridden": "^5.1.0", "postcss-merge-longhand": "^5.1.7", - "postcss-merge-rules": "^5.1.3", + "postcss-merge-rules": "^5.1.4", "postcss-minify-font-values": "^5.1.0", "postcss-minify-gradients": "^5.1.1", "postcss-minify-params": "^5.1.4", @@ -7026,7 +7153,7 @@ "postcss-normalize-url": "^5.1.0", "postcss-normalize-whitespace": "^5.1.1", "postcss-ordered-values": "^5.1.3", - "postcss-reduce-initial": "^5.1.1", + "postcss-reduce-initial": "^5.1.2", "postcss-reduce-transforms": "^5.1.0", "postcss-svgo": "^5.1.0", "postcss-unique-selectors": "^5.1.1" @@ -7123,9 +7250,9 @@ "peer": true }, "node_modules/csstype": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz", - "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==" + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", + "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==" }, "node_modules/customize-cra": { "version": "1.0.0", @@ -7229,9 +7356,9 @@ "peer": true }, "node_modules/deepmerge": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", - "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", "dev": true, "peer": true, "engines": { @@ -7262,9 +7389,9 @@ } }, "node_modules/define-properties": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", - "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz", + "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==", "dependencies": { "has-property-descriptors": "^1.0.0", "object-keys": "^1.1.1" @@ -7276,16 +7403,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/defined": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.1.tgz", - "integrity": "sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q==", - "dev": true, - "peer": true, - "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", @@ -7369,24 +7486,6 @@ "dev": true, "peer": true }, - "node_modules/detective": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/detective/-/detective-5.2.1.tgz", - "integrity": "sha512-v9XE1zRnz1wRtgurGu0Bs8uHKFSTdteYZNbIPFVhUZ39L/S79ppMpdmVOZAnoz1jfEFodc48n6MX483Xo3t1yw==", - "dev": true, - "peer": true, - "dependencies": { - "acorn-node": "^1.8.2", - "defined": "^1.0.0", - "minimist": "^1.2.6" - }, - "bin": { - "detective": "bin/detective.js" - }, - "engines": { - "node": ">=0.8.0" - } - }, "node_modules/didyoumean": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", @@ -7429,9 +7528,9 @@ "peer": true }, "node_modules/dns-packet": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.4.0.tgz", - "integrity": "sha512-EgqGeaBB8hLiHLZtp/IbaDQTL8pZ0+IvwzSHA6d7VyMDM+B9hgddEMa9xjK5oYnw0ci0JQ6g2XCD7/f6cafU6g==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.5.0.tgz", + "integrity": "sha512-USawdAUzRkV6xrqTjiAEp6M9YagZEzWcSUaZTcIFAiyQWW1SoI6KyId8y2+/71wbgHKQAKd+iupLv4YvEwYWvA==", "dev": true, "peer": true, "dependencies": { @@ -7594,9 +7693,9 @@ "peer": true }, "node_modules/ejs": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.8.tgz", - "integrity": "sha512-/sXZeMlhS0ArkfX2Aw780gJzXSMPnKjtspYZv+f3NiKLlubezAHDU5+9xz6gd3/NhG3txQCo6xlglmTS+oTGEQ==", + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.9.tgz", + "integrity": "sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ==", "dev": true, "peer": true, "dependencies": { @@ -7610,9 +7709,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.284", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz", - "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==", + "version": "1.4.365", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.365.tgz", + "integrity": "sha512-FRHZO+1tUNO4TOPXmlxetkoaIY8uwHzd1kKopK/Gx2SKn1L47wJXWD44wxP5CGRyyP98z/c8e1eBzJrgPeiBOg==", "dev": true, "peer": true }, @@ -7701,18 +7800,18 @@ } }, "node_modules/es-abstract": { - "version": "1.21.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.21.1.tgz", - "integrity": "sha512-QudMsPOz86xYz/1dG1OuGBKOELjCh99IIWHLzy5znUB6j8xG2yMA7bfTV86VSqKF+Y/H08vQPR+9jyXpuC6hfg==", + "version": "1.21.2", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.21.2.tgz", + "integrity": "sha512-y/B5POM2iBnIxCiernH1G7rC9qQoM77lLIMQLuob0zhp8C56Po81+2Nj0WFKnd0pNReDTnkYryc+zhOzpEIROg==", "dev": true, "dependencies": { + "array-buffer-byte-length": "^1.0.0", "available-typed-arrays": "^1.0.5", "call-bind": "^1.0.2", "es-set-tostringtag": "^2.0.1", "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", "function.prototype.name": "^1.1.5", - "get-intrinsic": "^1.1.3", + "get-intrinsic": "^1.2.0", "get-symbol-description": "^1.0.0", "globalthis": "^1.0.3", "gopd": "^1.0.1", @@ -7720,8 +7819,8 @@ "has-property-descriptors": "^1.0.0", "has-proto": "^1.0.1", "has-symbols": "^1.0.3", - "internal-slot": "^1.0.4", - "is-array-buffer": "^3.0.1", + "internal-slot": "^1.0.5", + "is-array-buffer": "^3.0.2", "is-callable": "^1.2.7", "is-negative-zero": "^2.0.2", "is-regex": "^1.1.4", @@ -7729,11 +7828,12 @@ "is-string": "^1.0.7", "is-typed-array": "^1.1.10", "is-weakref": "^1.0.2", - "object-inspect": "^1.12.2", + "object-inspect": "^1.12.3", "object-keys": "^1.1.1", "object.assign": "^4.1.4", "regexp.prototype.flags": "^1.4.3", "safe-regex-test": "^1.0.0", + "string.prototype.trim": "^1.2.7", "string.prototype.trimend": "^1.0.6", "string.prototype.trimstart": "^1.0.6", "typed-array-length": "^1.0.4", @@ -7774,9 +7874,9 @@ } }, "node_modules/es-module-lexer": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.3.tgz", - "integrity": "sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.2.1.tgz", + "integrity": "sha512-9978wrXM50Y4rTMmW5kXIC09ZdXQZqkE4mxhwkd8VbzsGkXGPgV4zWuqQJgCEzYngdo2dYDa0l8xhX4fkSwJSg==", "dev": true, "peer": true }, @@ -7935,13 +8035,16 @@ } }, "node_modules/eslint": { - "version": "8.32.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.32.0.tgz", - "integrity": "sha512-nETVXpnthqKPFyuY2FNjz/bEd6nbosRgKbkgS/y1C7LJop96gYHWpiguLecMHQ2XCPxn77DS0P+68WzG6vkZSQ==", + "version": "8.38.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.38.0.tgz", + "integrity": "sha512-pIdsD2jwlUGf/U38Jv97t8lq6HpaU/G9NKbYmpWpZGw3LdTNhZLbJePqxOXGB5+JEKfOPU/XLxYxFh03nr1KTg==", "dev": true, "peer": true, "dependencies": { - "@eslint/eslintrc": "^1.4.1", + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.4.0", + "@eslint/eslintrc": "^2.0.2", + "@eslint/js": "8.38.0", "@humanwhocodes/config-array": "^0.11.8", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", @@ -7952,10 +8055,9 @@ "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", "eslint-scope": "^7.1.1", - "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.3.0", - "espree": "^9.4.0", - "esquery": "^1.4.0", + "eslint-visitor-keys": "^3.4.0", + "espree": "^9.5.1", + "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", @@ -7976,7 +8078,6 @@ "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.1", - "regexpp": "^3.2.0", "strip-ansi": "^6.0.1", "strip-json-comments": "^3.1.0", "text-table": "^0.2.0" @@ -8043,13 +8144,13 @@ } }, "node_modules/eslint-import-resolver-node/node_modules/resolve": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", - "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "version": "1.22.3", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.3.tgz", + "integrity": "sha512-P8ur/gp/AmbEzjr729bZnLjXK5Z+4P0zhIJgBgzqRih7hL7BOukHGtSTA3ACMY467GRFz3duQsi0bDZdR7DKdw==", "dev": true, "peer": true, "dependencies": { - "is-core-module": "^2.9.0", + "is-core-module": "^2.12.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, @@ -8061,9 +8162,9 @@ } }, "node_modules/eslint-module-utils": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.4.tgz", - "integrity": "sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==", + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz", + "integrity": "sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==", "dev": true, "peer": true, "dependencies": { @@ -8161,13 +8262,13 @@ } }, "node_modules/eslint-plugin-import/node_modules/resolve": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", - "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "version": "1.22.3", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.3.tgz", + "integrity": "sha512-P8ur/gp/AmbEzjr729bZnLjXK5Z+4P0zhIJgBgzqRih7hL7BOukHGtSTA3ACMY467GRFz3duQsi0bDZdR7DKdw==", "dev": true, "peer": true, "dependencies": { - "is-core-module": "^2.9.0", + "is-core-module": "^2.12.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, @@ -8235,9 +8336,9 @@ } }, "node_modules/eslint-plugin-react": { - "version": "7.32.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.32.1.tgz", - "integrity": "sha512-vOjdgyd0ZHBXNsmvU+785xY8Bfe57EFbTYYk8XrROzWpr9QBvpjITvAXt9xqcE6+8cjR/g1+mfumPToxsl1www==", + "version": "7.32.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.32.2.tgz", + "integrity": "sha512-t2fBMa+XzonrrNkyVirzKlvn5RXzzPwRHtMvLAtVZrt8oxgnTQaYbU6SXTOO1mwQgp1y5+toMSKInnzGr0Knqg==", "dev": true, "dependencies": { "array-includes": "^3.1.6", @@ -8289,13 +8390,13 @@ } }, "node_modules/eslint-plugin-testing-library": { - "version": "5.9.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-testing-library/-/eslint-plugin-testing-library-5.9.1.tgz", - "integrity": "sha512-6BQp3tmb79jLLasPHJmy8DnxREe+2Pgf7L+7o09TSWPfdqqtQfRZmZNetr5mOs3yqZk/MRNxpN3RUpJe0wB4LQ==", + "version": "5.10.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-testing-library/-/eslint-plugin-testing-library-5.10.3.tgz", + "integrity": "sha512-0yhsKFsjHLud5PM+f2dWr9K3rqYzMy4cSHs3lcmFYMa1CdSzRvHGgXvsFarBjZ41gU8jhTdMIkg8jHLxGJqLqw==", "dev": true, "peer": true, "dependencies": { - "@typescript-eslint/utils": "^5.13.0" + "@typescript-eslint/utils": "^5.58.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0", @@ -8327,40 +8428,16 @@ "node": ">=4.0" } }, - "node_modules/eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^2.0.0" - }, - "engines": { - "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=5" - } - }, - "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true, - "engines": { - "node": ">=10" - } - }, "node_modules/eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.0.tgz", + "integrity": "sha512-HPpKPUBQcAsZOsHAFwTtIKcYlCje62XB7SEAcxjtmW6TD1WVpkS6i6/hOVtTZIl4zGj/mBqpFVGvaDneik+VoQ==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/eslint-webpack-plugin": { @@ -8451,16 +8528,16 @@ "peer": true }, "node_modules/eslint-webpack-plugin/node_modules/schema-utils": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", - "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.1.tgz", + "integrity": "sha512-lELhBAAly9NowEsX0yZBlw9ahZG+sK/1RJ21EpzdYHKEs13Vku3LJ+MIPhh4sMs0oCCeufZQEQbMekiA4vuVIQ==", "dev": true, "peer": true, "dependencies": { "@types/json-schema": "^7.0.9", - "ajv": "^8.8.0", + "ajv": "^8.9.0", "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.0.0" + "ajv-keywords": "^5.1.0" }, "engines": { "node": ">= 12.13.0" @@ -8553,9 +8630,9 @@ } }, "node_modules/eslint/node_modules/eslint-scope": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", - "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz", + "integrity": "sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==", "dev": true, "peer": true, "dependencies": { @@ -8564,12 +8641,15 @@ }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/eslint/node_modules/globals": { - "version": "13.19.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.19.0.tgz", - "integrity": "sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==", + "version": "13.20.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", + "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", "dev": true, "peer": true, "dependencies": { @@ -8619,15 +8699,15 @@ } }, "node_modules/espree": { - "version": "9.4.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz", - "integrity": "sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==", + "version": "9.5.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.1.tgz", + "integrity": "sha512-5yxtHSZXRSW5pvv3hAlXM5+/Oswi1AUFqBmbibKb5s6bp3rGIDkyXU6xCoyuuLhijr4SFwPrXRoZjz0AZDN9tg==", "dev": true, "peer": true, "dependencies": { "acorn": "^8.8.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.3.0" + "eslint-visitor-keys": "^3.4.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -8651,9 +8731,9 @@ } }, "node_modules/esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", "dev": true, "peer": true, "dependencies": { @@ -8844,6 +8924,22 @@ "dev": true, "peer": true }, + "node_modules/express/node_modules/qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dev": true, + "peer": true, + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -9135,9 +9231,9 @@ } }, "node_modules/fork-ts-checker-webpack-plugin": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.2.tgz", - "integrity": "sha512-m5cUmF30xkZ7h4tWUgTAcEaKmUW7tfyUyTqNNOz7OxWJ0v1VWKTcOvH8FWHUwSjlW/356Ijc9vi3XfcPstpQKA==", + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.3.tgz", + "integrity": "sha512-SbH/l9ikmMWycd5puHJKTkZJKddF4iRLyW3DeZ08HTI7NGyLS38MXd/KGgeWumQO7YNQbW2u/NtPT2YowbPaGQ==", "dev": true, "peer": true, "dependencies": { @@ -9303,9 +9399,9 @@ } }, "node_modules/fork-ts-checker-webpack-plugin/node_modules/semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.4.0.tgz", + "integrity": "sha512-RgOxM8Mw+7Zus0+zcLEUn8+JfoLpj/huFTItQy2hsM4khuC1HYRDp0cU482Ewn/Fcy6bCjufD8vAj7voC66KQw==", "dev": true, "peer": true, "dependencies": { @@ -9491,9 +9587,9 @@ } }, "node_modules/get-intrinsic": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", - "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz", + "integrity": "sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==", "dependencies": { "function-bind": "^1.1.1", "has": "^1.0.3", @@ -9688,9 +9784,9 @@ } }, "node_modules/graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "dev": true, "peer": true }, @@ -9698,8 +9794,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/gzip-size": { "version": "6.0.0", @@ -9847,9 +9942,9 @@ "peer": true }, "node_modules/hpack.js/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dev": true, "peer": true, "dependencies": { @@ -9929,9 +10024,9 @@ } }, "node_modules/html-webpack-plugin": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.5.0.tgz", - "integrity": "sha512-sy88PC2cRTVxvETRgUHFrL4No3UxvcH8G1NepGhqaTT+GXN2kTamqasot0inS5hXeg1cMbFDt27zzo9p35lZVw==", + "version": "5.5.1", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.5.1.tgz", + "integrity": "sha512-cTUzZ1+NqjGEKjmVgZKLMdiFg3m9MdRXkZW2OEe69WYVi5ONLMmlnSZdXzGGMOq0C8jGDrL6EWyEDDUioHO/pA==", "dev": true, "peer": true, "dependencies": { @@ -10138,9 +10233,9 @@ } }, "node_modules/immer": { - "version": "9.0.18", - "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.18.tgz", - "integrity": "sha512-eAPNpsj7Ax1q6Y/3lm2PmlwRcFzpON7HSNQ3ru5WQH1/PSpnyed/HpNOELl2CxLKoj4r+bAHgdyKqW5gc2Se1A==", + "version": "9.0.21", + "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz", + "integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==", "dev": true, "peer": true, "funding": { @@ -10149,9 +10244,9 @@ } }, "node_modules/immutable": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.2.2.tgz", - "integrity": "sha512-fTMKDwtbvO5tldky9QZ2fMX7slR0mYpY5nbnFWYp0fOzDhHqhgIw9KoYgxLWsoNTS9ZHGauHj18DTyEw6BK3Og==" + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.0.tgz", + "integrity": "sha512-0AOCmOip+xgJwEVTQj1EfiDDOkPmuyllDuTuEX+DDXUgapLAsBIfkg3sxCYyCEA8mQqZrrxPUGjcOQ2JS3WLkg==" }, "node_modules/import-fresh": { "version": "3.3.0", @@ -10234,11 +10329,11 @@ "peer": true }, "node_modules/internal-slot": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.4.tgz", - "integrity": "sha512-tA8URYccNzMo94s5MQZgH8NB/XTa6HsOo0MLfXTKKEnHVVdegzaQoFZ7Jp44bdvLvY2waT5dc+j5ICEswhi7UQ==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", + "integrity": "sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==", "dependencies": { - "get-intrinsic": "^1.1.3", + "get-intrinsic": "^1.2.0", "has": "^1.0.3", "side-channel": "^1.0.4" }, @@ -10280,12 +10375,12 @@ } }, "node_modules/is-array-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.1.tgz", - "integrity": "sha512-ASfLknmY8Xa2XtB4wmbz13Wu202baeA18cJBCeCy0wXUHZF0IPyVEXqKEcd+t2fNSLLL1vC6k7lxZEojNbISXQ==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", + "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==", "dependencies": { "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.3", + "get-intrinsic": "^1.2.0", "is-typed-array": "^1.1.10" }, "funding": { @@ -10348,9 +10443,9 @@ } }, "node_modules/is-core-module": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", - "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.0.tgz", + "integrity": "sha512-RECHCBCd/viahWmwj6enj19sKbHfJrddi/6cBDsNTKbNq0f7VeaUkBo60BqzvPqo/W54ChS62Z5qyun7cfOMqQ==", "dev": true, "dependencies": { "has": "^1.0.3" @@ -11965,13 +12060,13 @@ } }, "node_modules/jest-resolve/node_modules/resolve": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", - "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "version": "1.22.3", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.3.tgz", + "integrity": "sha512-P8ur/gp/AmbEzjr729bZnLjXK5Z+4P0zhIJgBgzqRih7hL7BOukHGtSTA3ACMY467GRFz3duQsi0bDZdR7DKdw==", "dev": true, "peer": true, "dependencies": { - "is-core-module": "^2.9.0", + "is-core-module": "^2.12.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, @@ -12339,9 +12434,9 @@ } }, "node_modules/jest-snapshot/node_modules/semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.4.0.tgz", + "integrity": "sha512-RgOxM8Mw+7Zus0+zcLEUn8+JfoLpj/huFTItQy2hsM4khuC1HYRDp0cU482Ewn/Fcy6bCjufD8vAj7voC66KQw==", "dev": true, "peer": true, "dependencies": { @@ -12647,9 +12742,9 @@ } }, "node_modules/jest-watch-typeahead/node_modules/@types/yargs": { - "version": "17.0.20", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.20.tgz", - "integrity": "sha512-eknWrTHofQuPk2iuqDm1waA7V6xPlbgBoaaXEgYkClhLOnB0TtbW+srJaOToAgawPxPlHQzwypFA2bhZaUGP5A==", + "version": "17.0.24", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.24.tgz", + "integrity": "sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw==", "dev": true, "peer": true, "dependencies": { @@ -13092,10 +13187,20 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, + "node_modules/jiti": { + "version": "1.18.2", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.18.2.tgz", + "integrity": "sha512-QAdOptna2NYiSSpv0O/BwoHBSmz4YhpzJHyi+fnMRTXFjp7B8i/YG5Z8IfusxB1ufjcD2Sre1F3R+nX3fvy7gg==", + "dev": true, + "peer": true, + "bin": { + "jiti": "bin/jiti.js" + } + }, "node_modules/js-sdsl": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.2.0.tgz", - "integrity": "sha512-dyBIzQBDkCqCu+0upx25Y2jGdbTGxE9fshMsCdK0ViOongpV+n5tXRcZY9v7CaVQ79AGS9KA1KHtojxiM7aXSQ==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.4.0.tgz", + "integrity": "sha512-FfVSdx6pJ41Oa+CF7RDaFmTnCaFhua+SNYQX74riGOpl96x+2jQCqEfQ2bnXu/5DPCqlRuiqyvTJM0Qjz26IVg==", "dev": true, "peer": true, "funding": { @@ -13305,6 +13410,17 @@ "language-subtag-registry": "~0.3.2" } }, + "node_modules/launch-editor": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.6.0.tgz", + "integrity": "sha512-JpDCcQnyAAzZZaZ7vEiSqL690w7dAEyLao+KC96zBplnYbJS7TYNjvM3M7y3dGz+v7aIsJk3hllWuc0kWAjyRQ==", + "dev": true, + "peer": true, + "dependencies": { + "picocolors": "^1.0.0", + "shell-quote": "^1.7.3" + } + }, "node_modules/leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", @@ -13330,9 +13446,9 @@ } }, "node_modules/lilconfig": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.6.tgz", - "integrity": "sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", + "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", "dev": true, "peer": true, "engines": { @@ -13473,9 +13589,9 @@ } }, "node_modules/lz-string": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.4.4.tgz", - "integrity": "sha512-0ckx7ZHRPqb0oUm8zNr+90mtf9DQB60H1wMCjBtfi62Kl3a7JbHob6gA2bC+xRvZoOL+1hzUK8jeuEIQE8svEQ==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", + "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", "bin": { "lz-string": "bin/bin.js" } @@ -13517,9 +13633,9 @@ } }, "node_modules/marked": { - "version": "4.2.12", - "resolved": "https://registry.npmjs.org/marked/-/marked-4.2.12.tgz", - "integrity": "sha512-yr8hSKa3Fv4D3jdZmtMMPghgVt6TWbk86WQaWhDloQjRSQhMMYCAro7jP7VDJrjjdV8pxVxMssXS8B8Y5DZ5aw==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz", + "integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==", "bin": { "marked": "bin/marked.js" }, @@ -13545,9 +13661,9 @@ } }, "node_modules/memfs": { - "version": "3.4.13", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.4.13.tgz", - "integrity": "sha512-omTM41g3Skpvx5dSYeZIbXKcXoAVc/AoMNwn9TKx++L/gaen/+4TTttmu8ZSch5vfVJ8uJvGbroTsIlslRg6lg==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.0.tgz", + "integrity": "sha512-yK6o8xVJlQerz57kvPROwTMgx5WtGwC2ZxDtOUsnGl49rHjYkfQoPNZPCKH73VdLE1BwBu/+Fx/NL8NYMUw2aA==", "dev": true, "peer": true, "dependencies": { @@ -13658,9 +13774,9 @@ } }, "node_modules/mini-css-extract-plugin": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.7.2.tgz", - "integrity": "sha512-EdlUizq13o0Pd+uCp+WO/JpkLvHRVGt97RqfeGhXqAcorYo1ypJSpkV+WDT0vY/kmh/p7wRdJNJtuyK540PXDw==", + "version": "2.7.5", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.7.5.tgz", + "integrity": "sha512-9HaR++0mlgom81s95vvNjxkg52n2b5s//3ZTI1EtzFb98awsLSivs2LMsVqnQ3ay0PVhqWcGNyDaTE961FOcjQ==", "dev": true, "peer": true, "dependencies": { @@ -13715,16 +13831,16 @@ "peer": true }, "node_modules/mini-css-extract-plugin/node_modules/schema-utils": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", - "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.1.tgz", + "integrity": "sha512-lELhBAAly9NowEsX0yZBlw9ahZG+sK/1RJ21EpzdYHKEs13Vku3LJ+MIPhh4sMs0oCCeufZQEQbMekiA4vuVIQ==", "dev": true, "peer": true, "dependencies": { "@types/json-schema": "^7.0.9", - "ajv": "^8.8.0", + "ajv": "^8.9.0", "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.0.0" + "ajv-keywords": "^5.1.0" }, "engines": { "node": ">= 12.13.0" @@ -13754,9 +13870,9 @@ } }, "node_modules/minimist": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", - "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", "dev": true, "peer": true, "funding": { @@ -13796,12 +13912,30 @@ "multicast-dns": "cli.js" } }, - "node_modules/nanoid": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", - "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", "dev": true, "peer": true, + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", + "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "peer": true, "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -13868,9 +14002,9 @@ "peer": true }, "node_modules/node-releases": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.8.tgz", - "integrity": "sha512-dFSmB8fFHEH/s81Xi+Y/15DQY6VHW81nXRj86EMSL3lmuTmK1e+aT4wrFCkTbm+gSwkw4KpX+rT/pMM2c1mF+A==", + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz", + "integrity": "sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==", "dev": true, "peer": true }, @@ -13932,9 +14066,9 @@ } }, "node_modules/nwsapi": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.2.tgz", - "integrity": "sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw==", + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.4.tgz", + "integrity": "sha512-NHj4rzRo0tQdijE9ZqAx6kYDcoRwYwSYzCA8MY3JzfxlrvEU0jhnhJT9BhqhJs7I/dKcrDm6TyulaRqZPIhN5g==", "dev": true, "peer": true }, @@ -14142,9 +14276,9 @@ } }, "node_modules/open": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/open/-/open-8.4.0.tgz", - "integrity": "sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q==", + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", "dev": true, "peer": true, "dependencies": { @@ -14550,9 +14684,9 @@ } }, "node_modules/postcss": { - "version": "8.4.21", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.21.tgz", - "integrity": "sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==", + "version": "8.4.22", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.22.tgz", + "integrity": "sha512-XseknLAfRHzVWjCEtdviapiBtfLdgyzExD50Rg2ePaucEesyh8Wv4VPdW0nbyDa1ydbrAxV19jvMT4+LFmcNUA==", "dev": true, "funding": [ { @@ -14562,11 +14696,15 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ], "peer": true, "dependencies": { - "nanoid": "^3.3.4", + "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" }, @@ -14699,13 +14837,13 @@ } }, "node_modules/postcss-colormin": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-5.3.0.tgz", - "integrity": "sha512-WdDO4gOFG2Z8n4P8TWBpshnL3JpmNmJwdnfP2gbk2qBA8PWwOYcmjmI/t3CmMeL72a7Hkd+x/Mg9O2/0rD54Pg==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-5.3.1.tgz", + "integrity": "sha512-UsWQG0AqTFQmpBegeLLc1+c3jIqBNB0zlDGRWR+dQ3pRKJL1oeMzyqmH3o2PIfn9MBdNrVPWhDbT769LxCTLJQ==", "dev": true, "peer": true, "dependencies": { - "browserslist": "^4.16.6", + "browserslist": "^4.21.4", "caniuse-api": "^3.0.0", "colord": "^2.9.1", "postcss-value-parser": "^4.2.0" @@ -15011,13 +15149,13 @@ } }, "node_modules/postcss-import/node_modules/resolve": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", - "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "version": "1.22.3", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.3.tgz", + "integrity": "sha512-P8ur/gp/AmbEzjr729bZnLjXK5Z+4P0zhIJgBgzqRih7hL7BOukHGtSTA3ACMY467GRFz3duQsi0bDZdR7DKdw==", "dev": true, "peer": true, "dependencies": { - "is-core-module": "^2.9.0", + "is-core-module": "^2.12.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, @@ -15039,9 +15177,9 @@ } }, "node_modules/postcss-js": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.0.tgz", - "integrity": "sha512-77QESFBwgX4irogGVPgQ5s07vLvFqWr228qZY+w6lW599cRlK/HmnlivnnVUxkjHnCu4J16PDMHcH+e+2HbvTQ==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", + "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", "dev": true, "peer": true, "dependencies": { @@ -15055,7 +15193,7 @@ "url": "https://opencollective.com/postcss/" }, "peerDependencies": { - "postcss": "^8.3.3" + "postcss": "^8.4.21" } }, "node_modules/postcss-lab-function": { @@ -15146,9 +15284,9 @@ } }, "node_modules/postcss-loader/node_modules/semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.4.0.tgz", + "integrity": "sha512-RgOxM8Mw+7Zus0+zcLEUn8+JfoLpj/huFTItQy2hsM4khuC1HYRDp0cU482Ewn/Fcy6bCjufD8vAj7voC66KQw==", "dev": true, "peer": true, "dependencies": { @@ -15212,9 +15350,9 @@ } }, "node_modules/postcss-merge-rules": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.1.3.tgz", - "integrity": "sha512-LbLd7uFC00vpOuMvyZop8+vvhnfRGpp2S+IMQKeuOZZapPRY4SMq5ErjQeHbHsjCUgJkRNrlU+LmxsKIqPKQlA==", + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.1.4.tgz", + "integrity": "sha512-0R2IuYpgU93y9lhVbO/OylTtKMVcHb67zjWIfCiKR9rWL3GUk1677LAqD/BcHizukdZEjT8Ru3oHRoAYoJy44g==", "dev": true, "peer": true, "dependencies": { @@ -15743,9 +15881,9 @@ } }, "node_modules/postcss-reduce-initial": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.1.1.tgz", - "integrity": "sha512-//jeDqWcHPuXGZLoolFrUXBDyuEGbr9S2rMo19bkTIjBQ4PqkaO+oI8wua5BOUxpfi97i3PCoInsiFIEBfkm9w==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.1.2.tgz", + "integrity": "sha512-dE/y2XRaqAi6OvjzD22pjTUQ8eOfc6m/natGHgKFBK9DxFmIm69YmaRVQrGgFlEfc1HePIurY0TmDeROK05rIg==", "dev": true, "peer": true, "dependencies": { @@ -15923,9 +16061,9 @@ "peer": true }, "node_modules/preact": { - "version": "10.11.3", - "resolved": "https://registry.npmjs.org/preact/-/preact-10.11.3.tgz", - "integrity": "sha512-eY93IVpod/zG3uMF22Unl8h9KkrcKIRs2EGar8hwLZZDU1lkjph303V9HZBwufh2s736U6VXuhD109LYqPoffg==", + "version": "10.13.2", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.13.2.tgz", + "integrity": "sha512-q44QFLhOhty2Bd0Y46fnYW0gD/cbVM9dUVtNTDKPcdXSMA7jfY+Jpd6rk3GB0lcQss0z5s/6CmVP0Z/hV+g6pw==", "funding": { "type": "opencollective", "url": "https://opencollective.com/preact" @@ -16069,9 +16207,9 @@ "peer": true }, "node_modules/punycode": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.2.0.tgz", - "integrity": "sha512-LN6QV1IJ9ZhxWTNdktaPClrNfp8xdSAYS0Zk2ddX7XsXZAxckMHPCBcHRo0cTcEIgYPRiGEkmji3Idkh2yFtYw==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", "dev": true, "peer": true, "engines": { @@ -16090,9 +16228,9 @@ } }, "node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "version": "6.11.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.1.tgz", + "integrity": "sha512-0wsrzgTz/kAVIeuxSjnpGC56rzYtr6JT/2BwEvMaPhFIoYa1aGO8LbzuU1R0uUYQkLpWBTOj0l/CLAJB64J6nQ==", "dependencies": { "side-channel": "^1.0.4" }, @@ -16450,11 +16588,11 @@ } }, "node_modules/react-router": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.7.0.tgz", - "integrity": "sha512-KNWlG622ddq29MAM159uUsNMdbX8USruoKnwMMQcs/QWZgFUayICSn2oB7reHce1zPj6CG18kfkZIunSSRyGHg==", + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.10.0.tgz", + "integrity": "sha512-Nrg0BWpQqrC3ZFFkyewrflCud9dio9ME3ojHCF/WLsprJVzkq3q3UeEhMCAW1dobjeGbWgjNn/PVF6m46ANxXQ==", "dependencies": { - "@remix-run/router": "1.3.0" + "@remix-run/router": "1.5.0" }, "engines": { "node": ">=14" @@ -16464,12 +16602,12 @@ } }, "node_modules/react-router-dom": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.7.0.tgz", - "integrity": "sha512-jQtXUJyhso3kFw430+0SPCbmCmY1/kJv8iRffGHwHy3CkoomGxeYzMkmeSPYo6Egzh3FKJZRAL22yg5p2tXtfg==", + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.10.0.tgz", + "integrity": "sha512-E5dfxRPuXKJqzwSe/qGcqdwa18QiWC6f3H3cWXM24qj4N0/beCIf/CWTipop2xm7mR0RCS99NnaqPNjHtrAzCg==", "dependencies": { - "@remix-run/router": "1.3.0", - "react-router": "6.7.0" + "@remix-run/router": "1.5.0", + "react-router": "6.10.0" }, "engines": { "node": ">=14" @@ -16567,13 +16705,13 @@ } }, "node_modules/react-scripts/node_modules/resolve": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", - "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "version": "1.22.3", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.3.tgz", + "integrity": "sha512-P8ur/gp/AmbEzjr729bZnLjXK5Z+4P0zhIJgBgzqRih7hL7BOukHGtSTA3ACMY467GRFz3duQsi0bDZdR7DKdw==", "dev": true, "peer": true, "dependencies": { - "is-core-module": "^2.9.0", + "is-core-module": "^2.12.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, @@ -16585,9 +16723,9 @@ } }, "node_modules/react-scripts/node_modules/semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.4.0.tgz", + "integrity": "sha512-RgOxM8Mw+7Zus0+zcLEUn8+JfoLpj/huFTItQy2hsM4khuC1HYRDp0cU482Ewn/Fcy6bCjufD8vAj7voC66KQw==", "dev": true, "peer": true, "dependencies": { @@ -16618,9 +16756,9 @@ } }, "node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "dev": true, "peer": true, "dependencies": { @@ -16726,28 +16864,16 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - } - }, "node_modules/regexpu-core": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.2.2.tgz", - "integrity": "sha512-T0+1Zp2wjF/juXMrMxHxidqGYn8U4R+zleSJhX9tQ1PUsS8a9UtYfbsF9LdiVgNX3kiX8RNaKM42nfSgvFJjmw==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", + "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", "dev": true, "peer": true, "dependencies": { + "@babel/regjsgen": "^0.8.0", "regenerate": "^1.4.2", "regenerate-unicode-properties": "^10.1.0", - "regjsgen": "^0.7.1", "regjsparser": "^0.9.1", "unicode-match-property-ecmascript": "^2.0.0", "unicode-match-property-value-ecmascript": "^2.1.0" @@ -16756,13 +16882,6 @@ "node": ">=4" } }, - "node_modules/regjsgen": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.7.1.tgz", - "integrity": "sha512-RAt+8H2ZEzHeYWxZ3H2z6tF18zyyOnlcdaafLrm21Bguj7uZy6ULibiAFdXEtKQY4Sy7wDTwDiOazasMLc4KPA==", - "dev": true, - "peer": true - }, "node_modules/regjsparser": { "version": "0.9.1", "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", @@ -17151,9 +17270,9 @@ "peer": true }, "node_modules/sass": { - "version": "1.57.1", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.57.1.tgz", - "integrity": "sha512-O2+LwLS79op7GI0xZ8fqzF7X2m/m8WFfI02dHOdsK5R2ECeS5F62zrwg/relM1rjSLy7Vd/DiMNIvPrQGsA0jw==", + "version": "1.62.0", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.62.0.tgz", + "integrity": "sha512-Q4USplo4pLYgCi+XlipZCWUQz5pkg/ruSSgJ0WRDSb/+3z9tXUOkQ7QPYn4XrhZKYAK4HlpaQecRwKLJX6+DBg==", "dependencies": { "chokidar": ">=3.0.0 <4.0.0", "immutable": "^4.0.0", @@ -17163,7 +17282,7 @@ "sass": "sass.js" }, "engines": { - "node": ">=12.0.0" + "node": ">=14.0.0" } }, "node_modules/sass-loader": { @@ -17235,9 +17354,9 @@ } }, "node_modules/schema-utils": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", - "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.2.tgz", + "integrity": "sha512-pvjEHOgWc9OWA/f/DE3ohBWTD6EleVLf7iFUkoSwAxttdBhB9QUebQgxER2kWueOvRJXPHNnyrvvh9eZINB8Eg==", "dev": true, "peer": true, "dependencies": { @@ -17474,9 +17593,9 @@ } }, "node_modules/shell-quote": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.4.tgz", - "integrity": "sha512-8o/QEhSSRb1a5i7TFR0iM4G16Z0vYB2OQVs4G3aAFXjn3T6yEx8AZxy1PgDF7I00LZHYA3WxaSYIf5e5sAX8Rw==", + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", + "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", "dev": true, "peer": true, "funding": { @@ -17777,6 +17896,23 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/string.prototype.trim": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz", + "integrity": "sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/string.prototype.trimend": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz", @@ -17888,9 +18024,9 @@ } }, "node_modules/style-loader": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.1.tgz", - "integrity": "sha512-GPcQ+LDJbrcxHORTRes6Jy2sfvK2kS6hpSfI/fXhPt+spVzxF6LJ1dHLN9zIGmVaaP044YKaIatFaufENRiDoQ==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.2.tgz", + "integrity": "sha512-RHs/vcrKdQK8wZliteNK4NKzxvLBzpuHMqYmUVWeKa6MkaIQ97ZTOS0b+zapZhy6GcrgWnvWYCMHRirC3FsUmw==", "dev": true, "peer": true, "engines": { @@ -17921,6 +18057,60 @@ "postcss": "^8.2.15" } }, + "node_modules/sucrase": { + "version": "3.32.0", + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.32.0.tgz", + "integrity": "sha512-ydQOU34rpSyj2TGyz4D2p8rbktIOZ8QY9s+DGLvFU1i5pWJE8vkpruCjGCMHsdXwnD7JDcS+noSwM/a7zyNFDQ==", + "dev": true, + "peer": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "glob": "7.1.6", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "ts-interface-checker": "^0.1.9" + }, + "bin": { + "sucrase": "bin/sucrase", + "sucrase-node": "bin/sucrase-node" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/sucrase/node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/sucrase/node_modules/glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "peer": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -18104,35 +18294,36 @@ "peer": true }, "node_modules/tailwindcss": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.2.4.tgz", - "integrity": "sha512-AhwtHCKMtR71JgeYDaswmZXhPcW9iuI9Sp2LvZPo9upDZ7231ZJ7eA9RaURbhpXGVlrjX4cFNlB4ieTetEb7hQ==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.3.1.tgz", + "integrity": "sha512-Vkiouc41d4CEq0ujXl6oiGFQ7bA3WEhUZdTgXAhtKxSy49OmKs8rEfQmupsfF0IGW8fv2iQkp1EVUuapCFrZ9g==", "dev": true, "peer": true, "dependencies": { "arg": "^5.0.2", "chokidar": "^3.5.3", "color-name": "^1.1.4", - "detective": "^5.2.1", "didyoumean": "^1.2.2", "dlv": "^1.1.3", "fast-glob": "^3.2.12", "glob-parent": "^6.0.2", "is-glob": "^4.0.3", + "jiti": "^1.17.2", "lilconfig": "^2.0.6", "micromatch": "^4.0.5", "normalize-path": "^3.0.0", "object-hash": "^3.0.0", "picocolors": "^1.0.0", - "postcss": "^8.4.18", + "postcss": "^8.0.9", "postcss-import": "^14.1.0", "postcss-js": "^4.0.0", "postcss-load-config": "^3.1.4", "postcss-nested": "6.0.0", - "postcss-selector-parser": "^6.0.10", + "postcss-selector-parser": "^6.0.11", "postcss-value-parser": "^4.2.0", "quick-lru": "^5.1.1", - "resolve": "^1.22.1" + "resolve": "^1.22.1", + "sucrase": "^3.29.0" }, "bin": { "tailwind": "lib/cli.js", @@ -18153,13 +18344,13 @@ "peer": true }, "node_modules/tailwindcss/node_modules/resolve": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", - "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "version": "1.22.3", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.3.tgz", + "integrity": "sha512-P8ur/gp/AmbEzjr729bZnLjXK5Z+4P0zhIJgBgzqRih7hL7BOukHGtSTA3ACMY467GRFz3duQsi0bDZdR7DKdw==", "dev": true, "peer": true, "dependencies": { - "is-core-module": "^2.9.0", + "is-core-module": "^2.12.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, @@ -18240,9 +18431,9 @@ } }, "node_modules/terser": { - "version": "5.16.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.16.1.tgz", - "integrity": "sha512-xvQfyfA1ayT0qdK47zskQgRZeWLoOQ8JQ6mIgRGVNwZKdQMU+5FkCBjmv4QjcrTzyZquRw2FVtlJSRUmMKQslw==", + "version": "5.16.9", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.16.9.tgz", + "integrity": "sha512-HPa/FdTB9XGI2H1/keLFZHxl6WNvAI4YalHGtDQTlMnJcoqSab1UwL4l1hGEhs6/GmLHBZIg/YgB++jcbzoOEg==", "dev": true, "peer": true, "dependencies": { @@ -18259,17 +18450,17 @@ } }, "node_modules/terser-webpack-plugin": { - "version": "5.3.6", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.6.tgz", - "integrity": "sha512-kfLFk+PoLUQIbLmB1+PZDMRSZS99Mp+/MHqDNmMA6tOItzRt+Npe3E+fsMs5mfcM0wCtrrdU387UnV+vnSffXQ==", + "version": "5.3.7", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.7.tgz", + "integrity": "sha512-AfKwIktyP7Cu50xNjXF/6Qb5lBNzYaWpU6YfoX3uZicTx0zTy0stDDCsvjDapKsSDvOeWo5MEq4TmdBy2cNoHw==", "dev": true, "peer": true, "dependencies": { - "@jridgewell/trace-mapping": "^0.3.14", + "@jridgewell/trace-mapping": "^0.3.17", "jest-worker": "^27.4.5", "schema-utils": "^3.1.1", - "serialize-javascript": "^6.0.0", - "terser": "^5.14.1" + "serialize-javascript": "^6.0.1", + "terser": "^5.16.5" }, "engines": { "node": ">= 10.13.0" @@ -18322,6 +18513,29 @@ "dev": true, "peer": true }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dev": true, + "peer": true, + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "dev": true, + "peer": true, + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, "node_modules/throat": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.2.tgz", @@ -18420,15 +18634,22 @@ "dev": true, "peer": true }, + "node_modules/ts-interface-checker": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", + "dev": true, + "peer": true + }, "node_modules/tsconfig-paths": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", - "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==", + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz", + "integrity": "sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==", "dev": true, "peer": true, "dependencies": { "@types/json5": "^0.0.29", - "json5": "^1.0.1", + "json5": "^1.0.2", "minimist": "^1.2.6", "strip-bom": "^3.0.0" } @@ -18457,9 +18678,9 @@ } }, "node_modules/tslib": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", - "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz", + "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==", "dev": true, "peer": true }, @@ -18681,9 +18902,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", - "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", + "integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==", "dev": true, "funding": [ { @@ -18693,6 +18914,10 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ], "peer": true, @@ -18701,16 +18926,16 @@ "picocolors": "^1.0.0" }, "bin": { - "browserslist-lint": "cli.js" + "update-browserslist-db": "cli.js" }, "peerDependencies": { "browserslist": ">= 4.21.0" } }, "node_modules/uplot": { - "version": "1.6.23", - "resolved": "https://registry.npmjs.org/uplot/-/uplot-1.6.23.tgz", - "integrity": "sha512-zERH8HUbHE6kYyAqfP58SYuESp9M5jphSrMjsyckAM0DJ8C39SEI19YrpVvTCTLZB5joFUBPOwueRnJCdV2OdQ==" + "version": "1.6.24", + "resolved": "https://registry.npmjs.org/uplot/-/uplot-1.6.24.tgz", + "integrity": "sha512-WpH2BsrFrqxkMu+4XBvc0eCDsRBhzoq9crttYeSI0bfxpzR5YoSVzZXOKFVWcVC7sp/aDXrdDPbDZGCtck2PVg==" }, "node_modules/uri-js": { "version": "4.4.1", @@ -18890,14 +19115,14 @@ } }, "node_modules/webpack": { - "version": "5.76.2", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.76.2.tgz", - "integrity": "sha512-Th05ggRm23rVzEOlX8y67NkYCHa9nTNcwHPBhdg+lKG+mtiW7XgggjAeeLnADAe7mLjJ6LUNfgHAuRRh+Z6J7w==", + "version": "5.79.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.79.0.tgz", + "integrity": "sha512-3mN4rR2Xq+INd6NnYuL9RC9GAmc1ROPKJoHhrZ4pAjdMFEkJJWrsPw8o2JjCIyQyTu7rTXYn4VG6OpyB3CobZg==", "dev": true, "peer": true, "dependencies": { "@types/eslint-scope": "^3.7.3", - "@types/estree": "^0.0.51", + "@types/estree": "^1.0.0", "@webassemblyjs/ast": "1.11.1", "@webassemblyjs/wasm-edit": "1.11.1", "@webassemblyjs/wasm-parser": "1.11.1", @@ -18906,7 +19131,7 @@ "browserslist": "^4.14.5", "chrome-trace-event": "^1.0.2", "enhanced-resolve": "^5.10.0", - "es-module-lexer": "^0.9.0", + "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", "events": "^3.2.0", "glob-to-regexp": "^0.4.1", @@ -18917,7 +19142,7 @@ "neo-async": "^2.6.2", "schema-utils": "^3.1.0", "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.1.3", + "terser-webpack-plugin": "^5.3.7", "watchpack": "^2.4.0", "webpack-sources": "^3.2.3" }, @@ -18999,16 +19224,16 @@ "peer": true }, "node_modules/webpack-dev-middleware/node_modules/schema-utils": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", - "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.1.tgz", + "integrity": "sha512-lELhBAAly9NowEsX0yZBlw9ahZG+sK/1RJ21EpzdYHKEs13Vku3LJ+MIPhh4sMs0oCCeufZQEQbMekiA4vuVIQ==", "dev": true, "peer": true, "dependencies": { "@types/json-schema": "^7.0.9", - "ajv": "^8.8.0", + "ajv": "^8.9.0", "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.0.0" + "ajv-keywords": "^5.1.0" }, "engines": { "node": ">= 12.13.0" @@ -19019,9 +19244,9 @@ } }, "node_modules/webpack-dev-server": { - "version": "4.11.1", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.11.1.tgz", - "integrity": "sha512-lILVz9tAUy1zGFwieuaQtYiadImb5M3d+H+L1zDYalYoDl0cksAB1UNyuE5MMWJrG6zR1tXkCP2fitl7yoUJiw==", + "version": "4.13.3", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.13.3.tgz", + "integrity": "sha512-KqqzrzMRSRy5ePz10VhjyL27K2dxqwXQLP5rAKwRJBPUahe7Z2bBWzHw37jeb8GCPKxZRO79ZdQUAPesMh/Nug==", "dev": true, "peer": true, "dependencies": { @@ -19044,6 +19269,7 @@ "html-entities": "^2.3.2", "http-proxy-middleware": "^2.0.3", "ipaddr.js": "^2.0.1", + "launch-editor": "^2.6.0", "open": "^8.0.9", "p-retry": "^4.5.0", "rimraf": "^3.0.2", @@ -19053,7 +19279,7 @@ "sockjs": "^0.3.24", "spdy": "^4.0.2", "webpack-dev-middleware": "^5.3.1", - "ws": "^8.4.2" + "ws": "^8.13.0" }, "bin": { "webpack-dev-server": "bin/webpack-dev-server.js" @@ -19069,6 +19295,9 @@ "webpack": "^4.37.0 || ^5.0.0" }, "peerDependenciesMeta": { + "webpack": { + "optional": true + }, "webpack-cli": { "optional": true } @@ -19112,16 +19341,16 @@ "peer": true }, "node_modules/webpack-dev-server/node_modules/schema-utils": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", - "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.1.tgz", + "integrity": "sha512-lELhBAAly9NowEsX0yZBlw9ahZG+sK/1RJ21EpzdYHKEs13Vku3LJ+MIPhh4sMs0oCCeufZQEQbMekiA4vuVIQ==", "dev": true, "peer": true, "dependencies": { "@types/json-schema": "^7.0.9", - "ajv": "^8.8.0", + "ajv": "^8.9.0", "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.0.0" + "ajv-keywords": "^5.1.0" }, "engines": { "node": ">= 12.13.0" @@ -19132,9 +19361,9 @@ } }, "node_modules/webpack-dev-server/node_modules/ws": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.12.0.tgz", - "integrity": "sha512-kU62emKIdKVeEIOIKVegvqpXMSTAMLJozpHZaJNDYqBjzlSYXQGviYwN1osDLJ9av68qHd4a2oSjd7yD4pacig==", + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", + "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", "dev": true, "peer": true, "engines": { @@ -19204,13 +19433,6 @@ "node": ">=10.13.0" } }, - "node_modules/webpack/node_modules/@types/estree": { - "version": "0.0.51", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz", - "integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==", - "dev": true, - "peer": true - }, "node_modules/websocket-driver": { "version": "0.7.4", "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", @@ -19820,16 +20042,6 @@ "dev": true, "peer": true }, - "node_modules/xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true, - "peer": true, - "engines": { - "node": ">=0.4" - } - }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", diff --git a/app/vmui/packages/vmui/src/components/Chart/BarChart/BarChart.tsx b/app/vmui/packages/vmui/src/components/Chart/BarChart/BarChart.tsx index 6f1a7a465c..fe1a3429db 100644 --- a/app/vmui/packages/vmui/src/components/Chart/BarChart/BarChart.tsx +++ b/app/vmui/packages/vmui/src/components/Chart/BarChart/BarChart.tsx @@ -1,19 +1,17 @@ import React, { FC, useEffect, useRef, useState } from "preact/compat"; import uPlot, { Options as uPlotOptions } from "uplot"; -import useResize from "../../../hooks/useResize"; import { BarChartProps } from "./types"; import "./style.scss"; import { useAppState } from "../../../state/common/StateContext"; const BarChart: FC<BarChartProps> = ({ data, - container, + layoutSize, configs }) => { const { isDarkTheme } = useAppState(); const uPlotRef = useRef<HTMLDivElement>(null); const [uPlotInst, setUPlotInst] = useState<uPlot>(); - const layoutSize = useResize(container); const options: uPlotOptions ={ ...configs, diff --git a/app/vmui/packages/vmui/src/components/Chart/BarChart/types.ts b/app/vmui/packages/vmui/src/components/Chart/BarChart/types.ts index 50377534cb..2dfeedbc4d 100644 --- a/app/vmui/packages/vmui/src/components/Chart/BarChart/types.ts +++ b/app/vmui/packages/vmui/src/components/Chart/BarChart/types.ts @@ -1,7 +1,8 @@ import { AlignedData as uPlotData, Options as uPlotOptions } from "uplot"; +import { ElementSize } from "../../../hooks/useElementSize"; export interface BarChartProps { data: uPlotData; - container: HTMLDivElement | null, + layoutSize: ElementSize, configs: uPlotOptions, } diff --git a/app/vmui/packages/vmui/src/components/Chart/Heatmap/ChartTooltipHeatmap/ChartTooltipHeatmap.tsx b/app/vmui/packages/vmui/src/components/Chart/Heatmap/ChartTooltipHeatmap/ChartTooltipHeatmap.tsx index 3cfeb5a355..3995aa2c9e 100644 --- a/app/vmui/packages/vmui/src/components/Chart/Heatmap/ChartTooltipHeatmap/ChartTooltipHeatmap.tsx +++ b/app/vmui/packages/vmui/src/components/Chart/Heatmap/ChartTooltipHeatmap/ChartTooltipHeatmap.tsx @@ -1,4 +1,4 @@ -import React, { FC, useEffect, useMemo, useRef, useState } from "preact/compat"; +import React, { FC, useCallback, useEffect, useRef, useState } from "preact/compat"; import uPlot from "uplot"; import ReactDOM from "react-dom"; import Button from "../../../Main/Button/Button"; @@ -6,6 +6,7 @@ import { CloseIcon, DragIcon } from "../../../Main/Icons"; import classNames from "classnames"; import { MouseEvent as ReactMouseEvent } from "react"; import "../../Line/ChartTooltip/style.scss"; +import useEventListener from "../../../../hooks/useEventListener"; export interface TooltipHeatmapProps { cursor: {left: number, top: number} @@ -45,24 +46,22 @@ const ChartTooltipHeatmap: FC<ChartTooltipHeatmapProps> = ({ const [moving, setMoving] = useState(false); const [moved, setMoved] = useState(false); - const targetPortal = useMemo(() => u.root.querySelector(".u-wrap"), [u]); - const handleClose = () => { onClose && onClose(id); }; - const handleMouseDown = (e: ReactMouseEvent<HTMLButtonElement, MouseEvent>) => { + const handleMouseDown = (e: ReactMouseEvent) => { setMoved(true); setMoving(true); const { clientX, clientY } = e; setPosition({ top: clientY, left: clientX }); }; - const handleMouseMove = (e: MouseEvent) => { + const handleMouseMove = useCallback((e: MouseEvent) => { if (!moving) return; const { clientX, clientY } = e; setPosition({ top: clientY, left: clientX }); - }; + }, [moving]); const handleMouseUp = () => { setMoving(false); @@ -88,19 +87,10 @@ const ChartTooltipHeatmap: FC<ChartTooltipHeatmapProps> = ({ useEffect(calcPosition, [u, cursor, tooltipOffset, tooltipRef]); - useEffect(() => { - if (moving) { - document.addEventListener("mousemove", handleMouseMove); - document.addEventListener("mouseup", handleMouseUp); - } + useEventListener("mousemove", handleMouseMove); + useEventListener("mouseup", handleMouseUp); - return () => { - document.removeEventListener("mousemove", handleMouseMove); - document.removeEventListener("mouseup", handleMouseUp); - }; - }, [moving]); - - if (!targetPortal || !cursor.left || !cursor.top || !value) return null; + if (!cursor?.left || !cursor?.top || !value) return null; return ReactDOM.createPortal(( <div @@ -146,7 +136,7 @@ const ChartTooltipHeatmap: FC<ChartTooltipHeatmapProps> = ({ {bucket} </div> </div> - ), targetPortal); + ), u.root); }; export default ChartTooltipHeatmap; diff --git a/app/vmui/packages/vmui/src/components/Chart/Heatmap/HeatmapChart/HeatmapChart.tsx b/app/vmui/packages/vmui/src/components/Chart/Heatmap/HeatmapChart/HeatmapChart.tsx index cdbe20fc58..f483ff83b8 100644 --- a/app/vmui/packages/vmui/src/components/Chart/Heatmap/HeatmapChart/HeatmapChart.tsx +++ b/app/vmui/packages/vmui/src/components/Chart/Heatmap/HeatmapChart/HeatmapChart.tsx @@ -10,7 +10,6 @@ import { getAxes } from "../../../../utils/uplot/axes"; import { MetricResult } from "../../../../api/types"; import { dateFromSeconds, formatDateForNativeInput, limitsDurations } from "../../../../utils/time"; import throttle from "lodash.throttle"; -import useResize from "../../../../hooks/useResize"; import { TimeParams } from "../../../../types"; import { YaxisState } from "../../../../state/graph/reducer"; import "uplot/dist/uPlot.min.css"; @@ -23,6 +22,8 @@ import ChartTooltipHeatmap, { ChartTooltipHeatmapProps, TooltipHeatmapProps } from "../ChartTooltipHeatmap/ChartTooltipHeatmap"; +import { ElementSize } from "../../../../hooks/useElementSize"; +import useEventListener from "../../../../hooks/useEventListener"; export interface HeatmapChartProps { metrics: MetricResult[]; @@ -31,7 +32,7 @@ export interface HeatmapChartProps { yaxis: YaxisState; unit?: string; setPeriod: ({ from, to }: {from: Date, to: Date}) => void; - container: HTMLDivElement | null; + layoutSize: ElementSize, height?: number; onChangeLegend: (val: TooltipHeatmapProps) => void; } @@ -45,7 +46,7 @@ const HeatmapChart: FC<HeatmapChartProps> = ({ yaxis, unit, setPeriod, - container, + layoutSize, height, onChangeLegend, }) => { @@ -56,7 +57,6 @@ const HeatmapChart: FC<HeatmapChartProps> = ({ const [xRange, setXRange] = useState({ min: period.start, max: period.end }); const [uPlotInst, setUPlotInst] = useState<uPlot>(); const [startTouchDistance, setStartTouchDistance] = useState(0); - const layoutSize = useResize(container); const [tooltipProps, setTooltipProps] = useState<TooltipHeatmapProps | null>(null); const [tooltipOffset, setTooltipOffset] = useState({ left: 0, top: 0 }); @@ -116,7 +116,7 @@ const HeatmapChart: FC<HeatmapChartProps> = ({ }); }; - const handleKeyDown = (e: KeyboardEvent) => { + const handleKeyDown = useCallback((e: KeyboardEvent) => { const { target, ctrlKey, metaKey, key } = e; const isInput = target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement; if (!uPlotInst || isInput) return; @@ -131,10 +131,10 @@ const HeatmapChart: FC<HeatmapChartProps> = ({ max: xRange.max - factor }); } - }; + }, [uPlotInst, xRange]); - const handleClick = () => { - if (!tooltipProps) return; + const handleClick = useCallback(() => { + if (!tooltipProps?.value) return; const id = `${tooltipProps?.bucket}_${tooltipProps?.startDate}`; const props = { id, @@ -147,13 +147,12 @@ const HeatmapChart: FC<HeatmapChartProps> = ({ const res = JSON.parse(JSON.stringify(props)); setStickyToolTips(prev => [...prev, res]); } - }; + }, [stickyTooltips, tooltipProps, tooltipOffset, unit]); - const handleUnStick = (id:string) => { + const handleUnStick = (id: string) => { setStickyToolTips(prev => prev.filter(t => t.id !== id)); }; - const setCursor = (u: uPlot) => { const left = u.cursor.left && u.cursor.left > 0 ? u.cursor.left : 0; const top = u.cursor.top && u.cursor.top > 0 ? u.cursor.top : 0; @@ -263,21 +262,14 @@ const HeatmapChart: FC<HeatmapChartProps> = ({ useEffect(() => { setStickyToolTips([]); setTooltipProps(null); - if (!uPlotRef.current || !layoutSize.width || !layoutSize.height) return; + const isValidData = data[0] === null && Array.isArray(data[1]); + if (!uPlotRef.current || !layoutSize.width || !layoutSize.height || !isValidData) return; const u = new uPlot(options, data, uPlotRef.current); setUPlotInst(u); setXRange({ min: period.start, max: period.end }); return u.destroy; }, [uPlotRef.current, layoutSize, height, isDarkTheme, data]); - useEffect(() => { - window.addEventListener("keydown", handleKeyDown); - - return () => { - window.removeEventListener("keydown", handleKeyDown); - }; - }, [xRange]); - const handleTouchStart = (e: TouchEvent) => { if (e.touches.length !== 2) return; e.preventDefault(); @@ -287,7 +279,7 @@ const HeatmapChart: FC<HeatmapChartProps> = ({ setStartTouchDistance(Math.sqrt(dx * dx + dy * dy)); }; - const handleTouchMove = (e: TouchEvent) => { + const handleTouchMove = useCallback((e: TouchEvent) => { if (e.touches.length !== 2 || !uPlotInst) return; e.preventDefault(); @@ -307,34 +299,20 @@ const HeatmapChart: FC<HeatmapChartProps> = ({ min: min + zoomFactor, max: max - zoomFactor })); - }; - - useEffect(() => { - window.addEventListener("touchmove", handleTouchMove); - window.addEventListener("touchstart", handleTouchStart); - - return () => { - window.removeEventListener("touchmove", handleTouchMove); - window.removeEventListener("touchstart", handleTouchStart); - }; - }, [uPlotInst, startTouchDistance]); + }, [uPlotInst, startTouchDistance, xRange]); useEffect(() => updateChart(typeChartUpdate.xRange), [xRange]); useEffect(() => updateChart(typeChartUpdate.yRange), [yaxis]); - useEffect(() => { - const show = !!tooltipProps?.value; - if (show) window.addEventListener("click", handleClick); - - return () => { - window.removeEventListener("click", handleClick); - }; - }, [tooltipProps, stickyTooltips]); - useEffect(() => { if (tooltipProps) onChangeLegend(tooltipProps); }, [tooltipProps]); + useEventListener("click", handleClick); + useEventListener("keydown", handleKeyDown); + useEventListener("touchmove", handleTouchMove); + useEventListener("touchstart", handleTouchStart); + return ( <div className={classNames({ diff --git a/app/vmui/packages/vmui/src/components/Chart/Line/ChartTooltip/ChartTooltip.tsx b/app/vmui/packages/vmui/src/components/Chart/Line/ChartTooltip/ChartTooltip.tsx index 23c2a434a3..1c7e21d473 100644 --- a/app/vmui/packages/vmui/src/components/Chart/Line/ChartTooltip/ChartTooltip.tsx +++ b/app/vmui/packages/vmui/src/components/Chart/Line/ChartTooltip/ChartTooltip.tsx @@ -1,4 +1,4 @@ -import React, { FC, useEffect, useMemo, useRef, useState } from "preact/compat"; +import React, { FC, useCallback, useEffect, useMemo, useRef, useState } from "preact/compat"; import uPlot from "uplot"; import { MetricResult } from "../../../../api/types"; import { formatPrettyNumber } from "../../../../utils/uplot/helpers"; @@ -12,6 +12,7 @@ import classNames from "classnames"; import { MouseEvent as ReactMouseEvent } from "react"; import "./style.scss"; import { SeriesItem } from "../../../../utils/uplot/series"; +import useEventListener from "../../../../hooks/useEventListener"; export interface ChartTooltipProps { id: string, @@ -47,8 +48,6 @@ const ChartTooltip: FC<ChartTooltipProps> = ({ const [seriesIdx, setSeriesIdx] = useState(tooltipIdx.seriesIdx); const [dataIdx, setDataIdx] = useState(tooltipIdx.dataIdx); - const targetPortal = useMemo(() => u.root.querySelector(".u-wrap"), [u]); - const value = get(u, ["data", seriesIdx, dataIdx], 0); const valueFormat = formatPrettyNumber(value, get(yRange, [0]), get(yRange, [1])); const dataTime = u.data[0][dataIdx]; @@ -85,11 +84,11 @@ const ChartTooltip: FC<ChartTooltipProps> = ({ setPosition({ top: clientY, left: clientX }); }; - const handleMouseMove = (e: MouseEvent) => { + const handleMouseMove = useCallback((e: MouseEvent) => { if (!moving) return; const { clientX, clientY } = e; setPosition({ top: clientY, left: clientX }); - }; + }, [moving]); const handleMouseUp = () => { setMoving(false); @@ -125,19 +124,10 @@ const ChartTooltip: FC<ChartTooltipProps> = ({ setDataIdx(tooltipIdx.dataIdx); }, [tooltipIdx]); - useEffect(() => { - if (moving) { - document.addEventListener("mousemove", handleMouseMove); - document.addEventListener("mouseup", handleMouseUp); - } + useEventListener("mousemove", handleMouseMove); + useEventListener("mouseup", handleMouseUp); - return () => { - document.removeEventListener("mousemove", handleMouseMove); - document.removeEventListener("mouseup", handleMouseUp); - }; - }, [moving]); - - if (!targetPortal || tooltipIdx.seriesIdx < 0 || tooltipIdx.dataIdx < 0) return null; + if (tooltipIdx.seriesIdx < 0 || tooltipIdx.dataIdx < 0) return null; return ReactDOM.createPortal(( <div @@ -190,7 +180,7 @@ const ChartTooltip: FC<ChartTooltipProps> = ({ {fullMetricName} </div> </div> - ), targetPortal); + ), u.root); }; export default ChartTooltip; diff --git a/app/vmui/packages/vmui/src/components/Chart/Line/Legend/LegendItem/LegendItem.tsx b/app/vmui/packages/vmui/src/components/Chart/Line/Legend/LegendItem/LegendItem.tsx index ebc080825d..7893d7ab7d 100644 --- a/app/vmui/packages/vmui/src/components/Chart/Line/Legend/LegendItem/LegendItem.tsx +++ b/app/vmui/packages/vmui/src/components/Chart/Line/Legend/LegendItem/LegendItem.tsx @@ -5,6 +5,7 @@ import "./style.scss"; import classNames from "classnames"; import Tooltip from "../../../../Main/Tooltip/Tooltip"; import { getFreeFields } from "./helpers"; +import useCopyToClipboard from "../../../../../hooks/useCopyToClipboard"; interface LegendItemProps { legend: LegendItemType; @@ -13,16 +14,20 @@ interface LegendItemProps { } const LegendItem: FC<LegendItemProps> = ({ legend, onChange, isHeatmap }) => { + const copyToClipboard = useCopyToClipboard(); const [copiedValue, setCopiedValue] = useState(""); + const freeFormFields = useMemo(() => { const result = getFreeFields(legend); return isHeatmap ? result.filter(f => f.key !== "vmrange") : result; }, [legend, isHeatmap]); + const calculations = legend.calculations; const showCalculations = Object.values(calculations).some(v => v); const handleClickFreeField = async (val: string, id: string) => { - await navigator.clipboard.writeText(val); + const copied = await copyToClipboard(val); + if (!copied) return; setCopiedValue(id); setTimeout(() => setCopiedValue(""), 2000); }; diff --git a/app/vmui/packages/vmui/src/components/Chart/Line/LineChart/LineChart.tsx b/app/vmui/packages/vmui/src/components/Chart/Line/LineChart/LineChart.tsx index 7fab79c11e..e47d6cfba0 100644 --- a/app/vmui/packages/vmui/src/components/Chart/Line/LineChart/LineChart.tsx +++ b/app/vmui/packages/vmui/src/components/Chart/Line/LineChart/LineChart.tsx @@ -13,7 +13,6 @@ import { getAxes, getMinMaxBuffer } from "../../../../utils/uplot/axes"; import { MetricResult } from "../../../../api/types"; import { dateFromSeconds, formatDateForNativeInput, limitsDurations } from "../../../../utils/time"; import throttle from "lodash.throttle"; -import useResize from "../../../../hooks/useResize"; import { TimeParams } from "../../../../types"; import { YaxisState } from "../../../../state/graph/reducer"; import "uplot/dist/uPlot.min.css"; @@ -23,6 +22,8 @@ import ChartTooltip, { ChartTooltipProps } from "../ChartTooltip/ChartTooltip"; import dayjs from "dayjs"; import { useAppState } from "../../../../state/common/StateContext"; import { SeriesItem } from "../../../../utils/uplot/series"; +import { ElementSize } from "../../../../hooks/useElementSize"; +import useEventListener from "../../../../hooks/useEventListener"; export interface LineChartProps { metrics: MetricResult[]; @@ -32,7 +33,7 @@ export interface LineChartProps { series: uPlotSeries[]; unit?: string; setPeriod: ({ from, to }: {from: Date, to: Date}) => void; - container: HTMLDivElement | null; + layoutSize: ElementSize; height?: number; } @@ -46,7 +47,7 @@ const LineChart: FC<LineChartProps> = ({ yaxis, unit, setPeriod, - container, + layoutSize, height }) => { const { isDarkTheme } = useAppState(); @@ -57,7 +58,6 @@ const LineChart: FC<LineChartProps> = ({ const [yRange, setYRange] = useState([0, 1]); const [uPlotInst, setUPlotInst] = useState<uPlot>(); const [startTouchDistance, setStartTouchDistance] = useState(0); - const layoutSize = useResize(container); const [showTooltip, setShowTooltip] = useState(false); const [tooltipIdx, setTooltipIdx] = useState({ seriesIdx: -1, dataIdx: -1 }); @@ -115,7 +115,7 @@ const LineChart: FC<LineChartProps> = ({ }); }; - const handleKeyDown = (e: KeyboardEvent) => { + const handleKeyDown = useCallback((e: KeyboardEvent) => { const { target, ctrlKey, metaKey, key } = e; const isInput = target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement; if (!uPlotInst || isInput) return; @@ -130,9 +130,10 @@ const LineChart: FC<LineChartProps> = ({ max: xRange.max - factor }); } - }; + }, [uPlotInst, xRange]); - const handleClick = () => { + const handleClick = useCallback(() => { + if (!showTooltip) return; const id = `${tooltipIdx.seriesIdx}_${tooltipIdx.dataIdx}`; const props = { id, @@ -148,7 +149,7 @@ const LineChart: FC<LineChartProps> = ({ const tooltipProps = JSON.parse(JSON.stringify(props)); setStickyToolTips(prev => [...prev, tooltipProps]); } - }; + }, [metrics, series, stickyTooltips, tooltipIdx, tooltipOffset, showTooltip, unit, yRange]); const handleUnStick = (id:string) => { setStickyToolTips(prev => prev.filter(t => t.id !== id)); @@ -231,14 +232,6 @@ const LineChart: FC<LineChartProps> = ({ return u.destroy; }, [uPlotRef.current, series, layoutSize, height, isDarkTheme]); - useEffect(() => { - window.addEventListener("keydown", handleKeyDown); - - return () => { - window.removeEventListener("keydown", handleKeyDown); - }; - }, [xRange]); - const handleTouchStart = (e: TouchEvent) => { if (e.touches.length !== 2) return; e.preventDefault(); @@ -248,7 +241,7 @@ const LineChart: FC<LineChartProps> = ({ setStartTouchDistance(Math.sqrt(dx * dx + dy * dy)); }; - const handleTouchMove = (e: TouchEvent) => { + const handleTouchMove = useCallback((e: TouchEvent) => { if (e.touches.length !== 2 || !uPlotInst) return; e.preventDefault(); @@ -268,17 +261,7 @@ const LineChart: FC<LineChartProps> = ({ min: min + zoomFactor, max: max - zoomFactor })); - }; - - useEffect(() => { - window.addEventListener("touchmove", handleTouchMove); - window.addEventListener("touchstart", handleTouchStart); - - return () => { - window.removeEventListener("touchmove", handleTouchMove); - window.removeEventListener("touchstart", handleTouchStart); - }; - }, [uPlotInst, startTouchDistance]); + }, [uPlotInst, startTouchDistance, xRange]); useEffect(() => updateChart(typeChartUpdate.xRange), [xRange]); useEffect(() => updateChart(typeChartUpdate.yRange), [yaxis]); @@ -286,14 +269,13 @@ const LineChart: FC<LineChartProps> = ({ useEffect(() => { const show = tooltipIdx.dataIdx !== -1 && tooltipIdx.seriesIdx !== -1; setShowTooltip(show); - - if (show) window.addEventListener("click", handleClick); - - return () => { - window.removeEventListener("click", handleClick); - }; }, [tooltipIdx, stickyTooltips]); + useEventListener("click", handleClick); + useEventListener("keydown", handleKeyDown); + useEventListener("touchmove", handleTouchMove); + useEventListener("touchstart", handleTouchStart); + return ( <div className={classNames({ diff --git a/app/vmui/packages/vmui/src/components/Chart/SimpleBarChart/style.scss b/app/vmui/packages/vmui/src/components/Chart/SimpleBarChart/style.scss index a274c1cfe8..135feac615 100644 --- a/app/vmui/packages/vmui/src/components/Chart/SimpleBarChart/style.scss +++ b/app/vmui/packages/vmui/src/components/Chart/SimpleBarChart/style.scss @@ -7,13 +7,13 @@ $color-bar-highest: #F79420; display: grid; grid-template-columns: auto 1fr; height: 100%; - padding-bottom: #{$font-size-small/2}; + padding-bottom: calc($font-size-small/2); overflow: hidden; &-y-axis { position: relative; display: grid; - transform: translateY(#{$font-size-small}); + transform: translateY($font-size-small); &__tick { position: relative; diff --git a/app/vmui/packages/vmui/src/components/Configurators/AdditionalSettings/AdditionalSettings.tsx b/app/vmui/packages/vmui/src/components/Configurators/AdditionalSettings/AdditionalSettings.tsx index 1ea20aeaac..f4b7b66947 100644 --- a/app/vmui/packages/vmui/src/components/Configurators/AdditionalSettings/AdditionalSettings.tsx +++ b/app/vmui/packages/vmui/src/components/Configurators/AdditionalSettings/AdditionalSettings.tsx @@ -1,4 +1,4 @@ -import React, { FC, useRef, useState } from "preact/compat"; +import React, { FC, useRef } from "preact/compat"; import { useCustomPanelDispatch, useCustomPanelState } from "../../../state/customPanel/CustomPanelStateContext"; import { useQueryDispatch, useQueryState } from "../../../state/query/QueryStateContext"; import "./style.scss"; @@ -8,6 +8,7 @@ import Popper from "../../Main/Popper/Popper"; import { TuneIcon } from "../../Main/Icons"; import Button from "../../Main/Button/Button"; import classNames from "classnames"; +import useBoolean from "../../../hooks/useBoolean"; const AdditionalSettingsControls: FC<{isMobile?: boolean}> = ({ isMobile }) => { const { autocomplete } = useQueryState(); @@ -59,16 +60,13 @@ const AdditionalSettingsControls: FC<{isMobile?: boolean}> = ({ isMobile }) => { const AdditionalSettings: FC = () => { const { isMobile } = useDeviceDetect(); - const [openList, setOpenList] = useState(false); const targetRef = useRef<HTMLDivElement>(null); - const handleToggleList = () => { - setOpenList(prev => !prev); - }; - - const handleCloseList = () => { - setOpenList(false); - }; + const { + value: openList, + toggle: handleToggleList, + setFalse: handleCloseList, + } = useBoolean(false); if (isMobile) { return ( diff --git a/app/vmui/packages/vmui/src/components/Configurators/GlobalSettings/GlobalSettings.tsx b/app/vmui/packages/vmui/src/components/Configurators/GlobalSettings/GlobalSettings.tsx index 4751a112eb..420a048bee 100644 --- a/app/vmui/packages/vmui/src/components/Configurators/GlobalSettings/GlobalSettings.tsx +++ b/app/vmui/packages/vmui/src/components/Configurators/GlobalSettings/GlobalSettings.tsx @@ -15,6 +15,7 @@ import Timezones from "./Timezones/Timezones"; import { useTimeDispatch, useTimeState } from "../../../state/time/TimeStateContext"; import ThemeControl from "../ThemeControl/ThemeControl"; import useDeviceDetect from "../../../hooks/useDeviceDetect"; +import useBoolean from "../../../hooks/useBoolean"; const title = "Settings"; @@ -40,15 +41,14 @@ const GlobalSettings: FC = () => { setTimezone(stateTimezone); }; - const [open, setOpen] = useState(false); - const handleOpen = () => setOpen(true); - const handleClose = () => { - setOpen(false); - setDefaultsValues(); - }; + const { + value: open, + setTrue: handleOpen, + setFalse: handleClose, + } = useBoolean(false); - const handleCloseForce = () => { - setOpen(false); + const handleCloseAndReset = () => { + handleClose(); setDefaultsValues(); }; @@ -60,7 +60,7 @@ const GlobalSettings: FC = () => { dispatch({ type: "SET_SERVER", payload: serverUrl }); timeDispatch({ type: "SET_TIMEZONE", payload: timezone }); customPanelDispatch({ type: "SET_SERIES_LIMITS", payload: limits }); - setOpen(false); + handleClose(); }; useEffect(() => { @@ -97,7 +97,7 @@ const GlobalSettings: FC = () => { {open && ( <Modal title={title} - onClose={handleClose} + onClose={handleCloseAndReset} > <div className={classNames({ @@ -140,7 +140,7 @@ const GlobalSettings: FC = () => { <Button color="error" variant="outlined" - onClick={handleCloseForce} + onClick={handleCloseAndReset} > Cancel </Button> diff --git a/app/vmui/packages/vmui/src/components/Configurators/GlobalSettings/TenantsConfiguration/TenantsConfiguration.tsx b/app/vmui/packages/vmui/src/components/Configurators/GlobalSettings/TenantsConfiguration/TenantsConfiguration.tsx index 5f32aa2d31..dd0dfd6c42 100644 --- a/app/vmui/packages/vmui/src/components/Configurators/GlobalSettings/TenantsConfiguration/TenantsConfiguration.tsx +++ b/app/vmui/packages/vmui/src/components/Configurators/GlobalSettings/TenantsConfiguration/TenantsConfiguration.tsx @@ -11,6 +11,7 @@ import Tooltip from "../../../Main/Tooltip/Tooltip"; import useDeviceDetect from "../../../../hooks/useDeviceDetect"; import TextField from "../../../Main/TextField/TextField"; import { getTenantIdFromUrl, replaceTenantId } from "../../../../utils/tenants"; +import useBoolean from "../../../../hooks/useBoolean"; const TenantsConfiguration: FC<{accountIds: string[]}> = ({ accountIds }) => { const appModeEnable = getAppModeEnable(); @@ -21,9 +22,14 @@ const TenantsConfiguration: FC<{accountIds: string[]}> = ({ accountIds }) => { const timeDispatch = useTimeDispatch(); const [search, setSearch] = useState(""); - const [openOptions, setOpenOptions] = useState(false); const optionsButtonRef = useRef<HTMLDivElement>(null); + const { + value: openOptions, + toggle: toggleOpenOptions, + setFalse: handleCloseOptions, + } = useBoolean(false); + const accountIdsFiltered = useMemo(() => { if (!search) return accountIds; try { @@ -37,14 +43,6 @@ const TenantsConfiguration: FC<{accountIds: string[]}> = ({ accountIds }) => { const showTenantSelector = useMemo(() => accountIds.length > 1, [accountIds]); - const toggleOpenOptions = () => { - setOpenOptions(prev => !prev); - }; - - const handleCloseOptions = () => { - setOpenOptions(false); - }; - const createHandlerChange = (value: string) => () => { const tenant = value; dispatch({ type: "SET_TENANT_ID", payload: tenant }); diff --git a/app/vmui/packages/vmui/src/components/Configurators/GlobalSettings/Timezones/Timezones.tsx b/app/vmui/packages/vmui/src/components/Configurators/GlobalSettings/Timezones/Timezones.tsx index 1af4e1c980..6bb0372ea6 100644 --- a/app/vmui/packages/vmui/src/components/Configurators/GlobalSettings/Timezones/Timezones.tsx +++ b/app/vmui/packages/vmui/src/components/Configurators/GlobalSettings/Timezones/Timezones.tsx @@ -9,6 +9,7 @@ import TextField from "../../../Main/TextField/TextField"; import { Timezone } from "../../../../types"; import "./style.scss"; import useDeviceDetect from "../../../../hooks/useDeviceDetect"; +import useBoolean from "../../../../hooks/useBoolean"; interface TimezonesProps { timezoneState: string @@ -19,10 +20,15 @@ const Timezones: FC<TimezonesProps> = ({ timezoneState, onChange }) => { const { isMobile } = useDeviceDetect(); const timezones = getTimezoneList(); - const [openList, setOpenList] = useState(false); const [search, setSearch] = useState(""); const targetRef = useRef<HTMLDivElement>(null); + const { + value: openList, + toggle: toggleOpenList, + setFalse: handleCloseList, + } = useBoolean(false); + const searchTimezones = useMemo(() => { if (!search) return timezones; try { @@ -44,14 +50,6 @@ const Timezones: FC<TimezonesProps> = ({ timezoneState, onChange }) => { utc: getUTCByTimezone(timezoneState) }), [timezoneState]); - const toggleOpenList = () => { - setOpenList(prev => !prev); - }; - - const handleCloseList = () => { - setOpenList(false); - }; - const handleChangeSearch = (val: string) => { setSearch(val); }; diff --git a/app/vmui/packages/vmui/src/components/Configurators/GraphSettings/GraphSettings.tsx b/app/vmui/packages/vmui/src/components/Configurators/GraphSettings/GraphSettings.tsx index d46de83fda..129d28bffb 100644 --- a/app/vmui/packages/vmui/src/components/Configurators/GraphSettings/GraphSettings.tsx +++ b/app/vmui/packages/vmui/src/components/Configurators/GraphSettings/GraphSettings.tsx @@ -1,4 +1,4 @@ -import React, { FC, useRef, useState } from "preact/compat"; +import React, { FC, useRef } from "preact/compat"; import AxesLimitsConfigurator from "./AxesLimitsConfigurator/AxesLimitsConfigurator"; import { AxisRange, YaxisState } from "../../../state/graph/reducer"; import { SettingsIcon } from "../../Main/Icons"; @@ -6,6 +6,7 @@ import Button from "../../Main/Button/Button"; import Popper from "../../Main/Popper/Popper"; import "./style.scss"; import Tooltip from "../../Main/Tooltip/Tooltip"; +import useBoolean from "../../../hooks/useBoolean"; const title = "Axes settings"; @@ -17,16 +18,13 @@ interface GraphSettingsProps { const GraphSettings: FC<GraphSettingsProps> = ({ yaxis, setYaxisLimits, toggleEnableLimits }) => { const popperRef = useRef<HTMLDivElement>(null); - const [openPopper, setOpenPopper] = useState(false); const buttonRef = useRef<HTMLDivElement>(null); - const toggleOpen = () => { - setOpenPopper(prev => !prev); - }; - - const handleClose = () => { - setOpenPopper(false); - }; + const { + value: openPopper, + toggle: toggleOpen, + setFalse: handleClose, + } = useBoolean(false); return ( <div className="vm-graph-settings"> diff --git a/app/vmui/packages/vmui/src/components/Configurators/StepConfigurator/StepConfigurator.tsx b/app/vmui/packages/vmui/src/components/Configurators/StepConfigurator/StepConfigurator.tsx index 5372568f28..42b1a16402 100644 --- a/app/vmui/packages/vmui/src/components/Configurators/StepConfigurator/StepConfigurator.tsx +++ b/app/vmui/packages/vmui/src/components/Configurators/StepConfigurator/StepConfigurator.tsx @@ -13,6 +13,7 @@ import { getAppModeEnable } from "../../../utils/app-mode"; import Popper from "../../Main/Popper/Popper"; import useDeviceDetect from "../../../hooks/useDeviceDetect"; import classNames from "classnames"; +import useBoolean from "../../../hooks/useBoolean"; const StepConfigurator: FC = () => { const appModeEnable = getAppModeEnable(); @@ -28,20 +29,17 @@ const StepConfigurator: FC = () => { return getStepFromDuration(end - start, isHistogram); }, [step, isHistogram]); - const [openOptions, setOpenOptions] = useState(false); const [customStep, setCustomStep] = useState(value || defaultStep); const [error, setError] = useState(""); + const { + value: openOptions, + toggle: toggleOpenOptions, + setFalse: handleCloseOptions, + } = useBoolean(false); + const buttonRef = useRef<HTMLDivElement>(null); - const toggleOpenOptions = () => { - setOpenOptions(prev => !prev); - }; - - const handleCloseOptions = () => { - setOpenOptions(false); - }; - const handleApply = (value?: string) => { const step = value || customStep || defaultStep || "1s"; const durations = step.match(/[a-zA-Z]+/g) || []; diff --git a/app/vmui/packages/vmui/src/components/Configurators/TimeRangeSettings/ExecutionControls/ExecutionControls.tsx b/app/vmui/packages/vmui/src/components/Configurators/TimeRangeSettings/ExecutionControls/ExecutionControls.tsx index 168c1dfd7c..87b5743003 100644 --- a/app/vmui/packages/vmui/src/components/Configurators/TimeRangeSettings/ExecutionControls/ExecutionControls.tsx +++ b/app/vmui/packages/vmui/src/components/Configurators/TimeRangeSettings/ExecutionControls/ExecutionControls.tsx @@ -8,6 +8,7 @@ import "./style.scss"; import classNames from "classnames"; import Tooltip from "../../../Main/Tooltip/Tooltip"; import useDeviceDetect from "../../../../hooks/useDeviceDetect"; +import useBoolean from "../../../../hooks/useBoolean"; interface AutoRefreshOption { seconds: number @@ -38,12 +39,19 @@ export const ExecutionControls: FC = () => { const [selectedDelay, setSelectedDelay] = useState<AutoRefreshOption>(delayOptions[0]); + const { + value: openOptions, + toggle: toggleOpenOptions, + setFalse: handleCloseOptions, + } = useBoolean(false); + const optionsButtonRef = useRef<HTMLDivElement>(null); + const handleChange = (d: AutoRefreshOption) => { if ((autoRefresh && !d.seconds) || (!autoRefresh && d.seconds)) { setAutoRefresh(prev => !prev); } setSelectedDelay(d); - setOpenOptions(false); + handleCloseOptions(); }; const handleUpdate = () => { @@ -65,17 +73,6 @@ export const ExecutionControls: FC = () => { }; }, [selectedDelay, autoRefresh]); - const [openOptions, setOpenOptions] = useState(false); - const optionsButtonRef = useRef<HTMLDivElement>(null); - - const toggleOpenOptions = () => { - setOpenOptions(prev => !prev); - }; - - const handleCloseOptions = () => { - setOpenOptions(false); - }; - const createHandlerChange = (d: AutoRefreshOption) => () => { handleChange(d); }; diff --git a/app/vmui/packages/vmui/src/components/Configurators/TimeRangeSettings/TimeSelector/TimeSelector.tsx b/app/vmui/packages/vmui/src/components/Configurators/TimeRangeSettings/TimeSelector/TimeSelector.tsx index 368545f89d..1909f27d10 100644 --- a/app/vmui/packages/vmui/src/components/Configurators/TimeRangeSettings/TimeSelector/TimeSelector.tsx +++ b/app/vmui/packages/vmui/src/components/Configurators/TimeRangeSettings/TimeSelector/TimeSelector.tsx @@ -9,20 +9,21 @@ import Button from "../../../Main/Button/Button"; import Popper from "../../../Main/Popper/Popper"; import Tooltip from "../../../Main/Tooltip/Tooltip"; import { DATE_TIME_FORMAT } from "../../../../constants/date"; -import useResize from "../../../../hooks/useResize"; import "./style.scss"; import useClickOutside from "../../../../hooks/useClickOutside"; import classNames from "classnames"; import { useAppState } from "../../../../state/common/StateContext"; import useDeviceDetect from "../../../../hooks/useDeviceDetect"; import DateTimeInput from "../../../Main/DatePicker/DateTimeInput/DateTimeInput"; +import useBoolean from "../../../../hooks/useBoolean"; +import useWindowSize from "../../../../hooks/useWindowSize"; export const TimeSelector: FC = () => { const { isMobile } = useDeviceDetect(); const { isDarkTheme } = useAppState(); const wrapperRef = useRef<HTMLDivElement>(null); - const documentSize = useResize(document.body); - const displayFullDate = useMemo(() => documentSize.width > 1280, [documentSize]); + const documentSize = useWindowSize(); + const displayFullDate = useMemo(() => documentSize.width > 1120, [documentSize]); const [until, setUntil] = useState<string>(); const [from, setFrom] = useState<string>(); @@ -31,6 +32,12 @@ export const TimeSelector: FC = () => { const dispatch = useTimeDispatch(); const appModeEnable = getAppModeEnable(); + const { + value: openOptions, + toggle: toggleOpenOptions, + setFalse: handleCloseOptions, + } = useBoolean(false); + const activeTimezone = useMemo(() => ({ region: timezone, utc: getUTCByTimezone(timezone) @@ -46,7 +53,7 @@ export const TimeSelector: FC = () => { const setDuration = ({ duration, until, id }: {duration: string, until: Date, id: string}) => { dispatch({ type: "SET_RELATIVE_TIME", payload: { duration, until, id } }); - setOpenOptions(false); + handleCloseOptions(); }; const formatRange = useMemo(() => { @@ -62,7 +69,6 @@ export const TimeSelector: FC = () => { const fromPickerRef = useRef<HTMLDivElement>(null); const untilPickerRef = useRef<HTMLDivElement>(null); - const [openOptions, setOpenOptions] = useState(false); const buttonRef = useRef<HTMLDivElement>(null); const setTimeAndClosePicker = () => { @@ -72,7 +78,7 @@ export const TimeSelector: FC = () => { to: dayjs.tz(until).toDate() } }); } - setOpenOptions(false); + handleCloseOptions(); }; const onSwitchToNow = () => dispatch({ type: "RUN_QUERY_TO_NOW" }); @@ -80,15 +86,7 @@ export const TimeSelector: FC = () => { const onCancelClick = () => { setUntil(formatDateForNativeInput(dateFromSeconds(end))); setFrom(formatDateForNativeInput(dateFromSeconds(start))); - setOpenOptions(false); - }; - - const toggleOpenOptions = () => { - setOpenOptions(prev => !prev); - }; - - const handleCloseOptions = () => { - setOpenOptions(false); + handleCloseOptions(); }; useEffect(() => { diff --git a/app/vmui/packages/vmui/src/components/ExploreMetrics/ExploreMetricGraph/ExploreMetricItemGraph.tsx b/app/vmui/packages/vmui/src/components/ExploreMetrics/ExploreMetricGraph/ExploreMetricItemGraph.tsx index 0b6279f78e..936504372a 100644 --- a/app/vmui/packages/vmui/src/components/ExploreMetrics/ExploreMetricGraph/ExploreMetricItemGraph.tsx +++ b/app/vmui/packages/vmui/src/components/ExploreMetrics/ExploreMetricGraph/ExploreMetricItemGraph.tsx @@ -11,6 +11,7 @@ import "./style.scss"; import classNames from "classnames"; import useDeviceDetect from "../../../hooks/useDeviceDetect"; import { getDurationFromMilliseconds, getSecondsFromDuration, getStepFromDuration } from "../../../utils/time"; +import useBoolean from "../../../hooks/useBoolean"; interface ExploreMetricItemGraphProps { name: string, @@ -41,7 +42,10 @@ const ExploreMetricItem: FC<ExploreMetricItemGraphProps> = ({ const [isHeatmap, setIsHeatmap] = useState(false); const step = isHeatmap && customStep === defaultStep ? heatmapStep : customStep; - const [showAllSeries, setShowAllSeries] = useState(false); + const { + value: showAllSeries, + setTrue: handleShowAll, + } = useBoolean(false); const query = useMemo(() => { const params = Object.entries({ job, instance }) @@ -81,10 +85,6 @@ with (q = ${queryBase}) ( timeDispatch({ type: "SET_PERIOD", payload: { from, to } }); }; - const handleShowAll = () => { - setShowAllSeries(true); - }; - useEffect(() => { setIsHeatmap(isHistogram); }, [isHistogram]); diff --git a/app/vmui/packages/vmui/src/components/ExploreMetrics/ExploreMetricItem/ExploreMetricItem.tsx b/app/vmui/packages/vmui/src/components/ExploreMetrics/ExploreMetricItem/ExploreMetricItem.tsx index 4f07c68d1e..bd8e48c0ca 100644 --- a/app/vmui/packages/vmui/src/components/ExploreMetrics/ExploreMetricItem/ExploreMetricItem.tsx +++ b/app/vmui/packages/vmui/src/components/ExploreMetrics/ExploreMetricItem/ExploreMetricItem.tsx @@ -2,8 +2,8 @@ import React, { FC, useEffect, useMemo, useState } from "preact/compat"; import ExploreMetricItemGraph from "../ExploreMetricGraph/ExploreMetricItemGraph"; import ExploreMetricItemHeader from "../ExploreMetricItemHeader/ExploreMetricItemHeader"; import "./style.scss"; -import useResize from "../../../hooks/useResize"; import { GraphSize } from "../../../types"; +import useWindowSize from "../../../hooks/useWindowSize"; interface ExploreMetricItemProps { name: string @@ -32,7 +32,7 @@ const ExploreMetricItem: FC<ExploreMetricItemProps> = ({ const [rateEnabled, setRateEnabled] = useState(isCounter); - const windowSize = useResize(document.body); + const windowSize = useWindowSize(); const graphHeight = useMemo(size.height, [size, windowSize]); useEffect(() => { diff --git a/app/vmui/packages/vmui/src/components/ExploreMetrics/ExploreMetricItemHeader/ExploreMetricItemHeader.tsx b/app/vmui/packages/vmui/src/components/ExploreMetrics/ExploreMetricItemHeader/ExploreMetricItemHeader.tsx index d135266c23..1dc00078d6 100644 --- a/app/vmui/packages/vmui/src/components/ExploreMetrics/ExploreMetricItemHeader/ExploreMetricItemHeader.tsx +++ b/app/vmui/packages/vmui/src/components/ExploreMetrics/ExploreMetricItemHeader/ExploreMetricItemHeader.tsx @@ -1,4 +1,4 @@ -import React, { FC, useState } from "preact/compat"; +import React, { FC } from "preact/compat"; import "./style.scss"; import Switch from "../../Main/Switch/Switch"; import Tooltip from "../../Main/Tooltip/Tooltip"; @@ -6,6 +6,7 @@ import Button from "../../Main/Button/Button"; import { ArrowDownIcon, CloseIcon, MinusIcon, MoreIcon, PlusIcon } from "../../Main/Icons"; import useDeviceDetect from "../../../hooks/useDeviceDetect"; import Modal from "../../Main/Modal/Modal"; +import useBoolean from "../../../hooks/useBoolean"; interface ExploreMetricItemControlsProps { name: string @@ -30,7 +31,12 @@ const ExploreMetricItemHeader: FC<ExploreMetricItemControlsProps> = ({ onChangeOrder, }) => { const { isMobile } = useDeviceDetect(); - const [openOptions, setOpenOptions] = useState(false); + + const { + value: openOptions, + setTrue: handleOpenOptions, + setFalse: handleCloseOptions, + } = useBoolean(false); const handleClickRemove = () => { onRemoveItem(name); @@ -44,14 +50,6 @@ const ExploreMetricItemHeader: FC<ExploreMetricItemControlsProps> = ({ onChangeOrder(name, index, index - 1); }; - const handleOpenOptions = () => { - setOpenOptions(true); - }; - - const handleCloseOptions = () => { - setOpenOptions(false); - }; - if (isMobile) { return ( <div className="vm-explore-metrics-item-header vm-explore-metrics-item-header_mobile"> diff --git a/app/vmui/packages/vmui/src/components/Layout/Header/Header.tsx b/app/vmui/packages/vmui/src/components/Layout/Header/Header.tsx index b64be06a09..5b826bc57c 100644 --- a/app/vmui/packages/vmui/src/components/Layout/Header/Header.tsx +++ b/app/vmui/packages/vmui/src/components/Layout/Header/Header.tsx @@ -8,15 +8,15 @@ import "./style.scss"; import classNames from "classnames"; import { useAppState } from "../../../state/common/StateContext"; import HeaderNav from "./HeaderNav/HeaderNav"; -import useResize from "../../../hooks/useResize"; import SidebarHeader from "./SidebarNav/SidebarHeader"; import HeaderControls from "./HeaderControls/HeaderControls"; import useDeviceDetect from "../../../hooks/useDeviceDetect"; +import useWindowSize from "../../../hooks/useWindowSize"; const Header: FC = () => { const { isMobile } = useDeviceDetect(); - const windowSize = useResize(document.body); + const windowSize = useWindowSize(); const displaySidebar = useMemo(() => window.innerWidth < 1000, [windowSize]); const { isDarkTheme } = useAppState(); diff --git a/app/vmui/packages/vmui/src/components/Layout/Header/HeaderControls/HeaderControls.tsx b/app/vmui/packages/vmui/src/components/Layout/Header/HeaderControls/HeaderControls.tsx index 51f746a637..c8dc27f865 100644 --- a/app/vmui/packages/vmui/src/components/Layout/Header/HeaderControls/HeaderControls.tsx +++ b/app/vmui/packages/vmui/src/components/Layout/Header/HeaderControls/HeaderControls.tsx @@ -1,4 +1,4 @@ -import React, { FC, useMemo, useState } from "preact/compat"; +import React, { FC, useMemo } from "preact/compat"; import { RouterOptions, routerOptions, RouterOptionsHeader } from "../../../../router"; import TenantsConfiguration from "../../../Configurators/GlobalSettings/TenantsConfiguration/TenantsConfiguration"; import StepConfigurator from "../../../Configurators/StepConfigurator/StepConfigurator"; @@ -15,6 +15,7 @@ import "./style.scss"; import classNames from "classnames"; import { getAppModeEnable } from "../../../../utils/app-mode"; import Modal from "../../../Main/Modal/Modal"; +import useBoolean from "../../../../hooks/useBoolean"; interface HeaderControlsProp { displaySidebar: boolean @@ -50,22 +51,19 @@ const Controls: FC<HeaderControlsProp> = ({ const HeaderControls: FC<HeaderControlsProp> = (props) => { const appModeEnable = getAppModeEnable(); - const [openList, setOpenList] = useState(false); const { pathname } = useLocation(); const { accountIds } = useFetchAccountIds(); + const { + value: openList, + toggle: handleToggleList, + setFalse: handleCloseList, + } = useBoolean(false); + const headerSetup = useMemo(() => { return ((routerOptions[pathname] || {}) as RouterOptions).header || {}; }, [pathname]); - const handleToggleList = () => { - setOpenList(prev => !prev); - }; - - const handleCloseList = () => { - setOpenList(false); - }; - if (props.isMobile) { return ( <> diff --git a/app/vmui/packages/vmui/src/components/Layout/Header/HeaderNav/NavSubItem.tsx b/app/vmui/packages/vmui/src/components/Layout/Header/HeaderNav/NavSubItem.tsx index 19928b3fb5..462bb71dd9 100644 --- a/app/vmui/packages/vmui/src/components/Layout/Header/HeaderNav/NavSubItem.tsx +++ b/app/vmui/packages/vmui/src/components/Layout/Header/HeaderNav/NavSubItem.tsx @@ -5,6 +5,7 @@ import { ArrowDropDownIcon } from "../../../Main/Icons"; import Popper from "../../../Main/Popper/Popper"; import NavItem from "./NavItem"; import { useEffect } from "react"; +import useBoolean from "../../../../hooks/useBoolean"; interface NavItemProps { activeMenu: string, @@ -25,17 +26,18 @@ const NavSubItem: FC<NavItemProps> = ({ }) => { const { pathname } = useLocation(); - const [openSubmenu, setOpenSubmenu] = useState(false); const [menuTimeout, setMenuTimeout] = useState<NodeJS.Timeout | null>(null); const buttonRef = useRef<HTMLDivElement>(null); - const handleOpenSubmenu = () => { - setOpenSubmenu(true); - if (menuTimeout) clearTimeout(menuTimeout); - }; + const { + value: openSubmenu, + setFalse: handleCloseSubmenu, + setTrue: setOpenSubmenu, + } = useBoolean(false); - const handleCloseSubmenu = () => { - setOpenSubmenu(false); + const handleOpenSubmenu = () => { + setOpenSubmenu(); + if (menuTimeout) clearTimeout(menuTimeout); }; const handleMouseLeave = () => { diff --git a/app/vmui/packages/vmui/src/components/Layout/Header/SidebarNav/SidebarHeader.tsx b/app/vmui/packages/vmui/src/components/Layout/Header/SidebarNav/SidebarHeader.tsx index fc845ca033..92fa9eb848 100644 --- a/app/vmui/packages/vmui/src/components/Layout/Header/SidebarNav/SidebarHeader.tsx +++ b/app/vmui/packages/vmui/src/components/Layout/Header/SidebarNav/SidebarHeader.tsx @@ -1,4 +1,4 @@ -import React, { FC, useEffect, useRef, useState } from "preact/compat"; +import React, { FC, useEffect, useRef } from "preact/compat"; import { useLocation } from "react-router-dom"; import ShortcutKeys from "../../../Main/ShortcutKeys/ShortcutKeys"; import classNames from "classnames"; @@ -7,6 +7,7 @@ import useClickOutside from "../../../../hooks/useClickOutside"; import MenuBurger from "../../../Main/MenuBurger/MenuBurger"; import useDeviceDetect from "../../../../hooks/useDeviceDetect"; import "./style.scss"; +import useBoolean from "../../../../hooks/useBoolean"; interface SidebarHeaderProps { background: string @@ -21,15 +22,12 @@ const SidebarHeader: FC<SidebarHeaderProps> = ({ const { isMobile } = useDeviceDetect(); const sidebarRef = useRef<HTMLDivElement>(null); - const [openMenu, setOpenMenu] = useState(false); - const handleToggleMenu = () => { - setOpenMenu(prev => !prev); - }; - - const handleCloseMenu = () => { - setOpenMenu(false); - }; + const { + value: openMenu, + toggle: handleToggleMenu, + setFalse: handleCloseMenu, + } = useBoolean(false); useEffect(handleCloseMenu, [pathname]); diff --git a/app/vmui/packages/vmui/src/components/Layout/Layout.tsx b/app/vmui/packages/vmui/src/components/Layout/Layout.tsx index 7a34cac181..db5e3fd1af 100644 --- a/app/vmui/packages/vmui/src/components/Layout/Layout.tsx +++ b/app/vmui/packages/vmui/src/components/Layout/Layout.tsx @@ -26,16 +26,15 @@ const Layout: FC = () => { // for support old links with search params const redirectSearchToHashParams = () => { - const { search } = window.location; + const { search, href } = window.location; if (search) { const query = qs.parse(search, { ignoreQueryPrefix: true }); - Object.entries(query).forEach(([key, value]) => { - searchParams.set(key, value as string); - setSearchParams(searchParams); - }); + Object.entries(query).forEach(([key, value]) => searchParams.set(key, value as string)); + setSearchParams(searchParams); window.location.search = ""; } - window.location.replace(window.location.href.replace(/\/\?#\//, "/#/")); + const newHref = href.replace(/\/\?#\//, "/#/"); + if (newHref !== href) window.location.replace(newHref); }; useEffect(setDocumentTitle, [pathname]); diff --git a/app/vmui/packages/vmui/src/components/Main/Autocomplete/Autocomplete.tsx b/app/vmui/packages/vmui/src/components/Main/Autocomplete/Autocomplete.tsx index e65a51beab..a53feacf1a 100644 --- a/app/vmui/packages/vmui/src/components/Main/Autocomplete/Autocomplete.tsx +++ b/app/vmui/packages/vmui/src/components/Main/Autocomplete/Autocomplete.tsx @@ -1,9 +1,11 @@ -import React, { FC, Ref, useEffect, useMemo, useRef, useState } from "preact/compat"; +import React, { FC, Ref, useCallback, useEffect, useMemo, useRef, useState } from "preact/compat"; import classNames from "classnames"; import Popper from "../Popper/Popper"; import "./style.scss"; import { DoneIcon } from "../Icons"; import useDeviceDetect from "../../../hooks/useDeviceDetect"; +import useBoolean from "../../../hooks/useBoolean"; +import useEventListener from "../../../hooks/useEventListener"; interface AutocompleteProps { value: string @@ -39,9 +41,14 @@ const Autocomplete: FC<AutocompleteProps> = ({ const { isMobile } = useDeviceDetect(); const wrapperEl = useRef<HTMLDivElement>(null); - const [openAutocomplete, setOpenAutocomplete] = useState(false); const [focusOption, setFocusOption] = useState(-1); + const { + value: openAutocomplete, + setValue: setOpenAutocomplete, + setFalse: handleCloseAutocomplete, + } = useBoolean(false); + const foundOptions = useMemo(() => { if (!openAutocomplete) return []; try { @@ -57,10 +64,6 @@ const Autocomplete: FC<AutocompleteProps> = ({ return noOptionsText && !foundOptions.length; }, [noOptionsText,foundOptions]); - const handleCloseAutocomplete = () => { - setOpenAutocomplete(false); - }; - const createHandlerSelect = (item: string) => () => { if (disabled) return; onSelect(item); @@ -73,7 +76,7 @@ const Autocomplete: FC<AutocompleteProps> = ({ if (target?.scrollIntoView) target.scrollIntoView({ block: "center" }); }; - const handleKeyDown = (e: KeyboardEvent) => { + const handleKeyDown = useCallback((e: KeyboardEvent) => { const { key, ctrlKey, metaKey, shiftKey } = e; const modifiers = ctrlKey || metaKey || shiftKey; const hasOptions = foundOptions.length; @@ -98,22 +101,16 @@ const Autocomplete: FC<AutocompleteProps> = ({ if (key === "Escape") { handleCloseAutocomplete(); } - }; + }, [focusOption, foundOptions, handleCloseAutocomplete, onSelect, selected]); useEffect(() => { const words = (value.match(/[a-zA-Z_:.][a-zA-Z0-9_:.]*/gm) || []).length; setOpenAutocomplete(value.length > minLength && words <= maxWords); }, [value]); - useEffect(() => { - scrollToValue(); + useEventListener("keydown", handleKeyDown); - window.addEventListener("keydown", handleKeyDown); - - return () => { - window.removeEventListener("keydown", handleKeyDown); - }; - }, [focusOption, foundOptions]); + useEffect(scrollToValue, [focusOption, foundOptions]); useEffect(() => { setFocusOption(-1); diff --git a/app/vmui/packages/vmui/src/components/Main/DatePicker/DatePicker.tsx b/app/vmui/packages/vmui/src/components/Main/DatePicker/DatePicker.tsx index 92a61fee68..cb41a99d92 100644 --- a/app/vmui/packages/vmui/src/components/Main/DatePicker/DatePicker.tsx +++ b/app/vmui/packages/vmui/src/components/Main/DatePicker/DatePicker.tsx @@ -1,9 +1,11 @@ -import React, { Ref, useEffect, useMemo, useState, forwardRef } from "preact/compat"; +import React, { Ref, useMemo, forwardRef } from "preact/compat"; import Calendar from "../../Main/DatePicker/Calendar/Calendar"; import dayjs, { Dayjs } from "dayjs"; import Popper from "../../Main/Popper/Popper"; import { DATE_TIME_FORMAT } from "../../../constants/date"; import useDeviceDetect from "../../../hooks/useDeviceDetect"; +import useBoolean from "../../../hooks/useBoolean"; +import useEventListener from "../../../hooks/useEventListener"; interface DatePickerProps { date: string | Date | Dayjs, @@ -20,17 +22,14 @@ const DatePicker = forwardRef<HTMLDivElement, DatePickerProps>(({ onChange, label }, ref) => { - const [openCalendar, setOpenCalendar] = useState(false); const dateDayjs = useMemo(() => dayjs(date).isValid() ? dayjs.tz(date) : dayjs().tz(), [date]); const { isMobile } = useDeviceDetect(); - const toggleOpenCalendar = () => { - setOpenCalendar(prev => !prev); - }; - - const handleCloseCalendar = () => { - setOpenCalendar(false); - }; + const { + value: openCalendar, + toggle: toggleOpenCalendar, + setFalse: handleCloseCalendar, + } = useBoolean(false); const handleChangeDate = (val: string) => { onChange(val); @@ -41,21 +40,8 @@ const DatePicker = forwardRef<HTMLDivElement, DatePickerProps>(({ if (e.key === "Escape" || e.key === "Enter") handleCloseCalendar(); }; - useEffect(() => { - targetRef.current?.addEventListener("click", toggleOpenCalendar); - - return () => { - targetRef.current?.removeEventListener("click", toggleOpenCalendar); - }; - }, [targetRef]); - - useEffect(() => { - window.addEventListener("keyup", handleKeyUp); - - return () => { - window.removeEventListener("keyup", handleKeyUp); - }; - }, []); + useEventListener("click", toggleOpenCalendar, targetRef); + useEventListener("keyup", handleKeyUp); return (<> <Popper diff --git a/app/vmui/packages/vmui/src/components/Main/Icons/PreviewIcons.tsx b/app/vmui/packages/vmui/src/components/Main/Icons/PreviewIcons.tsx index 23bbc69244..7d6e533a8a 100644 --- a/app/vmui/packages/vmui/src/components/Main/Icons/PreviewIcons.tsx +++ b/app/vmui/packages/vmui/src/components/Main/Icons/PreviewIcons.tsx @@ -1,18 +1,13 @@ import React, { FC } from "preact/compat"; import * as icons from "./index"; -import { useSnack } from "../../../contexts/Snackbar"; +import useCopyToClipboard from "../../../hooks/useCopyToClipboard"; import "./style.scss"; const PreviewIcons: FC = () => { - const { showInfoMessage } = useSnack(); + const copyToClipboard = useCopyToClipboard(); - const handleClickIcon = (copyValue: string) => { - navigator.clipboard.writeText(`<${copyValue}/>`); - showInfoMessage({ text: `<${copyValue}/> has been copied`, type: "success" }); - }; - - const createHandlerClickIcon = (key: string) => () => { - handleClickIcon(key); + const createHandlerClickIcon = (key: string) => async () => { + await copyToClipboard(`<${key}/>`, `<${key}/> has been copied`); }; return ( diff --git a/app/vmui/packages/vmui/src/components/Main/Modal/Modal.tsx b/app/vmui/packages/vmui/src/components/Main/Modal/Modal.tsx index 6fbbaeb137..1cbeb524bf 100644 --- a/app/vmui/packages/vmui/src/components/Main/Modal/Modal.tsx +++ b/app/vmui/packages/vmui/src/components/Main/Modal/Modal.tsx @@ -1,4 +1,4 @@ -import React, { FC, useEffect } from "preact/compat"; +import React, { FC, useCallback, useEffect } from "preact/compat"; import ReactDOM from "react-dom"; import { CloseIcon } from "../Icons"; import Button from "../Button/Button"; @@ -7,6 +7,7 @@ import "./style.scss"; import useDeviceDetect from "../../../hooks/useDeviceDetect"; import classNames from "classnames"; import { useLocation, useNavigate } from "react-router-dom"; +import useEventListener from "../../../hooks/useEventListener"; interface ModalProps { title?: string @@ -21,48 +22,42 @@ const Modal: FC<ModalProps> = ({ children, onClose, className, - isOpen= true + isOpen = true }) => { const { isMobile } = useDeviceDetect(); const navigate = useNavigate(); const location = useLocation(); - const handleKeyUp = (e: KeyboardEvent) => { + const handleKeyUp = useCallback((e: KeyboardEvent) => { + if (!isOpen) return; if (e.key === "Escape") onClose(); - }; + }, [isOpen]); const handleMouseDown = (e: MouseEvent<HTMLDivElement>) => { e.stopPropagation(); }; - const handlePopstate = () => { + const handlePopstate = useCallback(() => { if (isOpen) { navigate(location, { replace: true }); onClose(); } - }; - - useEffect(() => { - window.addEventListener("popstate", handlePopstate); - - return () => { - window.removeEventListener("popstate", handlePopstate); - }; - }, [isOpen, location]); + }, [isOpen, location, onClose]); const handleDisplayModal = () => { if (!isOpen) return; document.body.style.overflow = "hidden"; - window.addEventListener("keyup", handleKeyUp); return () => { document.body.style.overflow = "auto"; - window.removeEventListener("keyup", handleKeyUp); }; }; useEffect(handleDisplayModal, [isOpen]); + useEventListener("popstate", handlePopstate); + useEventListener("keyup", handleKeyUp); + return ReactDOM.createPortal(( <div className={classNames({ diff --git a/app/vmui/packages/vmui/src/components/Main/Popper/Popper.tsx b/app/vmui/packages/vmui/src/components/Main/Popper/Popper.tsx index 3e7f79de3a..9caee30e3f 100644 --- a/app/vmui/packages/vmui/src/components/Main/Popper/Popper.tsx +++ b/app/vmui/packages/vmui/src/components/Main/Popper/Popper.tsx @@ -7,6 +7,9 @@ import useDeviceDetect from "../../../hooks/useDeviceDetect"; import Button from "../Button/Button"; import { CloseIcon } from "../Icons"; import { useLocation, useNavigate } from "react-router-dom"; +import useBoolean from "../../../hooks/useBoolean"; +import useEventListener from "../../../hooks/useEventListener"; +import { useCallback } from "preact/compat"; interface PopperProps { children: ReactNode @@ -37,23 +40,16 @@ const Popper: FC<PopperProps> = ({ const { isMobile } = useDeviceDetect(); const navigate = useNavigate(); const location = useLocation(); - const [isOpen, setIsOpen] = useState(false); const [popperSize, setPopperSize] = useState({ width: 0, height: 0 }); + const { + value: isOpen, + setValue: setIsOpen, + setFalse: handleClose, + } = useBoolean(false); + const popperRef = useRef<HTMLDivElement>(null); - const onScrollWindow = () => { - setIsOpen(false); - }; - - useEffect(() => { - window.addEventListener("scroll", onScrollWindow); - - return () => { - window.removeEventListener("scroll", onScrollWindow); - }; - }, []); - useEffect(() => { setIsOpen(open); }, [open]); @@ -137,32 +133,25 @@ const Popper: FC<PopperProps> = ({ } }, [isOpen, popperRef]); - const handlePopstate = () => { + const handlePopstate = useCallback(() => { if (isOpen && isMobile && !disabledFullScreen) { navigate(location, { replace: true }); onClose(); } - }; + }, [isOpen, isMobile, disabledFullScreen, location, onClose]); - useEffect(() => { - window.addEventListener("popstate", handlePopstate); - - return () => { - window.removeEventListener("popstate", handlePopstate); - }; - }, [isOpen, isMobile, disabledFullScreen, location]); - - const popperClasses = classNames({ - "vm-popper": true, - "vm-popper_mobile": isMobile && !disabledFullScreen, - "vm-popper_open": (isMobile || Object.keys(popperStyle).length) && isOpen, - }); + useEventListener("scroll", handleClose); + useEventListener("popstate", handlePopstate); return ( <> {(isOpen || !popperSize.width) && ReactDOM.createPortal(( <div - className={popperClasses} + className={classNames({ + "vm-popper": true, + "vm-popper_mobile": isMobile && !disabledFullScreen, + "vm-popper_open": (isMobile || Object.keys(popperStyle).length) && isOpen, + })} ref={popperRef} style={(isMobile && !disabledFullScreen) ? {} : popperStyle} > diff --git a/app/vmui/packages/vmui/src/components/Main/Select/Select.tsx b/app/vmui/packages/vmui/src/components/Main/Select/Select.tsx index dba043960e..906df1a035 100644 --- a/app/vmui/packages/vmui/src/components/Main/Select/Select.tsx +++ b/app/vmui/packages/vmui/src/components/Main/Select/Select.tsx @@ -7,6 +7,7 @@ import { useAppState } from "../../../state/common/StateContext"; import "./style.scss"; import useDeviceDetect from "../../../hooks/useDeviceDetect"; import MultipleSelectedValue from "./MultipleSelectedValue/MultipleSelectedValue"; +import useEventListener from "../../../hooks/useEventListener"; interface SelectProps { value: string | string[] @@ -105,13 +106,7 @@ const Select: FC<SelectProps> = ({ inputRef.current.focus(); }, [autofocus, inputRef]); - useEffect(() => { - window.addEventListener("keyup", handleKeyUp); - - return () => { - window.removeEventListener("keyup", handleKeyUp); - }; - }, []); + useEventListener("keyup", handleKeyUp); return ( <div diff --git a/app/vmui/packages/vmui/src/components/Main/ShortcutKeys/ShortcutKeys.tsx b/app/vmui/packages/vmui/src/components/Main/ShortcutKeys/ShortcutKeys.tsx index 3da26c0340..171d730834 100644 --- a/app/vmui/packages/vmui/src/components/Main/ShortcutKeys/ShortcutKeys.tsx +++ b/app/vmui/packages/vmui/src/components/Main/ShortcutKeys/ShortcutKeys.tsx @@ -1,4 +1,4 @@ -import React, { FC, useEffect, useState } from "preact/compat"; +import React, { FC, useCallback } from "preact/compat"; import { getAppModeEnable } from "../../../utils/app-mode"; import Button from "../Button/Button"; import { KeyboardIcon } from "../Icons"; @@ -7,38 +7,31 @@ import "./style.scss"; import Tooltip from "../Tooltip/Tooltip"; import keyList from "./constants/keyList"; import { isMacOs } from "../../../utils/detect-device"; +import useBoolean from "../../../hooks/useBoolean"; +import useEventListener from "../../../hooks/useEventListener"; const title = "Shortcut keys"; const isMac = isMacOs(); const keyOpenHelp = isMac ? "Cmd + /" : "F1"; const ShortcutKeys: FC<{ showTitle?: boolean }> = ({ showTitle }) => { - const [openList, setOpenList] = useState(false); const appModeEnable = getAppModeEnable(); - const handleOpen = () => { - setOpenList(true); - }; + const { + value: openList, + setTrue: handleOpen, + setFalse: handleClose, + } = useBoolean(false); - const handleClose = () => { - setOpenList(false); - }; - - const handleKeyDown = (e: KeyboardEvent) => { + const handleKeyDown = useCallback((e: KeyboardEvent) => { const openOnMac = isMac && e.key === "/" && e.metaKey; const openOnOther = !isMac && e.key === "F1" && !e.metaKey; if (openOnMac || openOnOther) { handleOpen(); } - }; + }, [handleOpen]); - useEffect(() => { - window.addEventListener("keydown", handleKeyDown); - - return () => { - window.removeEventListener("keydown", handleKeyDown); - }; - }, []); + useEventListener("keydown", handleKeyDown); return <> <Tooltip diff --git a/app/vmui/packages/vmui/src/components/Main/ShortcutKeys/style.scss b/app/vmui/packages/vmui/src/components/Main/ShortcutKeys/style.scss index 2d1c32a67b..b9da067f06 100644 --- a/app/vmui/packages/vmui/src/components/Main/ShortcutKeys/style.scss +++ b/app/vmui/packages/vmui/src/components/Main/ShortcutKeys/style.scss @@ -64,6 +64,7 @@ svg { width: 24px; padding: 4px; + color: $color-primary; } } diff --git a/app/vmui/packages/vmui/src/components/Main/Tabs/Tabs.tsx b/app/vmui/packages/vmui/src/components/Main/Tabs/Tabs.tsx index ea8bf74554..ec319cb25b 100644 --- a/app/vmui/packages/vmui/src/components/Main/Tabs/Tabs.tsx +++ b/app/vmui/packages/vmui/src/components/Main/Tabs/Tabs.tsx @@ -1,9 +1,9 @@ import React, { Component, FC, useRef, useState } from "preact/compat"; import { ReactNode, useEffect } from "react"; import { getCssVariable } from "../../../utils/theme"; -import useResize from "../../../hooks/useResize"; import TabItem from "./TabItem"; import "./style.scss"; +import useWindowSize from "../../../hooks/useWindowSize"; export interface TabItemType { value: string @@ -29,7 +29,7 @@ const Tabs: FC<TabsProps> = ({ indicatorPlacement = "bottom", isNavLink, }) => { - const windowSize = useResize(document.body); + const windowSize = useWindowSize(); const activeNavRef = useRef<Component>(null); const [indicatorPosition, setIndicatorPosition] = useState({ left: 0, width: 0, bottom: 0 }); diff --git a/app/vmui/packages/vmui/src/components/Main/ThemeProvider/ThemeProvider.ts b/app/vmui/packages/vmui/src/components/Main/ThemeProvider/ThemeProvider.ts index c0905fe0e5..4ea1c65a80 100644 --- a/app/vmui/packages/vmui/src/components/Main/ThemeProvider/ThemeProvider.ts +++ b/app/vmui/packages/vmui/src/components/Main/ThemeProvider/ThemeProvider.ts @@ -7,7 +7,7 @@ import { darkPalette, lightPalette } from "../../../constants/palette"; import { Theme } from "../../../types"; import { useAppDispatch, useAppState } from "../../../state/common/StateContext"; import useSystemTheme from "../../../hooks/useSystemTheme"; -import useResize from "../../../hooks/useResize"; +import useWindowSize from "../../../hooks/useWindowSize"; interface ThemeProviderProps { onLoaded: (val: boolean) => void @@ -29,7 +29,7 @@ export const ThemeProvider: FC<ThemeProviderProps> = ({ onLoaded }) => { const { theme } = useAppState(); const isDarkTheme = useSystemTheme(); const dispatch = useAppDispatch(); - const windowSize = useResize(document.body); + const windowSize = useWindowSize(); const [palette, setPalette] = useState({ [Theme.dark]: darkPalette, diff --git a/app/vmui/packages/vmui/src/components/Main/Tooltip/Tooltip.tsx b/app/vmui/packages/vmui/src/components/Main/Tooltip/Tooltip.tsx index 3eef672f92..30ad88f1b8 100644 --- a/app/vmui/packages/vmui/src/components/Main/Tooltip/Tooltip.tsx +++ b/app/vmui/packages/vmui/src/components/Main/Tooltip/Tooltip.tsx @@ -4,6 +4,7 @@ import "./style.scss"; import { ReactNode } from "react"; import { ExoticComponent } from "react"; import useDeviceDetect from "../../../hooks/useDeviceDetect"; +import useEventListener from "../../../hooks/useEventListener"; interface TooltipProps { children: ReactNode @@ -29,14 +30,7 @@ const Tooltip: FC<TooltipProps> = ({ const popperRef = useRef<HTMLDivElement>(null); const onScrollWindow = () => setIsOpen(false); - - useEffect(() => { - window.addEventListener("scroll", onScrollWindow); - - return () => { - window.removeEventListener("scroll", onScrollWindow); - }; - }, []); + useEventListener("scroll", onScrollWindow); useEffect(() => { if (!popperRef.current || !isOpen) return; diff --git a/app/vmui/packages/vmui/src/components/Views/GraphView/GraphView.tsx b/app/vmui/packages/vmui/src/components/Views/GraphView/GraphView.tsx index cdd95003d1..1cdab1387c 100644 --- a/app/vmui/packages/vmui/src/components/Views/GraphView/GraphView.tsx +++ b/app/vmui/packages/vmui/src/components/Views/GraphView/GraphView.tsx @@ -1,4 +1,4 @@ -import React, { FC, useCallback, useEffect, useMemo, useRef, useState } from "preact/compat"; +import React, { FC, useCallback, useEffect, useMemo, useState } from "preact/compat"; import { MetricResult } from "../../../api/types"; import LineChart from "../../Chart/Line/LineChart/LineChart"; import { AlignedData as uPlotData, Series as uPlotSeries } from "uplot"; @@ -18,6 +18,7 @@ import { promValueToNumber } from "../../../utils/metric"; import { normalizeData } from "../../../utils/uplot/heatmap"; import useDeviceDetect from "../../../hooks/useDeviceDetect"; import { TooltipHeatmapProps } from "../../Chart/Heatmap/ChartTooltipHeatmap/ChartTooltipHeatmap"; +import useElementSize from "../../../hooks/useElementSize"; export interface GraphViewProps { data?: MetricResult[]; @@ -164,7 +165,7 @@ const GraphView: FC<GraphViewProps> = ({ setLegend(tempLegend); }, [hideSeries]); - const containerRef = useRef<HTMLDivElement>(null); + const [containerRef, containerSize] = useElementSize(); return ( <div @@ -175,7 +176,7 @@ const GraphView: FC<GraphViewProps> = ({ })} ref={containerRef} > - {containerRef?.current && !isHistogram && ( + {!isHistogram && ( <LineChart data={dataChart} series={series} @@ -184,11 +185,11 @@ const GraphView: FC<GraphViewProps> = ({ yaxis={yaxis} unit={unit} setPeriod={setPeriod} - container={containerRef?.current} + layoutSize={containerSize} height={height} /> )} - {containerRef?.current && isHistogram && ( + {isHistogram && ( <HeatmapChart data={dataChart} metrics={data} @@ -196,7 +197,7 @@ const GraphView: FC<GraphViewProps> = ({ yaxis={yaxis} unit={unit} setPeriod={setPeriod} - container={containerRef?.current} + layoutSize={containerSize} height={height} onChangeLegend={handleChangeLegend} /> diff --git a/app/vmui/packages/vmui/src/components/Views/JsonView/JsonView.tsx b/app/vmui/packages/vmui/src/components/Views/JsonView/JsonView.tsx index d1496c8460..d569b817f9 100644 --- a/app/vmui/packages/vmui/src/components/Views/JsonView/JsonView.tsx +++ b/app/vmui/packages/vmui/src/components/Views/JsonView/JsonView.tsx @@ -1,6 +1,6 @@ import React, { FC, useMemo } from "preact/compat"; import { InstantMetricResult } from "../../../api/types"; -import { useSnack } from "../../../contexts/Snackbar"; +import useCopyToClipboard from "../../../hooks/useCopyToClipboard"; import { TopQuery } from "../../../types"; import Button from "../../Main/Button/Button"; import "./style.scss"; @@ -10,13 +10,12 @@ export interface JsonViewProps { } const JsonView: FC<JsonViewProps> = ({ data }) => { - const { showInfoMessage } = useSnack(); + const copyToClipboard = useCopyToClipboard(); const formattedJson = useMemo(() => JSON.stringify(data, null, 2), [data]); - const handlerCopy = () => { - navigator.clipboard.writeText(formattedJson); - showInfoMessage({ text: "Formatted JSON has been copied", type: "success" }); + const handlerCopy = async () => { + await copyToClipboard(formattedJson, "Formatted JSON has been copied"); }; return ( diff --git a/app/vmui/packages/vmui/src/components/Views/TableView/TableView.tsx b/app/vmui/packages/vmui/src/components/Views/TableView/TableView.tsx index 94d90feebc..41e3aa1dbe 100644 --- a/app/vmui/packages/vmui/src/components/Views/TableView/TableView.tsx +++ b/app/vmui/packages/vmui/src/components/Views/TableView/TableView.tsx @@ -1,4 +1,4 @@ -import React, { FC, useEffect, useMemo, useRef, useState } from "preact/compat"; +import React, { FC, useCallback, useEffect, useMemo, useRef, useState } from "preact/compat"; import { InstantMetricResult } from "../../../api/types"; import { InstantDataSeries } from "../../../types"; import { useSortedCategories } from "../../../hooks/useSortedCategories"; @@ -7,12 +7,13 @@ import classNames from "classnames"; import { ArrowDropDownIcon, CopyIcon } from "../../Main/Icons"; import Tooltip from "../../Main/Tooltip/Tooltip"; import Button from "../../Main/Button/Button"; -import { useSnack } from "../../../contexts/Snackbar"; +import useCopyToClipboard from "../../../hooks/useCopyToClipboard"; import { getNameForMetric } from "../../../utils/metric"; import { useCustomPanelState } from "../../../state/customPanel/CustomPanelStateContext"; import "./style.scss"; -import useResize from "../../../hooks/useResize"; import useDeviceDetect from "../../../hooks/useDeviceDetect"; +import useWindowSize from "../../../hooks/useWindowSize"; +import useEventListener from "../../../hooks/useEventListener"; export interface GraphViewProps { data: InstantMetricResult[]; @@ -20,11 +21,11 @@ export interface GraphViewProps { } const TableView: FC<GraphViewProps> = ({ data, displayColumns }) => { - const { showInfoMessage } = useSnack(); + const copyToClipboard = useCopyToClipboard(); const { isMobile } = useDeviceDetect(); const { tableCompact } = useCustomPanelState(); - const windowSize = useResize(document.body); + const windowSize = useWindowSize(); const tableRef = useRef<HTMLTableElement>(null); const [tableTop, setTableTop] = useState(0); const [headTop, setHeadTop] = useState(0); @@ -74,33 +75,22 @@ const TableView: FC<GraphViewProps> = ({ data, displayColumns }) => { setOrderBy(key); }; - const copyHandler = async (copyValue: string) => { - await navigator.clipboard.writeText(copyValue); - showInfoMessage({ text: "Row has been copied", type: "success" }); - }; - const createSortHandler = (key: string) => () => { sortHandler(key); }; - const createCopyHandler = (copyValue: string) => () => { - copyHandler(copyValue); + const createCopyHandler = (copyValue: string) => async () => { + await copyToClipboard(copyValue, "Row has been copied"); }; - const handleScroll = () => { + const handleScroll = useCallback(() => { if (!tableRef.current) return; const { top } = tableRef.current.getBoundingClientRect(); setHeadTop(top < 0 ? window.scrollY - tableTop : 0); - }; - - useEffect(() => { - window.addEventListener("scroll", handleScroll); - - return () => { - window.removeEventListener("scroll", handleScroll); - }; }, [tableRef, tableTop, windowSize]); + useEventListener("scroll", handleScroll); + useEffect(() => { if (!tableRef.current) return; const { top } = tableRef.current.getBoundingClientRect(); diff --git a/app/vmui/packages/vmui/src/hooks/useClickOutside.ts b/app/vmui/packages/vmui/src/hooks/useClickOutside.ts index 5f39e15261..912a477e04 100644 --- a/app/vmui/packages/vmui/src/hooks/useClickOutside.ts +++ b/app/vmui/packages/vmui/src/hooks/useClickOutside.ts @@ -1,4 +1,6 @@ -import { useEffect, RefObject } from "react"; +import { RefObject } from "react"; +import useEventListener from "./useEventListener"; +import { useCallback } from "preact/compat"; type Event = MouseEvent | TouchEvent; @@ -7,26 +9,19 @@ const useClickOutside = <T extends HTMLElement = HTMLElement>( handler: (event: Event) => void, preventRef?: RefObject<T> ) => { - useEffect(() => { - const listener = (event: Event) => { - const el = ref?.current; - const target = event.target as HTMLElement; - const isPreventRef = preventRef?.current && preventRef.current.contains(target); - if (!el || el.contains((event?.target as Node) || null) || isPreventRef) { - return; - } + const listener = useCallback((event: Event) => { + const el = ref?.current; + const target = event.target as HTMLElement; + const isPreventRef = preventRef?.current && preventRef.current.contains(target); + if (!el || el.contains((event?.target as Node) || null) || isPreventRef) { + return; + } - handler(event); // Call the handler only if the click is outside of the element passed. - }; + handler(event); // Call the handler only if the click is outside of the element passed. + }, [ref, handler]); - document.addEventListener("mousedown", listener); - document.addEventListener("touchstart", listener); - - return () => { - document.removeEventListener("mousedown", listener); - document.removeEventListener("touchstart", listener); - }; - }, [ref, handler]); // Reload only if ref or handler changes + useEventListener("mousedown", listener); + useEventListener("touchstart", listener); }; export default useClickOutside; diff --git a/app/vmui/packages/vmui/src/hooks/useCopyToClipboard.ts b/app/vmui/packages/vmui/src/hooks/useCopyToClipboard.ts new file mode 100644 index 0000000000..970417f549 --- /dev/null +++ b/app/vmui/packages/vmui/src/hooks/useCopyToClipboard.ts @@ -0,0 +1,32 @@ +import { useSnack } from "../contexts/Snackbar"; + +type CopyFn = (text: string, msgInfo?: string) => Promise<boolean> // Return success + +const useCopyToClipboard = (): CopyFn => { + const { showInfoMessage } = useSnack(); + + return async (text, msgInfo) => { + if (!navigator?.clipboard) { + showInfoMessage({ text: "Clipboard not supported", type: "error" }); + console.warn("Clipboard not supported"); + return false; + } + + // Try to save to clipboard then save it in the state if worked + try { + await navigator.clipboard.writeText(text); + if (msgInfo) { + showInfoMessage({ text: msgInfo, type: "success" }); + } + return true; + } catch (error) { + if (error instanceof Error) { + showInfoMessage({ text: `${error.name}: ${error.message}`, type: "error" }); + } + console.warn("Copy failed", error); + return false; + } + }; +}; + +export default useCopyToClipboard; diff --git a/app/vmui/packages/vmui/src/hooks/useDeviceDetect.ts b/app/vmui/packages/vmui/src/hooks/useDeviceDetect.ts index 8b8608a2ec..7d26cdb89f 100644 --- a/app/vmui/packages/vmui/src/hooks/useDeviceDetect.ts +++ b/app/vmui/packages/vmui/src/hooks/useDeviceDetect.ts @@ -1,9 +1,9 @@ import { useEffect, useState } from "react"; import { isMobileAgent } from "../utils/detect-device"; -import useResize from "./useResize"; +import useWindowSize from "./useWindowSize"; export default function useDeviceDetect() { - const windowSize = useResize(document.body); + const windowSize = useWindowSize(); const getIsMobile = () => { const mobileAgent = isMobileAgent(); diff --git a/app/vmui/packages/vmui/src/hooks/useDropzone.ts b/app/vmui/packages/vmui/src/hooks/useDropzone.ts index 7395a53bd9..9af2f2a386 100644 --- a/app/vmui/packages/vmui/src/hooks/useDropzone.ts +++ b/app/vmui/packages/vmui/src/hooks/useDropzone.ts @@ -1,8 +1,11 @@ -import { useState, useEffect } from "preact/compat"; +import { useState } from "preact/compat"; +import useEventListener from "./useEventListener"; +import { useRef } from "react"; -const useDropzone = (node: HTMLElement | null): {dragging: boolean, files: File[]} => { +const useDropzone = (): { dragging: boolean, files: File[] } => { const [files, setFiles] = useState<File[]>([]); const [dragging, setDragging] = useState(false); + const bodyRef = useRef(document.body); const handleAddFiles = (fileList: FileList) => { const filesArray = Array.from(fileList || []); @@ -43,21 +46,11 @@ const useDropzone = (node: HTMLElement | null): {dragging: boolean, files: File[ setFiles(jsonFiles); }; - useEffect(() => { - node?.addEventListener("dragenter", handleDrag); - node?.addEventListener("dragleave", handleDrag); - node?.addEventListener("dragover", handleDrag); - node?.addEventListener("drop", handleDrop); - node?.addEventListener("paste", handlePaste); - - return () => { - node?.removeEventListener("dragenter", handleDrag); - node?.removeEventListener("dragleave", handleDrag); - node?.removeEventListener("dragover", handleDrag); - node?.removeEventListener("drop", handleDrop); - node?.removeEventListener("paste", handlePaste); - }; - }, [node]); + useEventListener("dragenter", handleDrag, bodyRef); + useEventListener("dragleave", handleDrag, bodyRef); + useEventListener("dragover", handleDrag, bodyRef); + useEventListener("drop", handleDrop, bodyRef); + useEventListener("paste", handlePaste, bodyRef); return { files, diff --git a/app/vmui/packages/vmui/src/hooks/useElementSize.ts b/app/vmui/packages/vmui/src/hooks/useElementSize.ts new file mode 100644 index 0000000000..603b328e4b --- /dev/null +++ b/app/vmui/packages/vmui/src/hooks/useElementSize.ts @@ -0,0 +1,36 @@ +import { useCallback, useState } from "react"; +import useIsomorphicLayoutEffect from "./useIsomorphicLayoutEffect"; +import useEventListener from "./useEventListener"; + +export interface ElementSize { + width: number + height: number +} + +const useElementSize = <T extends HTMLElement = HTMLDivElement>(): [(node: T | null) => void, ElementSize] => { + // Mutable values like 'ref.current' aren't valid dependencies + // because mutating them doesn't re-render the component. + // Instead, we use a state as a ref to be reactive. + const [ref, setRef] = useState<T | null>(null); + const [size, setSize] = useState<ElementSize>({ + width: 0, + height: 0, + }); + + // Prevent too many rendering using useCallback + const handleSize = useCallback(() => { + setSize({ + width: ref?.offsetWidth || 0, + height: ref?.offsetHeight || 0, + }); + + }, [ref?.offsetHeight, ref?.offsetWidth]); + + useEventListener("resize", handleSize); + + useIsomorphicLayoutEffect(handleSize, [ref?.offsetHeight, ref?.offsetWidth]); + + return [setRef, size]; +}; + +export default useElementSize; diff --git a/app/vmui/packages/vmui/src/hooks/useEventListener.ts b/app/vmui/packages/vmui/src/hooks/useEventListener.ts new file mode 100644 index 0000000000..f97ce2d852 --- /dev/null +++ b/app/vmui/packages/vmui/src/hooks/useEventListener.ts @@ -0,0 +1,81 @@ +import { RefObject, useEffect, useRef } from "react"; +import useIsomorphicLayoutEffect from "./useIsomorphicLayoutEffect"; + +// MediaQueryList Event based useEventListener interface +function useEventListener<K extends keyof MediaQueryListEventMap>( + eventName: K, + handler: (event: MediaQueryListEventMap[K]) => void, + element: RefObject<MediaQueryList>, + options?: boolean | AddEventListenerOptions, +): void + +// Window Event based useEventListener interface +function useEventListener<K extends keyof WindowEventMap>( + eventName: K, + handler: (event: WindowEventMap[K]) => void, + element?: undefined, + options?: boolean | AddEventListenerOptions, +): void + +// Element Event based useEventListener interface +function useEventListener< + K extends keyof HTMLElementEventMap, + T extends HTMLElement = HTMLDivElement, +>( + eventName: K, + handler: (event: HTMLElementEventMap[K]) => void, + element: RefObject<T>, + options?: boolean | AddEventListenerOptions, +): void + +// Document Event based useEventListener interface +function useEventListener<K extends keyof DocumentEventMap>( + eventName: K, + handler: (event: DocumentEventMap[K]) => void, + element: RefObject<Document>, + options?: boolean | AddEventListenerOptions, +): void + +function useEventListener< + KW extends keyof WindowEventMap, + KH extends keyof HTMLElementEventMap, + KM extends keyof MediaQueryListEventMap, + T extends HTMLElement | MediaQueryList | void = void, +>( + eventName: KW | KH | KM, + handler: ( + event: + | WindowEventMap[KW] + | HTMLElementEventMap[KH] + | MediaQueryListEventMap[KM] + | Event, + ) => void, + element?: RefObject<T>, + options?: boolean | AddEventListenerOptions, +) { + // Create a ref that stores handler + const savedHandler = useRef(handler); + + useIsomorphicLayoutEffect(() => { + savedHandler.current = handler; + }, [handler]); + + useEffect(() => { + // Define the listening target + const targetElement: T | Window = element?.current ?? window; + + if (!(targetElement && targetElement.addEventListener)) return; + + // Create event listener that calls handler function stored in ref + const listener: typeof handler = event => savedHandler.current(event); + + targetElement.addEventListener(eventName, listener, options); + + // Remove event listener on cleanup + return () => { + targetElement.removeEventListener(eventName, listener, options); + }; + }, [eventName, element, options]); +} + +export default useEventListener; diff --git a/app/vmui/packages/vmui/src/hooks/useIsomorphicLayoutEffect.ts b/app/vmui/packages/vmui/src/hooks/useIsomorphicLayoutEffect.ts new file mode 100644 index 0000000000..8ccca8a63e --- /dev/null +++ b/app/vmui/packages/vmui/src/hooks/useIsomorphicLayoutEffect.ts @@ -0,0 +1,5 @@ +import { useEffect, useLayoutEffect } from "react"; + +const useIsomorphicLayoutEffect = typeof window !== "undefined" ? useLayoutEffect : useEffect; + +export default useIsomorphicLayoutEffect; diff --git a/app/vmui/packages/vmui/src/hooks/useResize.ts b/app/vmui/packages/vmui/src/hooks/useResize.ts deleted file mode 100644 index c3b10ca484..0000000000 --- a/app/vmui/packages/vmui/src/hooks/useResize.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { useState, useEffect } from "preact/compat"; - -const useResize = (node: HTMLElement | null): {width: number, height: number} => { - const [windowSize, setWindowSize] = useState({ - width: 0, - height: 0, - }); - useEffect(() => { - const observer = new ResizeObserver((entries) => { - const { width, height } = entries[0].contentRect; - setWindowSize({ width, height }); - }); - if (node) observer.observe(node); - return () => { - if (node) observer.unobserve(node); - }; - }, [node]); - return windowSize; -}; - -export default useResize; diff --git a/app/vmui/packages/vmui/src/hooks/useWindowSize.ts b/app/vmui/packages/vmui/src/hooks/useWindowSize.ts new file mode 100644 index 0000000000..1b1e1021f3 --- /dev/null +++ b/app/vmui/packages/vmui/src/hooks/useWindowSize.ts @@ -0,0 +1,31 @@ +import { useState } from "react"; +import useIsomorphicLayoutEffect from "./useIsomorphicLayoutEffect"; +import useEventListener from "./useEventListener"; + +interface WindowSize { + width: number + height: number +} + +const useWindowSize = (): WindowSize => { + const [windowSize, setWindowSize] = useState<WindowSize>({ + width: 0, + height: 0, + }); + + const handleSize = () => { + setWindowSize({ + width: window.innerWidth, + height: window.innerHeight, + }); + }; + + useEventListener("resize", handleSize); + + // Set size at the first client-side load + useIsomorphicLayoutEffect(handleSize, []); + + return windowSize; +}; + +export default useWindowSize; diff --git a/app/vmui/packages/vmui/src/pages/CardinalityPanel/Table/TableSettings/TableSettings.tsx b/app/vmui/packages/vmui/src/pages/CardinalityPanel/Table/TableSettings/TableSettings.tsx index 7f3765932e..6b231fa49f 100644 --- a/app/vmui/packages/vmui/src/pages/CardinalityPanel/Table/TableSettings/TableSettings.tsx +++ b/app/vmui/packages/vmui/src/pages/CardinalityPanel/Table/TableSettings/TableSettings.tsx @@ -1,4 +1,4 @@ -import React, { FC, useEffect, useState, useRef, useMemo } from "preact/compat"; +import React, { FC, useEffect, useRef, useMemo } from "preact/compat"; import { useSortedCategories } from "../../../../hooks/useSortedCategories"; import { InstantMetricResult } from "../../../../api/types"; import Button from "../../../../components/Main/Button/Button"; @@ -12,6 +12,7 @@ import Switch from "../../../../components/Main/Switch/Switch"; import { arrayEquals } from "../../../../utils/array"; import classNames from "classnames"; import useDeviceDetect from "../../../../hooks/useDeviceDetect"; +import useBoolean from "../../../../hooks/useBoolean"; const title = "Table settings"; @@ -30,7 +31,11 @@ const TableSettings: FC<TableSettingsProps> = ({ data, defaultColumns = [], onCh const buttonRef = useRef<HTMLDivElement>(null); - const [openSettings, setOpenSettings] = useState(false); + const { + value: openSettings, + toggle: toggleOpenSettings, + setFalse: handleClose, + } = useBoolean(false); const disabledButton = useMemo(() => !columns.length, [columns]); @@ -38,16 +43,12 @@ const TableSettings: FC<TableSettingsProps> = ({ data, defaultColumns = [], onCh onChange(defaultColumns.includes(key) ? defaultColumns.filter(col => col !== key) : [...defaultColumns, key]); }; - const handleClose = () => { - setOpenSettings(false); - }; - const toggleTableCompact = () => { customPanelDispatch({ type: "TOGGLE_TABLE_COMPACT" }); }; const handleResetColumns = () => { - setOpenSettings(false); + handleClose(); onChange(columns.map(col => col.key)); }; @@ -55,10 +56,6 @@ const TableSettings: FC<TableSettingsProps> = ({ data, defaultColumns = [], onCh handleChange(key); }; - const toggleOpenSettings = () => { - setOpenSettings(prev => !prev); - }; - useEffect(() => { const values = columns.map(col => col.key); if (arrayEquals(values, defaultColumns)) return; diff --git a/app/vmui/packages/vmui/src/pages/CustomPanel/index.tsx b/app/vmui/packages/vmui/src/pages/CustomPanel/index.tsx index dcca302636..b493557360 100644 --- a/app/vmui/packages/vmui/src/pages/CustomPanel/index.tsx +++ b/app/vmui/packages/vmui/src/pages/CustomPanel/index.tsx @@ -24,6 +24,7 @@ import classNames from "classnames"; import useDeviceDetect from "../../hooks/useDeviceDetect"; import GraphTips from "../../components/Chart/GraphTips/GraphTips"; import InstantQueryTip from "./InstantQueryTip/InstantQueryTip"; +import useBoolean from "../../hooks/useBoolean"; const CustomPanel: FC = () => { const { displayType, isTracingEnabled } = useCustomPanelState(); @@ -36,9 +37,14 @@ const CustomPanel: FC = () => { const [displayColumns, setDisplayColumns] = useState<string[]>(); const [tracesState, setTracesState] = useState<Trace[]>([]); const [hideQuery, setHideQuery] = useState<number[]>([]); - const [showAllSeries, setShowAllSeries] = useState(false); const [hideError, setHideError] = useState(!query[0]); + const { + value: showAllSeries, + setTrue: handleShowAll, + setFalse: handleHideSeries, + } = useBoolean(false); + const { customStep, yaxis } = useGraphState(); const graphDispatch = useGraphDispatch(); @@ -72,10 +78,6 @@ const CustomPanel: FC = () => { timeDispatch({ type: "SET_PERIOD", payload: { from, to } }); }; - const handleShowAll = () => { - setShowAllSeries(true); - }; - const handleTraceDelete = (trace: Trace) => { const updatedTraces = tracesState.filter((data) => data.idValue !== trace.idValue); setTracesState([...updatedTraces]); @@ -99,9 +101,7 @@ const CustomPanel: FC = () => { setTracesState([]); }, [displayType]); - useEffect(() => { - setShowAllSeries(false); - }, [query]); + useEffect(handleHideSeries, [query]); useEffect(() => { graphDispatch({ type: "SET_IS_HISTOGRAM", payload: isHistogram }); diff --git a/app/vmui/packages/vmui/src/pages/PredefinedPanels/PredefinedDashboard/PredefinedDashboard.tsx b/app/vmui/packages/vmui/src/pages/PredefinedPanels/PredefinedDashboard/PredefinedDashboard.tsx index 21cbed41b9..d9e7291213 100644 --- a/app/vmui/packages/vmui/src/pages/PredefinedPanels/PredefinedDashboard/PredefinedDashboard.tsx +++ b/app/vmui/packages/vmui/src/pages/PredefinedPanels/PredefinedDashboard/PredefinedDashboard.tsx @@ -1,12 +1,13 @@ import React, { FC, useEffect, useMemo, useState } from "preact/compat"; -import { MouseEvent as ReactMouseEvent } from "react"; +import { MouseEvent as ReactMouseEvent, useCallback } from "react"; import { DashboardRow } from "../../../types"; import PredefinedPanel from "../PredefinedPanel/PredefinedPanel"; -import useResize from "../../../hooks/useResize"; import Accordion from "../../../components/Main/Accordion/Accordion"; import "./style.scss"; import classNames from "classnames"; import Alert from "../../../components/Main/Alert/Alert"; +import useWindowSize from "../../../hooks/useWindowSize"; +import useEventListener from "../../../hooks/useEventListener"; export interface PredefinedDashboardProps extends DashboardRow { filename: string; @@ -20,7 +21,7 @@ const PredefinedDashboard: FC<PredefinedDashboardProps> = ({ filename }) => { - const windowSize = useResize(document.body); + const windowSize = useWindowSize(); const sizeSection = useMemo(() => { return windowSize.width / 12; }, [windowSize]); @@ -34,16 +35,14 @@ const PredefinedDashboard: FC<PredefinedDashboardProps> = ({ const [resize, setResize] = useState({ start: 0, target: 0, enable: false }); - const handleMouseMove = (e: MouseEvent) => { + const handleMouseMove = useCallback((e: MouseEvent) => { if (!resize.enable) return; const { start } = resize; const sectionCount = Math.ceil((start - e.clientX)/sizeSection); if (Math.abs(sectionCount) >= 12) return; - const width = panelsWidth.map((p, i) => { - return p - (i === resize.target ? sectionCount : 0); - }); + const width = panelsWidth.map((p, i) => p - (i === resize.target ? sectionCount : 0)); setPanelsWidth(width); - }; + }, [resize, sizeSection]); const handleMouseDown = (e: ReactMouseEvent<HTMLButtonElement, MouseEvent>, i: number) => { setResize({ @@ -52,12 +51,13 @@ const PredefinedDashboard: FC<PredefinedDashboardProps> = ({ enable: true, }); }; - const handleMouseUp = () => { + + const handleMouseUp = useCallback(() => { setResize({ ...resize, enable: false }); - }; + }, [resize]); const handleChangeExpanded = (val: boolean) => setExpanded(val); @@ -65,14 +65,8 @@ const PredefinedDashboard: FC<PredefinedDashboardProps> = ({ handleMouseDown(e, index); }; - useEffect(() => { - window.addEventListener("mousemove", handleMouseMove); - window.addEventListener("mouseup", handleMouseUp); - return () => { - window.removeEventListener("mousemove", handleMouseMove); - window.removeEventListener("mouseup", handleMouseUp); - }; - }, [resize]); + useEventListener("mousemove", handleMouseMove); + useEventListener("mouseup", handleMouseUp); const HeaderAccordion = () => ( <div diff --git a/app/vmui/packages/vmui/src/pages/PredefinedPanels/PredefinedDashboard/style.scss b/app/vmui/packages/vmui/src/pages/PredefinedPanels/PredefinedDashboard/style.scss index ee042864de..f3da4853a0 100644 --- a/app/vmui/packages/vmui/src/pages/PredefinedPanels/PredefinedDashboard/style.scss +++ b/app/vmui/packages/vmui/src/pages/PredefinedPanels/PredefinedDashboard/style.scss @@ -61,7 +61,7 @@ height: 20px; transform: scale(0); transition: transform 200ms ease-in-out; - cursor: se-resize; + cursor: ew-resize; z-index: 1; &:after { diff --git a/app/vmui/packages/vmui/src/pages/TracePage/JsonForm/JsonForm.tsx b/app/vmui/packages/vmui/src/pages/TracePage/JsonForm/JsonForm.tsx index 5bec4a98f5..b34764138b 100644 --- a/app/vmui/packages/vmui/src/pages/TracePage/JsonForm/JsonForm.tsx +++ b/app/vmui/packages/vmui/src/pages/TracePage/JsonForm/JsonForm.tsx @@ -5,7 +5,7 @@ import Button from "../../../components/Main/Button/Button"; import Trace from "../../../components/TraceQuery/Trace"; import { ErrorTypes } from "../../../types"; import classNames from "classnames"; -import { useSnack } from "../../../contexts/Snackbar"; +import useCopyToClipboard from "../../../hooks/useCopyToClipboard"; import { CopyIcon, RestartIcon } from "../../../components/Main/Icons"; import useDeviceDetect from "../../../hooks/useDeviceDetect"; @@ -28,7 +28,7 @@ const JsonForm: FC<JsonFormProps> = ({ onClose, onUpload, }) => { - const { showInfoMessage } = useSnack(); + const copyToClipboard = useCopyToClipboard(); const { isMobile } = useDeviceDetect(); const [json, setJson] = useState(defaultJson); @@ -58,8 +58,7 @@ const JsonForm: FC<JsonFormProps> = ({ }; const handlerCopy = async () => { - await navigator.clipboard.writeText(json); - showInfoMessage({ text: "Formatted JSON has been copied", type: "success" }); + await copyToClipboard(json, "Formatted JSON has been copied"); }; const handleReset = () => { diff --git a/app/vmui/packages/vmui/src/pages/TracePage/index.tsx b/app/vmui/packages/vmui/src/pages/TracePage/index.tsx index b3e6429a0b..088f336ec7 100644 --- a/app/vmui/packages/vmui/src/pages/TracePage/index.tsx +++ b/app/vmui/packages/vmui/src/pages/TracePage/index.tsx @@ -12,21 +12,19 @@ import { ErrorTypes } from "../../types"; import { useSearchParams } from "react-router-dom"; import useDropzone from "../../hooks/useDropzone"; import TraceUploadButtons from "./TraceUploadButtons/TraceUploadButtons"; +import useBoolean from "../../hooks/useBoolean"; const TracePage: FC = () => { - const [openModal, setOpenModal] = useState(false); const [tracesState, setTracesState] = useState<Trace[]>([]); const [errors, setErrors] = useState<{filename: string, text: string}[]>([]); const hasTraces = useMemo(() => !!tracesState.length, [tracesState]); const [, setSearchParams] = useSearchParams(); - const handleOpenModal = () => { - setOpenModal(true); - }; - - const handleCloseModal = () => { - setOpenModal(false); - }; + const { + value: openModal, + setTrue: handleOpenModal, + setFalse: handleCloseModal, + } = useBoolean(false); const handleError = (e: Error, filename = "") => { setErrors(prev => [{ filename, text: `: ${e.message}` }, ...prev]); @@ -84,7 +82,7 @@ const TracePage: FC = () => { }, []); - const { files, dragging } = useDropzone(document.body); + const { files, dragging } = useDropzone(); useEffect(() => { handleReadFiles(files);