From 6754620d7abfb7273cff5f173349eb507fc0c8b7 Mon Sep 17 00:00:00 2001 From: Haishan Date: Fri, 8 Nov 2019 00:40:48 +0800 Subject: [PATCH] feat: connections inspection --- package.json | 5 +- src/api/connections.js | 51 ++++++ src/components/ConnectionTable.js | 99 ++++++++++++ src/components/ConnectionTable.module.css | 38 +++++ src/components/Connections.js | 55 +++++++ src/components/Root.css | 5 + src/components/Root.js | 2 + src/components/SideBar.js | 25 +-- src/components/SvgActivity.js | 24 --- src/components/SvgCommand.js | 25 --- src/components/SvgFile.js | 25 --- src/components/SvgGlobe.js | 25 --- src/components/SvgSettings.js | 25 --- yarn.lock | 186 +++++++++++++++------- 14 files changed, 393 insertions(+), 197 deletions(-) create mode 100644 src/api/connections.js create mode 100644 src/components/ConnectionTable.js create mode 100644 src/components/ConnectionTable.module.css create mode 100644 src/components/Connections.js delete mode 100644 src/components/SvgActivity.js delete mode 100644 src/components/SvgCommand.js delete mode 100644 src/components/SvgFile.js delete mode 100644 src/components/SvgGlobe.js delete mode 100644 src/components/SvgSettings.js diff --git a/package.json b/package.json index e0a8bb4..bb8d4b6 100644 --- a/package.json +++ b/package.json @@ -34,12 +34,13 @@ "license": "MIT", "dependencies": { "@babel/runtime": "^7.7.1", - "@hot-loader/react-dom": "^16.9.0", + "@hot-loader/react-dom": "16.10.2", "@hsjs/react-cache": "0.0.0-alpha.aa94237", "@sentry/browser": "^5.7.1", "chart.js": "^2.9.2", "classnames": "^2.2.6", "core-js": "^3.3.6", + "date-fns": "^2.7.0", "history": "^4.7.2", "invariant": "^2.2.4", "lodash-es": "^4.17.14", @@ -48,8 +49,10 @@ "prop-types": "^15.5.10", "react": "^0.0.0-experimental-f6b8d31a7", "react-dom": "^0.0.0-experimental-f6b8d31a7", + "react-feather": "^2.0.3", "react-modal": "^3.11.1", "react-router-dom": "^5.1.2", + "react-table": "^7.0.0-beta.12", "react-window": "^1.8.5", "redux": "^4.0.4", "redux-logger": "^3.0.6", diff --git a/src/api/connections.js b/src/api/connections.js new file mode 100644 index 0000000..594fc5e --- /dev/null +++ b/src/api/connections.js @@ -0,0 +1,51 @@ +const endpoint = '/connections'; + +let fetched = false; +let subscribers = []; + +function appendData(s) { + let o; + try { + o = JSON.parse(s); + } catch (err) { + // eslint-disable-next-line no-console + console.log('JSON.parse error', JSON.parse(s)); + } + subscribers.forEach(f => f(o)); +} + +function getWsUrl(apiConfig) { + const { hostname, port, secret } = apiConfig; + let qs = ''; + if (typeof secret === 'string' && secret !== '') { + qs += '?token=' + secret; + } + return `ws://${hostname}:${port}${endpoint}${qs}`; +} + +let wsState; +function fetchData(apiConfig, listener) { + if (fetched || wsState === 1) { + if (listener) return subscribe(listener); + } + wsState = 1; + const url = getWsUrl(apiConfig); + const ws = new WebSocket(url); + ws.addEventListener('error', function(_ev) { + wsState = 3; + }); + ws.addEventListener('message', function(event) { + appendData(event.data); + }); + if (listener) return subscribe(listener); +} + +function subscribe(listener) { + subscribers.push(listener); + return function unsubscribe() { + const idx = subscribers.indexOf(listener); + subscribers.splice(idx, 1); + }; +} + +export { fetchData }; diff --git a/src/components/ConnectionTable.js b/src/components/ConnectionTable.js new file mode 100644 index 0000000..547925c --- /dev/null +++ b/src/components/ConnectionTable.js @@ -0,0 +1,99 @@ +import React from 'react'; +import { ArrowUp, ArrowDown } from 'react-feather'; +import prettyBytes from '../misc/pretty-bytes'; +import { formatDistance } from 'date-fns'; +import cx from 'classnames'; +import { useTable, useSortBy } from 'react-table'; + +import s from './ConnectionTable.module.css'; + +const columns = [ + { Header: 'Host', accessor: 'host' }, + { Header: 'Download', accessor: 'download' }, + { Header: 'Upload', accessor: 'upload' }, + { Header: 'Network', accessor: 'network' }, + { Header: 'Type', accessor: 'type' }, + { Header: 'Chains', accessor: 'chains' }, + { Header: 'Rule', accessor: 'rule' }, + { Header: 'Time', accessor: 'start' }, + { Header: 'Source IP', accessor: 'sourceIP' }, + { Header: 'Source Port', accessor: 'sourcePort' }, + { Header: 'Designation IP', accessor: 'destinationIP' }, + { Header: 'Designation Port', accessor: 'destinationPort' } +]; + +function renderCell(cell, now) { + switch (cell.column.id) { + case 'start': + return formatDistance(-cell.value, now); + case 'download': + case 'upload': + return prettyBytes(cell.value); + default: + return cell.value; + } +} + +function Table({ data }) { + const now = new Date(); + const { + getTableProps, + // getTableBodyProps, + headerGroups, + rows, + prepareRow + } = useTable( + { + columns, + data + }, + useSortBy + ); + return ( +
+
+ {headerGroups.map(headerGroup => ( +
+ {headerGroup.headers.map(column => ( +
+ {column.render('Header')} + + {column.isSorted ? ( + column.isSortedDesc ? ( + + ) : ( + + ) + ) : null} + +
+ ))} + + {rows.map((row, i) => { + prepareRow(row); + return row.cells.map((cell, j) => { + return ( +
+ {renderCell(cell, now)} +
+ ); + }); + })} +
+ ))} +
+
+ ); +} + +export default Table; diff --git a/src/components/ConnectionTable.module.css b/src/components/ConnectionTable.module.css new file mode 100644 index 0000000..f145542 --- /dev/null +++ b/src/components/ConnectionTable.module.css @@ -0,0 +1,38 @@ +.thead .tr { + display: grid; + grid-template-columns: repeat(12, max-content); +} + +.th { + padding: 8px 0 14px 10px; + height: 50px; + background: var(--color-background); + position: sticky; + top: 0; + + display: flex; + align-items: center; + justify-content: space-between; +} + +.th span:last-child { + margin-left: 10px; + width: 16px; + height: 16px; +} + +.td { + padding: 8px 10px; + font-size: 0.9em; + + font-family: var(--font-normal); +} + +.td.odd { + background: var(--color-row-odd); +} + +/* download upload td cells */ +.du { + text-align: right; +} diff --git a/src/components/Connections.js b/src/components/Connections.js new file mode 100644 index 0000000..66ce2ef --- /dev/null +++ b/src/components/Connections.js @@ -0,0 +1,55 @@ +import React from 'react'; +import ContentHeader from 'c/ContentHeader'; +import ConnectionTable from 'c/ConnectionTable'; +import useRemainingViewPortHeight from '../hooks/useRemainingViewPortHeight'; +import { useStoreState } from 'm/store'; +import { getClashAPIConfig } from 'd/app'; +import * as connAPI from '../api/connections'; + +const { useEffect, useState } = React; + +const paddingBottom = 30; + +function formatConnectionDataItem(i) { + const { id, metadata, upload, download, start, chains, rule } = i; + // const started = formatDistance(new Date(start), now); + return { + id, + upload, + download, + start: 0 - new Date(start), + chains: chains.reverse().join(' / '), + rule, + ...metadata + }; +} + +function Conn() { + const [refContainer, containerHeight] = useRemainingViewPortHeight(); + const config = useStoreState(getClashAPIConfig); + const [conns, setConns] = useState([]); + useEffect(() => { + function read({ connections }) { + const x = connections.map(c => formatConnectionDataItem(c)); + setConns(x); + } + return connAPI.fetchData(config, read); + }, [config]); + return ( +
+ +
+
+ +
+
+
+ ); +} + +export default Conn; diff --git a/src/components/Root.css b/src/components/Root.css index c08c538..88b3d6c 100644 --- a/src/components/Root.css +++ b/src/components/Root.css @@ -61,6 +61,9 @@ :root { --font-mono: 'Roboto Mono', Menlo, monospace; + --font-normal: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica, + Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol, + 'PingFang SC', 'Microsoft YaHei', '微软雅黑', Arial, sans-serif; --color-focus-blue: #1a73e8; } @@ -88,6 +91,7 @@ body.dark { --color-btn-bg: #232323; --color-btn-fg: #bebebe; --color-bg-proxy-selected: #303030; + --color-row-odd: #282828; } body.light { @@ -104,4 +108,5 @@ body.light { --color-btn-bg: #f4f4f4; --color-btn-fg: #101010; --color-bg-proxy-selected: #cfcfcf; + --color-row-odd: #f5f5f5; } diff --git a/src/components/Root.js b/src/components/Root.js index e7f0e60..56c0be0 100644 --- a/src/components/Root.js +++ b/src/components/Root.js @@ -8,6 +8,7 @@ import SideBar from 'c/SideBar'; import Home from 'c/Home'; import Logs from 'c/Logs'; import Config from 'c/Config'; +import Connections from 'c/Connections'; import APIDiscovery from 'c/APIDiscovery'; import { store } from '../store/configureStore'; import './Root.css'; @@ -45,6 +46,7 @@ const Root = () => (
}> } /> + } /> diff --git a/src/components/SideBar.js b/src/components/SideBar.js index c78d6a9..09b517e 100644 --- a/src/components/SideBar.js +++ b/src/components/SideBar.js @@ -2,6 +2,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import cx from 'classnames'; import { Link } from 'react-router-dom'; +import { Command, Activity, Globe, Link2, Settings, File } from 'react-feather'; import { useActions } from 'm/store'; import { switchTheme } from 'd/app'; @@ -11,20 +12,16 @@ import Icon from 'c/Icon'; import moon from 's/moon.svg'; import SvgYacd from './SvgYacd'; -import SvgActivity from './SvgActivity'; -import SvgGlobe from './SvgGlobe'; -import SvgCommand from './SvgCommand'; -import SvgSettings from './SvgSettings'; -import SvgFile from './SvgFile'; import s from 'c/SideBar.module.css'; const icons = { - activity: SvgActivity, - globe: SvgGlobe, - command: SvgCommand, - file: SvgFile, - settings: SvgSettings + activity: Activity, + globe: Globe, + command: Command, + file: File, + settings: Settings, + link: Link2 }; const SideBarRow = React.memo(function SideBarRow({ @@ -38,7 +35,7 @@ const SideBarRow = React.memo(function SideBarRow({ const className = cx(s.row, isActive ? s.rowActive : null); return ( - +
{labelText}
); @@ -89,6 +86,12 @@ function SideBar({ location }) { iconId="command" labelText="Rules" /> + - - - - - ); -} - -export default SvgActivity; diff --git a/src/components/SvgCommand.js b/src/components/SvgCommand.js deleted file mode 100644 index 58fb607..0000000 --- a/src/components/SvgCommand.js +++ /dev/null @@ -1,25 +0,0 @@ -import React from 'react'; - -export default function SvgCommand() { - return ( - - - - - - ); -} diff --git a/src/components/SvgFile.js b/src/components/SvgFile.js deleted file mode 100644 index 503f7b3..0000000 --- a/src/components/SvgFile.js +++ /dev/null @@ -1,25 +0,0 @@ -import React from 'react'; - -export default function SvgFile() { - return ( - - - - - - - - - ); -} diff --git a/src/components/SvgGlobe.js b/src/components/SvgGlobe.js deleted file mode 100644 index d7c66da..0000000 --- a/src/components/SvgGlobe.js +++ /dev/null @@ -1,25 +0,0 @@ -import React from 'react'; - -export default function SvgGlobe() { - return ( - - - - - - - - - ); -} diff --git a/src/components/SvgSettings.js b/src/components/SvgSettings.js deleted file mode 100644 index 1d7af11..0000000 --- a/src/components/SvgSettings.js +++ /dev/null @@ -1,25 +0,0 @@ -import React from 'react'; - -export default function SvgSettings() { - return ( - - - - - - - - - ); -} diff --git a/yarn.lock b/yarn.lock index a2a5ed0..c9fcf4d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10,18 +10,18 @@ "@babel/highlight" "^7.0.0" "@babel/core@^7.7.0": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.7.0.tgz#461d2948b1a7113088baf999499bcbd39a7faa3b" - integrity sha512-Bb1NjZCaiwTQC/ARL+MwDpgocdnwWDCaugvkGt6cxfBzQa8Whv1JybBoUEiBDKl8Ni3H3c7Fykwk7QChUsHRlg== + version "7.7.2" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.7.2.tgz#ea5b99693bcfc058116f42fa1dd54da412b29d91" + integrity sha512-eeD7VEZKfhK1KUXGiyPFettgF3m513f8FoBSWiQ1xTvl1RAopLs42Wp9+Ze911I6H0N9lNqJMDgoZT7gHsipeQ== dependencies: "@babel/code-frame" "^7.5.5" - "@babel/generator" "^7.7.0" + "@babel/generator" "^7.7.2" "@babel/helpers" "^7.7.0" - "@babel/parser" "^7.7.0" + "@babel/parser" "^7.7.2" "@babel/template" "^7.7.0" - "@babel/traverse" "^7.7.0" - "@babel/types" "^7.7.0" - convert-source-map "^1.1.0" + "@babel/traverse" "^7.7.2" + "@babel/types" "^7.7.2" + convert-source-map "^1.7.0" debug "^4.1.0" json5 "^2.1.0" lodash "^4.17.13" @@ -29,12 +29,12 @@ semver "^5.4.1" source-map "^0.5.0" -"@babel/generator@^7.7.0": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.7.0.tgz#c6d4d1f7a0d6e139cbd01aca73170b0bff5425b4" - integrity sha512-1wdJ6UxHyL1XoJQ119JmvuRX27LRih7iYStMPZOWAjQqeAabFg3dYXKMpgihma+to+0ADsTVVt6oRyUxWZw6Mw== +"@babel/generator@^7.7.0", "@babel/generator@^7.7.2": + version "7.7.2" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.7.2.tgz#2f4852d04131a5e17ea4f6645488b5da66ebf3af" + integrity sha512-WthSArvAjYLz4TcbKOi88me+KmDJdKSlfwwN8CnUYn9jBkzhq0ZEPuBfkAWIvjJ3AdEV1Cf/+eSQTnp3IDJKlQ== dependencies: - "@babel/types" "^7.7.0" + "@babel/types" "^7.7.2" jsesc "^2.5.1" lodash "^4.17.13" source-map "^0.5.0" @@ -240,11 +240,16 @@ esutils "^2.0.2" js-tokens "^4.0.0" -"@babel/parser@^7.0.0", "@babel/parser@^7.7.0": +"@babel/parser@^7.0.0": version "7.7.0" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.7.0.tgz#232618f6e8947bc54b407fa1f1c91a22758e7159" integrity sha512-GqL+Z0d7B7ADlQBMXlJgvXEbtt5qlqd1YQ5fr12hTSfh7O/vgrEIvJxU2e7aSVrEUn75zTZ6Nd0s8tthrlZnrQ== +"@babel/parser@^7.7.0", "@babel/parser@^7.7.2": + version "7.7.2" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.7.2.tgz#ea8334dc77416bfd9473eb470fd00d8245b3943b" + integrity sha512-DDaR5e0g4ZTb9aP7cpSZLkACEBdoLGwJDWgHtBhrGX7Q1RjhdoMOfexICj5cqTAtpowjGQWfcvfnQG7G2kAB5w== + "@babel/plugin-proposal-async-generator-functions@^7.7.0": version "7.7.0" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.7.0.tgz#83ef2d6044496b4c15d8b4904e2219e6dccc6971" @@ -720,13 +725,20 @@ "@babel/plugin-transform-react-jsx-self" "^7.0.0" "@babel/plugin-transform-react-jsx-source" "^7.0.0" -"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.4.0", "@babel/runtime@^7.4.5", "@babel/runtime@^7.7.1": +"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.4.0", "@babel/runtime@^7.4.5": version "7.7.1" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.7.1.tgz#b223497bbfbcbbb38116673904debc71470ca528" integrity sha512-SQ0sS7KUJDvgCI2cpZG0nJygO6002oTbhgSuw4WcocsnbxLwL5Q8I3fqbJdyBAc3uFrWZiR2JomseuxSuci3SQ== dependencies: regenerator-runtime "^0.13.2" +"@babel/runtime@^7.7.1": + version "7.7.2" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.7.2.tgz#111a78002a5c25fc8e3361bedc9529c696b85a6a" + integrity sha512-JONRbXbTXc9WQE2mAZd1p0Z3DZ/6vaQIkgYMSTP3KjRCyd7rCZCcfhCyX+YjwcKxcZ82UrxbRD358bpExNgrjw== + dependencies: + regenerator-runtime "^0.13.2" + "@babel/template@^7.7.0": version "7.7.0" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.7.0.tgz#4fadc1b8e734d97f56de39c77de76f2562e597d0" @@ -736,7 +748,7 @@ "@babel/parser" "^7.7.0" "@babel/types" "^7.7.0" -"@babel/traverse@^7.0.0", "@babel/traverse@^7.7.0": +"@babel/traverse@^7.0.0": version "7.7.0" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.7.0.tgz#9f5744346b8d10097fd2ec2eeffcaf19813cbfaf" integrity sha512-ea/3wRZc//e/uwCpuBX2itrhI0U9l7+FsrKWyKGNyvWbuMcCG7ATKY2VI4wlg2b2TA39HHwIxnvmXvtiKsyn7w== @@ -751,7 +763,22 @@ globals "^11.1.0" lodash "^4.17.13" -"@babel/types@^7.0.0", "@babel/types@^7.7.0", "@babel/types@^7.7.1": +"@babel/traverse@^7.7.0", "@babel/traverse@^7.7.2": + version "7.7.2" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.7.2.tgz#ef0a65e07a2f3c550967366b3d9b62a2dcbeae09" + integrity sha512-TM01cXib2+rgIZrGJOLaHV/iZUAxf4A0dt5auY6KNZ+cm6aschuJGqKJM3ROTt3raPUdIDk9siAufIFEleRwtw== + dependencies: + "@babel/code-frame" "^7.5.5" + "@babel/generator" "^7.7.2" + "@babel/helper-function-name" "^7.7.0" + "@babel/helper-split-export-declaration" "^7.7.0" + "@babel/parser" "^7.7.2" + "@babel/types" "^7.7.2" + debug "^4.1.0" + globals "^11.1.0" + lodash "^4.17.13" + +"@babel/types@^7.0.0", "@babel/types@^7.7.1": version "7.7.1" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.7.1.tgz#8b08ea368f2baff236613512cf67109e76285827" integrity sha512-kN/XdANDab9x1z5gcjDc9ePpxexkt+1EQ2MQUiM4XnMvQfvp87/+6kY4Ko2maLXH+tei/DgJ/ybFITeqqRwDiA== @@ -760,7 +787,16 @@ lodash "^4.17.13" to-fast-properties "^2.0.0" -"@hot-loader/react-dom@^16.9.0": +"@babel/types@^7.7.0", "@babel/types@^7.7.2": + version "7.7.2" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.7.2.tgz#550b82e5571dcd174af576e23f0adba7ffc683f7" + integrity sha512-YTf6PXoh3+eZgRCBzzP25Bugd2ngmpQVrk7kXX0i5N9BO7TFBtIgZYs7WtxtOGs8e6A4ZI7ECkbBCEHeXocvOA== + dependencies: + esutils "^2.0.2" + lodash "^4.17.13" + to-fast-properties "^2.0.0" + +"@hot-loader/react-dom@16.10.2": version "16.10.2" resolved "https://registry.yarnpkg.com/@hot-loader/react-dom/-/react-dom-16.10.2.tgz#91920442252acac6f343eef5df41aca333f7dcea" integrity sha512-vbrSDuZMoE1TXiDNAVCSAcIS6UX55Fa9KF0MD0wQgOaOIPZs/C6CtEDUcnNFEwTQ5ciIULcp+96lQlSuANNagA== @@ -894,11 +930,24 @@ resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e" integrity sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA== +"@types/prop-types@*": + version "15.7.3" + resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.3.tgz#2ab0d5da2e5815f94b0b9d4b95d1e5f243ab2ca7" + integrity sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw== + "@types/q@^1.5.1": version "1.5.2" resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.2.tgz#690a1475b84f2a884fd07cd797c00f5f31356ea8" integrity sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw== +"@types/react@^15.0.0 || ^16.0.0": + version "16.9.11" + resolved "https://registry.yarnpkg.com/@types/react/-/react-16.9.11.tgz#70e0b7ad79058a7842f25ccf2999807076ada120" + integrity sha512-UBT4GZ3PokTXSWmdgC/GeCGEJXE5ofWyibCcecRLUVN2ZBpXQGVgQGtG2foS7CrTKFKlQVVswLvf7Js6XA/CVQ== + dependencies: + "@types/prop-types" "*" + csstype "^2.2.0" + "@types/source-list-map@*": version "0.1.2" resolved "https://registry.yarnpkg.com/@types/source-list-map/-/source-list-map-0.1.2.tgz#0078836063ffaf17412349bba364087e0ac02ec9" @@ -1633,27 +1682,7 @@ bytes@3.1.0: resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg== -cacache@^11.3.3: - version "11.3.3" - resolved "https://registry.yarnpkg.com/cacache/-/cacache-11.3.3.tgz#8bd29df8c6a718a6ebd2d010da4d7972ae3bbadc" - integrity sha512-p8WcneCytvzPxhDvYp31PD039vi77I12W+/KfR9S8AZbaiARFBCpsPJS+9uhWfeBfeAtW7o/4vt3MUqLkbY6nA== - dependencies: - bluebird "^3.5.5" - chownr "^1.1.1" - figgy-pudding "^3.5.1" - glob "^7.1.4" - graceful-fs "^4.1.15" - lru-cache "^5.1.1" - mississippi "^3.0.0" - mkdirp "^0.5.1" - move-concurrently "^1.0.1" - promise-inflight "^1.0.1" - rimraf "^2.6.3" - ssri "^6.0.1" - unique-filename "^1.1.1" - y18n "^4.0.0" - -cacache@^12.0.2: +cacache@^12.0.2, cacache@^12.0.3: version "12.0.3" resolved "https://registry.yarnpkg.com/cacache/-/cacache-12.0.3.tgz#be99abba4e1bf5df461cd5a2c1071fc432573390" integrity sha512-kqdmfXEGFepesTuROHMs3MpFLWrPkSSpRqOw80RCflZXy/khxaArvFrQ7uJxSUduzAufc6G0g1VUCOZXxWavPw== @@ -2070,7 +2099,7 @@ content-type@~1.0.4: resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== -convert-source-map@^1.1.0: +convert-source-map@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442" integrity sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA== @@ -2105,11 +2134,11 @@ copy-descriptor@^0.1.0: integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= copy-webpack-plugin@^5.0.4: - version "5.0.4" - resolved "https://registry.yarnpkg.com/copy-webpack-plugin/-/copy-webpack-plugin-5.0.4.tgz#c78126f604e24f194c6ec2f43a64e232b5d43655" - integrity sha512-YBuYGpSzoCHSSDGyHy6VJ7SHojKp6WHT4D7ItcQFNAYx2hrwkMe56e97xfVR0/ovDuMTrMffXUiltvQljtAGeg== + version "5.0.5" + resolved "https://registry.yarnpkg.com/copy-webpack-plugin/-/copy-webpack-plugin-5.0.5.tgz#731df6a837a2ef0f8f8e2345bdfe9b7c62a2da68" + integrity sha512-7N68eIoQTyudAuxkfPT7HzGoQ+TsmArN/I3HFwG+lVE3FNzqvZKIiaxtYh4o3BIznioxUvx9j26+Rtsc9htQUQ== dependencies: - cacache "^11.3.3" + cacache "^12.0.3" find-cache-dir "^2.1.0" glob-parent "^3.1.0" globby "^7.1.1" @@ -2117,9 +2146,9 @@ copy-webpack-plugin@^5.0.4: loader-utils "^1.2.3" minimatch "^3.0.4" normalize-path "^3.0.0" - p-limit "^2.2.0" + p-limit "^2.2.1" schema-utils "^1.0.0" - serialize-javascript "^1.7.0" + serialize-javascript "^2.1.0" webpack-log "^2.0.0" core-js-compat@^3.1.1: @@ -2131,9 +2160,9 @@ core-js-compat@^3.1.1: semver "^6.3.0" core-js@^3.3.6: - version "3.3.6" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.3.6.tgz#6ad1650323c441f45379e176ed175c0d021eac92" - integrity sha512-u4oM8SHwmDuh5mWZdDg9UwNVq5s1uqq6ZDLLIs07VY+VJU91i3h4f3K/pgFvtUQPGdeStrZ+odKyfyt4EnKHfA== + version "3.4.0" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.4.0.tgz#29ea478601789c72f2978e9bb98f43546f89d3aa" + integrity sha512-lQxb4HScV71YugF/X28LtePZj9AB7WqOpcB+YztYxusvhrgZiQXPmCYfPC5LHsw/+ScEtDbXU3xbqH3CjBRmYA== core-util-is@~1.0.0: version "1.0.2" @@ -2377,6 +2406,11 @@ csso@^4.0.2: dependencies: css-tree "1.0.0-alpha.37" +csstype@^2.2.0: + version "2.6.7" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.7.tgz#20b0024c20b6718f4eda3853a1f5a1cce7f5e4a5" + integrity sha512-9Mcn9sFbGBAdmimWb2gLVDtFJzeKtDGIr76TUqmjZrw9LFXBMSU70lcs+C0/7fyCd6iBDqmksUcCOUIkisPHsQ== + cyclist@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9" @@ -2392,6 +2426,11 @@ date-fns@^1.27.2: resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.30.1.tgz#2e71bf0b119153dbb4cc4e88d9ea5acfb50dc05c" integrity sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw== +date-fns@^2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.7.0.tgz#8271d943cc4636a1f27698f1b8d6a9f1ceb74026" + integrity sha512-wxYp2PGoUDN5ZEACc61aOtYFvSsJUylIvCjpjDOqM1UDaKIIuMJ9fAnMYFHV3TQaDpfTVxhwNK/GiCaHKuemTA== + debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" @@ -2877,9 +2916,9 @@ eslint-plugin-import@^2.18.0: resolve "^1.11.0" eslint-plugin-jest@^23.0.2: - version "23.0.2" - resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-23.0.2.tgz#54a59bfe77245186afe13711a297067aefefff0a" - integrity sha512-fkxcvOJm0hC/jbJqYJjtuC9mvpTJqXd0Nixx7joVQvJoBQuXk/ws3+MtRYzD/4TcKSgvr21uuSLdwSxKJKC2cg== + version "23.0.3" + resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-23.0.3.tgz#d3f157f7791f97713372c13259ba1dfc436eb4c1" + integrity sha512-9cNxr66zeOyz1S9AkQL4/ouilR6QHpYj8vKOQZ60fu9hAt5PJWS4KqWqfr1aqN5NFEZSPjFOla2Azn+KTWiGwg== dependencies: "@typescript-eslint/experimental-utils" "^2.5.0" @@ -3499,7 +3538,7 @@ glob-parent@^5.0.0, glob-parent@^5.1.0: dependencies: is-glob "^4.0.1" -glob@^7.0.3, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4: +glob@^7.0.3: version "7.1.5" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.5.tgz#6714c69bee20f3c3e64c4dd905553e532b40cdc0" integrity sha512-J9dlskqUXK1OeTOYBEn5s8aMukWMwWfs+rPTn/jn50Ux4MNXVhubL1wu/j2t+H4NVI+cXEcCaYellqaPVGXNqQ== @@ -3511,6 +3550,18 @@ glob@^7.0.3, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4: once "^1.3.0" path-is-absolute "^1.0.0" +glob@^7.1.2, glob@^7.1.3, glob@^7.1.4: + version "7.1.6" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" + integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + global-modules@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-2.0.0.tgz#997605ad2345f27f51539bea26574421215c7780" @@ -5431,7 +5482,7 @@ p-limit@^1.1.0: dependencies: p-try "^1.0.0" -p-limit@^2.0.0, p-limit@^2.2.0: +p-limit@^2.0.0, p-limit@^2.2.0, p-limit@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.1.tgz#aa07a788cc3151c939b5131f63570f0dd2009537" integrity sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg== @@ -5903,9 +5954,9 @@ postcss-modules-values@^3.0.0: postcss "^7.0.6" postcss-nested@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/postcss-nested/-/postcss-nested-4.2.0.tgz#e6e6777b05dddd47358c676d983bd7251d0e67a2" - integrity sha512-qRAOC0uJ4TbFXlURB+3Y5sCi9+MLTkXmt7VGpqHw5oAWCnHqeFa4MGf7kb5ceFDthknumJc+E4A0TjV4XEVWBQ== + version "4.2.1" + resolved "https://registry.yarnpkg.com/postcss-nested/-/postcss-nested-4.2.1.tgz#4bc2e5b35e3b1e481ff81e23b700da7f82a8b248" + integrity sha512-AMayXX8tS0HCp4O4lolp4ygj9wBn32DJWXvG6gCv+ZvJrEa00GUxJcJEEzMh87BIe6FrWdYkpR2cuyqHKrxmXw== dependencies: postcss "^7.0.21" postcss-selector-parser "^6.0.2" @@ -6352,11 +6403,19 @@ react-dom@^0.0.0-experimental-f6b8d31a7: prop-types "^15.6.2" scheduler "0.0.0-experimental-f6b8d31a7" -react-hot-loader@^4.12.14: - version "4.12.15" - resolved "https://registry.yarnpkg.com/react-hot-loader/-/react-hot-loader-4.12.15.tgz#6bf3984e52edbdf02ea8952777f53da1b3c68c95" - integrity sha512-sgkN6g+tgPE6xZzD0Ysqll7KUFYJbMX0DrczT5OxD6S7hZlSnmqSC3ceudwCkiDd65ZTtm+Ayk4Y9k5xxCvpOw== +react-feather@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/react-feather/-/react-feather-2.0.3.tgz#1453ff5d8c242f72b8c02846118fbd2d406375ad" + integrity sha512-XVjtxIyMxb2RFlqC2APoB/IZvXKDW9uLN1c264XEeZNYe8jIxjQVQpeTo3nxtHiLTgMfgf0ZYxJC6HwmY8+9BA== dependencies: + prop-types "^15.7.2" + +react-hot-loader@^4.12.14: + version "4.12.16" + resolved "https://registry.yarnpkg.com/react-hot-loader/-/react-hot-loader-4.12.16.tgz#353bd07fbb08f791b5720535f86b0a8f9b651317" + integrity sha512-KC33uTBacgdunMtfpZFP2pgPpyvKIcCwuh0XmWESbeFrkWLqUtCFN91zyaTdU5OiAM982+E8xh1gjE5EINumaw== + dependencies: + "@types/react" "^15.0.0 || ^16.0.0" fast-levenshtein "^2.0.6" global "^4.3.0" hoist-non-react-statics "^3.3.0" @@ -6415,6 +6474,11 @@ react-router@5.1.2: tiny-invariant "^1.0.2" tiny-warning "^1.0.0" +react-table@^7.0.0-beta.12: + version "7.0.0-beta.12" + resolved "https://registry.yarnpkg.com/react-table/-/react-table-7.0.0-beta.12.tgz#ae54b398fbdb527b9fad82e52c4d829c00fdd5dc" + integrity sha512-h1c0KNTBRPAMgZumaNixr3X0w7kFTuqk6pHwia12LsMgnTHNEEeqp7+tQ5fTPwwMArp1/OHXeOdSKEes1C83iw== + react-window@^1.8.5: version "1.8.5" resolved "https://registry.yarnpkg.com/react-window/-/react-window-1.8.5.tgz#a56b39307e79979721021f5d06a67742ecca52d1"