diff --git a/babel.config.js b/babel.config.js index 4dcf484ca2..fede5876b3 100644 --- a/babel.config.js +++ b/babel.config.js @@ -48,6 +48,8 @@ module.exports = (api) => { require('@babel/plugin-syntax-import-meta'), [require('@babel/plugin-proposal-class-properties'), { loose: true }], require('@babel/plugin-proposal-json-strings'), + [require('@babel/plugin-proposal-private-property-in-object'), { loose: true }], + [require('@babel/plugin-proposal-private-methods'), { loose: true }], ...(development ? developmentPlugins : productionPlugins), ], diff --git a/configs/webpack.config.renderer.dev.babel.js b/configs/webpack.config.renderer.dev.babel.js index dbbdd62361..2c67686e9d 100644 --- a/configs/webpack.config.renderer.dev.babel.js +++ b/configs/webpack.config.renderer.dev.babel.js @@ -209,6 +209,7 @@ export default merge(baseConfig, { BASE_API_URL: 'http://localhost', RESOURCES_BASE_URL: 'http://localhost', SCAN_COUNT_DEFAULT: '500', + SCAN_TREE_COUNT_DEFAULT: '10000', BUILD_TYPE: 'ELECTRON', APP_VERSION: version, SEGMENT_WRITE_KEY: diff --git a/configs/webpack.config.renderer.dev.dll.babel.js b/configs/webpack.config.renderer.dev.dll.babel.js index b5ac030987..c047ce8082 100644 --- a/configs/webpack.config.renderer.dev.dll.babel.js +++ b/configs/webpack.config.renderer.dev.dll.babel.js @@ -51,6 +51,7 @@ export default merge(baseConfig, { BASE_API_URL: 'http://localhost', RESOURCES_BASE_URL: 'http://localhost', SCAN_COUNT_DEFAULT: '500', + SCAN_TREE_COUNT_DEFAULT: '10000', SEGMENT_WRITE_KEY: 'SEGMENT_WRITE_KEY' in process.env ? process.env.SEGMENT_WRITE_KEY : 'SOURCE_WRITE_KEY', }), diff --git a/configs/webpack.config.renderer.prod.babel.js b/configs/webpack.config.renderer.prod.babel.js index 61af89e279..bdd683d597 100644 --- a/configs/webpack.config.renderer.prod.babel.js +++ b/configs/webpack.config.renderer.prod.babel.js @@ -197,6 +197,7 @@ export default merge(baseConfig, { RESOURCES_BASE_URL: process.env.SERVER_TLS_CERT && process.env.SERVER_TLS_KEY ? 'https://localhost' : 'http://localhost', APP_ENV: 'electron', SCAN_COUNT_DEFAULT: '500', + SCAN_TREE_COUNT_DEFAULT: '10000', SEGMENT_WRITE_KEY: 'SEGMENT_WRITE_KEY' in process.env ? process.env.SEGMENT_WRITE_KEY : 'SOURCE_WRITE_KEY', }), diff --git a/configs/webpack.config.renderer.stage.babel.js b/configs/webpack.config.renderer.stage.babel.js index cc2d3bf051..b17db4ef7c 100644 --- a/configs/webpack.config.renderer.stage.babel.js +++ b/configs/webpack.config.renderer.stage.babel.js @@ -20,6 +20,7 @@ export default merge(baseConfig, { RESOURCES_BASE_URL: process.env.SERVER_TLS_CERT && process.env.SERVER_TLS_KEY ? 'https://localhost' : 'http://localhost', APP_ENV: 'electron', SCAN_COUNT_DEFAULT: '500', + SCAN_COUNT_MEMORY_ANALYSES: '10000', SEGMENT_WRITE_KEY: 'SEGMENT_WRITE_KEY' in process.env ? process.env.SEGMENT_WRITE_KEY : 'SOURCE_WRITE_KEY', }), diff --git a/configs/webpack.config.web.dev.babel.js b/configs/webpack.config.web.dev.babel.js index 7a128ed947..e77d4f12f8 100644 --- a/configs/webpack.config.web.dev.babel.js +++ b/configs/webpack.config.web.dev.babel.js @@ -183,10 +183,11 @@ export default merge(commonConfig, { NODE_ENV: 'development', APP_ENV: 'web', API_PREFIX: 'api', - API_PORT: '5000', + API_PORT: '5001', BASE_API_URL: `http://${require('os').hostname()}`, RESOURCES_BASE_URL: `http://${require('os').hostname()}`, SCAN_COUNT_DEFAULT: '500', + SCAN_TREE_COUNT_DEFAULT: '10000', SEGMENT_WRITE_KEY: 'SEGMENT_WRITE_KEY' in process.env ? process.env.SEGMENT_WRITE_KEY : 'SOURCE_WRITE_KEY', }), diff --git a/configs/webpack.config.web.prod.babel.js b/configs/webpack.config.web.prod.babel.js index acb39ccb29..3cef848ea1 100644 --- a/configs/webpack.config.web.prod.babel.js +++ b/configs/webpack.config.web.prod.babel.js @@ -46,12 +46,13 @@ export default merge(commonConfig, { new webpack.EnvironmentPlugin({ NODE_ENV: 'production', APP_ENV: 'web', - API_PORT: '5000', + API_PORT: '5001', API_PREFIX: '', BASE_API_URL: 'api/', RESOURCES_BASE_URL: process.env.SERVER_TLS_CERT && process.env.SERVER_TLS_KEY ? 'https://localhost' : 'http://localhost', SCAN_COUNT_DEFAULT: '500', + SCAN_TREE_COUNT_DEFAULT: '10000', SEGMENT_WRITE_KEY: 'SEGMENT_WRITE_KEY' in process.env ? process.env.SEGMENT_WRITE_KEY : 'SOURCE_WRITE_KEY', }), diff --git a/package.json b/package.json index feeb33faac..b96beefa2e 100644 --- a/package.json +++ b/package.json @@ -134,7 +134,6 @@ "@teamsupercell/typings-for-css-modules-loader": "^2.4.0", "@testing-library/jest-dom": "^5.11.6", "@testing-library/react": "^11.2.2", - "@testing-library/react-hooks": "^5.0.3", "@types/axios": "^0.14.0", "@types/classnames": "^2.2.11", "@types/date-fns": "^2.6.0", @@ -253,6 +252,9 @@ "react-redux": "^7.2.2", "react-router-dom": "^5.2.0", "react-virtualized": "^9.22.2", + "react-virtualized-auto-sizer": "^1.0.6", + "react-vtree": "^3.0.0-beta.3", + "react-window": "^1.8.6", "rehype-stringify": "^9.0.2", "remark-gfm": "^3.0.1", "remark-parse": "^10.0.1", diff --git a/redisinsight/ui/src/assets/img/icons/treeview.svg b/redisinsight/ui/src/assets/img/icons/treeview.svg new file mode 100644 index 0000000000..8485d3e366 --- /dev/null +++ b/redisinsight/ui/src/assets/img/icons/treeview.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/redisinsight/ui/src/assets/img/icons/treeview_active.svg b/redisinsight/ui/src/assets/img/icons/treeview_active.svg new file mode 100644 index 0000000000..dd271c7ec0 --- /dev/null +++ b/redisinsight/ui/src/assets/img/icons/treeview_active.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/redisinsight/ui/src/components/group-badge/GroupBadge.tsx b/redisinsight/ui/src/components/group-badge/GroupBadge.tsx index ef08bd472d..fb7a4bb29f 100644 --- a/redisinsight/ui/src/components/group-badge/GroupBadge.tsx +++ b/redisinsight/ui/src/components/group-badge/GroupBadge.tsx @@ -15,7 +15,7 @@ const GroupBadge = ({ type, name = '', className = '' }: Props) => ( data-testid={`badge-${type} ${name}`} > - {type ? (GROUP_TYPES_DISPLAY as any)[type] ?? type.replace(/_/g, ' ') : ''} + {type ? (GROUP_TYPES_DISPLAY as any)[type] ?? type?.replace(/_/g, ' ') : ''} ) diff --git a/redisinsight/ui/src/components/keys-summary/KeysSummary.spec.tsx b/redisinsight/ui/src/components/keys-summary/KeysSummary.spec.tsx new file mode 100644 index 0000000000..8a7f59a6cd --- /dev/null +++ b/redisinsight/ui/src/components/keys-summary/KeysSummary.spec.tsx @@ -0,0 +1,26 @@ +import React from 'react' +import { instance, mock } from 'ts-mockito' +import { render } from 'uiSrc/utils/test-utils' +import KeysSummary, { Props } from './KeysSummary' + +const mockedProps = mock() + +describe('KeysSummary', () => { + it('should render', () => { + expect(render()).toBeTruthy() + }) + + it('should "Scanning..." be in the document until loading and totalItemsCount == 0 ', () => { + const { queryByTestId } = render( + + ) + expect(queryByTestId('scanning-text')).toBeInTheDocument() + }) + + it('should Keys summary be in the document meanwhile totalItemsCount != 0 ', () => { + const { queryByTestId } = render( + + ) + expect(queryByTestId('keys-summary')).toBeInTheDocument() + }) +}) diff --git a/redisinsight/ui/src/components/keys-summary/KeysSummary.tsx b/redisinsight/ui/src/components/keys-summary/KeysSummary.tsx new file mode 100644 index 0000000000..2d4dc0d478 --- /dev/null +++ b/redisinsight/ui/src/components/keys-summary/KeysSummary.tsx @@ -0,0 +1,93 @@ +import React from 'react' +import cx from 'classnames' +import { EuiText, EuiTextColor } from '@elastic/eui' + +import { numberWithSpaces } from 'uiSrc/utils/numbers' +import ScanMore from '../scan-more' + +import styles from './styles.module.scss' + +export interface Props { + loading: boolean + items: any[] + scanned?: number + totalItemsCount?: number + scanMoreStyle?: { + [key: string]: string | number; + } + loadMoreItems?: (config: any) => void +} + +const KeysSummary = ({ + items, + loading, + scanned = 0, + totalItemsCount = 0, + scanMoreStyle, + loadMoreItems, +}: Props) => ( + <> + {!!totalItemsCount && ( +
+ {!!totalItemsCount && ( + + {!!scanned && ( + <> + + + Results:  + {numberWithSpaces(items.length)} + {' '} + key + {items.length === 1 ? '' : 's'} + .  + + + Scanned + {' '} + {numberWithSpaces(scanned)} + {' '} + / + {' '} + {numberWithSpaces(totalItemsCount)} + {' '} + keys + + + + + + )} + + {!scanned && ( + + + Total:  + {numberWithSpaces(totalItemsCount)} + + + )} + + + )} +
+ )} + {loading && !totalItemsCount && ( + + Scanning... + + )} + +) + +export default KeysSummary diff --git a/redisinsight/ui/src/components/keys-summary/index.ts b/redisinsight/ui/src/components/keys-summary/index.ts new file mode 100644 index 0000000000..79c35a567b --- /dev/null +++ b/redisinsight/ui/src/components/keys-summary/index.ts @@ -0,0 +1,3 @@ +import KeysSummary from './KeysSummary' + +export default KeysSummary diff --git a/redisinsight/ui/src/components/keys-summary/styles.module.scss b/redisinsight/ui/src/components/keys-summary/styles.module.scss new file mode 100644 index 0000000000..198f838ff6 --- /dev/null +++ b/redisinsight/ui/src/components/keys-summary/styles.module.scss @@ -0,0 +1,7 @@ +.loading { + opacity: 0; +} + +.loadingShow { + opacity: 1; +} diff --git a/redisinsight/ui/src/components/main-router/interfaces.ts b/redisinsight/ui/src/components/main-router/interfaces.ts index 7f3e32b497..0a642a5e6e 100644 --- a/redisinsight/ui/src/components/main-router/interfaces.ts +++ b/redisinsight/ui/src/components/main-router/interfaces.ts @@ -1,50 +1,3 @@ -import { KeyTypes, UnsupportedKeyTypes } from 'uiSrc/constants' -import { IKeyPropTypes } from 'uiSrc/constants/prop-types/keys' -import { Maybe, Nullable } from 'uiSrc/utils' - export interface RouteParams { instanceId: string; } - -export interface Key { - name: string; - type: KeyTypes; - ttl: number; - size: number; -} - -export interface KeysStore { - loading: boolean; - error: string; - search: string; - filter: Nullable; - isFiltered: boolean; - isSearched: boolean; - data: { - total: number; - scanned: number; - nextCursor: string; - keys: Key[]; - shardsMeta: Record; - previousResultCount: number; - lastRefreshTime: Nullable; - }; - selectedKey: { - loading: boolean; - refreshing: boolean; - lastRefreshTime: Nullable; - error: string; - data: Nullable; - length: Maybe; - }; - addKey: { - loading: boolean; - error: string; - }; -} diff --git a/redisinsight/ui/src/components/scan-more/ScanMore.spec.tsx b/redisinsight/ui/src/components/scan-more/ScanMore.spec.tsx new file mode 100644 index 0000000000..a2572f1109 --- /dev/null +++ b/redisinsight/ui/src/components/scan-more/ScanMore.spec.tsx @@ -0,0 +1,40 @@ +import React from 'react' +import { instance, mock } from 'ts-mockito' +import { fireEvent, screen, render } from 'uiSrc/utils/test-utils' +import ScanMore, { Props } from './ScanMore' + +const mockedProps = mock() + +describe('ActionBar', () => { + it('should render', () => { + expect(render()).toBeTruthy() + }) + + it('should call "loadMoreItems"', () => { + const handleClick = jest.fn() + + const renderer = render( + + ) + + expect(renderer).toBeTruthy() + + fireEvent.click(screen.getByTestId('scan-more')) + expect(handleClick).toHaveBeenCalledTimes(1) + }) + + it('should button be hidden when totalItemsCount < scanned ', () => { + const { queryByTestId } = render( + + ) + + expect(queryByTestId('scan-more')).not.toBeInTheDocument() + }) + it('should button be shown when totalItemsCount > scanned ', () => { + const { queryByTestId } = render( + + ) + + expect(queryByTestId('scan-more')).toBeInTheDocument() + }) +}) diff --git a/redisinsight/ui/src/components/scan-more/ScanMore.tsx b/redisinsight/ui/src/components/scan-more/ScanMore.tsx new file mode 100644 index 0000000000..2b066da607 --- /dev/null +++ b/redisinsight/ui/src/components/scan-more/ScanMore.tsx @@ -0,0 +1,61 @@ +import React from 'react' +import { EuiButton, EuiIcon, EuiToolTip } from '@elastic/eui' + +import { SCAN_COUNT_DEFAULT } from 'uiSrc/constants/api' +import styles from './styles.module.scss' + +export interface Props { + withAlert?: boolean + fill?: boolean + loading: boolean + scanned?: number + totalItemsCount?: number + style?: { + [key: string]: string | number; + } + loadMoreItems?: (config: any) => void +} + +const WARNING_MESSAGE = 'Scanning additional keys may decrease performance and memory available.' + +const ScanMore = ({ + fill = true, + withAlert = true, + scanned = 0, + totalItemsCount = 0, + loading, + style, + loadMoreItems, +}: Props) => ( + <> + {scanned < totalItemsCount && ( + + loadMoreItems?.({ + stopIndex: SCAN_COUNT_DEFAULT - 1, + startIndex: 0, + })} + data-testid="scan-more" + > + {withAlert && ( + + + + )} + Scan more + + )} + +) + +export default ScanMore diff --git a/redisinsight/ui/src/components/scan-more/index.ts b/redisinsight/ui/src/components/scan-more/index.ts new file mode 100644 index 0000000000..3f58e85757 --- /dev/null +++ b/redisinsight/ui/src/components/scan-more/index.ts @@ -0,0 +1,3 @@ +import ScanMore from './ScanMore' + +export default ScanMore diff --git a/redisinsight/ui/src/components/scan-more/styles.module.scss b/redisinsight/ui/src/components/scan-more/styles.module.scss new file mode 100644 index 0000000000..c76972c7fd --- /dev/null +++ b/redisinsight/ui/src/components/scan-more/styles.module.scss @@ -0,0 +1,12 @@ +.btn { + :global(.euiButtonContent .euiButton__text) { + font: normal normal normal 12px/18px Graphik, sans-serif !important; + letter-spacing: -0.12px; + } + + svg { + color: var(--euiColorWarningLight) !important; + margin-bottom: 2px; + margin-right: 6px; + } +} diff --git a/redisinsight/ui/src/components/virtual-table/VirtualTable.spec.tsx b/redisinsight/ui/src/components/virtual-table/VirtualTable.spec.tsx index 1c459b23f5..39c69dae5a 100644 --- a/redisinsight/ui/src/components/virtual-table/VirtualTable.spec.tsx +++ b/redisinsight/ui/src/components/virtual-table/VirtualTable.spec.tsx @@ -195,7 +195,6 @@ describe('VirtualTable', () => { const onLoadMoreItems = jest.fn() const argMock = { - keyName: '', stopIndex: SCAN_COUNT_DEFAULT - 1, startIndex: 0, } diff --git a/redisinsight/ui/src/components/virtual-table/VirtualTable.tsx b/redisinsight/ui/src/components/virtual-table/VirtualTable.tsx index 3e0b3a6ca7..cc17863b16 100644 --- a/redisinsight/ui/src/components/virtual-table/VirtualTable.tsx +++ b/redisinsight/ui/src/components/virtual-table/VirtualTable.tsx @@ -7,17 +7,15 @@ import { EuiProgress, EuiResizeObserver, EuiIcon, - EuiTextColor, - EuiButton, } from '@elastic/eui' import { Maybe, Nullable } from 'uiSrc/utils' import { SortOrder } from 'uiSrc/constants' import { SCAN_COUNT_DEFAULT } from 'uiSrc/constants/api' -import { numberWithSpaces } from 'uiSrc/utils/numbers' import TableColumnSearch from 'uiSrc/components/table-column-search/TableColumnSearch' import TableColumnSearchTrigger from 'uiSrc/components/table-column-search-trigger/TableColumnSearchTrigger' import { IColumnSearchState, IProps, IResizeEvent, ITableColumn } from './interfaces' +import KeysSummary from '../keys-summary' import styles from './styles.module.scss' @@ -27,7 +25,6 @@ const VirtualTable = (props: IProps) => { rowHeight = 40, scanned = 0, totalItemsCount = 0, - totalSize = 0, onRowClick = () => {}, onSearch = () => {}, onChangeSorting = () => {}, @@ -43,7 +40,8 @@ const VirtualTable = (props: IProps) => { keyName, loadMoreItems, setScrollTopPosition = () => {}, - scrollTopProp = 0 + scrollTopProp = 0, + hideFooter = false, } = props const scrollTopRef = useRef(0) const [selectedRowIndex, setSelectedRowIndex] = useState>(null) @@ -217,7 +215,7 @@ const VirtualTable = (props: IProps) => { if (forceScrollTop !== undefined) return if (!loading) { - loadMoreItems({ keyName, startIndex, stopIndex }) + loadMoreItems?.({ keyName, startIndex, stopIndex }) } } @@ -338,6 +336,7 @@ const VirtualTable = (props: IProps) => { {columns.map((column: ITableColumn, index: number) => ( { )} - {!!(totalItemsCount || totalSize) && ( -
- {!!totalItemsCount && ( - - {scanned ? ( - <> - - - Results:  - {numberWithSpaces(items.length)} - {' '} - key - {items.length === 1 ? '' : 's'} - .  - - - Scanned - {' '} - {numberWithSpaces(scanned)} - {' '} - / - {' '} - {numberWithSpaces(totalItemsCount)} - {' '} - keys - - - - {scanned < totalItemsCount && ( - - loadMoreRows({ - stopIndex: SCAN_COUNT_DEFAULT - 1, - startIndex: 0, - })} - data-testid="scan-more" - > - Scan more - - )} - - ) : ( - - - Total:  - {numberWithSpaces(totalItemsCount)} - - - )} - - )} - {!!totalSize && ( -
- - Total Size: - {' '} - {totalSize / 1000} - kB - -
- )} + {!hideFooter && ( +
+
)} +
)} diff --git a/redisinsight/ui/src/components/virtual-table/interfaces.ts b/redisinsight/ui/src/components/virtual-table/interfaces.ts index cb64917618..f9f422ea36 100644 --- a/redisinsight/ui/src/components/virtual-table/interfaces.ts +++ b/redisinsight/ui/src/components/virtual-table/interfaces.ts @@ -6,13 +6,13 @@ import { } from 'uiSrc/constants' export interface IColumnSearchState { - initialSearchValue?: string; - id: string; - value: string; - prependSearchName: string; - isOpened: boolean; - staySearchAlwaysOpen: boolean; - searchValidation?: (value: string) => string; + initialSearchValue?: string + id: string + value: string + prependSearchName: string + isOpened: boolean + staySearchAlwaysOpen: boolean + searchValidation?: (value: string) => string } export interface IResizeEvent { @@ -21,53 +21,54 @@ export interface IResizeEvent { } export interface ITableColumn { - id: string; - label: string | ReactNode; - minWidth?: number; - isSortable?: boolean; - isSearchable?: boolean; - isSearchOpen?: boolean; - initialSearchValue?: string; - headerClassName?: string; - truncateText?: boolean; - relativeWidth?: number; - absoluteWidth?: number; - alignment?: TableCellAlignment; - textAlignment?: TableCellTextAlignment; - render?: (cellData?: any, columnItem?: any) => any; - className?: string; - prependSearchName?: string; - staySearchAlwaysOpen?: boolean; - searchValidation?: (value: string) => string; + id: string + label: string | ReactNode + minWidth?: number + maxWidth?: number + isSortable?: boolean + isSearchable?: boolean + isSearchOpen?: boolean + initialSearchValue?: string + headerClassName?: string + truncateText?: boolean + relativeWidth?: number + absoluteWidth?: number | string + alignment?: TableCellAlignment + textAlignment?: TableCellTextAlignment + render?: (cellData?: any, columnItem?: any) => any + className?: string + prependSearchName?: string + staySearchAlwaysOpen?: boolean + searchValidation?: (value: string) => string } export interface IProps { - loading: boolean; - scanned?: number; - columns: ITableColumn[]; - loadMoreItems: (config: any) => void; - rowHeight?: number; - footerHeight?: number; - isRowSelectable?: boolean; - keyName?: string; - headerHeight?: number; - searching?: boolean; - onRowClick?: (rowData: any) => void; - onSearch?: (newState: any) => void; - onWheel?: (event: React.WheelEvent) => void; - onChangeSorting?: (cellData?: any, columnItem?: any) => void; - items?: any; - noItemsMessage?: string | string[] | JSX.Element; - totalItemsCount?: number; - totalSize?: number; - selectedKey?: any; - sortedColumn?: ISortedColumn; - disableScroll?: boolean; - setScrollTopPosition?: (position: number) => void; - scrollTopProp?: number; + loading: boolean + scanned?: number + columns: ITableColumn[] + loadMoreItems?: (config: any) => void + rowHeight?: number + footerHeight?: number + isRowSelectable?: boolean + keyName?: string + headerHeight?: number + searching?: boolean + onRowClick?: (rowData: any) => void + onSearch?: (newState: any) => void + onWheel?: (event: React.WheelEvent) => void + onChangeSorting?: (cellData?: any, columnItem?: any) => void + items?: any + noItemsMessage?: string | string[] | JSX.Element + totalItemsCount?: number + selectedKey?: any + sortedColumn?: ISortedColumn + disableScroll?: boolean + setScrollTopPosition?: (position: number) => void + scrollTopProp?: number + hideFooter?: boolean } export interface ISortedColumn { - column: string; - order: SortOrder; + column: string + order: SortOrder } diff --git a/redisinsight/ui/src/components/virtual-table/styles.module.scss b/redisinsight/ui/src/components/virtual-table/styles.module.scss index 75c980c6ed..ef5ffe605b 100644 --- a/redisinsight/ui/src/components/virtual-table/styles.module.scss +++ b/redisinsight/ui/src/components/virtual-table/styles.module.scss @@ -24,6 +24,10 @@ $footerHeight: 38px; padding-bottom: $footerHeight; } +:global(.keys-tree__count) { + padding-left: 10px; +} + .table { :global { .ReactVirtualized__Table__headerRow { @@ -45,14 +49,12 @@ $footerHeight: 38px; display: flex; align-items: center; box-sizing: border-box; - padding: 8px; + padding: 8px 18px; min-height: 43px; } .tableRow { cursor: pointer; - border-bottom: 1px solid var(--euiColorLightShade); - // border-top: 1px solid transparent; border-top-width: 0; & > div:last-of-type { border-right: 1px solid transparent; @@ -135,15 +137,20 @@ $footerHeight: 38px; white-space: pre-wrap; } -:global(.key-details-table), -:global(.key-list-table) { - height: calc(100% - 38px); + +:global(.key-details-table) { :global(.ReactVirtualized__Table__row) { font-size: 13px; } } +:global(.key-list-table) { + height: calc(100% - 58px); +} + + :global(.key-details-table) { + height: calc(100% - 38px); &:global(.footerOpened) { :global(.ReactVirtualized__Table__Grid) { padding-bottom: 254px; diff --git a/redisinsight/ui/src/components/virtual-tree/VirtualTree.spec.tsx b/redisinsight/ui/src/components/virtual-tree/VirtualTree.spec.tsx new file mode 100644 index 0000000000..9dfacdd3b1 --- /dev/null +++ b/redisinsight/ui/src/components/virtual-tree/VirtualTree.spec.tsx @@ -0,0 +1,101 @@ +import React from 'react' +import { mock, instance } from 'ts-mockito' + +import { render } from 'uiSrc/utils/test-utils' +import VirtualTree, { Props } from './VirtualTree' + +const mockedProps = mock() + +const mockedItems = [ + { + name: 'test', + type: 'hash', + ttl: 2147474450, + size: 3041, + }, +] + +export const mockLeafKeys = { + test: { name: 'test', type: 'hash', ttl: -1, size: 9849176 } +} + +export const mockVirtualTreeResult = [{ + children: [{ + children: [], + fullName: 'car:110:', + id: '0.snc1rc3zwgo', + keyApproximate: 0.01, + keyCount: 1, + name: '110', + }], + fullName: 'car:', + id: '0.sz1ie1koqi8', + keyApproximate: 47.18, + keyCount: 4718, + name: 'car', +}, +{ + children: [], + fullName: 'test', + id: '0.snc1rc3zwg1o', + keyApproximate: 0.01, + keyCount: 1, + name: 'test', + keys: mockLeafKeys +}] + +jest.mock('uiSrc/services', () => ({ + ...jest.requireActual('uiSrc/services'), + useDisposableWebworker: () => ({ result: mockVirtualTreeResult, run: jest.fn() }), +})) + +describe('VirtualTree', () => { + it('should render with empty nodes', () => { + expect(render()).toBeTruthy() + }) + + it('should render Spinner with empty nodes and loading', () => { + const mockFn = jest.fn() + const { queryByTestId } = render( + + ) + + expect(queryByTestId('virtual-tree-spinner')).toBeInTheDocument() + }) + + it('should render items', async () => { + const mockFn = jest.fn() + const { queryByTestId } = render( + + ) + + expect(queryByTestId('test')).toBeInTheDocument() + }) + + it('should select first leaf "Keys" by default', async () => { + const mockConstructingTreeFn = jest.fn() + const mockOnStatusSelected = jest.fn() + const mockOnSelectLeaf = jest.fn() + + render( + + ) + + expect(mockOnSelectLeaf).toHaveBeenCalledWith(mockLeafKeys) + expect(mockOnStatusSelected).toHaveBeenCalledWith('test', mockLeafKeys) + }) +}) diff --git a/redisinsight/ui/src/components/virtual-tree/VirtualTree.tsx b/redisinsight/ui/src/components/virtual-tree/VirtualTree.tsx new file mode 100644 index 0000000000..82c433f97b --- /dev/null +++ b/redisinsight/ui/src/components/virtual-tree/VirtualTree.tsx @@ -0,0 +1,196 @@ +/* eslint-disable no-console */ +import React, { useCallback, useContext, useEffect, useState } from 'react' +import AutoSizer from 'react-virtualized-auto-sizer' +import { isArray, isEmpty } from 'lodash' +import { + TreeWalker, + TreeWalkerValue, + FixedSizeTree as Tree, +} from 'react-vtree' +import { EuiIcon, EuiLoadingSpinner } from '@elastic/eui' + +import { useDisposableWebworker } from 'uiSrc/services' +import { IKeyPropTypes } from 'uiSrc/constants/prop-types/keys' +import { ThemeContext } from 'uiSrc/contexts/themeContext' +import { DEFAULT_SEPARATOR, Theme } from 'uiSrc/constants' +import KeyLightSVG from 'uiSrc/assets/img/sidebar/browser.svg' +import KeyDarkSVG from 'uiSrc/assets/img/sidebar/browser_active.svg' + +import { Node } from './components/Node' +import { NodeMeta, TreeData, TreeNode } from './interfaces' + +import styles from './styles.module.scss' + +export interface Props { + items: IKeyPropTypes[] + separator?: string + loadingIcon?: string + loading: boolean + statusSelected: { + [key: string]: IKeyPropTypes[] + } + statusOpen: { + [key: string]: boolean + } + webworkerFn: (...args: any) => any + onSelectLeaf?: (items: any[]) => void + onStatusOpen?: (name: string, value: boolean) => void + onStatusSelected?: (id: string, keys: any) => void + setConstructingTree: (status: boolean) => void +} + +const timeLabel = 'Time for construct a Tree' +const VirtualTree = (props: Props) => { + const { + items, + separator = DEFAULT_SEPARATOR, + loadingIcon = 'empty', + statusOpen = {}, + statusSelected = {}, + loading, + onStatusOpen, + onStatusSelected, + onSelectLeaf, + setConstructingTree, + webworkerFn = () => {} + } = props + + const { theme } = useContext(ThemeContext) + + const [nodes, setNodes] = useState([]) + const [firstConstruct, setFirstConstruct] = useState(false) + + const { result, run: runWebworker } = useDisposableWebworker(webworkerFn) + + useEffect(() => + () => setNodes([]), + []) + + // receive result from the "runWebworker" + useEffect(() => { + if (!result) { + return + } + // [ToDo] remove after tests + console.timeEnd(timeLabel) + + setNodes(result) + setConstructingTree?.(false) + + // set "root" keys after first render (construct a tree) + if (!firstConstruct && isArray(result) && isEmpty(statusSelected)) { + const rootLeaf = result?.find(({ children = [] }) => children.length === 0) ?? {} + setFirstConstruct(true) + onStatusSelected?.(rootLeaf?.fullName, rootLeaf?.keys) + onSelectLeaf?.(rootLeaf?.keys ?? []) + } + }, [result]) + + useEffect(() => { + if (!items?.length) { + setNodes([]) + return + } + + // [ToDo] remove after tests + console.time(timeLabel) + setConstructingTree(true) + runWebworker?.({ items, separator }) + }, [items]) + + const handleSelectLeaf = useCallback((keys: any[]) => { + onSelectLeaf?.(keys) + }, [onSelectLeaf]) + + const handleUpdateSelected = useCallback((fullName: string, keys: any) => { + onStatusSelected?.(fullName, keys) + }, [onStatusSelected]) + + const handleUpdateOpen = useCallback((name: string, value: boolean) => { + onStatusOpen?.(name, value) + }, [onStatusOpen]) + + // This helper function constructs the object that will be sent back at the step + // [2] during the treeWalker function work. Except for the mandatory `data` + // field you can put any additional data here. + const getNodeData = ( + node: TreeNode, + nestingLevel: number, + ): TreeWalkerValue => ({ + data: { + id: node.id.toString(), + isLeaf: node.children?.length === 0, + keyCount: node.keyCount, + name: node.name, + fullName: node.fullName, + nestingLevel, + setItems: handleSelectLeaf, + updateStatusSelected: handleUpdateSelected, + updateStatusOpen: handleUpdateOpen, + leafIcon: theme === Theme.Dark ? KeyDarkSVG : KeyLightSVG, + keyApproximate: node.keyApproximate, + keys: node.keys || node?.['keys:keys'], + isSelected: Object.keys(statusSelected)[0] === node.fullName, + isOpenByDefault: statusOpen[node.fullName], + }, + nestingLevel, + node, + }) + + // The `treeWalker` function runs only on tree re-build which is performed + // whenever the `treeWalker` prop is changed. + const treeWalker = useCallback( + function* treeWalker(): ReturnType> { + // Step [1]: Define the root multiple nodes of our tree + for (let i = 0; i < nodes.length; i++) { + yield getNodeData(nodes[i], 0) + } + + // Step [2]: Get the parent component back. It will be the object + // the `getNodeData` function constructed, so you can read any data from it. + while (true) { + const parentMeta = yield + + for (let i = 0; i < parentMeta.node.children?.length; i++) { + // Step [3]: Yielding all the children of the provided component. Then we + // will return for the step [2] with the first children. + yield getNodeData( + parentMeta.node.children[i], + parentMeta.nestingLevel + 1, + ) + } + } + }, + [nodes, statusSelected], + ) + + return ( + + {({ height, width }) => ( +
+ { nodes.length > 0 && ( + + {Node} + + )} + { nodes.length === 0 && loading && ( +
+
+ + +
+
+ )} +
+ )} +
+ ) +} + +export default VirtualTree diff --git a/redisinsight/ui/src/components/virtual-tree/components/Node/Node.spec.tsx b/redisinsight/ui/src/components/virtual-tree/components/Node/Node.spec.tsx new file mode 100644 index 0000000000..42ffc12c83 --- /dev/null +++ b/redisinsight/ui/src/components/virtual-tree/components/Node/Node.spec.tsx @@ -0,0 +1,111 @@ +import React from 'react' +import { NodePublicState } from 'react-vtree/dist/es/Tree' +import { instance, mock } from 'ts-mockito' +import { render, screen } from 'uiSrc/utils/test-utils' +import KeyDarkSVG from 'uiSrc/assets/img/sidebar/browser_active.svg' +import Node from './Node' +import { TreeData } from '../../interfaces' +import { mockLeafKeys } from '../../VirtualTree.spec' + +const mockedProps = mock>() +const mockedPropsData = mock() +const mockedData: TreeData = { + ...instance(mockedPropsData), + nestingLevel: 3, + leafIcon: KeyDarkSVG +} +const mockDataFullName = 'test' + +describe('Node', () => { + it('should render', () => { + expect(render()).toBeTruthy() + }) + + it('should render arrow and folder icons for Node properly', () => { + const mockData: TreeData = { + ...mockedData, + isLeaf: false, + fullName: mockDataFullName + } + + const { container } = render() + + expect(container.querySelector(`[data-test-subj="node-arrow-icon_${mockDataFullName}"`)).toBeInTheDocument() + expect(container.querySelector(`[data-test-subj="node-folder-icon_${mockDataFullName}"`)).toBeInTheDocument() + }) + + it('should render leaf icon for Leaf properly', () => { + const mockData: TreeData = { + ...mockedData, + isLeaf: true, + fullName: mockDataFullName + } + + const { container } = render() + + expect(container.querySelector(`[data-test-subj="leaf-icon_${mockDataFullName}"`)).toBeInTheDocument() + }) + + it('"setItems", "updateStatusSelected" should be called after click on Leaf', () => { + const mockSetItems = jest.fn() + const mockUpdateStatusSelected = jest.fn() + const mockUpdateStatusOpen = jest.fn() + const mockSetOpen = jest.fn() + + const mockData: TreeData = { + ...mockedData, + isLeaf: true, + fullName: mockDataFullName, + keys: mockLeafKeys, + setItems: mockSetItems, + updateStatusSelected: mockUpdateStatusSelected, + updateStatusOpen: mockUpdateStatusOpen, + } + + render() + + screen.getByTestId(mockDataFullName).click() + + expect(mockSetItems).toBeCalledWith(mockLeafKeys) + expect(mockUpdateStatusSelected).toBeCalledWith(mockDataFullName, mockLeafKeys) + expect(mockUpdateStatusOpen).toBeCalledWith(mockDataFullName, true) + expect(mockSetOpen).not.toBeCalled() + }) + + it('"updateStatusOpen", "setOpen" should be called after click on Node', () => { + const mockSetItems = jest.fn() + const mockUpdateStatusSelected = jest.fn() + const mockUpdateStatusOpen = jest.fn() + const mockSetOpen = jest.fn() + const mockIsOpen = false + + const mockData: TreeData = { + ...mockedData, + isLeaf: mockIsOpen, + fullName: mockDataFullName, + keys: mockLeafKeys, + setItems: mockSetItems, + updateStatusSelected: mockUpdateStatusSelected, + updateStatusOpen: mockUpdateStatusOpen, + } + + render() + + screen.getByTestId(mockDataFullName).click() + + expect(mockSetItems).not.toBeCalled() + expect(mockUpdateStatusSelected).not.toBeCalled() + expect(mockUpdateStatusOpen).toHaveBeenCalledWith(mockDataFullName, !mockIsOpen) + expect(mockSetOpen).toBeCalledWith(!mockIsOpen) + }) +}) diff --git a/redisinsight/ui/src/components/virtual-tree/components/Node/Node.tsx b/redisinsight/ui/src/components/virtual-tree/components/Node/Node.tsx new file mode 100644 index 0000000000..4ddf4a7723 --- /dev/null +++ b/redisinsight/ui/src/components/virtual-tree/components/Node/Node.tsx @@ -0,0 +1,130 @@ +import React from 'react' +import { NodePublicState } from 'react-vtree/dist/es/Tree' +import cx from 'classnames' +import { EuiIcon, EuiToolTip, keys as ElasticKeys } from '@elastic/eui' + +import { TreeData } from '../../interfaces' +import styles from './styles.module.scss' + +// Node component receives all the data we created in the `treeWalker` + +// internal openness state (`isOpen`), function to change internal openness +// `style` parameter that should be added to the root div. +const Node = ({ + data, + isOpen, + style, + setOpen +}: NodePublicState) => { + const { + id, + isLeaf, + leafIcon, + keys, + name, + keyCount, + nestingLevel, + fullName, + keyApproximate, + isSelected, + setItems, + updateStatusOpen, + updateStatusSelected, + } = data + + const handleClick = () => { + if (isLeaf && keys) { + setItems?.(keys) + updateStatusSelected?.(fullName, keys) + } + + updateStatusOpen?.(fullName, !isOpen) + + !isLeaf && setOpen(!isOpen) + } + + const handleKeyDown = ({ key }: React.KeyboardEvent) => { + if (key === ElasticKeys.SPACE) { + handleClick() + } + } + + const Node = ( +
{}} + data-testid={fullName} + > +
+ {!isLeaf && ( + <> + + + {name} + + )} + + {isLeaf && ( + <> + + Keys + + )} +
+
+ {keyCount ?? ''} + + {keyApproximate ? `${keyApproximate < 1 ? '<1' : Math.round(keyApproximate)}%` : '' } + +
+
+ ) + + const content = ( + <> + {`${fullName}*`} +
+ {`${keyCount} key(s) (${Math.round(keyApproximate * 100) / 100}%)`} + + ) + + return ( +
+ {isLeaf && Node} + {!isLeaf && ( + + {Node} + + )} +
+ ) +} + +export default Node diff --git a/redisinsight/ui/src/components/virtual-tree/components/Node/index.ts b/redisinsight/ui/src/components/virtual-tree/components/Node/index.ts new file mode 100644 index 0000000000..15472d4f72 --- /dev/null +++ b/redisinsight/ui/src/components/virtual-tree/components/Node/index.ts @@ -0,0 +1,5 @@ +import Node from './Node' + +export { Node } + +export default Node diff --git a/redisinsight/ui/src/components/virtual-tree/components/Node/styles.module.scss b/redisinsight/ui/src/components/virtual-tree/components/Node/styles.module.scss new file mode 100644 index 0000000000..c4932258fe --- /dev/null +++ b/redisinsight/ui/src/components/virtual-tree/components/Node/styles.module.scss @@ -0,0 +1,62 @@ +.anchorTooltipNode { + width: 100%; + display: inline-block; + position: relative; +} + +.nodeContainer { + border-left: 3px solid transparent; + + &:hover { + background-color: var(--browserTreeNodeOpen); + } +} + +.nodeContent { + display: flex; + justify-content: space-between; + cursor: pointer; + padding-right: 8px; + color: var(--euiTextSubduedColor) !important; + font: normal normal normal 13px/28px Graphik, sans-serif !important; + letter-spacing: -0.13px; + + + &Open { + color: var(--euiColorFullShade) !important; + } +} + +.nodeSelected { + // border-left: 3px solid transparent; + border-left-color: var(--euiColorPrimary) !important; + background-color: var(--browserTreeNodeOpen); + + .nodeContent { + color: var(--euiColorFullShade) !important; + } +} + +.nodeIcon { + margin-right: 8px; + + &Arrow { + margin-left: 8px; + margin-right: 6px; + width: 10px !important; + height: 10px !important; + } + + &Leaf { + margin-left: 25px; + margin-bottom: 2px; + width: 14px; + height: 14px; + } +} + +.approximate { + display: inline-block; + width: 36px; + text-align: end; +} diff --git a/redisinsight/ui/src/components/virtual-tree/index.ts b/redisinsight/ui/src/components/virtual-tree/index.ts new file mode 100644 index 0000000000..af2d6857c2 --- /dev/null +++ b/redisinsight/ui/src/components/virtual-tree/index.ts @@ -0,0 +1,7 @@ +import VirtualTree from './VirtualTree' + +export * from './interfaces' + +export { VirtualTree } + +export default VirtualTree diff --git a/redisinsight/ui/src/components/virtual-tree/interfaces.ts b/redisinsight/ui/src/components/virtual-tree/interfaces.ts new file mode 100644 index 0000000000..4c3f3535c9 --- /dev/null +++ b/redisinsight/ui/src/components/virtual-tree/interfaces.ts @@ -0,0 +1,50 @@ +import { FixedSizeNodeData } from 'react-vtree' +import { IKeyPropTypes } from 'uiSrc/constants/prop-types/keys' + +export interface TreeNode { + children: TreeNode[] + id: number + keyCount: number + keyApproximate: number + fullName: string + name: string + keys: any[] + 'keys:keys'?: any +} + +export interface NodeMeta { + nestingLevel: number; + node: TreeNode; + data: NodeMetaData +} + +export interface NodeMetaData { + id: string, + isLeaf: boolean, + keyCount: number, + name: string, + fullName: string, + setItems: (keys: any[]) => void, + updateStatusSelected: (fullName: string, keys: any) => void, + updateStatusOpen: (name: string, value: boolean) => void, + leafIcon: string, + keyApproximate: number, + keys: any, + isSelected: boolean, + isOpenByDefault: boolean, +} + +export interface TreeData extends FixedSizeNodeData { + isLeaf: boolean + name: string + keyCount: number + keyApproximate: number + fullName: string + leafIcon: string + keys: IKeyPropTypes[] + nestingLevel: number + isSelected: boolean + setItems: (keys: any[]) => void + updateStatusOpen: (fullName: string, value: boolean) => void + updateStatusSelected: (fullName: string, keys: IKeyPropTypes[]) => void +} diff --git a/redisinsight/ui/src/components/virtual-tree/styles.module.scss b/redisinsight/ui/src/components/virtual-tree/styles.module.scss new file mode 100644 index 0000000000..88595be6ce --- /dev/null +++ b/redisinsight/ui/src/components/virtual-tree/styles.module.scss @@ -0,0 +1,38 @@ +@import '@elastic/eui/src/global_styling/mixins/helpers'; +@import '@elastic/eui/src/components/table/mixins'; +@import '@elastic/eui/src/global_styling/index'; + +.customScroll { + @include euiScrollBar; + + height: 100%; + position: relative; +} + +.loadingContainer { + display: flex; + width: 100%; + height: 100%; + align-items: center; +} + +.loadingBody { + display: flex; + width: 54px; + height: 54px; + margin: auto; + position: relative; +} + +.loadingSpinner { + width: 54px !important; + height: 54px !important; +} + +.loadingIcon { + position: absolute; + width: 28px !important; + height: 28px !important; + top: 12px; + left: 12px; +} diff --git a/redisinsight/ui/src/constants/api.ts b/redisinsight/ui/src/constants/api.ts index 3fa425d886..fb1ca509e4 100644 --- a/redisinsight/ui/src/constants/api.ts +++ b/redisinsight/ui/src/constants/api.ts @@ -54,7 +54,9 @@ enum ApiEndpoints { export const DEFAULT_SEARCH_MATCH = '*' const SCAN_COUNT_DEFAULT_ENV = process.env.SCAN_COUNT_DEFAULT || '500' +const SCAN_TREE_COUNT_DEFAULT_ENV = process.env.SCAN_TREE_COUNT_DEFAULT || '10000' export const SCAN_COUNT_DEFAULT = parseInt(SCAN_COUNT_DEFAULT_ENV, 10) +export const SCAN_TREE_COUNT_DEFAULT = parseInt(SCAN_TREE_COUNT_DEFAULT_ENV, 10) export default ApiEndpoints diff --git a/redisinsight/ui/src/constants/browser.ts b/redisinsight/ui/src/constants/browser.ts new file mode 100644 index 0000000000..1c7a18714f --- /dev/null +++ b/redisinsight/ui/src/constants/browser.ts @@ -0,0 +1 @@ +export const DEFAULT_SEPARATOR = ':' diff --git a/redisinsight/ui/src/constants/index.ts b/redisinsight/ui/src/constants/index.ts index 3cd6b3eb0b..d4aaa5cea8 100644 --- a/redisinsight/ui/src/constants/index.ts +++ b/redisinsight/ui/src/constants/index.ts @@ -18,4 +18,5 @@ export * from './socketEvents' export * from './mocks/mock-redis-commands' export * from './mocks/mock-enablement-area' export * from './socketErrors' +export * from './browser' export { ApiEndpoints, BrowserStorageItem, ApiStatusCode, apiErrors } diff --git a/redisinsight/ui/src/constants/storage.ts b/redisinsight/ui/src/constants/storage.ts index 2ed5408c4a..57176c18e0 100644 --- a/redisinsight/ui/src/constants/storage.ts +++ b/redisinsight/ui/src/constants/storage.ts @@ -1,6 +1,7 @@ enum BrowserStorageItem { instancesCount = 'instancesCount', theme = 'theme', + browserViewType = 'browserViewType', cliClientUuid = 'cliClientUuid', cliResizableContainer = 'cliResizableContainer', cliInputHistory = 'cliInputHistory', @@ -8,7 +9,7 @@ enum BrowserStorageItem { segmentAnonymousId = 'ajs_anonymous_id', wbClientUuid = 'wbClientUuid', wbInputHistory = 'wbInputHistory', - isEnablementAreaMinimized = 'isEnablementAreaMinimized' + isEnablementAreaMinimized = 'isEnablementAreaMinimized', } export default BrowserStorageItem diff --git a/redisinsight/ui/src/helpers/constructKeysToTree.ts b/redisinsight/ui/src/helpers/constructKeysToTree.ts new file mode 100644 index 0000000000..6e3743dfed --- /dev/null +++ b/redisinsight/ui/src/helpers/constructKeysToTree.ts @@ -0,0 +1,91 @@ +import { IKeyPropTypes } from 'uiSrc/constants/prop-types/keys' + +interface Props { + items: IKeyPropTypes[] + separator?: string +} + +export const constructKeysToTree = (props: Props): any[] => { + const { items: keys, separator = ':' } = props + // const keysSymbol = Symbol(`keys${separator}keys`) + // const keysSymbol = Symbol('keys') + const keysSymbol = `keys${separator}keys` + const tree: any = {} + + keys.forEach((key: any) => { + // eslint-disable-next-line prefer-object-spread + let currentNode: any = tree + const { name } = key + const nameSplitted = name.split(separator) + const lastIndex = nameSplitted.length - 1 + + nameSplitted.forEach((value:any, index: number) => { + // create a key leaf + if (index === lastIndex) { + if (currentNode[keysSymbol] === undefined) { + currentNode[keysSymbol] = {} + } + + currentNode[keysSymbol][name] = key + } else if (currentNode[value] === undefined) { + currentNode[value] = {} + } + + currentNode = currentNode[value] + }) + }) + + const ids: any = {} + + // common functions + const getUniqueId = ():number | string => { + const candidateId = Math.random().toString(36) + + if (ids[candidateId]) { + return getUniqueId() + } + + ids[candidateId] = true + return candidateId + } + + // FormatTreeData + const formatTreeData = (tree: any, previousKey = '', separator = ':') => { + const treeNodes = Reflect.ownKeys(tree) + + // sort Ungrouped Keys group to top + treeNodes.some((key, index) => { + if (key === keysSymbol) { + const temp = treeNodes[0] + treeNodes[0] = key + treeNodes[index] = temp + return true + } + return false + }) + + return treeNodes.map((key) => { + const name = key?.toString() + const node: any = { name } + const tillNowKeyName = previousKey + name + separator + + // populate node with children nodes + if (key !== keysSymbol && Reflect.ownKeys(tree[key]).length > 0) { + node.children = formatTreeData(tree[key], tillNowKeyName, separator) + node.keyCount = node.children.reduce((a: any, b:any) => a + (b.keyCount || 0), 0) + } else { + // populate leaf with keys + node.children = [] + node.keys = tree[keysSymbol] ?? [] + node.keyCount = Object.keys(node.keys ?? [])?.length ?? 1 + } + + node.fullName = tillNowKeyName + node.keyApproximate = (node.keyCount / keys.length) * 100 + node.id = getUniqueId() + return node + }) + } + + return formatTreeData(tree, '', separator) +} diff --git a/redisinsight/ui/src/helpers/index.ts b/redisinsight/ui/src/helpers/index.ts new file mode 100644 index 0000000000..fb165497f0 --- /dev/null +++ b/redisinsight/ui/src/helpers/index.ts @@ -0,0 +1 @@ +export * from './constructKeysToTree' diff --git a/redisinsight/ui/src/helpers/tests/constructKeysToTree.spec.ts b/redisinsight/ui/src/helpers/tests/constructKeysToTree.spec.ts new file mode 100644 index 0000000000..aa50233014 --- /dev/null +++ b/redisinsight/ui/src/helpers/tests/constructKeysToTree.spec.ts @@ -0,0 +1,34 @@ +import { constructKeysToTree } from '../constructKeysToTree' +import { constructKeysToTreeMockResult } from './constructKeysToTreeMockResult' + +const constructKeysToTreeTests: any[] = [ + [{ + items: [ + { name: 'keys:1:2', type: 'hash', ttl: -1, size: 71 }, + { name: 'keys2', type: 'hash', ttl: -1, size: 71 }, + { name: 'keys:1:1', type: 'hash', ttl: -1, size: 71 }, + { name: 'empty::test', type: 'hash', ttl: -1, size: 71 }, + { name: 'test1', type: 'hash', ttl: -1, size: 71 }, + { name: 'test2', type: 'hash', ttl: -1, size: 71 }, + { name: 'keys:1', type: 'hash', ttl: -1, size: 71 }, + { name: 'keys1', type: 'hash', ttl: -1, size: 71 }, + { name: 'keys:3', type: 'hash', ttl: -1, size: 71 }, + { name: 'keys:2', type: 'hash', ttl: -1, size: 71 }, + ], + separator: ':' }, + constructKeysToTreeMockResult + ] +] + +const removeIds = (nodes: any[]) => nodes.map(({ children, id, ...rest }) => ({ + ...rest, + children: removeIds(children) +})) + +describe('constructKeysToTree', () => { + it.each(constructKeysToTreeTests)('for input: %s (items), should be output: %s', + (items, expected) => { + const result = constructKeysToTree(items) + expect(removeIds(result)).toEqual(expected) + }) +}) diff --git a/redisinsight/ui/src/helpers/tests/constructKeysToTreeMockResult.ts b/redisinsight/ui/src/helpers/tests/constructKeysToTreeMockResult.ts new file mode 100644 index 0000000000..8d1445ae1b --- /dev/null +++ b/redisinsight/ui/src/helpers/tests/constructKeysToTreeMockResult.ts @@ -0,0 +1,130 @@ +export const constructKeysToTreeMockResult = [ + { + name: 'keys:keys', + children: [], + keys: { + keys2: { + name: 'keys2', + type: 'hash', + ttl: -1, + size: 71 + }, + test1: { + name: 'test1', + type: 'hash', + ttl: -1, + size: 71 + }, + test2: { + name: 'test2', + type: 'hash', + ttl: -1, + size: 71 + }, + keys1: { + name: 'keys1', + type: 'hash', + ttl: -1, + size: 71 + } + }, + keyCount: 4, + fullName: 'keys:keys:', + keyApproximate: 40, + }, + { + name: 'keys', + children: [ + { + name: 'keys:keys', + children: [], + keys: { + 'keys:1': { + name: 'keys:1', + type: 'hash', + ttl: -1, + size: 71 + }, + 'keys:3': { + name: 'keys:3', + type: 'hash', + ttl: -1, + size: 71 + }, + 'keys:2': { + name: 'keys:2', + type: 'hash', + ttl: -1, + size: 71 + } + }, + keyCount: 3, + fullName: 'keys:keys:keys:', + keyApproximate: 30, + }, + { + name: '1', + children: [ + { + name: 'keys:keys', + children: [], + keys: { + 'keys:1:2': { + name: 'keys:1:2', + type: 'hash', + ttl: -1, + size: 71 + }, + 'keys:1:1': { + name: 'keys:1:1', + type: 'hash', + ttl: -1, + size: 71 + } + }, + keyCount: 2, + fullName: 'keys:1:keys:keys:', + keyApproximate: 20, + } + ], + keyCount: 2, + fullName: 'keys:1:', + keyApproximate: 20, + } + ], + keyCount: 5, + fullName: 'keys:', + keyApproximate: 50, + }, + { + name: 'empty', + children: [ + { + name: '', + children: [ + { + name: 'keys:keys', + children: [], + keys: { + 'empty::test': { + name: 'empty::test', + type: 'hash', + ttl: -1, + size: 71 + } + }, + keyCount: 1, + fullName: 'empty::keys:keys:', + keyApproximate: 10, + } + ], + keyCount: 1, + fullName: 'empty::', + keyApproximate: 10, + } + ], + keyCount: 1, + fullName: 'empty:', + keyApproximate: 10, + } +] diff --git a/redisinsight/ui/src/pages/browser/BrowserPage.spec.tsx b/redisinsight/ui/src/pages/browser/BrowserPage.spec.tsx index 6efc268f05..2742b40933 100644 --- a/redisinsight/ui/src/pages/browser/BrowserPage.spec.tsx +++ b/redisinsight/ui/src/pages/browser/BrowserPage.spec.tsx @@ -11,6 +11,7 @@ import KeyDetailsWrapper, { Props as KeyDetailsWrapperProps } from './components/key-details/KeyDetailsWrapper' import AddKey, { Props as AddKeyProps } from './components/add-key/AddKey' +import KeysHeader, { Props as KeysHeaderProps } from './components/keys-header' jest.mock('./components/key-list/KeyList', () => ({ __esModule: true, @@ -30,19 +31,18 @@ jest.mock('./components/key-details/KeyDetailsWrapper', () => ({ default: jest.fn(), })) +jest.mock('./components/keys-header', () => ({ + __esModule: true, + namedExport: jest.fn(), + default: jest.fn(), +})) + const mockKeyList = (props: KeyListProps) => (
- @@ -61,6 +61,18 @@ const mockAddKey = (props: AddKeyProps) => (
) +const mockKeysHeader = (props: KeysHeaderProps) => ( +
+ +
+) + let store: typeof mockedStore beforeEach(() => { cleanup() @@ -71,6 +83,7 @@ beforeEach(() => { describe('BrowserPage', () => { beforeAll(() => { KeyList.mockImplementation(mockKeyList) + KeysHeader.mockImplementation(mockKeysHeader) KeyDetailsWrapper.mockImplementation(mockKeyDetailsWrapper) AddKey.mockImplementation(mockAddKey) }) diff --git a/redisinsight/ui/src/pages/browser/BrowserPage.tsx b/redisinsight/ui/src/pages/browser/BrowserPage.tsx index c097d5b518..c9d34e1e63 100644 --- a/redisinsight/ui/src/pages/browser/BrowserPage.tsx +++ b/redisinsight/ui/src/pages/browser/BrowserPage.tsx @@ -5,7 +5,7 @@ import cx from 'classnames' import { EuiResizableContainer } from '@elastic/eui' import { formatLongName, getDbIndex, Nullable, setTitle } from 'uiSrc/utils' -import { SCAN_COUNT_DEFAULT } from 'uiSrc/constants/api' +import { SCAN_COUNT_DEFAULT, SCAN_TREE_COUNT_DEFAULT } from 'uiSrc/constants/api' import { sendPageViewTelemetry, TelemetryPageView } from 'uiSrc/telemetry' import { fetchKeys, @@ -28,15 +28,18 @@ import { import { appAnalyticsInfoSelector } from 'uiSrc/slices/app/info' import { resetErrors } from 'uiSrc/slices/app/notifications' import InstanceHeader from 'uiSrc/components/instance-header' +import { KeyViewType } from 'uiSrc/slices/interfaces/keys' import AddKey from './components/add-key/AddKey' import KeyList from './components/key-list/KeyList' +import KeyTree from './components/key-tree' +import KeysHeader from './components/keys-header' import KeyDetailsWrapper from './components/key-details/KeyDetailsWrapper' import styles from './styles.module.scss' const widthResponsiveSize = 1124 -export const firstPanelId = 'keyList' +export const firstPanelId = 'keys' export const secondPanelId = 'keyDetails' const BrowserPage = () => { @@ -48,7 +51,7 @@ const BrowserPage = () => { panelSizes } = useSelector(appContextBrowser) const keysState = useSelector(keysDataSelector) - const { loading } = useSelector(keysSelector) + const { loading, viewType } = useSelector(keysSelector) const { type } = useSelector(selectedKeyDataSelector) ?? { type: '' } const [isPageViewSent, setIsPageViewSent] = useState(false) @@ -115,11 +118,11 @@ const BrowserPage = () => { setIsPageViewSent(true) } - const loadKeys = () => { + const loadKeys = (keyViewType?: KeyViewType) => { dispatch(setConnectedInstanceId(instanceId)) dispatch(fetchKeys( '0', - SCAN_COUNT_DEFAULT, + keyViewType === KeyViewType.Browser ? SCAN_COUNT_DEFAULT : SCAN_TREE_COUNT_DEFAULT, () => dispatch(setBrowserKeyListDataLoaded(true)), () => dispatch(setBrowserKeyListDataLoaded(false)) )) @@ -167,7 +170,7 @@ const BrowserPage = () => { id={firstPanelId} scrollable={false} initialSize={sizes[firstPanelId] ?? 50} - minSize="510px" + minSize="670px" paddingSize="none" wrapperProps={{ className: cx(styles.resizePanelLeft, { @@ -175,13 +178,34 @@ const BrowserPage = () => { }), }} > - + <> + + + {viewType === KeyViewType.Browser && ( + + )} + {viewType === KeyViewType.Tree && ( + + )} + () let store: typeof mockedStore const filterSelectId = 'select-filter-key-type' @@ -35,13 +35,13 @@ beforeEach(() => { describe('FilterKeyType', () => { it('should render', () => { - expect(render()).toBeTruthy() + expect(render()).toBeTruthy() const searchInput = screen.getByTestId(filterSelectId) expect(searchInput).toBeInTheDocument() }) it('should not be disabled filter with database redis version > 6.0', () => { - render() + render() const filterSelect = screen.getByTestId(filterSelectId) expect(filterSelect).not.toBeDisabled() @@ -49,20 +49,25 @@ describe('FilterKeyType', () => { it('should be info icon with database redis version > 6.0', () => { const { queryByTestId } = render( - + ) expect(queryByTestId(filterInfoId)).not.toBeInTheDocument() }) it('"setFilter" and "loadKeys" should be called after selecte "Hash" type', () => { const { queryByText } = render( - + ) fireEvent.click(screen.getByTestId(filterSelectId)) fireEvent.click(queryByText('Hash') || document) - const expectedActions = [setFilter(KeyTypes.Hash), loadKeys()] + const expectedActions = [ + setFilter(KeyTypes.Hash), + loadKeys(), + setBrowserTreeNodesOpen({}), + setBrowserTreeSelectedLeaf({}) + ] expect(clearStoreActions(store.getActions())).toEqual( clearStoreActions(expectedActions) ) @@ -72,7 +77,7 @@ describe('FilterKeyType', () => { connectedInstanceOverviewSelector.mockImplementation(() => ({ version: '5.1', })) - render() + render() const filterSelect = screen.getByTestId(filterSelectId) expect(filterSelect).toBeDisabled() @@ -82,7 +87,7 @@ describe('FilterKeyType', () => { connectedInstanceOverviewSelector.mockImplementation(() => ({ version: '5.1', })) - render() + render() expect(screen.getByTestId(filterInfoId)).toBeInTheDocument() }) }) diff --git a/redisinsight/ui/src/pages/browser/components/filter-key-type/FilterKeyType.tsx b/redisinsight/ui/src/pages/browser/components/filter-key-type/FilterKeyType.tsx index c97086865e..4b307cfbb6 100644 --- a/redisinsight/ui/src/pages/browser/components/filter-key-type/FilterKeyType.tsx +++ b/redisinsight/ui/src/pages/browser/components/filter-key-type/FilterKeyType.tsx @@ -9,12 +9,14 @@ import { import cx from 'classnames' import React, { useEffect, useState } from 'react' import { useDispatch, useSelector } from 'react-redux' -import { SCAN_COUNT_DEFAULT } from 'uiSrc/constants/api' +import { SCAN_COUNT_DEFAULT, SCAN_TREE_COUNT_DEFAULT } from 'uiSrc/constants/api' import { CommandsVersions } from 'uiSrc/constants/commandsVersions' import { connectedInstanceOverviewSelector } from 'uiSrc/slices/instances' import { fetchKeys, keysSelector, setFilter } from 'uiSrc/slices/keys' import { isVersionHigherOrEquals } from 'uiSrc/utils' import HelpTexts from 'uiSrc/constants/help-texts' +import { setBrowserTreeNodesOpen, setBrowserTreeSelectedLeaf } from 'uiSrc/slices/app/context' +import { KeyViewType } from 'uiSrc/slices/interfaces/keys' import { FILTER_KEY_TYPE_OPTIONS } from './constants' import styles from './styles.module.scss' @@ -26,7 +28,7 @@ const FilterKeyType = () => { const [isInfoPopoverOpen, setIsInfoPopoverOpen] = useState(false) const { version } = useSelector(connectedInstanceOverviewSelector) - const { filter } = useSelector(keysSelector) + const { filter, viewType } = useSelector(keysSelector) const dispatch = useDispatch() useEffect(() => { @@ -68,7 +70,11 @@ const FilterKeyType = () => { setTypeSelected(value) setIsSelectOpen(false) dispatch(setFilter(value || null)) - dispatch(fetchKeys('0', SCAN_COUNT_DEFAULT)) + dispatch(fetchKeys('0', viewType === KeyViewType.Browser ? SCAN_COUNT_DEFAULT : SCAN_TREE_COUNT_DEFAULT)) + + // reset browser tree context + dispatch(setBrowserTreeNodesOpen({})) + dispatch(setBrowserTreeSelectedLeaf({})) } const UnsupportedInfo = () => ( diff --git a/redisinsight/ui/src/pages/browser/components/hash-details/styles.module.scss b/redisinsight/ui/src/pages/browser/components/hash-details/styles.module.scss index 0a40b24bb0..5bc7d3b97d 100644 --- a/redisinsight/ui/src/pages/browser/components/hash-details/styles.module.scss +++ b/redisinsight/ui/src/pages/browser/components/hash-details/styles.module.scss @@ -2,6 +2,6 @@ display: flex; flex: 1; width: 100%; - padding: 16px 16px 30px; + padding: 16px; background-color: var(--euiColorEmptyShade); } diff --git a/redisinsight/ui/src/pages/browser/components/key-details/styles.module.scss b/redisinsight/ui/src/pages/browser/components/key-details/styles.module.scss index 5f73431790..dba08481c2 100644 --- a/redisinsight/ui/src/pages/browser/components/key-details/styles.module.scss +++ b/redisinsight/ui/src/pages/browser/components/key-details/styles.module.scss @@ -18,8 +18,6 @@ .content { height: calc(100% - 220px); background-color: var(--euiColorEmptyShade); - border: 1px solid var(--euiColorLightShade); - border-bottom-width: 0; > div { height: 100%; } diff --git a/redisinsight/ui/src/pages/browser/components/key-list/KeyList.spec.tsx b/redisinsight/ui/src/pages/browser/components/key-list/KeyList.spec.tsx index 850de75192..40e87dd6a3 100644 --- a/redisinsight/ui/src/pages/browser/components/key-list/KeyList.spec.tsx +++ b/redisinsight/ui/src/pages/browser/components/key-list/KeyList.spec.tsx @@ -31,7 +31,7 @@ const propsMock = { nextCursor: '0', total: 3, } as IKeyListPropTypes, - loadingState: false, + loading: false, selectKey: jest.fn(), loadMoreItems: jest.fn(), handleAddKeyPanel: jest.fn(), @@ -49,10 +49,4 @@ describe('KeyList', () => { ) expect(rows).toHaveLength(3) }) - - it('should render search properly', () => { - render() - const searchInput = screen.queryByTestId('search-key') - expect(searchInput).toBeInTheDocument() - }) }) diff --git a/redisinsight/ui/src/pages/browser/components/key-list/KeyList.tsx b/redisinsight/ui/src/pages/browser/components/key-list/KeyList.tsx index 076a37678d..013c649400 100644 --- a/redisinsight/ui/src/pages/browser/components/key-list/KeyList.tsx +++ b/redisinsight/ui/src/pages/browser/components/key-list/KeyList.tsx @@ -1,16 +1,13 @@ -import React, { useState } from 'react' +import React from 'react' import { useDispatch, useSelector } from 'react-redux' +import cx from 'classnames' + import { - EuiButton, EuiIcon, EuiText, - EuiFlexGroup, - EuiFlexItem, - EuiButtonIcon, EuiToolTip, EuiTextColor, } from '@elastic/eui' -import { formatDistanceToNow } from 'date-fns' import { formatBytes, formatLongName, @@ -26,7 +23,6 @@ import { ScanNoResultsFoundText, } from 'uiSrc/constants/texts' import { - fetchKeys, keysDataSelector, keysSelector, selectedKeySelector, @@ -34,69 +30,36 @@ import { } from 'uiSrc/slices/keys' import { appContextBrowser, - setBrowserKeyListDataLoaded, setBrowserKeyListScrollPosition } from 'uiSrc/slices/app/context' -import { connectedInstanceSelector } from 'uiSrc/slices/instances' import { GroupBadge } from 'uiSrc/components' -import { sendEventTelemetry, TelemetryEvent } from 'uiSrc/telemetry' import { SCAN_COUNT_DEFAULT } from 'uiSrc/constants/api' import { IKeyListPropTypes } from 'uiSrc/constants/prop-types/keys' import VirtualTable from 'uiSrc/components/virtual-table/VirtualTable' import { ITableColumn } from 'uiSrc/components/virtual-table/interfaces' import { TableCellAlignment, TableCellTextAlignment } from 'uiSrc/constants' -import FilterKeyType from '../filter-key-type' -import SearchKeyList from '../search-key-list' - import styles from './styles.module.scss' export interface Props { - keysState: IKeyListPropTypes; - loading: boolean; - selectKey: ({ rowData }: { rowData: any }) => void; - loadMoreItems: ({ startIndex, stopIndex }: { startIndex: number; stopIndex: number }) => void; - handleAddKeyPanel: (value: boolean) => void; + hideHeader?: boolean + keysState: IKeyListPropTypes + loading: boolean + hideFooter?: boolean + selectKey: ({ rowData }: { rowData: any }) => void + loadMoreItems?: ({ startIndex, stopIndex }: { startIndex: number, stopIndex: number }) => void } const KeyList = (props: Props) => { let wheelTimer = 0 - const { selectKey, loadMoreItems, loading, keysState, handleAddKeyPanel } = props - - const [lastRefreshMessage, setLastRefreshMessage] = useState('') + const { selectKey, loadMoreItems, loading, keysState, hideFooter } = props const { data: selectedKey } = useSelector(selectedKeySelector) - const { total, nextCursor, previousResultCount, lastRefreshTime } = useSelector(keysDataSelector) + const { total, nextCursor, previousResultCount } = useSelector(keysDataSelector) const { isSearched, isFiltered } = useSelector(keysSelector) - const { id: instanceId } = useSelector(connectedInstanceSelector) const { keyList: { scrollTopPosition } } = useSelector(appContextBrowser) const dispatch = useDispatch() - const handleRefreshKeys = () => { - sendEventTelemetry({ - event: TelemetryEvent.BROWSER_KEY_LIST_REFRESH_CLICKED, - eventData: { - databaseId: instanceId - } - }) - dispatch(fetchKeys( - '0', - SCAN_COUNT_DEFAULT, - () => dispatch(setBrowserKeyListDataLoaded(true)), - () => dispatch(setBrowserKeyListDataLoaded(false)), - )) - } - - const openAddKeyPanel = () => { - handleAddKeyPanel(true) - sendEventTelemetry({ - event: TelemetryEvent.BROWSER_KEY_ADD_BUTTON_CLICKED, - eventData: { - databaseId: instanceId - } - }) - } - const getNoItemsMessage = () => { if (isSearched) { return keysState.scanned < total ? ScanNoResultsFoundText : FullScanNoResultsFoundText @@ -107,14 +70,6 @@ const KeyList = (props: Props) => { return total ? NoResultsFoundText : NoKeysToDisplayText } - const updateLastRefresh = () => { - setLastRefreshMessage( - lastRefreshTime - ? `${formatDistanceToNow(lastRefreshTime, { addSuffix: true })}` - : 'Refresh' - ) - } - const onWheelSearched = (event: React.WheelEvent) => { if ( !loading @@ -126,7 +81,7 @@ const KeyList = (props: Props) => { ) { clearTimeout(wheelTimer) wheelTimer = window.setTimeout(() => { - loadMoreItems({ stopIndex: SCAN_COUNT_DEFAULT, startIndex: 1 }) + loadMoreItems?.({ stopIndex: SCAN_COUNT_DEFAULT, startIndex: 1 }) }, 100) } } @@ -135,39 +90,18 @@ const KeyList = (props: Props) => { dispatch(setBrowserKeyListScrollPosition(position)) } - const keyHeaderLabel = ( - - - Key - - - - - + Key - - - - ) - const columns: ITableColumn[] = [ { id: 'type', label: 'Type', - absoluteWidth: 107, - minWidth: 107, + absoluteWidth: 'auto', + minWidth: 124, render: (cellData: any, { name }: any) => , }, { id: 'name', - label: keyHeaderLabel, - minWidth: 160, + label: 'Key', + minWidth: 100, truncateText: true, render: (cellData: string = '', { name }: any) => { // Better to cut the long string, because it could affect virtual scroll performance @@ -281,35 +215,11 @@ const KeyList = (props: Props) => { return (
-
- - -
- - - -
-
- -
+
{ selectedKey={selectedKey} scrollTopProp={scrollTopPosition} setScrollTopPosition={setScrollTopPosition} + hideFooter={hideFooter} />
diff --git a/redisinsight/ui/src/pages/browser/components/key-list/styles.module.scss b/redisinsight/ui/src/pages/browser/components/key-list/styles.module.scss index 63c18840eb..15fc8becf0 100644 --- a/redisinsight/ui/src/pages/browser/components/key-list/styles.module.scss +++ b/redisinsight/ui/src/pages/browser/components/key-list/styles.module.scss @@ -1,6 +1,7 @@ .page { height: 100%; overflow: hidden; + padding-right: 1px; } .tooltip { @@ -11,29 +12,20 @@ width: 100%; height: 100%; background-color: var(--euiColorEmptyShade); - border-top: 1px solid var(--euiColorLightShade); } .table { height: calc(100% - 48px); - border: 1px solid var(--euiColorLightShade); - border-bottom: none; + + &__withoutFooter { + height: calc(100% - 50px) !important; + } } :global(.show-cli) .table { border-bottom: 1px solid var(--euiColorLightShade); } -.header { - height: 48px; - padding-left: 8px; - border-left: 1px solid var(--euiColorLightShade); - border-right: 1px solid var(--euiColorLightShade); - display: flex; - align-items: center; - position: relative; -} - .filter { display: inline-block; width: 100px; @@ -42,18 +34,6 @@ background-color: var(--tableLightestBorderColor); } -.refresh { - right: 18px; - position: absolute; -} - -.btnRefresh { - svg { - width: 20px; - height: 20px; - } -} - .action { opacity: 0; transition: opacity 250ms ease-in-out; diff --git a/redisinsight/ui/src/pages/browser/components/key-tree/KeyTree.spec.tsx b/redisinsight/ui/src/pages/browser/components/key-tree/KeyTree.spec.tsx new file mode 100644 index 0000000000..aff47e317e --- /dev/null +++ b/redisinsight/ui/src/pages/browser/components/key-tree/KeyTree.spec.tsx @@ -0,0 +1,136 @@ +import { cloneDeep } from 'lodash' +import React from 'react' +import { + cleanup, + clearStoreActions, + fireEvent, + mockedStore, + render, + screen, +} from 'uiSrc/utils/test-utils' +import { setSearchMatch } from 'uiSrc/slices/keys' +import { IKeyListPropTypes } from 'uiSrc/constants/prop-types/keys' +import { mockVirtualTreeResult } from 'uiSrc/components/virtual-tree/VirtualTree.spec' +import { setBrowserTreeNodesOpen, setBrowserTreeSelectedLeaf } from 'uiSrc/slices/app/context' +import KeyTree from './KeyTree' + +let store: typeof mockedStore +beforeEach(() => { + cleanup() + store = cloneDeep(mockedStore) + store.clearActions() +}) + +const propsMock = { + keysState: { + keys: [ + { + name: 'key1', + type: 'hash', + ttl: -1, + size: 100, + length: 100, + }, + { + name: 'key2', + type: 'hash', + ttl: -1, + size: 150, + length: 100, + }, + { + name: 'key3', + type: 'hash', + ttl: -1, + size: 110, + length: 100, + }, + ], + nextCursor: '0', + total: 3, + } as IKeyListPropTypes, + loading: false, + selectKey: jest.fn(), +} + +const mockLeafKeys = { + test: { name: 'test', type: 'hash', ttl: -1, size: 9849176 } +} + +const mockWebWorkerResult = [{ + children: [{ + children: [], + fullName: 'car:110:', + id: '0.snc1rc3zwgo', + keyApproximate: 0.01, + keyCount: 1, + name: '110', + }], + fullName: 'car:', + id: '0.sz1ie1koqi8', + keyApproximate: 47.18, + keyCount: 4718, + name: 'car', +}, +{ + children: [], + fullName: 'test', + id: '0.snc1rc3zwg1o', + keyApproximate: 0.01, + keyCount: 1, + name: 'test', + keys: mockLeafKeys +}] + +jest.mock('uiSrc/services', () => ({ + ...jest.requireActual('uiSrc/services'), + useDisposableWebworker: () => ({ result: mockWebWorkerResult, run: jest.fn() }), +})) + +describe('KeyTree', () => { + it('Key tree separator should be in the document', () => { + render() + + expect(screen.getByTestId('select-tree-view-separator')).toBeInTheDocument() + }) + + it('Tree view panel should be in the document', () => { + const { container } = render() + + expect(container.querySelector('[data-test-subj="tree-view-panel"]')).toBeInTheDocument() + }) + + it('Key list panel should be in the document', () => { + const { container } = render() + + expect(container.querySelector('[data-test-subj="key-list-panel"]')).toBeInTheDocument() + }) + + it.only('"setBrowserTreeNodesOpen" should be called for Open a node', () => { + render() + + fireEvent.click(screen.getByTestId(mockVirtualTreeResult?.[0]?.fullName)) + + const expectedActions = [setBrowserTreeSelectedLeaf({}), setBrowserTreeNodesOpen({})] + + expect(clearStoreActions(store.getActions())).toEqual( + clearStoreActions(expectedActions) + ) + }) + + it.skip('"setSearchMatch" should be called after "onChange"', () => { + const searchTerm = 'a' + + render() + + fireEvent.change(screen.getByTestId('search-key'), { + target: { value: searchTerm }, + }) + + const expectedActions = [setSearchMatch(searchTerm)] + + expect(clearStoreActions(store.getActions())).toEqual( + clearStoreActions(expectedActions) + ) + }) +}) diff --git a/redisinsight/ui/src/pages/browser/components/key-tree/KeyTree.tsx b/redisinsight/ui/src/pages/browser/components/key-tree/KeyTree.tsx new file mode 100644 index 0000000000..9cc5a1a7aa --- /dev/null +++ b/redisinsight/ui/src/pages/browser/components/key-tree/KeyTree.tsx @@ -0,0 +1,187 @@ +import React, { useCallback, useEffect, useState } from 'react' +import cx from 'classnames' +import { EuiResizableContainer, EuiSuperSelect, EuiSuperSelectOption } from '@elastic/eui' +import { useDispatch, useSelector } from 'react-redux' + +import { + appContextBrowserTree, + setBrowserTreeNodesOpen, + setBrowserTreeSelectedLeaf +} from 'uiSrc/slices/app/context' +import { constructKeysToTree } from 'uiSrc/helpers' +import VirtualTree from 'uiSrc/components/virtual-tree' +import { DEFAULT_SEPARATOR } from 'uiSrc/constants' +import { IKeyListPropTypes, } from 'uiSrc/constants/prop-types/keys' +import TreeViewSVG from 'uiSrc/assets/img/icons/treeview.svg' + +import KeyList from '../key-list/KeyList' +import styles from './styles.module.scss' + +export interface Props { + keysState: IKeyListPropTypes + loading: boolean + selectKey: ({ rowData }: { rowData: any }) => void +} + +export const firstPanelId = 'tree' +export const secondPanelId = 'keys' + +const KeyTree = (props: Props) => { + const { selectKey, loading, keysState } = props + + const firstPanelId = 'tree' + const secondPanelId = 'keys' + + const { panelSizes, openNodes, selectedLeaf } = useSelector(appContextBrowserTree) + + const [statusSelected, setStatusSelected] = useState(selectedLeaf) + const [statusOpen, setStatusOpen] = useState(openNodes) + const [sizes, setSizes] = useState(panelSizes) + const [separator, setSeparator] = useState(DEFAULT_SEPARATOR) + const [keyListState, setKeyListState] = useState(keysState) + const [constructingTree, setConstructingTree] = useState(false) + + const dispatch = useDispatch() + + useEffect(() => { + updateKeysList() + }, []) + + useEffect(() => { + setStatusOpen(openNodes) + }, [openNodes]) + + useEffect(() => { + if (selectedLeaf) { + setStatusSelected(selectedLeaf) + updateKeysList(Object.values(selectedLeaf)[0]) + } + }, [selectedLeaf]) + + const options: EuiSuperSelectOption[] = [{ + value: DEFAULT_SEPARATOR, + inputDisplay: DEFAULT_SEPARATOR, + 'data-test-subj': 'separator-colon', + }] + + const updateKeysList = (items:any = {}) => { + const newState:IKeyListPropTypes = { + ...keyListState, + keys: Object.values(items) + } + + setKeyListState(newState) + } + + const onPanelWidthChange = useCallback((newSizes: any) => { + setSizes((prevSizes: any) => ({ + ...prevSizes, + ...newSizes, + })) + }, []) + + const onChangeSeparator = (initValue: string) => { + setSeparator(initValue) + } + + const handleStatusOpen = (name: string, value:boolean) => { + setStatusOpen((prevState) => { + const newState = { ...prevState } + + // add or remove opened node + if (newState[name]) { + delete newState[name] + } else { + newState[name] = value + } + + dispatch(setBrowserTreeNodesOpen(newState)) + return newState + }) + } + + const handleStatusSelected = (fullName: string, keys: any) => { + dispatch(setBrowserTreeSelectedLeaf({ [fullName]: keys })) + } + + return ( +
+
+
+ + {(EuiResizablePanel, EuiResizableButton) => ( + <> + +
+ onChangeSeparator(value)} + data-testid="select-tree-view-separator" + /> + +
+
+ + + + +
+ +
+
+ + )} +
+ +
+
+
+ ) +} + +export default KeyTree diff --git a/redisinsight/ui/src/pages/browser/components/key-tree/index.ts b/redisinsight/ui/src/pages/browser/components/key-tree/index.ts new file mode 100644 index 0000000000..24664563b0 --- /dev/null +++ b/redisinsight/ui/src/pages/browser/components/key-tree/index.ts @@ -0,0 +1,3 @@ +import KeyTree from './KeyTree' + +export default KeyTree diff --git a/redisinsight/ui/src/pages/browser/components/key-tree/styles.module.scss b/redisinsight/ui/src/pages/browser/components/key-tree/styles.module.scss new file mode 100644 index 0000000000..cebf171e2f --- /dev/null +++ b/redisinsight/ui/src/pages/browser/components/key-tree/styles.module.scss @@ -0,0 +1,120 @@ +@import '@elastic/eui/src/global_styling/mixins/helpers'; +@import '@elastic/eui/src/components/table/mixins'; +@import '@elastic/eui/src/global_styling/index'; + +$selectSeparatorHeight: 18px; + +.page { + height: 100%; + overflow: hidden; +} + +.tooltip { + max-width: 372px !important; +} + +.content { + width: 100%; + height: 100%; + background-color: var(--euiColorEmptyShade); + border-top: 1px solid var(--euiColorLightShade); +} + +.body { + display: flex; + height: calc(100% - 20px); + + :global(.ReactVirtualized__Table__headerRow) { + border: none !important; + } +} + +.resizablePanelLeft { + border-right: 1px solid var(--euiColorLightShade); +} +.resizablePanelLeft, +.resizablePanelRight { + :global(.euiResizablePanel__content) { + padding-right: 0px !important; + } +} + +.resizableButton:not(:hover) { + &::before, &::after { + width: 0px !important; + } +} + +.tree { + @include euiScrollBar; + + border-bottom: none; + position: relative; + padding-top: 6px; + + height: calc(100% - 90px); + overflow: hidden; + + flex: 1; +} + +.list { + height: calc(100% + 20px); + flex: 3; + min-width: 400px; +} + +.filter { + display: inline-block; + width: 100px; + height: 38px; + margin-left: 8px; + background-color: var(--tableLightestBorderColor); +} + +.action { + opacity: 0; + transition: opacity 250ms ease-in-out; +} + +:global(.table-row-selected) .action { + opacity: 1; +} + +.separatorSelect { + width: 60px; + height: $selectSeparatorHeight; + padding-left: 12px; + margin-bottom: 10px; + + :global { + .euiSuperSelectControl, + .euiPopover__anchor { + height: $selectSeparatorHeight; + line-height: $selectSeparatorHeight; + } + + .euiSuperSelectControl { + display: flex; + align-items: flex-end; + border-color: var(--separatorColor) !important; + border-radius: 4px !important; + padding-left: 8px; + } + + .euiFormControlLayoutIcons { + right: 2px !important; + } + } + + + svg { + width: 12px !important; + height: 12px !important; + } + +} + +.separatorSelectItem { + height: $selectSeparatorHeight; +} diff --git a/redisinsight/ui/src/pages/browser/components/keys-header/KeysHeader.spec.tsx b/redisinsight/ui/src/pages/browser/components/keys-header/KeysHeader.spec.tsx new file mode 100644 index 0000000000..003baa7cff --- /dev/null +++ b/redisinsight/ui/src/pages/browser/components/keys-header/KeysHeader.spec.tsx @@ -0,0 +1,58 @@ +import React from 'react' +import { render, screen } from 'uiSrc/utils/test-utils' +import { IKeyListPropTypes } from 'uiSrc/constants/prop-types/keys' +import KeysHeader from './KeysHeader' + +const propsMock = { + keysState: { + keys: [ + { + name: 'key1', + type: 'hash', + ttl: -1, + size: 100, + length: 100, + }, + { + name: 'key2', + type: 'hash', + ttl: -1, + size: 150, + length: 100, + }, + { + name: 'key3', + type: 'hash', + ttl: -1, + size: 110, + length: 100, + }, + ], + nextCursor: '0', + total: 3, + } as IKeyListPropTypes, + loading: false, + sizes: {}, + loadKeys: jest.fn(), + loadMoreItems: jest.fn(), + handleAddKeyPanel: jest.fn(), +} + +describe('KeysHeader', () => { + it('should render', () => { + expect(render()).toBeTruthy() + }) + + it('should render search properly', () => { + render() + const searchInput = screen.queryByTestId('search-key') + expect(searchInput).toBeInTheDocument() + }) + + it('should render key view type switcher properly', () => { + render() + + const keyViewTypeSwitcherInput = screen.queryByTestId('key-view-type-switcher') + expect(keyViewTypeSwitcherInput).toBeInTheDocument() + }) +}) diff --git a/redisinsight/ui/src/pages/browser/components/keys-header/KeysHeader.tsx b/redisinsight/ui/src/pages/browser/components/keys-header/KeysHeader.tsx new file mode 100644 index 0000000000..8774fc462e --- /dev/null +++ b/redisinsight/ui/src/pages/browser/components/keys-header/KeysHeader.tsx @@ -0,0 +1,257 @@ +/* eslint-disable react/no-this-in-sfc */ +import React, { Ref, useEffect, useRef, useState } from 'react' +import { useDispatch, useSelector } from 'react-redux' +import cx from 'classnames' +import { formatDistanceToNow } from 'date-fns' +import { + EuiButton, + EuiButtonIcon, + EuiTextColor, + EuiToolTip, +} from '@elastic/eui' + +import { + changeKeyViewType, + fetchKeys, + keysDataSelector, + keysSelector, +} from 'uiSrc/slices/keys' +import { + setBrowserKeyListDataLoaded, setBrowserTreeNodesOpen, setBrowserTreeSelectedLeaf, +} from 'uiSrc/slices/app/context' +import { connectedInstanceSelector } from 'uiSrc/slices/instances' +import { sendEventTelemetry, TelemetryEvent } from 'uiSrc/telemetry' +import { SCAN_COUNT_DEFAULT, SCAN_TREE_COUNT_DEFAULT } from 'uiSrc/constants/api' +import { KeyViewType } from 'uiSrc/slices/interfaces/keys' +import KeysSummary from 'uiSrc/components/keys-summary' +import { IKeyListPropTypes } from 'uiSrc/constants/prop-types/keys' +import { localStorageService } from 'uiSrc/services' +import { BrowserStorageItem } from 'uiSrc/constants' +import TreeViewSVG from 'uiSrc/assets/img/icons/treeview.svg' +import TreeViewActiveSVG from 'uiSrc/assets/img/icons/treeview_active.svg' + +import FilterKeyType from '../filter-key-type' +import SearchKeyList from '../search-key-list' + +import styles from './styles.module.scss' + +const TIMEOUT_TO_UPDATE_REFRESH_TIME = 1_000 * 60 // once a minute +const HIDE_REFRESH_LABEL_WIDTH = 650 + +interface IViewType { + tooltipText: string + type: KeyViewType + ariaLabel: string + dataTestId: string + getClassName: () => string + isActiveView: () => boolean + getIconType: () => string +} + +export interface Props { + loading: boolean + keysState: IKeyListPropTypes + sizes: any + loadKeys: (type?: KeyViewType) => void + loadMoreItems?: (config: any) => void + handleAddKeyPanel: (value: boolean) => void +} + +const KeysHeader = (props: Props) => { + let interval: NodeJS.Timeout + const { loading, keysState, sizes, loadKeys, loadMoreItems, handleAddKeyPanel } = props + + const { lastRefreshTime } = useSelector(keysDataSelector) + const { id: instanceId } = useSelector(connectedInstanceSelector) + const { viewType, isSearched, isFiltered } = useSelector(keysSelector) + + const [lastRefreshMessage, setLastRefreshMessage] = useState('') + const [showRefreshLabel, setShowRefreshLabel] = useState(true) + const rootDivRef: Ref = useRef(null) + + const dispatch = useDispatch() + + const viewTypes: IViewType[] = [ + { + type: KeyViewType.Browser, + tooltipText: 'Browser', + ariaLabel: 'Browser view button', + dataTestId: 'view-type-browser-btn', + isActiveView() { return viewType === this.type }, + getClassName() { + return cx(styles.viewTypeBtn, { [styles.active]: this.isActiveView() }) + }, + getIconType() { + return 'menu' + }, + }, + { + type: KeyViewType.Tree, + tooltipText: 'Tree View', + ariaLabel: 'Tree view button', + dataTestId: 'view-type-list-btn', + isActiveView() { return viewType === this.type }, + getClassName() { + return cx(styles.viewTypeBtn, { [styles.active]: this.isActiveView() }) + }, + getIconType() { + return this.isActiveView() ? TreeViewActiveSVG : TreeViewSVG + }, + }, + ] + + const scanMoreStyle = { + marginLeft: 10, + height: '36px !important', + } + + useEffect(() => { + updateLastRefresh() + + interval = setInterval(() => { + if (document.hidden) return + + updateLastRefresh() + }, TIMEOUT_TO_UPDATE_REFRESH_TIME) + return () => clearInterval(interval) + }, [lastRefreshTime]) + + useEffect(() => { + const isShowRefreshLabel = (rootDivRef?.current?.offsetWidth || 0) > HIDE_REFRESH_LABEL_WIDTH + if (isShowRefreshLabel !== showRefreshLabel) { + setShowRefreshLabel(isShowRefreshLabel) + } + }, [sizes]) + + const handleRefreshKeys = () => { + sendEventTelemetry({ + event: TelemetryEvent.BROWSER_KEY_LIST_REFRESH_CLICKED, + eventData: { + databaseId: instanceId + } + }) + dispatch(fetchKeys( + '0', + viewType === KeyViewType.Browser ? SCAN_COUNT_DEFAULT : SCAN_TREE_COUNT_DEFAULT, + () => dispatch(setBrowserKeyListDataLoaded(true)), + () => dispatch(setBrowserKeyListDataLoaded(false)), + )) + dispatch(setBrowserTreeNodesOpen({})) + dispatch(setBrowserTreeSelectedLeaf({})) + } + + const handleScanMore = (config: any) => { + loadMoreItems?.({ + ...config, + stopIndex: (viewType === KeyViewType.Browser ? SCAN_COUNT_DEFAULT : SCAN_TREE_COUNT_DEFAULT) - 1, + }) + } + + const updateLastRefresh = () => { + lastRefreshTime && setLastRefreshMessage( + `${formatDistanceToNow(lastRefreshTime, { addSuffix: true })}` + ) + } + + const openAddKeyPanel = () => { + handleAddKeyPanel(true) + sendEventTelemetry({ + event: TelemetryEvent.BROWSER_KEY_ADD_BUTTON_CLICKED, + eventData: { + databaseId: instanceId + } + }) + } + + const handleSwitchView = (type: KeyViewType) => { + dispatch(changeKeyViewType(type)) + localStorageService.set(BrowserStorageItem.browserViewType, type) + loadKeys(type) + } + + const AddKeyBtn = ( + + + Key + + ) + + const ViewSwitch = ( +
+ {viewTypes.map((view) => ( + + handleSwitchView(view.type)} + data-testid={view.dataTestId} + /> + + ))} + +
+ ) + + const RefreshBtn = ( +
+ {showRefreshLabel && ( + + Last refresh: + + {` ${lastRefreshMessage}`} + + + )} + + + + +
+ ) + + return ( +
+
+ + + {ViewSwitch} + {AddKeyBtn} +
+ +
+ + {RefreshBtn} +
+
+ ) +} + +export default KeysHeader diff --git a/redisinsight/ui/src/pages/browser/components/keys-header/index.ts b/redisinsight/ui/src/pages/browser/components/keys-header/index.ts new file mode 100644 index 0000000000..5ae92a7ad8 --- /dev/null +++ b/redisinsight/ui/src/pages/browser/components/keys-header/index.ts @@ -0,0 +1,3 @@ +import KeysHeader from './KeysHeader' + +export default KeysHeader diff --git a/redisinsight/ui/src/pages/browser/components/keys-header/styles.module.scss b/redisinsight/ui/src/pages/browser/components/keys-header/styles.module.scss new file mode 100644 index 0000000000..69fa59f74e --- /dev/null +++ b/redisinsight/ui/src/pages/browser/components/keys-header/styles.module.scss @@ -0,0 +1,83 @@ +.content { + width: 100%; + background-color: var(--euiColorEmptyShade); + + height: 108px; + padding: 18px 18px 0; + + display: flex; + flex-direction: column; + position: relative; + + .addKey { + height: 36px !important; + width: 78px !important; + + :global(.euiButton__text) { + font: normal normal 500 15px/24px 'Graphik', sans-serif !important; + } + } + +} + +.top, .bottom { + display: flex; + text-align: center; + align-items: center; + min-height: 38px; +} + +.bottom { + padding-top: 10px; +} + + +.refresh { + right: 18px; + position: absolute; +} + +.btnRefresh { + svg { + width: 20px; + height: 20px; + } +} + +.refreshTime { + color: var(--euiColorWarningLight); + padding-right: 6px; +} + +.refreshSummary { + vertical-align: middle; + font: normal normal normal 12px/18px 'Graphik', sans-serif !important; + letter-spacing: -0.12px; +} + +.tooltip { + max-width: 372px !important; +} + +.viewTypeSwitch { + padding: 0 24px; +} + + +.viewTypeBtn { + width: 36px !important; + height: 36px !important; + background-color: var(--browserViewTypePassive) !important; + + svg { + color: var(--euiTextSubduedColor) !important; + } + + &.active { + background-color: var(--browserViewTypeActive) !important; + + svg { + color: var(--euiColorPrimary) !important; + } + } +} diff --git a/redisinsight/ui/src/pages/browser/components/list-details/styles.module.scss b/redisinsight/ui/src/pages/browser/components/list-details/styles.module.scss index d34c5b933c..b617668ba8 100644 --- a/redisinsight/ui/src/pages/browser/components/list-details/styles.module.scss +++ b/redisinsight/ui/src/pages/browser/components/list-details/styles.module.scss @@ -2,7 +2,7 @@ display: flex; flex: 1; width: 100%; - padding: 16px 16px 30px; + padding: 16px; background-color: var(--euiColorEmptyShade); } diff --git a/redisinsight/ui/src/pages/browser/components/rejson-details/styles.module.scss b/redisinsight/ui/src/pages/browser/components/rejson-details/styles.module.scss index cc5462624b..198effe2f1 100644 --- a/redisinsight/ui/src/pages/browser/components/rejson-details/styles.module.scss +++ b/redisinsight/ui/src/pages/browser/components/rejson-details/styles.module.scss @@ -8,7 +8,7 @@ display: flex; flex: 1; width: 100%; - padding: 16px 16px 30px; + padding: 16px; overflow-y: auto; overflow-x: auto; background-color: var(--euiColorEmptyShade); diff --git a/redisinsight/ui/src/pages/browser/components/search-key-list/SearchKeyList.tsx b/redisinsight/ui/src/pages/browser/components/search-key-list/SearchKeyList.tsx index 163da88b96..a181e69df2 100644 --- a/redisinsight/ui/src/pages/browser/components/search-key-list/SearchKeyList.tsx +++ b/redisinsight/ui/src/pages/browser/components/search-key-list/SearchKeyList.tsx @@ -1,18 +1,24 @@ import { EuiFieldSearch, keys } from '@elastic/eui' import React, { ChangeEvent } from 'react' import { useDispatch, useSelector } from 'react-redux' -import { SCAN_COUNT_DEFAULT } from 'uiSrc/constants/api' +import { SCAN_COUNT_DEFAULT, SCAN_TREE_COUNT_DEFAULT } from 'uiSrc/constants/api' import { replaceSpaces } from 'uiSrc/utils' import { fetchKeys, keysSelector, setSearchMatch } from 'uiSrc/slices/keys' +import { setBrowserTreeNodesOpen, setBrowserTreeSelectedLeaf } from 'uiSrc/slices/app/context' +import { KeyViewType } from 'uiSrc/slices/interfaces/keys' import styles from './styles.module.scss' const SearchKeyList = () => { const dispatch = useDispatch() - const { search: value = '' } = useSelector(keysSelector) + const { search: value = '', viewType } = useSelector(keysSelector) const handleApply = () => { - dispatch(fetchKeys('0', SCAN_COUNT_DEFAULT)) + dispatch(fetchKeys('0', viewType === KeyViewType.Browser ? SCAN_COUNT_DEFAULT : SCAN_TREE_COUNT_DEFAULT)) + + // reset browser tree context + dispatch(setBrowserTreeNodesOpen({})) + dispatch(setBrowserTreeSelectedLeaf({})) } const handleChangeValue = (initValue: string) => { diff --git a/redisinsight/ui/src/pages/browser/components/search-key-list/styles.module.scss b/redisinsight/ui/src/pages/browser/components/search-key-list/styles.module.scss index 7044d8b1af..e584344b68 100644 --- a/redisinsight/ui/src/pages/browser/components/search-key-list/styles.module.scss +++ b/redisinsight/ui/src/pages/browser/components/search-key-list/styles.module.scss @@ -1,5 +1,5 @@ .container { - max-width: calc(100% - 160px); + width: calc(100% - 305px); height: 38px; margin-left: 106px; @@ -11,7 +11,6 @@ :global(.euiFieldSearch) { &.input { - min-width: 345px; height: 36px !important; max-width: 100% !important; diff --git a/redisinsight/ui/src/pages/browser/components/set-details/styles.module.scss b/redisinsight/ui/src/pages/browser/components/set-details/styles.module.scss index 0a40b24bb0..5bc7d3b97d 100644 --- a/redisinsight/ui/src/pages/browser/components/set-details/styles.module.scss +++ b/redisinsight/ui/src/pages/browser/components/set-details/styles.module.scss @@ -2,6 +2,6 @@ display: flex; flex: 1; width: 100%; - padding: 16px 16px 30px; + padding: 16px; background-color: var(--euiColorEmptyShade); } diff --git a/redisinsight/ui/src/pages/browser/components/zset-details/styles.module.scss b/redisinsight/ui/src/pages/browser/components/zset-details/styles.module.scss index 0a40b24bb0..5bc7d3b97d 100644 --- a/redisinsight/ui/src/pages/browser/components/zset-details/styles.module.scss +++ b/redisinsight/ui/src/pages/browser/components/zset-details/styles.module.scss @@ -2,6 +2,6 @@ display: flex; flex: 1; width: 100%; - padding: 16px 16px 30px; + padding: 16px; background-color: var(--euiColorEmptyShade); } diff --git a/redisinsight/ui/src/pages/home/styles.scss b/redisinsight/ui/src/pages/home/styles.scss index bd4ea44bdc..7af7de592c 100644 --- a/redisinsight/ui/src/pages/home/styles.scss +++ b/redisinsight/ui/src/pages/home/styles.scss @@ -373,7 +373,7 @@ margin-right: 20px; } - .flexGroupResposiveForm { + .flexGroupResponsiveForm { flex-wrap: wrap; margin-left: 0; margin-right: 0; diff --git a/redisinsight/ui/src/pages/instance/InstancePage.tsx b/redisinsight/ui/src/pages/instance/InstancePage.tsx index 4dcb0e00fc..b2eea29784 100644 --- a/redisinsight/ui/src/pages/instance/InstancePage.tsx +++ b/redisinsight/ui/src/pages/instance/InstancePage.tsx @@ -13,7 +13,7 @@ import { setAppContextConnectedInstanceId, setAppContextInitialState, } from 'uiSrc/slices/app/context' -import { resetKeys } from 'uiSrc/slices/keys' +import { resetKeysData } from 'uiSrc/slices/keys' import { BrowserStorageItem } from 'uiSrc/constants' import { localStorageService } from 'uiSrc/services' import { resetOutput } from 'uiSrc/slices/cli/cli-output' @@ -82,7 +82,7 @@ const InstancePage = ({ routes = [] }: Props) => { const resetContext = () => { dispatch(setMonitorInitialState()) dispatch(setAppContextInitialState()) - dispatch(resetKeys()) + dispatch(resetKeysData()) setTimeout(() => { dispatch(resetOutput()) }, 0) diff --git a/redisinsight/ui/src/services/hooks.ts b/redisinsight/ui/src/services/hooks/hooks.ts similarity index 88% rename from redisinsight/ui/src/services/hooks.ts rename to redisinsight/ui/src/services/hooks/hooks.ts index ee3898a068..56cea99cfb 100644 --- a/redisinsight/ui/src/services/hooks.ts +++ b/redisinsight/ui/src/services/hooks/hooks.ts @@ -5,7 +5,7 @@ export const useResizableFormField = ( width: number ) => { const flexFormWidth = 700 - const flexGroupResposiveForm = 'flexGroupResposiveForm' + const flexGroupResponsiveForm = 'flexGroupResponsiveForm' const flexItemResponsiveForm = 'flexItemResponsiveForm' const [flexGroupClassName, setFlexGroupClassName] = useState('') @@ -19,7 +19,7 @@ export const useResizableFormField = ( offsetWidth < flexFormWidth ? flexItemResponsiveForm : '' ) setFlexGroupClassName( - offsetWidth < flexFormWidth ? flexGroupResposiveForm : '' + offsetWidth < flexFormWidth ? flexGroupResponsiveForm : '' ) } }, [width]) diff --git a/redisinsight/ui/src/services/hooks/index.ts b/redisinsight/ui/src/services/hooks/index.ts new file mode 100644 index 0000000000..1d290f906d --- /dev/null +++ b/redisinsight/ui/src/services/hooks/index.ts @@ -0,0 +1,2 @@ +export * from './hooks' +export * from './useWebworkers' diff --git a/redisinsight/ui/src/services/hooks/useWebworkers.ts b/redisinsight/ui/src/services/hooks/useWebworkers.ts new file mode 100644 index 0000000000..d4726a6a7c --- /dev/null +++ b/redisinsight/ui/src/services/hooks/useWebworkers.ts @@ -0,0 +1,59 @@ +import { useEffect, useState, useRef } from 'react' +import { Nullable } from 'uiSrc/utils' + +const workerHandler = (fn: (...args: any) => any) => { + onmessage = (event) => { + postMessage(fn(event.data)) + } +} + +export const useWebworker = (fn: (...args: any) => any) => { + const [result, setResult] = useState>(null) + const [error, setError] = useState>(null) + + const workerRef = useRef>(null) + + useEffect(() => { + const worker = new Worker( + URL.createObjectURL(new Blob([`(${workerHandler})(${fn})`])) + ) + workerRef.current = worker + worker.onmessage = (event) => setResult(event.data) + worker.onerror = (error: ErrorEvent) => setError(error) + return () => { + worker.terminate() + } + }, [fn]) + + return { + result, + error, + run: (value:any) => workerRef.current?.postMessage(value), + } +} + +export const useDisposableWebworker = (fn: (...args: any) => any) => { + const [result, setResult] = useState>(null) + const [error, setError] = useState>(null) + + const run = (value: any) => { + const worker = new Worker( + URL.createObjectURL(new Blob([`(${workerHandler})(${fn})`])) + ) + worker.onmessage = (event) => { + setResult(event.data) + worker.terminate() + } + worker.onerror = (error: ErrorEvent) => { + setError(error) + worker.terminate() + } + worker.postMessage(value) + } + + return { + result, + error, + run, + } +} diff --git a/redisinsight/ui/src/services/tests/queryHistory.spec.ts b/redisinsight/ui/src/services/tests/queryHistory.spec.ts deleted file mode 100644 index 67978e3d4f..0000000000 --- a/redisinsight/ui/src/services/tests/queryHistory.spec.ts +++ /dev/null @@ -1,139 +0,0 @@ -import { cloneDeep } from 'lodash' -import { WBHistoryObject } from 'uiSrc/pages/workbench/interfaces' -import { waitFor } from 'uiSrc/utils/test-utils' -import HistoryContainer from '../queryHistory' - -type T = WBHistoryObject - -let history: HistoryContainer -beforeEach(() => { - history = cloneDeep(new HistoryContainer(`SEARCH_HISTORY_WRAPPER_NAME_${Math.random()}`)) -}) - -describe('queryHistory', () => { - it('getData should return all data', async () => { - const data: T = { - query: 'query', - data: 'data', - id: Date.now(), - } - const newHistory = cloneDeep(history) - - await waitFor(() => { - newHistory.pushData(data) - }) - - expect(newHistory.getData()).toEqual([data]) - }) - - it('pushData should add data entry to the container ', async () => { - const data: T = { - query: 'query', - data: 'data', - id: Date.now(), - } - const newHistory = cloneDeep(history) - newHistory.pushData(data) - - expect(newHistory.getData().length).toEqual(1) - - await waitFor(() => { - newHistory.pushData(data) - newHistory.pushData(data) - newHistory.pushData(data) - }) - - expect(newHistory.getData().length).toEqual(4) - }) - - it('getLength should return the length of the history', async () => { - const data: T = { - query: 'query', - data: 'data', - id: Date.now(), - } - const newHistory = cloneDeep(history) - - await waitFor(() => { - newHistory.pushData(data) - newHistory.pushData(data) - newHistory.pushData(data) - }) - - expect(newHistory.getLength()).toEqual(3) - }) - - it('hasId should check whether container has an item with the given id', () => { - const id = Date.now() - const data: T = { - query: 'query', - data: 'data', - id, - } - const newHistory = cloneDeep(history) - newHistory.pushData(data) - const isHasId = newHistory.hasId(id) - const isHasNotId = newHistory.hasId(123) - - expect(isHasId).toBeTruthy() - expect(isHasNotId).not.toBeTruthy() - }) - - it('replaceHistoryItem should replace history data whose id equals `id` with `data`', () => { - const id = Date.now() - const id2 = 123 - const data: T = { - query: 'query', - data: 'data', - id, - } - const newHistory = cloneDeep(history) - newHistory.pushData(data) - - newHistory.replaceHistoryItem(id, { ...data, id: id2 }) - - expect(newHistory.getData()[0]).toEqual({ ...data, id: id2 }) - }) - - it('deleteHistoryLastItem should delete an history last item', async () => { - const data: T = { - query: 'query', - data: 'data', - id: 1, - } - const newHistory = cloneDeep(history) - - await waitFor(() => { - newHistory.pushData(data) - newHistory.pushData({ ...data, id: data.id + 1 }) - newHistory.pushData({ ...data, id: data.id + 2 }) - - newHistory.deleteHistoryLastItem() - newHistory.deleteHistoryLastItem() - }) - - expect(newHistory.getData().length).toEqual(1) - }) - - it('deleteHistoryItem should delete an history item by id', async () => { - const data: T = { - query: 'query', - data: 'data', - id: 1, - } - - const findingId = data.id + 1 - const newHistory = cloneDeep(history) - - await waitFor(() => { - newHistory.pushData(data) - newHistory.pushData({ ...data, id: findingId }) - newHistory.pushData({ ...data, id: findingId + 2 }) - newHistory.deleteHistoryItem(findingId) - }) - - const historyData = newHistory.getData() - - expect(historyData.find(({ id }) => id === findingId)).toBeFalsy() - }) -}) diff --git a/redisinsight/ui/src/slices/app/context.ts b/redisinsight/ui/src/slices/app/context.ts index 7d671a6c45..9fb4d765e4 100644 --- a/redisinsight/ui/src/slices/app/context.ts +++ b/redisinsight/ui/src/slices/app/context.ts @@ -12,7 +12,12 @@ export const initialState: StateAppContext = { scrollTopPosition: 0, selectedKey: null }, - panelSizes: {} + panelSizes: {}, + tree: { + panelSizes: {}, + openNodes: {}, + selectedLeaf: {}, + } }, workbench: { script: '', @@ -48,6 +53,15 @@ const appContextSlice = createSlice({ setBrowserPanelSizes: (state, { payload }: { payload: any }) => { state.browser.panelSizes = payload }, + setBrowserTreeSelectedLeaf: (state, { payload }: { payload: any }) => { + state.browser.tree.selectedLeaf = payload + }, + setBrowserTreeNodesOpen: (state, { payload }: { payload: { [key: string]: boolean; } }) => { + state.browser.tree.openNodes = payload + }, + setBrowserTreePanelSizes: (state, { payload }: { payload: any }) => { + state.browser.tree.panelSizes = payload + }, setWorkbenchScript: (state, { payload }: { payload: string }) => { state.workbench.script = payload }, @@ -82,6 +96,9 @@ export const { setBrowserSelectedKey, setBrowserKeyListScrollPosition, setBrowserPanelSizes, + setBrowserTreeSelectedLeaf, + setBrowserTreeNodesOpen, + setBrowserTreePanelSizes, setWorkbenchScript, setWorkbenchVerticalPanelSizes, setLastPageContext, @@ -95,6 +112,8 @@ export const appContextSelector = (state: RootState) => state.app.context export const appContextBrowser = (state: RootState) => state.app.context.browser +export const appContextBrowserTree = (state: RootState) => + state.app.context.browser.tree export const appContextWorkbench = (state: RootState) => state.app.context.workbench export const appContextSelectedKey = (state: RootState) => diff --git a/redisinsight/ui/src/slices/interfaces/app.ts b/redisinsight/ui/src/slices/interfaces/app.ts index 7c0269d42f..6611a035f7 100644 --- a/redisinsight/ui/src/slices/interfaces/app.ts +++ b/redisinsight/ui/src/slices/interfaces/app.ts @@ -2,6 +2,7 @@ import { AxiosError } from 'axios' import { Nullable } from 'uiSrc/utils' import { GetServerInfoResponse } from 'apiSrc/dto/server.dto' import { ICommands } from 'uiSrc/constants' +import { IKeyPropTypes } from 'uiSrc/constants/prop-types/keys'; export interface IError extends AxiosError { id: string; @@ -42,6 +43,17 @@ export interface StateAppContext { }, panelSizes: { [key: string]: number; + }, + tree: { + panelSizes: { + [key: string]: number; + }, + openNodes: { + [key: string]: boolean; + }, + selectedLeaf: { + [key: string]: IKeyPropTypes[]; + }, } }, workbench: { diff --git a/redisinsight/ui/src/slices/interfaces/keys.ts b/redisinsight/ui/src/slices/interfaces/keys.ts new file mode 100644 index 0000000000..f18ec0fc89 --- /dev/null +++ b/redisinsight/ui/src/slices/interfaces/keys.ts @@ -0,0 +1,52 @@ +import { KeyTypes, UnsupportedKeyTypes } from 'uiSrc/constants' +import { IKeyPropTypes } from 'uiSrc/constants/prop-types/keys' +import { Maybe, Nullable } from 'uiSrc/utils' + +export interface Key { + name: string; + type: KeyTypes; + ttl: number; + size: number; +} + +export enum KeyViewType { + Browser = 'Browser', + Tree = 'Tree', +} + +export interface KeysStore { + loading: boolean; + error: string; + search: string; + filter: Nullable; + isFiltered: boolean; + isSearched: boolean; + viewType: KeyViewType, + data: { + total: number; + scanned: number; + nextCursor: string; + keys: Key[]; + shardsMeta: Record; + previousResultCount: number; + lastRefreshTime: Nullable; + }; + selectedKey: { + loading: boolean; + refreshing: boolean; + lastRefreshTime: Nullable; + error: string; + data: Nullable; + length: Maybe; + }; + addKey: { + loading: boolean; + error: string; + }; +} diff --git a/redisinsight/ui/src/slices/keys.ts b/redisinsight/ui/src/slices/keys.ts index 7e870e819b..37febbcb97 100644 --- a/redisinsight/ui/src/slices/keys.ts +++ b/redisinsight/ui/src/slices/keys.ts @@ -1,8 +1,8 @@ import { createSlice } from '@reduxjs/toolkit' import { cloneDeep, remove, get } from 'lodash' import axios, { CancelTokenSource } from 'axios' -import { apiService } from 'uiSrc/services' -import { ApiEndpoints, KeyTypes, SortOrder } from 'uiSrc/constants' +import { apiService, localStorageService } from 'uiSrc/services' +import { ApiEndpoints, BrowserStorageItem, KeyTypes, SortOrder } from 'uiSrc/constants' import { getApiErrorMessage, isStatusNotFoundError, @@ -11,7 +11,6 @@ import { getUrl, isStatusSuccessful, } from 'uiSrc/utils' -import { KeysStore } from 'uiSrc/components/main-router/interfaces' import { DEFAULT_SEARCH_MATCH, SCAN_COUNT_DEFAULT } from 'uiSrc/constants/api' import successMessages from 'uiSrc/components/notifications/success-messages' import { @@ -30,6 +29,7 @@ import { fetchReJSON } from './rejson' import { setHashInitialState, fetchHashFields } from './hash' import { setListInitialState, fetchListElements } from './list' import { addErrorNotification, addMessageNotification } from './app/notifications' +import { KeysStore, KeyViewType } from './interfaces/keys' export const initialState: KeysStore = { loading: false, @@ -38,6 +38,7 @@ export const initialState: KeysStore = { search: '', isSearched: false, isFiltered: false, + viewType: localStorageService?.get(BrowserStorageItem.browserViewType) ?? KeyViewType.Browser, data: { total: 0, scanned: 0, @@ -268,6 +269,11 @@ const keysSlice = createSlice({ setFilter: (state, { payload }) => { state.filter = payload }, + + changeKeyViewType: (state, { payload }:{ payload: KeyViewType }) => { + state.viewType = payload + }, + resetAddKey: (state) => { state.addKey = cloneDeep(initialState.addKey) }, @@ -278,6 +284,11 @@ const keysSlice = createSlice({ // reset keys for keys slice resetKeys: () => cloneDeep(initialState), + + resetKeysData: (state) => { + // state.data.keys = [] + state.data.keys.length = 0 + }, }, }) @@ -311,8 +322,10 @@ export const { updateSelectedKeyLength, setSearchMatch, setFilter, + changeKeyViewType, resetKeyInfo, resetKeys, + resetKeysData, } = keysSlice.actions // A selector diff --git a/redisinsight/ui/src/styles/themes/dark_theme/_dark_theme.lazy.scss b/redisinsight/ui/src/styles/themes/dark_theme/_dark_theme.lazy.scss index 9123a1e2d6..35fa44c44e 100644 --- a/redisinsight/ui/src/styles/themes/dark_theme/_dark_theme.lazy.scss +++ b/redisinsight/ui/src/styles/themes/dark_theme/_dark_theme.lazy.scss @@ -89,6 +89,9 @@ --hoverInListColorDarken: #{$hoverInListColorDarken}; --externalLinkColor: #{$externalLinkColor}; --externalLinkTooltipColor: #{$externalLinkTooltipColor}; + --browserViewTypePassive: #{$browserViewTypePassive}; + --browserViewTypeActive: #{$browserViewTypeActive}; + --browserTreeNodeOpen: #{$browserTreeNodeOpen}; --iconsDefaultColor: #{$iconsDefaultColor}; --iconsDefaultHoverColor: #{$iconsDefaultHoverColor}; diff --git a/redisinsight/ui/src/styles/themes/dark_theme/_theme_color.scss b/redisinsight/ui/src/styles/themes/dark_theme/_theme_color.scss index 686b1533c8..e4dd560a4a 100644 --- a/redisinsight/ui/src/styles/themes/dark_theme/_theme_color.scss +++ b/redisinsight/ui/src/styles/themes/dark_theme/_theme_color.scss @@ -43,6 +43,9 @@ $tableLightestBorderColor: #707070; $tableDarkestBorderColor: #2c2c2c; $browserTableRowEven: #171717; +$browserViewTypePassive: #171717; +$browserViewTypeActive: #212536; +$browserTreeNodeOpen: #2B2F40; $inputTextColor: #DFE5EF; $inputDisabledBackgroundColor: $euiColorEmptyShade; diff --git a/redisinsight/ui/src/styles/themes/light_theme/_light_theme.lazy.scss b/redisinsight/ui/src/styles/themes/light_theme/_light_theme.lazy.scss index ca63f58810..c4bdb054a3 100644 --- a/redisinsight/ui/src/styles/themes/light_theme/_light_theme.lazy.scss +++ b/redisinsight/ui/src/styles/themes/light_theme/_light_theme.lazy.scss @@ -91,6 +91,9 @@ --hoverInListColorDarken: #{$hoverInListColorLight}; --externalLinkColor: #{$externalLinkColor}; --externalLinkTooltipColor: #{$externalLinkTooltipColor}; + --browserViewTypePassive: #{$browserViewTypePassive}; + --browserViewTypeActive: #{$browserViewTypeActive}; + --browserTreeNodeOpen: #{$browserTreeNodeOpen}; --iconsDefaultColor: #{$iconsDefaultColor}; --iconsDefaultHoverColor: #{$iconsDefaultHoverColor}; diff --git a/redisinsight/ui/src/styles/themes/light_theme/_theme_color.scss b/redisinsight/ui/src/styles/themes/light_theme/_theme_color.scss index d8d05da59d..85234b92b9 100644 --- a/redisinsight/ui/src/styles/themes/light_theme/_theme_color.scss +++ b/redisinsight/ui/src/styles/themes/light_theme/_theme_color.scss @@ -39,6 +39,9 @@ $tableLightestBorderColor: #C1CBD9; $tableDarkestBorderColor: #E9EDF3; $browserTableRowEven: #F6F8FD; +$browserViewTypePassive: #f6f7f9; +$browserViewTypeActive: #d7e3fa; +$browserTreeNodeOpen: #d7e3fa; $inputTextColor: #173369; $inputPlaceholderColor: #395984; diff --git a/redisinsight/ui/src/telemetry/index.ts b/redisinsight/ui/src/telemetry/index.ts index ca71aaeac4..ffad3a082d 100644 --- a/redisinsight/ui/src/telemetry/index.ts +++ b/redisinsight/ui/src/telemetry/index.ts @@ -1,6 +1,6 @@ import { TelemetryEvent } from './events' import { TelemetryPageView } from './pageViews' -import { ITelemetrySendEvent, ITelemetryService } from './interfaces' +import type { ITelemetrySendEvent, ITelemetryService } from './interfaces' export * from './telemetryUtils' diff --git a/redisinsight/ui/src/utils/apiResponse.ts b/redisinsight/ui/src/utils/apiResponse.ts index 48d1bbdc7f..0ce0ac4132 100644 --- a/redisinsight/ui/src/utils/apiResponse.ts +++ b/redisinsight/ui/src/utils/apiResponse.ts @@ -14,7 +14,7 @@ export function getApiErrorMessage(error: AxiosError): string { } export function getApiErrorName(error: AxiosError): string { - return get(error, 'response.data.name', 'Error') + return get(error, 'response.data.name', 'Error') ?? '' } export function getApiErrorsFromBulkOperation( diff --git a/redisinsight/ui/src/utils/index.ts b/redisinsight/ui/src/utils/index.ts index 79d5c91ab1..73854a4e21 100644 --- a/redisinsight/ui/src/utils/index.ts +++ b/redisinsight/ui/src/utils/index.ts @@ -1,6 +1,6 @@ import getUrl from './getUrlInstance' import removeEmpty from './removeEmpty' -import { Nullable, Maybe } from './types' +import type { Nullable, Maybe } from './types' import handlePasteHostName from './handlePasteHostName' import RouterWithSubRoutes from './routerWithSubRoutes' import replaceSpaces from './replaceSpaces' diff --git a/redisinsight/ui/src/utils/parseResponse.ts b/redisinsight/ui/src/utils/parseResponse.ts index 5e1aa534e8..d2420d1cb3 100644 --- a/redisinsight/ui/src/utils/parseResponse.ts +++ b/redisinsight/ui/src/utils/parseResponse.ts @@ -57,7 +57,8 @@ export const parseKeysListResponse = (prevShards = {}, data = []) => { shard.scanned = shard.total } - result.keys.push(...node.keys) + // result.keys.push(...node.keys) + result.keys = result.keys.concat(node.keys) }) // summarize result numbers diff --git a/redisinsight/ui/src/utils/test-utils.tsx b/redisinsight/ui/src/utils/test-utils.tsx index aeaf030037..da54d907ad 100644 --- a/redisinsight/ui/src/utils/test-utils.tsx +++ b/redisinsight/ui/src/utils/test-utils.tsx @@ -146,6 +146,12 @@ jest.mock('react-redux', () => ({ }), })) +// mock +jest.mock( + 'react-virtualized-auto-sizer', + () => ({ children }) => children({ height: 600, width: 600 }) +) + export const localStorageMock = { getItem: jest.fn(), setItem: jest.fn(), diff --git a/tsconfig.json b/tsconfig.json index 3fd25aa656..fea27bdfb9 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -50,8 +50,12 @@ ], "exclude": [ "./redisinsight/api", - "main.prod.js", - "renderer.prod.js", - "dist" + "**/main.prod.js", + "**/renderer.prod.js", + "./release", + "./node_modules", + "**/node_modules", + "./dist", + "**/dist" ] } diff --git a/yarn.lock b/yarn.lock index 5bdf08b7b7..d630705b9b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -74,52 +74,19 @@ dependencies: "@babel/highlight" "^7.10.4" -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.14.5", "@babel/code-frame@^7.8.3": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.14.5.tgz#23b08d740e83f49c5e59945fbf1b43e80bbf4edb" - integrity sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw== - dependencies: - "@babel/highlight" "^7.14.5" - -"@babel/code-frame@^7.16.7": +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.16.7", "@babel/code-frame@^7.8.3": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.7.tgz#44416b6bd7624b998f5b1af5d470856c40138789" integrity sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg== dependencies: "@babel/highlight" "^7.16.7" -"@babel/compat-data@^7.12.7", "@babel/compat-data@^7.15.0": - version "7.15.0" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.15.0.tgz#2dbaf8b85334796cafbb0f5793a90a2fc010b176" - integrity sha512-0NqAC1IJE0S0+lL1SWFMxMkz1pKCNCjI4tr2Zx4LJSXxCLAdr6KyArnY+sno5m3yH9g737ygOyPABDsnXkpxiA== - "@babel/compat-data@^7.13.11", "@babel/compat-data@^7.16.4", "@babel/compat-data@^7.16.8": version "7.17.0" resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.17.0.tgz#86850b8597ea6962089770952075dcaabb8dba34" integrity sha512-392byTlpGWXMv4FbyWw3sAZ/FrW/DrwqLGXpy0mbyNe9Taqv1mg9yON5/o0cnr8XYCkFTZbC1eV+c+LAROgrng== -"@babel/core@^7.1.0", "@babel/core@^7.12.9", "@babel/core@^7.7.5": - version "7.15.5" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.15.5.tgz#f8ed9ace730722544609f90c9bb49162dc3bf5b9" - integrity sha512-pYgXxiwAgQpgM1bNkZsDEq85f0ggXMA5L7c+o3tskGMh2BunCI9QUwB9Z4jpvXUOuMdyGKiGKQiRe11VS6Jzvg== - dependencies: - "@babel/code-frame" "^7.14.5" - "@babel/generator" "^7.15.4" - "@babel/helper-compilation-targets" "^7.15.4" - "@babel/helper-module-transforms" "^7.15.4" - "@babel/helpers" "^7.15.4" - "@babel/parser" "^7.15.5" - "@babel/template" "^7.15.4" - "@babel/traverse" "^7.15.4" - "@babel/types" "^7.15.4" - convert-source-map "^1.7.0" - debug "^4.1.0" - gensync "^1.0.0-beta.2" - json5 "^2.1.2" - semver "^6.3.0" - source-map "^0.5.0" - -"@babel/core@^7.15.5": +"@babel/core@^7.1.0", "@babel/core@^7.12.9", "@babel/core@^7.15.5", "@babel/core@^7.7.5": version "7.17.2" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.17.2.tgz#2c77fc430e95139d816d39b113b31bf40fb22337" integrity sha512-R3VH5G42VSDolRHyUO4V2cfag8WHcZyxdq5Z/m8Xyb92lW/Erm/6kM+XtRFGf3Mulre3mveni2NHfEUws8wSvw== @@ -140,15 +107,6 @@ json5 "^2.1.2" semver "^6.3.0" -"@babel/generator@^7.15.4": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.15.4.tgz#85acb159a267ca6324f9793986991ee2022a05b0" - integrity sha512-d3itta0tu+UayjEORPNz6e1T3FtvWlP5N4V5M+lhp/CxT4oAA7/NcScnpRyspUMLK6tu9MNHmQHxRykuN2R7hw== - dependencies: - "@babel/types" "^7.15.4" - jsesc "^2.5.1" - source-map "^0.5.0" - "@babel/generator@^7.17.0": version "7.17.0" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.17.0.tgz#7bd890ba706cd86d3e2f727322346ffdbf98f65e" @@ -158,28 +116,13 @@ jsesc "^2.5.1" source-map "^0.5.0" -"@babel/helper-annotate-as-pure@^7.10.4", "@babel/helper-annotate-as-pure@^7.12.10": - version "7.12.10" - resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.12.10.tgz#54ab9b000e60a93644ce17b3f37d313aaf1d115d" - integrity sha512-XplmVbC1n+KY6jL8/fgLVXXUauDIB+lD5+GsQEh6F6GBF1dq1qy4DP4yXWzDKcoqXB3X58t61e85Fitoww4JVQ== - dependencies: - "@babel/types" "^7.12.10" - -"@babel/helper-annotate-as-pure@^7.16.7": +"@babel/helper-annotate-as-pure@^7.10.4", "@babel/helper-annotate-as-pure@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.7.tgz#bb2339a7534a9c128e3102024c60760a3a7f3862" integrity sha512-s6t2w/IPQVTAET1HitoowRGXooX8mCgtuP5195wD/QJPV6wYjpujCGF7JuMODVX2ZAJOf1GT6DT9MHEZvLOFSw== dependencies: "@babel/types" "^7.16.7" -"@babel/helper-builder-binary-assignment-operator-visitor@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.10.4.tgz#bb0b75f31bf98cbf9ff143c1ae578b87274ae1a3" - integrity sha512-L0zGlFrGWZK4PbT8AszSfLTM5sDU1+Az/En9VrdT8/LmEiJt4zXt+Jve9DCAnQcbqDhCI+29y/L93mrDzddCcg== - dependencies: - "@babel/helper-explode-assignable-expression" "^7.10.4" - "@babel/types" "^7.10.4" - "@babel/helper-builder-binary-assignment-operator-visitor@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.16.7.tgz#38d138561ea207f0f69eb1626a418e4f7e6a580b" @@ -196,16 +139,6 @@ "@babel/helper-annotate-as-pure" "^7.10.4" "@babel/types" "^7.10.4" -"@babel/helper-compilation-targets@^7.12.5", "@babel/helper-compilation-targets@^7.15.4": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.15.4.tgz#cf6d94f30fbefc139123e27dd6b02f65aeedb7b9" - integrity sha512-rMWPCirulnPSe4d+gwdWXLfAXTTBj8M3guAf5xFQJ0nvFY7tfNAFnWdqaHegHlgDZOCT4qvhF3BYlSJag8yhqQ== - dependencies: - "@babel/compat-data" "^7.15.0" - "@babel/helper-validator-option" "^7.14.5" - browserslist "^4.16.6" - semver "^6.3.0" - "@babel/helper-compilation-targets@^7.13.0", "@babel/helper-compilation-targets@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.7.tgz#06e66c5f299601e6c7da350049315e83209d551b" @@ -216,18 +149,7 @@ browserslist "^4.17.5" semver "^6.3.0" -"@babel/helper-create-class-features-plugin@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.12.1.tgz#3c45998f431edd4a9214c5f1d3ad1448a6137f6e" - integrity sha512-hkL++rWeta/OVOBTRJc9a5Azh5mt5WgZUGAKMD8JM141YsE08K//bp1unBBieO6rUKkIPyUE0USQ30jAy3Sk1w== - dependencies: - "@babel/helper-function-name" "^7.10.4" - "@babel/helper-member-expression-to-functions" "^7.12.1" - "@babel/helper-optimise-call-expression" "^7.10.4" - "@babel/helper-replace-supers" "^7.12.1" - "@babel/helper-split-export-declaration" "^7.10.4" - -"@babel/helper-create-class-features-plugin@^7.16.10", "@babel/helper-create-class-features-plugin@^7.16.7": +"@babel/helper-create-class-features-plugin@^7.12.1", "@babel/helper-create-class-features-plugin@^7.16.10", "@babel/helper-create-class-features-plugin@^7.16.7": version "7.17.1" resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.17.1.tgz#9699f14a88833a7e055ce57dcd3ffdcd25186b21" integrity sha512-JBdSr/LtyYIno/pNnJ75lBcqc3Z1XXujzPanHqjvvrhOA+DTceTFuJi8XjmWTZh4r3fsdfqaCMN0iZemdkxZHQ== @@ -240,14 +162,6 @@ "@babel/helper-replace-supers" "^7.16.7" "@babel/helper-split-export-declaration" "^7.16.7" -"@babel/helper-create-regexp-features-plugin@^7.12.1": - version "7.12.7" - resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.12.7.tgz#2084172e95443fa0a09214ba1bb328f9aea1278f" - integrity sha512-idnutvQPdpbduutvi3JVfEgcVIHooQnhvhx0Nk9isOINOIGYkZea1Pk2JlJRiUnMefrlvr0vkByATBY/mB4vjQ== - dependencies: - "@babel/helper-annotate-as-pure" "^7.10.4" - regexpu-core "^4.7.1" - "@babel/helper-create-regexp-features-plugin@^7.16.7": version "7.17.0" resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.17.0.tgz#1dcc7d40ba0c6b6b25618997c5dbfd310f186fe1" @@ -256,15 +170,6 @@ "@babel/helper-annotate-as-pure" "^7.16.7" regexpu-core "^5.0.1" -"@babel/helper-define-map@^7.10.4": - version "7.10.5" - resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.10.5.tgz#b53c10db78a640800152692b13393147acb9bb30" - integrity sha512-fMw4kgFB720aQFXSVaXr79pjjcW5puTCM16+rECJ/plGS+zByelE8l9nCpV1GibxTnFVmUuYG9U8wYfQHdzOEQ== - dependencies: - "@babel/helper-function-name" "^7.10.4" - "@babel/types" "^7.10.5" - lodash "^4.17.19" - "@babel/helper-define-polyfill-provider@^0.3.1": version "0.3.1" resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.1.tgz#52411b445bdb2e676869e5a74960d2d3826d2665" @@ -286,13 +191,6 @@ dependencies: "@babel/types" "^7.16.7" -"@babel/helper-explode-assignable-expression@^7.10.4": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.12.1.tgz#8006a466695c4ad86a2a5f2fb15b5f2c31ad5633" - integrity sha512-dmUwH8XmlrUpVqgtZ737tK88v07l840z9j3OEhCLwKTkjlvKpfqXVIZ0wpK3aeOxspwGrf/5AP5qLx4rO3w5rA== - dependencies: - "@babel/types" "^7.12.1" - "@babel/helper-explode-assignable-expression@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.16.7.tgz#12a6d8522fdd834f194e868af6354e8650242b7a" @@ -300,15 +198,6 @@ dependencies: "@babel/types" "^7.16.7" -"@babel/helper-function-name@^7.10.4", "@babel/helper-function-name@^7.15.4": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.15.4.tgz#845744dafc4381a4a5fb6afa6c3d36f98a787ebc" - integrity sha512-Z91cOMM4DseLIGOnog+Z8OI6YseR9bua+HpvLAQ2XayUGU+neTtX+97caALaLdyu53I/fjhbeCnWnRH1O3jFOw== - dependencies: - "@babel/helper-get-function-arity" "^7.15.4" - "@babel/template" "^7.15.4" - "@babel/types" "^7.15.4" - "@babel/helper-function-name@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz#f1ec51551fb1c8956bc8dd95f38523b6cf375f8f" @@ -318,13 +207,6 @@ "@babel/template" "^7.16.7" "@babel/types" "^7.16.7" -"@babel/helper-get-function-arity@^7.15.4": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.15.4.tgz#098818934a137fce78b536a3e015864be1e2879b" - integrity sha512-1/AlxSF92CmGZzHnC515hm4SirTxtpDnLEJ0UyEMgTMZN+6bxXKg04dKhiRx5Enel+SUA1G1t5Ed/yQia0efrA== - dependencies: - "@babel/types" "^7.15.4" - "@babel/helper-get-function-arity@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz#ea08ac753117a669f1508ba06ebcc49156387419" @@ -332,13 +214,6 @@ dependencies: "@babel/types" "^7.16.7" -"@babel/helper-hoist-variables@^7.10.4", "@babel/helper-hoist-variables@^7.15.4": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.15.4.tgz#09993a3259c0e918f99d104261dfdfc033f178df" - integrity sha512-VTy085egb3jUGVK9ycIxQiPbquesq0HUQ+tPO0uv5mPEBZipk+5FkRKiWq5apuyTE9FUrjENB0rCf8y+n+UuhA== - dependencies: - "@babel/types" "^7.15.4" - "@babel/helper-hoist-variables@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz#86bcb19a77a509c7b77d0e22323ef588fa58c246" @@ -346,13 +221,6 @@ dependencies: "@babel/types" "^7.16.7" -"@babel/helper-member-expression-to-functions@^7.12.1", "@babel/helper-member-expression-to-functions@^7.15.4": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.15.4.tgz#bfd34dc9bba9824a4658b0317ec2fd571a51e6ef" - integrity sha512-cokOMkxC/BTyNP1AlY25HuBWM32iCEsLPI4BHDpJCHHm1FU2E7dKWWIXJgQgSFiu4lp8q3bL1BIKwqkSUviqtA== - dependencies: - "@babel/types" "^7.15.4" - "@babel/helper-member-expression-to-functions@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.16.7.tgz#42b9ca4b2b200123c3b7e726b0ae5153924905b0" @@ -360,34 +228,13 @@ dependencies: "@babel/types" "^7.16.7" -"@babel/helper-module-imports@^7.12.1", "@babel/helper-module-imports@^7.12.5", "@babel/helper-module-imports@^7.15.4": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.15.4.tgz#e18007d230632dea19b47853b984476e7b4e103f" - integrity sha512-jeAHZbzUwdW/xHgHQ3QmWR4Jg6j15q4w/gCfwZvtqOxoo5DKtLHk8Bsf4c5RZRC7NmLEs+ohkdq8jFefuvIxAA== - dependencies: - "@babel/types" "^7.15.4" - -"@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.16.7": +"@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.12.5", "@babel/helper-module-imports@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz#25612a8091a999704461c8a222d0efec5d091437" integrity sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg== dependencies: "@babel/types" "^7.16.7" -"@babel/helper-module-transforms@^7.12.1", "@babel/helper-module-transforms@^7.15.4": - version "7.15.7" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.15.7.tgz#7da80c8cbc1f02655d83f8b79d25866afe50d226" - integrity sha512-ZNqjjQG/AuFfekFTY+7nY4RgBSklgTu970c7Rj3m/JOhIu5KPBUuTA9AY6zaKcUvk4g6EbDXdBnhi35FAssdSw== - dependencies: - "@babel/helper-module-imports" "^7.15.4" - "@babel/helper-replace-supers" "^7.15.4" - "@babel/helper-simple-access" "^7.15.4" - "@babel/helper-split-export-declaration" "^7.15.4" - "@babel/helper-validator-identifier" "^7.15.7" - "@babel/template" "^7.15.4" - "@babel/traverse" "^7.15.4" - "@babel/types" "^7.15.6" - "@babel/helper-module-transforms@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.16.7.tgz#7665faeb721a01ca5327ddc6bba15a5cb34b6a41" @@ -402,13 +249,6 @@ "@babel/traverse" "^7.16.7" "@babel/types" "^7.16.7" -"@babel/helper-optimise-call-expression@^7.10.4", "@babel/helper-optimise-call-expression@^7.15.4": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.15.4.tgz#f310a5121a3b9cc52d9ab19122bd729822dee171" - integrity sha512-E/z9rfbAOt1vDW1DR7k4SzhzotVV5+qMciWV6LaG1g4jeFrkDlJedjtV4h0i4Q/ITnUu+Pk08M7fczsB9GXBDw== - dependencies: - "@babel/types" "^7.15.4" - "@babel/helper-optimise-call-expression@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.16.7.tgz#a34e3560605abbd31a18546bd2aad3e6d9a174f2" @@ -416,25 +256,11 @@ dependencies: "@babel/types" "^7.16.7" -"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz#5ac822ce97eec46741ab70a517971e443a70c5a9" - integrity sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ== - -"@babel/helper-plugin-utils@^7.13.0", "@babel/helper-plugin-utils@^7.16.7": +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.13.0", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.16.7", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz#aa3a8ab4c3cceff8e65eb9e73d87dc4ff320b2f5" integrity sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA== -"@babel/helper-remap-async-to-generator@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.12.1.tgz#8c4dbbf916314f6047dc05e6a2217074238347fd" - integrity sha512-9d0KQCRM8clMPcDwo8SevNs+/9a8yWVVmaE80FGJcEP8N1qToREmWEGnBn8BUlJhYRFz6fqxeRL1sl5Ogsed7A== - dependencies: - "@babel/helper-annotate-as-pure" "^7.10.4" - "@babel/helper-wrap-function" "^7.10.4" - "@babel/types" "^7.12.1" - "@babel/helper-remap-async-to-generator@^7.16.8": version "7.16.8" resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.16.8.tgz#29ffaade68a367e2ed09c90901986918d25e57e3" @@ -444,16 +270,6 @@ "@babel/helper-wrap-function" "^7.16.8" "@babel/types" "^7.16.8" -"@babel/helper-replace-supers@^7.12.1", "@babel/helper-replace-supers@^7.15.4": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.15.4.tgz#52a8ab26ba918c7f6dee28628b07071ac7b7347a" - integrity sha512-/ztT6khaXF37MS47fufrKvIsiQkx1LBRvSJNzRqmbyeZnTwU9qBxXYLaaT/6KaxfKhjs2Wy8kG8ZdsFUuWBjzw== - dependencies: - "@babel/helper-member-expression-to-functions" "^7.15.4" - "@babel/helper-optimise-call-expression" "^7.15.4" - "@babel/traverse" "^7.15.4" - "@babel/types" "^7.15.4" - "@babel/helper-replace-supers@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.16.7.tgz#e9f5f5f32ac90429c1a4bdec0f231ef0c2838ab1" @@ -465,13 +281,6 @@ "@babel/traverse" "^7.16.7" "@babel/types" "^7.16.7" -"@babel/helper-simple-access@^7.12.1", "@babel/helper-simple-access@^7.15.4": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.15.4.tgz#ac368905abf1de8e9781434b635d8f8674bcc13b" - integrity sha512-UzazrDoIVOZZcTeHHEPYrr1MvTR/K+wgLg6MY6e1CJyaRhbibftF6fR2KU2sFRtI/nERUZR9fBd6aKgBlIBaPg== - dependencies: - "@babel/types" "^7.15.4" - "@babel/helper-simple-access@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.16.7.tgz#d656654b9ea08dbb9659b69d61063ccd343ff0f7" @@ -479,13 +288,6 @@ dependencies: "@babel/types" "^7.16.7" -"@babel/helper-skip-transparent-expression-wrappers@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.12.1.tgz#462dc63a7e435ade8468385c63d2b84cce4b3cbf" - integrity sha512-Mf5AUuhG1/OCChOJ/HcADmvcHM42WJockombn8ATJG3OnyiSxBK/Mm5x78BQWvmtXZKHgbjdGL2kin/HOLlZGA== - dependencies: - "@babel/types" "^7.12.1" - "@babel/helper-skip-transparent-expression-wrappers@^7.16.0": version "7.16.0" resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.16.0.tgz#0ee3388070147c3ae051e487eca3ebb0e2e8bb09" @@ -493,13 +295,6 @@ dependencies: "@babel/types" "^7.16.0" -"@babel/helper-split-export-declaration@^7.10.4", "@babel/helper-split-export-declaration@^7.15.4": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.15.4.tgz#aecab92dcdbef6a10aa3b62ab204b085f776e257" - integrity sha512-HsFqhLDZ08DxCpBdEVtKmywj6PQbwnF6HHybur0MAnkAKnlS6uHkwnmRIkElB2Owpfb4xL4NwDmDLFubueDXsw== - dependencies: - "@babel/types" "^7.15.4" - "@babel/helper-split-export-declaration@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz#0b648c0c42da9d3920d85ad585f2778620b8726b" @@ -507,37 +302,17 @@ dependencies: "@babel/types" "^7.16.7" -"@babel/helper-validator-identifier@^7.10.4", "@babel/helper-validator-identifier@^7.14.5", "@babel/helper-validator-identifier@^7.14.9", "@babel/helper-validator-identifier@^7.15.7": - version "7.15.7" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz#220df993bfe904a4a6b02ab4f3385a5ebf6e2389" - integrity sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w== - "@babel/helper-validator-identifier@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz#e8c602438c4a8195751243da9031d1607d247cad" integrity sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw== -"@babel/helper-validator-option@^7.12.1", "@babel/helper-validator-option@^7.12.11", "@babel/helper-validator-option@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz#6e72a1fff18d5dfcb878e1e62f1a021c4b72d5a3" - integrity sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow== - "@babel/helper-validator-option@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz#b203ce62ce5fe153899b617c08957de860de4d23" integrity sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ== -"@babel/helper-wrap-function@^7.10.4": - version "7.12.3" - resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.12.3.tgz#3332339fc4d1fbbf1c27d7958c27d34708e990d9" - integrity sha512-Cvb8IuJDln3rs6tzjW3Y8UeelAOdnpB8xtQ4sme2MSZ9wOxrbThporC0y/EtE16VAtoyEfLM404Xr1e0OOp+ow== - dependencies: - "@babel/helper-function-name" "^7.10.4" - "@babel/template" "^7.10.4" - "@babel/traverse" "^7.10.4" - "@babel/types" "^7.10.4" - -"@babel/helper-wrap-function@^7.16.8": +"@babel/helper-wrap-function@^7.10.4", "@babel/helper-wrap-function@^7.16.8": version "7.16.8" resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.16.8.tgz#58afda087c4cd235de92f7ceedebca2c41274200" integrity sha512-8RpyRVIAW1RcDDGTA+GpPAwV22wXCfKOoM9bet6TLkGIFTkRQSkH1nMQ5Yet4MpoXe1ZwHPVtNasc2w0uZMqnw== @@ -547,15 +322,6 @@ "@babel/traverse" "^7.16.8" "@babel/types" "^7.16.8" -"@babel/helpers@^7.15.4": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.15.4.tgz#5f40f02050a3027121a3cf48d497c05c555eaf43" - integrity sha512-V45u6dqEJ3w2rlryYYXf6i9rQ5YMNu4FLS6ngs8ikblhu2VdR1AqAd6aJjBzmf2Qzh6KOLqKHxEN9+TFbAkAVQ== - dependencies: - "@babel/template" "^7.15.4" - "@babel/traverse" "^7.15.4" - "@babel/types" "^7.15.4" - "@babel/helpers@^7.17.2": version "7.17.2" resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.17.2.tgz#23f0a0746c8e287773ccd27c14be428891f63417" @@ -565,16 +331,7 @@ "@babel/traverse" "^7.17.0" "@babel/types" "^7.17.0" -"@babel/highlight@^7.10.4", "@babel/highlight@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.14.5.tgz#6861a52f03966405001f6aa534a01a24d99e8cd9" - integrity sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg== - dependencies: - "@babel/helper-validator-identifier" "^7.14.5" - chalk "^2.0.0" - js-tokens "^4.0.0" - -"@babel/highlight@^7.16.7": +"@babel/highlight@^7.10.4", "@babel/highlight@^7.16.7": version "7.16.10" resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.16.10.tgz#744f2eb81579d6eea753c227b0f570ad785aba88" integrity sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw== @@ -583,12 +340,7 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.1.0", "@babel/parser@^7.15.4", "@babel/parser@^7.15.5", "@babel/parser@^7.7.0": - version "7.15.7" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.15.7.tgz#0c3ed4a2eb07b165dfa85b3cc45c727334c4edae" - integrity sha512-rycZXvQ+xS9QyIcJ9HXeDWf1uxqlbVFAUq0Rq0dbc50Zb/+wUe/ehyfzGfm9KZZF0kBejYgxltBXocP+gKdL2g== - -"@babel/parser@^7.16.7", "@babel/parser@^7.17.0": +"@babel/parser@^7.1.0", "@babel/parser@^7.16.7", "@babel/parser@^7.17.0", "@babel/parser@^7.7.0": version "7.17.0" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.17.0.tgz#f0ac33eddbe214e4105363bb17c3341c5ffcc43c" integrity sha512-VKXSCQx5D8S04ej+Dqsr1CzYvvWgf20jIw2D+YhQCrIlr2UZGaDds23Y0xg75/skOxpLCRpUZvk/1EAVkGoDOw== @@ -609,15 +361,6 @@ "@babel/helper-skip-transparent-expression-wrappers" "^7.16.0" "@babel/plugin-proposal-optional-chaining" "^7.16.7" -"@babel/plugin-proposal-async-generator-functions@^7.12.1": - version "7.12.12" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.12.12.tgz#04b8f24fd4532008ab4e79f788468fd5a8476566" - integrity sha512-nrz9y0a4xmUrRq51bYkWJIO5SBZyG2ys2qinHsN0zHDHVsUaModrkpyWWWXfGqYQmOL3x9sQIcTNN/pBGpo09A== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-remap-async-to-generator" "^7.12.1" - "@babel/plugin-syntax-async-generators" "^7.8.0" - "@babel/plugin-proposal-async-generator-functions@^7.16.8": version "7.16.8" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.16.8.tgz#3bdd1ebbe620804ea9416706cd67d60787504bc8" @@ -627,15 +370,7 @@ "@babel/helper-remap-async-to-generator" "^7.16.8" "@babel/plugin-syntax-async-generators" "^7.8.4" -"@babel/plugin-proposal-class-properties@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.12.1.tgz#a082ff541f2a29a4821065b8add9346c0c16e5de" - integrity sha512-cKp3dlQsFsEs5CWKnN7BnSHOd0EOW8EKpEjkoz1pO2E5KzIDNV9Ros1b0CnmbVgAGXJubOYVBOGCT1OmJwOI7w== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.12.1" - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-proposal-class-properties@^7.16.7": +"@babel/plugin-proposal-class-properties@^7.12.1", "@babel/plugin-proposal-class-properties@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.16.7.tgz#925cad7b3b1a2fcea7e59ecc8eb5954f961f91b0" integrity sha512-IobU0Xme31ewjYOShSIqd/ZGM/r/cuOz2z0MDbNrhF5FW+ZVgi0f2lyeoj9KFPDOAqsYxmLWZte1WOwlvY9aww== @@ -669,14 +404,6 @@ "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-do-expressions" "^7.12.1" -"@babel/plugin-proposal-dynamic-import@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.12.1.tgz#43eb5c2a3487ecd98c5c8ea8b5fdb69a2749b2dc" - integrity sha512-a4rhUSZFuq5W8/OO8H7BL5zspjnc1FLd9hlOxIK/f7qG4a0qsqk8uvF/ywgBA8/OmjsapjpvaEOYItfGG1qIvQ== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-syntax-dynamic-import" "^7.8.0" - "@babel/plugin-proposal-dynamic-import@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.16.7.tgz#c19c897eaa46b27634a00fee9fb7d829158704b2" @@ -693,15 +420,7 @@ "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-export-default-from" "^7.12.1" -"@babel/plugin-proposal-export-namespace-from@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.12.1.tgz#8b9b8f376b2d88f5dd774e4d24a5cc2e3679b6d4" - integrity sha512-6CThGf0irEkzujYS5LQcjBx8j/4aQGiVv7J9+2f7pGfxqyKh3WnmVJYW3hdrQjyksErMGBPQrCnHfOtna+WLbw== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-syntax-export-namespace-from" "^7.8.3" - -"@babel/plugin-proposal-export-namespace-from@^7.16.7": +"@babel/plugin-proposal-export-namespace-from@^7.12.1", "@babel/plugin-proposal-export-namespace-from@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.16.7.tgz#09de09df18445a5786a305681423ae63507a6163" integrity sha512-ZxdtqDXLRGBL64ocZcs7ovt71L3jhC1RGSyR996svrCi3PYqHNkb3SwPJCs8RIzD86s+WPpt2S73+EHCGO+NUA== @@ -726,15 +445,7 @@ "@babel/helper-wrap-function" "^7.10.4" "@babel/plugin-syntax-function-sent" "^7.12.1" -"@babel/plugin-proposal-json-strings@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.12.1.tgz#d45423b517714eedd5621a9dfdc03fa9f4eb241c" - integrity sha512-GoLDUi6U9ZLzlSda2Df++VSqDJg3CG+dR0+iWsv6XRw1rEq+zwt4DirM9yrxW6XWaTpmai1cWJLMfM8qQJf+yw== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-syntax-json-strings" "^7.8.0" - -"@babel/plugin-proposal-json-strings@^7.16.7": +"@babel/plugin-proposal-json-strings@^7.12.1", "@babel/plugin-proposal-json-strings@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.16.7.tgz#9732cb1d17d9a2626a08c5be25186c195b6fa6e8" integrity sha512-lNZ3EEggsGY78JavgbHsK9u5P3pQaW7k4axlgFLYkMd7UBsiNahCITShLjNQschPyjtO6dADrL24757IdhBrsQ== @@ -742,15 +453,7 @@ "@babel/helper-plugin-utils" "^7.16.7" "@babel/plugin-syntax-json-strings" "^7.8.3" -"@babel/plugin-proposal-logical-assignment-operators@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.12.1.tgz#f2c490d36e1b3c9659241034a5d2cd50263a2751" - integrity sha512-k8ZmVv0JU+4gcUGeCDZOGd0lCIamU/sMtIiX3UWnUc5yzgq6YUGyEolNYD+MLYKfSzgECPcqetVcJP9Afe/aCA== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" - -"@babel/plugin-proposal-logical-assignment-operators@^7.16.7": +"@babel/plugin-proposal-logical-assignment-operators@^7.12.1", "@babel/plugin-proposal-logical-assignment-operators@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.16.7.tgz#be23c0ba74deec1922e639832904be0bea73cdea" integrity sha512-K3XzyZJGQCr00+EtYtrDjmwX7o7PLK6U9bi1nCwkQioRFVUv6dJoxbQjtWVtP+bCPy82bONBKG8NPyQ4+i6yjg== @@ -758,15 +461,7 @@ "@babel/helper-plugin-utils" "^7.16.7" "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" -"@babel/plugin-proposal-nullish-coalescing-operator@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.12.1.tgz#3ed4fff31c015e7f3f1467f190dbe545cd7b046c" - integrity sha512-nZY0ESiaQDI1y96+jk6VxMOaL4LPo/QDHBqL+SF3/vl6dHkTwHlOI8L4ZwuRBHgakRBw5zsVylel7QPbbGuYgg== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0" - -"@babel/plugin-proposal-nullish-coalescing-operator@^7.16.7": +"@babel/plugin-proposal-nullish-coalescing-operator@^7.12.1", "@babel/plugin-proposal-nullish-coalescing-operator@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.16.7.tgz#141fc20b6857e59459d430c850a0011e36561d99" integrity sha512-aUOrYU3EVtjf62jQrCj63pYZ7k6vns2h/DQvHPWGmsJRYzWXZ6/AsfgpiRy6XiuIDADhJzP2Q9MwSMKauBQ+UQ== @@ -774,14 +469,6 @@ "@babel/helper-plugin-utils" "^7.16.7" "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" -"@babel/plugin-proposal-numeric-separator@^7.12.7": - version "7.12.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.12.7.tgz#8bf253de8139099fea193b297d23a9d406ef056b" - integrity sha512-8c+uy0qmnRTeukiGsjLGy6uVs/TFjJchGXUeBqlG4VWYOdJWkhhVPdQ3uHwbmalfJwv2JsV0qffXP4asRfL2SQ== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-syntax-numeric-separator" "^7.10.4" - "@babel/plugin-proposal-numeric-separator@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.16.7.tgz#d6b69f4af63fb38b6ca2558442a7fb191236eba9" @@ -790,15 +477,6 @@ "@babel/helper-plugin-utils" "^7.16.7" "@babel/plugin-syntax-numeric-separator" "^7.10.4" -"@babel/plugin-proposal-object-rest-spread@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.12.1.tgz#def9bd03cea0f9b72283dac0ec22d289c7691069" - integrity sha512-s6SowJIjzlhx8o7lsFx5zmY4At6CTtDvgNQDdPzkBQucle58A6b/TTeEBYtyDgmcXjUTM+vE8YOGHZzzbc/ioA== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-syntax-object-rest-spread" "^7.8.0" - "@babel/plugin-transform-parameters" "^7.12.1" - "@babel/plugin-proposal-object-rest-spread@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.16.7.tgz#94593ef1ddf37021a25bdcb5754c4a8d534b01d8" @@ -810,14 +488,6 @@ "@babel/plugin-syntax-object-rest-spread" "^7.8.3" "@babel/plugin-transform-parameters" "^7.16.7" -"@babel/plugin-proposal-optional-catch-binding@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.12.1.tgz#ccc2421af64d3aae50b558a71cede929a5ab2942" - integrity sha512-hFvIjgprh9mMw5v42sJWLI1lzU5L2sznP805zeT6rySVRA0Y18StRhDqhSxlap0oVgItRsB6WSROp4YnJTJz0g== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-syntax-optional-catch-binding" "^7.8.0" - "@babel/plugin-proposal-optional-catch-binding@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.16.7.tgz#c623a430674ffc4ab732fd0a0ae7722b67cb74cf" @@ -826,16 +496,7 @@ "@babel/helper-plugin-utils" "^7.16.7" "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" -"@babel/plugin-proposal-optional-chaining@^7.12.7": - version "7.12.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.12.7.tgz#e02f0ea1b5dc59d401ec16fb824679f683d3303c" - integrity sha512-4ovylXZ0PWmwoOvhU2vhnzVNnm88/Sm9nx7V8BPgMvAzn5zDou3/Awy0EjglyubVHasJj+XCEkr/r1X3P5elCA== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-skip-transparent-expression-wrappers" "^7.12.1" - "@babel/plugin-syntax-optional-chaining" "^7.8.0" - -"@babel/plugin-proposal-optional-chaining@^7.16.7": +"@babel/plugin-proposal-optional-chaining@^7.12.7", "@babel/plugin-proposal-optional-chaining@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.16.7.tgz#7cd629564724816c0e8a969535551f943c64c39a" integrity sha512-eC3xy+ZrUcBtP7x+sq62Q/HYd674pPTb/77XZMb5wbDPGWIdUbSr4Agr052+zaUPSb+gGRnjxXfKFvx5iMJ+DA== @@ -852,14 +513,6 @@ "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-pipeline-operator" "^7.12.1" -"@babel/plugin-proposal-private-methods@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.12.1.tgz#86814f6e7a21374c980c10d38b4493e703f4a389" - integrity sha512-mwZ1phvH7/NHK6Kf8LP7MYDogGV+DKB1mryFOEwx5EBNQrosvIczzZFTUmWaeujd5xT6G1ELYWUz3CutMhjE1w== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.12.1" - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-proposal-private-methods@^7.16.11": version "7.16.11" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.16.11.tgz#e8df108288555ff259f4527dbe84813aac3a1c50" @@ -886,15 +539,7 @@ "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-throw-expressions" "^7.12.1" -"@babel/plugin-proposal-unicode-property-regex@^7.12.1", "@babel/plugin-proposal-unicode-property-regex@^7.4.4": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.12.1.tgz#2a183958d417765b9eae334f47758e5d6a82e072" - integrity sha512-MYq+l+PvHuw/rKUz1at/vb6nCnQ2gmJBNaM62z0OgH7B2W1D9pvkpYtlti9bGtizNIU1K3zm4bZF9F91efVY0w== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.12.1" - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-proposal-unicode-property-regex@^7.16.7": +"@babel/plugin-proposal-unicode-property-regex@^7.16.7", "@babel/plugin-proposal-unicode-property-regex@^7.4.4": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.16.7.tgz#635d18eb10c6214210ffc5ff4932552de08188a2" integrity sha512-QRK0YI/40VLhNVGIjRNAAQkEHws0cswSdFFjpFyt943YmJIU1da9uW63Iu6NFV6CxTZW5eTDCrwZUstBWgp/Rg== @@ -902,7 +547,7 @@ "@babel/helper-create-regexp-features-plugin" "^7.16.7" "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-syntax-async-generators@^7.8.0", "@babel/plugin-syntax-async-generators@^7.8.4": +"@babel/plugin-syntax-async-generators@^7.8.4": version "7.8.4" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== @@ -916,7 +561,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-class-properties@^7.12.1", "@babel/plugin-syntax-class-properties@^7.12.13", "@babel/plugin-syntax-class-properties@^7.8.3": +"@babel/plugin-syntax-class-properties@^7.12.13", "@babel/plugin-syntax-class-properties@^7.8.3": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10" integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== @@ -944,7 +589,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-syntax-dynamic-import@^7.8.0", "@babel/plugin-syntax-dynamic-import@^7.8.3": +"@babel/plugin-syntax-dynamic-import@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3" integrity sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ== @@ -986,20 +631,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-syntax-json-strings@^7.8.0", "@babel/plugin-syntax-json-strings@^7.8.3": +"@babel/plugin-syntax-json-strings@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-jsx@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.12.1.tgz#9d9d357cc818aa7ae7935917c1257f67677a0926" - integrity sha512-1yRi7yAtB0ETgxdY9ti/p2TivUxJkTdhu/ZbF9MshVGqOx1TdB3b7xCXs49Fupgg50N45KcAsRP/ZqWjs9SRjg== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-syntax-jsx@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.16.7.tgz#50b6571d13f764266a113d77c82b4a6508bbe665" @@ -1014,7 +652,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.0", "@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": +"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== @@ -1028,21 +666,21 @@ dependencies: "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-syntax-object-rest-spread@^7.8.0", "@babel/plugin-syntax-object-rest-spread@^7.8.3": +"@babel/plugin-syntax-object-rest-spread@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-optional-catch-binding@^7.8.0", "@babel/plugin-syntax-optional-catch-binding@^7.8.3": +"@babel/plugin-syntax-optional-catch-binding@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-optional-chaining@^7.8.0", "@babel/plugin-syntax-optional-chaining@^7.8.3": +"@babel/plugin-syntax-optional-chaining@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== @@ -1070,20 +708,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-syntax-top-level-await@^7.12.1", "@babel/plugin-syntax-top-level-await@^7.14.5", "@babel/plugin-syntax-top-level-await@^7.8.3": +"@babel/plugin-syntax-top-level-await@^7.14.5", "@babel/plugin-syntax-top-level-await@^7.8.3": version "7.14.5" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz#c1cfdadc35a646240001f06138247b741c34d94c" integrity sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw== dependencies: "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-syntax-typescript@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.12.1.tgz#460ba9d77077653803c3dd2e673f76d66b4029e5" - integrity sha512-UZNEcCY+4Dp9yYRCAHrHDU+9ZXLYaY9MgBXSRLkB9WjYFRR6quJBumfVrEkUxrePPBwFcpWfNKXqVRQQtm7mMA== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-syntax-typescript@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.16.7.tgz#39c9b55ee153151990fb038651d58d3fd03f98f8" @@ -1091,13 +722,6 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-arrow-functions@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.12.1.tgz#8083ffc86ac8e777fbe24b5967c4b2521f3cb2b3" - integrity sha512-5QB50qyN44fzzz4/qxDPQMBCTHgxg3n0xRBLJUmBlLoU/sFvxVWGZF/ZUfMVDQuJUKXaBhbupxIzIfZ6Fwk/0A== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-transform-arrow-functions@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.16.7.tgz#44125e653d94b98db76369de9c396dc14bef4154" @@ -1105,15 +729,6 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-async-to-generator@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.12.1.tgz#3849a49cc2a22e9743cbd6b52926d30337229af1" - integrity sha512-SDtqoEcarK1DFlRJ1hHRY5HvJUj5kX4qmtpMAm2QnhOlyuMC4TMdCRgW6WXpv93rZeYNeLP22y8Aq2dbcDRM1A== - dependencies: - "@babel/helper-module-imports" "^7.12.1" - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-remap-async-to-generator" "^7.12.1" - "@babel/plugin-transform-async-to-generator@^7.16.8": version "7.16.8" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.16.8.tgz#b83dff4b970cf41f1b819f8b49cc0cfbaa53a808" @@ -1123,13 +738,6 @@ "@babel/helper-plugin-utils" "^7.16.7" "@babel/helper-remap-async-to-generator" "^7.16.8" -"@babel/plugin-transform-block-scoped-functions@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.12.1.tgz#f2a1a365bde2b7112e0a6ded9067fdd7c07905d9" - integrity sha512-5OpxfuYnSgPalRpo8EWGPzIYf0lHBWORCkj5M0oLBwHdlux9Ri36QqGW3/LR13RSVOAoUUMzoPI/jpE4ABcHoA== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-transform-block-scoped-functions@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.16.7.tgz#4d0d57d9632ef6062cdf354bb717102ee042a620" @@ -1137,13 +745,6 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-block-scoping@^7.12.11": - version "7.12.12" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.12.12.tgz#d93a567a152c22aea3b1929bb118d1d0a175cdca" - integrity sha512-VOEPQ/ExOVqbukuP7BYJtI5ZxxsmegTwzZ04j1aF0dkSypGo9XpDHuOrABsJu+ie+penpSJheDJ11x1BEZNiyQ== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-transform-block-scoping@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.16.7.tgz#f50664ab99ddeaee5bc681b8f3a6ea9d72ab4f87" @@ -1151,20 +752,6 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-classes@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.12.1.tgz#65e650fcaddd3d88ddce67c0f834a3d436a32db6" - integrity sha512-/74xkA7bVdzQTBeSUhLLJgYIcxw/dpEpCdRDiHgPJ3Mv6uC11UhjpOhl72CgqbBCmt1qtssCyB2xnJm1+PFjog== - dependencies: - "@babel/helper-annotate-as-pure" "^7.10.4" - "@babel/helper-define-map" "^7.10.4" - "@babel/helper-function-name" "^7.10.4" - "@babel/helper-optimise-call-expression" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-replace-supers" "^7.12.1" - "@babel/helper-split-export-declaration" "^7.10.4" - globals "^11.1.0" - "@babel/plugin-transform-classes@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.16.7.tgz#8f4b9562850cd973de3b498f1218796eb181ce00" @@ -1179,13 +766,6 @@ "@babel/helper-split-export-declaration" "^7.16.7" globals "^11.1.0" -"@babel/plugin-transform-computed-properties@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.12.1.tgz#d68cf6c9b7f838a8a4144badbe97541ea0904852" - integrity sha512-vVUOYpPWB7BkgUWPo4C44mUQHpTZXakEqFjbv8rQMg7TC6S6ZhGZ3otQcRH6u7+adSlE5i0sp63eMC/XGffrzg== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-transform-computed-properties@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.16.7.tgz#66dee12e46f61d2aae7a73710f591eb3df616470" @@ -1193,13 +773,6 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-destructuring@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.12.1.tgz#b9a570fe0d0a8d460116413cb4f97e8e08b2f847" - integrity sha512-fRMYFKuzi/rSiYb2uRLiUENJOKq4Gnl+6qOv5f8z0TZXg3llUwUhsNNwrwaT/6dUhJTzNpBr+CUvEWBtfNY1cw== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-transform-destructuring@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.16.7.tgz#ca9588ae2d63978a4c29d3f33282d8603f618e23" @@ -1207,15 +780,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-dotall-regex@^7.12.1", "@babel/plugin-transform-dotall-regex@^7.4.4": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.12.1.tgz#a1d16c14862817b6409c0a678d6f9373ca9cd975" - integrity sha512-B2pXeRKoLszfEW7J4Hg9LoFaWEbr/kzo3teWHmtFCszjRNa/b40f9mfeqZsIDLLt/FjwQ6pz/Gdlwy85xNckBA== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.12.1" - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-transform-dotall-regex@^7.16.7": +"@babel/plugin-transform-dotall-regex@^7.16.7", "@babel/plugin-transform-dotall-regex@^7.4.4": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.16.7.tgz#6b2d67686fab15fb6a7fd4bd895d5982cfc81241" integrity sha512-Lyttaao2SjZF6Pf4vk1dVKv8YypMpomAbygW+mU5cYP3S5cWTfCJjG8xV6CFdzGFlfWK81IjL9viiTvpb6G7gQ== @@ -1223,13 +788,6 @@ "@babel/helper-create-regexp-features-plugin" "^7.16.7" "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-duplicate-keys@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.12.1.tgz#745661baba295ac06e686822797a69fbaa2ca228" - integrity sha512-iRght0T0HztAb/CazveUpUQrZY+aGKKaWXMJ4uf9YJtqxSUe09j3wteztCUDRHs+SRAL7yMuFqUsLoAKKzgXjw== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-transform-duplicate-keys@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.16.7.tgz#2207e9ca8f82a0d36a5a67b6536e7ef8b08823c9" @@ -1237,14 +795,6 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-exponentiation-operator@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.12.1.tgz#b0f2ed356ba1be1428ecaf128ff8a24f02830ae0" - integrity sha512-7tqwy2bv48q+c1EHbXK0Zx3KXd2RVQp6OC7PbwFNt/dPTAV3Lu5sWtWuAj8owr5wqtWnqHfl2/mJlUmqkChKug== - dependencies: - "@babel/helper-builder-binary-assignment-operator-visitor" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-transform-exponentiation-operator@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.16.7.tgz#efa9862ef97e9e9e5f653f6ddc7b665e8536fe9b" @@ -1253,13 +803,6 @@ "@babel/helper-builder-binary-assignment-operator-visitor" "^7.16.7" "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-for-of@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.12.1.tgz#07640f28867ed16f9511c99c888291f560921cfa" - integrity sha512-Zaeq10naAsuHo7heQvyV0ptj4dlZJwZgNAtBYBnu5nNKJoW62m0zKcIEyVECrUKErkUkg6ajMy4ZfnVZciSBhg== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-transform-for-of@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.16.7.tgz#649d639d4617dff502a9a158c479b3b556728d8c" @@ -1267,14 +810,6 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-function-name@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.12.1.tgz#2ec76258c70fe08c6d7da154003a480620eba667" - integrity sha512-JF3UgJUILoFrFMEnOJLJkRHSk6LUSXLmEFsA23aR2O5CSLUxbeUX1IZ1YQ7Sn0aXb601Ncwjx73a+FVqgcljVw== - dependencies: - "@babel/helper-function-name" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-transform-function-name@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.16.7.tgz#5ab34375c64d61d083d7d2f05c38d90b97ec65cf" @@ -1284,13 +819,6 @@ "@babel/helper-function-name" "^7.16.7" "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-literals@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.12.1.tgz#d73b803a26b37017ddf9d3bb8f4dc58bfb806f57" - integrity sha512-+PxVGA+2Ag6uGgL0A5f+9rklOnnMccwEBzwYFL3EUaKuiyVnUipyXncFcfjSkbimLrODoqki1U9XxZzTvfN7IQ== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-transform-literals@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.16.7.tgz#254c9618c5ff749e87cb0c0cef1a0a050c0bdab1" @@ -1298,13 +826,6 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-member-expression-literals@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.12.1.tgz#496038602daf1514a64d43d8e17cbb2755e0c3ad" - integrity sha512-1sxePl6z9ad0gFMB9KqmYofk34flq62aqMt9NqliS/7hPEpURUCMbyHXrMPlo282iY7nAvUB1aQd5mg79UD9Jg== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-transform-member-expression-literals@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.16.7.tgz#6e5dcf906ef8a098e630149d14c867dd28f92384" @@ -1312,15 +833,6 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-modules-amd@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.12.1.tgz#3154300b026185666eebb0c0ed7f8415fefcf6f9" - integrity sha512-tDW8hMkzad5oDtzsB70HIQQRBiTKrhfgwC/KkJeGsaNFTdWhKNt/BiE8c5yj19XiGyrxpbkOfH87qkNg1YGlOQ== - dependencies: - "@babel/helper-module-transforms" "^7.12.1" - "@babel/helper-plugin-utils" "^7.10.4" - babel-plugin-dynamic-import-node "^2.3.3" - "@babel/plugin-transform-modules-amd@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.16.7.tgz#b28d323016a7daaae8609781d1f8c9da42b13186" @@ -1330,16 +842,6 @@ "@babel/helper-plugin-utils" "^7.16.7" babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-modules-commonjs@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.12.1.tgz#fa403124542636c786cf9b460a0ffbb48a86e648" - integrity sha512-dY789wq6l0uLY8py9c1B48V8mVL5gZh/+PQ5ZPrylPYsnAvnEMjqsUXkuoDVPeVK+0VyGar+D08107LzDQ6pag== - dependencies: - "@babel/helper-module-transforms" "^7.12.1" - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-simple-access" "^7.12.1" - babel-plugin-dynamic-import-node "^2.3.3" - "@babel/plugin-transform-modules-commonjs@^7.16.8": version "7.16.8" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.16.8.tgz#cdee19aae887b16b9d331009aa9a219af7c86afe" @@ -1350,17 +852,6 @@ "@babel/helper-simple-access" "^7.16.7" babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-modules-systemjs@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.12.1.tgz#663fea620d593c93f214a464cd399bf6dc683086" - integrity sha512-Hn7cVvOavVh8yvW6fLwveFqSnd7rbQN3zJvoPNyNaQSvgfKmDBO9U1YL9+PCXGRlZD9tNdWTy5ACKqMuzyn32Q== - dependencies: - "@babel/helper-hoist-variables" "^7.10.4" - "@babel/helper-module-transforms" "^7.12.1" - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-validator-identifier" "^7.10.4" - babel-plugin-dynamic-import-node "^2.3.3" - "@babel/plugin-transform-modules-systemjs@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.16.7.tgz#887cefaef88e684d29558c2b13ee0563e287c2d7" @@ -1372,14 +863,6 @@ "@babel/helper-validator-identifier" "^7.16.7" babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-modules-umd@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.12.1.tgz#eb5a218d6b1c68f3d6217b8fa2cc82fec6547902" - integrity sha512-aEIubCS0KHKM0zUos5fIoQm+AZUMt1ZvMpqz0/H5qAQ7vWylr9+PLYurT+Ic7ID/bKLd4q8hDovaG3Zch2uz5Q== - dependencies: - "@babel/helper-module-transforms" "^7.12.1" - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-transform-modules-umd@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.16.7.tgz#23dad479fa585283dbd22215bff12719171e7618" @@ -1388,13 +871,6 @@ "@babel/helper-module-transforms" "^7.16.7" "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-named-capturing-groups-regex@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.12.1.tgz#b407f5c96be0d9f5f88467497fa82b30ac3e8753" - integrity sha512-tB43uQ62RHcoDp9v2Nsf+dSM8sbNodbEicbQNA53zHz8pWUhsgHSJCGpt7daXxRydjb0KnfmB+ChXOv3oADp1Q== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.12.1" - "@babel/plugin-transform-named-capturing-groups-regex@^7.16.8": version "7.16.8" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.16.8.tgz#7f860e0e40d844a02c9dcf9d84965e7dfd666252" @@ -1402,13 +878,6 @@ dependencies: "@babel/helper-create-regexp-features-plugin" "^7.16.7" -"@babel/plugin-transform-new-target@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.12.1.tgz#80073f02ee1bb2d365c3416490e085c95759dec0" - integrity sha512-+eW/VLcUL5L9IvJH7rT1sT0CzkdUTvPrXC2PXTn/7z7tXLBuKvezYbGdxD5WMRoyvyaujOq2fWoKl869heKjhw== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-transform-new-target@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.16.7.tgz#9967d89a5c243818e0800fdad89db22c5f514244" @@ -1416,14 +885,6 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-object-super@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.12.1.tgz#4ea08696b8d2e65841d0c7706482b048bed1066e" - integrity sha512-AvypiGJH9hsquNUn+RXVcBdeE3KHPZexWRdimhuV59cSoOt5kFBmqlByorAeUlGG2CJWd0U+4ZtNKga/TB0cAw== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-replace-supers" "^7.12.1" - "@babel/plugin-transform-object-super@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.16.7.tgz#ac359cf8d32cf4354d27a46867999490b6c32a94" @@ -1432,13 +893,6 @@ "@babel/helper-plugin-utils" "^7.16.7" "@babel/helper-replace-supers" "^7.16.7" -"@babel/plugin-transform-parameters@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.12.1.tgz#d2e963b038771650c922eff593799c96d853255d" - integrity sha512-xq9C5EQhdPK23ZeCdMxl8bbRnAgHFrw5EOC3KJUsSylZqdkCaFEXxGSBuTSObOpiiHHNyb82es8M1QYgfQGfNg== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-transform-parameters@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.16.7.tgz#a1721f55b99b736511cb7e0152f61f17688f331f" @@ -1446,13 +900,6 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-property-literals@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.12.1.tgz#41bc81200d730abb4456ab8b3fbd5537b59adecd" - integrity sha512-6MTCR/mZ1MQS+AwZLplX4cEySjCpnIF26ToWo942nqn8hXSm7McaHQNeGx/pt7suI1TWOWMfa/NgBhiqSnX0cQ== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-transform-property-literals@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.16.7.tgz#2dadac85155436f22c696c4827730e0fe1057a55" @@ -1460,27 +907,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-react-constant-elements@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.12.1.tgz#4471f0851feec3231cc9aaa0dccde39947c1ac1e" - integrity sha512-KOHd0tIRLoER+J+8f9DblZDa1fLGPwaaN1DI1TVHuQFOpjHV22C3CUB3obeC4fexHY9nx+fH0hQNvLFFfA1mxA== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-transform-react-constant-elements@^7.14.5": +"@babel/plugin-transform-react-constant-elements@^7.12.1", "@babel/plugin-transform-react-constant-elements@^7.14.5": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.16.7.tgz#19e9e4c2df2f6c3e6b3aea11778297d81db8df62" integrity sha512-lF+cfsyTgwWkcw715J88JhMYJ5GpysYNLhLP1PkvkhTRN7B3e74R/1KsDxFxhRpSn0UUD3IWM4GvdBR2PEbbQQ== dependencies: "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-react-display-name@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.12.1.tgz#1cbcd0c3b1d6648c55374a22fc9b6b7e5341c00d" - integrity sha512-cAzB+UzBIrekfYxyLlFqf/OagTvHLcVBb5vpouzkYkBclRPraiygVnafvAoipErZLI8ANv8Ecn6E/m5qPXD26w== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-transform-react-display-name@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.16.7.tgz#7b6d40d232f4c0f550ea348593db3b21e2404340" @@ -1496,13 +929,6 @@ "@babel/helper-builder-react-jsx" "^7.10.4" "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-react-jsx-development@^7.12.7": - version "7.12.12" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.12.12.tgz#bccca33108fe99d95d7f9e82046bfe762e71f4e7" - integrity sha512-i1AxnKxHeMxUaWVXQOSIco4tvVvvCxMSfeBMnMM06mpaJt3g+MpxYQQrDfojUQldP1xxraPSJYSMEljoWM/dCg== - dependencies: - "@babel/plugin-transform-react-jsx" "^7.12.12" - "@babel/plugin-transform-react-jsx-development@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.16.7.tgz#43a00724a3ed2557ed3f276a01a929e6686ac7b8" @@ -1510,17 +936,6 @@ dependencies: "@babel/plugin-transform-react-jsx" "^7.16.7" -"@babel/plugin-transform-react-jsx@^7.12.10", "@babel/plugin-transform-react-jsx@^7.12.12": - version "7.12.12" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.12.12.tgz#b0da51ffe5f34b9a900e9f1f5fb814f9e512d25e" - integrity sha512-JDWGuzGNWscYcq8oJVCtSE61a5+XAOos+V0HrxnDieUus4UMnBEosDnY1VJqU5iZ4pA04QY7l0+JvHL1hZEfsw== - dependencies: - "@babel/helper-annotate-as-pure" "^7.12.10" - "@babel/helper-module-imports" "^7.12.5" - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-syntax-jsx" "^7.12.1" - "@babel/types" "^7.12.12" - "@babel/plugin-transform-react-jsx@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.16.7.tgz#86a6a220552afd0e4e1f0388a68a372be7add0d4" @@ -1532,14 +947,6 @@ "@babel/plugin-syntax-jsx" "^7.16.7" "@babel/types" "^7.16.7" -"@babel/plugin-transform-react-pure-annotations@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.12.1.tgz#05d46f0ab4d1339ac59adf20a1462c91b37a1a42" - integrity sha512-RqeaHiwZtphSIUZ5I85PEH19LOSzxfuEazoY7/pWASCAIBuATQzpSVD+eT6MebeeZT2F4eSL0u4vw6n4Nm0Mjg== - dependencies: - "@babel/helper-annotate-as-pure" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-transform-react-pure-annotations@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.16.7.tgz#232bfd2f12eb551d6d7d01d13fe3f86b45eb9c67" @@ -1548,13 +955,6 @@ "@babel/helper-annotate-as-pure" "^7.16.7" "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-regenerator@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.12.1.tgz#5f0a28d842f6462281f06a964e88ba8d7ab49753" - integrity sha512-gYrHqs5itw6i4PflFX3OdBPMQdPbF4bj2REIUxlMRUFk0/ZOAIpDFuViuxPjUL7YC8UPnf+XG7/utJvqXdPKng== - dependencies: - regenerator-transform "^0.14.2" - "@babel/plugin-transform-regenerator@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.16.7.tgz#9e7576dc476cb89ccc5096fff7af659243b4adeb" @@ -1562,13 +962,6 @@ dependencies: regenerator-transform "^0.14.2" -"@babel/plugin-transform-reserved-words@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.12.1.tgz#6fdfc8cc7edcc42b36a7c12188c6787c873adcd8" - integrity sha512-pOnUfhyPKvZpVyBHhSBoX8vfA09b7r00Pmm1sH+29ae2hMTKVmSp4Ztsr8KBKjLjx17H0eJqaRC3bR2iThM54A== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-transform-reserved-words@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.16.7.tgz#1d798e078f7c5958eec952059c460b220a63f586" @@ -1585,13 +978,6 @@ "@babel/helper-plugin-utils" "^7.10.4" semver "^5.5.1" -"@babel/plugin-transform-shorthand-properties@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.12.1.tgz#0bf9cac5550fce0cfdf043420f661d645fdc75e3" - integrity sha512-GFZS3c/MhX1OusqB1MZ1ct2xRzX5ppQh2JU1h2Pnfk88HtFTM+TWQqJNfwkmxtPQtb/s1tk87oENfXJlx7rSDw== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-transform-shorthand-properties@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.16.7.tgz#e8549ae4afcf8382f711794c0c7b6b934c5fbd2a" @@ -1599,14 +985,6 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-spread@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.12.1.tgz#527f9f311be4ec7fdc2b79bb89f7bf884b3e1e1e" - integrity sha512-vuLp8CP0BE18zVYjsEBZ5xoCecMK6LBMMxYzJnh01rxQRvhNhH1csMMmBfNo5tGpGO+NhdSNW2mzIvBu3K1fng== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-skip-transparent-expression-wrappers" "^7.12.1" - "@babel/plugin-transform-spread@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.16.7.tgz#a303e2122f9f12e0105daeedd0f30fb197d8ff44" @@ -1615,13 +993,6 @@ "@babel/helper-plugin-utils" "^7.16.7" "@babel/helper-skip-transparent-expression-wrappers" "^7.16.0" -"@babel/plugin-transform-sticky-regex@^7.12.7": - version "7.12.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.12.7.tgz#560224613ab23987453948ed21d0b0b193fa7fad" - integrity sha512-VEiqZL5N/QvDbdjfYQBhruN0HYjSPjC4XkeqW4ny/jNtH9gcbgaqBIXYEZCNnESMAGs0/K/R7oFGMhOyu/eIxg== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-transform-sticky-regex@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.16.7.tgz#c84741d4f4a38072b9a1e2e3fd56d359552e8660" @@ -1629,13 +1000,6 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-template-literals@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.12.1.tgz#b43ece6ed9a79c0c71119f576d299ef09d942843" - integrity sha512-b4Zx3KHi+taXB1dVRBhVJtEPi9h1THCeKmae2qP0YdUHIFhVjtpqqNfxeVAa1xeHVhAy4SbHxEwx5cltAu5apw== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-transform-template-literals@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.16.7.tgz#f3d1c45d28967c8e80f53666fc9c3e50618217ab" @@ -1643,13 +1007,6 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-typeof-symbol@^7.12.10": - version "7.12.10" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.12.10.tgz#de01c4c8f96580bd00f183072b0d0ecdcf0dec4b" - integrity sha512-JQ6H8Rnsogh//ijxspCjc21YPd3VLVoYtAwv3zQmqAt8YGYUtdo5usNhdl4b9/Vir2kPFZl6n1h0PfUz4hJhaA== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-transform-typeof-symbol@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.16.7.tgz#9cdbe622582c21368bd482b660ba87d5545d4f7e" @@ -1657,15 +1014,6 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-typescript@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.12.1.tgz#d92cc0af504d510e26a754a7dbc2e5c8cd9c7ab4" - integrity sha512-VrsBByqAIntM+EYMqSm59SiMEf7qkmI9dqMt6RbD/wlwueWmYcI0FFK5Fj47pP6DRZm+3teXjosKlwcZJ5lIMw== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.12.1" - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-syntax-typescript" "^7.12.1" - "@babel/plugin-transform-typescript@^7.16.7": version "7.16.8" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.16.8.tgz#591ce9b6b83504903fa9dd3652c357c2ba7a1ee0" @@ -1675,13 +1023,6 @@ "@babel/helper-plugin-utils" "^7.16.7" "@babel/plugin-syntax-typescript" "^7.16.7" -"@babel/plugin-transform-unicode-escapes@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.12.1.tgz#5232b9f81ccb07070b7c3c36c67a1b78f1845709" - integrity sha512-I8gNHJLIc7GdApm7wkVnStWssPNbSRMPtgHdmH3sRM1zopz09UWPS4x5V4n1yz/MIWTVnJ9sp6IkuXdWM4w+2Q== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-transform-unicode-escapes@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.16.7.tgz#da8717de7b3287a2c6d659750c964f302b31ece3" @@ -1689,14 +1030,6 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-unicode-regex@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.12.1.tgz#cc9661f61390db5c65e3febaccefd5c6ac3faecb" - integrity sha512-SqH4ClNngh/zGwHZOOQMTD+e8FGWexILV+ePMyiDJttAWRh5dhDL8rcl5lSgU3Huiq6Zn6pWTMvdPAb21Dwdyg== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.12.1" - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-transform-unicode-regex@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.16.7.tgz#0f7aa4a501198976e25e82702574c34cfebe9ef2" @@ -1705,79 +1038,7 @@ "@babel/helper-create-regexp-features-plugin" "^7.16.7" "@babel/helper-plugin-utils" "^7.16.7" -"@babel/preset-env@^7.12.7": - version "7.12.11" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.12.11.tgz#55d5f7981487365c93dbbc84507b1c7215e857f9" - integrity sha512-j8Tb+KKIXKYlDBQyIOy4BLxzv1NUOwlHfZ74rvW+Z0Gp4/cI2IMDPBWAgWceGcE7aep9oL/0K9mlzlMGxA8yNw== - dependencies: - "@babel/compat-data" "^7.12.7" - "@babel/helper-compilation-targets" "^7.12.5" - "@babel/helper-module-imports" "^7.12.5" - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-validator-option" "^7.12.11" - "@babel/plugin-proposal-async-generator-functions" "^7.12.1" - "@babel/plugin-proposal-class-properties" "^7.12.1" - "@babel/plugin-proposal-dynamic-import" "^7.12.1" - "@babel/plugin-proposal-export-namespace-from" "^7.12.1" - "@babel/plugin-proposal-json-strings" "^7.12.1" - "@babel/plugin-proposal-logical-assignment-operators" "^7.12.1" - "@babel/plugin-proposal-nullish-coalescing-operator" "^7.12.1" - "@babel/plugin-proposal-numeric-separator" "^7.12.7" - "@babel/plugin-proposal-object-rest-spread" "^7.12.1" - "@babel/plugin-proposal-optional-catch-binding" "^7.12.1" - "@babel/plugin-proposal-optional-chaining" "^7.12.7" - "@babel/plugin-proposal-private-methods" "^7.12.1" - "@babel/plugin-proposal-unicode-property-regex" "^7.12.1" - "@babel/plugin-syntax-async-generators" "^7.8.0" - "@babel/plugin-syntax-class-properties" "^7.12.1" - "@babel/plugin-syntax-dynamic-import" "^7.8.0" - "@babel/plugin-syntax-export-namespace-from" "^7.8.3" - "@babel/plugin-syntax-json-strings" "^7.8.0" - "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0" - "@babel/plugin-syntax-numeric-separator" "^7.10.4" - "@babel/plugin-syntax-object-rest-spread" "^7.8.0" - "@babel/plugin-syntax-optional-catch-binding" "^7.8.0" - "@babel/plugin-syntax-optional-chaining" "^7.8.0" - "@babel/plugin-syntax-top-level-await" "^7.12.1" - "@babel/plugin-transform-arrow-functions" "^7.12.1" - "@babel/plugin-transform-async-to-generator" "^7.12.1" - "@babel/plugin-transform-block-scoped-functions" "^7.12.1" - "@babel/plugin-transform-block-scoping" "^7.12.11" - "@babel/plugin-transform-classes" "^7.12.1" - "@babel/plugin-transform-computed-properties" "^7.12.1" - "@babel/plugin-transform-destructuring" "^7.12.1" - "@babel/plugin-transform-dotall-regex" "^7.12.1" - "@babel/plugin-transform-duplicate-keys" "^7.12.1" - "@babel/plugin-transform-exponentiation-operator" "^7.12.1" - "@babel/plugin-transform-for-of" "^7.12.1" - "@babel/plugin-transform-function-name" "^7.12.1" - "@babel/plugin-transform-literals" "^7.12.1" - "@babel/plugin-transform-member-expression-literals" "^7.12.1" - "@babel/plugin-transform-modules-amd" "^7.12.1" - "@babel/plugin-transform-modules-commonjs" "^7.12.1" - "@babel/plugin-transform-modules-systemjs" "^7.12.1" - "@babel/plugin-transform-modules-umd" "^7.12.1" - "@babel/plugin-transform-named-capturing-groups-regex" "^7.12.1" - "@babel/plugin-transform-new-target" "^7.12.1" - "@babel/plugin-transform-object-super" "^7.12.1" - "@babel/plugin-transform-parameters" "^7.12.1" - "@babel/plugin-transform-property-literals" "^7.12.1" - "@babel/plugin-transform-regenerator" "^7.12.1" - "@babel/plugin-transform-reserved-words" "^7.12.1" - "@babel/plugin-transform-shorthand-properties" "^7.12.1" - "@babel/plugin-transform-spread" "^7.12.1" - "@babel/plugin-transform-sticky-regex" "^7.12.7" - "@babel/plugin-transform-template-literals" "^7.12.1" - "@babel/plugin-transform-typeof-symbol" "^7.12.10" - "@babel/plugin-transform-unicode-escapes" "^7.12.1" - "@babel/plugin-transform-unicode-regex" "^7.12.1" - "@babel/preset-modules" "^0.1.3" - "@babel/types" "^7.12.11" - core-js-compat "^3.8.0" - semver "^5.5.0" - -"@babel/preset-env@^7.15.6": +"@babel/preset-env@^7.12.7", "@babel/preset-env@^7.15.6": version "7.16.11" resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.16.11.tgz#5dd88fd885fae36f88fd7c8342475c9f0abe2982" integrity sha512-qcmWG8R7ZW6WBRPZK//y+E3Cli151B20W1Rv7ln27vuPaXU/8TKms6jFdiJtF7UDTxcrb7mZd88tAeK9LjdT8g== @@ -1857,17 +1118,6 @@ core-js-compat "^3.20.2" semver "^6.3.0" -"@babel/preset-modules@^0.1.3": - version "0.1.4" - resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.4.tgz#362f2b68c662842970fdb5e254ffc8fc1c2e415e" - integrity sha512-J36NhwnfdzpmH41M1DrnkkgAqhZaqr/NBdPfQ677mLzlaXo+oDiv1deyCDtgAhz8p328otdob0Du7+xgHGZbKg== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-proposal-unicode-property-regex" "^7.4.4" - "@babel/plugin-transform-dotall-regex" "^7.4.4" - "@babel/types" "^7.4.4" - esutils "^2.0.2" - "@babel/preset-modules@^0.1.5": version "0.1.5" resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.5.tgz#ef939d6e7f268827e1841638dc6ff95515e115d9" @@ -1879,18 +1129,7 @@ "@babel/types" "^7.4.4" esutils "^2.0.2" -"@babel/preset-react@^7.12.7": - version "7.12.10" - resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.12.10.tgz#4fed65f296cbb0f5fb09de6be8cddc85cc909be9" - integrity sha512-vtQNjaHRl4DUpp+t+g4wvTHsLQuye+n0H/wsXIZRn69oz/fvNC7gQ4IK73zGJBaxvHoxElDvnYCthMcT7uzFoQ== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-transform-react-display-name" "^7.12.1" - "@babel/plugin-transform-react-jsx" "^7.12.10" - "@babel/plugin-transform-react-jsx-development" "^7.12.7" - "@babel/plugin-transform-react-pure-annotations" "^7.12.1" - -"@babel/preset-react@^7.14.5": +"@babel/preset-react@^7.12.7", "@babel/preset-react@^7.14.5": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.16.7.tgz#4c18150491edc69c183ff818f9f2aecbe5d93852" integrity sha512-fWpyI8UM/HE6DfPBzD8LnhQ/OcH8AgTaqcqP2nGOXEUV+VKBR5JRN9hCk9ai+zQQ57vtm9oWeXguBCPNUjytgA== @@ -1902,16 +1141,7 @@ "@babel/plugin-transform-react-jsx-development" "^7.16.7" "@babel/plugin-transform-react-pure-annotations" "^7.16.7" -"@babel/preset-typescript@^7.12.7": - version "7.12.7" - resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.12.7.tgz#fc7df8199d6aae747896f1e6c61fc872056632a3" - integrity sha512-nOoIqIqBmHBSEgBXWR4Dv/XBehtIFcw9PqZw6rFYuKrzsZmOQm3PR5siLBnKZFEsDb03IegG8nSjU/iXXXYRmw== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-validator-option" "^7.12.1" - "@babel/plugin-transform-typescript" "^7.12.1" - -"@babel/preset-typescript@^7.15.0": +"@babel/preset-typescript@^7.12.7", "@babel/preset-typescript@^7.15.0": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.16.7.tgz#ab114d68bb2020afc069cd51b37ff98a046a70b9" integrity sha512-WbVEmgXdIyvzB77AQjGBEyYPZx+8tTsO50XtfozQrkW8QB2rLJpH2lgx0TRw5EJrBxOZQ+wCcyPVQvS8tjEHpQ== @@ -1939,23 +1169,14 @@ core-js-pure "^3.0.0" regenerator-runtime "^0.13.4" -"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.10.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5", "@babel/runtime@^7.15.4", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": - version "7.16.3" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.16.3.tgz#b86f0db02a04187a3c17caa77de69840165d42d5" - integrity sha512-WBwekcqacdY2e9AF/Q7WLFUWmdJGJTkbjqTjoMDgXkVZ3ZRUvOPsLb5KdwISoQVsbP+DQzVZW4Zhci0DvpbNTQ== +"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.10.2", "@babel/runtime@^7.11.0", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5", "@babel/runtime@^7.15.4", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.16.7.tgz#03ff99f64106588c9c403c6ecb8c3bafbbdff1fa" + integrity sha512-9E9FJowqAsytyOY6LG+1KuueckRL+aQW+mKvXRXnuFGyRAyepJPmEo9vgMfXUA6O9u3IeEdv9MAkppFcaQwogQ== dependencies: regenerator-runtime "^0.13.4" -"@babel/template@^7.10.4", "@babel/template@^7.15.4", "@babel/template@^7.3.3": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.15.4.tgz#51898d35dcf3faa670c4ee6afcfd517ee139f194" - integrity sha512-UgBAfEa1oGuYgDIPM2G+aHa4Nlo9Lh6mGD2bDBGMTbYnc38vulXPuC1MGjYILIEmlwl6Rd+BPR9ee3gm20CBtg== - dependencies: - "@babel/code-frame" "^7.14.5" - "@babel/parser" "^7.15.4" - "@babel/types" "^7.15.4" - -"@babel/template@^7.16.7": +"@babel/template@^7.16.7", "@babel/template@^7.3.3": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.16.7.tgz#8d126c8701fde4d66b264b3eba3d96f07666d155" integrity sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w== @@ -1964,22 +1185,7 @@ "@babel/parser" "^7.16.7" "@babel/types" "^7.16.7" -"@babel/traverse@^7.1.0", "@babel/traverse@^7.10.4", "@babel/traverse@^7.15.4", "@babel/traverse@^7.7.0": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.15.4.tgz#ff8510367a144bfbff552d9e18e28f3e2889c22d" - integrity sha512-W6lQD8l4rUbQR/vYgSuCAE75ADyyQvOpFVsvPPdkhf6lATXAsQIG9YdtOcu8BB1dZ0LKu+Zo3c1wEcbKeuhdlA== - dependencies: - "@babel/code-frame" "^7.14.5" - "@babel/generator" "^7.15.4" - "@babel/helper-function-name" "^7.15.4" - "@babel/helper-hoist-variables" "^7.15.4" - "@babel/helper-split-export-declaration" "^7.15.4" - "@babel/parser" "^7.15.4" - "@babel/types" "^7.15.4" - debug "^4.1.0" - globals "^11.1.0" - -"@babel/traverse@^7.13.0", "@babel/traverse@^7.16.7", "@babel/traverse@^7.16.8", "@babel/traverse@^7.17.0": +"@babel/traverse@^7.1.0", "@babel/traverse@^7.13.0", "@babel/traverse@^7.16.7", "@babel/traverse@^7.16.8", "@babel/traverse@^7.17.0", "@babel/traverse@^7.7.0": version "7.17.0" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.17.0.tgz#3143e5066796408ccc880a33ecd3184f3e75cd30" integrity sha512-fpFIXvqD6kC7c7PUNnZ0Z8cQXlarCLtCUpt2S1Dx7PjoRtCFffvOkHHSom+m5HIxMZn5bIBVb71lhabcmjEsqg== @@ -1995,15 +1201,7 @@ debug "^4.1.0" globals "^11.1.0" -"@babel/types@^7.0.0", "@babel/types@^7.10.4", "@babel/types@^7.10.5", "@babel/types@^7.12.1", "@babel/types@^7.12.10", "@babel/types@^7.12.11", "@babel/types@^7.12.12", "@babel/types@^7.15.4", "@babel/types@^7.15.6", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4", "@babel/types@^7.7.0": - version "7.15.6" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.15.6.tgz#99abdc48218b2881c058dd0a7ab05b99c9be758f" - integrity sha512-BPU+7QhqNjmWyDO0/vitH/CuhpV8ZmK1wpKva8nuyNF5MJfuRNWMc+hc14+u9xT93kvykMdncrJT19h74uB1Ig== - dependencies: - "@babel/helper-validator-identifier" "^7.14.9" - to-fast-properties "^2.0.0" - -"@babel/types@^7.16.0", "@babel/types@^7.16.7", "@babel/types@^7.16.8", "@babel/types@^7.17.0": +"@babel/types@^7.0.0", "@babel/types@^7.10.4", "@babel/types@^7.15.6", "@babel/types@^7.16.0", "@babel/types@^7.16.7", "@babel/types@^7.16.8", "@babel/types@^7.17.0", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4", "@babel/types@^7.7.0": version "7.17.0" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.17.0.tgz#a826e368bccb6b3d84acd76acad5c0d87342390b" integrity sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw== @@ -2711,18 +1909,6 @@ lodash "^4.17.15" redent "^3.0.0" -"@testing-library/react-hooks@^5.0.3": - version "5.0.3" - resolved "https://registry.yarnpkg.com/@testing-library/react-hooks/-/react-hooks-5.0.3.tgz#dd0d2048817b013b266d35ca45e3ea48a19fd87e" - integrity sha512-UrnnRc5II7LMH14xsYNm/WRch/67cBafmrSQcyFh0v+UUmSf1uzfB7zn5jQXSettGwOSxJwdQUN7PgkT0w22Lg== - dependencies: - "@babel/runtime" "^7.12.5" - "@types/react" ">=16.9.0" - "@types/react-dom" ">=16.9.0" - "@types/react-test-renderer" ">=16.9.0" - filter-console "^0.1.1" - react-error-boundary "^3.1.0" - "@testing-library/react@^11.2.2": version "11.2.3" resolved "https://registry.yarnpkg.com/@testing-library/react/-/react-11.2.3.tgz#9971ede1c8465a231d7982eeca3c39fc362d5443" @@ -3153,7 +2339,7 @@ dependencies: "@types/react" "*" -"@types/react-dom@>=16.9.0", "@types/react-dom@^17.0.0": +"@types/react-dom@^17.0.0": version "17.0.5" resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-17.0.5.tgz#df44eed5b8d9e0b13bb0cd38e0ea6572a1231227" integrity sha512-ikqukEhH4H9gr4iJCmQVNzTB307kROe3XFfHAOTxOXPOw7lAoEXnM5KWTkzeANGL5Ce6ABfiMl/zJBYNi7ObmQ== @@ -3201,13 +2387,6 @@ "@types/history" "*" "@types/react" "*" -"@types/react-test-renderer@>=16.9.0": - version "17.0.1" - resolved "https://registry.yarnpkg.com/@types/react-test-renderer/-/react-test-renderer-17.0.1.tgz#3120f7d1c157fba9df0118dae20cb0297ee0e06b" - integrity sha512-3Fi2O6Zzq/f3QR9dRnlnHso9bMl7weKCviFmfF6B4LS1Uat6Hkm15k0ZAQuDz+UBq6B3+g+NM6IT2nr5QgPzCw== - dependencies: - "@types/react" "*" - "@types/react-virtualized-auto-sizer@^1.0.0": version "1.0.1" resolved "https://registry.yarnpkg.com/@types/react-virtualized-auto-sizer/-/react-virtualized-auto-sizer-1.0.1.tgz#b3187dae1dfc4c15880c9cfc5b45f2719ea6ebd4" @@ -3230,7 +2409,7 @@ dependencies: "@types/react" "*" -"@types/react@*", "@types/react@>=16.9.0", "@types/react@^17.0.1": +"@types/react@*", "@types/react@^17.0.1": version "17.0.37" resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.37.tgz#6884d0aa402605935c397ae689deed115caad959" integrity sha512-2FS1oTqBGcH/s0E+CjrCCR9+JMpsu9b69RTFO+40ua43ZqP5MmQ4iUde/dMjWR909KxZwmOQIFq6AV6NjEG5xg== @@ -4708,18 +3887,7 @@ browserify-zlib@^0.2.0: dependencies: pako "~1.0.5" -browserslist@^4.0.0, browserslist@^4.12.2, browserslist@^4.14.5, browserslist@^4.16.0, browserslist@^4.16.6: - version "4.17.3" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.17.3.tgz#2844cd6eebe14d12384b0122d217550160d2d624" - integrity sha512-59IqHJV5VGdcJZ+GZ2hU5n4Kv3YiASzW6Xk5g9tf5a/MAzGeFwgGWU39fVzNIOVcgB3+Gp+kiQu0HEfTVU/3VQ== - dependencies: - caniuse-lite "^1.0.30001264" - electron-to-chromium "^1.3.857" - escalade "^3.1.1" - node-releases "^1.1.77" - picocolors "^0.2.1" - -browserslist@^4.17.5, browserslist@^4.19.1: +browserslist@^4.0.0, browserslist@^4.12.2, browserslist@^4.14.5, browserslist@^4.17.5, browserslist@^4.19.1: version "4.19.1" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.19.1.tgz#4ac0435b35ab655896c31d53018b6dd5e9e4c9a3" integrity sha512-u2tbbG5PdKRTUoctO3NBD8FQ5HdPh1ZXPHzp1rwaa5jTc+RV9/+RlWiAIKmjRPQF+xbGM9Kklj5bZQFa2s/38A== @@ -5020,12 +4188,7 @@ caniuse-api@^3.0.0: lodash.memoize "^4.1.2" lodash.uniq "^4.5.0" -caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001166, caniuse-lite@^1.0.30001264: - version "1.0.30001264" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001264.tgz#88f625a60efb6724c7c62ac698bc8dbd9757e55b" - integrity sha512-Ftfqqfcs/ePiUmyaySsQ4PUsdcYyXG2rfoBVsk3iY1ahHaJEw65vfb7Suzqm+cEkwwPIv/XWkg27iCpRavH4zA== - -caniuse-lite@^1.0.30001286: +caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001166, caniuse-lite@^1.0.30001286: version "1.0.30001310" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001310.tgz#da02cd07432c9eece6992689d1b84ca18139eea8" integrity sha512-cb9xTV8k9HTIUA3GnPUJCk0meUnrHL5gy5QePfDjxHyNBcnzPzrHFv5GqfP7ue5b1ZyzZL0RJboD6hQlPXjhjg== @@ -5498,12 +4661,7 @@ commander@^6.1.0, commander@^6.2.0: resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c" integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA== -commander@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-7.0.0.tgz#3e2bbfd8bb6724760980988fb5b22b7ee6b71ab2" - integrity sha512-ovx/7NkTrnPuIV8sqk/GjUIIM1+iUQeqA3ye2VNpq9sVoiZsooObWlQy+OPWGI17GDaEoybuAGJm6U8yC077BA== - -commander@^7.2.0: +commander@^7.0.0, commander@^7.2.0: version "7.2.0" resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== @@ -5691,14 +4849,6 @@ core-js-compat@^3.20.2, core-js-compat@^3.21.0: browserslist "^4.19.1" semver "7.0.0" -core-js-compat@^3.8.0: - version "3.8.2" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.8.2.tgz#3717f51f6c3d2ebba8cbf27619b57160029d1d4c" - integrity sha512-LO8uL9lOIyRRrQmZxHZFl1RV+ZbcsAkFWTktn5SmH40WgLtSNYN4m4W2v9ONT147PxBY/XrRhrWq8TlvObyUjQ== - dependencies: - browserslist "^4.16.0" - semver "7.0.0" - core-js-pure@^3.0.0: version "3.8.2" resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.8.2.tgz#286f885c0dac1cdcd6d78397392abc25ddeca225" @@ -5740,18 +4890,7 @@ cosmiconfig@^6.0.0: path-type "^4.0.0" yaml "^1.7.2" -cosmiconfig@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.0.0.tgz#ef9b44d773959cae63ddecd122de23853b60f8d3" - integrity sha512-pondGvTuVYDk++upghXJabWzL6Kxu6f26ljFw64Swq9v6sQPUL3EUlVDV56diOjpCayKihL6hVe8exIACU4XcA== - dependencies: - "@types/parse-json" "^4.0.0" - import-fresh "^3.2.1" - parse-json "^5.0.0" - path-type "^4.0.0" - yaml "^1.10.0" - -cosmiconfig@^7.0.1: +cosmiconfig@^7.0.0, cosmiconfig@^7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.0.1.tgz#714d756522cace867867ccb4474c5d01bbae5d6d" integrity sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ== @@ -6515,7 +5654,7 @@ domexception@^2.0.1: dependencies: webidl-conversions "^5.0.0" -domhandler@4.0.0, domhandler@^4.0.0: +domhandler@4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.0.0.tgz#01ea7821de996d85f69029e81fa873c21833098e" integrity sha512-KPTbnGQ1JeEMQyO1iYXoagsI6so/C96HZiFyByU3T6iAzpXn8EGEvct6unm1ZGoed8ByO2oirxgwxBmqKF9haA== @@ -6529,7 +5668,7 @@ domhandler@^2.3.0: dependencies: domelementtype "1" -domhandler@^4.2.0, domhandler@^4.3.0: +domhandler@^4.0.0, domhandler@^4.2.0, domhandler@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.3.0.tgz#16c658c626cf966967e306f966b431f77d4a5626" integrity sha512-fC0aXNQXqKSFTr2wDNZDhsEYjCiYsDWl3D01kwt25hm1YIPyDGHvvi3rw+PLqHAl/m71MaiF7d5zvBr0p5UB2g== @@ -6544,16 +5683,7 @@ domutils@^1.5.1, domutils@^1.7.0: dom-serializer "0" domelementtype "1" -domutils@^2.4.4: - version "2.4.4" - resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.4.4.tgz#282739c4b150d022d34699797369aad8d19bbbd3" - integrity sha512-jBC0vOsECI4OMdD0GC9mGn7NXPLb+Qt6KW1YDQzeQYRUFKmNG8lh7mO5HiELfr+lLQE7loDVI4QcAxV80HS+RA== - dependencies: - dom-serializer "^1.0.1" - domelementtype "^2.0.1" - domhandler "^4.0.0" - -domutils@^2.8.0: +domutils@^2.4.4, domutils@^2.8.0: version "2.8.0" resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135" integrity sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A== @@ -6783,11 +5913,6 @@ electron-store@*, electron-store@^8.0.0: conf "^10.0.0" type-fest "^1.0.2" -electron-to-chromium@^1.3.857: - version "1.3.859" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.859.tgz#4e0abc918e1c22b306ba13b4c3649f78295f5937" - integrity sha512-gXRXKNWedfdiKIzwr0Mg/VGCvxXzy+4SuK9hp1BDvfbCwx0O5Ot+2f4CoqQkqEJ3Zj/eAV/GoAFgBVFgkBLXuQ== - electron-to-chromium@^1.4.17: version "1.4.68" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.68.tgz#d79447b6bd1bec9183f166bb33d4bef0d5e4e568" @@ -7711,11 +6836,6 @@ fill-range@^7.0.1: dependencies: to-regex-range "^5.0.1" -filter-console@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/filter-console/-/filter-console-0.1.1.tgz#6242be28982bba7415bcc6db74a79f4a294fa67c" - integrity sha512-zrXoV1Uaz52DqPs+qEwNJWJFAWZpYJ47UNmpN9q4j+/EYsz85uV0DC9k8tRND5kYmoVzL0W+Y75q4Rg8sRJCdg== - finalhandler@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" @@ -9253,14 +8373,7 @@ is-color-stop@^1.0.0: rgb-regex "^1.0.1" rgba-regex "^1.0.0" -is-core-module@^2.2.0, is-core-module@^2.4.0: - version "2.7.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.7.0.tgz#3c0ef7d31b4acfc574f80c58409d568a836848e3" - integrity sha512-ByY+tjCciCr+9nLryBYcSD50EOGWt95c7tIsKTG1J2ixKKXPvF7Ej3AVd+UfDydAJom3biBGDBALaO79ktwgEQ== - dependencies: - has "^1.0.3" - -is-core-module@^2.8.1: +is-core-module@^2.2.0, is-core-module@^2.4.0, is-core-module@^2.8.1: version "2.8.1" resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.8.1.tgz#f59fdfca701d5879d0a6b100a40aa1560ce27211" integrity sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA== @@ -11738,11 +10851,6 @@ node-pre-gyp@^0.11.0: semver "^5.3.0" tar "^4" -node-releases@^1.1.77: - version "1.1.77" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.77.tgz#50b0cfede855dd374e7585bf228ff34e57c1c32e" - integrity sha512-rB1DUFUNAN4Gn9keO2K1efO35IDK7yKHCdCaIMvFO7yUYmmZYeDjnGKle26G4rwj+LKRQpjyUUvMkPglwGCYNQ== - node-releases@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.2.tgz#7139fe71e2f4f11b47d4d2986aaf8c48699e0c01" @@ -12986,13 +12094,13 @@ prompts@^2.0.1: sisteransi "^1.0.5" prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.1, prop-types@^15.7.2: - version "15.7.2" - resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" - integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== + version "15.8.1" + resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" + integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== dependencies: loose-envify "^1.4.0" object-assign "^4.1.1" - react-is "^16.8.1" + react-is "^16.13.1" property-information@^5.0.0, property-information@^5.3.0: version "5.6.0" @@ -13218,13 +12326,6 @@ react-dropzone@^11.2.0: file-selector "^0.2.2" prop-types "^15.7.2" -react-error-boundary@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/react-error-boundary/-/react-error-boundary-3.1.0.tgz#9487443df2f9ba1db90d8ab52351814907ea4af3" - integrity sha512-lmPrdi5SLRJR+AeJkqdkGlW/CRkAUvZnETahK58J4xb5wpbfDngasEGu+w0T1iXEhVrYBJZeW+c4V1hILCnMWQ== - dependencies: - "@babel/runtime" "^7.12.5" - react-fast-compare@^2.0.1: version "2.0.4" resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-2.0.4.tgz#e84b4d455b0fec113e0402c329352715196f81f9" @@ -13288,7 +12389,7 @@ react-input-autosize@^2.2.2: resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== -react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.4: +react-is@^16.13.1, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.4: version "16.13.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== @@ -13316,6 +12417,11 @@ react-lifecycles-compat@^3.0.4: resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362" integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA== +react-merge-refs@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/react-merge-refs/-/react-merge-refs-1.1.0.tgz#73d88b892c6c68cbb7a66e0800faa374f4c38b06" + integrity sha512-alTKsjEL0dKH/ru1Iyn7vliS2QRcBp9zZPGoWxUOvRGWPUYgjo+V01is7p04It6KhgrzhJGnIj9GgX8W4bZoCQ== + react-monaco-editor@*, react-monaco-editor@^0.44.0: version "0.44.0" resolved "https://registry.yarnpkg.com/react-monaco-editor/-/react-monaco-editor-0.44.0.tgz#9f966fd00b6c30e8be8873a3fbc86f14a0da2ba4" @@ -13421,7 +12527,7 @@ react-test-renderer@^17.0.1: react-shallow-renderer "^16.13.1" scheduler "^0.20.1" -react-virtualized-auto-sizer@^1.0.2: +react-virtualized-auto-sizer@^1.0.2, react-virtualized-auto-sizer@^1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/react-virtualized-auto-sizer/-/react-virtualized-auto-sizer-1.0.6.tgz#66c5b1c9278064c5ef1699ed40a29c11518f97ca" integrity sha512-7tQ0BmZqfVF6YYEWcIGuoR3OdYe8I/ZFbNclFlGOC3pMqunkYF/oL30NCjSGl9sMEb17AnzixDz98Kqc3N76HQ== @@ -13438,7 +12544,15 @@ react-virtualized@^9.22.2: prop-types "^15.7.2" react-lifecycles-compat "^3.0.4" -react-window@^1.8.5: +react-vtree@^3.0.0-beta.3: + version "3.0.0-beta.3" + resolved "https://registry.yarnpkg.com/react-vtree/-/react-vtree-3.0.0-beta.3.tgz#9a2dfc31fa730c39d19b0dff7a9df81ead816bd5" + integrity sha512-BGC8kOT2Ti3rne0Nwu+n90TAo8lbYiWT36Cu47aj6bz+Bs7k5p3EVgBTinyuCdU5+n4a9wJOXHAdop/zsR1RAA== + dependencies: + "@babel/runtime" "^7.11.0" + react-merge-refs "^1.1.0" + +react-window@^1.8.5, react-window@^1.8.6: version "1.8.6" resolved "https://registry.yarnpkg.com/react-window/-/react-window-1.8.6.tgz#d011950ac643a994118632665aad0c6382e2a112" integrity sha512-8VwEEYyjz6DCnGBsd+MgkD0KJ2/OXFULyDtorIiTz+QzwoP94tBoA7CnbtyXMm+cCeAUER5KJcPtWl9cpKbOBg== @@ -13642,14 +12756,7 @@ regenerate-unicode-properties@^10.0.1: dependencies: regenerate "^1.4.2" -regenerate-unicode-properties@^8.2.0: - version "8.2.0" - resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz#e5de7111d655e7ba60c057dbe9ff37c87e65cdec" - integrity sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA== - dependencies: - regenerate "^1.4.0" - -regenerate@^1.4.0, regenerate@^1.4.2: +regenerate@^1.4.2: version "1.4.2" resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== @@ -13687,18 +12794,6 @@ regexpp@^3.1.0: resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.1.0.tgz#206d0ad0a5648cffbdb8ae46438f3dc51c9f78e2" integrity sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q== -regexpu-core@^4.7.1: - version "4.7.1" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.7.1.tgz#2dea5a9a07233298fbf0db91fa9abc4c6e0f8ad6" - integrity sha512-ywH2VUraA44DZQuRKzARmw6S66mr48pQVva4LBeRhcOltJ6hExvWly5ZjFLYo67xbIxb6W1q4bAGtgfEl20zfQ== - dependencies: - regenerate "^1.4.0" - regenerate-unicode-properties "^8.2.0" - regjsgen "^0.5.1" - regjsparser "^0.6.4" - unicode-match-property-ecmascript "^1.0.4" - unicode-match-property-value-ecmascript "^1.2.0" - regexpu-core@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-5.0.1.tgz#c531122a7840de743dcf9c83e923b5560323ced3" @@ -13725,23 +12820,11 @@ registry-url@^5.0.0: dependencies: rc "^1.2.8" -regjsgen@^0.5.1: - version "0.5.2" - resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.5.2.tgz#92ff295fb1deecbf6ecdab2543d207e91aa33733" - integrity sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A== - regjsgen@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.6.0.tgz#83414c5354afd7d6627b16af5f10f41c4e71808d" integrity sha512-ozE883Uigtqj3bx7OhL1KNbCzGyW2NQZPl6Hs09WTvCuZD5sTI4JY58bkbQWa/Y9hxIsvJ3M8Nbf7j54IqeZbA== -regjsparser@^0.6.4: - version "0.6.6" - resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.6.6.tgz#6d8c939d1a654f78859b08ddcc4aa777f3fa800a" - integrity sha512-jjyuCp+IEMIm3N1H1LLTJW1EISEJV9+5oHdEyrt43Pg9cDSb6rrLZei2cVWpl0xTjmmlpec/lEQGYgM7xfpGCQ== - dependencies: - jsesc "~0.5.0" - regjsparser@^0.8.2: version "0.8.4" resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.8.4.tgz#8a14285ffcc5de78c5b95d62bbf413b6bc132d5f" @@ -13980,15 +13063,7 @@ resolve-url@^0.2.1: resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= -resolve@^1.1.6, resolve@^1.10.0, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.18.1, resolve@^1.20.0, resolve@^1.9.0: - version "1.20.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" - integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== - dependencies: - is-core-module "^2.2.0" - path-parse "^1.0.6" - -resolve@^1.14.2: +resolve@^1.1.6, resolve@^1.10.0, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.14.2, resolve@^1.18.1, resolve@^1.20.0, resolve@^1.9.0: version "1.22.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.0.tgz#5e0b8c67c15df57a89bdbabe603a002f21731198" integrity sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw== @@ -15750,24 +14825,11 @@ unherit@^1.0.4: inherits "^2.0.0" xtend "^4.0.0" -unicode-canonical-property-names-ecmascript@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz#2619800c4c825800efdd8343af7dd9933cbe2818" - integrity sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ== - unicode-canonical-property-names-ecmascript@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz#301acdc525631670d39f6146e0e77ff6bbdebddc" integrity sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ== -unicode-match-property-ecmascript@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz#8ed2a32569961bce9227d09cd3ffbb8fed5f020c" - integrity sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg== - dependencies: - unicode-canonical-property-names-ecmascript "^1.0.4" - unicode-property-aliases-ecmascript "^1.0.4" - unicode-match-property-ecmascript@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz#54fd16e0ecb167cf04cf1f756bdcc92eba7976c3" @@ -15776,21 +14838,11 @@ unicode-match-property-ecmascript@^2.0.0: unicode-canonical-property-names-ecmascript "^2.0.0" unicode-property-aliases-ecmascript "^2.0.0" -unicode-match-property-value-ecmascript@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz#0d91f600eeeb3096aa962b1d6fc88876e64ea531" - integrity sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ== - unicode-match-property-value-ecmascript@^2.0.0: version "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-property-aliases-ecmascript@^1.0.4: - version "1.1.0" - resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz#dd57a99f6207bedff4628abefb94c50db941c8f4" - integrity sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg== - unicode-property-aliases-ecmascript@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.0.0.tgz#0a36cb9a585c4f6abd51ad1deddb285c165297c8"