diff --git a/.env b/.env
new file mode 100644
index 0000000000000000000000000000000000000000..3ccb8fff3ef022e5adf5166117b885f96292f080
--- /dev/null
+++ b/.env
@@ -0,0 +1 @@
+EXTEND_ESLINT=true
\ No newline at end of file
diff --git a/.eslintrc.js b/.eslintrc.js
index 75cd94e1e7746aea5d1569fb2f08167d78adac81..a07f51e6770e756c50518e784fefe34c8eacd9b7 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -1,15 +1,39 @@
 module.exports = {
-  extends: 'erb/typescript',
+  extends: [
+    'airbnb',
+    'plugin:react/recommended',
+    'plugin:import/recommended',
+    'prettier',
+    'plugin:prettier/recommended',
+    'plugin:jest/recommended',
+    'plugin:promise/recommended',
+    'plugin:compat/recommended',
+    'airbnb-typescript',
+    'plugin:import/typescript',
+    'plugin:@typescript-eslint/recommended',
+    'prettier/@typescript-eslint',
+  ],
   rules: {
     // A temporary hack related to IDE not resolving correct package.json
     'import/no-extraneous-dependencies': 'off',
     'no-console': 'off',
+    'react/jsx-indent': 'off',
     'prettier/prettier': [
       'error',
       {
         endOfLine: 'auto',
       },
     ],
+    '@typescript-eslint/explicit-function-return-type': 'off',
+    '@typescript-eslint/explicit-module-boundary-types': 'off',
+    '@typescript-eslint/no-var-requires': 'off',
+    'no-param-reassign': ['error', { props: false }],
+    'comma-dangle': 'off',
+    'operator-linebreak': 'off',
+    'object-curly-newline': 'off',
+    'max-len': 'off',
+    'implicit-arrow-linebreak': 'off',
+    'function-paren-newline': 'off',
   },
   parserOptions: {
     ecmaVersion: 2020,
diff --git a/.gitignore b/.gitignore
index 38e1fb2ce1376370d9f83352eeb75edea7d9d176..2b7e9672a0f0c23298dbe55aa0e4058cd1b91d65 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,11 @@
 loginDetails.json
+package-lock.json
+
+out/
 
 *.LICENSE
+*.LICENSE.txt
+app/main.prod.js.LICENSE.txt
 
 # Logs
 logs
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 22ac592e5fa9941276d03d106c06936419715fbc..5abd08a393707b9e12d85ef37bd5ecb4b38d7313 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,23 +1,22 @@
 image: node:lts-alpine
 
-stages:
-  - pre
-  - test
-
 cache:
-  key: ${CI_COMMIT_REF_SLUG}
+  key:
+    files:
+      - yarn.lock
   paths:
     - node_modules/
 
-before_script:
-  - yarn install
-  - yarn build-main
-  - yarn build-renderer
+stages:
+  - test
+  - deploy
 
 lint:
   stage: test
   script:
+    - yarn install
     - yarn run lint
+
 #lint:types:
 #  stage: test
 #  script:
@@ -26,12 +25,25 @@ lint:
 tests:unit:
   stage: test
   script:
+    - yarn install
+    - yarn build
     - yarn run test
-#expo-deployments:
-#  stage: deploy
-#  only:
-#    - master
-#  script:
-#    - echo fs.inotify.max_user_watches=524288 | tee -a /etc/sysctl.conf && sysctl -p
-#    - npx expo login -u $EXPO_USERNAME -p $EXPO_PASSWORD
-#    - npx expo publish --non-interactive
+
+publish:
+  stage: deploy
+  only:
+    - master
+  image: simpliston/mysql-query-profiler:latest
+  script:
+    - node -v
+    # Getting version number from app/package.json
+    - ticked_version=$(jq .version app/package.json)
+    - version=${ticked_version//[\"]/}
+    # Packaging the app
+    - yarn install --check-files
+    - yarn run package-all
+    # Uploading to snap store
+    - snapcraft login --with ${snapcraft_login}
+    - snapcraft upload --release=stable release/mysql-query-profiler_${version}_amd64.snap
+    # Creating new version on Bintray
+    - bash publish-bintray.sh
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..5d8a4bb18055847b2a8bb6588bb3807f63a41643
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,43 @@
+FROM snapcore/snapcraft:stable
+
+ENV DEBIAN_FRONTEND=noninteractive
+
+RUN apt-get update && apt-get dist-upgrade -y
+
+RUN apt-get install -y snapcraft && apt-get clean
+
+RUN apt-get install -y curl
+
+RUN curl -sL https://deb.nodesource.com/setup_lts.x | sudo -E bash -
+
+RUN apt-get install -y nodejs
+
+RUN node -v
+
+RUN npm install -g yarn
+
+RUN nodejs -v
+
+RUN apt-get install -y rpm
+
+RUN apt-get purge wine
+
+RUN apt-get update && apt-get autoremove && apt-get clean && apt-get autoclean
+
+RUN dpkg --add-architecture i386
+
+RUN apt-get install -y software-properties-common
+
+RUN add-apt-repository ppa:ubuntu-wine/ppa && apt-get update
+
+RUN apt-get install -y wine1.8
+
+RUN apt-get install jq -y
+
+# TO BUILD: 
+# docker build -t simpliston/mysql-query-profiler .
+
+# TO PUSH: 
+# docker login
+# docker push simpliston/mysql-query-profiler:latest
+
diff --git a/README.md b/README.md
index 7932189748901def0ae9ff69aa5e44a27657e424..3d7c5de4ac567b7378ef421d7fd7e2b2fe88c12e 100644
--- a/README.md
+++ b/README.md
@@ -1,12 +1,40 @@
 # MySQL Query Profiler
 
-## Requirements
+[![Download](https://api.bintray.com/packages/kpro4/mysql-query-profiler/mysql-query-profiler/images/download.svg)](https://bintray.com/kpro4/mysql-query-profiler/mysql-query-profiler/_latestVersion)
+
+## Installation and use
+
+### Install
+
+#### **Linux**
+
+Either use the AppImage, deb, or rpm file in [Bintray](https://bintray.com/kpro4/mysql-query-profiler/mysql-query-profiler) or install the snap:
+
+```bash
+snap install mysql-query-profiler
+```
+
+#### **Windows**
+
+Install the exe-file from [Bintray](https://bintray.com/kpro4/mysql-query-profiler/mysql-query-profiler).
+
+#### **MacOS**
+
+Use the zip-file from [Bintray](https://bintray.com/kpro4/mysql-query-profiler/mysql-query-profiler).
+
+### Usage
+
+Start the application, connect to a database (remote or local) and insert a query you want to debug. Performance will be shown along with an optimizer trace in addition to more options you can configure.
+
+## Development
+
+### Requirements
 
 - Node 10 or later
 - Npm
 - Yarn
 
-## Install
+### Install for development
 
 First, clone the repo via git and install dependencies:
 
@@ -18,7 +46,7 @@ yarn
 
 Test database: [test_db](https://github.com/datacharmer/test_db)
 
-## Starting Development
+### Starting Development
 
 Start the app in the `dev` environment. This starts the renderer process in [**hot-module-replacement**](https://webpack.js.org/guides/hmr-react/) mode and starts a webpack dev server that sends hot updates to the renderer process:
 
@@ -26,7 +54,7 @@ Start the app in the `dev` environment. This starts the renderer process in [**h
 yarn dev
 ```
 
-## Packaging for Production
+### Packaging for Production
 
 To package apps for the local platform:
 
diff --git a/app/App.tsx b/app/App.tsx
index 39d56c50db9969f34f7989ecf0774987eaf9c099..b4350105949cdb9c5e08472f708c6de431c57847 100644
--- a/app/App.tsx
+++ b/app/App.tsx
@@ -1,7 +1,6 @@
 import React from 'react';
 import { createMuiTheme, ThemeProvider } from '@material-ui/core';
 import { HashRouter as Router, Switch, Route } from 'react-router-dom';
-import { SqlManagerProvider } from './context/SqlManagerContext';
 import { LoadingProvider } from './context/LoadingContext';
 import routes from './routes';
 import LoginScreen from './containers/LoginScreen';
@@ -11,6 +10,9 @@ import { LoginDetailsProvider } from './context/LoginDetailsContext';
 const theme = createMuiTheme({
   palette: {
     type: 'dark',
+    error: {
+      main: '#FF9292',
+    },
     primary: {
       light: '#769CFF',
       main: '#769CFF',
@@ -45,26 +47,22 @@ const theme = createMuiTheme({
 
 export default function App() {
   return (
-    <div>
+    <div className="content">
       <ThemeProvider theme={theme}>
-        <SqlManagerProvider>
-          <LoadingProvider>
-            <LoginDetailsProvider>
-              <div className="content">
-                <Router>
-                  <Switch>
-                    <Route exact path={routes.login}>
-                      <LoginScreen />
-                    </Route>
-                    <Route path={routes.dashboard}>
-                      <Dashboard />
-                    </Route>
-                  </Switch>
-                </Router>
-              </div>
-            </LoginDetailsProvider>
-          </LoadingProvider>
-        </SqlManagerProvider>
+        <LoadingProvider>
+          <LoginDetailsProvider>
+            <Router>
+              <Switch>
+                <Route exact path={routes.login}>
+                  <LoginScreen />
+                </Route>
+                <Route path={routes.dashboard}>
+                  <Dashboard />
+                </Route>
+              </Switch>
+            </Router>
+          </LoginDetailsProvider>
+        </LoadingProvider>
       </ThemeProvider>
     </div>
   );
diff --git a/app/QueryOutput.ts b/app/QueryOutput.ts
new file mode 100644
index 0000000000000000000000000000000000000000..1a7a89fc75f67c31b5bfe5a5508683ae23a44924
--- /dev/null
+++ b/app/QueryOutput.ts
@@ -0,0 +1,6 @@
+import { Result } from '../backend/utils/mysql';
+
+export interface QueryOutput {
+  results: Result | undefined;
+  error: undefined;
+}
diff --git a/app/app.global.css b/app/app.global.css
index 529eb368c19146638be71f9e840f411fa3ea3280..eed1a3f2d664da147cb1875058b76488799089b5 100644
--- a/app/app.global.css
+++ b/app/app.global.css
@@ -4,15 +4,19 @@
  *        See https://github.com/webpack-contrib/sass-loader#imports
  */
 
-body {
+body,
+body #root {
   color: rgba(255, 255, 255, 0.9);
+  max-height: 100vh;
+  max-width: 100vw;
   height: 100vh;
-  background-color: #404040;
+  width: 100vw;
+  background-color: #393939;
   margin: 0;
+  overflow: hidden;
 }
 
 .content {
-  display: flex;
-  flex-flow: column nowrap;
-  justify-content: space-between;
+  min-height: 100%;
+  min-width: 100%;
 }
diff --git a/app/app.html b/app/app.html
index 6307190b216ff19a4edaa0d2f31f2038b52b413b..29649a36b3c9af33ca7058fec9543efeebd2c21e 100644
--- a/app/app.html
+++ b/app/app.html
@@ -2,8 +2,12 @@
 <!DOCTYPE html>
 <html>
   <head>
-    <meta charset="utf-8" />
-    <title>Hello Electron React!</title>
+    <meta
+      charset="utf-8"
+      name="viewport"
+      content="width=device-width, initial-scale=1.0"
+    />
+    <title>MySQL Query Profiler</title>
     <link
       href="https://fonts.googleapis.com/css2?family=Raleway:wght@200;300;400;500;600;700&display=swap"
       rel="stylesheet"
diff --git a/app/components/Login.tsx b/app/components/Login.tsx
index 36166d56969e7b9f6a7cce80c76cafbfd2cfc41e..d8aa34fc491a7052f03d672196f730580560fd56 100644
--- a/app/components/Login.tsx
+++ b/app/components/Login.tsx
@@ -5,11 +5,11 @@ import {
   Paper,
   Typography,
   makeStyles,
+  LinearProgress,
 } from '@material-ui/core';
 import { useHistory, useLocation } from 'react-router';
 import clsx from 'clsx';
-import { SqlManagerContext } from '../context/SqlManagerContext';
-import SqlManager from '../../backend/recorder/SqlManager';
+import SqlManagerSingleton from '../../backend/recorder/SqlManagerSingleton';
 import { LoadingContext } from '../context/LoadingContext';
 import routes from '../routes';
 import { LoginDetailsContext } from '../context/LoginDetailsContext';
@@ -41,6 +41,13 @@ const useStyles = makeStyles((theme) => ({
     textAlign: 'center',
     marginBottom: theme.spacing(2),
   },
+  errorMessage: {
+    textAlign: 'center',
+    whiteSpace: 'pre-line',
+  },
+  progressBar: {
+    borderRadius: '2px',
+  },
 }));
 
 interface LoginProps {
@@ -52,7 +59,6 @@ const DefaultProps = {
 };
 
 export default function Login({ onConnect = undefined }: LoginProps) {
-  const sqlManagerContext = useContext(SqlManagerContext);
   const loadingContext = useContext(LoadingContext);
   const loginDetailsContext = useContext(LoginDetailsContext);
 
@@ -74,19 +80,17 @@ export default function Login({ onConnect = undefined }: LoginProps) {
   const [database, setDatabase] = useState(
     loginDetailsContext?.loginDetails?.database || ''
   );
+  const [connecting, setConnecting] = useState(false);
+  const [errorMessage, setErrorMessage] = useState('');
 
   async function handleConnectByLogin() {
-    let manager;
-    if (!sqlManagerContext?.sqlManager) {
-      manager = new SqlManager();
-      sqlManagerContext?.setSqlManager(manager);
-    } else {
-      manager = sqlManagerContext.sqlManager;
-    }
+    setConnecting(true);
+    const manager = SqlManagerSingleton.getInstance();
     try {
       loadingContext?.setConnected(false);
       loadingContext?.setConnecting(true);
       await manager.connect({ host, user, password, port }, database);
+      setErrorMessage('');
       loadingContext?.setConnecting(false);
       loadingContext?.setConnected(true);
 
@@ -98,12 +102,43 @@ export default function Login({ onConnect = undefined }: LoginProps) {
       }
     } catch (error) {
       console.error(error);
+      if (error?.info?.msg?.includes('Unknown database')) {
+        const newErrorMessage = `${error.info.msg.replace(
+          'Unknown',
+          'The'
+        )} does not exist on the chosen server`;
+        setErrorMessage(newErrorMessage);
+      } else if (String(error).includes('database was not passed')) {
+        setErrorMessage('There was no database to connect to');
+      } else if (
+        String(error).includes('EAI_AGAIN') ||
+        String(error).includes('ENOTFOUND')
+      ) {
+        setErrorMessage(`The host '${host}' could not be found`);
+      } else if (String(error).includes('Access denied')) {
+        setErrorMessage(`Wrong username or password, user: ${user}@${host}`);
+      } else if (String(error).includes('The server has gone away')) {
+        setErrorMessage(
+          `The server connection is not using the X Protocol.
+          Make sure you are connecting to the correct port and using a MySQL 5.7.12 (or higher) server instance.
+          Default port for X Protocol servers is 33060`
+        );
+      } else {
+        setErrorMessage('Failed to connect');
+      }
       loadingContext?.setConnecting(false);
       loadingContext?.setConnected(false);
+
+      setConnecting(false);
+    }
+  }
+
+  function handleKeyUp(e: { key: string }) {
+    if (e.key === 'Enter') {
+      handleConnectByLogin();
     }
   }
 
-  // TODO: Show connection indicator (spinning circle)
   // TODO: Show result of connection (success/failure)
 
   const classes = useStyles();
@@ -116,11 +151,13 @@ export default function Login({ onConnect = undefined }: LoginProps) {
         </Typography>
         <div className={clsx(classes.content, classes.element)}>
           <TextField
+            autoFocus
             className={classes.element}
             variant="filled"
             label="Host"
             value={host}
             onChange={(event) => setHost(event.target.value)}
+            onKeyUp={handleKeyUp}
           />
           <TextField
             className={classes.element}
@@ -128,6 +165,7 @@ export default function Login({ onConnect = undefined }: LoginProps) {
             label="User"
             value={user}
             onChange={(event) => setUser(event.target.value)}
+            onKeyUp={handleKeyUp}
           />
           <TextField
             className={classes.element}
@@ -136,6 +174,7 @@ export default function Login({ onConnect = undefined }: LoginProps) {
             type="password"
             value={password}
             onChange={(event) => setPassword(event.target.value)}
+            onKeyUp={handleKeyUp}
           />
           <TextField
             className={classes.element}
@@ -143,6 +182,7 @@ export default function Login({ onConnect = undefined }: LoginProps) {
             label="Port"
             value={port}
             onChange={(event) => setPort(Number(event.target.value))}
+            onKeyUp={handleKeyUp}
           />
           <TextField
             className={classes.element}
@@ -150,9 +190,19 @@ export default function Login({ onConnect = undefined }: LoginProps) {
             label="Database"
             value={database}
             onChange={(event) => setDatabase(event.target.value)}
+            onKeyUp={handleKeyUp}
           />
         </div>
+        {!!errorMessage && (
+          <Typography
+            color="error"
+            className={clsx(classes.element, classes.errorMessage)}
+          >
+            {errorMessage}
+          </Typography>
+        )}
         <Button
+          className={classes.element}
           type="button"
           variant="contained"
           color="primary"
@@ -160,6 +210,11 @@ export default function Login({ onConnect = undefined }: LoginProps) {
         >
           Connect
         </Button>
+        <LinearProgress
+          hidden={!connecting}
+          className={clsx(classes.element, classes.progressBar)}
+          color="primary"
+        />
       </Paper>
     </div>
   );
diff --git a/app/components/MemoryChart.tsx b/app/components/MemoryChart.tsx
index b86754e32784aec62ff5d75a1ba5c14ff7a3d861..0d19382f39abeff45394b9e3ebbf4a3314b8fa1e 100644
--- a/app/components/MemoryChart.tsx
+++ b/app/components/MemoryChart.tsx
@@ -1,4 +1,5 @@
-import React, { useState, ReactElement, ReactNode } from 'react';
+import _ from 'lodash';
+import React, { useState, useContext } from 'react';
 import {
   Legend,
   LineChart,
@@ -10,11 +11,10 @@ import {
   ResponsiveContainer,
   Surface,
   Symbols,
-  ContentRenderer,
-  LegendProps,
+  ReferenceLine,
+  Label,
 } from 'recharts';
-import _ from 'lodash';
-import { MemoryPerformance } from '../../backend/data-processor/DataProcessor';
+import { RecordingContext } from '../context/RecordingContext';
 
 interface Payload {
   value: string;
@@ -23,38 +23,47 @@ interface Payload {
   color: string;
 }
 
-const chartDataMock: MemoryPerformance = [
-  { relative_time: 0, geom: 0, total: 235378 },
-  { relative_time: 1, geom: 0, total: 263058 },
-  { relative_time: 2, geom: 0, total: 263058 },
-  { relative_time: 3, geom: 265, total: 263371 },
-  { relative_time: 4, geom: 265, total: 263371 },
-  { relative_time: 5, geom: 387, total: 263493 },
-  { relative_time: 6, geom: 3267, total: 266373 },
-  { relative_time: 7, geom: 3267, total: 266373 },
-  { relative_time: 8, geom: 32067, total: 295173 },
-  { relative_time: 9, geom: 32067, total: 295173 },
-  { relative_time: 10, geom: 256503, total: 519609 },
-  { relative_time: 11, geom: 320067, total: 726837 },
-  { relative_time: 12, geom: 320067, total: 726837 },
-  { relative_time: 13, geom: 1349729, total: 1756499 },
-  { relative_time: 14, geom: 1442129, total: 1848899 },
-  { relative_time: 15, geom: 1785089, total: 2191859 },
-  { relative_time: 16, geom: 1980689, total: 2387459 },
-  { relative_time: 17, geom: 1164423, total: 1571193 },
-  { relative_time: 18, geom: 1418583, total: 1825353 },
-  { relative_time: 19, geom: 1589703, total: 1996473 },
-  { relative_time: 20, geom: 0, total: 216938 },
-];
+interface ChartColors {
+  [key: string]: string;
+}
 
 export default function MemoryChart() {
   const [disabled, setDisabled] = useState<Array<string>>([]);
-  const [chartData, setChartData] = useState<MemoryPerformance>(chartDataMock);
-  const [chartColors, setChartColors] = useState({
-    geom: '#8884d8',
-    total: '#82ca9d',
-  });
+  const [chartColors, setChartColors] = useState({ total: '#82ca9d' });
+  const validStages = [
+    'stage/sql/preparing',
+    'stage/sql/optimizing',
+    'stage/sql/executing',
+    'stage/sql/end',
+  ];
+
+  const recordingContext = useContext(RecordingContext);
+  const stageTimes = recordingContext?.stageTimes;
+  const chartData = recordingContext?.chartData;
+
+  function getColor() {
+    return `#${(0x1000000 + Math.random() * 0xffffff)
+      .toString(16)
+      .substr(1, 6)}`;
+  }
+
+  function assignColor(key: string) {
+    const tempObject: ChartColors = {};
+    tempObject[key] = getColor();
+    return tempObject;
+  }
+
+  if (chartData && _.keys(chartColors).length === 1) {
+    const dataKeys = _.keys(chartData[0]).slice(1);
+    _.forEach(dataKeys, (key) => _.assign(chartColors, assignColor(key)));
+  }
+
+  function getMaxTime() {
+    // eslint-disable-next-line prefer-spread
+    return Math.max.apply(Math, _.map(chartData, 'relative_time'));
+  }
 
+  // When a legend is clicked the datakey is added to the disabled list, which will remove it form the line chart
   function handleClick(dataKey: string) {
     if (_.includes(disabled, dataKey)) {
       setDisabled(disabled.filter((obj) => obj !== dataKey));
@@ -63,9 +72,7 @@ export default function MemoryChart() {
     }
   }
 
-  function renderCustomizedLegend(props: {
-    payload: Array<Payload>;
-  }): ReactNode {
+  function renderCustomizedLegend(props: { payload: Array<Payload> }) {
     const { payload } = props;
     return (
       <div className="customized-legend">
@@ -85,14 +92,13 @@ export default function MemoryChart() {
               style={style}
               key={value}
             >
-              {/* viewBox="0 0 10 10" */}
               <Surface width={10} height={10}>
                 <Symbols cx={5} cy={5} type="circle" size={50} fill={color} />
                 {active && (
                   <Symbols cx={5} cy={5} type="circle" size={25} fill="#FFF" />
                 )}
               </Surface>
-              <span>{value}</span>
+              <span style={{ color: '#FFF' }}>{value}</span>
             </span>
           );
         })}
@@ -100,6 +106,16 @@ export default function MemoryChart() {
     );
   }
 
+  function formatBytes(byte: number) {
+    if (Math.abs(byte) > 10000000) {
+      return `${Math.floor(byte / 1024 / 1024)} MB`;
+    }
+    if (Math.abs(byte) > 10000) {
+      return `${Math.floor(byte / 1024)} KB`;
+    }
+    return `${Math.floor(byte)} B`;
+  }
+
   return (
     <div className="highlight-bar-charts">
       <ResponsiveContainer height={400}>
@@ -110,13 +126,27 @@ export default function MemoryChart() {
           margin={{ top: 20, right: 30, left: 20, bottom: 5 }}
         >
           <CartesianGrid strokeDasharray="3 10" />
-          <XAxis dataKey="relative_time" />
-          <YAxis />
-          <Tooltip />
+          {/* TODO: Create our own Axis tick component like this: http://recharts.org/en-US/examples/CustomizedLabelLineChart */}
+          <XAxis
+            dataKey="relative_time"
+            type="number"
+            tick={{ stroke: '#FFFFFF', strokeWidth: '0.5px' }}
+            domain={[0, getMaxTime()]}
+            tickCount={20}
+          />
+          <YAxis
+            type="number"
+            tickFormatter={formatBytes}
+            tick={{ stroke: '#FFFFFF', strokeWidth: '0.5px' }}
+          />
+          <Tooltip
+            formatter={(value) => formatBytes(Number(value))}
+            offset={100}
+          />
           <Legend
             verticalAlign="bottom"
             height={36}
-            align="left"
+            align="center"
             payload={_.toPairs(chartColors).map((pair, i) => ({
               value: pair[0],
               id: i,
@@ -125,6 +155,9 @@ export default function MemoryChart() {
             }))}
             content={renderCustomizedLegend}
           />
+
+          {/* Creates an array from the key:value pairs in chartColors.
+           The keys that are not disabled becomes a line */}
           {_.toPairs(chartColors)
             .filter((pair) => !_.includes(disabled, pair[0]))
             .map((pair) => (
@@ -133,8 +166,27 @@ export default function MemoryChart() {
                 dataKey={pair[0]}
                 key={pair[0]}
                 stroke={pair[1]}
+                dot={false}
               />
             ))}
+          {/* Filters stageTimes to only include stages that are in validStages and only the first instance of them.
+          Then creates reference lines from the data that remains */}
+
+          {_.forEach(_.uniqBy(stageTimes, 'stage'))
+            ?.filter((stage) => _.includes(validStages, stage.stage))
+            ?.map((item) => (
+              <ReferenceLine
+                x={item.startTime}
+                stroke="#769CFF"
+                key={_.uniqueId('ref_')}
+              >
+                <Label
+                  value={item.stage}
+                  position="top"
+                  style={{ color: '#FFFFFF' }}
+                />
+              </ReferenceLine>
+            ))}
         </LineChart>
       </ResponsiveContainer>
     </div>
diff --git a/app/components/OptimizerTrace.tsx b/app/components/OptimizerTrace.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..cb2f869e48bb67e5f11a4768dc369b8ab2919b4c
--- /dev/null
+++ b/app/components/OptimizerTrace.tsx
@@ -0,0 +1,21 @@
+import React, { useContext } from 'react';
+import ReactJson from 'react-json-view';
+import { RecordingContext } from '../context/RecordingContext';
+
+export default function OptimizerTrace() {
+  const recordingContext = useContext(RecordingContext);
+  const optimizerTrace = recordingContext?.optimizerTrace;
+  return (
+    <div>
+      {optimizerTrace && (
+        <ReactJson
+          src={optimizerTrace}
+          theme="twilight"
+          name="OptimizerTrace"
+          collapsed={5}
+          indentWidth={2}
+        />
+      )}
+    </div>
+  );
+}
diff --git a/app/components/QueryRecorder.tsx b/app/components/QueryRecorder.tsx
index 6aaa0a3c635736dfce0dc78425060bad04671bad..1889d6e910f17e8e3eceef27ad52cd5b7b8457a2 100644
--- a/app/components/QueryRecorder.tsx
+++ b/app/components/QueryRecorder.tsx
@@ -1,3 +1,4 @@
+/* eslint-disable react/jsx-wrap-multilines */
 import React, { useState, useContext } from 'react';
 import { makeStyles } from '@material-ui/core/styles';
 import {
@@ -7,11 +8,12 @@ import {
   Typography,
   FormControlLabel,
   Checkbox,
+  CircularProgress,
 } from '@material-ui/core';
 import clsx from 'clsx';
-import { SqlManagerContext } from '../context/SqlManagerContext';
-import { DataProcessor } from '../../backend/data-processor/DataProcessor';
 import { RecordingContext } from '../context/RecordingContext';
+import ResultJson from './ResultJson';
+import SqlManagerSingleton from '../../backend/recorder/SqlManagerSingleton';
 
 const useStyles = makeStyles((theme) => ({
   container: {
@@ -32,7 +34,11 @@ const useStyles = makeStyles((theme) => ({
     display: 'flex',
     flexFlow: 'column nowrap',
     flexGrow: 1,
-    width: '600px',
+  },
+  recordButtonWrapper: {
+    display: 'flex',
+    flexFlow: 'row nowrap',
+    alignItems: 'center',
   },
   output: {
     userSelect: 'none',
@@ -44,13 +50,15 @@ const useStyles = makeStyles((theme) => ({
 
 export default function QueryRecorder() {
   const [changedQuery, setChangedQuery] = useState('');
-  const [output, setOutput] = useState<string>('');
+  const [output, setOutput] = useState('');
   const [explainAnalyze, setExplainAnalyze] = useState(false);
+  const [waitRecording, setWaitRecording] = useState(false);
 
-  const manager = useContext(SqlManagerContext)?.sqlManager;
+  const manager = SqlManagerSingleton.getInstance();
   const recordingContext = useContext(RecordingContext);
 
   async function record() {
+    setWaitRecording(true);
     if (!manager) {
       console.log('not connected');
       return;
@@ -58,34 +66,34 @@ export default function QueryRecorder() {
 
     try {
       const result = await manager.record(changedQuery, explainAnalyze);
-      console.log(result);
       if (result?.error) {
         console.log(`QueryRecorder: Result: ${result}`);
-        setOutput(JSON.stringify(result.error.info.msg, undefined, 2));
+        recordingContext?.setQueryOutput(result.result.error);
+        const errorcode = JSON.stringify(result.error.info.code, undefined, 2);
+        const errormsg = JSON.stringify(result.error.info.msg, undefined, 2);
+        setOutput(`Errorcode: ${errorcode}\n${errormsg}`);
       } else {
+        recordingContext?.setQueryOutput(result.result);
         setOutput(JSON.stringify(result?.result, undefined, 2));
-        const memoryPerformance = DataProcessor.processMemoryPerformance(
-          result.memoryPerformance
-        );
-        recordingContext?.setMemoryPerformance(memoryPerformance);
+        recordingContext?.setOptimizerTrace(result.optimizerTrace);
+        recordingContext?.setChartData(result.memoryPerformance);
+        recordingContext?.setStageTimes(result.stageTimes);
       }
     } catch (error) {
       console.log(`QueryRecorder: Error: ${error}`);
+    } finally {
+      setWaitRecording(false);
     }
   }
 
-  async function doOptimizerQuery() {
-    if (!manager) {
-      console.log('not connected');
-      return;
+  const classes = useStyles();
+
+  function handleKeyUp(e: { key: string; ctrlKey: boolean }) {
+    if (e.key === 'Enter' && e.ctrlKey) {
+      record();
     }
-    const traceResult = await manager.executeWithTrace(changedQuery);
-    setOutput(JSON.stringify(traceResult.result, undefined, 2));
-    console.log(traceResult.trace);
   }
 
-  const classes = useStyles();
-
   return (
     <div className={classes.container}>
       <Paper className={classes.content} elevation={1}>
@@ -94,6 +102,7 @@ export default function QueryRecorder() {
         </div>
         <div className={clsx(classes.element, classes.input)}>
           <TextField
+            autoFocus
             multiline
             InputProps={{
               classes: {
@@ -106,12 +115,13 @@ export default function QueryRecorder() {
             rowsMax={10}
             value={changedQuery}
             onChange={(event) => setChangedQuery(event.target.value)}
+            onKeyUp={handleKeyUp}
+            helperText="Ctrl + Enter: Run"
           />
         </div>
         <div className={classes.element}>
           <FormControlLabel
             control={
-              // eslint-disable-next-line react/jsx-wrap-multilines
               <Checkbox
                 color="primary"
                 checked={explainAnalyze}
@@ -121,29 +131,25 @@ export default function QueryRecorder() {
             label="Explain analyze"
           />
         </div>
-        <div className={classes.element}>
-          <Button variant="contained" color="primary" onClick={() => record()}>
+        <div className={clsx(classes.element, classes.recordButtonWrapper)}>
+          <Button
+            disabled={waitRecording}
+            variant="contained"
+            color="primary"
+            onClick={() => record()}
+          >
             Record
           </Button>
-        </div>
-        <div className={classes.element}>
-          <Button variant="contained" onClick={() => doOptimizerQuery()}>
-            Optimizer
-          </Button>
+          {waitRecording && (
+            <CircularProgress
+              style={{ marginLeft: '16px' }}
+              size="24px"
+              color="primary"
+            />
+          )}
         </div>
         <div className={clsx(classes.element, classes.input)}>
-          <TextField
-            className={classes.output}
-            InputProps={{
-              classes: {
-                input: classes.code,
-              },
-            }}
-            multiline
-            rows={10}
-            variant="outlined"
-            value={output}
-          />
+          <ResultJson result={output} />
         </div>
       </Paper>
     </div>
diff --git a/app/components/ResultJson.tsx b/app/components/ResultJson.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..9cdb8ebb1f3c72ba951a1f46bc2a3d59bb621418
--- /dev/null
+++ b/app/components/ResultJson.tsx
@@ -0,0 +1,57 @@
+import React from 'react';
+import { makeStyles } from '@material-ui/core/styles';
+import { TextField } from '@material-ui/core';
+import clsx from 'clsx';
+
+interface TResultProps {
+  result: string;
+}
+
+const useStyles = makeStyles((theme) => ({
+  container: {
+    maxWidth: 600 + theme.spacing(4),
+  },
+  content: {
+    display: 'flex',
+    flexFlow: 'column nowrap',
+    paddingTop: theme.spacing(1),
+    paddingBottom: theme.spacing(1),
+    paddingLeft: theme.spacing(2),
+    paddingRight: theme.spacing(2),
+  },
+  element: {
+    marginBottom: theme.spacing(1),
+  },
+  input: {
+    display: 'flex',
+    flexFlow: 'column nowrap',
+    flexGrow: 1,
+  },
+  result: {
+    userSelect: 'none',
+  },
+  code: {
+    fontFamily: 'Roboto Mono !important',
+  },
+}));
+
+export default function ResultJson(props: TResultProps) {
+  const classes = useStyles();
+  const { result } = props;
+  return (
+    <div className={clsx(classes.element, classes.input)}>
+      <TextField
+        className={classes.result}
+        InputProps={{
+          classes: {
+            input: classes.code,
+          },
+        }}
+        multiline
+        rows={10}
+        variant="outlined"
+        value={result}
+      />
+    </div>
+  );
+}
diff --git a/app/components/ResultTable.tsx b/app/components/ResultTable.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..90a9675ca10cd8cbdb7418eca66bfe2ef01af666
--- /dev/null
+++ b/app/components/ResultTable.tsx
@@ -0,0 +1,111 @@
+/* eslint-disable prefer-template */
+import React, { useContext } from 'react';
+import {
+  makeStyles,
+  withStyles,
+  createStyles,
+  Theme,
+} from '@material-ui/core/styles';
+import Table from '@material-ui/core/Table';
+import TableBody from '@material-ui/core/TableBody';
+import TableCell from '@material-ui/core/TableCell';
+import TableContainer from '@material-ui/core/TableContainer';
+import TableHead from '@material-ui/core/TableHead';
+import TableRow from '@material-ui/core/TableRow';
+import Paper from '@material-ui/core/Paper';
+import { ResultValue } from '@mysql/xdevapi';
+import { RecordingContext } from '../context/RecordingContext';
+
+// interface TResultProps {
+//   result: TResult | undefined;
+// }
+
+const useStyles = makeStyles({
+  table: {
+    minWidth: 650,
+  },
+  container: {
+    maxHeight: 211,
+  },
+});
+
+const StyledTableCell = withStyles((theme: Theme) =>
+  createStyles({
+    head: {
+      backgroundColor: '#404040',
+      color: theme.palette.common.white,
+    },
+    body: {
+      fontSize: 14,
+    },
+  })
+)(TableCell);
+
+export default function ResultTable() {
+  const recordingContext = useContext(RecordingContext);
+
+  const classes = useStyles();
+
+  const result = recordingContext?.queryOutput;
+
+  const tableHeader: string[] | undefined = result?.results?.labels;
+  const tableBody: ResultValue[][] | undefined = result?.results?.values;
+  const types: number[] | undefined = result?.results?.types;
+
+  function formatDate(d: Date) {
+    let month = '' + (d.getMonth() + 1);
+    let day = '' + d.getDate();
+    const year = d.getFullYear();
+
+    if (month.length < 2) month = '0' + month;
+    if (day.length < 2) day = '0' + day;
+
+    return [year, month, day].join('-');
+  }
+
+  function format(index: number, entry: any): string {
+    let datatype = 0;
+    if (types) {
+      datatype = types[index];
+    }
+    if (datatype === 12) {
+      if (typeof entry === 'number') {
+        const date = new Date(entry);
+        return formatDate(date);
+      }
+      const date = new Date(entry);
+      return formatDate(date);
+    }
+    return entry;
+  }
+
+  return (
+    <TableContainer className={classes.container} component={Paper}>
+      <Table className={classes.table} aria-label="simple table" stickyHeader>
+        <TableHead>
+          <TableRow>
+            {tableHeader?.map((column) => (
+              <StyledTableCell key={column}>{column}</StyledTableCell>
+            ))}
+          </TableRow>
+        </TableHead>
+        <TableBody>
+          {tableBody?.map((row) => (
+            <TableRow key={row.join('-')}>
+              {row.map((cell) => (
+                <TableCell
+                  key={tableBody
+                    .indexOf(row)
+                    .toString()
+                    .concat(row.indexOf(cell).toString())}
+                >
+                  {format(row.indexOf(cell), cell)}
+                </TableCell>
+              ))}
+            </TableRow>
+          ))}
+        </TableBody>
+      </Table>
+    </TableContainer>
+  );
+}
diff --git a/app/components/TreeViewExplainAnalyze.tsx b/app/components/TreeViewExplainAnalyze.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..55261710a27b8893050683a83ee0b01ff94de916
--- /dev/null
+++ b/app/components/TreeViewExplainAnalyze.tsx
@@ -0,0 +1,135 @@
+import React, { useContext, useState } from 'react';
+import { makeStyles } from '@material-ui/core/styles';
+import TreeView from '@material-ui/lab/TreeView';
+import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
+import ChevronRightIcon from '@material-ui/icons/ChevronRight';
+import TreeItem from '@material-ui/lab/TreeItem';
+import { RecordingContext } from '../context/RecordingContext';
+
+interface Node {
+  id: string;
+  offset: number;
+  command: string;
+  cost_est?: number;
+  rows_est?: number;
+  time: string;
+  rows: number;
+  loops: number;
+  children: Node[];
+}
+
+const rootNode: Node = {
+  id: '0',
+  offset: -1,
+  command: '',
+  time: '',
+  rows: -1,
+  loops: -1,
+  children: [],
+};
+
+const useStyles = makeStyles({
+  root: {
+    flexGrow: 1,
+  },
+});
+
+/*
+  Helper function
+  INPUT: EXPLAIN ANALYZE data (string)
+  RETURN: List of Node objects
+ */
+function extractData(data: string) {
+  rootNode.children = [];
+  const regexp = /([ ]*)?-> (.+?)( \(cost=([\d.]+) rows=(\d+)\))? \(actual time=([\d.]+) rows=(\d+) loops=(\d+)\)/gm;
+  const matches = [...data.matchAll(regexp)];
+  const nodes: Node[] = [rootNode];
+  // Create object for each line. Root has ID 0
+  let idIterator = 1;
+  matches.forEach((element) => {
+    const node: Node = {
+      id: idIterator.toString(),
+      offset: element[1] === undefined ? 0 : element[1].length,
+      command: element[2],
+      cost_est: Number(element[4]),
+      rows_est: Number(element[5]),
+      time: element[6],
+      rows: Number(element[7]),
+      loops: Number(element[8]),
+      children: [],
+    };
+    nodes.push(node);
+    idIterator += 1;
+  });
+  return nodes;
+}
+
+/*
+  INPUT: EXPLAIN ANALYZE data
+  ACTION: Assigns children of root node, and to all child nodes, based on offset and order
+  RETURN: List of Node objects
+*/
+function buildTree(explainAnalyzeData: string) {
+  // Extract relevant data
+  const nodes: Node[] = extractData(explainAnalyzeData);
+  // Assign children of each object
+  // Iterate through all objects
+  for (let i = 1; i < nodes.length; i += 1) {
+    // Set current node as child if its offset is smaller
+    if (nodes[i - 1].offset < nodes[i].offset) {
+      nodes[i - 1].children.push(nodes[i]);
+    } else {
+      // If current node's offset is smaller then it cannot be child of the previous node
+      // Iterate backwards from current node until a node with smaller offset has been reached
+      for (let j = i - 1; i > 0; j -= 1) {
+        if (nodes[j].offset < nodes[i].offset) {
+          nodes[j].children.push(nodes[i]);
+          break;
+        }
+      }
+    }
+  }
+}
+
+export default function RecursiveTreeView() {
+  const recordingContext = useContext(RecordingContext);
+
+  const classes = useStyles();
+  const [previousData, setPreviousData] = useState('');
+  const data = JSON.stringify(recordingContext?.queryOutput, undefined, 2);
+  if (!data) return null;
+  // TODO: Only run when EXPLAIN ANALYZE detected
+  if (data !== previousData) {
+    buildTree(data);
+    setPreviousData(data);
+  }
+
+  const RenderTree = (nodes: Node) => (
+    <TreeItem key={nodes.id} nodeId={nodes.id} label={nodes.command}>
+      {Array.isArray(nodes.children)
+        ? nodes.children.map((node) => RenderTree(node))
+        : null}
+    </TreeItem>
+  );
+
+  const RenderTreeWithoutRoot = (root: Node) => {
+    // Renders only the children of root
+    const elements: JSX.Element[] = [];
+    root.children.forEach((child) => {
+      elements.push(RenderTree(child));
+    });
+    return elements;
+  };
+
+  // TODO: Find dynamic solution to defaultExpanded
+  return (
+    <TreeView
+      className={classes.root}
+      defaultCollapseIcon={<ExpandMoreIcon />}
+      defaultExpanded={['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10']}
+      defaultExpandIcon={<ChevronRightIcon />}
+    >
+      {[RenderTreeWithoutRoot(rootNode)]}
+    </TreeView>
+  );
+}
diff --git a/app/containers/Dashboard.tsx b/app/containers/Dashboard.tsx
index 302cd0eb802fbf5ba858d36b460f05bc1234512b..9142121b71a68a3ae4be50c081f08d8dcca83271 100644
--- a/app/containers/Dashboard.tsx
+++ b/app/containers/Dashboard.tsx
@@ -1,13 +1,31 @@
 import React, { useContext, useState } from 'react';
-import { Button, Dialog } from '@material-ui/core';
+import { Button, Dialog, makeStyles } from '@material-ui/core';
 import { useLocation, useHistory } from 'react-router';
+import PanelGroup from 'react-panelgroup';
 import QueryRecorder from '../components/QueryRecorder';
 import { LoadingContext } from '../context/LoadingContext';
 import routes from '../routes';
 import Login from '../components/Login';
 import { LoginDetailsContext } from '../context/LoginDetailsContext';
 import { RecordingProvider } from '../context/RecordingContext';
-import MemoryChart from '../components/MemoryChart';
+import ResultView from './ResultView';
+
+const useStyles = makeStyles((theme) => ({
+  wrapper: {
+    minHeight: '100%',
+    height: '100%',
+    maxHeight: '100vh',
+  },
+  column: {
+    display: 'flex',
+    flexFlow: 'column nowrap',
+    maxHeight: '98vh',
+    height: '100%',
+    padding: `${theme.spacing(1)}px ${theme.spacing(2)}px`,
+    width: '100%',
+    overflowY: 'auto',
+  },
+}));
 
 export default function Dashboard() {
   const [changeConnectionOpen, setChangeConnectionOpen] = useState(false);
@@ -32,26 +50,41 @@ export default function Dashboard() {
     setChangeConnectionOpen(true);
   }
 
+  const classes = useStyles();
+
   return (
-    <div>
-      <div>
-        <Button
-          variant="outlined"
-          color="primary"
-          onClick={() => openConnectionDialog()}
-        >
-          Change connection
-        </Button>
-        <Dialog
-          open={changeConnectionOpen}
-          onClose={() => setChangeConnectionOpen(false)}
-        >
-          <Login onConnect={() => setChangeConnectionOpen(false)} />
-        </Dialog>
-      </div>
+    <div className={classes.wrapper}>
       <RecordingProvider>
-        <QueryRecorder />
-        <MemoryChart />
+        <PanelGroup
+          borderColor="#4B4B4B"
+          spacing={16}
+          panelWidths={[
+            { minSize: 200, size: 700, resize: 'dynamic' },
+            { minSize: 200, resize: 'dynamic' },
+          ]}
+        >
+          <div className={classes.column}>
+            <div>
+              <Button
+                variant="outlined"
+                color="primary"
+                onClick={() => openConnectionDialog()}
+              >
+                Change connection
+              </Button>
+              <Dialog
+                open={changeConnectionOpen}
+                onClose={() => setChangeConnectionOpen(false)}
+              >
+                <Login onConnect={() => setChangeConnectionOpen(false)} />
+              </Dialog>
+            </div>
+            <QueryRecorder />
+          </div>
+          <div className={classes.column}>
+            <ResultView />
+          </div>
+        </PanelGroup>
       </RecordingProvider>
     </div>
   );
diff --git a/app/containers/LoginScreen.tsx b/app/containers/LoginScreen.tsx
index 5522ff0095ef59407d10e8f33452b4aba351af0f..fe128ae2dec5206c4fd29c3ca7accc2d3a7e92b7 100644
--- a/app/containers/LoginScreen.tsx
+++ b/app/containers/LoginScreen.tsx
@@ -1,7 +1,7 @@
 import React, { useEffect, useState, useContext } from 'react';
 import { Typography, makeStyles } from '@material-ui/core';
 import Login from '../components/Login';
-import { loadLoginDetails } from '../../backend/utils/fileutils';
+import FileIO from '../../backend/utils/FileIO';
 import { LoginDetailsContext } from '../context/LoginDetailsContext';
 
 const useStyles = makeStyles((theme) => ({
@@ -14,10 +14,10 @@ const useStyles = makeStyles((theme) => ({
     flexFlow: 'column nowrap',
     alignItems: 'center',
     justifyContent: 'space-between',
-    padding: `${theme.spacing(8)}px ${theme.spacing(16)}px`,
+    padding: `${theme.spacing(6)}px ${theme.spacing(16)}px`,
   },
   title: {
-    marginBottom: theme.spacing(8),
+    marginBottom: theme.spacing(6),
     textAlign: 'center',
   },
 }));
@@ -28,7 +28,7 @@ export default function LoginScreen() {
   const loginDetailsContext = useContext(LoginDetailsContext);
 
   useEffect(() => {
-    loadLoginDetails()
+    FileIO.loadLoginDetails()
       .then((response) => {
         if (response) {
           loginDetailsContext?.setLoginDetails(response);
@@ -37,7 +37,6 @@ export default function LoginScreen() {
         return true;
       })
       .catch((error) => console.error(error));
-    // eslint-disable-next-line react-hooks/exhaustive-deps
   }, []);
 
   const classes = useStyles();
@@ -46,7 +45,7 @@ export default function LoginScreen() {
     <div className={classes.wrapper}>
       {!loading && (
         <div className={classes.content}>
-          <Typography className={classes.title} variant="h2">
+          <Typography className={classes.title} variant="h3">
             Welcome to MySQL query profiler!
           </Typography>
           <Login />
diff --git a/app/containers/ResultView.tsx b/app/containers/ResultView.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..27a909d41af83256334fd2ceec7e67d6d61b8ac2
--- /dev/null
+++ b/app/containers/ResultView.tsx
@@ -0,0 +1,105 @@
+/* eslint-disable react/jsx-wrap-multilines */
+import {
+  makeStyles,
+  Checkbox,
+  FormControlLabel,
+  Paper,
+} from '@material-ui/core';
+import React, { useContext, useState } from 'react';
+import MemoryChart from '../components/MemoryChart';
+import OptimizerTrace from '../components/OptimizerTrace';
+import ResultTable from '../components/ResultTable';
+import { RecordingContext } from '../context/RecordingContext';
+import TreeViewExplainAnalyze from '../components/TreeViewExplainAnalyze';
+
+const useStyles = makeStyles((theme) => ({
+  wrapper: {
+    display: 'flex',
+    flexFlow: 'column nowrap',
+    alignContent: 'center',
+  },
+  item: {
+    margin: `${theme.spacing(1)}px ${theme.spacing(0)}`,
+  },
+}));
+
+export default function ResultView() {
+  const [showMemoryChart, setShowMemoryChart] = useState(true);
+  const [showOptimizerTrace, setShowOptimizerTrace] = useState(false);
+  const [showResultTable, setShowResultTable] = useState(false);
+  const [showExplainAnalyze, setShowExplainAnalyze] = useState(false);
+
+  const recordingContext = useContext(RecordingContext);
+
+  const classes = useStyles();
+
+  return (
+    <div className={classes.wrapper} style={{ minWidth: '200px' }}>
+      <div>
+        <FormControlLabel
+          label="Show result table"
+          control={
+            <Checkbox
+              color="primary"
+              checked={showResultTable}
+              onChange={(event) => setShowResultTable(event.target.checked)}
+            />
+          }
+        />
+        <FormControlLabel
+          label="Show memory chart"
+          control={
+            <Checkbox
+              color="primary"
+              checked={showMemoryChart}
+              onChange={(event) => setShowMemoryChart(event.target.checked)}
+            />
+          }
+        />
+        <FormControlLabel
+          label="Show optimizer trace"
+          control={
+            <Checkbox
+              color="primary"
+              checked={showOptimizerTrace}
+              onChange={(event) => setShowOptimizerTrace(event.target.checked)}
+            />
+          }
+        />
+        <FormControlLabel
+          label="Show explain analyze"
+          control={
+            <Checkbox
+              color="primary"
+              checked={showExplainAnalyze}
+              onChange={(event) => setShowExplainAnalyze(event.target.checked)}
+            />
+          }
+        />
+      </div>
+      {showResultTable && (
+        <Paper className={classes.item}>
+          <ResultTable />
+        </Paper>
+      )}
+      {showMemoryChart && (
+        <Paper
+          className={classes.item}
+          style={{ paddingBottom: 80, paddingTop: 8 }}
+        >
+          <MemoryChart />
+        </Paper>
+      )}
+      {showOptimizerTrace && recordingContext?.optimizerTrace && (
+        <Paper className={classes.item} style={{ padding: 8 }}>
+          <OptimizerTrace />
+        </Paper>
+      )}
+      {showExplainAnalyze && (
+        <Paper className={classes.item}>
+          <TreeViewExplainAnalyze />
+        </Paper>
+      )}
+    </div>
+  );
+}
diff --git a/app/context/RecordingContext.tsx b/app/context/RecordingContext.tsx
index 66ec853091b5f8790aa4bb6a0ec9ce25146774d0..b64e3d9f270ed8054b8cff117755305a77f30b5a 100644
--- a/app/context/RecordingContext.tsx
+++ b/app/context/RecordingContext.tsx
@@ -1,13 +1,24 @@
+import { ResultValue } from '@mysql/xdevapi';
 import React, { useState, createContext } from 'react';
-import { MemoryPerformance } from '../../backend/data-processor/DataProcessor';
+import {
+  ChartData,
+  StageTimes,
+} from '../../backend/data-processor/DataProcessor';
+import { QueryOutput } from '../QueryOutput';
 
 type ChildrenType = {
   children: React.ReactNode;
 };
 
 type ContextType = {
-  memoryPerformance: MemoryPerformance | undefined;
-  setMemoryPerformance: (value: MemoryPerformance | undefined) => void;
+  chartData: ChartData | undefined;
+  setChartData: (value: ChartData | undefined) => void;
+  stageTimes: StageTimes | undefined;
+  setStageTimes: (value: StageTimes | undefined) => void;
+  optimizerTrace: ResultValue[][] | undefined;
+  setOptimizerTrace: (value: ResultValue[][] | undefined) => void;
+  queryOutput: QueryOutput | undefined;
+  setQueryOutput: (value: QueryOutput | undefined) => void;
 };
 
 export const RecordingContext = createContext<ContextType | undefined>(
@@ -15,12 +26,28 @@ export const RecordingContext = createContext<ContextType | undefined>(
 );
 
 export const RecordingProvider = ({ children }: ChildrenType) => {
-  const [memoryPerformance, setMemoryPerformance] = useState<
-    MemoryPerformance | undefined
+  const [chartData, setChartData] = useState<ChartData | undefined>(undefined);
+  const [stageTimes, setStageTimes] = useState<StageTimes | undefined>(
+    undefined
+  );
+  const [optimizerTrace, setOptimizerTrace] = useState<
+    ResultValue[][] | undefined
   >(undefined);
+  const [queryOutput, setQueryOutput] = useState<QueryOutput | undefined>(
+    undefined
+  );
   return (
     <RecordingContext.Provider
-      value={{ memoryPerformance, setMemoryPerformance }}
+      value={{
+        chartData,
+        setChartData,
+        stageTimes,
+        setStageTimes,
+        optimizerTrace,
+        setOptimizerTrace,
+        queryOutput,
+        setQueryOutput,
+      }}
     >
       {children}
     </RecordingContext.Provider>
diff --git a/app/context/SqlManagerContext.tsx b/app/context/SqlManagerContext.tsx
deleted file mode 100644
index 486baf6cf1c89ac445f237b479942b4cc7019d8d..0000000000000000000000000000000000000000
--- a/app/context/SqlManagerContext.tsx
+++ /dev/null
@@ -1,26 +0,0 @@
-import React, { useState, createContext } from 'react';
-import SqlManager from '../../backend/recorder/SqlManager';
-
-type ChildrenType = {
-  children: React.ReactNode;
-};
-
-type ContextType = {
-  sqlManager: SqlManager | undefined;
-  setSqlManager: (value: SqlManager | undefined) => void;
-};
-
-export const SqlManagerContext = createContext<ContextType | undefined>(
-  undefined
-);
-
-export const SqlManagerProvider = ({ children }: ChildrenType) => {
-  const [sqlManager, setSqlManager] = useState<SqlManager | undefined>(
-    undefined
-  );
-  return (
-    <SqlManagerContext.Provider value={{ sqlManager, setSqlManager }}>
-      {children}
-    </SqlManagerContext.Provider>
-  );
-};
diff --git a/app/main.dev.ts b/app/main.dev.ts
index 63b86d851e970aedee61d230ac45d5a5c4eb1944..28d4d12c5feee2d2d05a9bce195e6fc1c4dbf38c 100644
--- a/app/main.dev.ts
+++ b/app/main.dev.ts
@@ -1,3 +1,4 @@
+/* eslint-disable compat/compat */
 /* eslint global-require: off, no-console: off */
 
 /**
@@ -10,12 +11,16 @@
  */
 import 'core-js/stable';
 import 'regenerator-runtime/runtime';
-import path from 'path';
 import { app, BrowserWindow } from 'electron';
 import { autoUpdater } from 'electron-updater';
 import log from 'electron-log';
+// import installExtension, {
+//   REACT_DEVELOPER_TOOLS,
+// } from 'electron-devtools-installer';
 import MenuBuilder from './menu';
 
+// app.allowRendererProcessReuse = true;
+
 export default class AppUpdater {
   constructor() {
     log.transports.file.level = 'info';
@@ -31,52 +36,42 @@ if (process.env.NODE_ENV === 'production') {
   sourceMapSupport.install();
 }
 
-if (
-  process.env.NODE_ENV === 'development' ||
-  process.env.DEBUG_PROD === 'true'
-) {
-  require('electron-debug')();
-}
+// if (
+//   process.env.NODE_ENV === 'development' ||
+//   process.env.DEBUG_PROD === 'true'
+// ) {
+//   require('electron-debug')();
+// }
 
-const installExtensions = async () => {
-  const installer = require('electron-devtools-installer');
-  const forceDownload = !!process.env.UPGRADE_EXTENSIONS;
-  const extensions = ['REACT_DEVELOPER_TOOLS', 'REDUX_DEVTOOLS'];
+// const installExtensions = async () => {
+//   const forceDownload = !!process.env.UPGRADE_EXTENSIONS;
+//   const extensions = [REACT_DEVELOPER_TOOLS];
 
-  return Promise.all(
-    extensions.map((name) => installer.default(installer[name], forceDownload))
-  ).catch(console.log);
-};
+//   return Promise.all(
+//     extensions.map((name) => installExtension(name, forceDownload))
+//   ).catch(console.log);
+// };
 
 const createWindow = async () => {
-  if (
-    process.env.NODE_ENV === 'development' ||
-    process.env.DEBUG_PROD === 'true'
-  ) {
-    await installExtensions();
-  }
+  // if (
+  //   process.env.NODE_ENV === 'development' ||
+  //   process.env.DEBUG_PROD === 'true'
+  // ) {
+  //   await installExtensions();
+  // }
 
   mainWindow = new BrowserWindow({
     show: false,
     width: 1080,
     height: 900,
-    webPreferences:
-      (process.env.NODE_ENV === 'development' ||
-        process.env.E2E_BUILD === 'true') &&
-      process.env.ERB_SECURE !== 'true'
-        ? {
-            nodeIntegration: true,
-          }
-        : {
-            preload: path.join(__dirname, 'dist/renderer.prod.js'),
-          },
+    webPreferences: {
+      nodeIntegration: true,
+    },
   });
 
   mainWindow.loadURL(`file://${__dirname}/app.html`);
 
-  // @TODO: Use 'ready-to-show' event
-  //        https://github.com/electron/electron/blob/master/docs/api/browser-window.md#using-ready-to-show-event
-  mainWindow.webContents.on('did-finish-load', () => {
+  mainWindow.once('ready-to-show', () => {
     if (!mainWindow) {
       throw new Error('"mainWindow" is not defined');
     }
@@ -85,6 +80,7 @@ const createWindow = async () => {
     } else {
       mainWindow.show();
       mainWindow.focus();
+      mainWindow.maximize();
     }
   });
 
diff --git a/app/package.json b/app/package.json
index 17220ff8b282f84950f1d73af38738bf5a68f0c5..44aac567f561e3768c9b6a6891f61250672b2248 100644
--- a/app/package.json
+++ b/app/package.json
@@ -1,13 +1,12 @@
 {
-  "name": "electron-react-boilerplate",
-  "productName": "electron-react-boilerplate",
-  "version": "1.3.0",
-  "description": "Electron application boilerplate based on React, React Router, Webpack, React Hot Loader for rapid application development",
+  "name": "mysql-query-profiler",
+  "productName": "MySQL Query Profiler",
+  "version": "0.2.0",
+  "description": "A profiler for MySQL queries using Electron and React",
   "main": "./main.prod.js",
   "author": {
-    "name": "Electron React Boilerplate Maintainers",
-    "email": "electronreactboilerplate@gmail.com",
-    "url": "https://github.com/electron-react-boilerplate"
+    "name": "Customer driven project group 4",
+    "email": "er.yd37@protonmail.com"
   },
   "scripts": {
     "electron-rebuild": "node -r ../internals/scripts/BabelRegister.js ../internals/scripts/ElectronRebuild.js",
diff --git a/backend/data-processor/DataProcessor.ts b/backend/data-processor/DataProcessor.ts
index 6b25ce1e159a5ad68e62ecd0104632c9415ae089..2cb653aa1b5b75ac61bc4955e008564befbe5e6d 100644
--- a/backend/data-processor/DataProcessor.ts
+++ b/backend/data-processor/DataProcessor.ts
@@ -1,30 +1,141 @@
+/* eslint-disable class-methods-use-this */
 import { ResultValue } from '@mysql/xdevapi';
 import { Result } from '../utils/mysql';
 
+export interface MemoryPerformanceTimeline {
+  eventName: string;
+  isBytesUsedZero: boolean;
+  times: Array<number>;
+  bytesUsed: Array<number>;
+}
+
 export interface MemoryPerformanceDataPoint {
   relative_time: number;
-  geom: number;
-  total: number;
+  [eventName: string]: number;
 }
 
-export type MemoryPerformance = Array<MemoryPerformanceDataPoint>;
+export interface StageTimePoint {
+  stage: string;
+  source: string;
+  startTime: number;
+  endTime: number;
+}
+
+export type MemoryPerformance = Array<MemoryPerformanceTimeline>;
+
+export type ChartData = Array<MemoryPerformanceDataPoint>;
+
+export type StageTimes = Array<StageTimePoint>;
 
 export class DataProcessor {
   static processMemoryPerformance(performanceData?: Result) {
     // TODO: Add more restrictive tests
-    if (!performanceData || performanceData.labels.indexOf('geom') !== -1) {
-      // TODO: Figure out why we need to skip the first element
-      return <MemoryPerformance>(
-        performanceData?.values.slice(1).map((value: Array<ResultValue>) => {
-          const dataPoint: MemoryPerformanceDataPoint = {
-            relative_time: Number(value[1]),
-            geom: Number(value[2]),
-            total: Number(value[3]),
-          };
-          return dataPoint;
-        })
-      );
+    if (performanceData && performanceData.labels && performanceData.values) {
+      const { values } = performanceData;
+      const result: MemoryPerformance = [
+        {
+          eventName: 'total',
+          isBytesUsedZero: true,
+          times: [],
+          bytesUsed: [],
+        },
+      ];
+      values.forEach((resultValue: ResultValue[]) => {
+        const foundTimeline = result.find(
+          (value) => value.eventName === resultValue[1]
+        );
+        // Sorting through and adding times and bytes used to timelines
+        if (foundTimeline) {
+          foundTimeline.times.push(Number(resultValue[0]));
+          foundTimeline.bytesUsed.push(Number(resultValue[2]));
+        } else {
+          result.push({
+            eventName: String(resultValue[1]),
+            isBytesUsedZero: true,
+            times: [Number(resultValue[0])],
+            bytesUsed: [Number(resultValue[2])],
+          });
+        }
+        // Adding bytes to total timeline
+        const foundTotalTimeline = result.find(
+          (value) => value.eventName === 'total'
+        );
+        if (foundTotalTimeline) {
+          // Adding timestamps not in the total timeline
+          if (!foundTotalTimeline.times.includes(Number(resultValue[0]))) {
+            foundTotalTimeline.times.push(Number(resultValue[0]));
+            foundTotalTimeline.bytesUsed.push(0); // Starting at 0 bytes, will increment
+          }
+          // Incrementing the bytes used for the current timestamp
+          foundTotalTimeline.bytesUsed[
+            foundTotalTimeline.times.length - 1
+          ] += Number(resultValue[2]);
+        }
+      });
+      // Checking if some timelines do not have memory use, setting a flag if no bytes used
+      result.forEach((timeLine) => {
+        timeLine.isBytesUsedZero =
+          timeLine.bytesUsed.reduce((a, b) => a + b, 0) === 0;
+      });
+      console.log(result);
+      return DataProcessor.getChartData(result);
     }
     throw new Error('DataProcessor: performanceData had wrong format');
   }
+
+  static getChartData(memoryPerformance: MemoryPerformance) {
+    const result: ChartData = [];
+
+    memoryPerformance[0].bytesUsed.forEach((_, index) => {
+      const memoryPerformanceDataPoint: MemoryPerformanceDataPoint = {
+        relative_time: memoryPerformance[0].times[index],
+      };
+
+      memoryPerformance.forEach((performanceTimeline) => {
+        if (!performanceTimeline.isBytesUsedZero) {
+          memoryPerformanceDataPoint[performanceTimeline.eventName] =
+            performanceTimeline.bytesUsed[index];
+        }
+      });
+      result.push(memoryPerformanceDataPoint);
+    });
+
+    console.log(result);
+    return result;
+  }
+
+  static processStageTimes(stageTimesRaw?: Result) {
+    if (stageTimesRaw && stageTimesRaw.labels && stageTimesRaw.values) {
+      const { values } = stageTimesRaw;
+      const result: StageTimes = [];
+      values.forEach((resultValue: ResultValue[]) => {
+        result.push({
+          stage: String(resultValue[0]),
+          source: String(resultValue[1]),
+          startTime: Number(resultValue[2]),
+          endTime: Number(resultValue[3]),
+        });
+      });
+      console.log(result);
+      return result;
+    }
+    throw new Error('DataProcessor: stageTimesRaw had wrong format');
+  }
+
+  static processOptimizerTrace(optimizerTrace?: Result) {
+    let traceResult;
+    if (optimizerTrace && optimizerTrace.values) {
+      traceResult = optimizerTrace;
+      console.log(
+        `Dataprocessor.processOptimizerTrace: Traceresult: ${JSON.stringify(
+          traceResult
+        )}`
+      );
+      if (traceResult.values.length > 0 && traceResult.values[0].length > 1) {
+        traceResult.values[0][1] = JSON.parse(String(traceResult.values[0][1]));
+      }
+      return traceResult.values;
+    }
+    throw new Error('DataProcessor: optimizerTrace had wrong format');
+  }
 }
diff --git a/backend/recorder/SqlManager.ts b/backend/recorder/SqlManager.ts
index 3c7d0530a57f1e788281afb8f51c629802427ae7..ab5ca284fb3d55bd6eea8783e175b91063523e65 100644
--- a/backend/recorder/SqlManager.ts
+++ b/backend/recorder/SqlManager.ts
@@ -1,10 +1,11 @@
 import { URI, Client } from '@mysql/xdevapi';
-import { saveLoginDetails } from '../utils/fileutils';
+import FileIO from '../utils/FileIO';
 import SqlRunner from './SqlRunner';
 import SqlMonitor from './SqlMonitor';
 import { closeConnection } from '../utils/mysql';
+import { DataProcessor } from '../data-processor/DataProcessor';
 
-class SqlManager {
+export default class SqlManager {
   connection?: URI;
 
   database?: string;
@@ -22,29 +23,52 @@ class SqlManager {
     this.client = await this.runner.connect(connection, database);
     this.monitor = new SqlMonitor();
     await this.monitor.connect(this.client, database);
-    await saveLoginDetails({ ...connection, database });
+    await FileIO.saveLoginDetails({ ...connection, database });
   }
 
   async record(query: string, explainAnalyze?: boolean) {
-    if (!this.runner || !this.monitor || !this.runner.connectionID)
+    if (!this.runner || !this.monitor || !this.runner.connectionID) {
       throw new Error(
-        'SqlManager: Runner, monitor or connectionID was missing. Maybe you forgot to call connect()?'
+        'SqlManager.record: Runner, monitor or connectionID was missing. Maybe you forgot to call connect()?'
       );
+    }
+    await this.monitor.prepareMonitoring(this.runner.connectionID);
     this.monitor.monitorConnection(this.runner.connectionID);
+
+    // Wait to make sure monitor is ready for runner to execute query
+    // TODO: Find a more optimal solution than waiting 1 second
+    // eslint-disable-next-line compat/compat
+    await new Promise((resolve) => setTimeout(resolve, 1000));
+
     const result = await this.runner.executeQuery(query, explainAnalyze);
     if (result?.error) {
       await this.reset();
       return { result, memoryPerformance: undefined, error: result.error };
     }
+    const optimizerTrace = await this.runner.getOptimizerTrace();
     const memoryPerformance = await this.monitor.dumpData();
+    const stageTimes = await this.monitor.getStageTimes();
     return {
       result,
-      memoryPerformance: memoryPerformance.results,
+      optimizerTrace: DataProcessor.processOptimizerTrace(
+        optimizerTrace.results
+      ),
+      memoryPerformance: DataProcessor.processMemoryPerformance(
+        memoryPerformance.results
+      ),
+      stageTimes: DataProcessor.processStageTimes(stageTimes.results),
       error: undefined,
     };
   }
 
   async reset() {
+    if (!this.runner || !this.monitor || !this.monitor.connectionID) {
+      throw new Error(
+        `SqlManager.reset: Runner, monitor or connectionID was missing. Invalid attempt at reset?`
+      );
+    }
+    // Kill monitor manually from runner as client.close won't interfere if monitor has called its procedure
+    await this.runner.executeQuery(`kill ${this.monitor.connectionID};`);
     await closeConnection(this.client);
     await this.connect(this.connection, this.database);
   }
@@ -54,12 +78,4 @@ class SqlManager {
     const result = await this.runner.executeQuery(query);
     return result;
   }
-
-  async executeWithTrace(query: string) {
-    if (!this.runner) return { result: [], trace: [] };
-    const result = await this.runner.executeTraceQuery(query);
-    return result;
-  }
 }
-
-export default SqlManager;
diff --git a/backend/recorder/SqlManagerSingleton.ts b/backend/recorder/SqlManagerSingleton.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c60832ed2c1dcc7ad5e10acd6314789cade07abe
--- /dev/null
+++ b/backend/recorder/SqlManagerSingleton.ts
@@ -0,0 +1,25 @@
+import SqlManager from './SqlManager';
+
+interface Singleton {
+  instance: SqlManager | undefined;
+  createInstance: () => SqlManager;
+  getInstance: () => SqlManager;
+}
+
+const SqlManagerSingleton: Singleton = {
+  instance: undefined,
+
+  createInstance: () => {
+    const manager = new SqlManager();
+    return manager;
+  },
+
+  getInstance: () => {
+    if (!SqlManagerSingleton.instance) {
+      SqlManagerSingleton.instance = SqlManagerSingleton.createInstance();
+    }
+    return SqlManagerSingleton.instance;
+  },
+};
+
+export default SqlManagerSingleton;
diff --git a/backend/recorder/SqlMonitor.ts b/backend/recorder/SqlMonitor.ts
index 5c27ae4d40795152fcab1545ba252500f22ae0a8..6c9af3285bc41aacbf7335c430bbf01fe4096788 100644
--- a/backend/recorder/SqlMonitor.ts
+++ b/backend/recorder/SqlMonitor.ts
@@ -6,8 +6,6 @@ export default class SqlMonitor {
 
   connectionID?: string;
 
-  fileCount = 0;
-
   async connect(client?: Client, database?: string) {
     this.session = await createSession(client, database);
     const resultSet = await runQuery(`SELECT connection_id();`, this.session);
@@ -15,11 +13,35 @@ export default class SqlMonitor {
     console.log(`SqlMonitor: ConnectionID: ${this.connectionID}`);
   }
 
-  async monitorConnection(connectionID: string) {
+  async prepareMonitoring(connectionID: string) {
+    await this.enableStageLogging();
+    const stageIgnoreBeforeResult = await runQuery(
+      `SELECT MAX(TIMER_END) FROM performance_schema.events_stages_history_long WHERE THREAD_ID=(SELECT THREAD_ID FROM performance_schema.threads WHERE PROCESSLIST_ID=${connectionID});`,
+      this.session
+    );
+    await this.createMonitorProcedure(
+      Number(stageIgnoreBeforeResult.results?.values[0])
+    );
+  }
+
+  async enableStageLogging() {
+    // Allow logging of stages
+    await runQuery(
+      `update performance_schema.setup_instruments set enabled="YES", timed="yes" where name like "stage/%";`,
+      this.session
+    );
+    await runQuery(
+      `update performance_schema.setup_consumers set enabled="YES" where name like "events_stages%";`,
+      this.session
+    );
+  }
+
+  async createMonitorProcedure(stageIgnoreBefore: number) {
     await runQuery(
       'DROP PROCEDURE IF EXISTS monitor_connection;',
       this.session
     );
+    // Create monitoring procedure
     await runQuery(
       `CREATE PROCEDURE monitor_connection(
         IN conn_id BIGINT UNSIGNED
@@ -32,34 +54,28 @@ export default class SqlMonitor {
 
         SET thd_id = (SELECT THREAD_ID FROM performance_schema.threads WHERE PROCESSLIST_ID=conn_id);
 
-        SET stage_ignore_before = (SELECT MAX(TIMER_END) FROM performance_schema.events_stages_history_long WHERE THREAD_ID=thd_id);
+        SET stage_ignore_before = ${stageIgnoreBefore};
         DROP TABLE IF EXISTS monitoring_data;
-        CREATE TABLE monitoring_data AS
-          SELECT
-            NOW(6) AS 'TS',
-            THREAD_ID,
-            EVENT_NAME,
-            COUNT_ALLOC,
-            COUNT_FREE,
-            SUM_NUMBER_OF_BYTES_ALLOC,
-            SUM_NUMBER_OF_BYTES_FREE,
-            LOW_COUNT_USED,
-            CURRENT_COUNT_USED,
-            HIGH_COUNT_USED,
-            LOW_NUMBER_OF_BYTES_USED,
-            CURRENT_NUMBER_OF_BYTES_USED,
-            HIGH_NUMBER_OF_BYTES_USED
-          FROM performance_schema.memory_summary_by_thread_by_event_name
-          WHERE THREAD_ID = thd_id;
-
-        SELECT CONCAT ('Waiting for connection ', conn_id, ' (thread ', thd_id, ') to start executing a query') AS 'Status';
+        CREATE TABLE monitoring_data (
+            TS DATETIME(6),
+            THREAD_ID BIGINT UNSIGNED,
+            EVENT_NAME VARCHAR(128),
+            COUNT_ALLOC BIGINT UNSIGNED,
+            COUNT_FREE BIGINT UNSIGNED,
+            SUM_NUMBER_OF_BYTES_ALLOC BIGINT UNSIGNED,
+            SUM_NUMBER_OF_BYTES_FREE BIGINT UNSIGNED,
+            LOW_COUNT_USED BIGINT,
+            CURRENT_COUNT_USED BIGINT,
+            HIGH_COUNT_USED BIGINT,
+            LOW_NUMBER_OF_BYTES_USED BIGINT,
+            CURRENT_NUMBER_OF_BYTES_USED BIGINT,
+            HIGH_NUMBER_OF_BYTES_USED BIGINT
+        );
 
         REPEAT
           SET state = (SELECT PROCESSLIST_COMMAND FROM performance_schema.threads WHERE THREAD_ID=thd_id);
         UNTIL state = 'Query' END REPEAT;
 
-        SELECT 'Connection monitoring starting' AS 'Status';
-
         REPEAT
           SET state = (SELECT PROCESSLIST_COMMAND FROM performance_schema.threads WHERE THREAD_ID=thd_id);
           INSERT INTO monitoring_data
@@ -82,19 +98,7 @@ export default class SqlMonitor {
           DO SLEEP(0.1);
         UNTIL state = 'Sleep' END REPEAT;
 
-        SELECT 'Connection monitoring ended' AS 'Status';
-
         SET stage_min_ts = (SELECT MIN(timer_start) FROM performance_schema.events_stages_history_long WHERE THREAD_ID=thd_id AND timer_start > stage_ignore_before);
-        SELECT stage_min_ts AS 'stage_min_ts', stage_ignore_before AS 'stage_ignore_before';
-        SELECT
-          EVENT_NAME,
-          SOURCE,
-          timer_start,
-          timer_end,
-          (timer_start - stage_min_ts) / 1000000000000 AS start,
-          (timer_end - stage_min_ts) / 1000000000000 AS end
-        FROM performance_schema.events_stages_history_long
-        WHERE THREAD_ID = thd_id AND timer_start > stage_ignore_before ORDER BY timer_start;
 
         DROP TABLE IF EXISTS monitoring_stages;
         CREATE TABLE monitoring_stages AS
@@ -110,6 +114,9 @@ export default class SqlMonitor {
       END`,
       this.session
     );
+  }
+
+  async monitorConnection(connectionID: string) {
     await runQuery(`call monitor_connection(${connectionID});`, this.session);
   }
 
@@ -120,26 +127,17 @@ export default class SqlMonitor {
     );
 
     const data = await runQuery(
-      `(SELECT
-        'wall_clock',
-        'relative time',
-        'geom',
-        CAST('total' AS CHAR))
-       UNION
-       (SELECT
-        TS AS the_ts,
-        UNIX_TIMESTAMP(TS) - @min_ts,
-        (SELECT
-          CURRENT_NUMBER_OF_BYTES_USED
-         FROM monitoring_data
-         WHERE EVENT_NAME='memory/sql/Geometry::ptr_and_wkb_data' AND TS=the_ts),
-        SUM(CURRENT_NUMBER_OF_BYTES_USED)
-        FROM monitoring_data
-        GROUP BY the_ts
-       );`,
+      `SELECT UNIX_TIMESTAMP(TS) - @min_ts, EVENT_NAME, CURRENT_NUMBER_OF_BYTES_USED FROM monitoring_data ORDER BY 1;`,
       this.session
     );
-    console.log(data);
     return data;
   }
+
+  async getStageTimes() {
+    const stageTimesRaw = await runQuery(
+      `select event_name, source, start, end from monitoring_stages;`,
+      this.session
+    );
+    return stageTimesRaw;
+  }
 }
diff --git a/backend/recorder/SqlRunner.ts b/backend/recorder/SqlRunner.ts
index 10168c8e78f9ecbe51f3a57758e03670b0b61add..1f94564e0a95c48102b4125a28518df4a2cb6a15 100644
--- a/backend/recorder/SqlRunner.ts
+++ b/backend/recorder/SqlRunner.ts
@@ -1,10 +1,5 @@
 import { URI, Session } from '@mysql/xdevapi';
-import {
-  createConnection,
-  createSession,
-  runQuery,
-  getOptimizerTrace,
-} from '../utils/mysql';
+import { createConnection, createSession, runQuery } from '../utils/mysql';
 
 export default class SqlRunner {
   session?: Session;
@@ -23,14 +18,18 @@ export default class SqlRunner {
   }
 
   async executeQuery(query: string, explainAnalyze?: boolean) {
-    if (explainAnalyze) {
+    await runQuery('SET optimizer_trace="enabled=on";', this.session);
+    if (explainAnalyze && !query.toLowerCase().includes('explain analyze')) {
       const newQuery = `EXPLAIN ANALYZE ${query}`;
       return runQuery(newQuery, this.session);
     }
     return runQuery(query, this.session);
   }
 
-  async executeTraceQuery(query: string) {
-    return getOptimizerTrace(query, this.session);
+  async getOptimizerTrace() {
+    return runQuery(
+      'SELECT * FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE;',
+      this.session
+    );
   }
 }
diff --git a/backend/utils/FileIO.ts b/backend/utils/FileIO.ts
new file mode 100644
index 0000000000000000000000000000000000000000..7dfc66e3a28c05342c9bed78897c2e293fa34e9f
--- /dev/null
+++ b/backend/utils/FileIO.ts
@@ -0,0 +1,26 @@
+import * as fs from 'fs';
+import { LoginDetails } from './LoginDetails';
+
+// fs docs: https://nodejs.org/api/fs.html#fs_file_paths
+
+export default class FileIO {
+  static async saveLoginDetails(loginDetails: LoginDetails) {
+    const loginDetailsLocation = 'loginDetails.json';
+    await fs.promises.writeFile(
+      loginDetailsLocation,
+      JSON.stringify(loginDetails, undefined, 2)
+    );
+  }
+
+  static async loadLoginDetails(): Promise<LoginDetails | undefined> {
+    const loginDetailsLocation = 'loginDetails.json';
+    if (fs.existsSync(loginDetailsLocation)) {
+      const data = await fs.promises.readFile(loginDetailsLocation);
+      return JSON.parse(String(data));
+    }
+    console.log(`${loginDetailsLocation} does not exist!`);
+    return undefined;
+  }
+}
+
+// export default { saveLoginDetails, loadLoginDetails };
diff --git a/backend/utils/fileutils.ts b/backend/utils/fileutils.ts
deleted file mode 100644
index c847e51e62b739e34e5153abb69f1597de7f5c05..0000000000000000000000000000000000000000
--- a/backend/utils/fileutils.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-import * as fs from 'fs';
-import { LoginDetails } from './LoginDetails';
-
-// fs docs: https://nodejs.org/api/fs.html#fs_file_paths
-
-export async function saveLoginDetails(loginDetails: LoginDetails) {
-  const loginDetailsLocation = 'loginDetails.json';
-  await fs.promises.writeFile(
-    loginDetailsLocation,
-    JSON.stringify(loginDetails, undefined, 2)
-  );
-}
-
-export async function loadLoginDetails(): Promise<LoginDetails | undefined> {
-  const loginDetailsLocation = 'loginDetails.json';
-  if (fs.existsSync(loginDetailsLocation)) {
-    const data = await fs.promises.readFile(loginDetailsLocation);
-    return JSON.parse(String(data));
-  }
-  console.log(`${loginDetailsLocation} does not exist!`);
-  return undefined;
-}
-
-// export default { saveLoginDetails, loadLoginDetails };
diff --git a/backend/utils/mysql.ts b/backend/utils/mysql.ts
index d346c156fe78ffbad0f293800f72f716756e0e9a..79a45106b8040805e5efe117a5a77246a8b6033b 100644
--- a/backend/utils/mysql.ts
+++ b/backend/utils/mysql.ts
@@ -11,9 +11,32 @@ import mysqlx, {
 
 export interface Result {
   labels: Array<string>;
+  types: Array<number>;
   values: Array<Array<ResultValue>>;
 }
 
+export type ColumnTypes = {
+  BIT: 1;
+  TINYINT: 2;
+  SMALLINT: 3;
+  MEDIUMINT: 4;
+  INT: 5;
+  BIGINT: 6;
+  FLOAT: 7;
+  DECIMAL: 8;
+  DOUBLE: 9;
+  JSON: 10;
+  STRING: 11;
+  BYTES: 12;
+  TIME: 13;
+  DATE: 14;
+  DATETIME: 15;
+  TIMESTAMP: 16;
+  SET: 17;
+  ENUM: 18;
+  GEOMETRY: 19;
+};
+
 /**
  * Run a query using a Session
  * @param session (Session)
@@ -25,22 +48,19 @@ export async function runQuery(query: string, session?: Session) {
     if (!session) throw new Error('No session was passed to runQuery');
     const result = await session.sql(query).execute();
     const columns = result.getColumns();
+    const types = columns.map((column) => column.getType());
     const fetchedResultSets = result.fetchAll();
     const results: Result = {
-      labels: columns.map((value: Column) => {
-        return value.getColumnLabel();
-      }),
-      values: fetchedResultSets.map((valueArray: Array<ResultValue>) => {
-        return valueArray.map((value: ResultValue) => value);
-      }),
+      labels: columns.map((value: Column) => value.getColumnLabel()),
+      types,
+      values: fetchedResultSets.map((valueArray: Array<ResultValue>) =>
+        valueArray.map((value: ResultValue) => value)
+      ),
     };
-    console.log(
-      `Result from query '${query}':\n${JSON.stringify(results, undefined, 2)}`
-    );
     return { results, error: undefined };
   } catch (error) {
     // TODO: Do more to handle errors
-    console.error(`Error while running query: ${error}`);
+    console.error(`Error while running query: ${error}\nQuery was: ${query}`);
     return { results: undefined, error };
   }
 }
@@ -67,23 +87,6 @@ export async function commit(session?: Session) {
   }
 }
 
-/**
- * Run a query using a Session and return its optimizer trace
- * @param session (Session)
- * @param query (string)
- * @returns Object: Optimizer trace steps
- */
-export async function getOptimizerTrace(query: string, session?: Session) {
-  await runQuery('SET optimizer_trace="enabled=on";', session);
-  const result = await runQuery(query, session);
-  const optimizerTrace = await runQuery(
-    'SELECT * FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE;',
-    session
-  );
-  await runQuery('SET optimizer_trace="enabled=on";', session);
-  return { result, trace: optimizerTrace };
-}
-
 /**
  * Create a connection to a MySQL server and return a Client
  * @param connection (URI | string): Connection config or a connectionstring
@@ -97,18 +100,19 @@ export async function createConnection(
   }
 ) {
   try {
-    if (!connection)
+    if (!connection) {
       throw new Error(
         'No connection information was passed to createConnection'
       );
+    }
     // Since this will only run locally, it's ok that the password is printed
-    console.log(
-      `Connecting with connectionstring: ${JSON.stringify(
-        connection,
-        undefined,
-        2
-      )}`
-    );
+    // console.log(
+    //   `Connecting with connectionstring: ${JSON.stringify(
+    //     connection,
+    //     undefined,
+    //     2
+    //   )}`
+    // );
     return await mysqlx.getClient(connection, poolingOptions);
   } catch (error) {
     // TODO: Do more to handle errors
@@ -124,17 +128,18 @@ export async function createConnection(
  * @returns Session
  */
 export async function createSession(client?: Client, database?: string) {
-  try {
-    if (!client) throw new Error('No client was passed to createSession');
-    const session = await client.getSession();
-    if (database) runQuery(`USE ${database};`, session);
-    console.log(session.inspect());
-    return session;
-  } catch (error) {
-    // TODO: Do more to handle errors
-    console.error(`Error while creating session: ${error}`);
-    throw error;
+  if (!client || !database) {
+    throw new Error(
+      'Either client or database was not passed to createSession'
+    );
+  }
+  const session = await client.getSession();
+  if (database) {
+    const result = await runQuery(`USE ${database};`, session);
+    if (result.error) throw result.error;
   }
+  console.log(session.inspect());
+  return session;
 }
 
 /**
diff --git a/package.json b/package.json
index 317db12e48c2922baf99085e55216f71a0439d05..d7cb1fce85f735472d4c1c2162de312c09442c8c 100644
--- a/package.json
+++ b/package.json
@@ -1,8 +1,21 @@
 {
   "name": "mysql-query-profiler",
   "productName": "MySQL Query Profiler",
-  "version": "0.0.1",
   "description": "A profiler for MySQL queries using Electron and React",
+  "repository": "https://gitlab.stud.idi.ntnu.no/erlenyd/mysql-query-profiler",
+  "homepage": "https://gitlab.stud.idi.ntnu.no/erlenyd/mysql-query-profiler",
+  "license": "MIT",
+  "author": {
+    "name": "Customer driven project group 4",
+    "email": "er.yd37@protonmail.com"
+  },
+  "keywords": [
+    "Electron",
+    "MySQL",
+    "Query profiler",
+    "Query",
+    "Profiler"
+  ],
   "scripts": {
     "build": "concurrently \"yarn build-main\" \"yarn build-renderer\"",
     "build-dll": "cross-env NODE_ENV=development webpack --config ./configs/webpack.config.renderer.dev.dll.babel.js --colors",
@@ -16,11 +29,11 @@
     "lint-styles": "stylelint --ignore-path .eslintignore '**/*.*(css|scss)' --syntax scss",
     "lint-styles-fix": "yarn --silent lint-styles --fix; exit 0",
     "package": "yarn build && electron-builder build --publish never",
-    "package-all": "yarn build && electron-builder build -mwl",
+    "package-all": "yarn build && electron-builder build -mwl --publish never",
     "package-ci": "yarn postinstall && yarn build && electron-builder --publish always",
-    "package-mac": "yarn build && electron-builder build --mac",
-    "package-linux": "yarn build && electron-builder build --linux",
-    "package-win": "yarn build && electron-builder build --win --x64",
+    "package-mac": "yarn build && electron-builder build --mac --publish never",
+    "package-linux": "yarn build && electron-builder build --linux --publish never",
+    "package-win": "yarn build && electron-builder build --win --x64 --publish never",
     "postinstall": "node -r @babel/register internals/scripts/CheckNativeDep.js && electron-builder install-app-deps && yarn build-dll && opencollective-postinstall",
     "postlint-fix": "prettier --ignore-path .eslintignore --single-quote --write '**/*.{js,jsx,json,html,css,less,scss,yml}'",
     "postlint-styles-fix": "prettier --ignore-path .eslintignore --single-quote --write '**/*.{css,scss}'",
@@ -51,8 +64,8 @@
     ]
   },
   "build": {
-    "productName": "ElectronReact",
-    "appId": "org.develar.ElectronReact",
+    "productName": "MySQL Query Profiler",
+    "appId": "id.mysql.query.profiler",
     "files": [
       "dist/",
       "node_modules/",
@@ -61,31 +74,19 @@
       "main.prod.js.map",
       "package.json"
     ],
-    "dmg": {
-      "contents": [
-        {
-          "x": 130,
-          "y": 220
-        },
-        {
-          "x": 410,
-          "y": 220,
-          "type": "link",
-          "path": "/Applications"
-        }
-      ]
+    "mac": {
+      "target": "zip",
+      "category": "public.app-category.developer-tools"
     },
     "win": {
-      "target": [
-        "nsis",
-        "msi"
-      ]
+      "target": "nsis"
     },
     "linux": {
       "target": [
         "deb",
         "rpm",
-        "AppImage"
+        "AppImage",
+        "snap"
       ],
       "category": "Development"
     },
@@ -93,14 +94,8 @@
       "buildResources": "resources",
       "output": "release"
     },
-    "publish": {
-      "provider": "gitlab",
-      "owner": "mysql-query-profiler",
-      "repo": "mysql-query-profiler",
-      "private": false
-    }
+    "publish": []
   },
-  "license": "MIT",
   "jest": {
     "testURL": "http://localhost/",
     "moduleNameMapper": {
@@ -147,6 +142,7 @@
     "@babel/preset-react": "^7.10.4",
     "@babel/preset-typescript": "^7.10.4",
     "@babel/register": "^7.10.5",
+    "@types/electron-devtools-installer": "^2.2.0",
     "@types/enzyme": "^3.10.5",
     "@types/enzyme-adapter-react-16": "^1.0.6",
     "@types/history": "^4.7.6",
@@ -155,12 +151,12 @@
     "@types/node": "12",
     "@types/react": "^16.9.49",
     "@types/react-dom": "^16.9.8",
-    "@types/react-redux": "^7.1.9",
+    "@types/react-panelgroup": "^1.0.1",
     "@types/react-router": "^5.1.8",
     "@types/react-router-dom": "^5.1.5",
     "@types/react-test-renderer": "^16.9.2",
     "@types/recharts": "^1.8.15",
-    "@types/redux-logger": "^3.0.8",
+    "@types/regenerator-runtime": "^0.13.0",
     "@types/webpack": "^4.41.21",
     "@types/webpack-env": "^1.15.2",
     "@typescript-eslint/eslint-plugin": "^4.0.1",
@@ -171,24 +167,21 @@
     "babel-loader": "^8.1.0",
     "babel-plugin-dev-expression": "^0.2.2",
     "babel-plugin-transform-react-remove-prop-types": "^0.4.24",
-    "browserslist-config-erb": "^0.0.1",
     "chalk": "^4.1.0",
-    "concurrently": "^5.2.0",
     "core-js": "^3.6.5",
-    "cross-env": "^7.0.0",
+    "cross-env": "^7.0.2",
     "css-loader": "^3.6.0",
     "detect-port": "^1.3.0",
-    "electron": "^8",
+    "electron": "^10",
     "electron-builder": "^22.3.6",
-    "electron-devtools-installer": "^2.2.4",
+    "electron-devtools-installer": "^3.1.1",
     "electron-rebuild": "^1.10.0",
     "enzyme": "^3.11.0",
     "enzyme-adapter-react-16": "^1.15.2",
     "enzyme-to-json": "^3.5.0",
-    "eslint": "^7.8.1",
+    "eslint": "^7.9.0",
     "eslint-config-airbnb": "^18.2.0",
     "eslint-config-airbnb-typescript": "^9.0.0",
-    "eslint-config-erb": "^1.0.0",
     "eslint-config-prettier": "^6.11.0",
     "eslint-import-resolver-webpack": "^0.12.2",
     "eslint-plugin-compat": "^3.8.0",
@@ -210,7 +203,6 @@
     "optimize-css-assets-webpack-plugin": "^5.0.3",
     "prettier": "^2.1.1",
     "react-test-renderer": "^16.12.0",
-    "redux-logger": "^3.0.6",
     "rimraf": "^3.0.0",
     "sass-loader": "^9.0.2",
     "style-loader": "^1.2.1",
@@ -233,28 +225,25 @@
     "yarn": "^1.22.5"
   },
   "dependencies": {
-    "@fortawesome/fontawesome-free": "^5.14.0",
     "@hot-loader/react-dom": "^16.13.0",
     "@material-ui/core": "^4.11.0",
+    "@material-ui/lab": "^4.0.0-alpha.56",
+    "@material-ui/icons": "^4.9.1",
     "@mysql/xdevapi": "8.0.21",
-    "@reduxjs/toolkit": "^1.4.0",
-    "connected-react-router": "^6.6.1",
-    "electron-debug": "^3.1.0",
-    "electron-log": "^4.2.2",
+    "concurrently": "^5.3.0",
+    "electron-log": "^4.2.4",
     "electron-react-devtools": "^0.5.3",
-    "electron-updater": "^4.3.1",
+    "electron-updater": "^4.3.5",
     "history": "^4.7.2",
     "lodash": "^4.17.20",
     "react": "^16.13.1",
     "react-dom": "^16.12.0",
     "react-hot-loader": "^4.12.21",
-    "react-redux": "^7.2.0",
+    "react-json-view": "^1.19.1",
+    "react-panelgroup": "^1.0.12",
     "react-router-dom": "^5.2.0",
-    "react-textarea-autosize": "^8.2.0",
     "recharts": "^1.8.5",
-    "redux": "^4.0.5",
-    "redux-thunk": "^2.3.0",
-    "regenerator-runtime": "^0.13.5",
+    "regenerator-runtime": "^0.13.7",
     "source-map-support": "^0.5.19",
     "use-deep-compare-effect": "^1.4.0"
   },
@@ -263,10 +252,6 @@
     "npm": ">=4.x",
     "yarn": ">=0.21.3"
   },
-  "collective": {
-    "url": "https://opencollective.com/electron-react-boilerplate-594"
-  },
-  "browserslist": [],
   "prettier": {
     "overrides": [
       {
@@ -298,5 +283,11 @@
     "hooks": {
       "pre-commit": "lint-staged"
     }
-  }
+  },
+  "browserslist": [
+    "last 2 version",
+    "not IE 11",
+    "not op_mini all",
+    "not dead"
+  ]
 }
diff --git a/publish-bintray.sh b/publish-bintray.sh
new file mode 100644
index 0000000000000000000000000000000000000000..6e0052f17ed0fe02f8bee3e4db8359d9b7dc8fcb
--- /dev/null
+++ b/publish-bintray.sh
@@ -0,0 +1,15 @@
+#! /bin/bash
+
+# Creating new version on Bintray
+ticked_version=$(jq .version app/package.json)
+version=${ticked_version//[\"]/}
+desc=$(jq .description package.json)
+# Uploading to Bintray
+curl -v -T release/'MySQL Query Profiler'-${version}.AppImage -ukpro4:${BT_TOKEN} -H "X-Bintray-Package:mysql-query-profiler" -H "X-Bintray-Version:${version}" https://api.bintray.com/content/kpro4/mysql-query-profiler/mysql-query-profiler-${version}.AppImage
+curl -v -T release/mysql-query-profiler_${version}_amd64.deb -ukpro4:${BT_TOKEN} -H "X-Bintray-Package:mysql-query-profiler" -H "X-Bintray-Version:${version}" https://api.bintray.com/content/kpro4/mysql-query-profiler/mysql-query-profiler-${version}.deb
+curl -v -T release/mysql-query-profiler-${version}.x86_64.rpm -ukpro4:${BT_TOKEN} -H "X-Bintray-Package:mysql-query-profiler" -H "X-Bintray-Version:${version}" https://api.bintray.com/content/kpro4/mysql-query-profiler/mysql-query-profiler-${version}.rpm
+curl -v -T release/'MySQL Query Profiler Setup '${version}.exe -ukpro4:${BT_TOKEN} -H "X-Bintray-Package:mysql-query-profiler" -H "X-Bintray-Version:${version}" https://api.bintray.com/content/kpro4/mysql-query-profiler/mysql-query-profiler-${version}.exe
+curl -v -T release/'MySQL Query Profiler'-${version}-mac.zip -ukpro4:${BT_TOKEN} -H "X-Bintray-Package:mysql-query-profiler" -H "X-Bintray-Version:${version}" https://api.bintray.com/content/kpro4/mysql-query-profiler/mysql-query-profiler-${version}-mac.zip
+# Publishing the new version
+curl -v -X POST -ukpro4:${BT_TOKEN} https://api.bintray.com/content/kpro4/mysql-query-profiler/mysql-query-profiler/${version}/publish
+
diff --git a/resources/icon.ico b/resources/icon.ico
new file mode 100644
index 0000000000000000000000000000000000000000..15e5d78bb470d7236df9db38259c730560d1141d
Binary files /dev/null and b/resources/icon.ico differ
diff --git a/resources/icon.png b/resources/icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..2c0f60050d903da7e723646396a896be9b90a9a8
Binary files /dev/null and b/resources/icon.png differ
diff --git a/resources/icons/16x16.png b/resources/icons/16x16.png
new file mode 100644
index 0000000000000000000000000000000000000000..b2a9c915f2c8059368c8e6a4c14168756e886745
Binary files /dev/null and b/resources/icons/16x16.png differ
diff --git a/resources/icons/32x32.png b/resources/icons/32x32.png
new file mode 100644
index 0000000000000000000000000000000000000000..2fca10cdbc0186242fbec8f6edbbdad44bc64f0f
Binary files /dev/null and b/resources/icons/32x32.png differ
diff --git a/resources/icons/48x48.png b/resources/icons/48x48.png
new file mode 100644
index 0000000000000000000000000000000000000000..581a1367d311e6b6cdffe536b6f3936c1f956230
Binary files /dev/null and b/resources/icons/48x48.png differ
diff --git a/resources/icons/512x512.png b/resources/icons/512x512.png
new file mode 100644
index 0000000000000000000000000000000000000000..6ff3ba1ecab12c8d4dbfb34dc88b3c6a7350ca27
Binary files /dev/null and b/resources/icons/512x512.png differ
diff --git a/resources/icons/96x96.png b/resources/icons/96x96.png
new file mode 100644
index 0000000000000000000000000000000000000000..ecc2b8a558bf6dd2089bf90cc5c92ece116cd4ed
Binary files /dev/null and b/resources/icons/96x96.png differ
diff --git a/yarn.lock b/yarn.lock
index 2ca3862b99b97a2ac4c7a1ba253388f032ef5218..d79c754ed012a760f7173780032ef7e955876933 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -7,11 +7,6 @@
   resolved "https://registry.yarnpkg.com/7zip-bin/-/7zip-bin-5.0.3.tgz#bc5b5532ecafd923a61f2fb097e3b108c0106a3f"
   integrity sha512-GLyWIFBbGvpKPGo55JyRZAo4lVbnBiD52cKlw/0Vt+wnmKvWJkpZvsjVoaIolyBXDeAQKSicRtqFNPem9w0WYA==
 
-"7zip@0.0.6":
-  version "0.0.6"
-  resolved "https://registry.yarnpkg.com/7zip/-/7zip-0.0.6.tgz#9cafb171af82329490353b4816f03347aa150a30"
-  integrity sha1-nK+xca+CMpSQNTtIFvAzR6oVCjA=
-
 "@amilajack/testcafe-browser-provider-electron@^0.0.15-alpha.1":
   version "0.0.15-alpha.1"
   resolved "https://registry.yarnpkg.com/@amilajack/testcafe-browser-provider-electron/-/testcafe-browser-provider-electron-0.0.15-alpha.1.tgz#506080ec623c1509fae489b13cb2a2894ec6fbb9"
@@ -47,7 +42,29 @@
     invariant "^2.2.4"
     semver "^5.5.0"
 
-"@babel/core@>=7.9.0", "@babel/core@^7.1.0", "@babel/core@^7.11.1", "@babel/core@^7.7.5":
+"@babel/core@>=7.9.0", "@babel/core@^7.11.1":
+  version "7.11.6"
+  resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.11.6.tgz#3a9455dc7387ff1bac45770650bc13ba04a15651"
+  integrity sha512-Wpcv03AGnmkgm6uS6k8iwhIwTrcP0m17TL1n1sy7qD0qelDu4XNeW0dN0mHfa+Gei211yDaLoEe/VlbXQzM4Bg==
+  dependencies:
+    "@babel/code-frame" "^7.10.4"
+    "@babel/generator" "^7.11.6"
+    "@babel/helper-module-transforms" "^7.11.0"
+    "@babel/helpers" "^7.10.4"
+    "@babel/parser" "^7.11.5"
+    "@babel/template" "^7.10.4"
+    "@babel/traverse" "^7.11.5"
+    "@babel/types" "^7.11.5"
+    convert-source-map "^1.7.0"
+    debug "^4.1.0"
+    gensync "^1.0.0-beta.1"
+    json5 "^2.1.2"
+    lodash "^4.17.19"
+    resolve "^1.3.2"
+    semver "^5.4.1"
+    source-map "^0.5.0"
+
+"@babel/core@^7.1.0", "@babel/core@^7.7.5":
   version "7.11.4"
   resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.11.4.tgz#4301dfdfafa01eeb97f1896c5501a3f0655d4229"
   integrity sha512-5deljj5HlqRXN+5oJTY7Zs37iH3z3b++KjiKtIsJy1NrjOOVSEaJHEetLBhyu0aQOSNNZ/0IuEAan9GzRuDXHg==
@@ -69,12 +86,12 @@
     semver "^5.4.1"
     source-map "^0.5.0"
 
-"@babel/generator@^7.11.0", "@babel/generator@^7.11.4":
-  version "7.11.4"
-  resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.11.4.tgz#1ec7eec00defba5d6f83e50e3ee72ae2fee482be"
-  integrity sha512-Rn26vueFx0eOoz7iifCN2UHT6rGtnkSGWSoDRIy8jZN3B91PzeSULbswfLoOWuTuAcNwpG/mxy+uCTDnZ9Mp1g==
+"@babel/generator@^7.11.0", "@babel/generator@^7.11.4", "@babel/generator@^7.11.5", "@babel/generator@^7.11.6":
+  version "7.11.6"
+  resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.11.6.tgz#b868900f81b163b4d464ea24545c61cbac4dc620"
+  integrity sha512-DWtQ1PV3r+cLbySoHrwn9RWEgKMBLLma4OBQloPRyDYvc5msJM9kvTLo1YnlJd1P/ZuKbdli3ijr5q3FvAF3uA==
   dependencies:
-    "@babel/types" "^7.11.0"
+    "@babel/types" "^7.11.5"
     jsesc "^2.5.1"
     source-map "^0.5.0"
 
@@ -302,11 +319,16 @@
     chalk "^2.0.0"
     js-tokens "^4.0.0"
 
-"@babel/parser@^7.1.0", "@babel/parser@^7.10.4", "@babel/parser@^7.11.0", "@babel/parser@^7.11.4", "@babel/parser@^7.7.0":
+"@babel/parser@^7.1.0", "@babel/parser@^7.7.0":
   version "7.11.4"
   resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.11.4.tgz#6fa1a118b8b0d80d0267b719213dc947e88cc0ca"
   integrity sha512-MggwidiH+E9j5Sh8pbrX5sJvMcsqS5o+7iB42M9/k0CD63MjYbdP4nhSh7uB5wnv2/RVzTZFTxzF/kIa5mrCqA==
 
+"@babel/parser@^7.10.4", "@babel/parser@^7.11.0", "@babel/parser@^7.11.4", "@babel/parser@^7.11.5":
+  version "7.11.5"
+  resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.11.5.tgz#c7ff6303df71080ec7a4f5b8c003c58f1cf51037"
+  integrity sha512-X9rD8qqm695vgmeaQ4fvz/o3+Wk4ZzQvSHkDBgpYKxpD4qTAUm88ZKtHkVqIOsYFFbIQ6wQYhC6q7pjqVK0E0Q==
+
 "@babel/plugin-proposal-async-generator-functions@^7.10.4":
   version "7.10.5"
   resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.10.5.tgz#3491cabf2f7c179ab820606cec27fed15e0e8558"
@@ -366,9 +388,9 @@
     "@babel/plugin-syntax-export-namespace-from" "^7.8.3"
 
 "@babel/plugin-proposal-function-bind@^7.10.5":
-  version "7.10.5"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-function-bind/-/plugin-proposal-function-bind-7.10.5.tgz#62acbdde1c43e7dfae6efc9ddd5bc60920cee719"
-  integrity sha512-1lYbE2ynV9yN0LCEYCdEBD5pR6GaNkRfjn1z1tWDdWMJgunTFcJBZDJUgiMPcTMqAc3D6Vrm8v2khxjjx6FrCg==
+  version "7.11.5"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-function-bind/-/plugin-proposal-function-bind-7.11.5.tgz#6ce571686dd1bc2f5c1ae7bdebad8aaa7fda3893"
+  integrity sha512-gkCyUqJp6jRPdHFAYZxGal6d6Poj17G+6FGbyUcHKew2sccp5HVilTgnreYqTzDsY10Ys0ZVB/U2knTnnJdkUQ==
   dependencies:
     "@babel/helper-plugin-utils" "^7.10.4"
     "@babel/plugin-syntax-function-bind" "^7.10.4"
@@ -959,9 +981,9 @@
     "@babel/helper-plugin-utils" "^7.10.4"
 
 "@babel/preset-env@^7.11.0":
-  version "7.11.0"
-  resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.11.0.tgz#860ee38f2ce17ad60480c2021ba9689393efb796"
-  integrity sha512-2u1/k7rG/gTh02dylX2kL3S0IJNF+J6bfDSp4DI2Ma8QN6Y9x9pmAax59fsCk6QUQG0yqH47yJWA+u1I1LccAg==
+  version "7.11.5"
+  resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.11.5.tgz#18cb4b9379e3e92ffea92c07471a99a2914e4272"
+  integrity sha512-kXqmW1jVcnB2cdueV+fyBM8estd5mlNfaQi6lwLgRwCby4edpavgbFhiBNjmWA3JpB/yZGSISa7Srf+TwxDQoA==
   dependencies:
     "@babel/compat-data" "^7.11.0"
     "@babel/helper-compilation-targets" "^7.10.4"
@@ -1025,7 +1047,7 @@
     "@babel/plugin-transform-unicode-escapes" "^7.10.4"
     "@babel/plugin-transform-unicode-regex" "^7.10.4"
     "@babel/preset-modules" "^0.1.3"
-    "@babel/types" "^7.11.0"
+    "@babel/types" "^7.11.5"
     browserslist "^4.12.0"
     core-js-compat "^3.6.2"
     invariant "^2.2.2"
@@ -1033,9 +1055,9 @@
     semver "^5.5.0"
 
 "@babel/preset-modules@^0.1.3":
-  version "0.1.3"
-  resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.3.tgz#13242b53b5ef8c883c3cf7dddd55b36ce80fbc72"
-  integrity sha512-Ra3JXOHBq2xd56xSF7lMKXdjBn3T772Y1Wet3yWnkDly9zHvJki029tAFzvAAK5cf4YV3yoxuP61crYRol6SVg==
+  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"
@@ -1065,9 +1087,9 @@
     "@babel/plugin-transform-typescript" "^7.10.4"
 
 "@babel/register@^7.10.5":
-  version "7.10.5"
-  resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.10.5.tgz#354f3574895f1307f79efe37a51525e52fd38d89"
-  integrity sha512-eYHdLv43nyvmPn9bfNfrcC4+iYNwdQ8Pxk1MFJuU/U5LpSYl/PH4dFMazCYZDFVi8ueG3shvO+AQfLrxpYulQw==
+  version "7.11.5"
+  resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.11.5.tgz#79becf89e0ddd0fba8b92bc279bc0f5d2d7ce2ea"
+  integrity sha512-CAml0ioKX+kOAvBQDHa/+t1fgOt3qkTIz0TrRtRAT6XY0m5qYZXR85k6/sLCNPMGhYDlCFHCYuU0ybTJbvlC6w==
   dependencies:
     find-cache-dir "^2.0.0"
     lodash "^4.17.19"
@@ -1099,7 +1121,7 @@
     "@babel/parser" "^7.10.4"
     "@babel/types" "^7.10.4"
 
-"@babel/traverse@^7.1.0", "@babel/traverse@^7.10.4", "@babel/traverse@^7.11.0", "@babel/traverse@^7.7.0":
+"@babel/traverse@^7.1.0", "@babel/traverse@^7.7.0":
   version "7.11.0"
   resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.11.0.tgz#9b996ce1b98f53f7c3e4175115605d56ed07dd24"
   integrity sha512-ZB2V+LskoWKNpMq6E5UUCrjtDUh5IOTAyIl0dTjIEoXum/iKWkoIEKIRDnUucO6f+2FzNkE0oD4RLKoPIufDtg==
@@ -1114,7 +1136,22 @@
     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.11.0", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4", "@babel/types@^7.7.0":
+"@babel/traverse@^7.10.4", "@babel/traverse@^7.11.0", "@babel/traverse@^7.11.5":
+  version "7.11.5"
+  resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.11.5.tgz#be777b93b518eb6d76ee2e1ea1d143daa11e61c3"
+  integrity sha512-EjiPXt+r7LiCZXEfRpSJd+jUMnBd4/9OUv7Nx3+0u9+eimMwJmG0Q98lw4/289JCoxSE8OolDMNZaaF/JZ69WQ==
+  dependencies:
+    "@babel/code-frame" "^7.10.4"
+    "@babel/generator" "^7.11.5"
+    "@babel/helper-function-name" "^7.10.4"
+    "@babel/helper-split-export-declaration" "^7.11.0"
+    "@babel/parser" "^7.11.5"
+    "@babel/types" "^7.11.5"
+    debug "^4.1.0"
+    globals "^11.1.0"
+    lodash "^4.17.19"
+
+"@babel/types@^7.0.0", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.7.0":
   version "7.11.0"
   resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.11.0.tgz#2ae6bf1ba9ae8c3c43824e5861269871b206e90d"
   integrity sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==
@@ -1123,6 +1160,15 @@
     lodash "^4.17.19"
     to-fast-properties "^2.0.0"
 
+"@babel/types@^7.10.4", "@babel/types@^7.10.5", "@babel/types@^7.11.0", "@babel/types@^7.11.5", "@babel/types@^7.4.4":
+  version "7.11.5"
+  resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.11.5.tgz#d9de577d01252d77c6800cee039ee64faf75662d"
+  integrity sha512-bvM7Qz6eKnJVFIn+1LPtjlBFPVN5jNDc1XmN15vWe7Q3DPBufWWsLiIvUu7xW87uTG6QoggpIDnUgLQvPheU+Q==
+  dependencies:
+    "@babel/helper-validator-identifier" "^7.10.4"
+    lodash "^4.17.19"
+    to-fast-properties "^2.0.0"
+
 "@bcoe/v8-coverage@^0.2.3":
   version "0.2.3"
   resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39"
@@ -1181,11 +1227,6 @@
     minimatch "^3.0.4"
     strip-json-comments "^3.1.1"
 
-"@fortawesome/fontawesome-free@^5.14.0":
-  version "5.14.0"
-  resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-free/-/fontawesome-free-5.14.0.tgz#a371e91029ebf265015e64f81bfbf7d228c9681f"
-  integrity sha512-OfdMsF+ZQgdKHP9jUbmDcRrP0eX90XXrsXIdyjLbkmSBzmMXPABB8eobUJtivaupucYaByz6WNe1PI1JuYm3qA==
-
 "@hot-loader/react-dom@^16.13.0":
   version "16.13.0"
   resolved "https://registry.yarnpkg.com/@hot-loader/react-dom/-/react-dom-16.13.0.tgz#de245b42358110baf80aaf47a0592153d4047997"
@@ -1411,6 +1452,24 @@
     react-is "^16.8.0"
     react-transition-group "^4.4.0"
 
+"@material-ui/icons@^4.9.1":
+  version "4.9.1"
+  resolved "https://registry.yarnpkg.com/@material-ui/icons/-/icons-4.9.1.tgz#fdeadf8cb3d89208945b33dbc50c7c616d0bd665"
+  integrity sha512-GBitL3oBWO0hzBhvA9KxqcowRUsA0qzwKkURyC8nppnC3fw54KPKZ+d4V1Eeg/UnDRSzDaI9nGCdel/eh9AQMg==
+  dependencies:
+    "@babel/runtime" "^7.4.4"
+
+"@material-ui/lab@^4.0.0-alpha.56":
+  version "4.0.0-alpha.56"
+  resolved "https://registry.yarnpkg.com/@material-ui/lab/-/lab-4.0.0-alpha.56.tgz#ff63080949b55b40625e056bbda05e130d216d34"
+  integrity sha512-xPlkK+z/6y/24ka4gVJgwPfoCF4RCh8dXb1BNE7MtF9bXEBLN/lBxNTK8VAa0qm3V2oinA6xtUIdcRh0aeRtVw==
+  dependencies:
+    "@babel/runtime" "^7.4.4"
+    "@material-ui/utils" "^4.10.2"
+    clsx "^1.0.4"
+    prop-types "^15.7.2"
+    react-is "^16.8.0"
+
 "@material-ui/styles@^4.10.0":
   version "4.10.0"
   resolved "https://registry.yarnpkg.com/@material-ui/styles/-/styles-4.10.0.tgz#2406dc23aa358217aa8cc772e6237bd7f0544071"
@@ -1506,16 +1565,6 @@
   dependencies:
     mkdirp "^1.0.4"
 
-"@reduxjs/toolkit@^1.4.0":
-  version "1.4.0"
-  resolved "https://registry.yarnpkg.com/@reduxjs/toolkit/-/toolkit-1.4.0.tgz#ee2e2384cc3d1d76780d844b9c2da3580d32710d"
-  integrity sha512-hkxQwVx4BNVRsYdxjNF6cAseRmtrkpSlcgJRr3kLUcHPIAMZAmMJkXmHh/eUEGTMqPzsYpJLM7NN2w9fxQDuGw==
-  dependencies:
-    immer "^7.0.3"
-    redux "^4.0.0"
-    redux-thunk "^2.3.0"
-    reselect "^4.0.0"
-
 "@sindresorhus/is@^0.14.0":
   version "0.14.0"
   resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea"
@@ -1535,7 +1584,7 @@
   dependencies:
     "@sinonjs/commons" "^1.7.0"
 
-"@stylelint/postcss-css-in-js@^0.37.1":
+"@stylelint/postcss-css-in-js@^0.37.2":
   version "0.37.2"
   resolved "https://registry.yarnpkg.com/@stylelint/postcss-css-in-js/-/postcss-css-in-js-0.37.2.tgz#7e5a84ad181f4234a2480803422a47b8749af3d2"
   integrity sha512-nEhsFoJurt8oUmieT8qy4nk81WRHmJynmVwn/Vts08PL9fhgIsMhk1GId5yAN643OzqEEb5S/6At2TZW7pqPDA==
@@ -1624,6 +1673,11 @@
   resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.5.tgz#b14efa8852b7768d898906613c23f688713e02cd"
   integrity sha512-Q1y515GcOdTHgagaVFhHnIFQ38ygs/kmxdNpvpou+raI9UO3YZcHDngBSYKQklcKlvA7iuQlmIKbzvmxcOE9CQ==
 
+"@types/electron-devtools-installer@^2.2.0":
+  version "2.2.0"
+  resolved "https://registry.yarnpkg.com/@types/electron-devtools-installer/-/electron-devtools-installer-2.2.0.tgz#32ee4ebbe99b3daf9847a6d2097dc00b5de94f10"
+  integrity sha512-HJNxpaOXuykCK4rQ6FOMxAA0NLFYsf7FiPFGmab0iQmtVBHSAfxzy3MRFpLTTDDWbV0yD2YsHOQvdu8yCqtCfw==
+
 "@types/enzyme-adapter-react-16@^1.0.6":
   version "1.0.6"
   resolved "https://registry.yarnpkg.com/@types/enzyme-adapter-react-16/-/enzyme-adapter-react-16-1.0.6.tgz#8aca7ae2fd6c7137d869b6616e696d21bb8b0cec"
@@ -1631,7 +1685,7 @@
   dependencies:
     "@types/enzyme" "*"
 
-"@types/enzyme@*", "@types/enzyme@^3.10.5":
+"@types/enzyme@*":
   version "3.10.5"
   resolved "https://registry.yarnpkg.com/@types/enzyme/-/enzyme-3.10.5.tgz#fe7eeba3550369eed20e7fb565bfb74eec44f1f0"
   integrity sha512-R+phe509UuUYy9Tk0YlSbipRpfVtIzb/9BHn5pTEtjJTF5LXvUjrIQcZvNyANNEyFrd2YGs196PniNT1fgvOQA==
@@ -1639,6 +1693,14 @@
     "@types/cheerio" "*"
     "@types/react" "*"
 
+"@types/enzyme@^3.10.5":
+  version "3.10.6"
+  resolved "https://registry.yarnpkg.com/@types/enzyme/-/enzyme-3.10.6.tgz#a34a6b09ff732be29c194dc8d786555f4717fd85"
+  integrity sha512-Jxyn2U+UfhmrE7EaeZYfV1sPA5OEDuZmg9Lxj8TxOnfCn71flf0Cn1136LWdCVYj7yapLFmUWqKCcgplWNZCJg==
+  dependencies:
+    "@types/cheerio" "*"
+    "@types/react" "*"
+
 "@types/error-stack-parser@^1.3.18":
   version "1.3.18"
   resolved "https://registry.yarnpkg.com/@types/error-stack-parser/-/error-stack-parser-1.3.18.tgz#e01c9f8c85ca83b610320c62258b0c9026ade0f7"
@@ -1676,18 +1738,15 @@
   dependencies:
     "@types/node" "*"
 
-"@types/history@*", "@types/history@^4.7.6":
+"@types/history@*":
   version "4.7.7"
   resolved "https://registry.yarnpkg.com/@types/history/-/history-4.7.7.tgz#613957d900fab9ff84c8dfb24fa3eef0c2a40896"
   integrity sha512-2xtoL22/3Mv6a70i4+4RB7VgbDDORoWwjcqeNysojZA0R7NK17RbY5Gof/2QiFfJgX+KkWghbwJ+d/2SB8Ndzg==
 
-"@types/hoist-non-react-statics@^3.3.0":
-  version "3.3.1"
-  resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz#1124aafe5118cb591977aeb1ceaaed1070eb039f"
-  integrity sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==
-  dependencies:
-    "@types/react" "*"
-    hoist-non-react-statics "^3.3.0"
+"@types/history@^4.7.6":
+  version "4.7.8"
+  resolved "https://registry.yarnpkg.com/@types/history/-/history-4.7.8.tgz#49348387983075705fe8f4e02fb67f7daaec4934"
+  integrity sha512-S78QIYirQcUoo6UJZx9CSP0O2ix9IaeAXwQi26Rhr/+mg7qqPy8TzaxHSUut7eGjL8WmLccT7/MXf304WjqHcA==
 
 "@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1":
   version "2.0.3"
@@ -1717,17 +1776,17 @@
     "@types/istanbul-lib-report" "*"
 
 "@types/jest@^26.0.10":
-  version "26.0.10"
-  resolved "https://registry.yarnpkg.com/@types/jest/-/jest-26.0.10.tgz#8faf7e9756c033c39014ae76a7329efea00ea607"
-  integrity sha512-i2m0oyh8w/Lum7wWK/YOZJakYF8Mx08UaKA1CtbmFeDquVhAEdA7znacsVSf2hJ1OQ/OfVMGN90pw/AtzF8s/Q==
+  version "26.0.14"
+  resolved "https://registry.yarnpkg.com/@types/jest/-/jest-26.0.14.tgz#078695f8f65cb55c5a98450d65083b2b73e5a3f3"
+  integrity sha512-Hz5q8Vu0D288x3iWXePSn53W7hAjP0H7EQ6QvDO9c7t46mR0lNOLlfuwQ+JkVxuhygHzlzPX+0jKdA3ZgSh+Vg==
   dependencies:
     jest-diff "^25.2.1"
     pretty-format "^25.2.1"
 
-"@types/json-schema@^7.0.3", "@types/json-schema@^7.0.4":
-  version "7.0.5"
-  resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.5.tgz#dcce4430e64b443ba8945f0290fb564ad5bac6dd"
-  integrity sha512-7+2BITlgjgDhH0vvwZU/HZJVyk+2XUlvxXe8dFMedNX/aMkaOq++rMAFXc0tM7ij15QaWlbdQASBR9dihi+bDQ==
+"@types/json-schema@^7.0.3", "@types/json-schema@^7.0.4", "@types/json-schema@^7.0.5":
+  version "7.0.6"
+  resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.6.tgz#f4c7ec43e81b319a9815115031709f26987891f0"
+  integrity sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw==
 
 "@types/json5@^0.0.29":
   version "0.0.29"
@@ -1735,9 +1794,9 @@
   integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4=
 
 "@types/lodash@^4.14.72":
-  version "4.14.160"
-  resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.160.tgz#2f1bba6500bc3cb9a732c6d66a083378fb0b0b29"
-  integrity sha512-aP03BShJoO+WVndoVj/WNcB/YBPt+CIU1mvaao2GRAHy2yg4pT/XS4XnVHEQBjPJGycWf/9seKEO9vopTJGkvA==
+  version "4.14.161"
+  resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.161.tgz#a21ca0777dabc6e4f44f3d07f37b765f54188b18"
+  integrity sha512-EP6O3Jkr7bXvZZSZYlsgt5DIjiGr0dXP1/jVEwVLTFgg0d+3lWVQkRavYVQszV7dYUwvg0B8R0MBDpcmXg7XIA==
 
 "@types/minimatch@*":
   version "3.0.3"
@@ -1757,20 +1816,25 @@
     "@types/node" "*"
 
 "@types/node@*":
-  version "14.6.0"
-  resolved "https://registry.yarnpkg.com/@types/node/-/node-14.6.0.tgz#7d4411bf5157339337d7cff864d9ff45f177b499"
-  integrity sha512-mikldZQitV94akrc4sCcSjtJfsTKt4p+e/s0AGscVA6XArQ9kFclP+ZiYUMnq987rc6QlYxXv/EivqlfSLxpKA==
+  version "14.11.1"
+  resolved "https://registry.yarnpkg.com/@types/node/-/node-14.11.1.tgz#56af902ad157e763f9ba63d671c39cda3193c835"
+  integrity sha512-oTQgnd0hblfLsJ6BvJzzSL+Inogp3lq9fGgqRkMB/ziKMgEUaFl801OncOzUmalfzt14N0oPHMK47ipl+wbTIw==
+
+"@types/node@12":
+  version "12.12.62"
+  resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.62.tgz#733923d73669188d35950253dd18a21570085d2b"
+  integrity sha512-qAfo81CsD7yQIM9mVyh6B/U47li5g7cfpVQEDMfQeF8pSZVwzbhwU3crc0qG4DmpsebpJPR49AKOExQyJ05Cpg==
 
-"@types/node@12", "@types/node@^12.0.12":
+"@types/node@^10.12.19":
+  version "10.17.35"
+  resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.35.tgz#58058f29b870e6ae57b20e4f6e928f02b7129f56"
+  integrity sha512-gXx7jAWpMddu0f7a+L+txMplp3FnHl53OhQIF9puXKq3hDGY/GjH+MF04oWnV/adPSCrbtHumDCFwzq2VhltWA==
+
+"@types/node@^12.0.12":
   version "12.12.54"
   resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.54.tgz#a4b58d8df3a4677b6c08bfbc94b7ad7a7a5f82d1"
   integrity sha512-ge4xZ3vSBornVYlDnk7yZ0gK6ChHf/CHB7Gl1I0Jhah8DDnEQqBzgohYG4FX4p81TNirSETOiSyn+y1r9/IR6w==
 
-"@types/node@^10.12.19":
-  version "10.17.28"
-  resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.28.tgz#0e36d718a29355ee51cec83b42d921299200f6d9"
-  integrity sha512-dzjES1Egb4c1a89C7lKwQh8pwjYmlOAG9dW1pBgxEk57tMrLnssOfEthz8kdkNaBd7lIqQx7APm5+mZ619IiCQ==
-
 "@types/normalize-package-data@^2.4.0":
   version "2.4.0"
   resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e"
@@ -1803,15 +1867,12 @@
   dependencies:
     "@types/react" "*"
 
-"@types/react-redux@^7.1.9":
-  version "7.1.9"
-  resolved "https://registry.yarnpkg.com/@types/react-redux/-/react-redux-7.1.9.tgz#280c13565c9f13ceb727ec21e767abe0e9b4aec3"
-  integrity sha512-mpC0jqxhP4mhmOl3P4ipRsgTgbNofMRXJb08Ms6gekViLj61v1hOZEKWDCyWsdONr6EjEA6ZHXC446wdywDe0w==
+"@types/react-panelgroup@^1.0.1":
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/@types/react-panelgroup/-/react-panelgroup-1.0.1.tgz#c25bf7d2a7c41323ef3744b191f128093675d9e5"
+  integrity sha512-dIeK8YQcS3yEyXhdsd8YpMK16ttWvrah2xQRiy6atqGmm6yPyHpvpzx4HldGWRJhsSjDWnl/6HHLaUV19dUo7w==
   dependencies:
-    "@types/hoist-non-react-statics" "^3.3.0"
     "@types/react" "*"
-    hoist-non-react-statics "^3.3.0"
-    redux "^4.0.0"
 
 "@types/react-router-dom@^5.1.5":
   version "5.1.5"
@@ -1844,15 +1905,7 @@
   dependencies:
     "@types/react" "*"
 
-"@types/react@*":
-  version "16.9.47"
-  resolved "https://registry.yarnpkg.com/@types/react/-/react-16.9.47.tgz#fb092936f0b56425f874d0ff1b08051fdf70c1ba"
-  integrity sha512-dAJO4VbrjYqTUwFiQqAKjLyHHl4RSTNnRyPdX3p16MPbDKvow51wxATUPxoe2QsiXNMEYrOjc2S6s92VjG+1VQ==
-  dependencies:
-    "@types/prop-types" "*"
-    csstype "^3.0.2"
-
-"@types/react@^16.9.49":
+"@types/react@*", "@types/react@^16.9.49":
   version "16.9.49"
   resolved "https://registry.yarnpkg.com/@types/react/-/react-16.9.49.tgz#09db021cf8089aba0cdb12a49f8021a69cce4872"
   integrity sha512-DtLFjSj0OYAdVLBbyjhuV9CdGVHCkHn2R+xr3XkBvK2rS1Y1tkc14XSGjYgm5Fjjr90AxH9tiSzc1pCFMGO06g==
@@ -1868,17 +1921,15 @@
     "@types/d3-shape" "*"
     "@types/react" "*"
 
-"@types/redux-logger@^3.0.8":
-  version "3.0.8"
-  resolved "https://registry.yarnpkg.com/@types/redux-logger/-/redux-logger-3.0.8.tgz#1fb6d26917bb198792bb1cf57feb31cae1532c5d"
-  integrity sha512-zM+cxiSw6nZtRbxpVp9SE3x/X77Z7e7YAfHD1NkxJyJbAGSXJGF0E9aqajZfPOa/sTYnuwutmlCldveExuCeLw==
-  dependencies:
-    redux "^4.0.0"
+"@types/regenerator-runtime@^0.13.0":
+  version "0.13.0"
+  resolved "https://registry.yarnpkg.com/@types/regenerator-runtime/-/regenerator-runtime-0.13.0.tgz#8b81e6047da0fbb71927c23d749e2a9edf9aad9b"
+  integrity sha512-U5osy6qZU3lOPGQRHGDIAt/hC/jAE7zP4Aq258UMXnF8/htmZ+72ALrSsmWTtqML7lCztKkKaPz6Pb5XHJF0Vw==
 
 "@types/semver@^7.3.1":
-  version "7.3.3"
-  resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.3.3.tgz#3ad6ed949e7487e7bda6f886b4a2434a2c3d7b1a"
-  integrity sha512-jQxClWFzv9IXdLdhSaTf16XI3NYe6zrEbckSpb5xhKfPbWgIyAY0AFyWWWfaiDcBuj3UHmMkCIwSRqpKMTZL2Q==
+  version "7.3.4"
+  resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.3.4.tgz#43d7168fec6fa0988bb1a513a697b29296721afb"
+  integrity sha512-+nVsLKlcUCeMzD2ufHEYuJ9a2ovstb6Dp52A5VsoKxDXgvE051XgHI/33I1EymwkRGQkwnA0LkhnUzituGs4EQ==
 
 "@types/source-list-map@*":
   version "0.1.2"
@@ -1915,9 +1966,9 @@
     "@types/react" "*"
 
 "@types/webpack-env@^1.15.2":
-  version "1.15.2"
-  resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.15.2.tgz#927997342bb9f4a5185a86e6579a0a18afc33b0a"
-  integrity sha512-67ZgZpAlhIICIdfQrB5fnDvaKFcDxpKibxznfYRVAT4mQE41Dido/3Ty+E3xGBmTogc5+0Qb8tWhna+5B8z1iQ==
+  version "1.15.3"
+  resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.15.3.tgz#fb602cd4c2f0b7c0fb857e922075fdf677d25d84"
+  integrity sha512-5oiXqR7kwDGZ6+gmzIO2lTC+QsriNuQXZDWNYRV3l2XRN/zmPgnC21DLSx2D05zvD8vnXW6qUg7JnXZ4I6qLVQ==
 
 "@types/webpack-sources@*":
   version "1.4.2"
@@ -1929,9 +1980,9 @@
     source-map "^0.7.3"
 
 "@types/webpack@^4.41.21":
-  version "4.41.21"
-  resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-4.41.21.tgz#cc685b332c33f153bb2f5fc1fa3ac8adeb592dee"
-  integrity sha512-2j9WVnNrr/8PLAB5csW44xzQSJwS26aOnICsP3pSGCEdsu6KYtfQ6QJsVUKHWRnm1bL7HziJsfh5fHqth87yKA==
+  version "4.41.22"
+  resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-4.41.22.tgz#ff9758a17c6bd499e459b91e78539848c32d0731"
+  integrity sha512-JQDJK6pj8OMV9gWOnN1dcLCyU9Hzs6lux0wBO4lr1+gyEhIBR9U3FMrz12t2GPkg110XAxEAw2WHF6g7nZIbRQ==
   dependencies:
     "@types/anymatch" "*"
     "@types/node" "*"
@@ -1953,12 +2004,12 @@
     "@types/yargs-parser" "*"
 
 "@typescript-eslint/eslint-plugin@^4.0.1":
-  version "4.0.1"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.0.1.tgz#88bde9239e29d688315718552cf80a3490491017"
-  integrity sha512-pQZtXupCn11O4AwpYVUX4PDFfmIJl90ZgrEBg0CEcqlwvPiG0uY81fimr1oMFblZnpKAq6prrT9a59pj1x58rw==
+  version "4.1.1"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.1.1.tgz#78d5b18e259b13c2f4ec41dd9105af269a161a75"
+  integrity sha512-Hoxyt99EA9LMmqo/5PuWWPeWeB3mKyvibfJ1Hy5SfiUpjE8Nqp+5QNd9fOkzL66+fqvIWSIE+Ett16LGMzCGnQ==
   dependencies:
-    "@typescript-eslint/experimental-utils" "4.0.1"
-    "@typescript-eslint/scope-manager" "4.0.1"
+    "@typescript-eslint/experimental-utils" "4.1.1"
+    "@typescript-eslint/scope-manager" "4.1.1"
     debug "^4.1.1"
     functional-red-black-tree "^1.0.1"
     regexpp "^3.0.0"
@@ -1976,15 +2027,15 @@
     eslint-scope "^5.0.0"
     eslint-utils "^2.0.0"
 
-"@typescript-eslint/experimental-utils@4.0.1":
-  version "4.0.1"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.0.1.tgz#7d9a3ab6821ad5274dad2186c1aa0d93afd696eb"
-  integrity sha512-gAqOjLiHoED79iYTt3F4uSHrYmg/GPz/zGezdB0jAdr6S6gwNiR/j7cTZ8nREKVzMVKLd9G3xbg1sV9GClW3sw==
+"@typescript-eslint/experimental-utils@4.1.1":
+  version "4.1.1"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.1.1.tgz#52ff4e37c93113eb96385a4e6d075abece1ea72d"
+  integrity sha512-jzYsNciHoa4Z3c1URtmeT/bamYm8Dwfw6vuN3WHIE/BXb1iC4KveAnXDErTAZtPVxTYBaYn3n2gbt6F6D2rm1A==
   dependencies:
     "@types/json-schema" "^7.0.3"
-    "@typescript-eslint/scope-manager" "4.0.1"
-    "@typescript-eslint/types" "4.0.1"
-    "@typescript-eslint/typescript-estree" "4.0.1"
+    "@typescript-eslint/scope-manager" "4.1.1"
+    "@typescript-eslint/types" "4.1.1"
+    "@typescript-eslint/typescript-estree" "4.1.1"
     eslint-scope "^5.0.0"
     eslint-utils "^2.0.0"
 
@@ -2010,32 +2061,32 @@
     eslint-visitor-keys "^1.1.0"
 
 "@typescript-eslint/parser@^4.0.1":
-  version "4.0.1"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.0.1.tgz#73772080db7a7a4534a35d719e006f503e664dc3"
-  integrity sha512-1+qLmXHNAWSQ7RB6fdSQszAiA7JTwzakj5cNYjBTUmpH2cqilxMZEIV+DRKjVZs8NzP3ALmKexB0w/ExjcK9Iw==
+  version "4.1.1"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.1.1.tgz#324b4b35e314075adbc92bd8330cf3ef0c88cf3e"
+  integrity sha512-NLIhmicpKGfJbdXyQBz9j48PA6hq6e+SDOoXy7Ak6bq1ebGqbgG+fR1UIDAuay6OjQdot69c/URu2uLlsP8GQQ==
   dependencies:
-    "@typescript-eslint/scope-manager" "4.0.1"
-    "@typescript-eslint/types" "4.0.1"
-    "@typescript-eslint/typescript-estree" "4.0.1"
+    "@typescript-eslint/scope-manager" "4.1.1"
+    "@typescript-eslint/types" "4.1.1"
+    "@typescript-eslint/typescript-estree" "4.1.1"
     debug "^4.1.1"
 
-"@typescript-eslint/scope-manager@4.0.1":
-  version "4.0.1"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.0.1.tgz#24d93c3000bdfcc5a157dc4d32b742405a8631b5"
-  integrity sha512-u3YEXVJ8jsj7QCJk3om0Y457fy2euEOkkzxIB/LKU3MdyI+FJ2gI0M4aKEaXzwCSfNDiZ13a3lDo5DVozc+XLQ==
+"@typescript-eslint/scope-manager@4.1.1":
+  version "4.1.1"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.1.1.tgz#bdb8526e82435f32b4ccd9dd4cec01af97b48850"
+  integrity sha512-0W8TTobCvIIQ2FsrYTffyZGAAFUyIbEHq5EYJb1m7Rpd005jrnOvKOo8ywCLhs/Bm17C+KsrUboBvBAARQVvyA==
   dependencies:
-    "@typescript-eslint/types" "4.0.1"
-    "@typescript-eslint/visitor-keys" "4.0.1"
+    "@typescript-eslint/types" "4.1.1"
+    "@typescript-eslint/visitor-keys" "4.1.1"
 
 "@typescript-eslint/types@3.10.1":
   version "3.10.1"
   resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-3.10.1.tgz#1d7463fa7c32d8a23ab508a803ca2fe26e758727"
   integrity sha512-+3+FCUJIahE9q0lDi1WleYzjCwJs5hIsbugIgnbB+dSCYUxl8L6PwmsyOPFZde2hc1DlTo/xnkOgiTLSyAbHiQ==
 
-"@typescript-eslint/types@4.0.1":
-  version "4.0.1"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.0.1.tgz#1cf72582f764931f085cb8230ff215980fe467b2"
-  integrity sha512-S+gD3fgbkZYW2rnbjugNMqibm9HpEjqZBZkTiI3PwbbNGWmAcxolWIUwZ0SKeG4Dy2ktpKKaI/6+HGYVH8Qrlg==
+"@typescript-eslint/types@4.1.1":
+  version "4.1.1"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.1.1.tgz#57500c4a86b28cb47094c1a62f1177ea279a09cb"
+  integrity sha512-zrBiqOKYerMTllKcn+BP+i1b7LW/EbMMYytroXMxUTvFPn1smkCu0D7lSAx29fTUO4jnwV0ljSvYQtn2vNrNxA==
 
 "@typescript-eslint/typescript-estree@2.34.0":
   version "2.34.0"
@@ -2064,13 +2115,13 @@
     semver "^7.3.2"
     tsutils "^3.17.1"
 
-"@typescript-eslint/typescript-estree@4.0.1":
-  version "4.0.1"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.0.1.tgz#29a43c7060641ec51c902d9f50ac7c5866ec479f"
-  integrity sha512-zGzleORFXrRWRJAMLTB2iJD1IZbCPkg4hsI8mGdpYlKaqzvKYSEWVAYh14eauaR+qIoZVWrXgYSXqLtTlxotiw==
+"@typescript-eslint/typescript-estree@4.1.1":
+  version "4.1.1"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.1.1.tgz#2015a84d71303ecdb6f46efd807ac19a51aab490"
+  integrity sha512-2AUg5v0liVBsqbGxBphbJ0QbGqSRVaF5qPoTPWcxop+66vMdU1h4CCvHxTC47+Qb+Pr4l2RhXDd41JNpwcQEKw==
   dependencies:
-    "@typescript-eslint/types" "4.0.1"
-    "@typescript-eslint/visitor-keys" "4.0.1"
+    "@typescript-eslint/types" "4.1.1"
+    "@typescript-eslint/visitor-keys" "4.1.1"
     debug "^4.1.1"
     globby "^11.0.1"
     is-glob "^4.0.1"
@@ -2085,12 +2136,12 @@
   dependencies:
     eslint-visitor-keys "^1.1.0"
 
-"@typescript-eslint/visitor-keys@4.0.1":
-  version "4.0.1"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.0.1.tgz#d4e8de62775f2a6db71c7e8539633680039fdd6c"
-  integrity sha512-yBSqd6FjnTzbg5RUy9J+9kJEyQjTI34JdGMJz+9ttlJzLCnGkBikxw+N5n2VDcc3CesbIEJ0MnZc5uRYnrEnCw==
+"@typescript-eslint/visitor-keys@4.1.1":
+  version "4.1.1"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.1.1.tgz#bb05664bf4bea28dc120d1da94f3027d42ab0f6f"
+  integrity sha512-/EOOXbA2ferGLG6RmCHEQ0lTTLkOlXYDgblCmQk3tIU7mTPLm4gKhFMeeUSe+bcchTUsKeCk8xcpbop5Zr/8Rw==
   dependencies:
-    "@typescript-eslint/types" "4.0.1"
+    "@typescript-eslint/types" "4.1.1"
     eslint-visitor-keys "^2.0.0"
 
 "@webassemblyjs/ast@1.9.0":
@@ -2282,9 +2333,9 @@ acorn-hammerhead@^0.3.0:
     "@types/estree" "^0.0.39"
 
 acorn-jsx@^5.2.0:
-  version "5.2.0"
-  resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.2.0.tgz#4c66069173d6fdd68ed85239fc256226182b2ebe"
-  integrity sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ==
+  version "5.3.1"
+  resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.1.tgz#fc8661e11b7ac1539c47dbfea2e72b3af34d267b"
+  integrity sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==
 
 acorn-walk@^7.1.1:
   version "7.2.0"
@@ -2339,12 +2390,22 @@ ajv-errors@^1.0.0:
   resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d"
   integrity sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==
 
-ajv-keywords@^3.1.0, ajv-keywords@^3.4.1:
+ajv-keywords@^3.1.0, ajv-keywords@^3.4.1, ajv-keywords@^3.5.2:
   version "3.5.2"
   resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d"
   integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==
 
-ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.0, ajv@^6.12.2, ajv@^6.12.3, ajv@^6.12.4:
+ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.0, ajv@^6.12.2, ajv@^6.12.4:
+  version "6.12.5"
+  resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.5.tgz#19b0e8bae8f476e5ba666300387775fb1a00a4da"
+  integrity sha512-lRF8RORchjpKG50/WFf8xmg7sgCLFiYNNnqdKflk63whMQcWR5ngGjiSXkL9bjxy6B2npOK2HSMN49jEBMSkag==
+  dependencies:
+    fast-deep-equal "^3.1.1"
+    fast-json-stable-stringify "^2.0.0"
+    json-schema-traverse "^0.4.1"
+    uri-js "^4.2.2"
+
+ajv@^6.12.3:
   version "6.12.4"
   resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.4.tgz#0614facc4522127fa713445c6bfd3ebd376e2234"
   integrity sha512-eienB2c9qVQs2KWexhkrdMLVDoIQCz5KSeLxwg9Lzk4DOfBtIK9PQwwufcsn1jjGuf9WZmqPMbGxOzfcuphJCQ==
@@ -2454,26 +2515,26 @@ anymatch@^3.0.3, anymatch@~3.1.1:
     normalize-path "^3.0.0"
     picomatch "^2.0.4"
 
-app-builder-bin@3.5.9:
-  version "3.5.9"
-  resolved "https://registry.yarnpkg.com/app-builder-bin/-/app-builder-bin-3.5.9.tgz#a3ac0c25286bac68357321cb2eaf7128b0bc0a4f"
-  integrity sha512-NSjtqZ3x2kYiDp3Qezsgukx/AUzKPr3Xgf9by4cYt05ILWGAptepeeu0Uv+7MO+41o6ujhLixTou8979JGg2Kg==
+app-builder-bin@3.5.10:
+  version "3.5.10"
+  resolved "https://registry.yarnpkg.com/app-builder-bin/-/app-builder-bin-3.5.10.tgz#4a7f9999fccc0c435b6284ae1366bc76a17c4a7d"
+  integrity sha512-Jd+GW68lR0NeetgZDo47PdWBEPdnD+p0jEa7XaxjRC8u6Oo/wgJsfKUkORRgr2NpkD19IFKN50P6JYy04XHFLQ==
 
-app-builder-lib@22.8.0:
-  version "22.8.0"
-  resolved "https://registry.yarnpkg.com/app-builder-lib/-/app-builder-lib-22.8.0.tgz#342a8976f50ae35cfd07412dbfd4f6c895b32eac"
-  integrity sha512-RGaIRjCUrqkmh6QOGsyekQPEOaVynHfmeh8JZuyUymFYUOFdzBbPamkA2nhBVBTkkgfjRHsxK7LhedFKPzvWEQ==
+app-builder-lib@22.8.1:
+  version "22.8.1"
+  resolved "https://registry.yarnpkg.com/app-builder-lib/-/app-builder-lib-22.8.1.tgz#02cd14c0a83d3a758675d28c327731832b2c0bc1"
+  integrity sha512-D/ac1+vuGIAAwEeTtXl8b+qWl7Gz/IQatFyzYl2ocag/7N8LqUjKzZFJJISQPWt6PFDPDH0oCj8/GMh63aV0yw==
   dependencies:
     "7zip-bin" "~5.0.3"
     "@develar/schema-utils" "~2.6.5"
     async-exit-hook "^2.0.1"
     bluebird-lst "^1.0.9"
-    builder-util "22.8.0"
+    builder-util "22.8.1"
     builder-util-runtime "8.7.2"
     chromium-pickle-js "^0.2.0"
-    debug "^4.1.1"
+    debug "^4.2.0"
     ejs "^3.1.3"
-    electron-publish "22.8.0"
+    electron-publish "22.8.1"
     fs-extra "^9.0.1"
     hosted-git-info "^3.0.5"
     is-ci "^2.0.0"
@@ -2616,6 +2677,11 @@ arrify@^1.0.1:
   resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d"
   integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=
 
+asap@~2.0.3:
+  version "2.0.6"
+  resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46"
+  integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=
+
 asar@^2.0.1:
   version "2.1.0"
   resolved "https://registry.yarnpkg.com/asar/-/asar-2.1.0.tgz#97c6a570408c4e38a18d4a3fb748a621b5a7844e"
@@ -2743,7 +2809,7 @@ atob@^2.1.2:
   resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9"
   integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==
 
-autoprefixer@^9.8.0:
+autoprefixer@^9.8.6:
   version "9.8.6"
   resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.8.6.tgz#3b73594ca1bf9266320c5acf1588d74dea74210f"
   integrity sha512-XrvP4VVHdRBCdX1S3WXVD8+RyG9qeb1D5Sn1DeLiG2xfSpzellk5k54xbUERJ3M5DggQxes39UGOTP8CFrEGbg==
@@ -3602,6 +3668,11 @@ balanced-match@^1.0.0:
   resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
   integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c=
 
+base16@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/base16/-/base16-1.0.0.tgz#e297f60d7ec1014a7a971a39ebc8a98c0b681e70"
+  integrity sha1-4pf2DX7BAUp6lxo568ipjAtoHnA=
+
 base64-js@^1.0.2, base64-js@^1.1.2:
   version "1.3.1"
   resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1"
@@ -3740,9 +3811,9 @@ bowser@1.6.0:
   integrity sha1-N/w4e2Fstq7zcNq01r1AK3TFxU0=
 
 bowser@^2.8.1:
-  version "2.10.0"
-  resolved "https://registry.yarnpkg.com/bowser/-/bowser-2.10.0.tgz#be3736f161c4bb8b10958027ab99465d2a811198"
-  integrity sha512-OCsqTQboTEWWsUjcp5jLSw2ZHsBiv2C105iFs61bOT0Hnwi9p7/uuXdd7mu8RYcarREfdjNN+8LitmEHATsLYg==
+  version "2.11.0"
+  resolved "https://registry.yarnpkg.com/bowser/-/bowser-2.11.0.tgz#5ca3c35757a7aa5771500c70a73a9f91ef420a8f"
+  integrity sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==
 
 boxen@^4.2.0:
   version "4.2.0"
@@ -3867,11 +3938,6 @@ browserify-zlib@^0.2.0:
   dependencies:
     pako "~1.0.5"
 
-browserslist-config-erb@^0.0.1:
-  version "0.0.1"
-  resolved "https://registry.yarnpkg.com/browserslist-config-erb/-/browserslist-config-erb-0.0.1.tgz#0a93648bbe11fac5b9fe555bf061f31980db64db"
-  integrity sha512-QQQzCXrYVVdSWxO0UuV+f2HGBt7xdGRRvgr49W1lcwoyXNpRQFVi5cTz8+B/rLHyBkWd4JbRFeTIKHAw7BpCBg==
-
 browserslist@^3.2.6:
   version "3.2.8"
   resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-3.2.8.tgz#b0005361d6471f0f5952797a76fc985f1f978fc6"
@@ -3880,7 +3946,17 @@ browserslist@^3.2.6:
     caniuse-lite "^1.0.30000844"
     electron-to-chromium "^1.3.47"
 
-browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.12.2, browserslist@^4.8.5:
+browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.8.5:
+  version "4.14.3"
+  resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.14.3.tgz#381f9e7f13794b2eb17e1761b4f118e8ae665a53"
+  integrity sha512-GcZPC5+YqyPO4SFnz48/B0YaCwS47Q9iPChRGi6t7HhflKBcINzFrJvRfC+jp30sRMKxF+d4EHGs27Z0XP1NaQ==
+  dependencies:
+    caniuse-lite "^1.0.30001131"
+    electron-to-chromium "^1.3.570"
+    escalade "^3.1.0"
+    node-releases "^1.1.61"
+
+browserslist@^4.12.2:
   version "4.14.0"
   resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.14.0.tgz#2908951abfe4ec98737b72f34c3bcedc8d43b000"
   integrity sha512-pUsXKAF2lVwhmtpeA3LJrZ76jXuusrNyhduuQs7CDFf9foT4Y38aQOserd2lMe5DSSrjf3fx34oHwryuvxAUgQ==
@@ -3934,19 +4010,19 @@ builder-util-runtime@8.7.2:
     debug "^4.1.1"
     sax "^1.2.4"
 
-builder-util@22.8.0:
-  version "22.8.0"
-  resolved "https://registry.yarnpkg.com/builder-util/-/builder-util-22.8.0.tgz#01684085d1f2370b1bd182f69cbd007426f63f64"
-  integrity sha512-H80P1JzVy3TGpi63x81epQDK24XalL034+jAZlrPb5IhLtYmnNNdxCCAVJvg3VjSISd73Y71O+uhqCxWpqbPHw==
+builder-util@22.8.1:
+  version "22.8.1"
+  resolved "https://registry.yarnpkg.com/builder-util/-/builder-util-22.8.1.tgz#efdfb327dbc22c59aa1e2f55adbe0e771086e839"
+  integrity sha512-LZG+E1xszMdut5hL5h7RkJQ7yOsQqdhJYgn1wvOP7MmF3MoUPRNDiRodLpYiWlaqZmgYhcfaipR/Mb8F/RqK8w==
   dependencies:
     "7zip-bin" "~5.0.3"
     "@types/debug" "^4.1.5"
     "@types/fs-extra" "^9.0.1"
-    app-builder-bin "3.5.9"
+    app-builder-bin "3.5.10"
     bluebird-lst "^1.0.9"
     builder-util-runtime "8.7.2"
     chalk "^4.1.0"
-    debug "^4.1.1"
+    debug "^4.2.0"
     fs-extra "^9.0.1"
     is-ci "^2.0.0"
     js-yaml "^3.14.0"
@@ -4123,10 +4199,10 @@ caniuse-db@^1.0.30001090:
   resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30001118.tgz#60f56de236d7b68859d9a377a7f2f69092283247"
   integrity sha512-yMoV0unAwrdNkqKbNI4jlyUHrLsBYrzf9IOYTNxhy3t1onqpLK2nH0IPHzr2isrmmY8pQ6UPqFGka/8Gc8Yt9w==
 
-caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000844, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001111:
-  version "1.0.30001118"
-  resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001118.tgz#116a9a670e5264aec895207f5e918129174c6f62"
-  integrity sha512-RNKPLojZo74a0cP7jFMidQI7nvLER40HgNfgKQEJ2PFm225L0ectUungNQoK3Xk3StQcFbpBPNEvoWD59436Hg==
+caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000844, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001111, caniuse-lite@^1.0.30001131:
+  version "1.0.30001132"
+  resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001132.tgz#309279274f10d3aa736aa91fa269fcc8d0cd7ef9"
+  integrity sha512-zk5FXbnsmHa0Ktc/NOZJRr+ilXva+2KFJuRiQfnjkxJfV/7DYP5C27lSQF++/veCUzVWE5xecZnSBJjf6fSwJA==
 
 capture-exit@^2.0.0:
   version "2.0.0"
@@ -4351,9 +4427,9 @@ clean-stack@^2.0.0:
   integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==
 
 cli-boxes@^2.2.0:
-  version "2.2.0"
-  resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.0.tgz#538ecae8f9c6ca508e3c3c95b453fe93cb4c168d"
-  integrity sha512-gpaBrMAizVEANOpfZp/EEUixTXDyGt7DFzdK5hU+UbWt/J0lB0w20ncZj59Z9a93xHb9u12zF5BS6i9RKbtg4w==
+  version "2.2.1"
+  resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.1.tgz#ddd5035d25094fce220e9cab40a45840a440318f"
+  integrity sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==
 
 cli-cursor@^2.1.0:
   version "2.1.0"
@@ -4548,9 +4624,9 @@ commander@^2.18.0, commander@^2.19.0, commander@^2.20.0, commander@^2.8.1:
   integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
 
 commander@^6.0.0:
-  version "6.0.0"
-  resolved "https://registry.yarnpkg.com/commander/-/commander-6.0.0.tgz#2b270da94f8fb9014455312f829a1129dbf8887e"
-  integrity sha512-s7EA+hDtTYNhuXkTlhqew4txMZVdszBmKWSPEMxGr8ru8JXR7bLUFIAtPhcSuFdJQ0ILMxnJi8GkQL0yvDy/YA==
+  version "6.1.0"
+  resolved "https://registry.yarnpkg.com/commander/-/commander-6.1.0.tgz#f8d722b78103141006b66f4c7ba1e97315ba75bc"
+  integrity sha512-wl7PNrYWd2y5mp1OK/LhTlv8Ff4kQJQRXXAvF+uU/TPNiVJUxZLRYGj/B0y/lPGAVcSbJqH2Za/cvHmrPMC8mA==
 
 commondir@^1.0.1:
   version "1.0.1"
@@ -4602,7 +4678,7 @@ concat-stream@^1.5.0, concat-stream@^1.6.2:
     readable-stream "^2.2.2"
     typedarray "^0.0.6"
 
-concurrently@^5.2.0:
+concurrently@^5.3.0:
   version "5.3.0"
   resolved "https://registry.yarnpkg.com/concurrently/-/concurrently-5.3.0.tgz#7500de6410d043c912b2da27de3202cb489b1e7b"
   integrity sha512-8MhqOB6PWlBfA2vJ8a0bSFKATOdWlHiQlk11IfmQBPaHVP8oP2gsh2MObE6UR3hqDHqvaIvLTyceNW6obVuFHQ==
@@ -4647,13 +4723,6 @@ connect-history-api-fallback@^1.6.0:
   resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz#8b32089359308d111115d81cad3fceab888f97bc"
   integrity sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==
 
-connected-react-router@^6.6.1:
-  version "6.8.0"
-  resolved "https://registry.yarnpkg.com/connected-react-router/-/connected-react-router-6.8.0.tgz#ddc687b31d498322445d235d660798489fa56cae"
-  integrity sha512-E64/6krdJM3Ag3MMmh2nKPtMbH15s3JQDuaYJvOVXzu6MbHbDyIvuwLOyhQIuP4Om9zqEfZYiVyflROibSsONg==
-  dependencies:
-    prop-types "^15.7.2"
-
 console-browserify@^1.1.0:
   version "1.2.0"
   resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336"
@@ -4763,17 +4832,6 @@ cosmiconfig@^5.0.0:
     js-yaml "^3.13.1"
     parse-json "^4.0.0"
 
-cosmiconfig@^6.0.0:
-  version "6.0.0"
-  resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-6.0.0.tgz#da4fee853c52f6b1e6935f41c1a2fc50bd4a9982"
-  integrity sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==
-  dependencies:
-    "@types/parse-json" "^4.0.0"
-    import-fresh "^3.1.0"
-    parse-json "^5.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"
@@ -4816,7 +4874,7 @@ create-hmac@^1.1.0, create-hmac@^1.1.4, create-hmac@^1.1.7:
     safe-buffer "^5.0.1"
     sha.js "^2.4.8"
 
-cross-env@^7.0.0:
+cross-env@^7.0.2:
   version "7.0.2"
   resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-7.0.2.tgz#bd5ed31339a93a3418ac4f3ca9ca3403082ae5f9"
   integrity sha512-KZP/bMEOJEDCkDQAyRhu3RL2ZO/SUVrxQVI0G3YEQ+OLbRA3c6zgixe8Mq8a/z7+HKlNEjo8oiLUs8iRijY2Rw==
@@ -4843,11 +4901,6 @@ cross-spawn@^7.0.0, cross-spawn@^7.0.1, cross-spawn@^7.0.2:
     shebang-command "^2.0.0"
     which "^2.0.1"
 
-cross-unzip@0.0.2:
-  version "0.0.2"
-  resolved "https://registry.yarnpkg.com/cross-unzip/-/cross-unzip-0.0.2.tgz#5183bc47a09559befcf98cc4657964999359372f"
-  integrity sha1-UYO8R6CVWb78+YzEZXlkmZNZNy8=
-
 crypto-browserify@^3.11.0:
   version "3.12.0"
   resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec"
@@ -5178,9 +5231,9 @@ data-urls@^2.0.0:
     whatwg-url "^8.0.0"
 
 date-fns@^2.0.1:
-  version "2.15.0"
-  resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.15.0.tgz#424de6b3778e4e69d3ff27046ec136af58ae5d5f"
-  integrity sha512-ZCPzAMJZn3rNUvvQIMlXhDr4A+Ar07eLeGsGREoWU19a3Pqf5oYa+ccd+B3F6XVtQY6HANMFdOQ8A+ipFnvJdQ==
+  version "2.16.1"
+  resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.16.1.tgz#05775792c3f3331da812af253e1a935851d3834b"
+  integrity sha512-sAJVKx/FqrLYHAQeN7VpJrPhagZc9R4ImZIWYRFZaaohR3KzmuK88touwsSwSVT8Qcbd4zoDsnGfX4GFB4imyQ==
 
 debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.5.1, debug@^2.6.0, debug@^2.6.8, debug@^2.6.9:
   version "2.6.9"
@@ -5189,7 +5242,7 @@ debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.5.1, debug@^2.6.0, debug@^2.6.
   dependencies:
     ms "2.0.0"
 
-debug@4.1.1, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1:
+debug@4.1.1:
   version "4.1.1"
   resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791"
   integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==
@@ -5203,6 +5256,13 @@ debug@^3.1.1, debug@^3.2.5:
   dependencies:
     ms "^2.1.1"
 
+debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.2.0:
+  version "4.2.0"
+  resolved "https://registry.yarnpkg.com/debug/-/debug-4.2.0.tgz#7f150f93920e94c58f5574c2fd01a3110effe7f1"
+  integrity sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==
+  dependencies:
+    ms "2.1.2"
+
 decamelize-keys@^1.1.0:
   version "1.1.0"
   resolved "https://registry.yarnpkg.com/decamelize-keys/-/decamelize-keys-1.1.0.tgz#d171a87933252807eb3cb61dc1c1445d078df2d9"
@@ -5253,11 +5313,6 @@ dedent@^0.7.0:
   resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c"
   integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=
 
-deep-diff@^0.3.5:
-  version "0.3.8"
-  resolved "https://registry.yarnpkg.com/deep-diff/-/deep-diff-0.3.8.tgz#c01de63efb0eec9798801d40c7e0dae25b582c84"
-  integrity sha1-wB3mPvsO7JeYgB1Ax+Da4ltYLIQ=
-
 deep-eql@^3.0.1:
   version "3.0.1"
   resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-3.0.1.tgz#dfc9404400ad1c8fe023e7da1df1c147c4b444df"
@@ -5312,7 +5367,7 @@ defer-to-connect@^1.0.1:
   resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.1.3.tgz#331ae050c08dcf789f8c83a7b81f0ed94f4ac591"
   integrity sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==
 
-define-properties@^1.1.2, define-properties@^1.1.3:
+define-properties@^1.1.3:
   version "1.1.3"
   resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1"
   integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==
@@ -5496,13 +5551,13 @@ discontinuous-range@1.0.0:
   resolved "https://registry.yarnpkg.com/discontinuous-range/-/discontinuous-range-1.0.0.tgz#e38331f0844bba49b9a9cb71c771585aab1bc65a"
   integrity sha1-44Mx8IRLukm5qctxx3FYWqsbxlo=
 
-dmg-builder@22.8.0:
-  version "22.8.0"
-  resolved "https://registry.yarnpkg.com/dmg-builder/-/dmg-builder-22.8.0.tgz#2b17127837ed444db3086317eda5cf8912f6e6a9"
-  integrity sha512-orePWjcrl97SYLA8F/6UUtbXJSoZCYu5KOP1lVqD4LOomr8bjGDyEVYZmZYcg5WqKmXucdmO6OpqgzH/aRMMuA==
+dmg-builder@22.8.1:
+  version "22.8.1"
+  resolved "https://registry.yarnpkg.com/dmg-builder/-/dmg-builder-22.8.1.tgz#9b3bcbbc43e5fed232525d61a5567ea4b66085c3"
+  integrity sha512-WeGom1moM00gBII6swljl4DQGrlJuEivoUhOmh8U9p1ALgeJL+EiTHbZFERlj8Ejy62xUUjURV+liOxUKmJFWg==
   dependencies:
-    app-builder-lib "22.8.0"
-    builder-util "22.8.0"
+    app-builder-lib "22.8.1"
+    builder-util "22.8.1"
     fs-extra "^9.0.1"
     iconv-lite "^0.6.2"
     js-yaml "^3.14.0"
@@ -5597,9 +5652,9 @@ domelementtype@1, domelementtype@^1.3.0, domelementtype@^1.3.1:
   integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==
 
 domelementtype@^2.0.1:
-  version "2.0.1"
-  resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.0.1.tgz#1f8bdfe91f5a78063274e803b4bdcedf6e94f94d"
-  integrity sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ==
+  version "2.0.2"
+  resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.0.2.tgz#f3b6e549201e46f588b59463dd77187131fe6971"
+  integrity sha512-wFwTwCVebUrMgGeAwRL/NhZtHAUyT9n9yg4IMDwf10+6iCMxSkVq9MGCVEH+QZWo1nNidy8kNvwmv4zWHDTqvA==
 
 domexception@^2.0.1:
   version "2.0.1"
@@ -5632,9 +5687,9 @@ domutils@^1.5.1, domutils@^1.7.0:
     domelementtype "1"
 
 dot-prop@^5.2.0:
-  version "5.2.0"
-  resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.2.0.tgz#c34ecc29556dc45f1f4c22697b6f4904e0cc4fcb"
-  integrity sha512-uEUyaDKoSQ1M4Oq8l45hSE26SnTxL6snNnqvK/VWx5wJhmff5z0FUVJDKDanor/6w3kzE3i7XZOk+7wC0EXr1A==
+  version "5.3.0"
+  resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.3.0.tgz#90ccce708cd9cd82cc4dc8c3ddd9abdd55b20e88"
+  integrity sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==
   dependencies:
     is-obj "^2.0.0"
 
@@ -5699,76 +5754,47 @@ ejs@^3.1.3:
     jake "^10.6.1"
 
 electron-builder@^22.3.6:
-  version "22.8.0"
-  resolved "https://registry.yarnpkg.com/electron-builder/-/electron-builder-22.8.0.tgz#d2c9fc5438c834e41fd794a271fca200165a3bad"
-  integrity sha512-dUv4F3srJouqxhWivtKqSoQP4Df6vYgjooGdzms+iYMTFi9f0b4LlEbr7kgsPvte8zAglee7VOGOODkCRJDkUQ==
+  version "22.8.1"
+  resolved "https://registry.yarnpkg.com/electron-builder/-/electron-builder-22.8.1.tgz#84295190dae17b3892df7aa39ac334983aeaea06"
+  integrity sha512-Hs7KTMq1rGSvT0fwGKXrjbLiJkK6sAKDQooUSwklOkktUgWi4ATjlP0fVE3l8SmS7zcLoww2yDZonSDqxEFhaQ==
   dependencies:
     "@types/yargs" "^15.0.5"
-    app-builder-lib "22.8.0"
+    app-builder-lib "22.8.1"
     bluebird-lst "^1.0.9"
-    builder-util "22.8.0"
+    builder-util "22.8.1"
     builder-util-runtime "8.7.2"
     chalk "^4.1.0"
-    dmg-builder "22.8.0"
+    dmg-builder "22.8.1"
     fs-extra "^9.0.1"
     is-ci "^2.0.0"
     lazy-val "^1.0.4"
     read-config-file "6.0.0"
     sanitize-filename "^1.6.3"
     update-notifier "^4.1.0"
-    yargs "^15.3.1"
-
-electron-debug@^3.1.0:
-  version "3.1.0"
-  resolved "https://registry.yarnpkg.com/electron-debug/-/electron-debug-3.1.0.tgz#0df17297487fa3c82344d810812853bf67f0bd69"
-  integrity sha512-SWEqLj4MgfV3tGuO5eBLQ5/Nr6M+KPxsnE0bUJZvQebGJus6RAcdmvd7L+l0Ji31h2mmrN23l2tHFtCa2FvurA==
-  dependencies:
-    electron-is-dev "^1.1.0"
-    electron-localshortcut "^3.1.0"
-
-electron-devtools-installer@^2.2.4:
-  version "2.2.4"
-  resolved "https://registry.yarnpkg.com/electron-devtools-installer/-/electron-devtools-installer-2.2.4.tgz#261a50337e37121d338b966f07922eb4939a8763"
-  integrity sha512-b5kcM3hmUqn64+RUcHjjr8ZMpHS2WJ5YO0pnG9+P/RTdx46of/JrEjuciHWux6pE+On6ynWhHJF53j/EDJN0PA==
-  dependencies:
-    "7zip" "0.0.6"
-    cross-unzip "0.0.2"
-    rimraf "^2.5.2"
-    semver "^5.3.0"
-
-electron-is-accelerator@^0.1.0:
-  version "0.1.2"
-  resolved "https://registry.yarnpkg.com/electron-is-accelerator/-/electron-is-accelerator-0.1.2.tgz#509e510c26a56b55e17f863a4b04e111846ab27b"
-  integrity sha1-UJ5RDCala1Xhf4Y6SwThEYRqsns=
-
-electron-is-dev@^1.1.0:
-  version "1.2.0"
-  resolved "https://registry.yarnpkg.com/electron-is-dev/-/electron-is-dev-1.2.0.tgz#2e5cea0a1b3ccf1c86f577cee77363ef55deb05e"
-  integrity sha512-R1oD5gMBPS7PVU8gJwH6CtT0e6VSoD0+SzSnYpNm+dBkcijgA+K7VAMHDfnRq/lkKPZArpzplTW6jfiMYosdzw==
+    yargs "^15.4.1"
 
-electron-localshortcut@^3.1.0:
-  version "3.2.1"
-  resolved "https://registry.yarnpkg.com/electron-localshortcut/-/electron-localshortcut-3.2.1.tgz#cfc83a3eff5e28faf98ddcc87f80a2ce4f623cd3"
-  integrity sha512-DWvhKv36GsdXKnaFFhEiK8kZZA+24/yFLgtTwJJHc7AFgDjNRIBJZ/jq62Y/dWv9E4ypYwrVWN2bVrCYw1uv7Q==
+electron-devtools-installer@^3.1.1:
+  version "3.1.1"
+  resolved "https://registry.yarnpkg.com/electron-devtools-installer/-/electron-devtools-installer-3.1.1.tgz#7b56c8c86475c5e4e10de6917d150c53c9ceb55e"
+  integrity sha512-g2D4J6APbpsiIcnLkFMyKZ6bOpEJ0Ltcc2m66F7oKUymyGAt628OWeU9nRZoh1cNmUs/a6Cls2UfOmsZtE496Q==
   dependencies:
-    debug "^4.0.1"
-    electron-is-accelerator "^0.1.0"
-    keyboardevent-from-electron-accelerator "^2.0.0"
-    keyboardevents-areequal "^0.2.1"
+    rimraf "^3.0.2"
+    semver "^7.2.1"
+    unzip-crx-3 "^0.2.0"
 
-electron-log@^4.2.2:
+electron-log@^4.2.4:
   version "4.2.4"
   resolved "https://registry.yarnpkg.com/electron-log/-/electron-log-4.2.4.tgz#a13e42a9fc42ca2cc7d2603c3746352efa82112e"
   integrity sha512-CXbDU+Iwi+TjKzugKZmTRIORIPe3uQRqgChUl19fkW/reFUn5WP7dt+cNGT3bkLV8xfPilpkPFv33HgtmLLewQ==
 
-electron-publish@22.8.0:
-  version "22.8.0"
-  resolved "https://registry.yarnpkg.com/electron-publish/-/electron-publish-22.8.0.tgz#7f410fe043abc5d3d896c4ee9eea7a43ea352c7d"
-  integrity sha512-uM0Zdi9hUqqGOrPj478v7toTvV1Kgto1w11rIiI168batiXAJvNLD8VZRfehOrZT0ibUyZlw8FtxoGCrjyHUOw==
+electron-publish@22.8.1:
+  version "22.8.1"
+  resolved "https://registry.yarnpkg.com/electron-publish/-/electron-publish-22.8.1.tgz#747e0d7f921cd1808f999713d29f599dbb390c4f"
+  integrity sha512-zqI66vl7j1CJZJ60J+1ez1tQNQeuqVspW44JvYDa5kZbM5wSFDAJFMK9RWHOqRF1Ezd4LDeiBa4aeTOwOt9syA==
   dependencies:
     "@types/fs-extra" "^9.0.1"
     bluebird-lst "^1.0.9"
-    builder-util "22.8.0"
+    builder-util "22.8.1"
     builder-util-runtime "8.7.2"
     chalk "^4.1.0"
     fs-extra "^9.0.1"
@@ -5795,15 +5821,15 @@ electron-rebuild@^1.10.0:
     spawn-rx "^3.0.0"
     yargs "^14.2.0"
 
-electron-to-chromium@^1.3.47, electron-to-chromium@^1.3.523:
-  version "1.3.548"
-  resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.548.tgz#b1bda6b24f7a1c1fa6250bb039a0bbed148f26f2"
-  integrity sha512-Xf4m3GFwCEcQ+4W45IHeZ6enPC1i+8/3aaXz8Pcd2VkNLULP0DMvoP7aKv2tQ+M/CH2SC7Qlm4S6DpzZUS2w1Q==
+electron-to-chromium@^1.3.47, electron-to-chromium@^1.3.523, electron-to-chromium@^1.3.570:
+  version "1.3.570"
+  resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.570.tgz#3f5141cc39b4e3892a276b4889980dabf1d29c7f"
+  integrity sha512-Y6OCoVQgFQBP5py6A/06+yWxUZHDlNr/gNDGatjH8AZqXl8X0tE4LfjLJsXGz/JmWJz8a6K7bR1k+QzZ+k//fg==
 
-electron-updater@^4.3.1:
-  version "4.3.4"
-  resolved "https://registry.yarnpkg.com/electron-updater/-/electron-updater-4.3.4.tgz#6003f88be9004d7834e4dd757167033d0fc2d29a"
-  integrity sha512-ekpgxDrYl+Wi24ktO4qfj2CtCABxrmK1C/oekp0tai6q4VR4ZdPkit4CX8+GenvKMme7uMmfPFnLp/vwhP/ThQ==
+electron-updater@^4.3.5:
+  version "4.3.5"
+  resolved "https://registry.yarnpkg.com/electron-updater/-/electron-updater-4.3.5.tgz#4fb36f593a031c87ea07ee141c9f064d5deffb15"
+  integrity sha512-5jjN7ebvfj1cLI0VZMdCnJk6aC4bP+dy7ryBf21vArR0JzpRVk0OZHA2QBD+H5rm6ZSeDYHOY6+8PrMEqJ4wlQ==
   dependencies:
     "@types/semver" "^7.3.1"
     builder-util-runtime "8.7.2"
@@ -5813,10 +5839,10 @@ electron-updater@^4.3.1:
     lodash.isequal "^4.5.0"
     semver "^7.3.2"
 
-electron@^8:
-  version "8.5.0"
-  resolved "https://registry.yarnpkg.com/electron/-/electron-8.5.0.tgz#a202738672214775fda27450b00ee516a66bffc4"
-  integrity sha512-ERqSTRlaQ4PqME5a1z9DWQbwQy2LbgSN1Jnau1MJCRRvHgq1FJlqbbb/ij/RGWuQuaxy4Djb2KnTs5rsemR5mQ==
+electron@^10:
+  version "10.1.2"
+  resolved "https://registry.yarnpkg.com/electron/-/electron-10.1.2.tgz#30b6fd7669f8daf08c56219a61dfa053fa2b0c70"
+  integrity sha512-SvN8DcKCmPZ0UcQSNAJBfaUu+LGACqtRhUn1rW0UBLHgdbbDM76L0GU5/XGQEllH5pu5bwlCZwax3srzIl+Aeg==
   dependencies:
     "@electron/get" "^1.0.1"
     "@types/node" "^12.0.12"
@@ -5880,6 +5906,13 @@ encodeurl@^1.0.2, encodeurl@~1.0.2:
   resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
   integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=
 
+encoding@^0.1.11:
+  version "0.1.13"
+  resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9"
+  integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==
+  dependencies:
+    iconv-lite "^0.6.2"
+
 end-of-stream@^1.0.0, end-of-stream@^1.1.0:
   version "1.4.4"
   resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0"
@@ -5936,9 +5969,9 @@ env-paths@^2.2.0:
   integrity sha512-6u0VYSCo/OW6IoD5WCLLy9JUGARbamfSavcNXry/eu8aHVFei6CD3Sw+VGX5alea1i9pgPHW0mbu6Xj0uBh7gA==
 
 enzyme-adapter-react-16@^1.15.2:
-  version "1.15.3"
-  resolved "https://registry.yarnpkg.com/enzyme-adapter-react-16/-/enzyme-adapter-react-16-1.15.3.tgz#90154055be3318d70a51df61ac89cfa22e3d5f60"
-  integrity sha512-98rqNI4n9HZslWIPuuwy4hK1bxRuMy+XX0CU1dS8iUqcgisTxeBaap6oPp2r4MWC8OphCbbqAT8EU/xHz3zIaQ==
+  version "1.15.4"
+  resolved "https://registry.yarnpkg.com/enzyme-adapter-react-16/-/enzyme-adapter-react-16-1.15.4.tgz#328a782365a363ecb424f99283c4833dd92c0f21"
+  integrity sha512-wPzxs+JaGDK2TPYzl5a9YWGce6i2SQ3Cg51ScLeyj2WotUZ8Obcq1ke/U1Y2VGpYlb9rrX2yCjzSMgtKCeAt5w==
   dependencies:
     enzyme-adapter-utils "^1.13.1"
     enzyme-shallow-equal "^1.0.4"
@@ -6076,10 +6109,10 @@ es6-error@^4.1.1:
   resolved "https://registry.yarnpkg.com/es6-error/-/es6-error-4.1.1.tgz#9e3af407459deed47e9a91f9b885a84eb05c561d"
   integrity sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==
 
-escalade@^3.0.2:
-  version "3.0.2"
-  resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.0.2.tgz#6a580d70edb87880f22b4c91d0d56078df6962c4"
-  integrity sha512-gPYAU37hYCUhW5euPeR+Y74F7BL+IBsV93j5cvGriSaD1aG6MGsqsV1yamRdrWrb2j3aiZvb0X+UBOWpx3JWtQ==
+escalade@^3.0.2, escalade@^3.1.0:
+  version "3.1.0"
+  resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.0.tgz#e8e2d7c7a8b76f6ee64c2181d6b8151441602d4e"
+  integrity sha512-mAk+hPSO8fLDkhV7V0dXazH5pDc6MrjBTPyD3VeKzxnVFjH1MIxbCdqGZB9O8+EwWakZs3ZCbDS4IpRt79V1ig==
 
 escape-goat@^2.0.0:
   version "2.1.1"
@@ -6145,13 +6178,6 @@ eslint-config-airbnb@^18.2.0:
     object.assign "^4.1.0"
     object.entries "^1.1.2"
 
-eslint-config-erb@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/eslint-config-erb/-/eslint-config-erb-1.0.0.tgz#f6dd13de09e3ed805b30576a6f20532e0753bf72"
-  integrity sha512-UvmtvjCxaPkYzmpDLYDjmvAxoTggpW+NWYT/Dq4QkfMPqx1nAooU+YU3QsTFrme3x3xp8fj1n3cvimO1kwxb1g==
-  dependencies:
-    babel-eslint "^10.1.0"
-
 eslint-config-prettier@^6.11.0:
   version "6.11.0"
   resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-6.11.0.tgz#f6d2238c1290d01c859a8b5c1f7d352a0b0da8b1"
@@ -6261,9 +6287,9 @@ eslint-plugin-promise@^4.2.1:
   integrity sha512-VoM09vT7bfA7D+upt+FjeBO5eHIJQBUWki1aPvB+vbNiHS3+oGIJGIeyBtKQTME6UPXXy3vV07OL1tHd3ANuDw==
 
 eslint-plugin-react-hooks@^4.0.8:
-  version "4.1.0"
-  resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.1.0.tgz#6323fbd5e650e84b2987ba76370523a60f4e7925"
-  integrity sha512-36zilUcDwDReiORXmcmTc6rRumu9JIM3WjSvV0nclHoUQ0CNrX866EwONvLR/UqaeqFutbAnVu8PEmctdo2SRQ==
+  version "4.1.2"
+  resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.1.2.tgz#2eb53731d11c95826ef7a7272303eabb5c9a271e"
+  integrity sha512-ykUeqkGyUGgwTtk78C0o8UG2fzwmgJ0qxBGPp2WqRKsTwcLuVf01kTDRAtOsd4u6whX2XOC8749n2vPydP82fg==
 
 eslint-plugin-react@^7.20.3:
   version "7.20.6"
@@ -6296,11 +6322,11 @@ eslint-scope@^4.0.3:
     estraverse "^4.1.1"
 
 eslint-scope@^5.0.0, eslint-scope@^5.1.0:
-  version "5.1.0"
-  resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.0.tgz#d0f971dfe59c69e0cada684b23d49dbf82600ce5"
-  integrity sha512-iiGRvtxWqgtx5m8EyQUJihBloE4EnYeGE/bz1wSPwJE6tZuJUtHlhqDM4Xj2ukE8Dyy1+HCZ4hE0fzIVMzb58w==
+  version "5.1.1"
+  resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c"
+  integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==
   dependencies:
-    esrecurse "^4.1.0"
+    esrecurse "^4.3.0"
     estraverse "^4.1.1"
 
 eslint-utils@^2.0.0, eslint-utils@^2.1.0:
@@ -6320,10 +6346,10 @@ eslint-visitor-keys@^2.0.0:
   resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz#21fdc8fbcd9c795cc0321f0563702095751511a8"
   integrity sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==
 
-eslint@^7.8.1:
-  version "7.8.1"
-  resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.8.1.tgz#e59de3573fb6a5be8ff526c791571646d124a8fa"
-  integrity sha512-/2rX2pfhyUG0y+A123d0ccXtMm7DV7sH1m3lk9nk2DZ2LReq39FXHueR9xZwshE5MdfSf0xunSaMWRqyIA6M1w==
+eslint@^7.9.0:
+  version "7.9.0"
+  resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.9.0.tgz#522aeccc5c3a19017cf0cb46ebfd660a79acf337"
+  integrity sha512-V6QyhX21+uXp4T+3nrNfI3hQNBDa/P8ga7LoQOenwrlEFXrEnUEE+ok1dMtaS3b6rmLXhT1TkTIsG75HMLbknA==
   dependencies:
     "@babel/code-frame" "^7.0.0"
     "@eslint/eslintrc" "^0.1.3"
@@ -6363,10 +6389,10 @@ eslint@^7.8.1:
     text-table "^0.2.0"
     v8-compile-cache "^2.0.3"
 
-esotope-hammerhead@0.5.5:
-  version "0.5.5"
-  resolved "https://registry.yarnpkg.com/esotope-hammerhead/-/esotope-hammerhead-0.5.5.tgz#dccae8ffe588238c3c3db9b78df45fe95add498a"
-  integrity sha512-EuSYJDtF8gLMB24lzjHw2KotauPsVJybFrtGfQyMm48oC7sTkspA26DqcqcbnRl4GC6sPVKWEx+ex72eqopX9Q==
+esotope-hammerhead@0.5.6:
+  version "0.5.6"
+  resolved "https://registry.yarnpkg.com/esotope-hammerhead/-/esotope-hammerhead-0.5.6.tgz#f846638bc10adf068642decdf54b9a9ac856ccfb"
+  integrity sha512-E5cJKuecAEt/psafJ8rBjAezBS5/5iqyzgzRPH2JWEhZYTRzkphX9c9djqpJj8Zcfv7PpqgNgXXbaqxgCIVsPw==
   dependencies:
     "@types/estree" "^0.0.39"
 
@@ -6391,19 +6417,19 @@ esquery@^1.2.0:
   dependencies:
     estraverse "^5.1.0"
 
-esrecurse@^4.1.0:
-  version "4.2.1"
-  resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf"
-  integrity sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==
+esrecurse@^4.1.0, esrecurse@^4.3.0:
+  version "4.3.0"
+  resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921"
+  integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==
   dependencies:
-    estraverse "^4.1.0"
+    estraverse "^5.2.0"
 
-estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0:
+estraverse@^4.1.1, estraverse@^4.2.0:
   version "4.3.0"
   resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d"
   integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==
 
-estraverse@^5.1.0:
+estraverse@^5.1.0, estraverse@^5.2.0:
   version "5.2.0"
   resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880"
   integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==
@@ -6653,7 +6679,7 @@ fast-glob@^2.2.6:
     merge2 "^1.2.3"
     micromatch "^3.1.10"
 
-fast-glob@^3.0.3, fast-glob@^3.1.1:
+fast-glob@^3.0.3, fast-glob@^3.1.1, fast-glob@^3.2.4:
   version "3.2.4"
   resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.4.tgz#d20aefbf99579383e7f3cc66529158c9b98554d3"
   integrity sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ==
@@ -6675,6 +6701,11 @@ fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6:
   resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
   integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=
 
+fastest-levenshtein@^1.0.12:
+  version "1.0.12"
+  resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz#9990f7d3a88cc5a9ffd1f1745745251700d497e2"
+  integrity sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==
+
 fastq@^1.6.0:
   version "1.8.0"
   resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.8.0.tgz#550e1f9f59bbc65fe185cb6a9b4d95357107f481"
@@ -6703,6 +6734,26 @@ fb-watchman@^2.0.0:
   dependencies:
     bser "2.1.1"
 
+fbemitter@^2.0.0:
+  version "2.1.1"
+  resolved "https://registry.yarnpkg.com/fbemitter/-/fbemitter-2.1.1.tgz#523e14fdaf5248805bb02f62efc33be703f51865"
+  integrity sha1-Uj4U/a9SSIBbsC9i78M75wP1GGU=
+  dependencies:
+    fbjs "^0.8.4"
+
+fbjs@^0.8.0, fbjs@^0.8.4:
+  version "0.8.17"
+  resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.17.tgz#c4d598ead6949112653d6588b01a5cdcd9f90fdd"
+  integrity sha1-xNWY6taUkRJlPWWIsBpc3Nn5D90=
+  dependencies:
+    core-js "^1.0.0"
+    isomorphic-fetch "^2.1.1"
+    loose-envify "^1.0.0"
+    object-assign "^4.1.0"
+    promise "^7.1.1"
+    setimmediate "^1.0.5"
+    ua-parser-js "^0.7.18"
+
 fd-slicer@~1.1.0:
   version "1.1.0"
   resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e"
@@ -6730,12 +6781,12 @@ file-entry-cache@^5.0.1:
     flat-cache "^2.0.1"
 
 file-loader@^6.0.0:
-  version "6.0.0"
-  resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-6.0.0.tgz#97bbfaab7a2460c07bcbd72d3a6922407f67649f"
-  integrity sha512-/aMOAYEFXDdjG0wytpTL5YQLfZnnTmLNjn+AIrJ/6HVnTfDqLsVKUUwkDf4I4kgex36BvjuXEn/TX9B/1ESyqQ==
+  version "6.1.0"
+  resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-6.1.0.tgz#65b9fcfb0ea7f65a234a1f10cdd7f1ab9a33f253"
+  integrity sha512-26qPdHyTsArQ6gU4P1HJbAbnFTyT2r0pG7czh1GFAd9TZbj0n94wWbupgixZH/ET/meqi2/5+F7DhW4OAXD+Lg==
   dependencies:
     loader-utils "^2.0.0"
-    schema-utils "^2.6.5"
+    schema-utils "^2.7.1"
 
 file-uri-to-path@1.0.0:
   version "1.0.0"
@@ -6876,6 +6927,14 @@ flush-write-stream@^1.0.0:
     inherits "^2.0.3"
     readable-stream "^2.3.6"
 
+flux@^3.1.3:
+  version "3.1.3"
+  resolved "https://registry.yarnpkg.com/flux/-/flux-3.1.3.tgz#d23bed515a79a22d933ab53ab4ada19d05b2f08a"
+  integrity sha1-0jvtUVp5oi2TOrU6tK2hnQWy8Io=
+  dependencies:
+    fbemitter "^2.0.0"
+    fbjs "^0.8.0"
+
 follow-redirects@^1.0.0:
   version "1.13.0"
   resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.13.0.tgz#b42e8d93a2a7eea5ed88633676d6597bc8e384db"
@@ -7380,7 +7439,7 @@ has-flag@^4.0.0:
   resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b"
   integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==
 
-has-symbols@^1.0.0, has-symbols@^1.0.1:
+has-symbols@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8"
   integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==
@@ -7676,14 +7735,14 @@ human-signals@^1.1.1:
   integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==
 
 husky@^4.2.5:
-  version "4.2.5"
-  resolved "https://registry.yarnpkg.com/husky/-/husky-4.2.5.tgz#2b4f7622673a71579f901d9885ed448394b5fa36"
-  integrity sha512-SYZ95AjKcX7goYVZtVZF2i6XiZcHknw50iXvY7b0MiGoj5RwdgRQNEHdb+gPDPCXKlzwrybjFjkL6FOj8uRhZQ==
+  version "4.3.0"
+  resolved "https://registry.yarnpkg.com/husky/-/husky-4.3.0.tgz#0b2ec1d66424e9219d359e26a51c58ec5278f0de"
+  integrity sha512-tTMeLCLqSBqnflBZnlVDhpaIMucSGaYyX6855jM4AguGeWCeSzNdb1mfyWduTZ3pe3SJVvVWGL0jO1iKZVPfTA==
   dependencies:
     chalk "^4.0.0"
     ci-info "^2.0.0"
     compare-versions "^3.6.0"
-    cosmiconfig "^6.0.0"
+    cosmiconfig "^7.0.0"
     find-versions "^3.2.0"
     opencollective-postinstall "^2.0.2"
     pkg-dir "^4.2.0"
@@ -7751,10 +7810,10 @@ ignore@^5.1.1, ignore@^5.1.4, ignore@^5.1.8:
   resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57"
   integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==
 
-immer@^7.0.3:
-  version "7.0.8"
-  resolved "https://registry.yarnpkg.com/immer/-/immer-7.0.8.tgz#41dcbc5669a76500d017bef3ad0d03ce0a1d7c1e"
-  integrity sha512-XnpIN8PXBBaOD43U8Z17qg6RQiKQYGDGGCIbz1ixmLGwBkSWwmrmx5X7d+hTtXDM8ur7m5OdLE0PiO+y5RB3pw==
+immediate@~3.0.5:
+  version "3.0.6"
+  resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b"
+  integrity sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=
 
 import-fresh@^2.0.0:
   version "2.0.0"
@@ -7764,7 +7823,7 @@ import-fresh@^2.0.0:
     caller-path "^2.0.0"
     resolve-from "^3.0.0"
 
-import-fresh@^3.0.0, import-fresh@^3.1.0, import-fresh@^3.2.1:
+import-fresh@^3.0.0, import-fresh@^3.2.1:
   version "3.2.1"
   resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.2.1.tgz#633ff618506e793af5ac91bf48b72677e15cbe66"
   integrity sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==
@@ -7990,7 +8049,12 @@ is-buffer@^2.0.0:
   resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.4.tgz#3e572f23c8411a5cfd9557c849e3665e0b290623"
   integrity sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==
 
-is-callable@^1.1.4, is-callable@^1.1.5, is-callable@^1.2.0:
+is-callable@^1.1.4, is-callable@^1.2.0:
+  version "1.2.1"
+  resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.1.tgz#4d1e21a4f437509d25ce55f8184350771421c96d"
+  integrity sha512-wliAfSzx6V+6WfMOmus1xy0XvSgf/dlStkvTfq7F0g4bOIW0PSUbnyse3NhDwdyYS1ozfUtAAySqTws3z9Eqgg==
+
+is-callable@^1.1.5:
   version "1.2.0"
   resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.0.tgz#83336560b54a38e35e3a2df7afd0454d691468bb"
   integrity sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==
@@ -8300,7 +8364,7 @@ is-resolvable@^1.0.0:
   resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88"
   integrity sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==
 
-is-stream@^1.1.0:
+is-stream@^1.0.1, is-stream@^1.1.0:
   version "1.1.0"
   resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
   integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ=
@@ -8408,6 +8472,14 @@ isobject@^3.0.0, isobject@^3.0.1:
   resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df"
   integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8=
 
+isomorphic-fetch@^2.1.1:
+  version "2.2.1"
+  resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9"
+  integrity sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=
+  dependencies:
+    node-fetch "^1.0.1"
+    whatwg-fetch ">=0.10.0"
+
 isstream@~0.1.2:
   version "0.1.2"
   resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
@@ -8942,9 +9014,9 @@ json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2:
   integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==
 
 json-parse-even-better-errors@^2.3.0:
-  version "2.3.0"
-  resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.0.tgz#371873c5ffa44304a6ba12419bcfa95f404ae081"
-  integrity sha512-o3aP+RsWDJZayj1SbHNQAI8x0v3T3SKiGoZlNYfbUP1S3omJQ6i9CnqADqkSPaOAxwua4/1YWx5CM7oiChJt2Q==
+  version "2.3.1"
+  resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d"
+  integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==
 
 json-schema-traverse@^0.4.1:
   version "0.4.1"
@@ -9094,15 +9166,15 @@ jsx-ast-utils@^2.4.1:
     array-includes "^3.1.1"
     object.assign "^4.1.0"
 
-keyboardevent-from-electron-accelerator@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/keyboardevent-from-electron-accelerator/-/keyboardevent-from-electron-accelerator-2.0.0.tgz#ace21b1aa4e47148815d160057f9edb66567c50c"
-  integrity sha512-iQcmNA0M4ETMNi0kG/q0h/43wZk7rMeKYrXP7sqKIJbHkTU8Koowgzv+ieR/vWJbOwxx5nDC3UnudZ0aLSu4VA==
-
-keyboardevents-areequal@^0.2.1:
-  version "0.2.2"
-  resolved "https://registry.yarnpkg.com/keyboardevents-areequal/-/keyboardevents-areequal-0.2.2.tgz#88191ec738ce9f7591c25e9056de928b40277194"
-  integrity sha512-Nv+Kr33T0mEjxR500q+I6IWisOQ0lK1GGOncV0kWE6n4KFmpcu7RUX5/2B0EUtX51Cb0HjZ9VJsSY3u4cBa0kw==
+jszip@^3.1.0:
+  version "3.5.0"
+  resolved "https://registry.yarnpkg.com/jszip/-/jszip-3.5.0.tgz#b4fd1f368245346658e781fec9675802489e15f6"
+  integrity sha512-WRtu7TPCmYePR1nazfrtuF216cIVon/3GWOvHS9QR5bIwSbnxtdpma6un3jyGGNhHsKCSzn5Ypk+EkDRvTGiFA==
+  dependencies:
+    lie "~3.3.0"
+    pako "~1.0.2"
+    readable-stream "~2.3.6"
+    set-immediate-shim "~1.0.1"
 
 keyv@^3.0.0:
   version "3.1.0"
@@ -9215,15 +9287,22 @@ levn@~0.3.0:
     prelude-ls "~1.1.2"
     type-check "~0.3.2"
 
+lie@~3.3.0:
+  version "3.3.0"
+  resolved "https://registry.yarnpkg.com/lie/-/lie-3.3.0.tgz#dcf82dee545f46074daf200c7c1c5a08e0f40f6a"
+  integrity sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==
+  dependencies:
+    immediate "~3.0.5"
+
 lines-and-columns@^1.1.6:
   version "1.1.6"
   resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00"
   integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=
 
 lint-staged@^10.2.11:
-  version "10.2.13"
-  resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-10.2.13.tgz#b9c504683470edfc464b7d3fe3845a5a1efcd814"
-  integrity sha512-conwlukNV6aL9SiMWjFtDp5exeDnTMekdNPDZsKGnpfQuHcO0E3L3Bbf58lcR+M7vk6LpCilxDAVks/DDVBYlA==
+  version "10.4.0"
+  resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-10.4.0.tgz#d18628f737328e0bbbf87d183f4020930e9a984e"
+  integrity sha512-uaiX4U5yERUSiIEQc329vhCTDDwUcSvKdRLsNomkYLRzijk3v8V9GWm2Nz0RMVB87VcuzLvtgy6OsjoH++QHIg==
   dependencies:
     chalk "^4.1.0"
     cli-truncate "^2.1.0"
@@ -9249,9 +9328,9 @@ linux-platform-info@^0.0.3:
     os-family "^1.0.0"
 
 listr2@^2.6.0:
-  version "2.6.0"
-  resolved "https://registry.yarnpkg.com/listr2/-/listr2-2.6.0.tgz#788a3d202978a1b8582062952cbc49272c8e206a"
-  integrity sha512-nwmqTJYQQ+AsKb4fCXH/6/UmLCEDL1jkRAdSn9M6cEUzoRGrs33YD/3N86gAZQnGZ6hxV18XSdlBcJ1GTmetJA==
+  version "2.6.2"
+  resolved "https://registry.yarnpkg.com/listr2/-/listr2-2.6.2.tgz#4912eb01e1e2dd72ec37f3895a56bf2622d6f36a"
+  integrity sha512-6x6pKEMs8DSIpA/tixiYY2m/GcbgMplMVmhQAaLFxEtNSKLeWTGjtmU57xvv6QCm2XcqzyNXL/cTSVf4IChCRA==
   dependencies:
     chalk "^4.1.0"
     cli-truncate "^2.1.0"
@@ -9333,6 +9412,11 @@ lodash.assign@^4.2.0:
   resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7"
   integrity sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=
 
+lodash.curry@^4.0.1:
+  version "4.1.1"
+  resolved "https://registry.yarnpkg.com/lodash.curry/-/lodash.curry-4.1.1.tgz#248e36072ede906501d75966200a86dab8b23170"
+  integrity sha1-JI42By7ekGUB11lmIAqG2riyMXA=
+
 lodash.debounce@^4.0.8:
   version "4.0.8"
   resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af"
@@ -9348,6 +9432,11 @@ lodash.flattendeep@^4.4.0:
   resolved "https://registry.yarnpkg.com/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz#fb030917f86a3134e5bc9bec0d69e0013ddfedb2"
   integrity sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=
 
+lodash.flow@^3.3.0:
+  version "3.5.0"
+  resolved "https://registry.yarnpkg.com/lodash.flow/-/lodash.flow-3.5.0.tgz#87bf40292b8cf83e4e8ce1a3ae4209e20071675a"
+  integrity sha1-h79AKSuM+D5OjOGjrkIJ4gBxZ1o=
+
 lodash.isequal@^4.5.0:
   version "4.5.0"
   resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0"
@@ -9607,10 +9696,10 @@ memory-fs@^0.5.0:
     errno "^0.1.3"
     readable-stream "^2.0.1"
 
-meow@^7.0.1:
-  version "7.1.0"
-  resolved "https://registry.yarnpkg.com/meow/-/meow-7.1.0.tgz#50ecbcdafa16f8b58fb7eb9675b933f6473b3a59"
-  integrity sha512-kq5F0KVteskZ3JdfyQFivJEj2RaA8NFsS4+r9DaMKLcUHpk5OcHS3Q0XkCXONB1mZRPsu/Y/qImKri0nwSEZog==
+meow@^7.1.1:
+  version "7.1.1"
+  resolved "https://registry.yarnpkg.com/meow/-/meow-7.1.1.tgz#7c01595e3d337fcb0ec4e8eed1666ea95903d306"
+  integrity sha512-GWHvA5QOcS412WCo8vwKDlTelGLsCGBVevQB5Kva961rmNfun0PCbv5+xta2kUMFJyR8/oWnn7ddeKdosbAPbA==
   dependencies:
     "@types/minimist" "^1.2.0"
     camelcase-keys "^6.2.2"
@@ -9887,9 +9976,9 @@ moment-duration-format-commonjs@^1.0.0:
   integrity sha512-MVFR4hIh4jfuwSCPBEE5CCwn3refvTsxK/Yv/DpKJ6YcNnCimlVJ6DQeTJG1KVQPw1o8m3tkbHE9gVjivyv9iA==
 
 moment@^2.10.3, moment@^2.14.1:
-  version "2.27.0"
-  resolved "https://registry.yarnpkg.com/moment/-/moment-2.27.0.tgz#8bff4e3e26a236220dfe3e36de756b6ebaa0105d"
-  integrity sha512-al0MUK7cpIcglMv3YF13qSgdAIqxHTO7brRtaz3DlSULbqfazqkc5kEjNrLDOM7fsjshoFIihnU8snrP7zUvhQ==
+  version "2.28.0"
+  resolved "https://registry.yarnpkg.com/moment/-/moment-2.28.0.tgz#cdfe73ce01327cee6537b0fafac2e0f21a237d75"
+  integrity sha512-Z5KOjYmnHyd/ukynmFd/WwyXHd7L4J9vTI/nn5Ap9AVUgaAE15VvQ9MOGmJJygEUklupqIrFnor/tjTwRU+tQw==
 
 moo@^0.5.0:
   version "0.5.1"
@@ -9918,7 +10007,7 @@ ms@2.1.1:
   resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a"
   integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==
 
-ms@^2.1.1:
+ms@2.1.2, ms@^2.1.1:
   version "2.1.2"
   resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
   integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
@@ -9946,11 +10035,6 @@ nan@^2.12.1:
   resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.1.tgz#d7be34dfa3105b91494c3147089315eff8874b01"
   integrity sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==
 
-nanoid@^0.2.2:
-  version "0.2.2"
-  resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-0.2.2.tgz#e2ebc6ad3db5e0454fd8124d30ca39b06555fe56"
-  integrity sha512-GHoRrvNEKiwdkwQ/enKL8AhQkkrBC/2KxMZkDvQzp8OtkpX8ZAmoYJWFVl7l8F2+HcEJUfdg21Ab2wXXfrvACQ==
-
 nanoid@^1.0.1:
   version "1.3.4"
   resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-1.3.4.tgz#ad89f62c9d1f4fd69710d4a90953d2893d2d31f4"
@@ -9961,6 +10045,11 @@ nanoid@^2.1.3:
   resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-2.1.11.tgz#ec24b8a758d591561531b4176a01e3ab4f0f0280"
   integrity sha512-s/snB+WGm6uwi0WjsZdaVcuf3KJXlfGl2LcxgwkEwJF0D/BWzVWAZW/XY4bFaiR7s0Jk3FPvlnepg1H1b1UwlA==
 
+nanoid@^3.1.12:
+  version "3.1.12"
+  resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.12.tgz#6f7736c62e8d39421601e4a0c77623a97ea69654"
+  integrity sha512-1qstj9z5+x491jfiC4Nelk+f8XBad7LN20PmyWINJEMRSf3wcAjAWysw1qaA8z6NSKe2sjq1hRSDpBH5paCb6A==
+
 nanomatch@^1.2.9:
   version "1.2.13"
   resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119"
@@ -10016,6 +10105,14 @@ node-abi@^2.11.0:
   dependencies:
     semver "^5.4.1"
 
+node-fetch@^1.0.1:
+  version "1.7.3"
+  resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef"
+  integrity sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==
+  dependencies:
+    encoding "^0.1.11"
+    is-stream "^1.0.1"
+
 node-forge@0.9.0:
   version "0.9.0"
   resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.9.0.tgz#d624050edbb44874adca12bb9a52ec63cb782579"
@@ -10098,10 +10195,10 @@ node-notifier@^8.0.0:
     uuid "^8.3.0"
     which "^2.0.2"
 
-node-releases@^1.1.60:
-  version "1.1.60"
-  resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.60.tgz#6948bdfce8286f0b5d0e5a88e8384e954dfe7084"
-  integrity sha512-gsO4vjEdQaTusZAEebUWp2a5d7dF5DYoIpDG7WySnk7BuZDW+GPpHXoXXuYawRBr/9t5q54tirPz79kFIWg4dA==
+node-releases@^1.1.60, node-releases@^1.1.61:
+  version "1.1.61"
+  resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.61.tgz#707b0fca9ce4e11783612ba4a2fcba09047af16e"
+  integrity sha512-DD5vebQLg8jLCOzwupn954fbIiZht05DAZs0k2u8NStSe6h9XdsuIQL8hSRKYiU8WUQRznmSDrKGbv3ObOmC7g==
 
 node-version@^1.0.0:
   version "1.2.0"
@@ -10254,7 +10351,7 @@ object-is@^1.0.1, object-is@^1.0.2, object-is@^1.1.2:
     define-properties "^1.1.3"
     es-abstract "^1.17.5"
 
-object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1:
+object-keys@^1.0.12, object-keys@^1.1.1:
   version "1.1.1"
   resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e"
   integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==
@@ -10267,14 +10364,14 @@ object-visit@^1.0.0:
     isobject "^3.0.0"
 
 object.assign@^4.1.0:
-  version "4.1.0"
-  resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da"
-  integrity sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==
+  version "4.1.1"
+  resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.1.tgz#303867a666cdd41936ecdedfb1f8f3e32a478cdd"
+  integrity sha512-VT/cxmx5yaoHSOTSyrCygIDFco+RsibY2NM0a4RdEeY/4KgqezwFtK1yr3U67xYhqJSlASm2pKhLVzPj2lr4bA==
   dependencies:
-    define-properties "^1.1.2"
-    function-bind "^1.1.1"
-    has-symbols "^1.0.0"
-    object-keys "^1.0.11"
+    define-properties "^1.1.3"
+    es-abstract "^1.18.0-next.0"
+    has-symbols "^1.0.1"
+    object-keys "^1.1.1"
 
 object.entries@^1.1.1, object.entries@^1.1.2:
   version "1.1.2"
@@ -10364,9 +10461,9 @@ opencollective-postinstall@^2.0.2, opencollective-postinstall@^2.0.3:
   integrity sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q==
 
 opener@^1.5.1:
-  version "1.5.1"
-  resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.1.tgz#6d2f0e77f1a0af0032aca716c2c1fbb8e7e8abed"
-  integrity sha512-goYSy5c2UXE4Ra1xixabeVh1guIX/ZV/YokJksb6q2lubWu6UbvPQ20p542/sFIll1nl8JnCyK9oBaOcCWXwvA==
+  version "1.5.2"
+  resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.2.tgz#5d37e1f35077b9dcac4301372271afdeb2a13598"
+  integrity sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==
 
 opn@^5.5.0:
   version "5.5.0"
@@ -10376,9 +10473,9 @@ opn@^5.5.0:
     is-wsl "^1.1.0"
 
 optimize-css-assets-webpack-plugin@^5.0.3:
-  version "5.0.3"
-  resolved "https://registry.yarnpkg.com/optimize-css-assets-webpack-plugin/-/optimize-css-assets-webpack-plugin-5.0.3.tgz#e2f1d4d94ad8c0af8967ebd7cf138dcb1ef14572"
-  integrity sha512-q9fbvCRS6EYtUKKSwI87qm2IxlyJK5b4dygW1rKUBT6mMDhdG5e5bZT63v6tnJR9F9FB/H5a0HTmtw+laUBxKA==
+  version "5.0.4"
+  resolved "https://registry.yarnpkg.com/optimize-css-assets-webpack-plugin/-/optimize-css-assets-webpack-plugin-5.0.4.tgz#85883c6528aaa02e30bbad9908c92926bb52dc90"
+  integrity sha512-wqd6FdI2a5/FdoiCNNkEvLeA//lHHfG24Ln2Xm2qqdIk4aOlsR18jwpyOihqQ8849W3qu2DX8fOYxpvTMj+93A==
   dependencies:
     cssnano "^4.1.10"
     last-call-webpack-plugin "^3.0.0"
@@ -10567,7 +10664,7 @@ package-json@^6.3.0:
     registry-url "^5.0.0"
     semver "^6.2.0"
 
-pako@~1.0.5:
+pako@~1.0.2, pako@~1.0.5:
   version "1.0.11"
   resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf"
   integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==
@@ -10814,16 +10911,16 @@ pinkie-promise@^2.0.0:
   dependencies:
     pinkie "^2.0.0"
 
-pinkie@1.0.0, pinkie@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-1.0.0.tgz#5a47f28ba1015d0201bda7bf0f358e47bec8c7e4"
-  integrity sha1-Wkfyi6EBXQIBvae/DzWOR77Ix+Q=
-
-pinkie@^2.0.0, pinkie@^2.0.1, pinkie@^2.0.4:
+pinkie@2.0.4, pinkie@^2.0.0, pinkie@^2.0.1, pinkie@^2.0.4:
   version "2.0.4"
   resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870"
   integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA=
 
+pinkie@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-1.0.0.tgz#5a47f28ba1015d0201bda7bf0f358e47bec8c7e4"
+  integrity sha1-Wkfyi6EBXQIBvae/DzWOR77Ix+Q=
+
 pirates@^4.0.0, pirates@^4.0.1:
   version "4.0.1"
   resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.1.tgz#643a92caf894566f91b2b986d2c66950a8e2fb87"
@@ -10884,9 +10981,9 @@ posix-character-classes@^0.1.0:
   integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=
 
 postcss-calc@^7.0.1:
-  version "7.0.3"
-  resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-7.0.3.tgz#d65cca92a3c52bf27ad37a5f732e0587b74f1623"
-  integrity sha512-IB/EAEmZhIMEIhG7Ov4x+l47UaXOS1n2f4FBUk/aKllQhtSCxWhTzn0nJgkqN7fo/jcWySvWTSB6Syk9L+31bA==
+  version "7.0.4"
+  resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-7.0.4.tgz#5e177ddb417341e6d4a193c5d9fd8ada79094f8b"
+  integrity sha512-0I79VRAd1UTkaHzY9w83P39YGO/M3bG7/tNLrHGEunBolfoGM0hSjrGvjoeaj0JE/zIw5GsI2KZ0UwDJqv5hjw==
   dependencies:
     postcss "^7.0.27"
     postcss-selector-parser "^6.0.2"
@@ -11163,16 +11260,6 @@ postcss-reduce-transforms@^4.0.2:
     postcss "^7.0.0"
     postcss-value-parser "^3.0.0"
 
-postcss-reporter@^6.0.1:
-  version "6.0.1"
-  resolved "https://registry.yarnpkg.com/postcss-reporter/-/postcss-reporter-6.0.1.tgz#7c055120060a97c8837b4e48215661aafb74245f"
-  integrity sha512-LpmQjfRWyabc+fRygxZjpRxfhRf9u/fdlKf4VHG4TSPbV2XNsuISzYW1KL+1aQzx53CAppa1bKG4APIB/DOXXw==
-  dependencies:
-    chalk "^2.4.1"
-    lodash "^4.17.11"
-    log-symbols "^2.2.0"
-    postcss "^7.0.7"
-
 postcss-resolve-nested-selector@^0.1.1:
   version "0.1.1"
   resolved "https://registry.yarnpkg.com/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.1.tgz#29ccbc7c37dedfac304e9fff0bf1596b3f6a0e4e"
@@ -11252,7 +11339,16 @@ postcss-value-parser@^4.0.2, postcss-value-parser@^4.1.0:
   resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz#443f6a20ced6481a2bda4fa8532a6e55d789a2cb"
   integrity sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==
 
-postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.14, postcss@^7.0.2, postcss@^7.0.21, postcss@^7.0.26, postcss@^7.0.27, postcss@^7.0.32, postcss@^7.0.5, postcss@^7.0.6, postcss@^7.0.7:
+postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.14, postcss@^7.0.2, postcss@^7.0.21, postcss@^7.0.26, postcss@^7.0.27, postcss@^7.0.32, postcss@^7.0.6:
+  version "7.0.34"
+  resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.34.tgz#f2baf57c36010df7de4009940f21532c16d65c20"
+  integrity sha512-H/7V2VeNScX9KE83GDrDZNiGT1m2H+UTnlinIzhjlLX9hfMUn1mHNnGeX81a1c8JSBdBvqk7c2ZOG6ZPn5itGw==
+  dependencies:
+    chalk "^2.4.2"
+    source-map "^0.6.1"
+    supports-color "^6.1.0"
+
+postcss@^7.0.5:
   version "7.0.32"
   resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.32.tgz#4310d6ee347053da3433db2be492883d62cec59d"
   integrity sha512-03eXong5NLnNCD05xscnGKGDZ98CyzoqPSMjOe6SuoQY7Z2hIj0Ld1g/O/UQRuOle2aRtiIRDg9tDcTGAkLfKw==
@@ -11289,9 +11385,9 @@ prettier-linter-helpers@^1.0.0:
     fast-diff "^1.1.2"
 
 prettier@^2.1.1:
-  version "2.1.1"
-  resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.1.1.tgz#d9485dd5e499daa6cb547023b87a6cf51bee37d6"
-  integrity sha512-9bY+5ZWCfqj3ghYBLxApy2zf6m+NJo5GzmLTpr9FsApsfjriNnS2dahWReHMi7qNPhhHl9SYHJs2cHZLgexNIw==
+  version "2.1.2"
+  resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.1.2.tgz#3050700dae2e4c8b67c4c3f666cdb8af405e1ce5"
+  integrity sha512-16c7K+x4qVlJg9rEbXl7HEGmQyZlG4R9AgP+oHKRMsMsuk8s+ATStlf1NpDqyBI1HpVyfjLOeMhH2LvuNvV5Vg==
 
 pretty-format@^25.2.1, pretty-format@^25.5.0:
   version "25.5.0"
@@ -11338,6 +11434,13 @@ promise-inflight@^1.0.1:
   resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3"
   integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM=
 
+promise@^7.1.1:
+  version "7.3.1"
+  resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf"
+  integrity sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==
+  dependencies:
+    asap "~2.0.3"
+
 promisify-event@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/promisify-event/-/promisify-event-1.0.0.tgz#bd7523ea06b70162f370979016b53a686c60e90f"
@@ -11462,6 +11565,11 @@ pupa@^2.0.1:
   dependencies:
     escape-goat "^2.0.0"
 
+pure-color@^1.2.0:
+  version "1.3.0"
+  resolved "https://registry.yarnpkg.com/pure-color/-/pure-color-1.3.0.tgz#1fe064fb0ac851f0de61320a8bf796836422f33e"
+  integrity sha1-H+Bk+wrIUfDeYTIKi/eWg2Qi8z4=
+
 q@^1.1.2:
   version "1.5.1"
   resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7"
@@ -11570,6 +11678,16 @@ rc@^1.2.8:
     minimist "^1.2.0"
     strip-json-comments "~2.0.1"
 
+react-base16-styling@^0.6.0:
+  version "0.6.0"
+  resolved "https://registry.yarnpkg.com/react-base16-styling/-/react-base16-styling-0.6.0.tgz#ef2156d66cf4139695c8a167886cb69ea660792c"
+  integrity sha1-7yFW1mz0E5aVyKFniGy2nqZgeSw=
+  dependencies:
+    base16 "^1.0.0"
+    lodash.curry "^4.0.1"
+    lodash.flow "^3.3.0"
+    pure-color "^1.2.0"
+
 react-dom@^16.12.0:
   version "16.13.1"
   resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.13.1.tgz#c1bd37331a0486c078ee54c4740720993b2e0e7f"
@@ -11594,26 +11712,32 @@ react-hot-loader@^4.12.21:
     shallowequal "^1.1.0"
     source-map "^0.7.3"
 
-react-is@^16.12.0, react-is@^16.13.1, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.0, react-is@^16.8.1, react-is@^16.8.6, react-is@^16.9.0:
+react-is@^16.12.0, react-is@^16.13.1, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.0, react-is@^16.8.1, react-is@^16.8.6:
   version "16.13.1"
   resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
   integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
 
+react-json-view@^1.19.1:
+  version "1.19.1"
+  resolved "https://registry.yarnpkg.com/react-json-view/-/react-json-view-1.19.1.tgz#95d8e59e024f08a25e5dc8f076ae304eed97cf5c"
+  integrity sha512-u5e0XDLIs9Rj43vWkKvwL8G3JzvXSl6etuS5G42a8klMohZuYFQzSN6ri+/GiBptDqlrXPTdExJVU7x9rrlXhg==
+  dependencies:
+    flux "^3.1.3"
+    react-base16-styling "^0.6.0"
+    react-lifecycles-compat "^3.0.4"
+    react-textarea-autosize "^6.1.0"
+
 react-lifecycles-compat@^3.0.4:
   version "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-redux@^7.2.0:
-  version "7.2.1"
-  resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-7.2.1.tgz#8dedf784901014db2feca1ab633864dee68ad985"
-  integrity sha512-T+VfD/bvgGTUA74iW9d2i5THrDQWbweXP0AVNI8tNd1Rk5ch1rnMiJkDD67ejw7YBKM4+REvcvqRuWJb7BLuEg==
+react-panelgroup@^1.0.12:
+  version "1.0.12"
+  resolved "https://registry.yarnpkg.com/react-panelgroup/-/react-panelgroup-1.0.12.tgz#e19c2d9d1fa4fbe504cdac9255eebc1c569c08f4"
+  integrity sha512-DuA+6TnxLK1TmlQqijYCbzvEVZYS3i6SyG9xqk7SW/S4pzzIxQ73lkSHLkMBG55/iOvGQEL/uH3Y96btk6mPDw==
   dependencies:
-    "@babel/runtime" "^7.5.5"
-    hoist-non-react-statics "^3.3.0"
-    loose-envify "^1.4.0"
-    prop-types "^15.7.2"
-    react-is "^16.9.0"
+    prop-types "^15.6.1"
 
 react-resize-detector@^2.3.0:
   version "2.3.0"
@@ -11674,14 +11798,12 @@ react-test-renderer@^16.0.0-0, react-test-renderer@^16.12.0:
     react-is "^16.8.6"
     scheduler "^0.19.1"
 
-react-textarea-autosize@^8.2.0:
-  version "8.2.0"
-  resolved "https://registry.yarnpkg.com/react-textarea-autosize/-/react-textarea-autosize-8.2.0.tgz#fae38653f5ec172a855fd5fffb39e466d56aebdb"
-  integrity sha512-grajUlVbkx6VdtSxCgzloUIphIZF5bKr21OYMceWPKkniy7H0mRAT/AXPrRtObAe+zUePnNlBwUc4ivVjUGIjw==
+react-textarea-autosize@^6.1.0:
+  version "6.1.0"
+  resolved "https://registry.yarnpkg.com/react-textarea-autosize/-/react-textarea-autosize-6.1.0.tgz#df91387f8a8f22020b77e3833c09829d706a09a5"
+  integrity sha512-F6bI1dgib6fSvG8so1HuArPUv+iVEfPliuLWusLF+gAKz0FbB4jLrWUrTAeq1afnPT2c9toEZYUdz/y1uKMy4A==
   dependencies:
-    "@babel/runtime" "^7.10.2"
-    use-composed-ref "^1.0.0"
-    use-latest "^1.0.0"
+    prop-types "^15.6.0"
 
 react-transition-group@^2.5.0:
   version "2.9.0"
@@ -11861,26 +11983,6 @@ reduce-function-call@^1.0.1:
   dependencies:
     balanced-match "^1.0.0"
 
-redux-logger@^3.0.6:
-  version "3.0.6"
-  resolved "https://registry.yarnpkg.com/redux-logger/-/redux-logger-3.0.6.tgz#f7555966f3098f3c88604c449cf0baf5778274bf"
-  integrity sha1-91VZZvMJjzyIYExEnPC69XeCdL8=
-  dependencies:
-    deep-diff "^0.3.5"
-
-redux-thunk@^2.3.0:
-  version "2.3.0"
-  resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.3.0.tgz#51c2c19a185ed5187aaa9a2d08b666d0d6467622"
-  integrity sha512-km6dclyFnmcvxhAcrQV2AkZmPQjzPDjgVlQtR0EQjxZPyJ0BnMf3in1ryuR8A2qU0HldVRfxYXbFSKlI3N7Slw==
-
-redux@^4.0.0, redux@^4.0.5:
-  version "4.0.5"
-  resolved "https://registry.yarnpkg.com/redux/-/redux-4.0.5.tgz#4db5de5816e17891de8a80c424232d06f051d93f"
-  integrity sha512-VSz1uMAH24DM6MF72vcojpYPtrTUu3ByVWfPL1nPfVRb5mZVTve5GnNCUV53QM/BZ66xfWrm0CTWoM+Xlz8V1w==
-  dependencies:
-    loose-envify "^1.4.0"
-    symbol-observable "^1.2.0"
-
 reflect.ownkeys@^0.2.0:
   version "0.2.0"
   resolved "https://registry.yarnpkg.com/reflect.ownkeys/-/reflect.ownkeys-0.2.0.tgz#749aceec7f3fdf8b63f927a04809e90c5c0b3460"
@@ -11903,7 +12005,7 @@ regenerator-runtime@^0.11.0:
   resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9"
   integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==
 
-regenerator-runtime@^0.13.4, regenerator-runtime@^0.13.5:
+regenerator-runtime@^0.13.4, regenerator-runtime@^0.13.7:
   version "0.13.7"
   resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz#cac2dacc8a1ea675feaabaeb8ae833898ae46f55"
   integrity sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==
@@ -11955,9 +12057,9 @@ regexpu-core@^2.0.0:
     regjsparser "^0.1.4"
 
 regexpu-core@^4.7.0:
-  version "4.7.0"
-  resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.7.0.tgz#fcbf458c50431b0bb7b45d6967b8192d91f3d938"
-  integrity sha512-TQ4KXRnIn6tz6tjnrXEkD/sshygKH/j5KzK86X8MkeHyZ8qst/LZ89j3X4/8HEIfHANTFIP/AbXakeRhWIl5YQ==
+  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"
@@ -12151,11 +12253,6 @@ requires-port@^1.0.0:
   resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff"
   integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=
 
-reselect@^4.0.0:
-  version "4.0.0"
-  resolved "https://registry.yarnpkg.com/reselect/-/reselect-4.0.0.tgz#f2529830e5d3d0e021408b246a206ef4ea4437f7"
-  integrity sha512-qUgANli03jjAyGlnbYVAV5vvnOmJnODyABz51RdBN7M4WaVu8mecZWgyQNkG8Yqe3KRGRt0l4K4B3XVEULC4CA==
-
 resize-observer-polyfill@^1.5.0:
   version "1.5.1"
   resolved "https://registry.yarnpkg.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz#0e9020dd3d21024458d4ebd27e23e40269810464"
@@ -12287,7 +12384,7 @@ rimraf@2.6.3:
   dependencies:
     glob "^7.1.3"
 
-rimraf@^2.2.8, rimraf@^2.5.2, rimraf@^2.5.4, rimraf@^2.6.3:
+rimraf@^2.2.8, rimraf@^2.5.4, rimraf@^2.6.3:
   version "2.7.1"
   resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec"
   integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==
@@ -12346,13 +12443,20 @@ run-queue@^1.0.0, run-queue@^1.0.3:
   dependencies:
     aproba "^1.1.1"
 
-rxjs@^6.3.1, rxjs@^6.5.2, rxjs@^6.6.2:
+rxjs@^6.3.1:
   version "6.6.2"
   resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.2.tgz#8096a7ac03f2cc4fe5860ef6e572810d9e01c0d2"
   integrity sha512-BHdBMVoWC2sL26w//BCu3YzKT4s2jip/WhwsGEDmeKYBhKDZeYezVUnHatYB7L85v5xs0BAQmg6BEYJEKxBabg==
   dependencies:
     tslib "^1.9.0"
 
+rxjs@^6.5.2, rxjs@^6.6.2:
+  version "6.6.3"
+  resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.3.tgz#8ca84635c4daa900c0d3967a6ee7ac60271ee552"
+  integrity sha512-trsQc+xYYXZ3urjOiJOuCOa5N3jAZ3eiSpQB5hIT8zGlL2QfnHLJ2r7GMkBGuIausdJN1OneaI6gQlsqNHHmZQ==
+  dependencies:
+    tslib "^1.9.0"
+
 safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1:
   version "5.1.2"
   resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
@@ -12437,7 +12541,16 @@ schema-utils@^1.0.0:
     ajv-errors "^1.0.0"
     ajv-keywords "^3.1.0"
 
-schema-utils@^2.6.5, schema-utils@^2.6.6, schema-utils@^2.7.0:
+schema-utils@^2.6.5, schema-utils@^2.7.1:
+  version "2.7.1"
+  resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.1.tgz#1ca4f32d1b24c590c203b8e7a50bf0ea4cd394d7"
+  integrity sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==
+  dependencies:
+    "@types/json-schema" "^7.0.5"
+    ajv "^6.12.4"
+    ajv-keywords "^3.5.2"
+
+schema-utils@^2.6.6, schema-utils@^2.7.0:
   version "2.7.0"
   resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.0.tgz#17151f76d8eae67fbbf77960c33c676ad9f4efc7"
   integrity sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==
@@ -12561,6 +12674,11 @@ set-blocking@^2.0.0, set-blocking@~2.0.0:
   resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"
   integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc=
 
+set-immediate-shim@~1.0.1:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61"
+  integrity sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=
+
 set-value@^2.0.0, set-value@^2.0.1:
   version "2.0.1"
   resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b"
@@ -12571,7 +12689,7 @@ set-value@^2.0.0, set-value@^2.0.1:
     is-plain-object "^2.0.3"
     split-string "^3.0.1"
 
-setimmediate@^1.0.4:
+setimmediate@^1.0.4, setimmediate@^1.0.5:
   version "1.0.5"
   resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285"
   integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=
@@ -12854,9 +12972,9 @@ spdx-expression-parse@^3.0.0:
     spdx-license-ids "^3.0.0"
 
 spdx-license-ids@^3.0.0:
-  version "3.0.5"
-  resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz#3694b5804567a458d3c8045842a6358632f62654"
-  integrity sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==
+  version "3.0.6"
+  resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.6.tgz#c80757383c28abf7296744998cbc106ae8b854ce"
+  integrity sha512-+orQK83kyMva3WyPf59k1+Y525csj5JejicWut55zeTWANuN17qSiSLUXWtzHeNWORSvT7GLDJ/E/XiIWoXBTw==
 
 spdy-transport@^3.0.0:
   version "3.0.0"
@@ -13245,18 +13363,20 @@ stylelint-config-standard@^20.0.0:
     stylelint-config-recommended "^3.0.0"
 
 stylelint@^13.6.1:
-  version "13.6.1"
-  resolved "https://registry.yarnpkg.com/stylelint/-/stylelint-13.6.1.tgz#cc1d76338116d55e8ff2be94c4a4386c1239b878"
-  integrity sha512-XyvKyNE7eyrqkuZ85Citd/Uv3ljGiuYHC6UiztTR6sWS9rza8j3UeQv/eGcQS9NZz/imiC4GKdk1EVL3wst5vw==
+  version "13.7.1"
+  resolved "https://registry.yarnpkg.com/stylelint/-/stylelint-13.7.1.tgz#bee97ee78d778a3f1dbe3f7397b76414973e263e"
+  integrity sha512-qzqazcyRxrSRdmFuO0/SZOJ+LyCxYy0pwcvaOBBnl8/2VfHSMrtNIE+AnyJoyq6uKb+mt+hlgmVrvVi6G6XHfQ==
   dependencies:
-    "@stylelint/postcss-css-in-js" "^0.37.1"
+    "@stylelint/postcss-css-in-js" "^0.37.2"
     "@stylelint/postcss-markdown" "^0.36.1"
-    autoprefixer "^9.8.0"
+    autoprefixer "^9.8.6"
     balanced-match "^1.0.0"
     chalk "^4.1.0"
-    cosmiconfig "^6.0.0"
+    cosmiconfig "^7.0.0"
     debug "^4.1.1"
     execall "^2.0.0"
+    fast-glob "^3.2.4"
+    fastest-levenshtein "^1.0.12"
     file-entry-cache "^5.0.1"
     get-stdin "^8.0.0"
     global-modules "^2.0.0"
@@ -13267,18 +13387,16 @@ stylelint@^13.6.1:
     import-lazy "^4.0.0"
     imurmurhash "^0.1.4"
     known-css-properties "^0.19.0"
-    leven "^3.1.0"
-    lodash "^4.17.15"
+    lodash "^4.17.20"
     log-symbols "^4.0.0"
     mathml-tag-names "^2.1.3"
-    meow "^7.0.1"
+    meow "^7.1.1"
     micromatch "^4.0.2"
     normalize-selector "^0.2.0"
     postcss "^7.0.32"
     postcss-html "^0.36.0"
     postcss-less "^3.1.4"
     postcss-media-query-parser "^0.2.3"
-    postcss-reporter "^6.0.1"
     postcss-resolve-nested-selector "^0.1.1"
     postcss-safe-parser "^4.0.2"
     postcss-sass "^0.4.4"
@@ -13294,7 +13412,7 @@ stylelint@^13.6.1:
     style-search "^0.1.0"
     sugarss "^2.0.0"
     svg-tags "^1.0.0"
-    table "^5.4.6"
+    table "^6.0.1"
     v8-compile-cache "^2.1.1"
     write-file-atomic "^3.0.3"
 
@@ -13331,13 +13449,20 @@ supports-color@^6.1.0:
   dependencies:
     has-flag "^3.0.0"
 
-supports-color@^7.0.0, supports-color@^7.1.0:
+supports-color@^7.0.0:
   version "7.1.0"
   resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.1.0.tgz#68e32591df73e25ad1c4b49108a2ec507962bfd1"
   integrity sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==
   dependencies:
     has-flag "^4.0.0"
 
+supports-color@^7.1.0:
+  version "7.2.0"
+  resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da"
+  integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==
+  dependencies:
+    has-flag "^4.0.0"
+
 supports-hyperlinks@^2.0.0:
   version "2.1.0"
   resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-2.1.0.tgz#f663df252af5f37c5d49bbd7eeefa9e0b9e59e47"
@@ -13370,17 +13495,12 @@ svgo@^1.0.0:
     unquote "~1.1.1"
     util.promisify "~1.0.0"
 
-symbol-observable@^1.2.0:
-  version "1.2.0"
-  resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804"
-  integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==
-
 symbol-tree@^3.2.4:
   version "3.2.4"
   resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2"
   integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==
 
-table@^5.2.3, table@^5.4.6:
+table@^5.2.3:
   version "5.4.6"
   resolved "https://registry.yarnpkg.com/table/-/table-5.4.6.tgz#1292d19500ce3f86053b05f0e8e7e4a3bb21079e"
   integrity sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==
@@ -13390,6 +13510,16 @@ table@^5.2.3, table@^5.4.6:
     slice-ansi "^2.1.0"
     string-width "^3.0.0"
 
+table@^6.0.1:
+  version "6.0.3"
+  resolved "https://registry.yarnpkg.com/table/-/table-6.0.3.tgz#e5b8a834e37e27ad06de2e0fda42b55cfd8a0123"
+  integrity sha512-8321ZMcf1B9HvVX/btKv8mMZahCjn2aYrDlpqHaBFCfnox64edeH9kEid0vTLTRR8gWR2A20aDgeuTTea4sVtw==
+  dependencies:
+    ajv "^6.12.4"
+    lodash "^4.17.20"
+    slice-ansi "^4.0.0"
+    string-width "^4.2.0"
+
 tapable@^0.1.8:
   version "0.1.10"
   resolved "https://registry.yarnpkg.com/tapable/-/tapable-0.1.10.tgz#29c35707c2b70e50d07482b5d202e8ed446dafd4"
@@ -13534,10 +13664,10 @@ testcafe-browser-tools@2.0.13:
     read-file-relative "^1.2.0"
     which-promise "^1.0.0"
 
-testcafe-hammerhead@17.1.13:
-  version "17.1.13"
-  resolved "https://registry.yarnpkg.com/testcafe-hammerhead/-/testcafe-hammerhead-17.1.13.tgz#e2ab9589e48aa145fa886c2303891e9e997d33fa"
-  integrity sha512-swNsC4gbs1vhKM9F9zmCcStA8oMg2FUTJZYUE30xL5ZdHae87x2tfg9T58jUcZK3CX0S9B2NCU1AJbwCsS0uqw==
+testcafe-hammerhead@17.1.18:
+  version "17.1.18"
+  resolved "https://registry.yarnpkg.com/testcafe-hammerhead/-/testcafe-hammerhead-17.1.18.tgz#1de65d6f63f7037a150f0987826f1f528df91c71"
+  integrity sha512-mrIMd1NsX+aRH37wb6tlGZoQMttXw0cwJn23iI4Y00oD8VwJfBz0x01Df1HVSuodjTqCEKdJHvDnyjAAsGjaAw==
   dependencies:
     acorn-hammerhead "^0.3.0"
     asar "^2.0.1"
@@ -13546,7 +13676,7 @@ testcafe-hammerhead@17.1.13:
     crypto-md5 "^1.0.0"
     css "2.2.3"
     debug "4.1.1"
-    esotope-hammerhead "0.5.5"
+    esotope-hammerhead "0.5.6"
     iconv-lite "0.5.1"
     lodash "^4.17.19"
     lru-cache "2.6.3"
@@ -13554,10 +13684,10 @@ testcafe-hammerhead@17.1.13:
     merge-stream "^1.0.1"
     mime "~1.4.1"
     mustache "^2.1.1"
-    nanoid "^0.2.2"
+    nanoid "^3.1.12"
     os-family "^1.0.0"
     parse5 "2.2.3"
-    pinkie "1.0.0"
+    pinkie "2.0.4"
     read-file-relative "^1.2.0"
     semver "5.5.0"
     tough-cookie "2.3.3"
@@ -13614,9 +13744,9 @@ testcafe-reporter-xunit@^2.1.0:
   integrity sha1-5tZsVyzhWvJmcGrw/WELKoQd1EM=
 
 testcafe@^1.8.8:
-  version "1.9.1"
-  resolved "https://registry.yarnpkg.com/testcafe/-/testcafe-1.9.1.tgz#2e3183d69561bf90da611408436c5b34b22f799c"
-  integrity sha512-18yGuCJvcdaGFhS3l4NhDwRnvJ24/mwXVfM+gqZm6vxNdw2NCujzXh36/BNr0qP2MhAEN56Y96G8XKkzn+5zYg==
+  version "1.9.3"
+  resolved "https://registry.yarnpkg.com/testcafe/-/testcafe-1.9.3.tgz#049b5d10127ce83993a46e35f429696ce774770b"
+  integrity sha512-1L5c8lHitGz/0Ta6AtA+J4e+YveV+XeoaY06mBWuVnijp56zJG4Xz1O2XNbMgprfLj7oNl96DW/MjJyW9B8QzA==
   dependencies:
     "@types/node" "^10.12.19"
     async-exit-hook "^1.1.2"
@@ -13647,6 +13777,7 @@ testcafe@^1.8.8:
     emittery "^0.4.1"
     endpoint-utils "^1.0.2"
     error-stack-parser "^1.3.6"
+    execa "^4.0.3"
     globby "^9.2.0"
     graceful-fs "^4.1.11"
     graphlib "^2.1.5"
@@ -13682,7 +13813,7 @@ testcafe@^1.8.8:
     source-map-support "^0.5.16"
     strip-bom "^2.0.0"
     testcafe-browser-tools "2.0.13"
-    testcafe-hammerhead "17.1.13"
+    testcafe-hammerhead "17.1.18"
     testcafe-legacy-api "4.0.0"
     testcafe-reporter-json "^2.1.0"
     testcafe-reporter-list "^2.1.0"
@@ -13906,11 +14037,6 @@ tryer@^1.0.1:
   resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.1.tgz#f2c85406800b9b0f74c9f7465b81eaad241252f8"
   integrity sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==
 
-ts-essentials@^2.0.3:
-  version "2.0.12"
-  resolved "https://registry.yarnpkg.com/ts-essentials/-/ts-essentials-2.0.12.tgz#c9303f3d74f75fa7528c3d49b80e089ab09d8745"
-  integrity sha512-3IVX4nI6B5cc31/GFFE+i8ey/N2eA0CZDbo6n0yrz0zDX8ZJ8djmU1p+XRz7G3is0F3bB3pu2pAroFdAWQKU3w==
-
 ts-node@^9.0.0:
   version "9.0.0"
   resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-9.0.0.tgz#e7699d2a110cc8c0d3b831715e417688683460b3"
@@ -14039,6 +14165,11 @@ typings-for-css-modules-loader@^1.7.0:
     graceful-fs "4.1.4"
     loader-utils "0.2.16"
 
+ua-parser-js@^0.7.18:
+  version "0.7.22"
+  resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.22.tgz#960df60a5f911ea8f1c818f3747b99c6e177eae3"
+  integrity sha512-YUxzMjJ5T71w6a8WWVcMGM6YWOTX27rCoIQgLXiWaxqXSx9D7DNjiGWn1aJIRSQ5qr0xuhra77bSIh6voR/46Q==
+
 ultron@~1.1.0:
   version "1.1.1"
   resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.1.1.tgz#9fe1536a10a664a65266a1e3ccf85fd36302bc9c"
@@ -14199,6 +14330,15 @@ unset-value@^1.0.0:
     has-value "^0.3.1"
     isobject "^3.0.0"
 
+unzip-crx-3@^0.2.0:
+  version "0.2.0"
+  resolved "https://registry.yarnpkg.com/unzip-crx-3/-/unzip-crx-3-0.2.0.tgz#d5324147b104a8aed9ae8639c95521f6f7cda292"
+  integrity sha512-0+JiUq/z7faJ6oifVB5nSwt589v1KCduqIJupNVDoWSXZtWDmjDGO3RAEOvwJ07w90aoXoP4enKsR7ecMrJtWQ==
+  dependencies:
+    jszip "^3.1.0"
+    mkdirp "^0.5.1"
+    yaku "^0.16.6"
+
 upath@^1.1.1:
   version "1.2.0"
   resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894"
@@ -14224,9 +14364,9 @@ update-notifier@^4.1.0:
     xdg-basedir "^4.0.0"
 
 uri-js@^4.2.2:
-  version "4.2.2"
-  resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0"
-  integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==
+  version "4.4.0"
+  resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.0.tgz#aa714261de793e8a82347a7bcc9ce74e86f28602"
+  integrity sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g==
   dependencies:
     punycode "^2.1.0"
 
@@ -14267,13 +14407,6 @@ url@^0.11.0:
     punycode "1.3.2"
     querystring "0.2.0"
 
-use-composed-ref@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/use-composed-ref/-/use-composed-ref-1.0.0.tgz#bb13e8f4a0b873632cde4940abeb88b92d03023a"
-  integrity sha512-RVqY3NFNjZa0xrmK3bIMWNmQ01QjKPDc7DeWR3xa/N8aliVppuutOE5bZzPkQfvL+5NRWMMp0DJ99Trd974FIw==
-  dependencies:
-    ts-essentials "^2.0.3"
-
 use-deep-compare-effect@^1.4.0:
   version "1.4.0"
   resolved "https://registry.yarnpkg.com/use-deep-compare-effect/-/use-deep-compare-effect-1.4.0.tgz#3f40e3fa5b0b8d79e4126e83be384ed602472405"
@@ -14283,18 +14416,6 @@ use-deep-compare-effect@^1.4.0:
     "@types/use-deep-compare-effect" "^1.2.0"
     dequal "^2.0.2"
 
-use-isomorphic-layout-effect@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.0.0.tgz#f56b4ed633e1c21cd9fc76fe249002a1c28989fb"
-  integrity sha512-JMwJ7Vd86NwAt1jH7q+OIozZSIxA4ND0fx6AsOe2q1H8ooBUp5aN6DvVCqZiIaYU6JaMRJGyR0FO7EBCIsb/Rg==
-
-use-latest@^1.0.0:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/use-latest/-/use-latest-1.1.0.tgz#7bf9684555869c3f5f37e10d0884c8accf4d3aa6"
-  integrity sha512-gF04d0ZMV3AMB8Q7HtfkAWe+oq1tFXP6dZKwBHQF5nVXtGsh2oAYeeqma5ZzxtlpOcW8Ro/tLcfmEodjDeqtuw==
-  dependencies:
-    use-isomorphic-layout-effect "^1.0.0"
-
 use@^3.1.0:
   version "3.1.1"
   resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f"
@@ -14493,9 +14614,9 @@ webidl-conversions@^6.1.0:
   integrity sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==
 
 webpack-bundle-analyzer@^3.8.0:
-  version "3.8.0"
-  resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-3.8.0.tgz#ce6b3f908daf069fd1f7266f692cbb3bded9ba16"
-  integrity sha512-PODQhAYVEourCcOuU+NiYI7WdR8QyELZGgPvB1y2tjbUpbmcQOt5Q7jEK+ttd5se0KSBKD9SXHCEozS++Wllmw==
+  version "3.9.0"
+  resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-3.9.0.tgz#f6f94db108fb574e415ad313de41a2707d33ef3c"
+  integrity sha512-Ob8amZfCm3rMB1ScjQVlbYYUEJyEjdEtQ92jqiFUYt5VkEeO2v5UMbv49P/gnmCZm3A6yaFQzCBvpZqN4MUsdA==
   dependencies:
     acorn "^7.1.1"
     acorn-walk "^7.1.1"
@@ -14506,7 +14627,7 @@ webpack-bundle-analyzer@^3.8.0:
     express "^4.16.3"
     filesize "^3.6.1"
     gzip-size "^5.0.0"
-    lodash "^4.17.15"
+    lodash "^4.17.19"
     mkdirp "^0.5.1"
     opener "^1.5.1"
     ws "^6.0.0"
@@ -14587,9 +14708,9 @@ webpack-log@^2.0.0:
     uuid "^3.3.2"
 
 webpack-merge@^5.0.9:
-  version "5.1.2"
-  resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-5.1.2.tgz#21dc1ed0e860c305cf5a07a48750f53a99750855"
-  integrity sha512-/slG0Kh0OKTf0zxdFJlhQHzv8bU9gUYVK5DkBjB3i/yoc1Xx4ADG0KITGO5S/6cqn2Ug43+8VR6Sz8daA/c+5g==
+  version "5.1.4"
+  resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-5.1.4.tgz#a2c3a0c38ac2c02055c47bb1d42de1f072f1aea4"
+  integrity sha512-LSmRD59mxREGkCBm9PCW3AaV4doDqxykGlx1NvioEE0FgkT2GQI54Wyvg39ptkiq2T11eRVoV39udNPsQvK+QQ==
   dependencies:
     clone-deep "^4.0.1"
     wildcard "^2.0.0"
@@ -14603,9 +14724,9 @@ webpack-sources@^1.1.0, webpack-sources@^1.4.0, webpack-sources@^1.4.1, webpack-
     source-map "~0.6.1"
 
 webpack@^4.43.0:
-  version "4.44.1"
-  resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.44.1.tgz#17e69fff9f321b8f117d1fda714edfc0b939cc21"
-  integrity sha512-4UOGAohv/VGUNQJstzEywwNxqX417FnjZgZJpJQegddzPmTvph37eBIRbRTfdySXzVtJXLJfbMN3mMYhM6GdmQ==
+  version "4.44.2"
+  resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.44.2.tgz#6bfe2b0af055c8b2d1e90ed2cd9363f841266b72"
+  integrity sha512-6KJVGlCxYdISyurpQ0IPTklv+DULv05rs2hseIXer6D7KrUicRDLFb4IUM1S6LUAKypPM/nSiVSuv8jHu1m3/Q==
   dependencies:
     "@webassemblyjs/ast" "1.9.0"
     "@webassemblyjs/helper-module-context" "1.9.0"
@@ -14659,6 +14780,11 @@ whatwg-encoding@^1.0.5:
   dependencies:
     iconv-lite "0.4.24"
 
+whatwg-fetch@>=0.10.0:
+  version "3.4.1"
+  resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.4.1.tgz#e5f871572d6879663fa5674c8f833f15a8425ab3"
+  integrity sha512-sofZVzE1wKwO+EYPbWfiwzaKovWiZXf4coEzjGP9b2GBVgQRLQUZ2QcuPpQExGDAW5GItpEm6Tl4OU5mywnAoQ==
+
 whatwg-mimetype@^2.3.0:
   version "2.3.0"
   resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf"
@@ -14831,6 +14957,11 @@ y18n@^4.0.0:
   resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b"
   integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==
 
+yaku@^0.16.6:
+  version "0.16.7"
+  resolved "https://registry.yarnpkg.com/yaku/-/yaku-0.16.7.tgz#1d195c78aa9b5bf8479c895b9504fd4f0847984e"
+  integrity sha1-HRlceKqbW/hHnIlblQT9TwhHmE4=
+
 yallist@^3.0.0, yallist@^3.0.2, yallist@^3.0.3:
   version "3.1.1"
   resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd"
@@ -14841,7 +14972,7 @@ yallist@^4.0.0:
   resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
   integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
 
-yaml@^1.10.0, yaml@^1.7.2:
+yaml@^1.10.0:
   version "1.10.0"
   resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.0.tgz#3b593add944876077d4d683fee01081bd9fff31e"
   integrity sha512-yr2icI4glYaNG+KWONODapy2/jDdMSDnrONSjblABjD9B4Z5LgiircSt8m8sRZFNi08kG9Sm0uSHtEmP3zaEGg==
@@ -14903,7 +15034,7 @@ yargs@^14.2.0:
     y18n "^4.0.0"
     yargs-parser "^15.0.1"
 
-yargs@^15.3.1:
+yargs@^15.3.1, yargs@^15.4.1:
   version "15.4.1"
   resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.4.1.tgz#0d87a16de01aee9d8bec2bfbf74f67851730f4f8"
   integrity sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==