diff options
author | Emiliano Ciavatta | 2020-12-25 13:48:11 +0000 |
---|---|---|
committer | Emiliano Ciavatta | 2020-12-25 13:48:11 +0000 |
commit | f8f3c91a8722e0cb5cc78f21ad163e8165ac5979 (patch) | |
tree | b6319bc00d886bf0c3a4aeaff19cae378a9cf47a /frontend | |
parent | ad0c27ae1fde7d24c24a34a7c305edeb0ea9974e (diff) |
Add stats page, add /api/statistics/totals
Diffstat (limited to 'frontend')
-rw-r--r-- | frontend/src/components/Header.js | 4 | ||||
-rw-r--r-- | frontend/src/components/pages/MainPage.js | 4 | ||||
-rw-r--r-- | frontend/src/components/panels/ConfigPane.js | 39 | ||||
-rw-r--r-- | frontend/src/components/panels/StatsPane.js | 274 | ||||
-rw-r--r-- | frontend/src/components/panels/StatsPane.scss | 21 | ||||
-rw-r--r-- | frontend/src/utils.js | 4 | ||||
-rw-r--r-- | frontend/yarn.lock | 168 |
7 files changed, 377 insertions, 137 deletions
diff --git a/frontend/src/components/Header.js b/frontend/src/components/Header.js index 4db05a5..e3fafc4 100644 --- a/frontend/src/components/Header.js +++ b/frontend/src/components/Header.js @@ -85,8 +85,8 @@ class Header extends Component { <Link to={"/services" + this.props.location.search}> <ButtonField variant="indigo" name="services" bordered/> </Link> - <Link to={"/config" + this.props.location.search}> - <ButtonField variant="blue" name="config" bordered/> + <Link to={"/stats" + this.props.location.search}> + <ButtonField variant="blue" name="stats" bordered/> </Link> </div> } diff --git a/frontend/src/components/pages/MainPage.js b/frontend/src/components/pages/MainPage.js index 6058edc..f005f44 100644 --- a/frontend/src/components/pages/MainPage.js +++ b/frontend/src/components/pages/MainPage.js @@ -21,13 +21,13 @@ import "react-reflex/styles.css" import {Route, Switch} from "react-router-dom"; import Filters from "../dialogs/Filters"; import Header from "../Header"; -import ConfigPane from "../panels/ConfigPane"; import Connections from "../panels/ConnectionsPane"; import MainPane from "../panels/MainPane"; import PcapsPane from "../panels/PcapsPane"; import RulesPane from "../panels/RulesPane"; import SearchPane from "../panels/SearchPane"; import ServicesPane from "../panels/ServicesPane"; +import StatsPane from "../panels/StatsPane"; import StreamsPane from "../panels/StreamsPane"; import Timeline from "../Timeline"; import "./MainPage.scss"; @@ -76,7 +76,7 @@ class MainPage extends Component { <Route path="/pcaps" children={<PcapsPane/>}/> <Route path="/rules" children={<RulesPane/>}/> <Route path="/services" children={<ServicesPane/>}/> - <Route path="/config" children={<ConfigPane/>}/> + <Route path="/stats" children={<StatsPane/>}/> <Route exact path="/connections/:id" children={<StreamsPane connection={this.state.selectedConnection}/>}/> <Route children={<MainPane version={this.props.version}/>}/> diff --git a/frontend/src/components/panels/ConfigPane.js b/frontend/src/components/panels/ConfigPane.js deleted file mode 100644 index 9710abd..0000000 --- a/frontend/src/components/panels/ConfigPane.js +++ /dev/null @@ -1,39 +0,0 @@ -/* - * This file is part of caronte (https://github.com/eciavatta/caronte). - * Copyright (c) 2020 Emiliano Ciavatta. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, version 3. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -import React, {Component} from "react"; -import "./common.scss"; - -class ConfigPane extends Component { - - state = {}; - - render() { - return ( - <div className="pane-container"> - <div className="main-pane"> - <div className="pane-section"> - Not implemented - </div> - </div> - </div> - ); - } - -} - -export default ConfigPane; diff --git a/frontend/src/components/panels/StatsPane.js b/frontend/src/components/panels/StatsPane.js new file mode 100644 index 0000000..dd774d0 --- /dev/null +++ b/frontend/src/components/panels/StatsPane.js @@ -0,0 +1,274 @@ +/* + * This file is part of caronte (https://github.com/eciavatta/caronte). + * Copyright (c) 2020 Emiliano Ciavatta. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +import React, {Component} from "react"; +import Table from "react-bootstrap/Table"; +import backend from "../../backend"; +import dispatcher from "../../dispatcher"; +import {formatSize} from "../../utils"; +import ButtonField from "../fields/ButtonField"; +import CopyLinkPopover from "../objects/CopyLinkPopover"; +import LinkPopover from "../objects/LinkPopover"; +import "./common.scss"; +import "./StatsPane.scss"; + +class StatsPane extends Component { + + state = { + rules: [] + }; + + componentDidMount() { + this.loadStats(); + this.loadResourcesStats(); + this.loadRules(); + dispatcher.register("notifications", this.handleNotifications); + document.title = "caronte:~/stats$"; + this.intervalToken = setInterval(() => this.loadResourcesStats(), 3000); + } + + componentWillUnmount() { + dispatcher.unregister(this.handleNotifications); + clearInterval(this.intervalToken); + } + + handleNotifications = (payload) => { + if (payload.event.startsWith("pcap")) { + this.loadStats(); + } else if (payload.event.startsWith("rules")) { + this.loadRules(); + } + }; + + loadStats = () => { + backend.get("/api/statistics/totals") + .then((res) => this.setState({stats: res.json, statsStatusCode: res.status})) + .catch((res) => this.setState({ + stats: res.json, statsStatusCode: res.status, + statsResponse: JSON.stringify(res.json) + })); + }; + + loadResourcesStats = () => { + backend.get("/api/resources/system") + .then((res) => this.setState({resourcesStats: res.json, resourcesStatsStatusCode: res.status})) + .catch((res) => this.setState({ + resourcesStats: res.json, resourcesStatsStatusCode: res.status, + resourcesStatsResponse: JSON.stringify(res.json) + })); + }; + + loadRules = () => { + backend.get("/api/rules").then((res) => this.setState({rules: res.json})); + }; + + render() { + const s = this.state.stats; + const rs = this.state.resourcesStats; + + const ports = s ? Object.keys(s["connections_per_service"]) : []; + let connections = 0, clientBytes = 0, serverBytes = 0, totalBytes = 0, duration = 0; + let servicesStats = ports.map((port) => { + connections += s["connections_per_service"][port]; + clientBytes += s["client_bytes_per_service"][port]; + serverBytes += s["server_bytes_per_service"][port]; + totalBytes += s["total_bytes_per_service"][port]; + duration += s["duration_per_service"][port]; + + return <tr key={port} className="row-small row-clickable"> + <td>{port}</td> + <td>{formatSize(s["connections_per_service"][port])}</td> + <td>{formatSize(s["client_bytes_per_service"][port])}B</td> + <td>{formatSize(s["server_bytes_per_service"][port])}B</td> + <td>{formatSize(s["total_bytes_per_service"][port])}B</td> + <td>{formatSize(s["duration_per_service"][port] / 1000)}s</td> + </tr>; + }); + servicesStats.push(<tr key="totals" className="row-small row-clickable font-weight-bold"> + <td>totals</td> + <td>{formatSize(connections)}</td> + <td>{formatSize(clientBytes)}B</td> + <td>{formatSize(serverBytes)}B</td> + <td>{formatSize(totalBytes)}B</td> + <td>{formatSize(duration / 1000)}s</td> + </tr>); + + const rulesStats = this.state.rules.map((r) => + <tr key={r.id} className="row-small row-clickable"> + <td><CopyLinkPopover text={r["id"].substring(0, 8)} value={r["id"]}/></td> + <td>{r["name"]}</td> + <td><ButtonField name={r["color"]} color={r["color"]} small/></td> + <td>{formatSize(s && s["matched_rules"] && s["matched_rules"][r.id] ? s["matched_rules"][r.id] : 0)}</td> + </tr> + ); + + const cpuStats = (rs ? rs["cpu_times"] : []).map((cpu, index) => + <tr key={cpu["cpu"]} className="row-small row-clickable"> + <td>{cpu["cpu"]}</td> + <td>{cpu["user"]}</td> + <td>{cpu["system"]}</td> + <td>{cpu["idle"]}</td> + <td>{cpu["nice"]}</td> + <td>{cpu["iowait"]}</td> + <td>{rs["cpu_percents"][index].toFixed(2)} %</td> + </tr> + ); + + return ( + <div className="pane-container stats-pane"> + <div className="pane-section stats-list"> + <div className="section-header"> + <span className="api-request">GET /api/statistics/totals</span> + <span className="api-response"><LinkPopover text={this.state.statsStatusCode} + content={this.state.statsResponse} + placement="left"/></span> + </div> + + <div className="section-content"> + <div className="section-table"> + <Table borderless size="sm"> + <thead> + <tr> + <th>service</th> + <th>connections</th> + <th>client_bytes</th> + <th>server_bytes</th> + <th>total_bytes</th> + <th>duration</th> + </tr> + </thead> + <tbody> + {servicesStats} + </tbody> + </Table> + </div> + + <div className="section-table"> + <Table borderless size="sm"> + <thead> + <tr> + <th>rule_id</th> + <th>rule_name</th> + <th>rule_color</th> + <th>occurrences</th> + </tr> + </thead> + <tbody> + {rulesStats} + </tbody> + </Table> + </div> + </div> + </div> + + <div className="pane-section stats-list" style={{"paddingTop": "10px"}}> + <div className="section-header"> + <span className="api-request">GET /api/resources/system</span> + <span className="api-response"><LinkPopover text={this.state.resourcesStatsStatusCode} + content={this.state.resourcesStatsResponse} + placement="left"/></span> + </div> + + <div className="section-content"> + <div className="section-table"> + <Table borderless size="sm"> + <thead> + <tr> + <th>type</th> + <th>total</th> + <th>used</th> + <th>free</th> + <th>shared</th> + <th>buff/cache</th> + <th>available</th> + </tr> + </thead> + <tbody> + <tr className="row-small row-clickable"> + <td>mem</td> + <td>{rs && formatSize(rs["virtual_memory"]["total"])}</td> + <td>{rs && formatSize(rs["virtual_memory"]["used"])}</td> + <td>{rs && formatSize(rs["virtual_memory"]["free"])}</td> + <td>{rs && formatSize(rs["virtual_memory"]["shared"])}</td> + <td>{rs && formatSize(rs["virtual_memory"]["cached"])}</td> + <td>{rs && formatSize(rs["virtual_memory"]["available"])}</td> + </tr> + <tr className="row-small row-clickable"> + <td>swap</td> + <td>{rs && formatSize(rs["virtual_memory"]["swaptotal"])}</td> + <td>{rs && formatSize(rs["virtual_memory"]["swaptotal"])}</td> + <td>{rs && formatSize(rs["virtual_memory"]["swapfree"])}</td> + <td>-</td> + <td>-</td> + <td>-</td> + </tr> + </tbody> + </Table> + </div> + + <div className="section-table"> + <Table borderless size="sm"> + <thead> + <tr> + <th>cpu</th> + <th>user</th> + <th>system</th> + <th>idle</th> + <th>nice</th> + <th>iowait</th> + <th>used_percent</th> + </tr> + </thead> + <tbody> + {cpuStats} + </tbody> + </Table> + </div> + + <div className="section-table"> + <Table borderless size="sm"> + <thead> + <tr> + <th>disk_path</th> + <th>fs_type</th> + <th>total</th> + <th>free</th> + <th>used</th> + <th>used_percent</th> + </tr> + </thead> + <tbody> + <tr className="row-small row-clickable"> + <td>{rs && rs["disk_usage"]["path"]}</td> + <td>{rs && rs["disk_usage"]["fstype"]}</td> + <td>{rs && formatSize(rs["disk_usage"]["total"])}</td> + <td>{rs && formatSize(rs["disk_usage"]["free"])}</td> + <td>{rs && formatSize(rs["disk_usage"]["used"])}</td> + <td>{rs && rs["disk_usage"]["usedPercent"].toFixed(2)} %</td> + </tr> + </tbody> + </Table> + </div> + </div> + </div> + </div> + ); + } + +} + +export default StatsPane; diff --git a/frontend/src/components/panels/StatsPane.scss b/frontend/src/components/panels/StatsPane.scss new file mode 100644 index 0000000..24a0a33 --- /dev/null +++ b/frontend/src/components/panels/StatsPane.scss @@ -0,0 +1,21 @@ +@import "../../colors.scss"; + +.stats-pane { + display: flex; + flex-direction: column; + + .stats-list { + position: relative; + flex: 1; + height: 50%; + + .section-content { + overflow-y: scroll; + height: calc(100% - 10px); + } + + .section-table { + margin-bottom: 10px; + } + } +} diff --git a/frontend/src/utils.js b/frontend/src/utils.js index 445e576..4849a92 100644 --- a/frontend/src/utils.js +++ b/frontend/src/utils.js @@ -120,8 +120,10 @@ export function formatSize(size) { return `${size}`; } else if (size < 1000000) { return `${(size / 1000).toFixed(1)}K`; - } else { + } else if (size < 1000000000) { return `${(size / 1000000).toFixed(1)}M`; + } else { + return `${(size / 1000000000).toFixed(1)}Gi`; } } diff --git a/frontend/yarn.lock b/frontend/yarn.lock index f1de5ae..d8718db 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -9,7 +9,7 @@ dependencies: "@babel/highlight" "^7.8.3" -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.8.3": +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.11", "@babel/code-frame@^7.8.3": version "7.12.11" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f" integrity sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw== @@ -64,7 +64,7 @@ semver "^5.4.1" source-map "^0.5.0" -"@babel/generator@^7.12.10", "@babel/generator@^7.4.0", "@babel/generator@^7.9.0": +"@babel/generator@^7.12.10", "@babel/generator@^7.12.11", "@babel/generator@^7.4.0", "@babel/generator@^7.9.0": version "7.12.11" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.12.11.tgz#98a7df7b8c358c9a37ab07a24056853016aba3af" integrity sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA== @@ -88,23 +88,6 @@ "@babel/helper-explode-assignable-expression" "^7.10.4" "@babel/types" "^7.10.4" -"@babel/helper-builder-react-jsx-experimental@^7.12.11": - version "7.12.11" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-react-jsx-experimental/-/helper-builder-react-jsx-experimental-7.12.11.tgz#a39616d7e4cf8f9da1f82b5fc3ee1f7406beeb11" - integrity sha512-4oGVOekPI8dh9JphkPXC68iIuP6qp/RPbaPmorRmEFbRAHZjSqxPjqHudn18GVDPgCuFM/KdFXc63C17Ygfa9w== - dependencies: - "@babel/helper-annotate-as-pure" "^7.12.10" - "@babel/helper-module-imports" "^7.12.5" - "@babel/types" "^7.12.11" - -"@babel/helper-builder-react-jsx@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.10.4.tgz#8095cddbff858e6fa9c326daee54a2f2732c1d5d" - integrity sha512-5nPcIZ7+KKDxT1427oBivl9V9YTal7qk0diccnh7RrcgrT/pGFOjgGw1dgryyx1GvHEpXVfoDF6Ak3rTiWh8Rg== - dependencies: - "@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.8.7": version "7.12.5" resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.12.5.tgz#cb470c76198db6a24e9dbc8987275631e5d29831" @@ -150,7 +133,7 @@ dependencies: "@babel/types" "^7.12.1" -"@babel/helper-function-name@^7.10.4": +"@babel/helper-function-name@^7.10.4", "@babel/helper-function-name@^7.12.11": version "7.12.11" resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.12.11.tgz#1fd7738aee5dcf53c3ecff24f1da9c511ec47b42" integrity sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA== @@ -247,7 +230,7 @@ dependencies: "@babel/types" "^7.12.1" -"@babel/helper-split-export-declaration@^7.10.4", "@babel/helper-split-export-declaration@^7.11.0": +"@babel/helper-split-export-declaration@^7.10.4", "@babel/helper-split-export-declaration@^7.11.0", "@babel/helper-split-export-declaration@^7.12.11": version "7.12.11" resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.11.tgz#1b4cc424458643c47d37022223da33d76ea4603a" integrity sha512-LsIVN8j48gHgwzfocYUSkO/hjYAOJqlpJEc7tGXcIm4cubjVUf8LGW6eWRyxEu7gA25q02p0rQUWoCI33HNS5g== @@ -292,15 +275,15 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.1.0", "@babel/parser@^7.12.10", "@babel/parser@^7.12.7", "@babel/parser@^7.4.3", "@babel/parser@^7.7.0", "@babel/parser@^7.9.0": +"@babel/parser@^7.1.0", "@babel/parser@^7.12.10", "@babel/parser@^7.12.11", "@babel/parser@^7.12.7", "@babel/parser@^7.4.3", "@babel/parser@^7.7.0", "@babel/parser@^7.9.0": version "7.12.11" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.12.11.tgz#9ce3595bcd74bc5c466905e86c535b8b25011e79" integrity sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg== "@babel/plugin-proposal-async-generator-functions@^7.12.1", "@babel/plugin-proposal-async-generator-functions@^7.8.3": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.12.1.tgz#dc6c1170e27d8aca99ff65f4925bd06b1c90550e" - integrity sha512-d+/o30tJxFxrA1lhzJqiUcEJdI6jKlNregCv5bASeGf2Q4MXmnwH7viDo7nhx1/ohf09oaH8j1GVYG/e3Yqk6A== + 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" @@ -581,9 +564,9 @@ "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-transform-block-scoping@^7.12.11", "@babel/plugin-transform-block-scoping@^7.8.3": - version "7.12.11" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.12.11.tgz#83ae92a104dbb93a7d6c6dd1844f351083c46b4f" - integrity sha512-atR1Rxc3hM+VPg/NvNvfYw0npQEAcHuJ+MGZnFn6h3bo+1U3BWXMdFMlvVRApBTWKQMX7SOwRJZA5FBF/JQbvA== + 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" @@ -771,13 +754,11 @@ "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-transform-react-jsx-development@^7.12.7", "@babel/plugin-transform-react-jsx-development@^7.9.0": - version "7.12.11" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.12.11.tgz#078aa7e1f5f75a68ee9598ebed90000fcb11092f" - integrity sha512-5MvsGschXeXJsbzQGR/BH89ATMzCsM7rx95n+R7/852cGoK2JgMbacDw/A9Pmrfex4tArdMab0L5SBV4SB/Nxg== + 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/helper-builder-react-jsx-experimental" "^7.12.11" - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-syntax-jsx" "^7.12.1" + "@babel/plugin-transform-react-jsx" "^7.12.12" "@babel/plugin-transform-react-jsx-self@^7.9.0": version "7.12.1" @@ -793,15 +774,16 @@ dependencies: "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-react-jsx@^7.12.10", "@babel/plugin-transform-react-jsx@^7.9.1": - version "7.12.11" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.12.11.tgz#09a7319195946b0ddc09f9a5f01346f2cb80dfdd" - integrity sha512-5nWOw6mTylaFU72BdZfa0dP1HsGdY3IMExpxn8LBE8dNmkQjB+W+sR+JwIdtbzkPvVuFviT3zyNbSUkuVTVxbw== +"@babel/plugin-transform-react-jsx@^7.12.10", "@babel/plugin-transform-react-jsx@^7.12.12", "@babel/plugin-transform-react-jsx@^7.9.1": + 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-builder-react-jsx" "^7.10.4" - "@babel/helper-builder-react-jsx-experimental" "^7.12.11" + "@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-pure-annotations@^7.12.1": version "7.12.1" @@ -1115,24 +1097,24 @@ "@babel/types" "^7.12.7" "@babel/traverse@^7.1.0", "@babel/traverse@^7.10.4", "@babel/traverse@^7.12.1", "@babel/traverse@^7.12.10", "@babel/traverse@^7.12.5", "@babel/traverse@^7.4.3", "@babel/traverse@^7.7.0", "@babel/traverse@^7.9.0": - version "7.12.10" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.12.10.tgz#2d1f4041e8bf42ea099e5b2dc48d6a594c00017a" - integrity sha512-6aEtf0IeRgbYWzta29lePeYSk+YAFIC3kyqESeft8o5CkFlYIMX+EQDDWEiAQ9LHOA3d0oHdgrSsID/CKqXJlg== - dependencies: - "@babel/code-frame" "^7.10.4" - "@babel/generator" "^7.12.10" - "@babel/helper-function-name" "^7.10.4" - "@babel/helper-split-export-declaration" "^7.11.0" - "@babel/parser" "^7.12.10" - "@babel/types" "^7.12.10" + version "7.12.12" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.12.12.tgz#d0cd87892704edd8da002d674bc811ce64743376" + integrity sha512-s88i0X0lPy45RrLM8b9mz8RPH5FqO9G9p7ti59cToE44xFm1Q+Pjh5Gq4SXBbtb88X7Uy7pexeqRIQDDMNkL0w== + dependencies: + "@babel/code-frame" "^7.12.11" + "@babel/generator" "^7.12.11" + "@babel/helper-function-name" "^7.12.11" + "@babel/helper-split-export-declaration" "^7.12.11" + "@babel/parser" "^7.12.11" + "@babel/types" "^7.12.12" debug "^4.1.0" globals "^11.1.0" lodash "^4.17.19" -"@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.5", "@babel/types@^7.12.7", "@babel/types@^7.3.0", "@babel/types@^7.4.0", "@babel/types@^7.4.4", "@babel/types@^7.7.0", "@babel/types@^7.9.0": - version "7.12.11" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.12.11.tgz#a86e4d71e30a9b6ee102590446c98662589283ce" - integrity sha512-ukA9SQtKThINm++CX1CwmliMrE54J6nIYB5XTwL5f/CLFW9owfls+YSU8tVW15RQ2w+a3fSbPjC6HdQNtWZkiA== +"@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.12.5", "@babel/types@^7.12.7", "@babel/types@^7.3.0", "@babel/types@^7.4.0", "@babel/types@^7.4.4", "@babel/types@^7.7.0", "@babel/types@^7.9.0": + version "7.12.12" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.12.12.tgz#4608a6ec313abbd87afa55004d373ad04a96c299" + integrity sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ== dependencies: "@babel/helper-validator-identifier" "^7.12.11" lodash "^4.17.19" @@ -1176,9 +1158,9 @@ "@fortawesome/fontawesome-common-types" "^0.2.32" "@fortawesome/react-fontawesome@^0.1.9": - version "0.1.13" - resolved "https://registry.yarnpkg.com/@fortawesome/react-fontawesome/-/react-fontawesome-0.1.13.tgz#ce9654bf4e537108014ec022f2423dbe8114fd62" - integrity sha512-/HrLnIft5Ks2511Pz6TxHBIctC9QalVscAC64sufQ4sJH/sXaQlG3uR9LCu6VpEwkBemgcBLrz/QPNP/ddbjDg== + version "0.1.14" + resolved "https://registry.yarnpkg.com/@fortawesome/react-fontawesome/-/react-fontawesome-0.1.14.tgz#bf28875c3935b69ce2dc620e1060b217a47f64ca" + integrity sha512-4wqNb0gRLVaBm/h+lGe8UfPPivcbuJ6ecI4hIgW0LjI7kzpYB9FkN0L9apbVzg+lsBdcTf0AlBtODjcSX5mmKA== dependencies: prop-types "^15.7.2" @@ -1684,9 +1666,9 @@ integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== "@types/node@*": - version "14.14.14" - resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.14.tgz#f7fd5f3cc8521301119f63910f0fb965c7d761ae" - integrity sha512-UHnOPWVWV1z+VV8k6L1HhG7UbGBgIdghqF3l9Ny9ApPghbjICXkUJSd/b9gOgQfjM1r+37cipdw/HJ3F6ICEnQ== + version "14.14.16" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.16.tgz#3cc351f8d48101deadfed4c9e4f116048d437b4b" + integrity sha512-naXYePhweTi+BMv11TgioE2/FXU4fSl29HAH1ffxVciNsH3rYXjNP2yM8wqmSm7jS20gM8TIklKiTen+1iVncw== "@types/parse-json@^4.0.0": version "4.0.0" @@ -1767,9 +1749,9 @@ integrity sha1-DSUBJorY+ZYrdA04fEZU9fjiPlI= "@types/yargs-parser@*": - version "15.0.0" - resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-15.0.0.tgz#cb3f9f741869e20cce330ffbeb9271590483882d" - integrity sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw== + version "20.2.0" + resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-20.2.0.tgz#dd3e6699ba3237f0348cd085e4698780204842f9" + integrity sha512-37RSHht+gzzgYeobbG+KWryeAW8J33Nhr69cjTqSYymXVZEN9NbRYWoYlRtDhHKPVT1FyNKwaTPC1NynKZpzRA== "@types/yargs@^13.0.0": version "13.0.11" @@ -2998,9 +2980,9 @@ caniuse-api@^3.0.0: lodash.uniq "^4.5.0" caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30001035, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001165: - version "1.0.30001168" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001168.tgz#6fcd098c139d003b9bd484cbb9ca26cb89907f9a" - integrity sha512-P2zmX7swIXKu+GMMR01TWa4csIKELTNnZKc+f1CjebmZJQtTAEXmpQSoKVJVVcvPGAA0TEYTOUp3VehavZSFPQ== + version "1.0.30001170" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001170.tgz#0088bfecc6a14694969e391cc29d7eb6362ca6a7" + integrity sha512-Dd4d/+0tsK0UNLrZs3CvNukqalnVTRrxb5mcQm8rHL49t7V5ZaTygwXkrq+FB+dVDf++4ri8eJnFEJAB8332PA== capture-exit@^2.0.0: version "2.0.0" @@ -4228,9 +4210,9 @@ domhandler@^2.3.0: domelementtype "1" dompurify@^2.1.1: - version "2.2.4" - resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.2.4.tgz#a98cd182b729bdd8715c3eb7a8bf8eafb2ff7410" - integrity sha512-jE21SelIgWrGKoXGfGPA524Zt1IJFBnktwfFMHDlEYRx5FZOdc+4eEH9mkA6PuhExrq3HVpJnY8hMYUzAMl0OA== + version "2.2.6" + resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.2.6.tgz#54945dc5c0b45ce5ae228705777e8e59d7b2edc4" + integrity sha512-7b7ZArhhH0SP6W2R9cqK6RjaU82FZ2UPM7RO8qN1b1wyvC/NY1FNWcX1Pu00fFOAnzEORtwXe4bPaClg6pUybQ== domutils@1.5.1: version "1.5.1" @@ -4302,9 +4284,9 @@ ee-first@1.1.1: integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= electron-to-chromium@^1.3.378, electron-to-chromium@^1.3.621: - version "1.3.627" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.627.tgz#4acdbbbbe31eb605fba8380063fd9c8a7e5ca4a0" - integrity sha512-O5IVRS4sCxP2+vECAp7uHkaI8V+dKYpuCyBcLn+hqVAOy/RONd8zx+6eH7TuWSTBYs/oUrzBXkNMZuVsQd58kQ== + version "1.3.633" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.633.tgz#16dd5aec9de03894e8d14a1db4cda8a369b9b7fe" + integrity sha512-bsVCsONiVX1abkWdH7KtpuDAhsQ3N3bjPYhROSAXE78roJKet0Y5wznA14JE9pzbwSZmSMAW6KiKYf1RvbTJkA== elliptic@^6.5.3: version "6.5.3" @@ -4378,9 +4360,9 @@ entities@^2.0.0: integrity sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w== errno@^0.1.3, errno@~0.1.7: - version "0.1.7" - resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618" - integrity sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg== + version "0.1.8" + resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.8.tgz#8bb3e9c7d463be4976ff888f76b4809ebc2e811f" + integrity sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A== dependencies: prr "~1.0.1" @@ -5311,9 +5293,9 @@ get-caller-file@^2.0.1: integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== get-intrinsic@^1.0.0, get-intrinsic@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.0.1.tgz#94a9768fcbdd0595a1c9273aacf4c89d075631be" - integrity sha512-ZnWP+AmS1VUaLgTRy47+zKtjTxz+0xMpx3I52i+aalBK1QP19ggLF3Db89KJX7kjfOfP2eoa01qc++GwPgufPg== + version "1.0.2" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.0.2.tgz#6820da226e50b24894e08859469dc68361545d49" + integrity sha512-aeX0vrFm21ILl3+JpFFRNe9aUvp6VFZb2/CTbgLb8j75kOhvoNYjt9d8KA/tJG4gSo8nzEDedRl0h7vDmBYRVg== dependencies: function-bind "^1.1.1" has "^1.0.3" @@ -5658,9 +5640,9 @@ html-encoding-sniffer@^1.0.2: whatwg-encoding "^1.0.1" html-entities@^1.2.1: - version "1.3.3" - resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.3.3.tgz#3dca638a43ee7de316fc23067398491152ad4736" - integrity sha512-/VulV3SYni1taM7a4RMdceqzJWR39gpZHjBwUnsCFKWV/GJkD14CJ5F7eWcZozmHJK0/f/H5U3b3SiPkuvxMgg== + version "1.4.0" + resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.4.0.tgz#cfbd1b01d2afaf9adca1b10ae7dffab98c71d2dc" + integrity sha512-8nxjcBcd8wovbeKx7h3wTji4e6+rhaVuPNpMqwWgnHh+N9ToqsCs6XztWRBPQ+UtzsoMAdKZtUENoVzU/EMtZA== html-escaper@^2.0.0: version "2.0.2" @@ -5869,9 +5851,9 @@ import-fresh@^2.0.0: resolve-from "^3.0.0" import-fresh@^3.0.0, import-fresh@^3.1.0: - version "3.2.2" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.2.2.tgz#fc129c160c5d68235507f4331a6baad186bdbc3e" - integrity sha512-cTPNrlvJT6twpYy+YmKUKrTSjWFs3bjYjAhCwm+z4EOCubZxAuO+hHpRN64TqjEaYSHs7tJAE0w1CKMGmsG/lw== + version "3.3.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" + integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== dependencies: parent-module "^1.0.0" resolve-from "^4.0.0" @@ -7202,9 +7184,9 @@ locate-path@^5.0.0: p-locate "^4.1.0" lodash-es@^4.17.15: - version "4.17.15" - resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.15.tgz#21bd96839354412f23d7a10340e5eac6ee455d78" - integrity sha512-rlrc3yU3+JNOpZ9zj5pQtxnx2THmvRykwL4Xlxoa8I9lHBlVbbyPhgyPMioxVZ4NqyxaVVtaJnzsyOidQIhyyQ== + version "4.17.20" + resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.20.tgz#29f6332eefc60e849f869c264bc71126ad61e8f7" + integrity sha512-JD1COMZsq8maT6mnuz1UMV0jvYD0E0aUsSOdrr1/nAG3dhqQXwRRgeW0cSqH1U43INKcqxaiVIQNOUDld7gRDA== lodash._reinterpolate@^3.0.0: version "3.0.0" @@ -9157,9 +9139,9 @@ postcss-selector-matches@^4.0.0: postcss "^7.0.2" postcss-selector-not@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/postcss-selector-not/-/postcss-selector-not-4.0.0.tgz#c68ff7ba96527499e832724a2674d65603b645c0" - integrity sha512-W+bkBZRhqJaYN8XAnbbZPLWMvZD1wKTu0UxtFKdhtGjWYmxhkUneoeOhRJKdAE5V7ZTlnbHfCR+6bNwK9e1dTQ== + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-selector-not/-/postcss-selector-not-4.0.1.tgz#263016eef1cf219e0ade9a913780fc1f48204cbf" + integrity sha512-YolvBgInEK5/79C+bdFMyzqTg6pkYqDbzZIST/PDMqa/o3qtXenD05apBG2jLgT0/BQ77d4U2UK12jWpilqMAQ== dependencies: balanced-match "^1.0.0" postcss "^7.0.2" @@ -9259,9 +9241,9 @@ prepend-http@^1.0.0: integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw= pretty-bytes@^5.1.0: - version "5.4.1" - resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.4.1.tgz#cd89f79bbcef21e3d21eb0da68ffe93f803e884b" - integrity sha512-s1Iam6Gwz3JI5Hweaz4GoCD1WUNUIyzePFy5+Js2hjwGVt2Z79wNN+ZKOZ2vB6C+Xs6njyB84Z1IthQg8d9LxA== + version "5.5.0" + resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.5.0.tgz#0cecda50a74a941589498011cf23275aa82b339e" + integrity sha512-p+T744ZyjjiaFlMUZZv6YPC5JrkNj8maRmPaQCWFJFplUAzpIUTRaTcS+7wmZtUoFXHtESJb23ISliaWyz3SHA== pretty-error@^2.1.1: version "2.1.2" |