From a75abdc3f74bcf93a4e5e98ce23586bbd4721129 Mon Sep 17 00:00:00 2001 From: rozetko Date: Wed, 14 Dec 2022 17:16:35 +0300 Subject: [PATCH] WIP: config page --- .config/webpack/webpack.config.ts | 41 +- package.json | 12 +- src/components/AppConfig/AppConfig.test.tsx | 51 -- src/components/AppConfig/AppConfig.tsx | 92 --- src/components/AppConfig/index.tsx | 1 - src/components/GBlock/Block.module.scss | 28 + src/components/GBlock/Block.tsx | 44 ++ .../PluginConfigPage/PluginConfigPage.tsx | 198 ++++++ src/components/PluginConfigPage/index.tsx | 1 + .../ConfigurationForm.module.css | 4 + .../parts/ConfigurationForm/index.tsx | 147 +++++ .../RemoveCurrentConfigurationButton.test.tsx | 32 + .../index.tsx | 20 + .../StatusMessageBlock.test.tsx | 12 + .../parts/StatusMessageBlock/index.tsx | 15 + src/components/Text/Text.module.scss | 72 ++ src/components/Text/Text.tsx | 164 +++++ src/components/WithConfirm/WithConfirm.tsx | 55 ++ src/module.ts | 4 +- src/plugin_state.ts | 189 ++++++ src/services/network_service.ts | 30 + src/types.ts | 16 + src/utils/index.ts | 7 + yarn.lock | 623 +++++++++++++----- 24 files changed, 1510 insertions(+), 348 deletions(-) delete mode 100644 src/components/AppConfig/AppConfig.test.tsx delete mode 100644 src/components/AppConfig/AppConfig.tsx delete mode 100644 src/components/AppConfig/index.tsx create mode 100644 src/components/GBlock/Block.module.scss create mode 100644 src/components/GBlock/Block.tsx create mode 100644 src/components/PluginConfigPage/PluginConfigPage.tsx create mode 100644 src/components/PluginConfigPage/index.tsx create mode 100644 src/components/PluginConfigPage/parts/ConfigurationForm/ConfigurationForm.module.css create mode 100644 src/components/PluginConfigPage/parts/ConfigurationForm/index.tsx create mode 100644 src/components/PluginConfigPage/parts/RemoveCurrentConfigurationButton/RemoveCurrentConfigurationButton.test.tsx create mode 100644 src/components/PluginConfigPage/parts/RemoveCurrentConfigurationButton/index.tsx create mode 100644 src/components/PluginConfigPage/parts/StatusMessageBlock/StatusMessageBlock.test.tsx create mode 100644 src/components/PluginConfigPage/parts/StatusMessageBlock/index.tsx create mode 100644 src/components/Text/Text.module.scss create mode 100644 src/components/Text/Text.tsx create mode 100644 src/components/WithConfirm/WithConfirm.tsx create mode 100644 src/plugin_state.ts create mode 100644 src/services/network_service.ts create mode 100644 src/types.ts create mode 100644 src/utils/index.ts diff --git a/.config/webpack/webpack.config.ts b/.config/webpack/webpack.config.ts index 953f3f1..ae8f22c 100644 --- a/.config/webpack/webpack.config.ts +++ b/.config/webpack/webpack.config.ts @@ -59,6 +59,7 @@ const config = async (env): Promise => ({ const stripPrefix = (request) => request.substr(prefix.length); if (hasPrefix(request)) { + // @ts-ignore return callback(null, stripPrefix(request)); } @@ -90,28 +91,24 @@ const config = async (env): Promise => ({ }, }, }, - { - test: /\.(png|jpe?g|gif|svg)$/, - use: [ - { - loader: 'asset/resource', - options: { - outputPath: '/', - name: Boolean(env.production) ? '[path][hash].[ext]' : '[path][name].[ext]', - }, - }, - ], - }, - { - test: /\.(woff|woff2|eot|ttf|otf)(\?v=\d+\.\d+\.\d+)?$/, - loader: 'asset/resource', - options: { - // Keep publicPath relative for host.com/grafana/ deployments - publicPath: `public/plugins/${getPluginId()}/fonts`, - outputPath: 'fonts', - name: Boolean(env.production) ? '[hash].[ext]' : '[name].[ext]', - }, - }, + // { + // test: /\.(png|jpe?g|gif|svg)$/, + // type: 'asset/resource', + // options: { + // outputPath: '/', + // name: Boolean(env.production) ? '[path][hash].[ext]' : '[path][name].[ext]', + // }, + // }, + // { + // test: /\.(woff|woff2|eot|ttf|otf)(\?v=\d+\.\d+\.\d+)?$/, + // type: 'asset/resource', + // options: { + // // Keep publicPath relative for host.com/grafana/ deployments + // publicPath: `public/plugins/${getPluginId()}/fonts`, + // outputPath: 'fonts', + // name: Boolean(env.production) ? '[hash].[ext]' : '[name].[ext]', + // }, + // }, ], }, diff --git a/package.json b/package.json index 49c4d40..6314911 100644 --- a/package.json +++ b/package.json @@ -27,12 +27,16 @@ "@swc/jest": "^0.2.20", "@testing-library/jest-dom": "^5.16.2", "@testing-library/react": "^12.1.3", + "@testing-library/user-event": "^14.4.3", "@types/glob": "^8.0.0", "@types/jest": "^27.4.1", - "@types/react-router-dom": "^5.3.3", + "@types/lodash-es": "^4.17.6", "@types/node": "^17.0.19", + "@types/react-copy-to-clipboard": "^5.0.4", + "@types/react-router-dom": "^5.3.3", "@typescript-eslint/eslint-plugin": "^4.33.0", "@typescript-eslint/parser": "^4.33.0", + "axios": "^1.2.1", "copy-webpack-plugin": "^10.0.0", "eslint": "^7.32.0", "eslint-config-prettier": "^8.3.0", @@ -41,14 +45,16 @@ "eslint-plugin-react": "^7.26.1", "eslint-plugin-react-hooks": "^4.2.0", "eslint-webpack-plugin": "^3.1.1", + "fork-ts-checker-webpack-plugin": "^7.2.0", "glob": "^8.0.3", "jest": "27.5.0", - "fork-ts-checker-webpack-plugin": "^7.2.0", + "lodash-es": "^4.17.21", "prettier": "^2.5.0", + "react-copy-to-clipboard": "^5.1.0", "replace-in-file-webpack-plugin": "^1.0.6", "swc-loader": "^0.1.15", - "tsconfig-paths": "^3.12.0", "ts-node": "^10.5.0", + "tsconfig-paths": "^3.12.0", "typescript": "^4.4.0", "webpack": "^5.69.1", "webpack-cli": "^4.9.2", diff --git a/src/components/AppConfig/AppConfig.test.tsx b/src/components/AppConfig/AppConfig.test.tsx deleted file mode 100644 index 7f7cd8b..0000000 --- a/src/components/AppConfig/AppConfig.test.tsx +++ /dev/null @@ -1,51 +0,0 @@ -import React from 'react'; -import { render, screen } from '@testing-library/react'; -import { PluginType } from '@grafana/data'; -import { AppConfig, AppConfigProps } from './AppConfig'; - -describe('Components/AppConfig', () => { - let props: AppConfigProps; - - beforeEach(() => { - jest.resetAllMocks(); - - props = { - plugin: { - meta: { - id: 'sample-app', - name: 'Sample App', - type: PluginType.app, - enabled: true, - jsonData: {}, - }, - }, - query: {}, - } as unknown as AppConfigProps; - }); - - test('renders without an error"', () => { - render(); - - expect(screen.queryByText(/Enable \/ Disable/i)).toBeInTheDocument(); - }); - - test('renders an "Enable" button if the plugin is disabled', () => { - const plugin = { meta: { ...props.plugin.meta, enabled: false } }; - - // @ts-ignore - We don't need to provide `addConfigPage()` and `setChannelSupport()` for these tests - render(); - - expect(screen.queryByText(/The plugin is currently not enabled./i)).toBeInTheDocument(); - expect(screen.queryByText(/The plugin is currently enabled./i)).not.toBeInTheDocument(); - }); - - test('renders a "Disable" button if the plugin is enabled', () => { - const plugin = { meta: { ...props.plugin.meta, enabled: true } }; - - // @ts-ignore - We don't need to provide `addConfigPage()` and `setChannelSupport()` for these tests - render(); - - expect(screen.queryByText(/The plugin is currently enabled./i)).toBeInTheDocument(); - expect(screen.queryByText(/The plugin is currently not enabled./i)).not.toBeInTheDocument(); - }); -}); diff --git a/src/components/AppConfig/AppConfig.tsx b/src/components/AppConfig/AppConfig.tsx deleted file mode 100644 index 8d82161..0000000 --- a/src/components/AppConfig/AppConfig.tsx +++ /dev/null @@ -1,92 +0,0 @@ -import React from 'react'; -import { Button, Legend, useStyles2 } from '@grafana/ui'; -import { PluginConfigPageProps, AppPluginMeta, PluginMeta, GrafanaTheme2 } from '@grafana/data'; -import { getBackendSrv } from '@grafana/runtime'; -import { css } from '@emotion/css'; -import { lastValueFrom } from 'rxjs'; - -export type AppPluginSettings = {}; - -export interface AppConfigProps extends PluginConfigPageProps> {} - -export const AppConfig = ({ plugin }: AppConfigProps) => { - const s = useStyles2(getStyles); - const { enabled, jsonData } = plugin.meta; - - return ( -
-
- {/* Enable the plugin */} - Enable / Disable - {!enabled && ( - <> -
The plugin is currently not enabled.
- - - )} - - {/* Disable the plugin */} - {enabled && ( - <> -
The plugin is currently enabled.
- - - )} -
-
- ); -}; - -const getStyles = (theme: GrafanaTheme2) => ({ - colorWeak: css` - color: ${theme.colors.text.secondary}; - `, - marginTop: css` - margin-top: ${theme.spacing(3)}; - `, -}); - -const updatePluginAndReload = async (pluginId: string, data: Partial) => { - try { - await updatePlugin(pluginId, data); - - // Reloading the page as the changes made here wouldn't be propagated to the actual plugin otherwise. - // This is not ideal, however unfortunately currently there is no supported way for updating the plugin state. - window.location.reload(); - } catch (e) { - console.error('Error while updating the plugin', e); - } -}; - -export const updatePlugin = async (pluginId: string, data: Partial) => { - const response = getBackendSrv().fetch({ - url: `/api/plugins/${pluginId}/settings`, - method: 'POST', - data, - }); - return lastValueFrom(response); -}; diff --git a/src/components/AppConfig/index.tsx b/src/components/AppConfig/index.tsx deleted file mode 100644 index 1dba18f..0000000 --- a/src/components/AppConfig/index.tsx +++ /dev/null @@ -1 +0,0 @@ -export * from './AppConfig'; diff --git a/src/components/GBlock/Block.module.scss b/src/components/GBlock/Block.module.scss new file mode 100644 index 0000000..b83e6c7 --- /dev/null +++ b/src/components/GBlock/Block.module.scss @@ -0,0 +1,28 @@ +.root { + padding: 16px; + border-radius: 2px; + + &--withBackGround { + background: var(--secondary-background); + } + + &--fullWidth { + width: 100%; + } + + &--hover:hover { + background: var(--hover-selected); + } +} + +:global(.theme-dark) .root_bordered { + border: var(--border-weak); +} + +:global(.theme-light) .root_bordered { + border: var(--border-weak); +} + +:global(.theme-dark) .root_shadowed { + box-shadow: 0 4px 10px rgba(0, 0, 0, 0.6); +} diff --git a/src/components/GBlock/Block.tsx b/src/components/GBlock/Block.tsx new file mode 100644 index 0000000..21852f4 --- /dev/null +++ b/src/components/GBlock/Block.tsx @@ -0,0 +1,44 @@ +import { css } from '@emotion/css'; +import React, { FC, HTMLAttributes } from 'react'; + +// import './Block.module.scss'; + +interface BlockProps extends HTMLAttributes { + bordered?: boolean; + shadowed?: boolean; + withBackground?: boolean; + hover?: boolean; + fullWidth?: boolean; +} + +const Block: FC = (props) => { + const { + children, + style, + className, + bordered = false, + fullWidth = false, + hover = false, + shadowed = false, + withBackground = false, + ...rest + } = props; + + return ( +
+ {children} +
+ ); +}; + +export default Block; diff --git a/src/components/PluginConfigPage/PluginConfigPage.tsx b/src/components/PluginConfigPage/PluginConfigPage.tsx new file mode 100644 index 0000000..490032c --- /dev/null +++ b/src/components/PluginConfigPage/PluginConfigPage.tsx @@ -0,0 +1,198 @@ +import React, { FC, useCallback, useEffect, useState } from 'react'; + +import { Legend, LoadingPlaceholder } from '@grafana/ui'; +import { useLocation } from 'react-router-dom'; + +// import logo from '../../img/logo.svg'; +import PluginState from '../../plugin_state'; + +import ConfigurationForm from './parts/ConfigurationForm'; +import RemoveCurrentConfigurationButton from './parts/RemoveCurrentConfigurationButton'; +import StatusMessageBlock from './parts/StatusMessageBlock'; +import { DataExporterPluginConfigPageProps } from 'types'; + +const PLUGIN_CONFIGURED_QUERY_PARAM = 'pluginConfigured'; +const PLUGIN_CONFIGURED_QUERY_PARAM_TRUTHY_VALUE = 'true'; + +const DEFAULT_API_URL = 'http://localhost:8080'; + +/** + * When everything is successfully configured, reload the page, and pass along a few query parameters + * so that we avoid an infinite configuration-check/data-sync loop + * + * Don't refresh the page if the plugin is already enabled.. + */ +export const reloadPageWithPluginConfiguredQueryParams = (pluginEnabled: boolean): void => { + if (!pluginEnabled) { + window.location.href = `${window.location.href}?${PLUGIN_CONFIGURED_QUERY_PARAM}=${PLUGIN_CONFIGURED_QUERY_PARAM_TRUTHY_VALUE}`; + } +}; + +/** + * remove the query params used to track state for a page reload after successful configuration, without triggering + * a page reload + * https://stackoverflow.com/a/19279428 + */ +export const removePluginConfiguredQueryParams = (pluginIsEnabled?: boolean): void => { + if (window.history.pushState && pluginIsEnabled) { + const newurl = `${window.location.protocol}//${window.location.host}${window.location.pathname}`; + window.history.pushState({ path: newurl }, '', newurl); + } +}; + +export const PluginConfigPage: FC = ({ + plugin: { + meta: { jsonData, enabled: pluginIsEnabled }, + }, +}) => { + const { search } = useLocation(); + const queryParams = new URLSearchParams(search); + const pluginConfiguredQueryParam = queryParams.get(PLUGIN_CONFIGURED_QUERY_PARAM); + + const pluginConfiguredRedirect = pluginConfiguredQueryParam === PLUGIN_CONFIGURED_QUERY_PARAM_TRUTHY_VALUE; + + const [checkingIfPluginIsConnected, setCheckingIfPluginIsConnected] = useState(!pluginConfiguredRedirect); + const [pluginConnectionCheckError, setPluginConnectionCheckError] = useState(null); + + const [pluginIsConnected, setPluginIsConnected] = useState(pluginConfiguredRedirect); + + const [resettingPlugin, setResettingPlugin] = useState(false); + const [pluginResetError, setPluginResetError] = useState(null); + + const pluginMetaDataExporterApiUrl = jsonData?.dataExporterApiUrl; + const dataExporterApiUrl = pluginMetaDataExporterApiUrl || DEFAULT_API_URL; + + const resetQueryParams = useCallback(() => removePluginConfiguredQueryParams(pluginIsEnabled), [pluginIsEnabled]); + + useEffect(resetQueryParams, [resetQueryParams]); + + useEffect(() => { + const configurePluginAndSyncData = async () => { + /** + * If the plugin has never been configured, DataExporterApiUrl will be undefined in the plugin's jsonData + * In that case, check to see if DataExporter_API_URL has been supplied as an env var. + * Supplying the env var basically allows to skip the configuration form + * (check webpack.config.js to see how this is set) + */ + if (!pluginMetaDataExporterApiUrl) { + /** + * DataExporterApiUrl is not yet saved in the grafana plugin settings, but has been supplied as an env var + * lets auto-trigger a self-hosted plugin install w/ the DataExporterApiUrl passed in as an env var + */ + const errorMsg = await PluginState.installPlugin(dataExporterApiUrl); + if (errorMsg) { + setPluginConnectionCheckError(errorMsg); + setCheckingIfPluginIsConnected(false); + return; + } + } + + /** + * If the DataExporterApiUrl is not set in the plugin settings, and not supplied via an env var + * there's no reason to check if the plugin is connected, we know it can't be + */ + if (dataExporterApiUrl) { + const pluginConnectionResponse = await PluginState.checkIfPluginIsConnected(dataExporterApiUrl); + + if (typeof pluginConnectionResponse === 'string') { + setPluginConnectionCheckError(pluginConnectionResponse); + } + } + setCheckingIfPluginIsConnected(false); + }; + + /** + * don't check the plugin status (or trigger a data sync) if the user was just redirected after a successful + * plugin setup + */ + if (!pluginConfiguredRedirect) { + configurePluginAndSyncData(); + } + }, [pluginMetaDataExporterApiUrl, dataExporterApiUrl, pluginConfiguredRedirect]); + + const resetState = useCallback(() => { + setPluginResetError(null); + setPluginConnectionCheckError(null); + setPluginIsConnected(null); + resetQueryParams(); + }, [resetQueryParams]); + + /** + * NOTE: there is a possible edge case when resetting the plugin, that would lead to an error message being shown + * (which could be fixed by just reloading the page) + * This would happen if the user removes the plugin configuration, leaves the page, then comes back to the plugin + * configuration. + * + * This is because the props being passed into this component wouldn't reflect the actual plugin + * provisioning state. The props would still have DataExporterApiUrl set in the plugin jsonData, so when we make the API + * call to check the plugin state w/ DataExporter API the plugin-proxy would return a 502 Bad Gateway because the actual + * provisioned plugin doesn't know about the DataExporterApiUrl. + * + * This could be fixed by instead of passing in the plugin provisioning information as props always fetching it + * when this component renders (via a useEffect). We probably don't need to worry about this because it should happen + * very rarely, if ever + */ + const triggerPluginReset = useCallback(async () => { + setResettingPlugin(true); + resetState(); + + try { + await PluginState.resetPlugin(); + } catch (e) { + // this should rarely, if ever happen, but we should handle the case nevertheless + setPluginResetError('There was an error resetting your plugin, try again.'); + } + + setResettingPlugin(false); + }, [resetState]); + + const onSuccessfulSetup = useCallback(async () => { + reloadPageWithPluginConfiguredQueryParams(false); + }, []); + + const RemoveConfigButton = useCallback( + () => , + [resettingPlugin, triggerPluginReset] + ); + + let content: React.ReactNode; + + if (checkingIfPluginIsConnected) { + content = ; + } else if (pluginConnectionCheckError || pluginResetError) { + content = ( + <> + + + + ); + } else if (!pluginIsConnected) { + content = ( + + ); + } else { + // plugin is fully connected and synced + content = ; + } + + return ( + <> + Configure DataExporter + {pluginIsConnected ? ( + <> +

+ Plugin is connected! Continue to DataExporter by clicking the{' '} + {/* DataExporter Logo icon over there 👈 */} +

+ + + ) : ( +

This page will help you configure the DataExporter plugin 👋

+ )} + {content} + + ); +}; diff --git a/src/components/PluginConfigPage/index.tsx b/src/components/PluginConfigPage/index.tsx new file mode 100644 index 0000000..8847e9c --- /dev/null +++ b/src/components/PluginConfigPage/index.tsx @@ -0,0 +1 @@ +export * from './PluginConfigPage'; diff --git a/src/components/PluginConfigPage/parts/ConfigurationForm/ConfigurationForm.module.css b/src/components/PluginConfigPage/parts/ConfigurationForm/ConfigurationForm.module.css new file mode 100644 index 0000000..5c2d1cf --- /dev/null +++ b/src/components/PluginConfigPage/parts/ConfigurationForm/ConfigurationForm.module.css @@ -0,0 +1,4 @@ +.info-block { + margin-bottom: 24px; + margin-top: 24px; +} diff --git a/src/components/PluginConfigPage/parts/ConfigurationForm/index.tsx b/src/components/PluginConfigPage/parts/ConfigurationForm/index.tsx new file mode 100644 index 0000000..546f2a4 --- /dev/null +++ b/src/components/PluginConfigPage/parts/ConfigurationForm/index.tsx @@ -0,0 +1,147 @@ +import React, { FC, useCallback, useState } from 'react'; + +import { Button, Field, Form, Input } from '@grafana/ui'; +// import cn from 'classnames/bind'; +import { isEmpty } from 'lodash-es'; +import { SubmitHandler } from 'react-hook-form'; + +import Block from '../../../GBlock/Block'; +import Text from '../../../Text/Text'; +import PluginState from '../../../../plugin_state'; +import { css } from '@emotion/css'; + +// import styles from './ConfigurationForm.module.css'; + +// const cx = cn.bind(styles); + +type Props = { + onSuccessfulSetup: () => void; + defaultDataExporterApiUrl: string; +}; + +type FormProps = { + dataExporterApiUrl: string; +}; + +/** + * https://stackoverflow.com/a/43467144 + */ +const isValidUrl = (url: string): boolean => { + try { + new URL(url); + return true; + } catch (_) { + return false; + } +}; + +const FormErrorMessage: FC<{ errorMsg: string }> = ({ errorMsg }) => ( + <> +
+      {errorMsg}
+    
+ + + Need help? +
- Reach out to the OnCall team in the{' '} + + #grafana-oncall + {' '} + community Slack channel +
- Ask questions on our GitHub Discussions page{' '} + + here + {' '} +
- Or file bugs on our GitHub Issues page{' '} + + here + +
+
+ +); + +const ConfigurationForm: FC = ({ onSuccessfulSetup, defaultDataExporterApiUrl }) => { + const [setupErrorMsg, setSetupErrorMsg] = useState(null); + const [formLoading, setFormLoading] = useState(false); + + const setupPlugin: SubmitHandler = useCallback(async ({ dataExporterApiUrl }) => { + setFormLoading(true); + + const errorMsg = await PluginState.installPlugin(dataExporterApiUrl); + + if (!errorMsg) { + onSuccessfulSetup(); + } else { + setSetupErrorMsg(errorMsg); + setFormLoading(false); + } + }, []); + + return ( + + defaultValues={{ dataExporterApiUrl: defaultDataExporterApiUrl }} + onSubmit={setupPlugin} + data-testid="plugin-configuration-form" + > + {({ register, errors }) => ( + <> +
+

1. Launch the OnCall backend

+ + Run hobby, dev or production backend. See{' '} + + here + {' '} + on how to get started. + +
+ +
+

2. Let us know the base URL of your OnCall API

+ + The OnCall backend must be reachable from your Grafana installation. Some examples are: +
+ - http://host.docker.internal:8080 +
- http://localhost:8080 +
+
+ + + + + + {setupErrorMsg && } + + + + )} + + ); +}; + +export default ConfigurationForm; diff --git a/src/components/PluginConfigPage/parts/RemoveCurrentConfigurationButton/RemoveCurrentConfigurationButton.test.tsx b/src/components/PluginConfigPage/parts/RemoveCurrentConfigurationButton/RemoveCurrentConfigurationButton.test.tsx new file mode 100644 index 0000000..3c1925c --- /dev/null +++ b/src/components/PluginConfigPage/parts/RemoveCurrentConfigurationButton/RemoveCurrentConfigurationButton.test.tsx @@ -0,0 +1,32 @@ +import React from 'react'; + +import { render, screen } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; + +import RemoveCurrentConfigurationButton from '.'; + +describe('RemoveCurrentConfigurationButton', () => { + test('It renders properly when enabled', () => { + const component = render( {}} disabled={false} />); + expect(component.baseElement).toMatchSnapshot(); + }); + + test('It renders properly when disabled', () => { + const component = render( {}} disabled />); + expect(component.baseElement).toMatchSnapshot(); + }); + + test('It calls the onClick handler when clicked', async () => { + const mockedOnClick = jest.fn(); + + render(); + + // click the button, which opens the modal + await userEvent.click(screen.getByRole('button')); + // click the confirm button within the modal, which actually triggers the callback + await userEvent.click(screen.getByText('Remove')); + + expect(mockedOnClick).toHaveBeenCalledWith(); + expect(mockedOnClick).toHaveBeenCalledTimes(1); + }); +}); diff --git a/src/components/PluginConfigPage/parts/RemoveCurrentConfigurationButton/index.tsx b/src/components/PluginConfigPage/parts/RemoveCurrentConfigurationButton/index.tsx new file mode 100644 index 0000000..28a65dd --- /dev/null +++ b/src/components/PluginConfigPage/parts/RemoveCurrentConfigurationButton/index.tsx @@ -0,0 +1,20 @@ +import React, { FC } from 'react'; + +import { Button } from '@grafana/ui'; + +import WithConfirm from '../../../WithConfirm/WithConfirm'; + +type Props = { + disabled: boolean; + onClick: () => void; +}; + +const RemoveCurrentConfigurationButton: FC = ({ disabled, onClick }) => ( + + + +); + +export default RemoveCurrentConfigurationButton; diff --git a/src/components/PluginConfigPage/parts/StatusMessageBlock/StatusMessageBlock.test.tsx b/src/components/PluginConfigPage/parts/StatusMessageBlock/StatusMessageBlock.test.tsx new file mode 100644 index 0000000..15c05f3 --- /dev/null +++ b/src/components/PluginConfigPage/parts/StatusMessageBlock/StatusMessageBlock.test.tsx @@ -0,0 +1,12 @@ +import React from 'react'; + +import { render } from '@testing-library/react'; + +import StatusMessageBlock from '.'; + +describe('StatusMessageBlock', () => { + test('It renders properly', async () => { + const component = render(); + expect(component.baseElement).toMatchSnapshot(); + }); +}); diff --git a/src/components/PluginConfigPage/parts/StatusMessageBlock/index.tsx b/src/components/PluginConfigPage/parts/StatusMessageBlock/index.tsx new file mode 100644 index 0000000..ac8427b --- /dev/null +++ b/src/components/PluginConfigPage/parts/StatusMessageBlock/index.tsx @@ -0,0 +1,15 @@ +import React, { FC } from 'react'; + +import Text from '../../../Text/Text'; + +type Props = { + text: string; +}; + +const StatusMessageBlock: FC = ({ text }) => ( +
+    {text}
+  
+); + +export default StatusMessageBlock; diff --git a/src/components/Text/Text.module.scss b/src/components/Text/Text.module.scss new file mode 100644 index 0000000..618bb29 --- /dev/null +++ b/src/components/Text/Text.module.scss @@ -0,0 +1,72 @@ +.root { + display: inline; +} + +.text { + &--primary { + color: var(--primary-text-color); + } + + &--secondary { + color: var(--secondary-text-color); + } + + &--disabled { + color: var(--disabled-text-color); + } + + &--warning { + color: var(--warning-text-color); + } + + &--link { + color: var(--primary-text-link); + } + + &--success { + color: var(--green-5); + } + + &--strong { + font-weight: bold; + } + + &--underline { + text-decoration: underline; + } + + &--small { + font-size: 12px; + } + + &--large { + font-size: 20px; + } +} + +.no-wrap { + white-space: nowrap; +} + +.keyboard { + margin: 0 0.2em; + padding: 0.15em 0.4em 0.1em; + font-size: 90%; + background: hsla(0, 0%, 58.8%, 0.06); + border: solid hsla(0, 0%, 39.2%, 0.2); + border-width: 1px 1px 2px; + border-radius: 3px; +} + +.title { + margin: 0; +} + +.icon-button { + margin-left: 4px; + display: none; +} + +.root:hover .icon-button { + display: inline-block; +} diff --git a/src/components/Text/Text.tsx b/src/components/Text/Text.tsx new file mode 100644 index 0000000..c6fcf46 --- /dev/null +++ b/src/components/Text/Text.tsx @@ -0,0 +1,164 @@ +import React, { FC, HTMLAttributes, ChangeEvent, useState, useCallback } from 'react'; + +import { IconButton, Modal, Input, HorizontalGroup, Button, VerticalGroup } from '@grafana/ui'; +import CopyToClipboard from 'react-copy-to-clipboard'; + +import { openNotification } from '../../utils'; + +// import './Text.module.scss'; +import { css } from '@emotion/css'; + +export type TextType = 'primary' | 'secondary' | 'disabled' | 'link' | 'success' | 'warning'; + +interface TextProps extends HTMLAttributes { + type?: TextType; + strong?: boolean; + underline?: boolean; + size?: 'small' | 'medium' | 'large'; + keyboard?: boolean; + className?: string; + wrap?: boolean; + copyable?: boolean; + editable?: boolean; + onTextChange?: (value?: string) => void; + clearBeforeEdit?: boolean; + hidden?: boolean; + editModalTitle?: string; +} + +interface TextInterface extends React.FC { + Title: React.FC; +} + +const PLACEHOLDER = '**********'; + +const Text: TextInterface = (props) => { + const { + type, + size = 'medium', + strong = false, + underline = false, + children, + onClick, + keyboard = false, + className, + wrap = true, + copyable = false, + editable = false, + onTextChange, + clearBeforeEdit = false, + hidden = false, + editModalTitle = 'New value', + style, + } = props; + + const [isEditMode, setIsEditMode] = useState(false); + const [value, setValue] = useState(); + + const handleEditClick = useCallback(() => { + setValue(clearBeforeEdit || hidden ? '' : (children as string)); + + setIsEditMode(true); + }, [clearBeforeEdit, hidden, children]); + + const handleCancelEdit = useCallback(() => { + setIsEditMode(false); + }, []); + + const handleConfirmEdit = useCallback(() => { + setIsEditMode(false); + //@ts-ignore + onTextChange(value); + }, [value, onTextChange]); + + const handleInputChange = useCallback((e: ChangeEvent) => { + setValue(e.target.value); + }, []); + + return ( + + {hidden ? PLACEHOLDER : children} + {editable && ( + + )} + {copyable && ( + { + openNotification('Text copied'); + }} + > + + + )} + {isEditMode && ( + + + { + if (node) { + node.focus(); + } + }} + value={value} + onChange={handleInputChange} + /> + + + + + + + )} + + ); +}; + +interface TitleProps extends TextProps { + level: 1 | 2 | 3 | 4 | 5 | 6; +} + +const Title: FC = (props) => { + const { level, className, style, ...restProps } = props; + // @ts-ignore + const Tag: keyof JSX.IntrinsicElements = `h${level}`; + + return ( + + + + ); +}; + +Text.Title = Title; + +export default Text; diff --git a/src/components/WithConfirm/WithConfirm.tsx b/src/components/WithConfirm/WithConfirm.tsx new file mode 100644 index 0000000..f76a875 --- /dev/null +++ b/src/components/WithConfirm/WithConfirm.tsx @@ -0,0 +1,55 @@ +import React, { ReactElement, useCallback, useState } from 'react'; + +import { ConfirmModal } from '@grafana/ui'; + +interface WithConfirmProps { + children: ReactElement; + title?: string; + body?: React.ReactNode; + confirmText?: string; + disabled?: boolean; +} + +const WithConfirm = (props: WithConfirmProps) => { + const { children, title = 'Are you sure to delete?', body, confirmText = 'Delete', disabled } = props; + + const [showConfirmation, setShowConfirmation] = useState(false); + + const onClickCallback = useCallback((event: any) => { + event.stopPropagation(); + + setShowConfirmation(true); + }, []); + + const onConfirmCallback = useCallback(() => { + if (children.props.onClick) { + children.props.onClick(); + } + + setShowConfirmation(false); + }, [children]); + + return ( + <> + {showConfirmation && ( + { + setShowConfirmation(false); + }} + /> + )} + {React.cloneElement(children, { + disabled: children.props.disabled || disabled, + onClick: onClickCallback, + })} + + ); +}; + +export default WithConfirm; diff --git a/src/module.ts b/src/module.ts index f58d46f..9005550 100644 --- a/src/module.ts +++ b/src/module.ts @@ -1,12 +1,12 @@ import { AppPlugin } from '@grafana/data'; import { App } from './components/App'; -import { AppConfig } from './components/AppConfig'; +import { PluginConfigPage } from './components/PluginConfigPage'; export const plugin = new AppPlugin<{}>().setRootPage(App).addConfigPage({ title: 'Configuration', icon: 'fa fa-cog', // @ts-ignore - Would expect a Class component, however works absolutely fine with a functional one // Implementation: https://github.com/grafana/grafana/blob/fd44c01675e54973370969dfb9e78f173aff7910/public/app/features/plugins/PluginPage.tsx#L157 - body: AppConfig, + body: PluginConfigPage, id: 'configuration', }); diff --git a/src/plugin_state.ts b/src/plugin_state.ts new file mode 100644 index 0000000..b8f00fb --- /dev/null +++ b/src/plugin_state.ts @@ -0,0 +1,189 @@ +import { makeRequest } from './services/network_service'; +import { + DataExporterAppPluginMeta, + DataExporterPluginMetaJSONData, + DataExporterPluginMetaSecureJSONData, +} from './types'; + +import { getBackendSrv } from '@grafana/runtime'; + +import axios from 'axios'; + +export type UpdateGrafanaPluginSettingsProps = { + jsonData?: Partial; + secureJsonData?: Partial; +}; + +type InstallPluginResponse = Pick< + DataExporterPluginMetaSecureJSONData, + 'grafanaToken' +> & { + dataExporterAPIResponse: DataExporterAPIResponse; +}; + +type PluginConnectedStatusResponse = string; + +class PluginState { + static DATA_EXPORTER_BASE_URL = '/plugin'; + static GRAFANA_PLUGIN_SETTINGS_URL = '/api/plugins/corpglory-dataexporter-app/settings'; + static grafanaBackend = getBackendSrv(); + + static generateInvalidDataExporterApiURLErrorMsg = (dataExporterApiUrl: string): string => + `Could not communicate with your DataExporter API at ${dataExporterApiUrl}.\nValidate that the URL is correct, your DataExporter API is running, and that it is accessible from your Grafana instance.`; + + static generateUnknownErrorMsg = (dataExporterApiUrl: string): string => + `An unknown error occured when trying to install the plugin. Are you sure that your DataExporter API URL, ${dataExporterApiUrl}, is correct?\nRefresh your page and try again, or try removing your plugin configuration and reconfiguring.`; + + static getHumanReadableErrorFromDataExporterError = (e: any, dataExporterApiUrl: string): string => { + let errorMsg: string; + const unknownErrorMsg = this.generateUnknownErrorMsg(dataExporterApiUrl); + const consoleMsg = `occured while trying to install the plugin w/ the DataExporter backend`; + + if (axios.isAxiosError(e)) { + const statusCode = e.response?.status; + + console.warn(`An HTTP related error ${consoleMsg}`, e.response); + + if (statusCode === 502) { + // 502 occurs when the plugin-proxy cannot communicate w/ the DataExporter API using the provided URL + errorMsg = this.generateInvalidDataExporterApiURLErrorMsg(dataExporterApiUrl); + } else if (statusCode === 400) { + /** + * A 400 is 'bubbled-up' from the DataExporter API. It indicates one of three cases: + * 1. there is a communication error when DataExporter API tries to contact Grafana's API + * 2. there is an auth error when DataExporter API tries to contact Grafana's API + * 3. (likely rare) user inputs an DataExporterApiUrl that is not RFC 1034/1035 compliant + * + * Check if the response body has an 'error' JSON attribute, if it does, assume scenario 1 or 2 + * Use the error message provided to give the user more context/helpful debugging information + */ + errorMsg = e.response?.data?.error || unknownErrorMsg; + } else { + // this scenario shouldn't occur.. + errorMsg = unknownErrorMsg; + } + } else { + // a non-axios related error occured.. this scenario shouldn't occur... + console.warn(`An unknown error ${consoleMsg}`, e); + errorMsg = unknownErrorMsg; + } + return errorMsg; + }; + + static getHumanReadableErrorFromGrafanaProvisioningError = (e: any, dataExporterApiUrl: string): string => { + let errorMsg: string; + + if (axios.isAxiosError(e)) { + // The user likely put in a bogus URL for the DataExporter API URL + console.warn('An HTTP related error occured while trying to provision the plugin w/ Grafana', e.response); + errorMsg = this.generateInvalidDataExporterApiURLErrorMsg(dataExporterApiUrl); + } else { + // a non-axios related error occured.. this scenario shouldn't occur... + console.warn('An unknown error occured while trying to provision the plugin w/ Grafana', e); + errorMsg = this.generateUnknownErrorMsg(dataExporterApiUrl); + } + return errorMsg; + }; + + static getGrafanaPluginSettings = async (): Promise => + this.grafanaBackend.get(this.GRAFANA_PLUGIN_SETTINGS_URL); + + static updateGrafanaPluginSettings = async (data: UpdateGrafanaPluginSettingsProps, enabled = true) => + this.grafanaBackend.post(this.GRAFANA_PLUGIN_SETTINGS_URL, { ...data, enabled, pinned: true }); + + static createGrafanaToken = async () => { + const baseUrl = '/api/auth/keys'; + const keys = await this.grafanaBackend.get(baseUrl); + const existingKey = keys.find((key: { id: number; name: string; role: string }) => key.name === 'DataExporter'); + + if (existingKey) { + await this.grafanaBackend.delete(`${baseUrl}/${existingKey.id}`); + } + + return await this.grafanaBackend.post(baseUrl, { + name: 'DataExporter', + role: 'Admin', + secondsToLive: null, + }); + }; + + static timeout = (pollCount: number) => new Promise((resolve) => setTimeout(resolve, 10 * 2 ** pollCount)); + + static connectBackend = async (): Promise> => { + const { key: grafanaToken } = await this.createGrafanaToken(); + await this.updateGrafanaPluginSettings({ secureJsonData: { grafanaToken } }); + const dataExporterAPIResponse = await makeRequest(`${this.DATA_EXPORTER_BASE_URL}/connect`, { + method: 'POST', + }); + return { grafanaToken, dataExporterAPIResponse }; + }; + + static installPlugin = async (dataExporterApiUrl: string): Promise => { + let pluginInstallationDataExporterResponse: InstallPluginResponse; + + // Step 1. Try provisioning the plugin w/ the Grafana API + try { + await this.updateGrafanaPluginSettings({ jsonData: { dataExporterApiUrl } }); + } catch (e) { + return this.getHumanReadableErrorFromGrafanaProvisioningError(e, dataExporterApiUrl); + } + + /** + * Step 2: + * - Create a grafana token + * - store that token in the Grafana plugin settings + * - configure the plugin in DataExporter's backend + */ + try { + pluginInstallationDataExporterResponse = await this.connectBackend(); + } catch (e) { + return this.getHumanReadableErrorFromDataExporterError(e, dataExporterApiUrl); + } + + // Step 3. reprovision the Grafana plugin settings, storing information that we get back from DataExporter's backend + try { + const { grafanaToken } = pluginInstallationDataExporterResponse; + + await this.updateGrafanaPluginSettings({ + jsonData: { + dataExporterApiUrl, + }, + secureJsonData: { + grafanaToken, + }, + }); + } catch (e) { + return this.getHumanReadableErrorFromGrafanaProvisioningError(e, dataExporterApiUrl); + } + + return null; + }; + + static checkIfPluginIsConnected = async (DataExporterApiUrl: string): Promise => { + try { + return await makeRequest(`${this.DATA_EXPORTER_BASE_URL}/status`, { + method: 'GET', + }); + } catch (e) { + return this.getHumanReadableErrorFromDataExporterError(e, DataExporterApiUrl); + } + }; + + static resetPlugin = (): Promise => { + /** + * mark both of these objects as Required.. this will ensure that we are resetting every attribute back to null + * and throw a type error in the event that DataExporterPluginMetaJSONData or DataExporterPluginMetaSecureJSONData is updated + * but we forget to add the attribute here + */ + const jsonData: Required = { + dataExporterApiUrl: null, + }; + const secureJsonData: Required = { + grafanaToken: null, + }; + + return this.updateGrafanaPluginSettings({ jsonData, secureJsonData }, false); + }; +} + +export default PluginState; diff --git a/src/services/network_service.ts b/src/services/network_service.ts new file mode 100644 index 0000000..6eb40c1 --- /dev/null +++ b/src/services/network_service.ts @@ -0,0 +1,30 @@ +import axios from 'axios'; + +export const API_HOST = `${window.location.protocol}//${window.location.host}/`; +export const API_PROXY_PREFIX = 'api/plugin-proxy/corpglory-dataexporter-app'; + +const instance = axios.create(); + +interface RequestConfig { + method?: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'OPTIONS'; + params?: any; + data?: any; + withCredentials?: boolean; + validateStatus?: (status: number) => boolean; +} + +export const makeRequest = async (path: string, config: RequestConfig) => { + const { method = 'GET', params, data, validateStatus } = config; + + const url = `${API_PROXY_PREFIX}${path}`; + + const response = await instance({ + method, + url, + params, + data, + validateStatus, + }); + + return response.data as RT; +}; diff --git a/src/types.ts b/src/types.ts new file mode 100644 index 0000000..a648e0c --- /dev/null +++ b/src/types.ts @@ -0,0 +1,16 @@ +import { AppRootProps as BaseAppRootProps, AppPluginMeta, PluginConfigPageProps } from '@grafana/data'; + +export type DataExporterPluginMetaJSONData = { + dataExporterApiUrl: string | null; +}; + +export type DataExporterPluginMetaSecureJSONData = { + grafanaToken: string | null; +}; + +export type AppRootProps = BaseAppRootProps; + +// NOTE: it is possible that plugin.meta.jsonData is null (ex. on first-ever setup) +// the typing on AppPluginMeta does not seem correct atm.. +export type DataExporterAppPluginMeta = AppPluginMeta; +export type DataExporterPluginConfigPageProps = PluginConfigPageProps; diff --git a/src/utils/index.ts b/src/utils/index.ts new file mode 100644 index 0000000..32d5f31 --- /dev/null +++ b/src/utils/index.ts @@ -0,0 +1,7 @@ +import { AppEvents } from '@grafana/data'; +// @ts-ignore +import appEvents from 'grafana/app/core/app_events'; + +export function openNotification(message: React.ReactNode) { + appEvents.emit(AppEvents.alertSuccess, [message]); +} diff --git a/yarn.lock b/yarn.lock index b93b9c2..3b9b6a8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -29,11 +29,16 @@ dependencies: "@babel/highlight" "^7.18.6" -"@babel/compat-data@^7.17.7", "@babel/compat-data@^7.18.8", "@babel/compat-data@^7.19.3": +"@babel/compat-data@^7.17.7", "@babel/compat-data@^7.19.3": version "7.19.3" resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.19.3.tgz#707b939793f867f5a73b2666e6d9a3396eb03151" integrity sha512-prBHMK4JYYK+wDjJF1q99KK4JLL+egWS4nmNqdlMUgCExMZ+iZW0hGhyC3VEbsPjvaN0TBhW//VIFwBrk8sEiw== +"@babel/compat-data@^7.18.8", "@babel/compat-data@^7.20.0", "@babel/compat-data@^7.20.1": + version "7.20.5" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.20.5.tgz#86f172690b093373a933223b4745deeb6049e733" + integrity sha512-KZXo2t10+/jxmkhNXc7pZTqRvSOIvVv/+lJwHS+B2rErwOyjuVRh60yVpb7liQ1U5t7lLJ1bz+t8tSypUZdm0g== + "@babel/core@7.18.9": version "7.18.9" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.18.9.tgz#805461f967c77ff46c74ca0460ccf4fe933ddd59" @@ -76,7 +81,16 @@ json5 "^2.2.1" semver "^6.3.0" -"@babel/generator@^7.18.9", "@babel/generator@^7.19.3", "@babel/generator@^7.7.2": +"@babel/generator@^7.18.9", "@babel/generator@^7.20.5": + version "7.20.5" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.20.5.tgz#cb25abee3178adf58d6814b68517c62bdbfdda95" + integrity sha512-jl7JY2Ykn9S0yj4DQP82sYvPU+T3g0HFcWTqDLqiuA9tGRNIj9VfbtXGAYTTkyNEnQk1jkMGOdYka8aG/lulCA== + dependencies: + "@babel/types" "^7.20.5" + "@jridgewell/gen-mapping" "^0.3.2" + jsesc "^2.5.1" + +"@babel/generator@^7.19.3", "@babel/generator@^7.7.2": version "7.19.3" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.19.3.tgz#d7f4d1300485b4547cb6f94b27d10d237b42bf59" integrity sha512-fqVZnmp1ncvZU757UzDheKZpfPgatqY59XtW2/j/18H7u76akb8xqvjw82f+i2UKd/ksYsSick/BCLQUUtJ/qQ== @@ -100,7 +114,7 @@ "@babel/helper-explode-assignable-expression" "^7.18.6" "@babel/types" "^7.18.9" -"@babel/helper-compilation-targets@^7.17.7", "@babel/helper-compilation-targets@^7.18.9", "@babel/helper-compilation-targets@^7.19.0", "@babel/helper-compilation-targets@^7.19.3": +"@babel/helper-compilation-targets@^7.17.7", "@babel/helper-compilation-targets@^7.18.9", "@babel/helper-compilation-targets@^7.19.3": version "7.19.3" resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.19.3.tgz#a10a04588125675d7c7ae299af86fa1b2ee038ca" integrity sha512-65ESqLGyGmLvgR0mst5AdW1FkNlj9rQsCKduzEoEPhBCDFGXvz2jW6bXFG6i0/MrV2s7hhXjjb2yAzcPuQlLwg== @@ -110,6 +124,16 @@ browserslist "^4.21.3" semver "^6.3.0" +"@babel/helper-compilation-targets@^7.20.0": + version "7.20.0" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.0.tgz#6bf5374d424e1b3922822f1d9bdaa43b1a139d0a" + integrity sha512-0jp//vDGp9e8hZzBc6N/KwA5ZK3Wsm/pfm4CrY7vzegkVxc65SgSn6wYOnwHe9Js9HRQ1YTCKLGPzDtaS3RoLQ== + dependencies: + "@babel/compat-data" "^7.20.0" + "@babel/helper-validator-option" "^7.18.6" + browserslist "^4.21.3" + semver "^6.3.0" + "@babel/helper-create-class-features-plugin@^7.18.6": version "7.19.0" resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.19.0.tgz#bfd6904620df4e46470bae4850d66be1054c404b" @@ -123,7 +147,7 @@ "@babel/helper-replace-supers" "^7.18.9" "@babel/helper-split-export-declaration" "^7.18.6" -"@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.19.0": +"@babel/helper-create-regexp-features-plugin@^7.18.6": version "7.19.0" resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.19.0.tgz#7976aca61c0984202baca73d84e2337a5424a41b" integrity sha512-htnV+mHX32DF81amCDrwIDr8nrp1PTm+3wfBN9/v8QJOLEioOCOG7qNyq0nHeFiWbT3Eb7gsPwEmV64UCQ1jzw== @@ -131,6 +155,14 @@ "@babel/helper-annotate-as-pure" "^7.18.6" regexpu-core "^5.1.0" +"@babel/helper-create-regexp-features-plugin@^7.20.5": + version "7.20.5" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.20.5.tgz#5ea79b59962a09ec2acf20a963a01ab4d076ccca" + integrity sha512-m68B1lkg3XDGX5yCvGO0kPx3v9WIYLnzjKfPcQiwntEQa5ZeRkPmo2X/ISJc8qxWGfwUr+kvZAeEzAwLec2r2w== + dependencies: + "@babel/helper-annotate-as-pure" "^7.18.6" + regexpu-core "^5.2.1" + "@babel/helper-define-polyfill-provider@^0.3.1", "@babel/helper-define-polyfill-provider@^0.3.2", "@babel/helper-define-polyfill-provider@^0.3.3": version "0.3.3" resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz#8612e55be5d51f0cd1f36b4a5a83924e89884b7a" @@ -184,7 +216,7 @@ dependencies: "@babel/types" "^7.18.6" -"@babel/helper-module-transforms@^7.18.6", "@babel/helper-module-transforms@^7.18.9", "@babel/helper-module-transforms@^7.19.0": +"@babel/helper-module-transforms@^7.18.6", "@babel/helper-module-transforms@^7.19.0": version "7.19.0" resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.19.0.tgz#309b230f04e22c58c6a2c0c0c7e50b216d350c30" integrity sha512-3HBZ377Fe14RbLIA+ac3sY4PTgpxHVkFrESaWhoI5PuyXPBBX8+C34qblV9G89ZtycGJCmCI/Ut+VUDK4bltNQ== @@ -198,6 +230,20 @@ "@babel/traverse" "^7.19.0" "@babel/types" "^7.19.0" +"@babel/helper-module-transforms@^7.18.9", "@babel/helper-module-transforms@^7.19.6": + version "7.20.2" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.20.2.tgz#ac53da669501edd37e658602a21ba14c08748712" + integrity sha512-zvBKyJXRbmK07XhMuujYoJ48B5yvvmM6+wcpv6Ivj4Yg6qO7NOZOSnvZN9CRl1zz1Z4cKf8YejmCMh8clOoOeA== + dependencies: + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-module-imports" "^7.18.6" + "@babel/helper-simple-access" "^7.20.2" + "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/helper-validator-identifier" "^7.19.1" + "@babel/template" "^7.18.10" + "@babel/traverse" "^7.20.1" + "@babel/types" "^7.20.2" + "@babel/helper-optimise-call-expression@^7.18.6": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz#9369aa943ee7da47edab2cb4e838acf09d290ffe" @@ -210,6 +256,11 @@ resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.19.0.tgz#4796bb14961521f0f8715990bee2fb6e51ce21bf" integrity sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw== +"@babel/helper-plugin-utils@^7.20.2": + version "7.20.2" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz#d1b9000752b18d0877cff85a5c376ce5c3121629" + integrity sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ== + "@babel/helper-remap-async-to-generator@^7.18.6", "@babel/helper-remap-async-to-generator@^7.18.9": version "7.18.9" resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz#997458a0e3357080e54e1d79ec347f8a8cd28519" @@ -220,7 +271,7 @@ "@babel/helper-wrap-function" "^7.18.9" "@babel/types" "^7.18.9" -"@babel/helper-replace-supers@^7.18.6", "@babel/helper-replace-supers@^7.18.9": +"@babel/helper-replace-supers@^7.18.6", "@babel/helper-replace-supers@^7.18.9", "@babel/helper-replace-supers@^7.19.1": version "7.19.1" resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.19.1.tgz#e1592a9b4b368aa6bdb8784a711e0bcbf0612b78" integrity sha512-T7ahH7wV0Hfs46SFh5Jz3s0B6+o8g3c+7TMxu7xKfmHikg7EAZ3I2Qk9LFhjxXq8sL7UkP5JflezNwoZa8WvWw== @@ -238,6 +289,13 @@ dependencies: "@babel/types" "^7.18.6" +"@babel/helper-simple-access@^7.20.2": + version "7.20.2" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz#0ab452687fe0c2cfb1e2b9e0015de07fc2d62dd9" + integrity sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA== + dependencies: + "@babel/types" "^7.20.2" + "@babel/helper-skip-transparent-expression-wrappers@^7.18.9": version "7.18.9" resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.18.9.tgz#778d87b3a758d90b471e7b9918f34a9a02eb5818" @@ -257,6 +315,11 @@ resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.18.10.tgz#181f22d28ebe1b3857fa575f5c290b1aaf659b56" integrity sha512-XtIfWmeNY3i4t7t4D2t02q50HvqHybPqW2ki1kosnvWCwuCMeo81Jf0gwr85jy/neUdg5XDdeFE/80DXiO+njw== +"@babel/helper-string-parser@^7.19.4": + version "7.19.4" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz#38d3acb654b4701a9b77fb0615a96f775c3a9e63" + integrity sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw== + "@babel/helper-validator-identifier@^7.18.6", "@babel/helper-validator-identifier@^7.19.1": version "7.19.1" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz#7eea834cf32901ffdc1a7ee555e2f9c27e249ca2" @@ -277,7 +340,16 @@ "@babel/traverse" "^7.19.0" "@babel/types" "^7.19.0" -"@babel/helpers@^7.18.9", "@babel/helpers@^7.19.0": +"@babel/helpers@^7.18.9": + version "7.20.6" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.20.6.tgz#e64778046b70e04779dfbdf924e7ebb45992c763" + integrity sha512-Pf/OjgfgFRW5bApskEz5pvidpim7tEDPlFtKcNRXWmfHGn9IEI2W2flqRQXTFb7gIPTyK++N6rVHuwKut4XK6w== + dependencies: + "@babel/template" "^7.18.10" + "@babel/traverse" "^7.20.5" + "@babel/types" "^7.20.5" + +"@babel/helpers@^7.19.0": version "7.19.0" resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.19.0.tgz#f30534657faf246ae96551d88dd31e9d1fa1fc18" integrity sha512-DRBCKGwIEdqY3+rPJgG/dKfQy9+08rHIAJx8q2p+HSWP87s2HCrQmaAMMyMll2kIXKCW0cO1RdQskx15Xakftg== @@ -295,11 +367,16 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.18.10", "@babel/parser@^7.18.9", "@babel/parser@^7.19.3": +"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.18.10", "@babel/parser@^7.19.3": version "7.19.3" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.19.3.tgz#8dd36d17c53ff347f9e55c328710321b49479a9a" integrity sha512-pJ9xOlNWHiy9+FuFP09DEAFbAn4JskgRsVcc169w2xRBC3FRGuQEwjeIMMND9L2zc0iEhO/tGv4Zq+km+hxNpQ== +"@babel/parser@^7.18.9", "@babel/parser@^7.20.5": + version "7.20.5" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.20.5.tgz#7f3c7335fe417665d929f34ae5dceae4c04015e8" + integrity sha512-r27t/cy/m9uKLXQNWWebeCUHgnAZq0CpG1OwKRxzJMP1vpSU4bSIK2hq+/cp0bQxetkXx38n09rNu8jVkcK/zA== + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.18.6": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.18.6.tgz#da5b8f9a580acdfbe53494dba45ea389fb09a4d2" @@ -317,9 +394,9 @@ "@babel/plugin-proposal-optional-chaining" "^7.18.9" "@babel/plugin-proposal-async-generator-functions@^7.18.6": - version "7.19.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.19.1.tgz#34f6f5174b688529342288cd264f80c9ea9fb4a7" - integrity sha512-0yu8vNATgLy4ivqMNBIwb1HebCelqN7YX8SL3FDXORv/RqT0zEEWUCH4GH44JsSrvCu6GqnAdR5EBFAPeNBB4Q== + version "7.20.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.20.1.tgz#352f02baa5d69f4e7529bdac39aaa02d41146af9" + integrity sha512-Gh5rchzSwE4kC+o/6T8waD0WHEQIsDmjltY8WnWRXHUdH8axZhuH86Ov9M72YhJfDrZseQwuuWaaIT/TmePp3g== dependencies: "@babel/helper-environment-visitor" "^7.18.9" "@babel/helper-plugin-utils" "^7.19.0" @@ -392,15 +469,15 @@ "@babel/plugin-syntax-numeric-separator" "^7.10.4" "@babel/plugin-proposal-object-rest-spread@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.18.9.tgz#f9434f6beb2c8cae9dfcf97d2a5941bbbf9ad4e7" - integrity sha512-kDDHQ5rflIeY5xl69CEqGEZ0KY369ehsCIEbTGb4siHG5BE9sga/T0r0OUwyZNLMmZE79E1kbsqAjwFCW4ds6Q== + version "7.20.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.2.tgz#a556f59d555f06961df1e572bb5eca864c84022d" + integrity sha512-Ks6uej9WFK+fvIMesSqbAto5dD8Dz4VuuFvGJFKgIGSkJuRGcrwGECPA1fDgQK3/DbExBJpEkTeYeB8geIFCSQ== dependencies: - "@babel/compat-data" "^7.18.8" - "@babel/helper-compilation-targets" "^7.18.9" - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/compat-data" "^7.20.1" + "@babel/helper-compilation-targets" "^7.20.0" + "@babel/helper-plugin-utils" "^7.20.2" "@babel/plugin-syntax-object-rest-spread" "^7.8.3" - "@babel/plugin-transform-parameters" "^7.18.8" + "@babel/plugin-transform-parameters" "^7.20.1" "@babel/plugin-proposal-optional-catch-binding@^7.18.6": version "7.18.6" @@ -602,24 +679,24 @@ "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-transform-block-scoping@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.18.9.tgz#f9b7e018ac3f373c81452d6ada8bd5a18928926d" - integrity sha512-5sDIJRV1KtQVEbt/EIBwGy4T01uYIo4KRB3VUqzkhrAIOGx7AoctL9+Ux88btY0zXdDyPJ9mW+bg+v+XEkGmtw== + version "7.20.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.20.5.tgz#401215f9dc13dc5262940e2e527c9536b3d7f237" + integrity sha512-WvpEIW9Cbj9ApF3yJCjIEEf1EiNJLtXagOrL5LNWEZOo3jv8pmPoYTSNJQvqej8OavVlgOoOPw6/htGZro6IkA== dependencies: - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-plugin-utils" "^7.20.2" "@babel/plugin-transform-classes@^7.18.9": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.19.0.tgz#0e61ec257fba409c41372175e7c1e606dc79bb20" - integrity sha512-YfeEE9kCjqTS9IitkgfJuxjcEtLUHMqa8yUJ6zdz8vR7hKuo6mOy2C05P0F1tdMmDCeuyidKnlrw/iTppHcr2A== + version "7.20.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.20.2.tgz#c0033cf1916ccf78202d04be4281d161f6709bb2" + integrity sha512-9rbPp0lCVVoagvtEyQKSo5L8oo0nQS/iif+lwlAz29MccX2642vWDlSZK+2T2buxbopotId2ld7zZAzRfz9j1g== dependencies: "@babel/helper-annotate-as-pure" "^7.18.6" - "@babel/helper-compilation-targets" "^7.19.0" + "@babel/helper-compilation-targets" "^7.20.0" "@babel/helper-environment-visitor" "^7.18.9" "@babel/helper-function-name" "^7.19.0" "@babel/helper-optimise-call-expression" "^7.18.6" - "@babel/helper-plugin-utils" "^7.19.0" - "@babel/helper-replace-supers" "^7.18.9" + "@babel/helper-plugin-utils" "^7.20.2" + "@babel/helper-replace-supers" "^7.19.1" "@babel/helper-split-export-declaration" "^7.18.6" globals "^11.1.0" @@ -631,11 +708,11 @@ "@babel/helper-plugin-utils" "^7.18.9" "@babel/plugin-transform-destructuring@^7.18.9": - version "7.18.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.18.13.tgz#9e03bc4a94475d62b7f4114938e6c5c33372cbf5" - integrity sha512-TodpQ29XekIsex2A+YJPj5ax2plkGa8YYY6mFjCohk/IG9IY42Rtuj1FuDeemfg2ipxIFLzPeA83SIBnlhSIow== + version "7.20.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.20.2.tgz#c23741cfa44ddd35f5e53896e88c75331b8b2792" + integrity sha512-mENM+ZHrvEgxLTBXUiQ621rRXZes3KWUv6NdQlrnr1TkWVw+hUjQBZuP2X32qKlrlG2BzgR95gkuCRSkJl8vIw== dependencies: - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-plugin-utils" "^7.20.2" "@babel/plugin-transform-dotall-regex@^7.18.6", "@babel/plugin-transform-dotall-regex@^7.4.4": version "7.18.6" @@ -710,15 +787,14 @@ babel-plugin-dynamic-import-node "^2.3.3" "@babel/plugin-transform-modules-systemjs@^7.18.9": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.19.0.tgz#5f20b471284430f02d9c5059d9b9a16d4b085a1f" - integrity sha512-x9aiR0WXAWmOWsqcsnrzGR+ieaTMVyGyffPVA7F8cXAGt/UxefYv6uSHZLkAFChN5M5Iy1+wjE+xJuPt22H39A== + version "7.19.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.19.6.tgz#59e2a84064b5736a4471b1aa7b13d4431d327e0d" + integrity sha512-fqGLBepcc3kErfR9R3DnVpURmckXP7gj7bAlrTQyBxrigFqszZCkFkcoxzCp2v32XmwXLvbw+8Yq9/b+QqksjQ== dependencies: "@babel/helper-hoist-variables" "^7.18.6" - "@babel/helper-module-transforms" "^7.19.0" + "@babel/helper-module-transforms" "^7.19.6" "@babel/helper-plugin-utils" "^7.19.0" - "@babel/helper-validator-identifier" "^7.18.6" - babel-plugin-dynamic-import-node "^2.3.3" + "@babel/helper-validator-identifier" "^7.19.1" "@babel/plugin-transform-modules-umd@^7.18.6": version "7.18.6" @@ -729,12 +805,12 @@ "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-transform-named-capturing-groups-regex@^7.18.6": - version "7.19.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.19.1.tgz#ec7455bab6cd8fb05c525a94876f435a48128888" - integrity sha512-oWk9l9WItWBQYS4FgXD4Uyy5kq898lvkXpXQxoJEY1RnvPk4R/Dvu2ebXU9q8lP+rlMwUQTFf2Ok6d78ODa0kw== + version "7.20.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.20.5.tgz#626298dd62ea51d452c3be58b285d23195ba69a8" + integrity sha512-mOW4tTzi5iTLnw+78iEq3gr8Aoq4WNRGpmSlrogqaiCBoR1HFhpU4JkpQFOHfeYx3ReVIFWOQJS4aZBRvuZ6mA== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.19.0" - "@babel/helper-plugin-utils" "^7.19.0" + "@babel/helper-create-regexp-features-plugin" "^7.20.5" + "@babel/helper-plugin-utils" "^7.20.2" "@babel/plugin-transform-new-target@^7.18.6": version "7.18.6" @@ -758,6 +834,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.18.6" +"@babel/plugin-transform-parameters@^7.20.1": + version "7.20.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.20.5.tgz#f8f9186c681d10c3de7620c916156d893c8a019e" + integrity sha512-h7plkOmcndIUWXZFLgpbrh2+fXAi47zcUX7IrOQuZdLD0I0KvjJ6cvo3BEcAOsDOcZhVKGJqv07mkSqK0y2isQ== + dependencies: + "@babel/helper-plugin-utils" "^7.20.2" + "@babel/plugin-transform-property-literals@^7.18.6": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.18.6.tgz#e22498903a483448e94e032e9bbb9c5ccbfc93a3" @@ -923,13 +1006,20 @@ "@babel/types" "^7.4.4" esutils "^2.0.2" -"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.10.1", "@babel/runtime@^7.11.1", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.0", "@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5", "@babel/runtime@^7.13.10", "@babel/runtime@^7.15.4", "@babel/runtime@^7.18.3", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": +"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.10.1", "@babel/runtime@^7.11.1", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.0", "@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5", "@babel/runtime@^7.15.4", "@babel/runtime@^7.18.3", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": version "7.19.0" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.19.0.tgz#22b11c037b094d27a8a2504ea4dcff00f50e2259" integrity sha512-eR8Lo9hnDS7tqkO7NsV+mKvCmv5boaXFSZ70DnfhcgiEne8hv9oCEd36Klw74EtizEqLsy4YnW8UWwpBVolHZA== dependencies: regenerator-runtime "^0.13.4" +"@babel/runtime@^7.13.10": + version "7.20.6" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.20.6.tgz#facf4879bfed9b5326326273a64220f099b0fce3" + integrity sha512-Q+8MqP7TiHMWzSfwiJwXCjyf4GYA4Dgw3emg/7xmwsdLJOZUp+nMqcOwOzzYheuM1rhDu8FSj2l0aoMygEuXuA== + dependencies: + regenerator-runtime "^0.13.11" + "@babel/template@^7.18.10", "@babel/template@^7.18.6", "@babel/template@^7.3.3": version "7.18.10" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.18.10.tgz#6f9134835970d1dbf0835c0d100c9f38de0c5e71" @@ -939,7 +1029,23 @@ "@babel/parser" "^7.18.10" "@babel/types" "^7.18.10" -"@babel/traverse@^7.18.9", "@babel/traverse@^7.19.0", "@babel/traverse@^7.19.1", "@babel/traverse@^7.19.3", "@babel/traverse@^7.7.2": +"@babel/traverse@^7.18.9", "@babel/traverse@^7.20.1", "@babel/traverse@^7.20.5": + version "7.20.5" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.20.5.tgz#78eb244bea8270fdda1ef9af22a5d5e5b7e57133" + integrity sha512-WM5ZNN3JITQIq9tFZaw1ojLU3WgWdtkxnhM1AegMS+PvHjkM5IXjmYEGY7yukz5XS4sJyEf2VzWjI8uAavhxBQ== + dependencies: + "@babel/code-frame" "^7.18.6" + "@babel/generator" "^7.20.5" + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-function-name" "^7.19.0" + "@babel/helper-hoist-variables" "^7.18.6" + "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/parser" "^7.20.5" + "@babel/types" "^7.20.5" + debug "^4.1.0" + globals "^11.1.0" + +"@babel/traverse@^7.19.0", "@babel/traverse@^7.19.1", "@babel/traverse@^7.19.3", "@babel/traverse@^7.7.2": version "7.19.3" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.19.3.tgz#3a3c5348d4988ba60884e8494b0592b2f15a04b4" integrity sha512-qh5yf6149zhq2sgIXmwjnsvmnNQC2iw70UFjp4olxucKrWd/dvlUsBI88VSLUsnMNF7/vnOiA+nk1+yLoCqROQ== @@ -964,6 +1070,15 @@ "@babel/helper-validator-identifier" "^7.19.1" to-fast-properties "^2.0.0" +"@babel/types@^7.20.2", "@babel/types@^7.20.5": + version "7.20.5" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.20.5.tgz#e206ae370b5393d94dfd1d04cd687cace53efa84" + integrity sha512-c9fst/h2/dcF7H+MJKZ2T0KjEQ8hY/BNnDk/H3XY8C4Aw/eWQXWn/lWntHF9ooUBnGmEvbfGrTgLWc+um0YDUg== + dependencies: + "@babel/helper-string-parser" "^7.19.4" + "@babel/helper-validator-identifier" "^7.19.1" + to-fast-properties "^2.0.0" + "@bcoe/v8-coverage@^0.2.3": version "0.2.3" resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" @@ -1032,7 +1147,7 @@ resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70" integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw== -"@emotion/babel-plugin@^11.10.0", "@emotion/babel-plugin@^11.7.1": +"@emotion/babel-plugin@^11.10.0": version "11.10.2" resolved "https://registry.yarnpkg.com/@emotion/babel-plugin/-/babel-plugin-11.10.2.tgz#879db80ba622b3f6076917a1e6f648b1c7d008c7" integrity sha512-xNQ57njWTFVfPAc3cjfuaPdsgLp5QOSuRsj9MA6ndEhH/AzuZM86qIQzt6rq+aGBwj3n5/TkLmU5lhAfdRmogA== @@ -1050,7 +1165,25 @@ source-map "^0.5.7" stylis "4.0.13" -"@emotion/cache@^11.10.0", "@emotion/cache@^11.4.0", "@emotion/cache@^11.7.1", "@emotion/cache@^11.9.3": +"@emotion/babel-plugin@^11.7.1": + version "11.10.5" + resolved "https://registry.yarnpkg.com/@emotion/babel-plugin/-/babel-plugin-11.10.5.tgz#65fa6e1790ddc9e23cc22658a4c5dea423c55c3c" + integrity sha512-xE7/hyLHJac7D2Ve9dKroBBZqBT7WuPQmWcq7HSGb84sUuP4mlOWoB8dvVfD9yk5DHkU1m6RW7xSoDtnQHNQeA== + dependencies: + "@babel/helper-module-imports" "^7.16.7" + "@babel/plugin-syntax-jsx" "^7.17.12" + "@babel/runtime" "^7.18.3" + "@emotion/hash" "^0.9.0" + "@emotion/memoize" "^0.8.0" + "@emotion/serialize" "^1.1.1" + babel-plugin-macros "^3.1.0" + convert-source-map "^1.5.0" + escape-string-regexp "^4.0.0" + find-root "^1.1.0" + source-map "^0.5.7" + stylis "4.1.3" + +"@emotion/cache@^11.10.0", "@emotion/cache@^11.4.0": version "11.10.3" resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-11.10.3.tgz#c4f67904fad10c945fea5165c3a5a0583c164b87" integrity sha512-Psmp/7ovAa8appWh3g51goxu/z3iVms7JXOreq136D8Bbn6dYraPnmL6mdM8GThEx9vwSn92Fz+mGSjBzN8UPQ== @@ -1061,6 +1194,17 @@ "@emotion/weak-memoize" "^0.3.0" stylis "4.0.13" +"@emotion/cache@^11.7.1", "@emotion/cache@^11.9.3": + version "11.10.5" + resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-11.10.5.tgz#c142da9351f94e47527ed458f7bbbbe40bb13c12" + integrity sha512-dGYHWyzTdmK+f2+EnIGBpkz1lKc4Zbj2KHd4cX3Wi8/OWr5pKslNjc3yABKH4adRGCvSX4VDC0i04mrrq0aiRA== + dependencies: + "@emotion/memoize" "^0.8.0" + "@emotion/sheet" "^1.2.1" + "@emotion/utils" "^1.2.0" + "@emotion/weak-memoize" "^0.3.0" + stylis "4.1.3" + "@emotion/css@11.9.0": version "11.9.0" resolved "https://registry.yarnpkg.com/@emotion/css/-/css-11.9.0.tgz#d5aeaca5ed19fc61cbdc9e032ad0b32fa6e366be" @@ -1120,7 +1264,18 @@ "@emotion/weak-memoize" "^0.3.0" hoist-non-react-statics "^3.3.1" -"@emotion/serialize@^1.0.3", "@emotion/serialize@^1.0.4", "@emotion/serialize@^1.1.0": +"@emotion/serialize@^1.0.3", "@emotion/serialize@^1.0.4", "@emotion/serialize@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-1.1.1.tgz#0595701b1902feded8a96d293b26be3f5c1a5cf0" + integrity sha512-Zl/0LFggN7+L1liljxXdsVSVlg6E/Z/olVWpfxUTxOAmi8NU7YoeWeLfi1RmnB2TATHoaWwIBRoL+FvAJiTUQA== + dependencies: + "@emotion/hash" "^0.9.0" + "@emotion/memoize" "^0.8.0" + "@emotion/unitless" "^0.8.0" + "@emotion/utils" "^1.2.0" + csstype "^3.0.2" + +"@emotion/serialize@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-1.1.0.tgz#b1f97b1011b09346a40e9796c37a3397b4ea8ea8" integrity sha512-F1ZZZW51T/fx+wKbVlwsfchr5q97iW8brAnXmsskz4d0hVB4O3M/SiA3SaeH06x02lSNzkkQv+n3AX3kCXKSFA== @@ -1131,7 +1286,12 @@ "@emotion/utils" "^1.2.0" csstype "^3.0.2" -"@emotion/sheet@^1.0.3", "@emotion/sheet@^1.2.0": +"@emotion/sheet@^1.0.3", "@emotion/sheet@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-1.2.1.tgz#0767e0305230e894897cadb6c8df2c51e61a6c2c" + integrity sha512-zxRBwl93sHMsOj4zs+OslQKg/uhF38MB+OMKoCrVuS0nyTkqnau+BM3WGEoOptg9Oz45T/aIGs1qbVAsEFo3nA== + +"@emotion/sheet@^1.2.0": version "1.2.0" resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-1.2.0.tgz#771b1987855839e214fc1741bde43089397f7be5" integrity sha512-OiTkRgpxescko+M51tZsMq7Puu/KP55wMT8BgpcXVG2hqXc0Vo0mfymJ/Uj24Hp0i083ji/o0aLddh08UEjq8w== @@ -1846,11 +2006,16 @@ dependencies: "@opentelemetry/api" "^1.0.0" -"@opentelemetry/api@^1.0.0", "@opentelemetry/api@^1.1.0": +"@opentelemetry/api@^1.0.0": version "1.2.0" resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.2.0.tgz#89ef99401cde6208cff98760b67663726ef26686" integrity sha512-0nBr+VZNKm9tvNDZFstI3Pq1fCTEDK5OZTnVKNvBNAKgd0yIvmwsP4m61rEv7ZP+tOUjWJhROpxK5MsnlF911g== +"@opentelemetry/api@^1.1.0": + version "1.3.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.3.0.tgz#27c6f776ac3c1c616651e506a89f438a0ed6a055" + integrity sha512-YveTnGNsFFixTKJz09Oi4zYkiLT5af3WpZDu4aIUM7xX+2bHAkOJayFTVQd6zB8kkWPpbua4Ha6Ql00grdLlJQ== + "@opentelemetry/core@1.3.1": version "1.3.1" resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-1.3.1.tgz#6eef5c5efca9a4cd7daa0cd4c7ff28ca2317c8d7" @@ -1950,39 +2115,39 @@ "@react-types/shared" "^3.13.1" clsx "^1.1.1" -"@react-aria/focus@^3.6.1", "@react-aria/focus@^3.9.0": - version "3.9.0" - resolved "https://registry.yarnpkg.com/@react-aria/focus/-/focus-3.9.0.tgz#fa4478eebdc3c199a0529470f1d7b36608ef0d10" - integrity sha512-DwesjEjWjFfwAwzv9qeqkyKZNPAYmPa3UrygxzmXeKEg2JpaACGZPxRcmT2EFJFEDbX8daQDEeRGyLO49o5agg== +"@react-aria/focus@^3.10.0", "@react-aria/focus@^3.6.1": + version "3.10.0" + resolved "https://registry.yarnpkg.com/@react-aria/focus/-/focus-3.10.0.tgz#12d85d46f58590a915009e57bddb2d90b56f5836" + integrity sha512-idI7Etgh6y2BYi3X4d+EuUpzR7gPZ94Lf/0UNnVyMkDM9fzcdz/8DCBt0qKOff24HlaLE1rmREt0+iTR/qRgbA== dependencies: "@babel/runtime" "^7.6.2" - "@react-aria/interactions" "^3.12.0" - "@react-aria/utils" "^3.14.0" - "@react-types/shared" "^3.15.0" + "@react-aria/interactions" "^3.13.0" + "@react-aria/utils" "^3.14.1" + "@react-types/shared" "^3.16.0" clsx "^1.1.1" -"@react-aria/i18n@^3.4.1", "@react-aria/i18n@^3.6.1": - version "3.6.1" - resolved "https://registry.yarnpkg.com/@react-aria/i18n/-/i18n-3.6.1.tgz#b97e78e3ec040a5ca08d166033f2d358ef1af4c5" - integrity sha512-kAetWsj9HOqwaqLhmFU2udhZ+4QGGYkQOgGBJYdrB7GfLZQ1GPBlZjv3QFdkX4oSf/k9cFqgftxvVQQDYZLOew== +"@react-aria/i18n@^3.4.1", "@react-aria/i18n@^3.6.2": + version "3.6.2" + resolved "https://registry.yarnpkg.com/@react-aria/i18n/-/i18n-3.6.2.tgz#74fa50f4b13ca7efe7738fd1960732a076ed049d" + integrity sha512-/G22mZQcISX6DcKLBn4j/X53y2SOnFfiD4wOEuY7sIZZDryktd+3I/QHukCnNlf0tKK3PdixQLvWa9Q1RqTSaw== dependencies: "@babel/runtime" "^7.6.2" "@internationalized/date" "^3.0.1" "@internationalized/message" "^3.0.9" "@internationalized/number" "^3.1.1" "@internationalized/string" "^3.0.0" - "@react-aria/ssr" "^3.3.0" - "@react-aria/utils" "^3.14.0" - "@react-types/shared" "^3.15.0" + "@react-aria/ssr" "^3.4.0" + "@react-aria/utils" "^3.14.1" + "@react-types/shared" "^3.16.0" -"@react-aria/interactions@^3.12.0", "@react-aria/interactions@^3.9.1": - version "3.12.0" - resolved "https://registry.yarnpkg.com/@react-aria/interactions/-/interactions-3.12.0.tgz#b16a392c3dc23351c8fd33a16cef0ef93dc4682d" - integrity sha512-KcKurjPZwme9ggvGQjbjqZtZtuyXipTBVMHUah9a3+Dz7vXxhRg5vFaEdM79oQnNsrGFW5xS6SKBehl/JG6BMw== +"@react-aria/interactions@^3.13.0", "@react-aria/interactions@^3.9.1": + version "3.13.0" + resolved "https://registry.yarnpkg.com/@react-aria/interactions/-/interactions-3.13.0.tgz#897ee2b4a7751bcf22c716ceccfc1321f427a8f2" + integrity sha512-gbZL+qs+6FPitR/abAramth4lqz/drEzXwzIDF6p6WyajF805mjyAgZin1/3mQygSE5BwJNDU7jMUSGRvgFyTw== dependencies: "@babel/runtime" "^7.6.2" - "@react-aria/utils" "^3.14.0" - "@react-types/shared" "^3.15.0" + "@react-aria/utils" "^3.14.1" + "@react-types/shared" "^3.16.0" "@react-aria/menu@3.5.1": version "3.5.1" @@ -2020,43 +2185,50 @@ react-transition-group "^4.4.2" "@react-aria/overlays@^3.9.1": - version "3.11.0" - resolved "https://registry.yarnpkg.com/@react-aria/overlays/-/overlays-3.11.0.tgz#9ecab7fbaf88b7c315215d55a3eb1ae1aa5b78f2" - integrity sha512-NqLqxSiEW9AuUPcEHCIp2lHH1moNxlkP0CkuUMkT2/T5MCPm/Iq+uD53VSR+NyeCWU/aGH3ykj2kq9NSITJkOA== + version "3.12.0" + resolved "https://registry.yarnpkg.com/@react-aria/overlays/-/overlays-3.12.0.tgz#66fc930a39771888123c6fd1b246fedd5e76ad89" + integrity sha512-jsGeLTB3W3S5Cf2zDTxh1ODTNkE69miFDOGMB0VLwS1GWDwDvytcTRpBKY9JBrxad+4u0x6evnah7IbJ61qNBA== dependencies: "@babel/runtime" "^7.6.2" - "@react-aria/focus" "^3.9.0" - "@react-aria/i18n" "^3.6.1" - "@react-aria/interactions" "^3.12.0" - "@react-aria/ssr" "^3.3.0" - "@react-aria/utils" "^3.14.0" - "@react-aria/visually-hidden" "^3.5.0" - "@react-stately/overlays" "^3.4.2" - "@react-types/button" "^3.6.2" - "@react-types/overlays" "^3.6.4" - "@react-types/shared" "^3.15.0" + "@react-aria/focus" "^3.10.0" + "@react-aria/i18n" "^3.6.2" + "@react-aria/interactions" "^3.13.0" + "@react-aria/ssr" "^3.4.0" + "@react-aria/utils" "^3.14.1" + "@react-aria/visually-hidden" "^3.6.0" + "@react-stately/overlays" "^3.4.3" + "@react-types/button" "^3.7.0" + "@react-types/overlays" "^3.6.5" + "@react-types/shared" "^3.16.0" "@react-aria/selection@^3.9.1": - version "3.11.0" - resolved "https://registry.yarnpkg.com/@react-aria/selection/-/selection-3.11.0.tgz#5d3457e9ea2a5aae4f8abf799da92c723d04172d" - integrity sha512-2Qcv0PxXqOrYYT1oL+TOaB+lE/jhIPzVEPHVmf8HYzEMP5WBYP8Q+R9no5s8x++b1W0DsbUVwmk9szY48O9Bmw== + version "3.12.0" + resolved "https://registry.yarnpkg.com/@react-aria/selection/-/selection-3.12.0.tgz#895ced39795180094ca79882c54b71441f4466e7" + integrity sha512-Akzx5Faxw+sOZFXLCOw6OddDNFbP5Kho3EP6bYJfd2pzMkBc8/JemC/YDrtIuy8e9x6Je9HHSZqtKjwiEaXWog== dependencies: "@babel/runtime" "^7.6.2" - "@react-aria/focus" "^3.9.0" - "@react-aria/i18n" "^3.6.1" - "@react-aria/interactions" "^3.12.0" - "@react-aria/utils" "^3.14.0" - "@react-stately/collections" "^3.4.4" - "@react-stately/selection" "^3.11.0" - "@react-types/shared" "^3.15.0" - -"@react-aria/ssr@^3.2.0", "@react-aria/ssr@^3.3.0": + "@react-aria/focus" "^3.10.0" + "@react-aria/i18n" "^3.6.2" + "@react-aria/interactions" "^3.13.0" + "@react-aria/utils" "^3.14.1" + "@react-stately/collections" "^3.5.0" + "@react-stately/selection" "^3.11.1" + "@react-types/shared" "^3.16.0" + +"@react-aria/ssr@^3.2.0": version "3.3.0" resolved "https://registry.yarnpkg.com/@react-aria/ssr/-/ssr-3.3.0.tgz#25e81daf0c7a270a4a891159d8d984578e4512d8" integrity sha512-yNqUDuOVZIUGP81R87BJVi/ZUZp/nYOBXbPsRe7oltJOfErQZD+UezMpw4vM2KRz18cURffvmC8tJ6JTeyDtaQ== dependencies: "@babel/runtime" "^7.6.2" +"@react-aria/ssr@^3.4.0": + version "3.4.0" + resolved "https://registry.yarnpkg.com/@react-aria/ssr/-/ssr-3.4.0.tgz#a2b9a170214f56e41d3c4c933d0d8fcffa07a12a" + integrity sha512-qzuGk14/fUyUAoW/EBwgFcuMkVNXJVGlezTgZ1HovpCZ+p9844E7MUFHE7CuzFzPEIkVeqhBNIoIu+VJJ8YCOA== + dependencies: + "@babel/runtime" "^7.6.2" + "@react-aria/utils@3.13.1": version "3.13.1" resolved "https://registry.yarnpkg.com/@react-aria/utils/-/utils-3.13.1.tgz#45557fdc7ae9de057a83014013bf09e54d074c96" @@ -2068,35 +2240,35 @@ "@react-types/shared" "^3.13.1" clsx "^1.1.1" -"@react-aria/utils@^3.13.1", "@react-aria/utils@^3.14.0": - version "3.14.0" - resolved "https://registry.yarnpkg.com/@react-aria/utils/-/utils-3.14.0.tgz#87877e89e959c8b6299da953ec3a7167de2192c3" - integrity sha512-DHgmwNBNEhnb6DEYYAfbt99wprBqJJOBBeIpQ2g3+pxwlw4BZ+v4Qr+rDD0ZibWV0mYzt8zOhZ9StpId7iTF0Q== +"@react-aria/utils@^3.13.1", "@react-aria/utils@^3.14.1": + version "3.14.1" + resolved "https://registry.yarnpkg.com/@react-aria/utils/-/utils-3.14.1.tgz#36aeb077f758f1f325951b1e3376a905217edd84" + integrity sha512-+ynP0YlxN02MHVEBaeuTrIhBsfBYpfJn36pZm2t7ZEFbafH8DPaMGZ70ffYZXAESkWzRULXL3e79DheWOFI1qA== dependencies: "@babel/runtime" "^7.6.2" - "@react-aria/ssr" "^3.3.0" + "@react-aria/ssr" "^3.4.0" "@react-stately/utils" "^3.5.1" - "@react-types/shared" "^3.15.0" + "@react-types/shared" "^3.16.0" clsx "^1.1.1" -"@react-aria/visually-hidden@^3.3.1", "@react-aria/visually-hidden@^3.5.0": - version "3.5.0" - resolved "https://registry.yarnpkg.com/@react-aria/visually-hidden/-/visually-hidden-3.5.0.tgz#aa8669545464cdb6a4b2ba47c9695d1405864a06" - integrity sha512-tF/kCZCGv1yebwgH21cKbhjSV5CmB5/SAHOUM5YkO5V/lIFjaPtywcamIPI8F0JSfrwGF/Z9EqvqBxvIYGRlCA== +"@react-aria/visually-hidden@^3.3.1", "@react-aria/visually-hidden@^3.6.0": + version "3.6.0" + resolved "https://registry.yarnpkg.com/@react-aria/visually-hidden/-/visually-hidden-3.6.0.tgz#cc4dd9e648a5c8b6d8dfbd1f70d8672b36d3f1bc" + integrity sha512-W3Ix5wdlVzh2GY7dytqOAyLCXiHzk3S4jLKSaoiCwPJX9fHE5zMlZwahhDy27V0LXfjmdjBltbwyEZOq4G/Q0w== dependencies: "@babel/runtime" "^7.6.2" - "@react-aria/interactions" "^3.12.0" - "@react-aria/utils" "^3.14.0" - "@react-types/shared" "^3.15.0" + "@react-aria/interactions" "^3.13.0" + "@react-aria/utils" "^3.14.1" + "@react-types/shared" "^3.16.0" clsx "^1.1.1" -"@react-stately/collections@^3.4.1", "@react-stately/collections@^3.4.4": - version "3.4.4" - resolved "https://registry.yarnpkg.com/@react-stately/collections/-/collections-3.4.4.tgz#9df0b690bac0d3a95bc01352937ec74160c6bd29" - integrity sha512-gryUYCe6uzqE0ea5frTwOxOPpx/6Z42PRk7KetOh3ddN3Ts0j8XQP08jP1IB/7BC1QidrkHWvDCqGHxRiEjiIg== +"@react-stately/collections@^3.4.1", "@react-stately/collections@^3.5.0": + version "3.5.0" + resolved "https://registry.yarnpkg.com/@react-stately/collections/-/collections-3.5.0.tgz#01606d4aa12364cc4296cc036e77690e48ec818c" + integrity sha512-3BAMRjJqrka0IGvyK4m3WslqCeiEfQGx7YsXEIgIgMJoLpk6Fi1Eh4CI8coBnl/wcVLiIRMCIvxubwFRWTgzdg== dependencies: "@babel/runtime" "^7.6.2" - "@react-types/shared" "^3.15.0" + "@react-types/shared" "^3.16.0" "@react-stately/menu@3.3.1": version "3.3.1" @@ -2110,55 +2282,55 @@ "@react-types/shared" "^3.13.1" "@react-stately/menu@^3.3.1": - version "3.4.2" - resolved "https://registry.yarnpkg.com/@react-stately/menu/-/menu-3.4.2.tgz#5bb6847c9bf4a6140d561114b5f8709a4df12a51" - integrity sha512-vFC8EloVEcqf6sgiP6ABIkC41ytjoJiGtj7Ws5OS7PvZNyxxDgJr4V0O3Pxd1T0AjlHCloBbojnvoTRwZiSr/A== + version "3.4.3" + resolved "https://registry.yarnpkg.com/@react-stately/menu/-/menu-3.4.3.tgz#65bb3fe29634047d3f6a3024577d3535e00802ae" + integrity sha512-ZWym6XQSLaC5uFUTZl6+mreEgzc8EUG6ElcnvdXYcH4DWUfswhLxCi3IdnG0lusWEi4NcHbZ2prEUxpT8VKqrg== dependencies: "@babel/runtime" "^7.6.2" - "@react-stately/overlays" "^3.4.2" + "@react-stately/overlays" "^3.4.3" "@react-stately/utils" "^3.5.1" - "@react-types/menu" "^3.7.2" - "@react-types/shared" "^3.15.0" + "@react-types/menu" "^3.7.3" + "@react-types/shared" "^3.16.0" -"@react-stately/overlays@^3.3.1", "@react-stately/overlays@^3.4.2": - version "3.4.2" - resolved "https://registry.yarnpkg.com/@react-stately/overlays/-/overlays-3.4.2.tgz#c6df94a65551137075263eeef70beba8b90b52a0" - integrity sha512-UTCnn0aT+JL4ZhYPQYUWHwhmuR2T3vKTFUEZeZN9sTuDCctg08VfGoASJx8qofqkLwYJXeb8D5PMhhTDPiUQPw== +"@react-stately/overlays@^3.3.1", "@react-stately/overlays@^3.4.3": + version "3.4.3" + resolved "https://registry.yarnpkg.com/@react-stately/overlays/-/overlays-3.4.3.tgz#2e935c404c0845ee7a7c6f001ff057d315161a16" + integrity sha512-WZCr3J8hj0cplQki1OVBR3MXg2l9V017h15Y2h+TNduWvnKH0yYOE/XfWviAT4KUP0LYoQfCnZ7XMHv+UI+8JA== dependencies: "@babel/runtime" "^7.6.2" "@react-stately/utils" "^3.5.1" - "@react-types/overlays" "^3.6.4" + "@react-types/overlays" "^3.6.5" -"@react-stately/selection@^3.11.0": - version "3.11.0" - resolved "https://registry.yarnpkg.com/@react-stately/selection/-/selection-3.11.0.tgz#50945d87dadd0d08505b37f1bb319d0c783d2037" - integrity sha512-cBgDzH+AY+bMEROJbcZFdhbMk0vgiwyqBB8ZKLtCL7EOHs2xeynTAohRM+/t27U/tF91o4qHPFo67Tkxrd16Bg== +"@react-stately/selection@^3.11.1": + version "3.11.1" + resolved "https://registry.yarnpkg.com/@react-stately/selection/-/selection-3.11.1.tgz#580145bade9aebb8395ebc2edabed422d84fde0a" + integrity sha512-UHB6/eH5NJ+Q70G+pmnxohHfR3bh0szT+lOlWPj7Mh76WPu9bu07IHKLEob6PSzyJ81h7+Ysk3hdIgS3TewGog== dependencies: "@babel/runtime" "^7.6.2" - "@react-stately/collections" "^3.4.4" + "@react-stately/collections" "^3.5.0" "@react-stately/utils" "^3.5.1" - "@react-types/shared" "^3.15.0" + "@react-types/shared" "^3.16.0" "@react-stately/toggle@^3.3.1": - version "3.4.2" - resolved "https://registry.yarnpkg.com/@react-stately/toggle/-/toggle-3.4.2.tgz#8c70922ad559d9ef32ecf3cc3d122a66eb858f0d" - integrity sha512-+pO13Ap/tj4optu6VjQrEAaAoZvJAEwarMUaZvrkc0kdvMTNPdiT/2vhN32yvsSW0ssuFqToa3jMrTylCbpo8w== + version "3.4.3" + resolved "https://registry.yarnpkg.com/@react-stately/toggle/-/toggle-3.4.3.tgz#331942e70314f918f852ee679b8f668d98771801" + integrity sha512-HsJLMa5d9i6SWyDIahkJExkanXZek86//hirsgSU0IvY7YJx33Wek8UwHE5Vskp39DAOu18QMz2GrAngnUErYQ== dependencies: "@babel/runtime" "^7.6.2" "@react-stately/utils" "^3.5.1" - "@react-types/checkbox" "^3.4.0" - "@react-types/shared" "^3.15.0" + "@react-types/checkbox" "^3.4.1" + "@react-types/shared" "^3.16.0" "@react-stately/tree@^3.3.1": - version "3.3.4" - resolved "https://registry.yarnpkg.com/@react-stately/tree/-/tree-3.3.4.tgz#2b71436dd7ed3bd42983f4fd29a9417f947876f9" - integrity sha512-CBgXvwa9qYBsJuxrAiVgGnm48eSxLe/6OjPMwH1pWf4s383Mx73MbbN4fS0oWDeXBVgdqz5/Xg/p8nvPIvl3WQ== + version "3.4.0" + resolved "https://registry.yarnpkg.com/@react-stately/tree/-/tree-3.4.0.tgz#e3985fcc4a6c4014a6cb28b146ff5f6903c7bd4c" + integrity sha512-MqxSABMzykwI6Wj1B7+jBcCoYc0b05CueRTQDyoL+PfVhnV0SzOH6P84UPD+FHlz8x3RG/2hTTmLr4A8McO2nQ== dependencies: "@babel/runtime" "^7.6.2" - "@react-stately/collections" "^3.4.4" - "@react-stately/selection" "^3.11.0" + "@react-stately/collections" "^3.5.0" + "@react-stately/selection" "^3.11.1" "@react-stately/utils" "^3.5.1" - "@react-types/shared" "^3.15.0" + "@react-types/shared" "^3.16.0" "@react-stately/utils@^3.5.0", "@react-stately/utils@^3.5.1": version "3.5.1" @@ -2167,48 +2339,53 @@ dependencies: "@babel/runtime" "^7.6.2" -"@react-types/button@^3.5.1", "@react-types/button@^3.6.2": - version "3.6.2" - resolved "https://registry.yarnpkg.com/@react-types/button/-/button-3.6.2.tgz#72d617deb0f76bd01a570ef28306ac1482c58a67" - integrity sha512-qgrYT6yiGVuZSPbzeDT6kTREQVxzJ9p5chV+JX7G5Rpjl2vyUDkEhZ5V/AHLKguBALgFaWJvjtwejHQ7FtycTw== +"@react-types/button@^3.5.1", "@react-types/button@^3.7.0": + version "3.7.0" + resolved "https://registry.yarnpkg.com/@react-types/button/-/button-3.7.0.tgz#774c043d8090a505e60fdf26f026d5f0cc968f0f" + integrity sha512-81BQO3QxSgF9PTXsVozNdNCKxBOB1lpbCWocV99dN1ws9s8uaYw8pmJJZ0LJKLiOsIECQ/3QrhQjmWTDW/qTug== dependencies: - "@react-types/shared" "^3.15.0" + "@react-types/shared" "^3.16.0" -"@react-types/checkbox@^3.4.0": - version "3.4.0" - resolved "https://registry.yarnpkg.com/@react-types/checkbox/-/checkbox-3.4.0.tgz#f2d6acabdf953cf2f7b8b874dab9ac8ae1c020fa" - integrity sha512-ZDqbtAYWWSGPjL4ydinaWHrD65Qft9yEGA6BCKQTxdJCgxiXxgGkA3pI7Sxwk+OulR+O0CYJ1JROExM9cSJyyQ== +"@react-types/checkbox@^3.4.1": + version "3.4.1" + resolved "https://registry.yarnpkg.com/@react-types/checkbox/-/checkbox-3.4.1.tgz#75a78b3f21f4cc72d2382761ba4c326aefd699db" + integrity sha512-kDMpy9SntjGQ7x00m5zmW8GENPouOtyiDgiEDKsPXUr2iYqHsNtricqVyG9S9+6hqpzuu8BzTcvZamc/xYjzlg== dependencies: - "@react-types/shared" "^3.15.0" + "@react-types/shared" "^3.16.0" "@react-types/dialog@^3.4.1": - version "3.4.4" - resolved "https://registry.yarnpkg.com/@react-types/dialog/-/dialog-3.4.4.tgz#48863c58e18d41de8a7e35cf2463a1ed44bd0135" - integrity sha512-mBaoQn+2nd14j0WSTfqGMb8dfG6Nak4+S9HqbJeP6UjKfwnmF8aXQ/Z3EYPNcwwDB+fNYStPagxRdBeqJ1GK4g== + version "3.4.5" + resolved "https://registry.yarnpkg.com/@react-types/dialog/-/dialog-3.4.5.tgz#a12c4e6d69dd7f098eb8b1534107ae6d970f734b" + integrity sha512-FkxZAYNRWkZVH5rjlw6qyQ/SpoGcYtNI/JQvn1H/xtZy/OJh2b2ERxGWv5x0RItGSeyATdSwFO1Qnf1Kl2K02A== dependencies: - "@react-types/overlays" "^3.6.4" - "@react-types/shared" "^3.15.0" + "@react-types/overlays" "^3.6.5" + "@react-types/shared" "^3.16.0" -"@react-types/menu@^3.6.1", "@react-types/menu@^3.7.2": - version "3.7.2" - resolved "https://registry.yarnpkg.com/@react-types/menu/-/menu-3.7.2.tgz#04a0447f791a7ffa0a6c8dc160cbff3bbeeedefd" - integrity sha512-BXMWrT3VCP6NTf0y7v1YYqRJNXkUKLzGXI+n7Qv9+aiZZfd3NNMyk20byHczhFoT2yuCcU5xhyOXzkxSo6ew3A== +"@react-types/menu@^3.6.1", "@react-types/menu@^3.7.3": + version "3.7.3" + resolved "https://registry.yarnpkg.com/@react-types/menu/-/menu-3.7.3.tgz#beb8d0fb7f1e50254e2e7661dfbfa4bb38826dad" + integrity sha512-3Pax24I/FyNKBjKyNR4ePD8eZs35Th57HzJAVjamQg2fHEDRomg9GQ7fdmfGj72Dv3x3JRCoPYqhJ3L5R3kbzg== dependencies: - "@react-types/overlays" "^3.6.4" - "@react-types/shared" "^3.15.0" + "@react-types/overlays" "^3.6.5" + "@react-types/shared" "^3.16.0" -"@react-types/overlays@^3.6.1", "@react-types/overlays@^3.6.4": - version "3.6.4" - resolved "https://registry.yarnpkg.com/@react-types/overlays/-/overlays-3.6.4.tgz#4ae4d7b3b38c45d122b0ca2dc88a57f08e89fd0e" - integrity sha512-REC4IyDUHS5WhwxMxcvTo+LdrvlSYpJKjyYkPFtJoDBpM3gmXfakTY3KW6K5eZkFv3TnmXjDF9Q2yboEk2u6WQ== +"@react-types/overlays@^3.6.1", "@react-types/overlays@^3.6.5": + version "3.6.5" + resolved "https://registry.yarnpkg.com/@react-types/overlays/-/overlays-3.6.5.tgz#466b325d9be51f67beb98b7bec3fd9295c72efac" + integrity sha512-IeWcF+YTucCYYHagNh8fZLH6R4YUONO1VHY57WJyIHwMy0qgEaKSQCwq72VO1fQJ0ySZgOgm31FniOyKkg6+eQ== dependencies: - "@react-types/shared" "^3.15.0" + "@react-types/shared" "^3.16.0" -"@react-types/shared@^3.13.1", "@react-types/shared@^3.15.0": +"@react-types/shared@^3.13.1": version "3.15.0" resolved "https://registry.yarnpkg.com/@react-types/shared/-/shared-3.15.0.tgz#a4a78f36bc8daaefe6e9a9df1f453271639c2233" integrity sha512-hwuE4BmgswqP+HRDSLMj7DcnYOCCK+ZRuKnc9AVhXS4LBrwRSkdUkNvXhgvqF5tav7IqTpG9pBYMR9wedehuhA== +"@react-types/shared@^3.16.0": + version "3.16.0" + resolved "https://registry.yarnpkg.com/@react-types/shared/-/shared-3.16.0.tgz#cab7bf0376969d1773480ecb2d6da5aa91391db5" + integrity sha512-IQgU4oAEvMwylEvaTsr2XB1G/mAoMe1JFYLD6G78v++oAR9l8o9MQxZ0YSeANDkqTamb2gKezGoT1RxvSKjVxw== + "@sentry/browser@6.19.7": version "6.19.7" resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-6.19.7.tgz#a40b6b72d911b5f1ed70ed3b4e7d4d4e625c0b5f" @@ -2439,6 +2616,11 @@ "@testing-library/dom" "^8.0.0" "@types/react-dom" "<18.0.0" +"@testing-library/user-event@^14.4.3": + version "14.4.3" + resolved "https://registry.yarnpkg.com/@testing-library/user-event/-/user-event-14.4.3.tgz#af975e367743fa91989cd666666aec31a8f50591" + integrity sha512-kCUc5MEwaEMakkO5x7aoD+DLi02ehmEM2QCGWvNqAS1dV/fAvORWEjnjsEIvml59M7Y5kCkWN6fCCyPOe8OL6Q== + "@tootallnate/once@1": version "1.1.2" resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" @@ -2618,6 +2800,18 @@ resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== +"@types/lodash-es@^4.17.6": + version "4.17.6" + resolved "https://registry.yarnpkg.com/@types/lodash-es/-/lodash-es-4.17.6.tgz#c2ed4c8320ffa6f11b43eb89e9eaeec65966a0a0" + integrity sha512-R+zTeVUKDdfoRxpAryaQNRKk3105Rrgx2CFRClIgRGaqDTdjsm8h6IYA8ir584W3ePzkZfst5xIgDwYrlh9HLg== + dependencies: + "@types/lodash" "*" + +"@types/lodash@*": + version "4.14.191" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.191.tgz#09511e7f7cba275acd8b419ddac8da9a6a79e2fa" + integrity sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ== + "@types/lodash@latest": version "4.14.186" resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.186.tgz#862e5514dd7bd66ada6c70ee5fce844b06c8ee97" @@ -2658,6 +2852,13 @@ resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.5.tgz#5f19d2b85a98e9558036f6a3cacc8819420f05cf" integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w== +"@types/react-copy-to-clipboard@^5.0.4": + version "5.0.4" + resolved "https://registry.yarnpkg.com/@types/react-copy-to-clipboard/-/react-copy-to-clipboard-5.0.4.tgz#558f2c38a97f53693e537815f6024f1e41e36a7e" + integrity sha512-otTJsJpofYAeaIeOwV5xBUGpo6exXG2HX7X4nseToCB2VgPEBxGBHCm/FecZ676doNR7HCSTVtmohxfG2b3/yQ== + dependencies: + "@types/react" "*" + "@types/react-dom@<18.0.0": version "17.0.17" resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-17.0.17.tgz#2e3743277a793a96a99f1bf87614598289da68a1" @@ -3368,6 +3569,15 @@ aws4@^1.8.0: resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59" integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA== +axios@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.2.1.tgz#44cf04a3c9f0c2252ebd85975361c026cb9f864a" + integrity sha512-I88cFiGu9ryt/tfVEi4kX2SITsvDddTajXTOFmt2uK1ZVA8LytjtdeyefdQWEf5PU8w+4SSJDoYnggflB5tW4A== + dependencies: + follow-redirects "^1.15.0" + form-data "^4.0.0" + proxy-from-env "^1.1.0" + babel-jest@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-27.5.1.tgz#a1bf8d61928edfefd21da27eb86a695bfd691444" @@ -3938,9 +4148,9 @@ copy-webpack-plugin@^10.0.0: serialize-javascript "^6.0.0" core-js-compat@^3.21.0, core-js-compat@^3.22.1: - version "3.25.5" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.25.5.tgz#0016e8158c904f7b059486639e6e82116eafa7d9" - integrity sha512-ovcyhs2DEBUIE0MGEKHP4olCUW/XYte3Vroyxuh38rD1wAO4dHohsovUC4eAOuzFxE6b+RXvBU3UZ9o0YhUTkA== + version "3.26.1" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.26.1.tgz#0e710b09ebf689d719545ac36e49041850f943df" + integrity sha512-622/KzTudvXCDLRw70iHW4KKs1aGpcRcowGWyYJr2DEBfRrd6hNJybxSWJFuZYD4ma86xhrwDDHxmDaIq4EA8A== dependencies: browserslist "^4.21.4" @@ -5278,6 +5488,11 @@ flatted@^3.1.0: resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.7.tgz#609f39207cb614b89d0765b477cb2d437fbf9787" integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ== +follow-redirects@^1.15.0: + version "1.15.2" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13" + integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== + forever-agent@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" @@ -5310,6 +5525,15 @@ form-data@^3.0.0: combined-stream "^1.0.8" mime-types "^2.1.12" +form-data@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" + integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + form-data@~2.3.2: version "2.3.3" resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" @@ -6813,9 +7037,9 @@ loader-runner@^4.2.0: integrity sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg== loader-utils@^1.0.2: - version "1.4.0" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.4.0.tgz#c579b5e34cb34b1a74edc6c1fb36bfa371d5a613" - integrity sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA== + version "1.4.2" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.4.2.tgz#29a957f3a63973883eb684f10ffd3d151fec01a3" + integrity sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg== dependencies: big.js "^5.2.2" emojis-list "^3.0.0" @@ -6844,6 +7068,11 @@ locate-path@^6.0.0: dependencies: p-locate "^5.0.0" +lodash-es@^4.17.21: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.21.tgz#43e626c46e6591b7750beb2b50117390c609e3ee" + integrity sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw== + lodash.debounce@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" @@ -7616,6 +7845,11 @@ proxy-from-env@1.0.0: resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.0.0.tgz#33c50398f70ea7eb96d21f7b817630a55791c7ee" integrity sha512-F2JHgJQ1iqwnHDcQjVBsq3n/uoaFL+iPW/eAeL7kVxy/2RrWaN4WroKjjvbsoRtv0ftelNyC01bjRhn/bhcf4A== +proxy-from-env@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" + integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== + prr@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" @@ -7922,6 +8156,14 @@ react-colorful@5.5.1: resolved "https://registry.yarnpkg.com/react-colorful/-/react-colorful-5.5.1.tgz#29d9c4e496f2ca784dd2bb5053a3a4340cfaf784" integrity sha512-M1TJH2X3RXEt12sWkpa6hLc/bbYS0H6F4rIqjQZ+RxNBstpY67d9TrFXtqdZwhpmBXcCwEi7stKqFue3ZRkiOg== +react-copy-to-clipboard@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/react-copy-to-clipboard/-/react-copy-to-clipboard-5.1.0.tgz#09aae5ec4c62750ccb2e6421a58725eabc41255c" + integrity sha512-k61RsNgAayIJNoy9yDsYzDe/yAZAzEbEgcz3DZMhF686LEyukcE1hzurxe85JandPUG+yTfGVFzuEw3xt8WP/A== + dependencies: + copy-to-clipboard "^3.3.1" + prop-types "^15.8.1" + react-custom-scrollbars-2@4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/react-custom-scrollbars-2/-/react-custom-scrollbars-2-4.5.0.tgz#cff18e7368bce9d570aea0be780045eda392c745" @@ -8225,6 +8467,11 @@ regenerator-runtime@^0.11.0: resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg== +regenerator-runtime@^0.13.11: + version "0.13.11" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9" + integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== + regenerator-transform@^0.15.0: version "0.15.0" resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.15.0.tgz#cbd9ead5d77fae1a48d957cf889ad0586adb6537" @@ -8258,6 +8505,18 @@ regexpu-core@^5.1.0: unicode-match-property-ecmascript "^2.0.0" unicode-match-property-value-ecmascript "^2.0.0" +regexpu-core@^5.2.1: + version "5.2.2" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-5.2.2.tgz#3e4e5d12103b64748711c3aad69934d7718e75fc" + integrity sha512-T0+1Zp2wjF/juXMrMxHxidqGYn8U4R+zleSJhX9tQ1PUsS8a9UtYfbsF9LdiVgNX3kiX8RNaKM42nfSgvFJjmw== + dependencies: + 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" + regextras@^0.8.0: version "0.8.0" resolved "https://registry.yarnpkg.com/regextras/-/regextras-0.8.0.tgz#ec0f99853d4912839321172f608b544814b02217" @@ -8950,6 +9209,11 @@ stylis@4.0.13: resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.0.13.tgz#f5db332e376d13cc84ecfe5dace9a2a51d954c91" integrity sha512-xGPXiFVl4YED9Jh7Euv2V220mriG9u4B2TA6Ybjc1catrstKD2PpIdU3U0RKpkVBC2EhmL/F0sPCr9vrFTNRag== +stylis@4.1.3: + version "4.1.3" + resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.1.3.tgz#fd2fbe79f5fed17c55269e16ed8da14c84d069f7" + integrity sha512-GP6WDNWf+o403jrEp9c5jibKavrtLW+/qYGhFxFrG8maXhwTBI7gLLhiBb0o7uFccWN+EOS9aMO6cGHWAO07OA== + stylis@^4.0.6: version "4.1.2" resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.1.2.tgz#870b3c1c2275f51b702bb3da9e94eedad87bba41" @@ -9329,9 +9593,9 @@ typescript@^4.4.0: integrity sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ== ua-parser-js@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-1.0.2.tgz#e2976c34dbfb30b15d2c300b2a53eac87c57a775" - integrity sha512-00y/AXhx0/SsnI51fTc0rLRmafiGOM4/O+ny10Ps7f+j/b8p/ZY11ytMgznXkOVo4GQ+KwQG5UQLkLGirsACRg== + version "1.0.32" + resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-1.0.32.tgz#786bf17df97de159d5b1c9d5e8e9e89806f8a030" + integrity sha512-dXVsz3M4j+5tTiovFVyVqssXBu5HM47//YSOeZ9fQkdDKkfzv2v3PP1jmH6FUyPW+yCSn7aBVK1fGGKNhowdDA== unbox-primitive@^1.0.2: version "1.0.2" @@ -9366,6 +9630,11 @@ unicode-match-property-value-ecmascript@^2.0.0: resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.0.0.tgz#1a01aa57247c14c568b89775a54938788189a714" integrity sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw== +unicode-match-property-value-ecmascript@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz#cb5fffdcd16a05124f5a4b0bf7c3770208acbbe0" + integrity sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA== + unicode-property-aliases-ecmascript@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz#43d41e3be698bd493ef911077c9b131f827e8ccd"