diff --git a/.gitignore b/.gitignore
index 82e56ec41..9bfbc9b30 100644
--- a/.gitignore
+++ b/.gitignore
@@ -42,4 +42,5 @@ venv.bak/
# Sphinx
sphinx/_build/
-*~
\ No newline at end of file
+*~
+node_modules
diff --git a/extensions/graphviz_support/graphviz_support/tests/demo_graph/amplifier.py b/extensions/graphviz_support/graphviz_support/tests/demo_graph/amplifier.py
index 9d5a1067e..a391d7f2b 100644
--- a/extensions/graphviz_support/graphviz_support/tests/demo_graph/amplifier.py
+++ b/extensions/graphviz_support/graphviz_support/tests/demo_graph/amplifier.py
@@ -4,9 +4,16 @@
import labgraph as lg
import numpy as np
import time
+import random
from .random_message import RandomMessage
+from datetime import datetime
+from time import perf_counter
+from collections import deque
-
+data = deque()
+throughput_data = ""
+datarate_data = ""
+one_second_must_pass = perf_counter()
class AmplifierConfig(lg.Config):
out_in_ratio: float
@@ -22,10 +29,35 @@ def output(self, _in: float) -> float:
@lg.subscriber(AMPLIFIER_INPUT)
@lg.publisher(AMPLIFIER_OUTPUT)
async def amplify(self, message: RandomMessage) -> lg.AsyncPublisher:
- current_time = time.time()
+ global data
+ global throughput_data
+ global datarate_data
+ global one_second_must_pass
+
+ current_time_UTC = str(datetime.utcnow()) + " (UTC)"
+ start_time = perf_counter()
+ # timestamp_data = time.time()
output_data = np.array(
[self.output(_in) for _in in message.data]
)
+
+
+ data.append(message.data.size * message.data.itemsize)
+ if perf_counter() - one_second_must_pass >= 1:
+ tempThroughput = 0
+ tempDataRate = 0
+ for messagedata in data:
+ tempThroughput += messagedata
+ tempDataRate += 1.0
+ throughput_data = str(tempThroughput) + " bytes"
+ datarate_data = str(tempDataRate) + " msg/sec"
+ data.clear()
+ one_second_must_pass = perf_counter()
+
+ latency_data = str(perf_counter() - start_time) + " s"
yield self.AMPLIFIER_OUTPUT, RandomMessage(
- timestamp=current_time, data=output_data
+ timestamp=current_time_UTC, data=output_data, latency=latency_data, throughput=throughput_data, datarate=datarate_data
)
+
+
+
\ No newline at end of file
diff --git a/extensions/graphviz_support/graphviz_support/tests/demo_graph/attenuator.py b/extensions/graphviz_support/graphviz_support/tests/demo_graph/attenuator.py
index d90a5c6d6..b8dd1e481 100644
--- a/extensions/graphviz_support/graphviz_support/tests/demo_graph/attenuator.py
+++ b/extensions/graphviz_support/graphviz_support/tests/demo_graph/attenuator.py
@@ -4,13 +4,23 @@
import labgraph as lg
import numpy as np
import time
+import random
from .random_message import RandomMessage
+from datetime import datetime
+from time import perf_counter
+from collections import deque
+data = deque()
+throughput_data = ""
+datarate_data = ""
+one_second_must_pass = perf_counter()
class AttenuatorConfig(lg.Config):
attenuation: float
-
+class CustomMessage(RandomMessage):
+ latency: float
+
class Attenuator(lg.Node):
ATTENUATOR_INPUT = lg.Topic(RandomMessage)
ATTENUATOR_OUTPUT = lg.Topic(RandomMessage)
@@ -22,10 +32,33 @@ def output(self, _in: float) -> float:
@lg.subscriber(ATTENUATOR_INPUT)
@lg.publisher(ATTENUATOR_OUTPUT)
async def attenuate(self, message: RandomMessage) -> lg.AsyncPublisher:
- current_time = time.time()
+ global data
+ global throughput_data
+ global datarate_data
+ global one_second_must_pass
+
+ start_time = perf_counter()
+ current_time_UCT = str(datetime.utcnow()) + " (UTC)"
output_data = np.array(
[self.output(_in) for _in in message.data]
)
+
+ data.append(message.data.size * message.data.itemsize)
+ if perf_counter() - one_second_must_pass >= 1:
+ tempThroughput = 0
+ tempDataRate = 0
+ for messagedata in data:
+ tempThroughput += messagedata
+ tempDataRate += 1.0
+ throughput_data = str(tempThroughput) + " bytes"
+ datarate_data = str(tempDataRate) + " msg/sec"
+ data.clear()
+ one_second_must_pass = perf_counter()
+
+ latency_data = str(perf_counter() - start_time) + " s"
yield self.ATTENUATOR_OUTPUT, RandomMessage(
- timestamp=current_time, data=output_data
+ timestamp=current_time_UCT, data=output_data, latency=latency_data,throughput=throughput_data, datarate=datarate_data
)
+
+
+
\ No newline at end of file
diff --git a/extensions/graphviz_support/graphviz_support/tests/demo_graph/noise_generator.py b/extensions/graphviz_support/graphviz_support/tests/demo_graph/noise_generator.py
index 31f04e052..5c6057b57 100644
--- a/extensions/graphviz_support/graphviz_support/tests/demo_graph/noise_generator.py
+++ b/extensions/graphviz_support/graphviz_support/tests/demo_graph/noise_generator.py
@@ -5,14 +5,16 @@
import numpy as np
import asyncio
import time
+import random
from .random_message import RandomMessage
-
+from datetime import datetime
+from time import perf_counter
class NoiseGeneratorConfig(lg.Config):
sample_rate: float
num_features: int
-
+
class NoiseGenerator(lg.Node):
NOISE_GENERATOR_OUTPUT = lg.Topic(RandomMessage)
config: NoiseGeneratorConfig
@@ -20,8 +22,21 @@ class NoiseGenerator(lg.Node):
@lg.publisher(NOISE_GENERATOR_OUTPUT)
async def generate_noise(self) -> lg.AsyncPublisher:
while True:
+ start_time = perf_counter()
+ timestamp_data = time.time()
+
+ datarate_data = random.random() + 6
+ throughput_data = len(str(np.random.rand(self.config.num_features)))
+ latency_data = perf_counter() - start_time
+
yield self.NOISE_GENERATOR_OUTPUT, RandomMessage(
- timestamp=time.time(),
- data=np.random.rand(self.config.num_features)
+ timestamp=timestamp_data,
+ data=np.random.rand(self.config.num_features),
+
+ latency=10.0,
+ throughput=throughput_data,
+ datarate=datarate_data
)
await asyncio.sleep(1 / self.config.sample_rate)
+
+
\ No newline at end of file
diff --git a/extensions/graphviz_support/graphviz_support/tests/demo_graph/rolling_averager.py b/extensions/graphviz_support/graphviz_support/tests/demo_graph/rolling_averager.py
index c4d51a463..a82ff2a4c 100644
--- a/extensions/graphviz_support/graphviz_support/tests/demo_graph/rolling_averager.py
+++ b/extensions/graphviz_support/graphviz_support/tests/demo_graph/rolling_averager.py
@@ -4,10 +4,18 @@
import labgraph as lg
import numpy as np
import time
+import random
from typing import List
from dataclasses import field
from .random_message import RandomMessage
+from datetime import datetime
+from time import perf_counter
+from collections import deque
+data = deque()
+throughput_data = ""
+datarate_data = ""
+one_second_must_pass = perf_counter()
class RollingState(lg.State):
messages: List[RandomMessage] = field(default_factory=list)
@@ -16,7 +24,7 @@ class RollingState(lg.State):
class RollingConfig(lg.Config):
window: float
-
+
class RollingAverager(lg.Node):
ROLLING_AVERAGER_INPUT = lg.Topic(RandomMessage)
ROLLING_AVERAGER_OUTPUT = lg.Topic(RandomMessage)
@@ -24,15 +32,24 @@ class RollingAverager(lg.Node):
state: RollingState
config: RollingConfig
+
+
@lg.subscriber(ROLLING_AVERAGER_INPUT)
@lg.publisher(ROLLING_AVERAGER_OUTPUT)
async def average(self, message: RandomMessage) -> lg.AsyncPublisher:
- current_time = time.time()
+ global data
+ global throughput_data
+ global datarate_data
+ global one_second_must_pass
+
+ start_time = perf_counter()
+ current_time_UTC = str(datetime.utcnow()) + " (UTC)"
+
self.state.messages.append(message)
self.state.messages = [
message
for message in self.state.messages
- if message.timestamp >= current_time - self.config.window
+ if message.timestamp >= time.time() - self.config.window
]
if len(self.state.messages) == 0:
return
@@ -40,7 +57,26 @@ async def average(self, message: RandomMessage) -> lg.AsyncPublisher:
[message.data for message in self.state.messages]
)
mean_data = np.mean(all_data, axis=0)
+
+ data.append(message.data.size * message.data.itemsize)
+ if perf_counter() - one_second_must_pass >= 1:
+ tempThroughput = 0
+ tempDataRate = 0
+ for messagedata in data:
+ tempThroughput += messagedata
+ tempDataRate += 1.0
+ throughput_data = str(tempThroughput) + " bytes"
+ datarate_data = str(tempDataRate) + " msg/sec"
+ data.clear()
+ one_second_must_pass = perf_counter()
+
+ latency_data = str(perf_counter() - start_time) + " s"
+
yield self.ROLLING_AVERAGER_OUTPUT, RandomMessage(
- timestamp=current_time,
- data=mean_data
+ timestamp=current_time_UTC,
+ data=mean_data,
+
+ latency=latency_data,
+ throughput=throughput_data,
+ datarate=datarate_data
)
diff --git a/extensions/prototypes/labgraph_monitor/src/components/SettingPanel/EdgeSettings.tsx b/extensions/prototypes/labgraph_monitor/src/components/SettingPanel/EdgeSettings.tsx
index cb086f68d..6bcea8792 100644
--- a/extensions/prototypes/labgraph_monitor/src/components/SettingPanel/EdgeSettings.tsx
+++ b/extensions/prototypes/labgraph_monitor/src/components/SettingPanel/EdgeSettings.tsx
@@ -112,11 +112,22 @@ const Edge: React.FC = (): JSX.Element => {
(field, index) => {
return (
- {open && (
-
- {field[0]}
+ {open ? (
+
+ {field[0] ===
+ 'timestamp' ||
+ field[0] === 'data'
+ ? `${field[0]} `
+ : null}
- )}
+ ) : null}
{open ? (
{
}}
>
{connection ===
- WS_STATE.CONNECTED
- ? `${field[1].content}, `
- : mockData.join(
+ WS_STATE.CONNECTED &&
+ (field[0] ===
+ 'timestamp' ||
+ field[0] ===
+ 'data')
+ ? `${field[1].content} `
+ : connection ===
+ WS_STATE.DISCONNECTED
+ ? mockData.join(
' '
- )}
+ )
+ : null}
) : null}
diff --git a/extensions/prototypes/labgraph_monitor/src/components/SettingPanel/NodeSettings.tsx b/extensions/prototypes/labgraph_monitor/src/components/SettingPanel/NodeSettings.tsx
index 5c4b8e948..c3896de11 100644
--- a/extensions/prototypes/labgraph_monitor/src/components/SettingPanel/NodeSettings.tsx
+++ b/extensions/prototypes/labgraph_monitor/src/components/SettingPanel/NodeSettings.tsx
@@ -4,11 +4,33 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
-import React from 'react';
+import {
+ Box,
+ Paper,
+ Table,
+ TableBody,
+ TableCell,
+ TableContainer,
+ // TableHead,
+ TableRow,
+ Typography,
+ Button,
+} from '@mui/material';
+import React, { useEffect } from 'react';
+import { useDispatch, useSelector } from 'react-redux';
+import WS_STATE from '../../redux/reducers/graph/ws/enums/WS_STATE';
+import { setMockRealtimeData } from '../../redux/reducers/graph/mock/mockReducer';
import { RootState } from '../../redux/store';
-import { useSelector } from 'react-redux';
-import { Box, Typography } from '@mui/material';
+interface IMessage {
+ name: string;
+ fields: {
+ [fieldName: string]: {
+ type: string;
+ content: any;
+ };
+ };
+}
/**
* A component that manages the settings of a node.
* All components related to node settings should be children of this component.
@@ -18,6 +40,41 @@ import { Box, Typography } from '@mui/material';
const Node: React.FC = (): JSX.Element => {
const { selectedNode } = useSelector((state: RootState) => state.config);
+ const { selectedEdge } = useSelector((state: RootState) => state.config);
+ const { connection, graph: realtimeGraph } = useSelector(
+ (state: RootState) => state.ws
+ );
+ const { mockGraph } = useSelector((state: RootState) => state.mock);
+ // const mockData = useSelector(
+ // (state: RootState) => state.mock.mockRealtimeData
+ // );
+ const graph = connection === WS_STATE.CONNECTED ? realtimeGraph : mockGraph;
+ const [open, setOpen] = React.useState(false);
+
+ const messages: IMessage[] =
+ graph && selectedEdge.target
+ ? graph['nodes'][selectedEdge.target]['upstreams'][
+ selectedEdge.source
+ ]
+ : [];
+ const handleToggle = () => {
+ setOpen(!open);
+ };
+ // creating mock data, check mockReducer.ts, IMock.ts and EdgeSettings.tsx for future updates
+ const dispatch = useDispatch();
+
+ useEffect(() => {
+ const id = setInterval(() => {
+ const date = Date.now();
+
+ dispatch(
+ setMockRealtimeData([date, date % 10, date * 3, date / 4])
+ );
+ }, 100);
+
+ return () => clearInterval(id);
+ }, [dispatch]);
+
return (
@@ -28,6 +85,75 @@ const Node: React.FC = (): JSX.Element => {
Click on a node to see its information
)}
+ {messages.map((message: IMessage, index) => {
+ return (
+
+
+
+ {/* ZMQMessage Edge */}
+
+
+
+ {Object.entries(message.fields).map(
+ (field, index) => {
+ return (
+
+ {open ? (
+
+ {connection ===
+ WS_STATE.CONNECTED &&
+ (field[0] ===
+ 'latency' ||
+ field[0] ===
+ 'throughput' ||
+ field[0] ===
+ 'datarate')
+ ? `${field[0]} `
+ : null}
+
+ ) : null}
+ {open ? (
+
+ {connection ===
+ WS_STATE.CONNECTED &&
+ (field[0] ===
+ 'latency' ||
+ field[0] ===
+ 'throughput' ||
+ field[0] ===
+ 'datarate')
+ ? `${field[1].content} `
+ : null}
+
+ ) : null}
+
+ );
+ }
+ )}
+
+
+
+ );
+ })}
);
diff --git a/extensions/prototypes/labgraph_monitor/src/components/SettingPanel/SettingPanel.tsx b/extensions/prototypes/labgraph_monitor/src/components/SettingPanel/SettingPanel.tsx
index 24b9883a6..d61d4f98a 100644
--- a/extensions/prototypes/labgraph_monitor/src/components/SettingPanel/SettingPanel.tsx
+++ b/extensions/prototypes/labgraph_monitor/src/components/SettingPanel/SettingPanel.tsx
@@ -12,7 +12,7 @@ import {
SettingsApplicationsRounded,
AlignHorizontalLeftOutlined,
AlignVerticalTopOutlined,
- Mode,
+ // Mode,
} from '@mui/icons-material';
import React, { useCallback } from 'react';
import SettingTabs from './SettingTabs';
diff --git a/extensions/yaml_support/labgraph_monitor/server/serializer_node.py b/extensions/yaml_support/labgraph_monitor/server/serializer_node.py
index 5395bd3e1..152067d46 100644
--- a/extensions/yaml_support/labgraph_monitor/server/serializer_node.py
+++ b/extensions/yaml_support/labgraph_monitor/server/serializer_node.py
@@ -56,6 +56,10 @@ def add_message_1(self, message: RandomMessage) -> None:
"grouping": grouping,
"timestamp": message.timestamp,
"numpy": list(message.data),
+
+ "latency": message.latency,
+ "throughput": message.throughput,
+ "datarate": message.datarate,
}
@lg.subscriber(SERIALIZER_INPUT_2)
@@ -65,6 +69,10 @@ def add_message_2(self, message: RandomMessage) -> None:
"grouping": grouping,
"timestamp": message.timestamp,
"numpy": list(message.data),
+
+ "latency": message.latency,
+ "throughput": message.throughput,
+ "datarate": message.datarate,
}
@lg.subscriber(SERIALIZER_INPUT_3)
@@ -74,6 +82,11 @@ def add_message_3(self, message: RandomMessage) -> None:
"grouping": grouping,
"timestamp": message.timestamp,
"numpy": list(message.data),
+
+ "latency": message.latency,
+ "throughput": message.throughput,
+ "datarate": message.datarate,
+
}
@lg.subscriber(SERIALIZER_INPUT_4)
@@ -83,6 +96,10 @@ def add_message_4(self, message: RandomMessage) -> None:
"grouping": grouping,
"timestamp": message.timestamp,
"numpy": list(message.data),
+
+ "latency": message.latency,
+ "throughput": message.throughput,
+ "datarate": message.datarate,
}
def output(self, _in: Dict) -> Dict:
@@ -97,6 +114,10 @@ def output(self, _in: Dict) -> Dict:
if state["grouping"] in value["upstreams"].keys():
value["upstreams"][state["grouping"]][0]["fields"]["timestamp"]["content"] = state["timestamp"]
value["upstreams"][state["grouping"]][0]["fields"]["data"]["content"] = state["numpy"]
+
+ value["upstreams"][state["grouping"]][0]["fields"]["latency"]["content"] = state["latency"]
+ value["upstreams"][state["grouping"]][0]["fields"]["throughput"]["content"] = state["throughput"]
+ value["upstreams"][state["grouping"]][0]["fields"]["datarate"]["content"] = state["datarate"]
return _in
diff --git a/labgraph/examples/random_message.py b/labgraph/examples/random_message.py
index 4199ab587..b4fc98f43 100644
--- a/labgraph/examples/random_message.py
+++ b/labgraph/examples/random_message.py
@@ -1,17 +1,14 @@
#!/usr/bin/env python3
-# Copyright 2004-present Facebook. All Rights Reserved.
-# -*- coding: utf-8 -*-
+# Copyright 2004-present Facebook. All Rights Reserve
-# Built-in imports
-
-# Import labgraph
import labgraph as lg
-
-# Imports required for this example
import numpy as np
-# A data type used in streaming, see docs: Messages
class RandomMessage(lg.Message):
- timestamp: float
+ timestamp: any
data: np.ndarray
+
+ latency: any = 1.0
+ throughput: any = 2.0
+ datarate: any = 3.0
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 000000000..adbd547c5
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,959 @@
+{
+ "name": "labgraph",
+ "lockfileVersion": 2,
+ "requires": true,
+ "packages": {
+ "": {
+ "dependencies": {
+ "@mui/icons-material": "^5.8.4",
+ "react-redux": "^8.0.2",
+ "resize-observer-polyfill": "^1.5.1"
+ }
+ },
+ "node_modules/@babel/runtime": {
+ "version": "7.18.9",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.18.9.tgz",
+ "integrity": "sha512-lkqXDcvlFT5rvEjiu6+QYO+1GXrEHRo2LOtS7E4GtX5ESIZOgepqsZBVIj6Pv+a6zqsya9VCgiK1KAK4BvJDAw==",
+ "dependencies": {
+ "regenerator-runtime": "^0.13.4"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@emotion/cache": {
+ "version": "11.10.1",
+ "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.10.1.tgz",
+ "integrity": "sha512-uZTj3Yz5D69GE25iFZcIQtibnVCFsc/6+XIozyL3ycgWvEdif2uEw9wlUt6umjLr4Keg9K6xRPHmD8LGi+6p1A==",
+ "peer": true,
+ "dependencies": {
+ "@emotion/memoize": "^0.8.0",
+ "@emotion/sheet": "^1.2.0",
+ "@emotion/utils": "^1.2.0",
+ "@emotion/weak-memoize": "^0.3.0",
+ "stylis": "4.0.13"
+ }
+ },
+ "node_modules/@emotion/is-prop-valid": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.0.tgz",
+ "integrity": "sha512-3aDpDprjM0AwaxGE09bOPkNxHpBd+kA6jty3RnaEXdweX1DF1U3VQpPYb0g1IStAuK7SVQ1cy+bNBBKp4W3Fjg==",
+ "peer": true,
+ "dependencies": {
+ "@emotion/memoize": "^0.8.0"
+ }
+ },
+ "node_modules/@emotion/memoize": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.0.tgz",
+ "integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==",
+ "peer": true
+ },
+ "node_modules/@emotion/sheet": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.0.tgz",
+ "integrity": "sha512-OiTkRgpxescko+M51tZsMq7Puu/KP55wMT8BgpcXVG2hqXc0Vo0mfymJ/Uj24Hp0i083ji/o0aLddh08UEjq8w==",
+ "peer": true
+ },
+ "node_modules/@emotion/utils": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.0.tgz",
+ "integrity": "sha512-sn3WH53Kzpw8oQ5mgMmIzzyAaH2ZqFEbozVVBSYp538E06OSE6ytOp7pRAjNQR+Q/orwqdQYJSe2m3hCOeznkw==",
+ "peer": true
+ },
+ "node_modules/@emotion/weak-memoize": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.0.tgz",
+ "integrity": "sha512-AHPmaAx+RYfZz0eYu6Gviiagpmiyw98ySSlQvCUhVGDRtDFe4DBS0x1bSjdF3gqUDYOczB+yYvBTtEylYSdRhg==",
+ "peer": true
+ },
+ "node_modules/@mui/base": {
+ "version": "5.0.0-alpha.93",
+ "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-alpha.93.tgz",
+ "integrity": "sha512-IVUWO0NNlELDc9FD7mM+fWTS1/6n5sJYdIbXpLQ00NjWdVEYmTyRgUAZDlJJJrz+tbF0eeffx0kOsvJvyTZlsA==",
+ "peer": true,
+ "dependencies": {
+ "@babel/runtime": "^7.17.2",
+ "@emotion/is-prop-valid": "^1.1.3",
+ "@mui/types": "^7.1.5",
+ "@mui/utils": "^5.9.3",
+ "@popperjs/core": "^2.11.6",
+ "clsx": "^1.2.1",
+ "prop-types": "^15.8.1",
+ "react-is": "^18.2.0"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/mui"
+ },
+ "peerDependencies": {
+ "@types/react": "^17.0.0 || ^18.0.0",
+ "react": "^17.0.0 || ^18.0.0",
+ "react-dom": "^17.0.0 || ^18.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@mui/core-downloads-tracker": {
+ "version": "5.10.1",
+ "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.10.1.tgz",
+ "integrity": "sha512-zyzLkVSqi+WuxG8UZrrOaWbhHkDK+MlHFjLpL+vqUVU6iSUaDYREu1xoLWEQsWOznT4oT2iEiGZLpQLgkn+WiA==",
+ "peer": true,
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/mui"
+ }
+ },
+ "node_modules/@mui/icons-material": {
+ "version": "5.8.4",
+ "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.8.4.tgz",
+ "integrity": "sha512-9Z/vyj2szvEhGWDvb+gG875bOGm8b8rlHBKOD1+nA3PcgC3fV6W1AU6pfOorPeBfH2X4mb9Boe97vHvaSndQvA==",
+ "dependencies": {
+ "@babel/runtime": "^7.17.2"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/mui"
+ },
+ "peerDependencies": {
+ "@mui/material": "^5.0.0",
+ "@types/react": "^17.0.0 || ^18.0.0",
+ "react": "^17.0.0 || ^18.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@mui/material": {
+ "version": "5.10.1",
+ "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.10.1.tgz",
+ "integrity": "sha512-E9fhskX6TwUdAzpL5+yoAzRxb6wY4oBqmBVlgUuLndSwPRYxXoGu+z74NxbDEkxUoHdb7vrDcRTswpB6ykDITQ==",
+ "peer": true,
+ "dependencies": {
+ "@babel/runtime": "^7.17.2",
+ "@mui/base": "5.0.0-alpha.93",
+ "@mui/core-downloads-tracker": "^5.10.1",
+ "@mui/system": "^5.10.1",
+ "@mui/types": "^7.1.5",
+ "@mui/utils": "^5.9.3",
+ "@types/react-transition-group": "^4.4.5",
+ "clsx": "^1.2.1",
+ "csstype": "^3.1.0",
+ "prop-types": "^15.8.1",
+ "react-is": "^18.2.0",
+ "react-transition-group": "^4.4.5"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/mui"
+ },
+ "peerDependencies": {
+ "@emotion/react": "^11.5.0",
+ "@emotion/styled": "^11.3.0",
+ "@types/react": "^17.0.0 || ^18.0.0",
+ "react": "^17.0.0 || ^18.0.0",
+ "react-dom": "^17.0.0 || ^18.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@emotion/react": {
+ "optional": true
+ },
+ "@emotion/styled": {
+ "optional": true
+ },
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@mui/private-theming": {
+ "version": "5.9.3",
+ "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.9.3.tgz",
+ "integrity": "sha512-Ys3WO39WqoGciGX9k5AIi/k2zJhlydv4FzlEEwtw9OqdMaV0ydK/TdZekKzjP9sTI/JcdAP3H5DWtUaPLQJjWg==",
+ "peer": true,
+ "dependencies": {
+ "@babel/runtime": "^7.17.2",
+ "@mui/utils": "^5.9.3",
+ "prop-types": "^15.8.1"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/mui"
+ },
+ "peerDependencies": {
+ "@types/react": "^17.0.0 || ^18.0.0",
+ "react": "^17.0.0 || ^18.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@mui/styled-engine": {
+ "version": "5.10.1",
+ "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.10.1.tgz",
+ "integrity": "sha512-xiQp6wvSLpMcRCOExbRSvkHf6gIQ/eeK7mx/Re6BtPPYIx6OerPwia+23uVIop/k4Bs5D+w7Rv2yXYJxo5rMSQ==",
+ "peer": true,
+ "dependencies": {
+ "@babel/runtime": "^7.17.2",
+ "@emotion/cache": "^11.9.3",
+ "csstype": "^3.1.0",
+ "prop-types": "^15.8.1"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/mui"
+ },
+ "peerDependencies": {
+ "@emotion/react": "^11.4.1",
+ "@emotion/styled": "^11.3.0",
+ "react": "^17.0.0 || ^18.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@emotion/react": {
+ "optional": true
+ },
+ "@emotion/styled": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@mui/system": {
+ "version": "5.10.1",
+ "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.10.1.tgz",
+ "integrity": "sha512-Ix8LVAMtVrNtmncK0yc5llHWlZKCm9okbw8QMnWbI5UH+nI9qhtf+Aure4p5ei6dGKdil++lukar/GxCjfzRSg==",
+ "peer": true,
+ "dependencies": {
+ "@babel/runtime": "^7.17.2",
+ "@mui/private-theming": "^5.9.3",
+ "@mui/styled-engine": "^5.10.1",
+ "@mui/types": "^7.1.5",
+ "@mui/utils": "^5.9.3",
+ "clsx": "^1.2.1",
+ "csstype": "^3.1.0",
+ "prop-types": "^15.8.1"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/mui"
+ },
+ "peerDependencies": {
+ "@emotion/react": "^11.5.0",
+ "@emotion/styled": "^11.3.0",
+ "@types/react": "^17.0.0 || ^18.0.0",
+ "react": "^17.0.0 || ^18.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@emotion/react": {
+ "optional": true
+ },
+ "@emotion/styled": {
+ "optional": true
+ },
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@mui/types": {
+ "version": "7.1.5",
+ "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.1.5.tgz",
+ "integrity": "sha512-HnRXrxgHJYJcT8ZDdDCQIlqk0s0skOKD7eWs9mJgBUu70hyW4iA6Kiv3yspJR474RFH8hysKR65VVSzUSzkuwA==",
+ "peer": true,
+ "peerDependencies": {
+ "@types/react": "*"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@mui/utils": {
+ "version": "5.9.3",
+ "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.9.3.tgz",
+ "integrity": "sha512-l0N5bcrenE9hnwZ/jPecpIRqsDFHkPXoFUcmkgysaJwVZzJ3yQkGXB47eqmXX5yyGrSc6HksbbqXEaUya+siew==",
+ "peer": true,
+ "dependencies": {
+ "@babel/runtime": "^7.17.2",
+ "@types/prop-types": "^15.7.5",
+ "@types/react-is": "^16.7.1 || ^17.0.0",
+ "prop-types": "^15.8.1",
+ "react-is": "^18.2.0"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/mui"
+ },
+ "peerDependencies": {
+ "react": "^17.0.0 || ^18.0.0"
+ }
+ },
+ "node_modules/@popperjs/core": {
+ "version": "2.11.6",
+ "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.6.tgz",
+ "integrity": "sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw==",
+ "peer": true,
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/popperjs"
+ }
+ },
+ "node_modules/@types/hoist-non-react-statics": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz",
+ "integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==",
+ "dependencies": {
+ "@types/react": "*",
+ "hoist-non-react-statics": "^3.3.0"
+ }
+ },
+ "node_modules/@types/prop-types": {
+ "version": "15.7.5",
+ "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz",
+ "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w=="
+ },
+ "node_modules/@types/react": {
+ "version": "18.0.17",
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.17.tgz",
+ "integrity": "sha512-38ETy4tL+rn4uQQi7mB81G7V1g0u2ryquNmsVIOKUAEIDK+3CUjZ6rSRpdvS99dNBnkLFL83qfmtLacGOTIhwQ==",
+ "dependencies": {
+ "@types/prop-types": "*",
+ "@types/scheduler": "*",
+ "csstype": "^3.0.2"
+ }
+ },
+ "node_modules/@types/react-is": {
+ "version": "17.0.3",
+ "resolved": "https://registry.npmjs.org/@types/react-is/-/react-is-17.0.3.tgz",
+ "integrity": "sha512-aBTIWg1emtu95bLTLx0cpkxwGW3ueZv71nE2YFBpL8k/z5czEW8yYpOo8Dp+UUAFAtKwNaOsh/ioSeQnWlZcfw==",
+ "peer": true,
+ "dependencies": {
+ "@types/react": "*"
+ }
+ },
+ "node_modules/@types/react-transition-group": {
+ "version": "4.4.5",
+ "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.5.tgz",
+ "integrity": "sha512-juKD/eiSM3/xZYzjuzH6ZwpP+/lejltmiS3QEzV/vmb/Q8+HfDmxu+Baga8UEMGBqV88Nbg4l2hY/K2DkyaLLA==",
+ "peer": true,
+ "dependencies": {
+ "@types/react": "*"
+ }
+ },
+ "node_modules/@types/scheduler": {
+ "version": "0.16.2",
+ "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz",
+ "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew=="
+ },
+ "node_modules/@types/use-sync-external-store": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz",
+ "integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA=="
+ },
+ "node_modules/clsx": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz",
+ "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==",
+ "peer": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/csstype": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.0.tgz",
+ "integrity": "sha512-uX1KG+x9h5hIJsaKR9xHUeUraxf8IODOwq9JLNPq6BwB04a/xgpq3rcx47l5BZu5zBPlgD342tdke3Hom/nJRA=="
+ },
+ "node_modules/dom-helpers": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz",
+ "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==",
+ "peer": true,
+ "dependencies": {
+ "@babel/runtime": "^7.8.7",
+ "csstype": "^3.0.2"
+ }
+ },
+ "node_modules/hoist-non-react-statics": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
+ "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
+ "dependencies": {
+ "react-is": "^16.7.0"
+ }
+ },
+ "node_modules/hoist-non-react-statics/node_modules/react-is": {
+ "version": "16.13.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
+ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
+ },
+ "node_modules/js-tokens": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+ "peer": true
+ },
+ "node_modules/loose-envify": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
+ "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
+ "peer": true,
+ "dependencies": {
+ "js-tokens": "^3.0.0 || ^4.0.0"
+ },
+ "bin": {
+ "loose-envify": "cli.js"
+ }
+ },
+ "node_modules/object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
+ "peer": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/prop-types": {
+ "version": "15.8.1",
+ "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
+ "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
+ "peer": true,
+ "dependencies": {
+ "loose-envify": "^1.4.0",
+ "object-assign": "^4.1.1",
+ "react-is": "^16.13.1"
+ }
+ },
+ "node_modules/prop-types/node_modules/react-is": {
+ "version": "16.13.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
+ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
+ "peer": true
+ },
+ "node_modules/react": {
+ "version": "18.2.0",
+ "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz",
+ "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==",
+ "peer": true,
+ "dependencies": {
+ "loose-envify": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/react-dom": {
+ "version": "18.2.0",
+ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz",
+ "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==",
+ "peer": true,
+ "dependencies": {
+ "loose-envify": "^1.1.0",
+ "scheduler": "^0.23.0"
+ },
+ "peerDependencies": {
+ "react": "^18.2.0"
+ }
+ },
+ "node_modules/react-is": {
+ "version": "18.2.0",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
+ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
+ },
+ "node_modules/react-redux": {
+ "version": "8.0.2",
+ "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-8.0.2.tgz",
+ "integrity": "sha512-nBwiscMw3NoP59NFCXFf02f8xdo+vSHT/uZ1ldDwF7XaTpzm+Phk97VT4urYBl5TYAPNVaFm12UHAEyzkpNzRA==",
+ "dependencies": {
+ "@babel/runtime": "^7.12.1",
+ "@types/hoist-non-react-statics": "^3.3.1",
+ "@types/use-sync-external-store": "^0.0.3",
+ "hoist-non-react-statics": "^3.3.2",
+ "react-is": "^18.0.0",
+ "use-sync-external-store": "^1.0.0"
+ },
+ "peerDependencies": {
+ "@types/react": "^16.8 || ^17.0 || ^18.0",
+ "@types/react-dom": "^16.8 || ^17.0 || ^18.0",
+ "react": "^16.8 || ^17.0 || ^18.0",
+ "react-dom": "^16.8 || ^17.0 || ^18.0",
+ "react-native": ">=0.59",
+ "redux": "^4"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ },
+ "react-dom": {
+ "optional": true
+ },
+ "react-native": {
+ "optional": true
+ },
+ "redux": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/react-transition-group": {
+ "version": "4.4.5",
+ "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz",
+ "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==",
+ "peer": true,
+ "dependencies": {
+ "@babel/runtime": "^7.5.5",
+ "dom-helpers": "^5.0.1",
+ "loose-envify": "^1.4.0",
+ "prop-types": "^15.6.2"
+ },
+ "peerDependencies": {
+ "react": ">=16.6.0",
+ "react-dom": ">=16.6.0"
+ }
+ },
+ "node_modules/regenerator-runtime": {
+ "version": "0.13.9",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz",
+ "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA=="
+ },
+ "node_modules/resize-observer-polyfill": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz",
+ "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg=="
+ },
+ "node_modules/scheduler": {
+ "version": "0.23.0",
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz",
+ "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==",
+ "peer": true,
+ "dependencies": {
+ "loose-envify": "^1.1.0"
+ }
+ },
+ "node_modules/stylis": {
+ "version": "4.0.13",
+ "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.0.13.tgz",
+ "integrity": "sha512-xGPXiFVl4YED9Jh7Euv2V220mriG9u4B2TA6Ybjc1catrstKD2PpIdU3U0RKpkVBC2EhmL/F0sPCr9vrFTNRag==",
+ "peer": true
+ },
+ "node_modules/use-sync-external-store": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz",
+ "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==",
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0"
+ }
+ }
+ },
+ "dependencies": {
+ "@babel/runtime": {
+ "version": "7.18.9",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.18.9.tgz",
+ "integrity": "sha512-lkqXDcvlFT5rvEjiu6+QYO+1GXrEHRo2LOtS7E4GtX5ESIZOgepqsZBVIj6Pv+a6zqsya9VCgiK1KAK4BvJDAw==",
+ "requires": {
+ "regenerator-runtime": "^0.13.4"
+ }
+ },
+ "@emotion/cache": {
+ "version": "11.10.1",
+ "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.10.1.tgz",
+ "integrity": "sha512-uZTj3Yz5D69GE25iFZcIQtibnVCFsc/6+XIozyL3ycgWvEdif2uEw9wlUt6umjLr4Keg9K6xRPHmD8LGi+6p1A==",
+ "peer": true,
+ "requires": {
+ "@emotion/memoize": "^0.8.0",
+ "@emotion/sheet": "^1.2.0",
+ "@emotion/utils": "^1.2.0",
+ "@emotion/weak-memoize": "^0.3.0",
+ "stylis": "4.0.13"
+ }
+ },
+ "@emotion/is-prop-valid": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.0.tgz",
+ "integrity": "sha512-3aDpDprjM0AwaxGE09bOPkNxHpBd+kA6jty3RnaEXdweX1DF1U3VQpPYb0g1IStAuK7SVQ1cy+bNBBKp4W3Fjg==",
+ "peer": true,
+ "requires": {
+ "@emotion/memoize": "^0.8.0"
+ }
+ },
+ "@emotion/memoize": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.0.tgz",
+ "integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==",
+ "peer": true
+ },
+ "@emotion/sheet": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.0.tgz",
+ "integrity": "sha512-OiTkRgpxescko+M51tZsMq7Puu/KP55wMT8BgpcXVG2hqXc0Vo0mfymJ/Uj24Hp0i083ji/o0aLddh08UEjq8w==",
+ "peer": true
+ },
+ "@emotion/utils": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.0.tgz",
+ "integrity": "sha512-sn3WH53Kzpw8oQ5mgMmIzzyAaH2ZqFEbozVVBSYp538E06OSE6ytOp7pRAjNQR+Q/orwqdQYJSe2m3hCOeznkw==",
+ "peer": true
+ },
+ "@emotion/weak-memoize": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.0.tgz",
+ "integrity": "sha512-AHPmaAx+RYfZz0eYu6Gviiagpmiyw98ySSlQvCUhVGDRtDFe4DBS0x1bSjdF3gqUDYOczB+yYvBTtEylYSdRhg==",
+ "peer": true
+ },
+ "@mui/base": {
+ "version": "5.0.0-alpha.93",
+ "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-alpha.93.tgz",
+ "integrity": "sha512-IVUWO0NNlELDc9FD7mM+fWTS1/6n5sJYdIbXpLQ00NjWdVEYmTyRgUAZDlJJJrz+tbF0eeffx0kOsvJvyTZlsA==",
+ "peer": true,
+ "requires": {
+ "@babel/runtime": "^7.17.2",
+ "@emotion/is-prop-valid": "^1.1.3",
+ "@mui/types": "^7.1.5",
+ "@mui/utils": "^5.9.3",
+ "@popperjs/core": "^2.11.6",
+ "clsx": "^1.2.1",
+ "prop-types": "^15.8.1",
+ "react-is": "^18.2.0"
+ }
+ },
+ "@mui/core-downloads-tracker": {
+ "version": "5.10.1",
+ "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.10.1.tgz",
+ "integrity": "sha512-zyzLkVSqi+WuxG8UZrrOaWbhHkDK+MlHFjLpL+vqUVU6iSUaDYREu1xoLWEQsWOznT4oT2iEiGZLpQLgkn+WiA==",
+ "peer": true
+ },
+ "@mui/icons-material": {
+ "version": "5.8.4",
+ "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.8.4.tgz",
+ "integrity": "sha512-9Z/vyj2szvEhGWDvb+gG875bOGm8b8rlHBKOD1+nA3PcgC3fV6W1AU6pfOorPeBfH2X4mb9Boe97vHvaSndQvA==",
+ "requires": {
+ "@babel/runtime": "^7.17.2"
+ }
+ },
+ "@mui/material": {
+ "version": "5.10.1",
+ "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.10.1.tgz",
+ "integrity": "sha512-E9fhskX6TwUdAzpL5+yoAzRxb6wY4oBqmBVlgUuLndSwPRYxXoGu+z74NxbDEkxUoHdb7vrDcRTswpB6ykDITQ==",
+ "peer": true,
+ "requires": {
+ "@babel/runtime": "^7.17.2",
+ "@mui/base": "5.0.0-alpha.93",
+ "@mui/core-downloads-tracker": "^5.10.1",
+ "@mui/system": "^5.10.1",
+ "@mui/types": "^7.1.5",
+ "@mui/utils": "^5.9.3",
+ "@types/react-transition-group": "^4.4.5",
+ "clsx": "^1.2.1",
+ "csstype": "^3.1.0",
+ "prop-types": "^15.8.1",
+ "react-is": "^18.2.0",
+ "react-transition-group": "^4.4.5"
+ }
+ },
+ "@mui/private-theming": {
+ "version": "5.9.3",
+ "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.9.3.tgz",
+ "integrity": "sha512-Ys3WO39WqoGciGX9k5AIi/k2zJhlydv4FzlEEwtw9OqdMaV0ydK/TdZekKzjP9sTI/JcdAP3H5DWtUaPLQJjWg==",
+ "peer": true,
+ "requires": {
+ "@babel/runtime": "^7.17.2",
+ "@mui/utils": "^5.9.3",
+ "prop-types": "^15.8.1"
+ }
+ },
+ "@mui/styled-engine": {
+ "version": "5.10.1",
+ "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.10.1.tgz",
+ "integrity": "sha512-xiQp6wvSLpMcRCOExbRSvkHf6gIQ/eeK7mx/Re6BtPPYIx6OerPwia+23uVIop/k4Bs5D+w7Rv2yXYJxo5rMSQ==",
+ "peer": true,
+ "requires": {
+ "@babel/runtime": "^7.17.2",
+ "@emotion/cache": "^11.9.3",
+ "csstype": "^3.1.0",
+ "prop-types": "^15.8.1"
+ }
+ },
+ "@mui/system": {
+ "version": "5.10.1",
+ "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.10.1.tgz",
+ "integrity": "sha512-Ix8LVAMtVrNtmncK0yc5llHWlZKCm9okbw8QMnWbI5UH+nI9qhtf+Aure4p5ei6dGKdil++lukar/GxCjfzRSg==",
+ "peer": true,
+ "requires": {
+ "@babel/runtime": "^7.17.2",
+ "@mui/private-theming": "^5.9.3",
+ "@mui/styled-engine": "^5.10.1",
+ "@mui/types": "^7.1.5",
+ "@mui/utils": "^5.9.3",
+ "clsx": "^1.2.1",
+ "csstype": "^3.1.0",
+ "prop-types": "^15.8.1"
+ }
+ },
+ "@mui/types": {
+ "version": "7.1.5",
+ "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.1.5.tgz",
+ "integrity": "sha512-HnRXrxgHJYJcT8ZDdDCQIlqk0s0skOKD7eWs9mJgBUu70hyW4iA6Kiv3yspJR474RFH8hysKR65VVSzUSzkuwA==",
+ "peer": true,
+ "requires": {}
+ },
+ "@mui/utils": {
+ "version": "5.9.3",
+ "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.9.3.tgz",
+ "integrity": "sha512-l0N5bcrenE9hnwZ/jPecpIRqsDFHkPXoFUcmkgysaJwVZzJ3yQkGXB47eqmXX5yyGrSc6HksbbqXEaUya+siew==",
+ "peer": true,
+ "requires": {
+ "@babel/runtime": "^7.17.2",
+ "@types/prop-types": "^15.7.5",
+ "@types/react-is": "^16.7.1 || ^17.0.0",
+ "prop-types": "^15.8.1",
+ "react-is": "^18.2.0"
+ }
+ },
+ "@popperjs/core": {
+ "version": "2.11.6",
+ "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.6.tgz",
+ "integrity": "sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw==",
+ "peer": true
+ },
+ "@types/hoist-non-react-statics": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz",
+ "integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==",
+ "requires": {
+ "@types/react": "*",
+ "hoist-non-react-statics": "^3.3.0"
+ }
+ },
+ "@types/prop-types": {
+ "version": "15.7.5",
+ "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz",
+ "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w=="
+ },
+ "@types/react": {
+ "version": "18.0.17",
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.17.tgz",
+ "integrity": "sha512-38ETy4tL+rn4uQQi7mB81G7V1g0u2ryquNmsVIOKUAEIDK+3CUjZ6rSRpdvS99dNBnkLFL83qfmtLacGOTIhwQ==",
+ "requires": {
+ "@types/prop-types": "*",
+ "@types/scheduler": "*",
+ "csstype": "^3.0.2"
+ }
+ },
+ "@types/react-is": {
+ "version": "17.0.3",
+ "resolved": "https://registry.npmjs.org/@types/react-is/-/react-is-17.0.3.tgz",
+ "integrity": "sha512-aBTIWg1emtu95bLTLx0cpkxwGW3ueZv71nE2YFBpL8k/z5czEW8yYpOo8Dp+UUAFAtKwNaOsh/ioSeQnWlZcfw==",
+ "peer": true,
+ "requires": {
+ "@types/react": "*"
+ }
+ },
+ "@types/react-transition-group": {
+ "version": "4.4.5",
+ "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.5.tgz",
+ "integrity": "sha512-juKD/eiSM3/xZYzjuzH6ZwpP+/lejltmiS3QEzV/vmb/Q8+HfDmxu+Baga8UEMGBqV88Nbg4l2hY/K2DkyaLLA==",
+ "peer": true,
+ "requires": {
+ "@types/react": "*"
+ }
+ },
+ "@types/scheduler": {
+ "version": "0.16.2",
+ "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz",
+ "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew=="
+ },
+ "@types/use-sync-external-store": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz",
+ "integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA=="
+ },
+ "clsx": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz",
+ "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==",
+ "peer": true
+ },
+ "csstype": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.0.tgz",
+ "integrity": "sha512-uX1KG+x9h5hIJsaKR9xHUeUraxf8IODOwq9JLNPq6BwB04a/xgpq3rcx47l5BZu5zBPlgD342tdke3Hom/nJRA=="
+ },
+ "dom-helpers": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz",
+ "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==",
+ "peer": true,
+ "requires": {
+ "@babel/runtime": "^7.8.7",
+ "csstype": "^3.0.2"
+ }
+ },
+ "hoist-non-react-statics": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
+ "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
+ "requires": {
+ "react-is": "^16.7.0"
+ },
+ "dependencies": {
+ "react-is": {
+ "version": "16.13.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
+ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
+ }
+ }
+ },
+ "js-tokens": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+ "peer": true
+ },
+ "loose-envify": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
+ "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
+ "peer": true,
+ "requires": {
+ "js-tokens": "^3.0.0 || ^4.0.0"
+ }
+ },
+ "object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
+ "peer": true
+ },
+ "prop-types": {
+ "version": "15.8.1",
+ "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
+ "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
+ "peer": true,
+ "requires": {
+ "loose-envify": "^1.4.0",
+ "object-assign": "^4.1.1",
+ "react-is": "^16.13.1"
+ },
+ "dependencies": {
+ "react-is": {
+ "version": "16.13.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
+ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
+ "peer": true
+ }
+ }
+ },
+ "react": {
+ "version": "18.2.0",
+ "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz",
+ "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==",
+ "peer": true,
+ "requires": {
+ "loose-envify": "^1.1.0"
+ }
+ },
+ "react-dom": {
+ "version": "18.2.0",
+ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz",
+ "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==",
+ "peer": true,
+ "requires": {
+ "loose-envify": "^1.1.0",
+ "scheduler": "^0.23.0"
+ }
+ },
+ "react-is": {
+ "version": "18.2.0",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
+ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
+ },
+ "react-redux": {
+ "version": "8.0.2",
+ "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-8.0.2.tgz",
+ "integrity": "sha512-nBwiscMw3NoP59NFCXFf02f8xdo+vSHT/uZ1ldDwF7XaTpzm+Phk97VT4urYBl5TYAPNVaFm12UHAEyzkpNzRA==",
+ "requires": {
+ "@babel/runtime": "^7.12.1",
+ "@types/hoist-non-react-statics": "^3.3.1",
+ "@types/use-sync-external-store": "^0.0.3",
+ "hoist-non-react-statics": "^3.3.2",
+ "react-is": "^18.0.0",
+ "use-sync-external-store": "^1.0.0"
+ }
+ },
+ "react-transition-group": {
+ "version": "4.4.5",
+ "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz",
+ "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==",
+ "peer": true,
+ "requires": {
+ "@babel/runtime": "^7.5.5",
+ "dom-helpers": "^5.0.1",
+ "loose-envify": "^1.4.0",
+ "prop-types": "^15.6.2"
+ }
+ },
+ "regenerator-runtime": {
+ "version": "0.13.9",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz",
+ "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA=="
+ },
+ "resize-observer-polyfill": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz",
+ "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg=="
+ },
+ "scheduler": {
+ "version": "0.23.0",
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz",
+ "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==",
+ "peer": true,
+ "requires": {
+ "loose-envify": "^1.1.0"
+ }
+ },
+ "stylis": {
+ "version": "4.0.13",
+ "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.0.13.tgz",
+ "integrity": "sha512-xGPXiFVl4YED9Jh7Euv2V220mriG9u4B2TA6Ybjc1catrstKD2PpIdU3U0RKpkVBC2EhmL/F0sPCr9vrFTNRag==",
+ "peer": true
+ },
+ "use-sync-external-store": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz",
+ "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==",
+ "requires": {}
+ }
+ }
+}
diff --git a/package.json b/package.json
new file mode 100644
index 000000000..1e9ec1db3
--- /dev/null
+++ b/package.json
@@ -0,0 +1,7 @@
+{
+ "dependencies": {
+ "@mui/icons-material": "^5.8.4",
+ "react-redux": "^8.0.2",
+ "resize-observer-polyfill": "^1.5.1"
+ }
+}